diff --git a/.clang-tidy b/.clang-tidy index 874dd51ad2..21eb0d83b3 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -23,6 +23,7 @@ Checks: '*,-fuchsia-*, -google-runtime-references,-google-readability-casting,-google-build-using-namespace, google-default-arguments,-cppcoreguidelines-pro-bounds-pointer-arithmetic, -cert-err58-cpp, + -altera-unroll-loops, -readability-function-cognitive-complexity,-readability-isolate-declaration, -misc-non-private-member-variables-in-classes,-altera-struct-pack-align,-readability-uppercase-literal-suffix, -cppcoreguidelines-non-private-member-variables-in-classes, diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 8272df7416..491d3b3509 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -1,48 +1,42 @@ name: C/C++ CI on: push jobs: - x86_ubuntu18_build: - name: Build and test on x86 Ubuntu 18.04 + x86_ubuntu_build: + name: Build on x86 + runs-on: ${{ matrix.os }} strategy: - matrix: - compiler: [gcc, clang] - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v1 - - name: Build srsRAN on x86 Ubuntu 18.04 - run: | - sudo apt update - sudo apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libconfig++-dev libsctp-dev colordiff ninja-build valgrind - mkdir build && cd build && cmake -DRF_FOUND=True -GNinja .. && ninja && ctest - x86_ubuntu16_build: - name: Build and test on x86 Ubuntu 16.04 - strategy: - matrix: - compiler: [gcc, clang] - runs-on: ubuntu-16.04 + fail-fast: false + matrix: + os: [ubuntu-22.04, ubuntu-20.04] + compiler: [gcc, clang] steps: - - uses: actions/checkout@v1 - - name: Build srsRAN on x86 Ubuntu 16.04 - run: | - sudo apt update - sudo apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libconfig++-dev libsctp-dev colordiff ninja-build valgrind - mkdir build && cd build && cmake -DRF_FOUND=True -GNinja .. && ninja && ctest - - aarch64_ubuntu18_build: - runs-on: ubuntu-18.04 + - uses: actions/checkout@v3 + - name: Build srsRAN on x86 ${{ matrix.os }} + run: | + sudo apt update + sudo apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libconfig++-dev libsctp-dev colordiff ninja-build valgrind + mkdir build && cd build && cmake -DRF_FOUND=True -GNinja .. && ninja && ctest + + aarch64_ubuntu_build: name: Build on aarch64 + runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: + os: [ubuntu-20.04] compiler: [gcc, clang] + include: + - os: ubuntu-20.04 + distro: ubuntu20.04 steps: - - uses: actions/checkout@v1 - - name: Build srsRAN on aarch64 + - uses: actions/checkout@v3 + - name: Build srsRAN on aarch64 ${{ matrix.os }} uses: uraimo/run-on-arch-action@master with: - architecture: aarch64 - distribution: ubuntu18.04 + arch: aarch64 + distro: ${{ matrix.distro }} run: | export CTEST_PARALLEL_LEVEL=$(nproc --all) apt update apt install -y build-essential cmake libfftw3-dev libmbedtls-dev libpcsclite-dev libboost-program-options-dev libconfig++-dev libsctp-dev ninja-build - ls -l && pwd && mkdir build && cd build && cmake -DRF_FOUND=True -GNinja .. && ninja \ No newline at end of file + ls -l && pwd && mkdir build && cd build && cmake -DRF_FOUND=True -GNinja .. && ninja diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..95d63895ce --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,69 @@ +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 update + sudo apt install -y \ + 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 bdc185dc0f..bf2f82a4d1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,41 @@ Change Log for Releases ======================= +## 23.04 + * Introduced configurable s1 connection timer + * Updated 4G RRC ASN.1 to Rel 17 + * Added reestablishment support during S1-Handover + * Added basic support for NSSAI based slicing in UE & gNodeB + * Updated the RRC to enable srsUE compatibility with new srsgnb + * Updated eMBMS to fix various outstanding issues + * Added basic support for RIC E2 interface + * other bug-fixes and improved stability and performance in all parts + + +## 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 + * Remove fixed coreset0 index for SSB + * Add support for SIB5 and SIB6 transmission in LTE + +## 22.04 + * Added baseline 5G-SA support to srsUE and srsENB + * Added dynamic loading of RF libraries + * Added RRC Redirect to srsUE + * Added support for A5 measurement events to srsENB + * Added Crest Factor Reduction (CFR) for srsENB downlink and srsUE uplink (4G only) + * Raise C++ standard to C++14 + * Other bug-fixes and improved stability and performance in all parts ## 21.10 * Add initial 5G NSA support to srsENB (tested with OnePlus 5G Nord) diff --git a/CMakeLists.txt b/CMakeLists.txt index e18cb5a3cd..5da6ac51bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -30,7 +30,7 @@ endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) ######################################################################## # Project setup ######################################################################## -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 3.5) project( SRSRAN ) message( STATUS "CMAKE_SYSTEM: " ${CMAKE_SYSTEM} ) message( STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR} ) @@ -69,6 +69,7 @@ option(DISABLE_SIMD "Disable SIMD instructions" OFF) option(AUTO_DETECT_ISA "Autodetect supported ISA extensions" ON) option(ENABLE_GUI "Enable GUI (using srsGUI)" ON) +option(ENABLE_RF_PLUGINS "Enable RF plugins" ON) option(ENABLE_UHD "Enable UHD" ON) option(ENABLE_BLADERF "Enable BladeRF" ON) option(ENABLE_SOAPYSDR "Enable SoapySDR" ON) @@ -82,7 +83,7 @@ option(ENABLE_ZMQ_TEST "Enable ZMQ based E2E tests" OFF) option(BUILD_STATIC "Attempt to statically link external deps" OFF) option(RPATH "Enable RPATH" OFF) option(ENABLE_ASAN "Enable gcc/clang address sanitizer" OFF) -option(ENABLE_GCOV "Enable gcc/clang address sanitizer" OFF) +option(ENABLE_GCOV "Enable gcov" OFF) option(ENABLE_MSAN "Enable clang memory sanitizer" OFF) option(ENABLE_TSAN "Enable clang thread sanitizer" OFF) option(ENABLE_TIDY "Enable clang tidy" OFF) @@ -106,12 +107,14 @@ option(ENABLE_ALL_TEST "Enable all unit/component test" OFF) # (gcc-ar, gcc-nm, ...). option(BUILD_WITH_LTO "Enable LTO (experimental)" OFF) -if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") - set(GCC_ARCH armv8-a CACHE STRING "GCC compile for specific architecture.") - message(STATUS "Detected aarch64 processor") -else(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") - set(GCC_ARCH native CACHE STRING "GCC compile for specific architecture.") -endif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") +if(NOT GCC_ARCH) + if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + set(GCC_ARCH armv8-a CACHE STRING "GCC compile for specific architecture.") + message(STATUS "Detected aarch64 processor") + else(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + set(GCC_ARCH native CACHE STRING "GCC compile for specific architecture.") + endif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") +endif() # On RAM constrained (embedded) systems it may be useful to limit parallel compilation with, e.g. -DPARALLEL_COMPILE_JOBS=1 if (PARALLEL_COMPILE_JOBS) @@ -179,29 +182,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) @@ -280,6 +271,9 @@ endif(BUILD_STATIC) set(BOOST_REQUIRED_COMPONENTS program_options ) +if(UHD_FOUND) # Ubuntu 18.04 requires component 'system' to link UHD + list(APPEND BOOST_REQUIRED_COMPONENTS "system") +endif(UHD_FOUND) if(UNIX AND EXISTS "/usr/lib64") list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix endif(UNIX AND EXISTS "/usr/lib64") @@ -379,9 +373,8 @@ macro(ADD_C_COMPILER_FLAG_IF_AVAILABLE flag have) endmacro(ADD_C_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} -Wall -Wno-comment -Wno-reorder -Wno-unused-variable -Wtype-limits -std=c++11 -fno-strict-aliasing") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-comment -Wno-reorder -Wno-unused-variable -Wtype-limits -std=c++14 -fno-strict-aliasing") - ADD_C_COMPILER_FLAG_IF_AVAILABLE("-Wno-unused-but-set-variable" HAVE_WNO_UNUSED_BUT_SET_VARIABLE) ADD_CXX_COMPILER_FLAG_IF_AVAILABLE("-Wno-unused-but-set-variable" HAVE_WNO_UNUSED_BUT_SET_VARIABLE) if (AUTO_DETECT_ISA) @@ -409,8 +402,8 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") endif(NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug") if(FORCE_32BIT) - ADD_C_COMPILER_FLAG_IF_AVAILABLE("-m32" HAVE_WNO_UNUSED_BUT_SET_VARIABLE) - ADD_CXX_COMPILER_FLAG_IF_AVAILABLE("-m32" HAVE_WNO_UNUSED_BUT_SET_VARIABLE) + ADD_C_COMPILER_FLAG_IF_AVAILABLE("-m32" HAVE_M32) + ADD_CXX_COMPILER_FLAG_IF_AVAILABLE("-m32" HAVE_M32) set(CMAKE_SHARED_LINKER_FLAGS "-m32") endif(FORCE_32BIT) @@ -421,6 +414,7 @@ ADD_C_COMPILER_FLAG_IF_AVAILABLE("-Werror=incompatible-pointer-types" HAVE_ERROR if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-comment -Wno-write-strings -Wno-unused-result -Wformat -Wmissing-field-initializers -Wtype-limits -std=c99 -fno-strict-aliasing -D_GNU_SOURCE") + ADD_C_COMPILER_FLAG_IF_AVAILABLE("-Wno-unused-but-set-variable" HAVE_WNO_UNUSED_BUT_SET_VARIABLE) if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") 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") @@ -506,8 +500,12 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") endif () if (ENABLE_ASAN) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") + # Note: When using ASAN, we need to ensure the use of RPATH instead of RUNPATH via "-Wl,--disable-new-dtags" + # While RPATH is default, some systems (e.g. Ubuntu 18.04 and 20.04) use RUNPATH by default, which is non-transitive. + # Since ASAN intercepts dlopen(), by which it replaces the dynamic string token "$ORIGIN" to its own location, + # the RF plugins won't be found by "libsrsran_rf.so" when using ASAN + RUNPATH in the top-level executable. + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -Wl,--disable-new-dtags") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -Wl,--disable-new-dtags") endif (ENABLE_ASAN) if (ENABLE_TSAN) @@ -544,6 +542,12 @@ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") endif() +# GCC >= 11.2.0: Disable analysis on "maybe-uninitialized" variables because of the high false-positive rate +if(CMAKE_COMPILER_IS_GNUCXX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11.2) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-maybe-uninitialized") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized") +endif() + if(CMAKE_C_COMPILER_ID MATCHES "GNU") # Increase inlining limit to allow gcc compilation on e.g. RPi2 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --param large-function-growth=1600") @@ -670,13 +674,14 @@ if(RF_FOUND) endif(ENABLE_SRSUE) if(ENABLE_SRSENB) - message(STATUS "Building with srsENB") + message(STATUS "Building with srsENB/srsGNB") add_subdirectory(srsenb) + add_subdirectory(srsgnb) else(ENABLE_SRSENB) - message(STATUS "srsENB build disabled") + message(STATUS "srsENB/srsGNB build disabled") endif(ENABLE_SRSENB) else(RF_FOUND) - message(STATUS "srsUE and srsENB builds disabled due to missing RF driver") + message(STATUS "srsUE and srsENB/srsGNB builds disabled due to missing RF driver") endif(RF_FOUND) if(ENABLE_SRSEPC) diff --git a/COPYRIGHT b/COPYRIGHT index 7b6dc37e79..dae09269f0 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,5 +1,5 @@ Files: * -Copyright: 2013-2021, Software Radio Systems Limited. +Copyright: 2013-2022, Software Radio Systems Limited. License: diff --git a/CTestConfig.cmake b/CTestConfig.cmake index fe80d73cf3..8d595d9631 100644 --- a/CTestConfig.cmake +++ b/CTestConfig.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/README.md b/README.md index 90659b531b..20d771bc16 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,20 @@ srsRAN ====== -[![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) -[![Coverity](https://scan.coverity.com/projects/23045/badge.svg)](https://scan.coverity.com/projects/srsran) +[![Build Status](https://github.com/srsran/srsRAN_4G/actions/workflows/ccpp.yml/badge.svg?branch=master)](https://github.com/srsran/srsRAN_4G/actions/workflows/ccpp.yml) +[![CodeQL](https://github.com/srsran/srsRAN_4G/actions/workflows/codeql.yml/badge.svg?branch=master)](https://github.com/srsran/srsRAN_4G/actions/workflows/codeql.yml) +[![Coverity](https://scan.coverity.com/projects/28268/badge.svg)](https://scan.coverity.com/projects/srsran_4g_agpl) -srsRAN is a 4G/5G software radio suite developed by [SRS](http://www.srs.io). +srsRAN is an open source 4G software radio suite developed by [SRS](http://www.srs.io). For 5G RAN, see our new O-RAN CU/DU solution - [srsRAN Project](https://www.github.com/srsran/srsran_project). -See the [srsRAN project pages](https://www.srsran.com) for information, guides and project news. +See the [srsRAN 4G project pages](https://www.srsran.com) for information, guides and project news. The srsRAN suite includes: - * srsUE - a full-stack SDR 4G/5G-NSA UE application (5G-SA coming soon) - * srsENB - a full-stack SDR 4G/5G-NSA eNodeB application (5G-SA coming soon) + * srsUE - a full-stack SDR 4G UE application with prototype 5G features + * srsENB - a full-stack SDR 4G eNodeB application * srsEPC - a light-weight 4G core network implementation with MME, HSS and S/P-GW -For application features, build instructions and user guides see the [srsRAN documentation](https://docs.srsran.com). +For application features, build instructions and user guides see the [srsRAN 4G documentation](https://docs.srsran.com/projects/4g/). For license details, see LICENSE file. @@ -22,3 +22,4 @@ Support ======= Mailing list: https://lists.srsran.com/mailman/listinfo/srsran-users + diff --git a/cmake/modules/CheckAtomic.cmake b/cmake/modules/CheckAtomic.cmake index 8a58bf251c..cfe2583b47 100644 --- a/cmake/modules/CheckAtomic.cmake +++ b/cmake/modules/CheckAtomic.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/CheckFunctionExists.c b/cmake/modules/CheckFunctionExists.c index 0cd33af0db..42a695c59c 100644 --- a/cmake/modules/CheckFunctionExists.c +++ b/cmake/modules/CheckFunctionExists.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/cmake/modules/FindFFTW3F.cmake b/cmake/modules/FindFFTW3F.cmake index c6a3ff7279..13a690caf9 100644 --- a/cmake/modules/FindFFTW3F.cmake +++ b/cmake/modules/FindFFTW3F.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/FindLibConfig.cmake b/cmake/modules/FindLibConfig.cmake index d109c21175..ff8d7b022b 100644 --- a/cmake/modules/FindLibConfig.cmake +++ b/cmake/modules/FindLibConfig.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/FindLimeSDR.cmake b/cmake/modules/FindLimeSDR.cmake index 41c7e8ce1e..cd41c6c434 100644 --- a/cmake/modules/FindLimeSDR.cmake +++ b/cmake/modules/FindLimeSDR.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/FindMKL.cmake b/cmake/modules/FindMKL.cmake index 22de689e6b..f8885462bb 100644 --- a/cmake/modules/FindMKL.cmake +++ b/cmake/modules/FindMKL.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -28,31 +28,45 @@ find_path(MKL_INCLUDE_DIR NAMES mkl.h HINTS $ENV{MKL_DIR}/include + /opt/intel/oneapi/mkl/latest/include + /opt/intel/mkl/include + /usr/include/mkl PATHS) find_path(MKL_FFTW_INCLUDE_DIR NAMES fftw3.h HINTS $ENV{MKL_DIR}/include/fftw + /opt/intel/oneapi/mkl/latest/include/fftw + /opt/intel/mkl/include/fftw + /usr/include/mkl/fftw PATHS) find_library(MKL_LIBRARIES NAMES mkl_rt HINTS $ENV{MKL_DIR}/lib/intel64 + /opt/intel/oneapi/mkl/latest/lib/intel64 + /opt/intel/mkl/lib/intel64 PATHS) find_library(MKL_CORE NAMES libmkl_core.a HINTS $ENV{MKL_DIR}/lib/intel64 + /opt/intel/oneapi/mkl/latest/lib/intel64/ + /opt/intel/mkl/lib/intel64 PATHS) find_library(MKL_ILP NAMES libmkl_intel_ilp64.a HINTS $ENV{MKL_DIR}/lib/intel64 + /opt/intel/oneapi/mkl/latest/lib/intel64/ + /opt/intel/mkl/lib/intel64 PATHS) find_library(MKL_SEQ NAMES libmkl_sequential.a HINTS $ENV{MKL_DIR}/lib/intel64 + /opt/intel/oneapi/mkl/latest/lib/intel64/ + /opt/intel/mkl/lib/intel64 PATHS) set(MKL_STATIC_LIBRARIES -Wl,--start-group ${MKL_CORE} ${MKL_ILP} ${MKL_SEQ} -Wl,--end-group -lpthread -lm -ldl) @@ -61,7 +75,7 @@ set(MKL_INCLUDE_DIRS ${MKL_INCLUDE_DIR} ${MKL_FFTW_INCLUDE_DIR}) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set MKL_FOUND to TRUE # if all listed variables are TRUE -find_package_handle_standard_args(mkl DEFAULT_MSG +find_package_handle_standard_args(MKL DEFAULT_MSG MKL_LIBRARIES MKL_CORE MKL_ILP MKL_SEQ MKL_INCLUDE_DIRS) if(MKL_FOUND) diff --git a/cmake/modules/FindMbedTLS.cmake b/cmake/modules/FindMbedTLS.cmake index 2cc4508ff4..9874c21aae 100644 --- a/cmake/modules/FindMbedTLS.cmake +++ b/cmake/modules/FindMbedTLS.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/FindPCSCLite.cmake b/cmake/modules/FindPCSCLite.cmake index 7305baa4ba..73ac618313 100644 --- a/cmake/modules/FindPCSCLite.cmake +++ b/cmake/modules/FindPCSCLite.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/FindPolarssl.cmake b/cmake/modules/FindPolarssl.cmake deleted file mode 100644 index e305cacb7e..0000000000 --- a/cmake/modules/FindPolarssl.cmake +++ /dev/null @@ -1,73 +0,0 @@ -# -# Copyright 2013-2021 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/FindSCTP.cmake b/cmake/modules/FindSCTP.cmake index 37ef92a6a8..c96ffb9559 100644 --- a/cmake/modules/FindSCTP.cmake +++ b/cmake/modules/FindSCTP.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/FindSKIQ.cmake b/cmake/modules/FindSKIQ.cmake index 9835842fe3..3ba8370453 100644 --- a/cmake/modules/FindSKIQ.cmake +++ b/cmake/modules/FindSKIQ.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -18,7 +18,7 @@ # and at http://www.gnu.org/licenses/. # -INCLUDE(FindPkgConfig) +FIND_PACKAGE(PkgConfig REQUIRED) #PKG_CHECK_MODULES(SKIQ SKIQ) IF(NOT SKIQ_FOUND) @@ -26,7 +26,7 @@ FIND_PATH( SKIQ_INCLUDE_DIRS NAMES sidekiq_api.h HINTS $ENV{SKIQ_DIR}/inc - $ENV{SKIQ_DIR}/sidekiq_core/inc + $ENV{SKIQ_DIR}/sidekiq_core/inc PATHS /usr/local/include /usr/include ) @@ -66,7 +66,18 @@ FIND_LIBRARY( /usr/local/lib32 ) -set(SKIQ_LIBRARIES ${SKIQ_LIBRARY} ${SKIQ_LIBRARY_GLIB} ${SKIQ_LIBRARY_USB}) +FIND_LIBRARY( + SKIQ_LIBRARY_TIRPC + NAMES libtirpc.so.3 + PATHS /usr/local/lib + /usr/lib64 + /usr/lib/epiq + /usr/lib/x86_64-linux-gnu + /usr/local/lib64 + /usr/local/lib32 +) + +set(SKIQ_LIBRARIES ${SKIQ_LIBRARY} ${SKIQ_LIBRARY_GLIB} ${SKIQ_LIBRARY_USB} ${SKIQ_LIBRARY_TIRPC}) message(STATUS "SKIQ LIBRARIES " ${SKIQ_LIBRARIES}) message(STATUS "SKIQ INCLUDE DIRS " ${SKIQ_INCLUDE_DIRS}) diff --git a/cmake/modules/FindSRSGUI.cmake b/cmake/modules/FindSRSGUI.cmake index e576aa4d45..923df069ed 100644 --- a/cmake/modules/FindSRSGUI.cmake +++ b/cmake/modules/FindSRSGUI.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/FindSSE.cmake b/cmake/modules/FindSSE.cmake index 6596d371c5..e904d000d3 100644 --- a/cmake/modules/FindSSE.cmake +++ b/cmake/modules/FindSSE.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/FindSoapySDR.cmake b/cmake/modules/FindSoapySDR.cmake index 2bc965f38c..7b461eb1d4 100644 --- a/cmake/modules/FindSoapySDR.cmake +++ b/cmake/modules/FindSoapySDR.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -23,12 +23,11 @@ if(NOT SOAPYSDR_FOUND) pkg_check_modules (SOAPYSDR_PKG SoapySDR) find_path(SOAPYSDR_INCLUDE_DIRS - NAMES Device.h + NAMES SoapySDR/Device.h HINTS $ENV{SOAPY_DIR}/include - $ENV{SOAPY_DIR}/include/SoapySDR PATHS ${SOAPYSDR_PKG_INCLUDE_DIRS} - /usr/include/SoapySDR - /usr/local/include/SoapySDR + /usr/include + /usr/local/include ) find_library(SOAPYSDR_LIBRARIES diff --git a/cmake/modules/FindUHD.cmake b/cmake/modules/FindUHD.cmake index 47e9b4ff9e..cc8f306678 100644 --- a/cmake/modules/FindUHD.cmake +++ b/cmake/modules/FindUHD.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/FindZeroMQ.cmake b/cmake/modules/FindZeroMQ.cmake index 9b0abf37b7..ad1744a0e5 100644 --- a/cmake/modules/FindZeroMQ.cmake +++ b/cmake/modules/FindZeroMQ.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/FindbladeRF.cmake b/cmake/modules/FindbladeRF.cmake index a6b0ab7901..6de3281df5 100644 --- a/cmake/modules/FindbladeRF.cmake +++ b/cmake/modules/FindbladeRF.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/SRSRANPackage.cmake b/cmake/modules/SRSRANPackage.cmake index 571c0e4b23..01e86f48c7 100644 --- a/cmake/modules/SRSRANPackage.cmake +++ b/cmake/modules/SRSRANPackage.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/cmake/modules/SRSRANVersion.cmake b/cmake/modules/SRSRANVersion.cmake index cd9ace6451..faa788c433 100644 --- a/cmake/modules/SRSRANVersion.cmake +++ b/cmake/modules/SRSRANVersion.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -18,8 +18,8 @@ # and at http://www.gnu.org/licenses/. # -SET(SRSRAN_VERSION_MAJOR 21) -SET(SRSRAN_VERSION_MINOR 10) +SET(SRSRAN_VERSION_MAJOR 23) +SET(SRSRAN_VERSION_MINOR 04) 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/cmake/modules/SRSRANbuildinfo.cmake.in b/cmake/modules/SRSRANbuildinfo.cmake.in index 8cbea73256..e2ce712737 100644 --- a/cmake/modules/SRSRANbuildinfo.cmake.in +++ b/cmake/modules/SRSRANbuildinfo.cmake.in @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 2.6) execute_process( COMMAND git rev-parse --abbrev-ref HEAD diff --git a/debian/packager.sh b/debian/packager.sh index 3f66ff062e..13e8f80583 100755 --- a/debian/packager.sh +++ b/debian/packager.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index eab1ce491a..fa2012286b 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/examples/CMakeLists.txt b/lib/examples/CMakeLists.txt index 2581ede59b..d694af8bde 100644 --- a/lib/examples/CMakeLists.txt +++ b/lib/examples/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -66,7 +66,7 @@ endif(SRSGUI_FOUND) if (ZEROMQ_FOUND) add_executable(zmq_remote_rx zmq_remote_rx.c) - target_link_libraries(zmq_remote_rx srsran_phy srsran_rf) + target_link_libraries(zmq_remote_rx srsran_phy srsran_rf ${ZEROMQ_LIBRARIES}) endif (ZEROMQ_FOUND) ################################################################# diff --git a/lib/examples/cell_search.c b/lib/examples/cell_search.c index bcb7c3c2bd..68b49d4b09 100644 --- a/lib/examples/cell_search.c +++ b/lib/examples/cell_search.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/examples/cell_search_nbiot.c b/lib/examples/cell_search_nbiot.c index c7e9e39c68..6fe4948aee 100644 --- a/lib/examples/cell_search_nbiot.c +++ b/lib/examples/cell_search_nbiot.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/examples/npdsch_enodeb.c b/lib/examples/npdsch_enodeb.c index 5d7d04c377..e902234836 100644 --- a/lib/examples/npdsch_enodeb.c +++ b/lib/examples/npdsch_enodeb.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -44,6 +44,9 @@ #define HAVE_NPDSCH 1 #define NPDCCH_SF_IDX 1 +#define NOF_TX_ANT 1 + +#define MAX_SRATE_DELTA 2 // allowable delta (in Hz) between requested and actual sample rate static const uint8_t dummy_sib1_payload[] = {0x43, 0x4d, 0xd0, 0x92, 0x22, 0x06, 0x04, 0x30, 0x28, 0x6e, 0x87, 0xd0, 0x4b, 0x13, 0x90, 0xb4, 0x12, 0xa1, @@ -74,6 +77,7 @@ static uint32_t i_rep_val = 0; static char* rf_args = ""; static float rf_amp = 0.8, rf_gain = 70.0, rf_freq = 0; static float file_snr = -100.0; +static char* rf_dev = ""; static bool null_file_sink = false; static srsran_random_t* random_gen; @@ -92,22 +96,23 @@ static srsran_ra_nbiot_dl_dci_t ra_dl; static srsran_ra_nbiot_dl_dci_t ra_dl_sib1; static srsran_chest_dl_nbiot_t ch_est; static srsran_mib_nb_t mib_nb; -static uint32_t sched_info_tag = - 0; // according to Table 16.4.1.3-3 in 36.213, 0 means 4 NPDSCH repetitions with TBS 208 +static uint32_t sched_info_tag = 0; + // according to Table 16.4.1.3-3 in 36.213, 0 means 4 NPDSCH repetitions with TBS 208 static cf_t *sf_buffer = NULL, *output_buffer = NULL; static int sf_n_re = 0, sf_n_samples = 0; void usage(char* prog) { - printf("Usage: %s [agmiftlReosncvrpu]\n", prog); + printf("Usage: %s [aeOgfostmirnlRpv]\n", prog); #ifndef DISABLE_RF printf("\t-a RF args [Default %s]\n", rf_args); printf("\t-e RF amplitude [Default %.2f]\n", rf_amp); + printf("\t-O RF device [Default use RF board]\n"); printf("\t-g RF TX gain [Default %.2f dB]\n", rf_gain); printf("\t-f RF TX frequency [Default %.1f MHz]\n", rf_freq / 1000000); #else - printf("\t RF is disabled.\n"); + printf("\t RF is disabled!\n"); #endif printf("\t-o output_file [Default use RF board]\n"); printf("\t-s SNR-10 (only if output to file) [Default %f]\n", file_snr); @@ -125,7 +130,7 @@ void usage(char* prog) void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "aglfmiosncrtvpuR")) != -1) { + while ((opt = getopt(argc, argv, "aeOgfostmirnlRpv")) != -1) { switch (opt) { case 'a': rf_args = argv[optind]; @@ -136,6 +141,9 @@ void parse_args(int argc, char** argv) case 'e': rf_amp = strtof(argv[optind], NULL); break; + case 'O': + rf_dev = argv[optind]; + break; case 'f': rf_freq = strtof(argv[optind], NULL); break; @@ -148,12 +156,12 @@ void parse_args(int argc, char** argv) case 't': sched_info_tag = (uint32_t)strtol(argv[optind], NULL, 10); break; - case 'm': - i_tbs_val = (uint32_t)strtol(argv[optind], NULL, 10); - break; case 'i': i_sf_val = (uint32_t)strtol(argv[optind], NULL, 10); break; + case 'm': + i_tbs_val = (uint32_t)strtol(argv[optind], NULL, 10); + break; case 'r': i_rep_val = (uint32_t)strtol(argv[optind], NULL, 10); break; @@ -180,7 +188,7 @@ void parse_args(int argc, char** argv) if (!output_file_name && rf_freq == 0) { usage(argv[0]); - printf("\nError! Either RF frequency or output filename need to be specified.\n"); + printf("\nError: either RF frequency or output filename needs to be specified\n"); exit(-1); } @@ -197,12 +205,12 @@ void base_init() // init memory sf_buffer = srsran_vec_cf_malloc(sf_n_re); if (!sf_buffer) { - perror("malloc"); + perror("Error: malloc for sf_buffer"); exit(-1); } output_buffer = srsran_vec_cf_malloc(sf_n_samples); if (!output_buffer) { - perror("malloc"); + perror("Error: malloc for output buffer"); exit(-1); } // open file or USRP @@ -218,13 +226,17 @@ void base_init() } } else { #ifndef DISABLE_RF - printf("Opening RF device...\n"); - if (srsran_rf_open(&radio, rf_args)) { - fprintf(stderr, "Error opening rf\n"); - exit(-1); + if (strlen(rf_dev) > 0) { + if (srsran_rf_open_devname(&radio, rf_dev, rf_args, NOF_TX_ANT)) { + fprintf(stderr, "Error opening RF device %s\n", rf_dev); + exit(-1); + } + } else if (srsran_rf_open(&radio, rf_args)) { + fprintf(stderr, "Error opening RF default device\n"); + exit(-1); } #else - printf("Error RF not available. Select an output file\n"); + printf("Error: RF not available - select an output file\n"); exit(-1); #endif } @@ -355,7 +367,7 @@ static int update_radl(void) srsran_ra_nbiot_dl_dci_to_grant(&ra_dl, &dummy_grant, DUMMY_SFN, DUMMY_SFIDX, DUMMY_R_MAX, false, cell.mode); srsran_ra_nbiot_dl_grant_to_nbits(&dummy_grant, cell, 0, &dummy_nbits); srsran_ra_nbiot_dl_grant_fprint(stdout, &dummy_grant); - printf("Type new MCS index and press Enter: "); + printf("Enter new MCS index: "); fflush(stdout); return SRSRAN_SUCCESS; @@ -382,7 +394,7 @@ static int update_control(void) i_tbs_val = atoi(input); bzero(input, sizeof(input)); if (update_radl()) { - printf("Trying with last known MCS index\n"); + printf("Trying last known MCS index\n"); i_tbs_val = last_i_tbs_val; return update_radl(); } @@ -390,7 +402,7 @@ static int update_control(void) return 0; } else if (n < 0) { // error - perror("select"); + perror("Error: select for MCS entry"); return -1; } else { return 0; @@ -459,7 +471,7 @@ int main(int argc, char** argv) } if (srsran_nbiot_ue_dl_set_cell(&ue_dl, cell)) { - fprintf(stderr, "Setting cell in UE DL\n"); + fprintf(stderr, "Error setting cell in UE DL\n"); return -1; } @@ -498,16 +510,17 @@ int main(int argc, char** argv) signal(SIGINT, sig_int_handler); if (!output_file_name) { + /* set sampling frequency */ int srate = srsran_sampling_freq_hz(cell.base.nof_prb); if (srate != -1) { - printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); + printf("Setting tx sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_tx_srate(&radio, (double)srate); - if (srate_rf != srate) { - fprintf(stderr, "Could not set sampling rate\n"); + if (abs(srate - (int)srate_rf) > MAX_SRATE_DELTA) { + ERROR("Could not set tx sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } } else { - fprintf(stderr, "Invalid number of PRB %d\n", cell.base.nof_prb); + fprintf(stderr, "Error: invalid number of PRB %d\n", cell.base.nof_prb); exit(-1); } srsran_rf_set_tx_gain(&radio, rf_gain); @@ -517,6 +530,7 @@ int main(int argc, char** argv) #endif if (update_radl()) { + fprintf(stderr, "Error updating radl\n"); exit(-1); } @@ -599,7 +613,7 @@ int main(int argc, char** argv) } if (srsran_nbiot_ue_dl_is_sib1_sf(&ue_dl, sfn, sf_idx)) { - INFO("%d.%d: Transmitting SIB1-NB.", sfn, sf_idx); + INFO("%d.%d: Transmitting SIB1-NB", sfn, sf_idx); assert(send_data == false); // configure DL grant for SIB1-NB transmission @@ -692,10 +706,9 @@ int main(int argc, char** argv) // find the noise spectral density float snr_lin = srsran_convert_dB_to_power(file_snr); float n0 = abs_avg / snr_lin; - float nstd = sqrtf(n0 / 2); // add some noise to the signal - srsran_ch_awgn_c(output_buffer, output_buffer, nstd, sf_n_samples); + srsran_ch_awgn_c(output_buffer, output_buffer, n0, sf_n_samples); } /* send to file or usrp */ @@ -724,7 +737,7 @@ int main(int argc, char** argv) base_free(); - printf("Done\n"); + printf("%s done\n", argv[0]); return SRSRAN_SUCCESS; } diff --git a/lib/examples/npdsch_ue.c b/lib/examples/npdsch_ue.c index 3dcebfb7b7..a1e676dedf 100644 --- a/lib/examples/npdsch_ue.c +++ b/lib/examples/npdsch_ue.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/examples/npdsch_ue_helper.cc b/lib/examples/npdsch_ue_helper.cc index 24121bc88d..611c908690 100644 --- a/lib/examples/npdsch_ue_helper.cc +++ b/lib/examples/npdsch_ue_helper.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/examples/npdsch_ue_helper.h b/lib/examples/npdsch_ue_helper.h index 26b6d725e8..53956bee54 100644 --- a/lib/examples/npdsch_ue_helper.h +++ b/lib/examples/npdsch_ue_helper.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index 44251303e1..44938ebb3b 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,6 +22,7 @@ #include "srsran/common/crash_handler.h" #include "srsran/common/gen_mch_tables.h" #include "srsran/srsran.h" +#include #include #include #include @@ -52,6 +53,14 @@ static char* output_file_name = NULL; #define PAGE_UP 53 #define PAGE_DOWN 54 +#define CFR_THRES_UP_KEY 't' +#define CFR_THRES_DN_KEY 'g' + +#define CFR_THRES_STEP 0.05f +#define CFR_PAPR_STEP 0.1f + +#define MAX_SRATE_DELTA 2 // allowable delta (in Hz) between requested and actual sample rate + static srsran_cell_t cell = { 25, // nof_prb 1, // nof_ports @@ -79,6 +88,27 @@ static bool enable_256qam = false; static float output_file_snr = +INFINITY; static bool use_standard_lte_rate = false; + +// CFR runtime control flags +static bool cfr_thr_inc = false; +static bool cfr_thr_dec = false; + +typedef struct { + int enable; + char* mode; + float manual_thres; + float strength; + float auto_target_papr; + float ema_alpha; +} cfr_args_t; + +static cfr_args_t cfr_args = {.enable = 0, + .mode = "manual", + .manual_thres = 1.0f, + .strength = 1.0f, + .auto_target_papr = 8.0f, + .ema_alpha = 1.0f / (float)SRSRAN_CP_NORM_NSYMB}; + static bool null_file_sink = false; static srsran_filesink_t fsink; static srsran_ofdm_t ifft[SRSRAN_MAX_PORTS]; @@ -94,6 +124,7 @@ static srsran_softbuffer_tx_t* softbuffers[SRSRAN_MAX_CODEWORDS]; static srsran_regs_t regs; static srsran_dci_dl_t dci_dl; static int rvidx[SRSRAN_MAX_CODEWORDS] = {0, 0}; +static srsran_cfr_cfg_t cfr_config = {}; static cf_t * sf_buffer[SRSRAN_MAX_PORTS] = {NULL}, *output_buffer[SRSRAN_MAX_PORTS] = {NULL}; static uint32_t sf_n_re, sf_n_samples; @@ -143,14 +174,28 @@ static void usage(char* prog) printf("\t-s output file SNR [Default %f]\n", output_file_snr); printf("\t-q Enable/Disable 256QAM modulation (default %s)\n", enable_256qam ? "enabled" : "disabled"); printf("\t-Q Use standard LTE sample rates (default %s)\n", use_standard_lte_rate ? "enabled" : "disabled"); + printf("CFR Options:\n"); + printf("\t--enable_cfr Enable the CFR (default %s)\n", cfr_args.enable ? "enabled" : "disabled"); + printf("\t--cfr_mode CFR mode: manual, auto_cma, auto_ema. (default %s)\n", cfr_args.mode); + printf("\t--cfr_manual_thres CFR manual threshold (default %.2f)\n", cfr_args.manual_thres); + printf("\t--cfr_strength CFR strength (default %.2f)\n", cfr_args.strength); + printf("\t--cfr_auto_papr CFR PAPR target for auto modes (default %.2f)\n", cfr_args.auto_target_papr); + printf("\t--cfr_ema_alpha CFR alpha parameter for EMA mode (default %.2f)\n", cfr_args.ema_alpha); printf("\n"); printf("\t*: See 3GPP 36.212 Table 5.3.3.1.5-4 for more information\n"); } +struct option cfr_opts[] = {{"enable_cfr", no_argument, &cfr_args.enable, 1}, + {"cfr_mode", required_argument, NULL, 'C'}, + {"cfr_manual_thres", required_argument, NULL, 'T'}, + {"cfr_strength", required_argument, NULL, 'S'}, + {"cfr_auto_papr", required_argument, NULL, 'P'}, + {"cfr_ema_alpha", required_argument, NULL, 'e'}, + {0, 0, 0, 0}}; static void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "IadglfmoncpqvutxbwMsBQ")) != -1) { + while ((opt = getopt_long(argc, argv, "IadglfmoncpqvutxbwMsBQ", cfr_opts, NULL)) != -1) { switch (opt) { case 'I': rf_dev = argv[optind]; @@ -215,6 +260,24 @@ static void parse_args(int argc, char** argv) case 'E': cell.cp = SRSRAN_CP_EXT; break; + case 'C': + cfr_args.mode = optarg; + break; + case 'T': + cfr_args.manual_thres = strtof(optarg, NULL); + break; + case 'S': + cfr_args.strength = strtof(optarg, NULL); + break; + case 'P': + cfr_args.auto_target_papr = strtof(optarg, NULL); + break; + case 'e': + cfr_args.ema_alpha = strtof(optarg, NULL); + break; + case 0: + /* getopt_long() set a variable, keep going */ + break; default: usage(argv[0]); exit(-1); @@ -228,6 +291,27 @@ static void parse_args(int argc, char** argv) #endif } +static int parse_cfr_args() +{ + cfr_config.cfr_enable = cfr_args.enable; + cfr_config.manual_thr = cfr_args.manual_thres; + cfr_config.max_papr_db = cfr_args.auto_target_papr; + cfr_config.alpha = cfr_args.strength; + cfr_config.ema_alpha = cfr_args.ema_alpha; + + cfr_config.cfr_mode = srsran_cfr_str2mode(cfr_args.mode); + if (cfr_config.cfr_mode == SRSRAN_CFR_THR_INVALID) { + ERROR("CFR mode not recognised"); + return SRSRAN_ERROR; + } + + if (!srsran_cfr_params_valid(&cfr_config)) { + ERROR("Invalid CFR parameters"); + return SRSRAN_ERROR; + } + return SRSRAN_SUCCESS; +} + static void base_init() { int i; @@ -325,6 +409,10 @@ static void base_init() } srsran_ofdm_set_normalize(&ifft[i], true); + if (srsran_ofdm_set_cfr(&ifft[i], &cfr_config)) { + ERROR("Error setting CFR object"); + exit(-1); + } } if (srsran_ofdm_tx_init_mbsfn(&ifft_mbsfn, SRSRAN_CP_EXT, sf_buffer[0], output_buffer[0], cell.nof_prb)) { @@ -333,6 +421,10 @@ static void base_init() } srsran_ofdm_set_non_mbsfn_region(&ifft_mbsfn, 2); srsran_ofdm_set_normalize(&ifft_mbsfn, true); + if (srsran_ofdm_set_cfr(&ifft_mbsfn, &cfr_config)) { + ERROR("Error setting CFR object"); + exit(-1); + } if (srsran_pbch_init(&pbch)) { ERROR("Error creating PBCH object"); @@ -483,6 +575,8 @@ static int update_radl() { ZERO_OBJECT(dci_dl); + int ret = SRSRAN_ERROR; + /* Configure cell and PDSCH in function of the transmission mode */ switch (transmission_mode) { case SRSRAN_TM1: @@ -505,7 +599,7 @@ static int update_radl() break; default: ERROR("Transmission mode not implemented."); - exit(-1); + goto exit; } dci_dl.rnti = UE_CRNTI; @@ -526,7 +620,80 @@ static int update_radl() SRSRAN_DCI_TB_DISABLE(dci_dl.tb[1]); } + // Increase the CFR threshold or target PAPR + if (cfr_thr_inc) { + cfr_thr_inc = false; // Reset the flag + if (cfr_config.cfr_enable && cfr_config.cfr_mode == SRSRAN_CFR_THR_MANUAL) { + cfr_config.manual_thr += CFR_THRES_STEP; + for (int i = 0; i < cell.nof_ports; i++) { + if (srsran_cfr_set_threshold(&ifft[i].tx_cfr, cfr_config.manual_thr) < SRSRAN_SUCCESS) { + ERROR("Setting the CFR"); + goto exit; + } + } + if (srsran_cfr_set_threshold(&ifft_mbsfn.tx_cfr, cfr_config.manual_thr) < SRSRAN_SUCCESS) { + ERROR("Setting the CFR"); + goto exit; + } + printf("CFR Thres. set to %.3f\n", cfr_config.manual_thr); + } else if (cfr_config.cfr_enable && cfr_config.cfr_mode != SRSRAN_CFR_THR_MANUAL) { + cfr_config.max_papr_db += CFR_PAPR_STEP; + for (int i = 0; i < cell.nof_ports; i++) { + if (srsran_cfr_set_papr(&ifft[i].tx_cfr, cfr_config.max_papr_db) < SRSRAN_SUCCESS) { + ERROR("Setting the CFR"); + goto exit; + } + } + if (srsran_cfr_set_papr(&ifft_mbsfn.tx_cfr, cfr_config.max_papr_db) < SRSRAN_SUCCESS) { + ERROR("Setting the CFR"); + goto exit; + } + printf("CFR target PAPR set to %.3f\n", cfr_config.max_papr_db); + } + } + + // Decrease the CFR threshold or target PAPR + if (cfr_thr_dec) { + cfr_thr_dec = false; // Reset the flag + if (cfr_config.cfr_enable && cfr_config.cfr_mode == SRSRAN_CFR_THR_MANUAL) { + if (cfr_config.manual_thr - CFR_THRES_STEP >= 0) { + cfr_config.manual_thr -= CFR_THRES_STEP; + for (int i = 0; i < cell.nof_ports; i++) { + if (srsran_cfr_set_threshold(&ifft[i].tx_cfr, cfr_config.manual_thr) < SRSRAN_SUCCESS) { + ERROR("Setting the CFR"); + goto exit; + } + } + if (srsran_cfr_set_threshold(&ifft_mbsfn.tx_cfr, cfr_config.manual_thr) < SRSRAN_SUCCESS) { + ERROR("Setting the CFR"); + goto exit; + } + printf("CFR Thres. set to %.3f\n", cfr_config.manual_thr); + } + } else if (cfr_config.cfr_enable && cfr_config.cfr_mode != SRSRAN_CFR_THR_MANUAL) { + if (cfr_config.max_papr_db - CFR_PAPR_STEP >= 0) { + cfr_config.max_papr_db -= CFR_PAPR_STEP; + for (int i = 0; i < cell.nof_ports; i++) { + if (srsran_cfr_set_papr(&ifft[i].tx_cfr, cfr_config.max_papr_db) < SRSRAN_SUCCESS) { + ERROR("Setting the CFR"); + goto exit; + } + } + if (srsran_cfr_set_papr(&ifft_mbsfn.tx_cfr, cfr_config.max_papr_db) < SRSRAN_SUCCESS) { + ERROR("Setting the CFR"); + goto exit; + } + printf("CFR target PAPR set to %.3f\n", cfr_config.max_papr_db); + } + } + } + srsran_dci_dl_fprint(stdout, &dci_dl, cell.nof_prb); + printf("\nCFR controls:\n"); + printf(" Param | INC | DEC |\n"); + printf("------------+-----+-----+\n"); + printf(" Thres/PAPR | %c | %c |\n", CFR_THRES_UP_KEY, CFR_THRES_DN_KEY); + printf("\n"); if (transmission_mode != SRSRAN_TM1) { printf("\nTransmission mode key table:\n"); printf(" Mode | 1TB | 2TB |\n"); @@ -535,13 +702,15 @@ static int update_radl() printf(" CDD | | z |\n"); printf("Multiplex | q,w,e,r | a,s |\n"); printf("\n"); - printf("Type new MCS index (0-28) or mode key and press Enter: "); + printf("Type new MCS index (0-28) or cfr/mode key and press Enter: "); } else { - printf("Type new MCS index (0-28) and press Enter: "); + printf("Type new MCS index (0-28) or cfr key and press Enter: "); } fflush(stdout); + ret = SRSRAN_SUCCESS; - return 0; +exit: + return ret; } /* Read new MCS from stdin */ @@ -635,6 +804,12 @@ static int update_control() case 'x': transmission_mode = SRSRAN_TM2; break; + case CFR_THRES_UP_KEY: + cfr_thr_inc = true; + break; + case CFR_THRES_DN_KEY: + cfr_thr_dec = true; + break; default: last_mcs_idx = mcs_idx; mcs_idx = strtol(input, NULL, 10); @@ -652,9 +827,9 @@ static int update_control() } else if (n < 0) { // error perror("select"); - return -1; + return SRSRAN_ERROR; } else { - return 0; + return SRSRAN_SUCCESS; } } @@ -728,6 +903,10 @@ int main(int argc, char** argv) #endif parse_args(argc, argv); + if (parse_cfr_args() < SRSRAN_SUCCESS) { + ERROR("Error parsing CFR args"); + exit(-1); + } srsran_use_standard_symbol_size(use_standard_lte_rate); @@ -788,12 +967,13 @@ int main(int argc, char** argv) signal(SIGINT, sig_int_handler); if (!output_file_name) { + /* set sampling frequency */ int srate = srsran_sampling_freq_hz(cell.nof_prb); if (srate != -1) { - printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); + printf("Setting tx sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_tx_srate(&radio, (double)srate); - if (srate_rf != srate) { - ERROR("Could not set sampling rate"); + if (abs(srate - (int)srate_rf) > MAX_SRATE_DELTA) { + ERROR("Could not set tx sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } } else { @@ -882,7 +1062,7 @@ int main(int argc, char** argv) srsran_pcfich_encode(&pcfich, &dl_sf, sf_symbols); /* Update DL resource allocation from control port */ - if (update_control()) { + if (update_control() < SRSRAN_SUCCESS) { ERROR("Error updating parameters from control port"); } @@ -1001,7 +1181,7 @@ int main(int argc, char** argv) if (!null_file_sink) { /* Apply AWGN */ if (output_file_snr != +INFINITY) { - float var = srsran_convert_dB_to_amplitude(-(output_file_snr + 3.0f)); + float var = srsran_convert_dB_to_power(-output_file_snr); for (int k = 0; k < cell.nof_ports; k++) { srsran_ch_awgn_c(output_buffer[k], output_buffer[k], var, sf_n_samples); } diff --git a/lib/examples/pdsch_ue.c b/lib/examples/pdsch_ue.c index 03d26c8f04..0e8d3a2084 100644 --- a/lib/examples/pdsch_ue.c +++ b/lib/examples/pdsch_ue.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -38,6 +38,8 @@ #define ENABLE_AGC_DEFAULT +#define MAX_SRATE_DELTA 2 // allowable delta (in Hz) between requested and actual sample rate + #ifndef DISABLE_RF #include "srsran/phy/rf/rf.h" @@ -484,7 +486,7 @@ int main(int argc, char** argv) signal(SIGINT, sig_int_handler); /* set receiver frequency */ - printf("Tunning receiver to %.3f MHz\n", (prog_args.rf_freq + prog_args.file_offset_freq) / 1000000); + printf("Tuning receiver to %.3f MHz\n", (prog_args.rf_freq + prog_args.file_offset_freq) / 1000000); srsran_rf_set_rx_freq(&rf, prog_args.rf_nof_rx_ant, prog_args.rf_freq + prog_args.file_offset_freq); uint32_t ntrial = 0; @@ -495,7 +497,7 @@ int main(int argc, char** argv) ERROR("Error searching for cell"); exit(-1); } else if (ret == 0 && !go_exit) { - printf("Cell not found after %d trials. Trying again (Press Ctrl+C to exit)\n", ntrial++); + printf("Cell not found after [%4d] attempts. Trying again... (Ctrl+C to exit)\n", ntrial++); } } while (ret == 0 && !go_exit); @@ -507,10 +509,10 @@ int main(int argc, char** argv) /* set sampling frequency */ int srate = srsran_sampling_freq_hz(cell.nof_prb); if (srate != -1) { - printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); + printf("Setting rx sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_rx_srate(&rf, (double)srate); - if (srate_rf != srate) { - ERROR("Could not set sampling rate"); + if (abs(srate - (int)srate_rf) > MAX_SRATE_DELTA) { + ERROR("Could not set rx sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } } else { @@ -640,7 +642,7 @@ int main(int argc, char** argv) #ifdef ENABLE_GUI if (!prog_args.disable_plots) { - init_plots(cell); + init_plots(); sleep(1); } #endif /* ENABLE_GUI */ diff --git a/lib/examples/pssch_ue.c b/lib/examples/pssch_ue.c index d45ccb428a..f42e8a8fd8 100644 --- a/lib/examples/pssch_ue.c +++ b/lib/examples/pssch_ue.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -43,6 +43,8 @@ #define PCAP_FILENAME "/tmp/pssch.pcap" +#define MAX_SRATE_DELTA 2 // allowable delta (in Hz) between requested and actual sample rate + static bool keep_running = true; static srsran_cell_sl_t cell_sl = {.nof_prb = 50, .tm = SRSRAN_SIDELINK_TM4, .cp = SRSRAN_CP_NORM, .N_sl_id = 0}; @@ -65,13 +67,12 @@ typedef struct { void args_default(prog_args_t* args) { - args->disable_plots = false; args->use_standard_lte_rates = false; + args->disable_plots = false; args->input_file_name = NULL; args->file_start_sf_idx = 0; args->nof_rx_antennas = 1; args->rf_dev = ""; - args->rf_dev = ""; args->rf_args = ""; args->rf_freq = 5.92e9; args->rf_gain = 50; @@ -263,13 +264,14 @@ int main(int argc, char** argv) printf("Set RX freq: %.6f MHz\n", srsran_rf_set_rx_freq(&radio, prog_args.nof_rx_antennas, prog_args.rf_freq) / 1e6); printf("Set RX gain: %.1f dB\n", prog_args.rf_gain); - int srate = srsran_sampling_freq_hz(cell_sl.nof_prb); + /* set sampling frequency */ + int srate = srsran_sampling_freq_hz(cell_sl.nof_prb); if (srate != -1) { printf("Setting sampling rate %.2f MHz\n", (float)srate / 1000000); float srate_rf = srsran_rf_set_rx_srate(&radio, (double)srate); - if (srate_rf != srate) { - ERROR("Could not set sampling rate"); + if (abs(srate - (int)srate_rf) > MAX_SRATE_DELTA) { + ERROR("Could not set sampling rate : wanted %d got %f", srate, srate_rf); exit(-1); } } else { @@ -303,7 +305,7 @@ int main(int argc, char** argv) cf_t* equalized_sf_buffer = srsran_vec_malloc(sizeof(cf_t) * sf_n_re); // RX - srsran_ofdm_t fft[SRSRAN_MAX_PORTS]; + srsran_ofdm_t fft[SRSRAN_MAX_PORTS] = {}; srsran_ofdm_cfg_t ofdm_cfg = {}; ofdm_cfg.nof_prb = cell_sl.nof_prb; ofdm_cfg.cp = SRSRAN_CP_NORM; @@ -392,7 +394,7 @@ int main(int argc, char** argv) #ifdef ENABLE_GUI if (!prog_args.disable_plots) { - init_plots(&pscch); + init_plots(); sleep(1); } #endif diff --git a/lib/examples/synch_file.c b/lib/examples/synch_file.c index 8d8bdf9506..e32c55c355 100644 --- a/lib/examples/synch_file.c +++ b/lib/examples/synch_file.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/examples/test/CMakeLists.txt b/lib/examples/test/CMakeLists.txt index 3fef66e28e..9f29aaae2d 100644 --- a/lib/examples/test/CMakeLists.txt +++ b/lib/examples/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/examples/test/iqtests.cmake b/lib/examples/test/iqtests.cmake index 6787908e51..3a3d07dfe5 100644 --- a/lib/examples/test/iqtests.cmake +++ b/lib/examples/test/iqtests.cmake @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/examples/usrp_capture.c b/lib/examples/usrp_capture.c index 392cb5ee15..4298aa8af1 100644 --- a/lib/examples/usrp_capture.c +++ b/lib/examples/usrp_capture.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/examples/usrp_capture_sync.c b/lib/examples/usrp_capture_sync.c index aa961d7569..282cec33ba 100644 --- a/lib/examples/usrp_capture_sync.c +++ b/lib/examples/usrp_capture_sync.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/examples/usrp_capture_sync_nbiot.c b/lib/examples/usrp_capture_sync_nbiot.c index cd5d49a510..423c5a3828 100644 --- a/lib/examples/usrp_capture_sync_nbiot.c +++ b/lib/examples/usrp_capture_sync_nbiot.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/examples/usrp_txrx.c b/lib/examples/usrp_txrx.c index a41fa8ec85..af21c6f52e 100644 --- a/lib/examples/usrp_txrx.c +++ b/lib/examples/usrp_txrx.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/examples/zmq_remote_rx.c b/lib/examples/zmq_remote_rx.c index a36dc2c1b5..c3b2d91ac3 100644 --- a/lib/examples/zmq_remote_rx.c +++ b/lib/examples/zmq_remote_rx.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/CMakeLists.txt b/lib/include/CMakeLists.txt index 586bda2dff..6a844fd945 100644 --- a/lib/include/CMakeLists.txt +++ b/lib/include/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/include/srsran/CMakeLists.txt b/lib/include/srsran/CMakeLists.txt index 666ffb9a41..f8ccaf19be 100644 --- a/lib/include/srsran/CMakeLists.txt +++ b/lib/include/srsran/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/include/srsran/adt/accumulators.h b/lib/include/srsran/adt/accumulators.h index 9cf9d76f31..7283362c41 100644 --- a/lib/include/srsran/adt/accumulators.h +++ b/lib/include/srsran/adt/accumulators.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/bounded_bitset.h b/lib/include/srsran/adt/bounded_bitset.h index 1926e21309..a01bdba140 100644 --- a/lib/include/srsran/adt/bounded_bitset.h +++ b/lib/include/srsran/adt/bounded_bitset.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/bounded_vector.h b/lib/include/srsran/adt/bounded_vector.h index c543445e68..d7ed95cfb4 100644 --- a/lib/include/srsran/adt/bounded_vector.h +++ b/lib/include/srsran/adt/bounded_vector.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/choice_type.h b/lib/include/srsran/adt/choice_type.h index 3ee27d4253..12fcd37d1d 100644 --- a/lib/include/srsran/adt/choice_type.h +++ b/lib/include/srsran/adt/choice_type.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/circular_array.h b/lib/include/srsran/adt/circular_array.h index 6874f48baa..22d5f5e44f 100644 --- a/lib/include/srsran/adt/circular_array.h +++ b/lib/include/srsran/adt/circular_array.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/circular_buffer.h b/lib/include/srsran/adt/circular_buffer.h index 67682b6706..7414dd9897 100644 --- a/lib/include/srsran/adt/circular_buffer.h +++ b/lib/include/srsran/adt/circular_buffer.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -300,7 +300,7 @@ class base_blocking_queue } return obj; } - bool pop_wait_until(T& obj, const std::chrono::system_clock::time_point& until) { return pop_(obj, true, &until); } + bool pop_wait_until(T& obj, const std::chrono::steady_clock::time_point& until) { return pop_(obj, true, &until); } void clear() { T obj; @@ -414,7 +414,7 @@ class base_blocking_queue return {}; } - bool pop_(T& obj, bool block, const std::chrono::system_clock::time_point* until = nullptr) + bool pop_(T& obj, bool block, const std::chrono::steady_clock::time_point* until = nullptr) { std::unique_lock lock(mutex); if (not active) { diff --git a/lib/include/srsran/adt/circular_map.h b/lib/include/srsran/adt/circular_map.h index eee22a67db..b3f3745dfa 100644 --- a/lib/include/srsran/adt/circular_map.h +++ b/lib/include/srsran/adt/circular_map.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/detail/index_sequence.h b/lib/include/srsran/adt/detail/index_sequence.h index 9825ab8108..4360705295 100644 --- a/lib/include/srsran/adt/detail/index_sequence.h +++ b/lib/include/srsran/adt/detail/index_sequence.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/detail/type_storage.h b/lib/include/srsran/adt/detail/type_storage.h index 9f98bef2b7..282b1929e8 100644 --- a/lib/include/srsran/adt/detail/type_storage.h +++ b/lib/include/srsran/adt/detail/type_storage.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -79,11 +79,9 @@ void copy_if_present_helper(type_storage& lhs, { if (lhs_present and rhs_present) { lhs.get() = rhs.get(); - } - if (lhs_present) { + } else if (lhs_present) { lhs.destroy(); - } - if (rhs_present) { + } else if (rhs_present) { lhs.copy_ctor(rhs); } } @@ -96,11 +94,9 @@ void move_if_present_helper(type_storage& lhs, { if (lhs_present and rhs_present) { lhs.move_assign(std::move(rhs)); - } - if (lhs_present) { + } else if (lhs_present) { lhs.destroy(); - } - if (rhs_present) { + } else if (rhs_present) { lhs.move_ctor(std::move(rhs)); } } diff --git a/lib/include/srsran/adt/detail/type_utils.h b/lib/include/srsran/adt/detail/type_utils.h index 961bc1ee36..c6b3a5c33c 100644 --- a/lib/include/srsran/adt/detail/type_utils.h +++ b/lib/include/srsran/adt/detail/type_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/expected.h b/lib/include/srsran/adt/expected.h index 16e1b94753..8d378e3ce2 100644 --- a/lib/include/srsran/adt/expected.h +++ b/lib/include/srsran/adt/expected.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/fsm.h b/lib/include/srsran/adt/fsm.h index a385cd5ae0..ba1add5563 100644 --- a/lib/include/srsran/adt/fsm.h +++ b/lib/include/srsran/adt/fsm.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -341,6 +341,9 @@ class base_fsm_t constexpr static void (Derived::*react_fn)(SrcState&, const Event&) = ReactFn; constexpr static bool (Derived::*guard_fn)(SrcState&, const Event&) = GuardFn; + // ignore warning "never nullptr" for template specialization w/wo defaults for ReactFn or GuardFn + _Pragma("GCC diagnostic push"); // save current diagnostic config + _Pragma("GCC diagnostic ignored \"-Waddress\""); // ignore -Waddress static bool react(derived_view* f, src_state_t& s, const event_t& ev) { if (guard_fn == nullptr or (f->*guard_fn)(s, ev)) { @@ -351,6 +354,7 @@ class base_fsm_t } return false; } + _Pragma("GCC diagnostic pop"); // restore diagnostic config template using is_match = std::is_same, type_list >; @@ -372,6 +376,9 @@ class base_fsm_t constexpr static void (Derived::*react_fn)(const Event&) = ReactFn; constexpr static bool (Derived::*guard_fn)(const Event&) = GuardFn; + // ignore warning "never nullptr" for template specialization w/wo defaults for ReactFn or GuardFn + _Pragma("GCC diagnostic push"); // save current diagnostic config + _Pragma("GCC diagnostic ignored \"-Waddress\""); // ignore -Waddress template static bool react(derived_view* f, SrcState& s, const event_t& ev) { @@ -383,6 +390,7 @@ class base_fsm_t } return false; } + _Pragma("GCC diagnostic pop"); // restore diagnostic config template using is_match = std::is_same; diff --git a/lib/include/srsran/adt/interval.h b/lib/include/srsran/adt/interval.h index e09798a5cb..274f30ecde 100644 --- a/lib/include/srsran/adt/interval.h +++ b/lib/include/srsran/adt/interval.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -86,6 +86,17 @@ class interval bool contains(T point) const { return start_ <= point and point < stop_; } + interval& intersect(const interval& other) + { + if (not overlaps(other)) { + *this = interval{}; + } else { + start_ = std::max(start(), other.start()); + stop_ = std::min(stop(), other.stop()); + } + return *this; + } + private: T start_; T stop_; diff --git a/lib/include/srsran/adt/intrusive_list.h b/lib/include/srsran/adt/intrusive_list.h index beb7985246..186a9829c8 100644 --- a/lib/include/srsran/adt/intrusive_list.h +++ b/lib/include/srsran/adt/intrusive_list.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/move_callback.h b/lib/include/srsran/adt/move_callback.h index e61d212b87..65542e14e2 100644 --- a/lib/include/srsran/adt/move_callback.h +++ b/lib/include/srsran/adt/move_callback.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/observer.h b/lib/include/srsran/adt/observer.h index 480c7a68e6..e190a883ed 100644 --- a/lib/include/srsran/adt/observer.h +++ b/lib/include/srsran/adt/observer.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/optional.h b/lib/include/srsran/adt/optional.h index 2eb946abab..0f5283f8d3 100644 --- a/lib/include/srsran/adt/optional.h +++ b/lib/include/srsran/adt/optional.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/optional_array.h b/lib/include/srsran/adt/optional_array.h index 630f6173d3..d58ce9fd1e 100644 --- a/lib/include/srsran/adt/optional_array.h +++ b/lib/include/srsran/adt/optional_array.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -41,7 +41,8 @@ class base_optional_span template class iterator_impl { - using It = iterator_impl; + using It = iterator_impl; + using parent_t = typename std::conditional::value, const base_t, base_t>::type; public: using iterator_category = std::forward_iterator_tag; @@ -51,7 +52,7 @@ class base_optional_span using reference = Obj&; iterator_impl() = default; - iterator_impl(base_t* parent_, size_t idx_) : parent(parent_), idx(idx_) + iterator_impl(parent_t* parent_, size_t idx_) : parent(parent_), idx(idx_) { if (idx < parent->vec.size() and not parent->contains(idx)) { ++(*this); @@ -80,8 +81,8 @@ class base_optional_span private: friend base_t; - base_t* parent = nullptr; - size_t idx = std::numeric_limits::max(); + parent_t* parent = nullptr; + size_t idx = std::numeric_limits::max(); }; size_t nof_elems = 0; @@ -92,6 +93,10 @@ class base_optional_span using iterator = iterator_impl; using const_iterator = iterator_impl; + base_optional_span() = default; + base_optional_span(Vec&& v, size_t nof_elems_) : vec(std::move(v)), nof_elems(nof_elems_) {} + base_optional_span(const Vec& v, size_t nof_elems_) : vec(v), nof_elems(nof_elems_) {} + // Find first position that is empty size_t find_first_empty(size_t start_guess = 0) { @@ -143,6 +148,16 @@ class base_optional_span this->nof_elems += this->contains(idx) ? 0 : 1; this->vec[idx] = std::forward(u); } + + template + void emplace(size_t idx, Args&&... args) + { + srsran_assert(idx < this->vec.size(), "Out-of-bounds access to array: %zd>=%zd", idx, this->vec.size()); + if (not this->contains(idx)) { + this->nof_elems++; + } + this->vec[idx].emplace(std::forward(args)...); + } }; template @@ -157,8 +172,7 @@ class base_optional_vector : public base_optional_span base_optional_vector() = default; base_optional_vector(const base_optional_vector&) = default; - base_optional_vector(base_optional_vector&& other) noexcept : base_t::vec(std::move(other.vec)), - base_t::nof_elems(other.nof_elems) + base_optional_vector(base_optional_vector&& other) noexcept : base_t(std::move(other.vec), other.size()) { other.nof_elems = 0; } @@ -167,7 +181,7 @@ class base_optional_vector : public base_optional_span { this->vec = std::move(other.vec); this->nof_elems = other.nof_elems; - this->nof_elems = 0; + other.nof_elems = 0; return *this; } }; @@ -205,6 +219,16 @@ class optional_vector : public detail::base_optional_vector(u)); } + + /// May allocate and cause pointer invalidation + template + void emplace(size_t idx, Args&&... args) + { + if (idx >= this->vec.size()) { + this->vec.resize(idx + 1); + } + base_t::emplace(idx, std::forward(args)...); + } }; template diff --git a/lib/include/srsran/adt/pool/batch_mem_pool.h b/lib/include/srsran/adt/pool/batch_mem_pool.h index 7d3a4eee86..9fb93d07c0 100644 --- a/lib/include/srsran/adt/pool/batch_mem_pool.h +++ b/lib/include/srsran/adt/pool/batch_mem_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/pool/cached_alloc.h b/lib/include/srsran/adt/pool/cached_alloc.h index 98c3fdb66a..f47e16ef0f 100644 --- a/lib/include/srsran/adt/pool/cached_alloc.h +++ b/lib/include/srsran/adt/pool/cached_alloc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/pool/circular_stack_pool.h b/lib/include/srsran/adt/pool/circular_stack_pool.h index b1681a1e51..5fb61a2c1d 100644 --- a/lib/include/srsran/adt/pool/circular_stack_pool.h +++ b/lib/include/srsran/adt/pool/circular_stack_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -116,6 +116,22 @@ class circular_stack_pool srslog::basic_logger& logger; }; +template +unique_pool_ptr make_pool_obj_with_fallback(circular_stack_pool& pool, size_t key, Args&&... args) +{ + void* block = pool.allocate(key, sizeof(T), alignof(T)); + if (block == nullptr) { + // allocated with "new" as a fallback + return unique_pool_ptr(new T(std::forward(args)...), std::default_delete()); + } + // allocation using memory pool was successful + new (block) T(std::forward(args)...); + return unique_pool_ptr(static_cast(block), [key, &pool](T* ptr) { + ptr->~T(); + pool.deallocate(key, ptr); + }); +} + } // namespace srsran #endif // SRSRAN_CIRCULAR_MAP_STACK_POOL_H diff --git a/lib/include/srsran/adt/pool/fixed_size_pool.h b/lib/include/srsran/adt/pool/fixed_size_pool.h index eecbc3d6ca..0fdd36361f 100644 --- a/lib/include/srsran/adt/pool/fixed_size_pool.h +++ b/lib/include/srsran/adt/pool/fixed_size_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/pool/linear_allocator.h b/lib/include/srsran/adt/pool/linear_allocator.h index 02088dfa5d..b2a4ba743f 100644 --- a/lib/include/srsran/adt/pool/linear_allocator.h +++ b/lib/include/srsran/adt/pool/linear_allocator.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/pool/mem_pool.h b/lib/include/srsran/adt/pool/mem_pool.h index 2a2cb1cab5..0f694bc10a 100644 --- a/lib/include/srsran/adt/pool/mem_pool.h +++ b/lib/include/srsran/adt/pool/mem_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/pool/memblock_cache.h b/lib/include/srsran/adt/pool/memblock_cache.h index 5df93890a3..4383e25bdb 100644 --- a/lib/include/srsran/adt/pool/memblock_cache.h +++ b/lib/include/srsran/adt/pool/memblock_cache.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/pool/obj_pool.h b/lib/include/srsran/adt/pool/obj_pool.h index 2d1c0a161b..356821f399 100644 --- a/lib/include/srsran/adt/pool/obj_pool.h +++ b/lib/include/srsran/adt/pool/obj_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/pool/pool_interface.h b/lib/include/srsran/adt/pool/pool_interface.h index 4f842ce1db..0a9f9f8bb8 100644 --- a/lib/include/srsran/adt/pool/pool_interface.h +++ b/lib/include/srsran/adt/pool/pool_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/pool/pool_utils.h b/lib/include/srsran/adt/pool/pool_utils.h index f04f781bd0..adb217f3aa 100644 --- a/lib/include/srsran/adt/pool/pool_utils.h +++ b/lib/include/srsran/adt/pool/pool_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/scope_exit.h b/lib/include/srsran/adt/scope_exit.h index 25f92b54cf..e9679bc992 100644 --- a/lib/include/srsran/adt/scope_exit.h +++ b/lib/include/srsran/adt/scope_exit.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/singleton.h b/lib/include/srsran/adt/singleton.h index 9ca4d78204..bc7c9395bd 100644 --- a/lib/include/srsran/adt/singleton.h +++ b/lib/include/srsran/adt/singleton.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/adt/span.h b/lib/include/srsran/adt/span.h index f2567980f5..7c57553ee7 100644 --- a/lib/include/srsran/adt/span.h +++ b/lib/include/srsran/adt/span.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/asn1/asn1_utils.h b/lib/include/srsran/asn1/asn1_utils.h index aa99f8c7bf..9422b9390c 100644 --- a/lib/include/srsran/asn1/asn1_utils.h +++ b/lib/include/srsran/asn1/asn1_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,17 +22,14 @@ #ifndef SRSASN_COMMON_UTILS_H #define SRSASN_COMMON_UTILS_H +#include "srsran/common/buffer_pool.h" #include "srsran/srslog/srslog.h" #include "srsran/support/srsran_assert.h" -#include #include #include #include -#include #include -#include #include -#include namespace asn1 { @@ -144,7 +141,8 @@ class bit_ref_impl bit_ref_impl() = default; bit_ref_impl(Ptr start_ptr_, uint32_t max_size_) : ptr(start_ptr_), start_ptr(start_ptr_), max_ptr(max_size_ + start_ptr_) - {} + { + } int distance(const bit_ref_impl& other) const; int distance(const uint8_t* ref_ptr) const; @@ -205,8 +203,12 @@ class dyn_array { size_ = nof_items; cap_ = nof_items; - data_ = new T[cap_]; - std::copy(ptr, ptr + size_, data_); + if (ptr != NULL) { + data_ = new T[cap_]; + std::copy(ptr, ptr + size_, data_); + } else { + data_ = NULL; + } } ~dyn_array() { @@ -263,7 +265,7 @@ class dyn_array std::copy(it + 1, end(), it); size_--; - return it + 1; + return it; } bool operator==(const dyn_array& other) const { @@ -298,7 +300,8 @@ class bounded_array using iterator = T*; using const_iterator = const T*; - explicit bounded_array(uint32_t size_ = 0) : data_(), current_size(size_) {} + bounded_array() : data_(), current_size(0) {} + explicit bounded_array(uint32_t size_) : data_(), current_size(size_) {} static uint32_t capacity() { return MAX_N; } uint32_t size() const { return current_size; } T& operator[](uint32_t idx) { return data_[idx]; } @@ -308,6 +311,7 @@ class bounded_array return size() == other.size() and std::equal(data_, data_ + size(), other.data_); } void resize(uint32_t new_size) { current_size = new_size; } + void clear() { resize(0); } void push_back(const T& elem) { if (current_size >= MAX_N) { @@ -869,7 +873,8 @@ class bitstring static const uint32_t lb = LB, ub = UB; static const bool has_ext = ext, is_aligned = aligned; - explicit bitstring(uint32_t siz_ = lb) { resize(siz_); } + bitstring() { resize(lb); } + explicit bitstring(uint32_t siz_) { resize(siz_); } explicit bitstring(const std::string& s) { resize(s.size()); @@ -1282,7 +1287,8 @@ struct choice_buffer_base_t { template struct choice_buffer_t : public choice_buffer_base_t::value, - static_max::value> {}; + static_max::value> { +}; using pod_choice_buffer_t = choice_buffer_t<>; @@ -1328,11 +1334,13 @@ class varlength_field_pack_guard ~varlength_field_pack_guard(); private: - bit_ref brefstart; - // bit_ref bref0; - bit_ref* bref_tracker; - uint8_t buffer[4096]; - bool align; + using byte_array_t = std::array; + using byte_array_ptr = srsran::any_pool_ptr; + + bit_ref brefstart; + bit_ref* bref_tracker; + byte_array_ptr buffer_ptr; + bool align; }; class varlength_field_unpack_guard @@ -1386,7 +1394,7 @@ inline auto to_json(json_writer& j, const T& obj) -> decltype(obj.to_json(j)) } template -inline void to_json(json_writer& j, const asn1::enumerated& obj) +inline auto to_json(json_writer& j, const T& obj) -> decltype(j.write_str(obj.to_string())) { j.write_str(obj.to_string()); } @@ -1451,6 +1459,431 @@ int test_pack_unpack_consistency(const Msg& msg) return SRSASN_SUCCESS; } +/************************ + General Layer Types +************************/ + +/// Enumerated used in RRC and RRC NR that distinguishes Release and Setup modes +struct setup_release_opts { + enum options { release, setup, nulltype } value; + + const char* to_string() const + { + static const char* options[] = {"release", "setup"}; + return convert_enum_idx(options, 2, value, "setup_release_c::types"); + } +}; +using setup_release_e = enumerated; + +// SetupRelease{ElementTypeParam} ::= CHOICE +template +struct setup_release_c { + using types_opts = setup_release_opts; + using types = setup_release_e; + + // choice methods + setup_release_c() = default; + void set(typename types::options e = types::nulltype) { type_ = e; } + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const + { + type_.pack(bref); + switch (type_.value) { + case types::release: + break; + case types::setup: + HANDLE_CODE(c.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "setup_release_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; + } + SRSASN_CODE unpack(cbit_ref& bref) + { + types e; + e.unpack(bref); + set(e); + switch (type_.value) { + case types::release: + break; + case types::setup: + HANDLE_CODE(c.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "setup_release_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; + } + void to_json(json_writer& j) const + { + j.start_obj(); + switch (type_.value) { + case types::release: + break; + case types::setup: + asn1::to_json(j, setup()); + break; + default: + log_invalid_choice_id(type_, "setup_release_c"); + } + j.end_obj(); + } + // getters + bool is_setup() const { return type_.value == setup_release_opts::setup; } + T& setup() + { + assert_choice_type(types::setup, type_, "SetupRelease"); + return c; + } + const T& setup() const + { + assert_choice_type(types::setup, type_, "SetupRelease"); + return c; + } + void set_release() { set(types::release); } + T& set_setup() + { + set(types::setup); + return c; + } + + bool operator==(const setup_release_c& other) const + { + return type_ == other.type_ and (type_ != types::setup or (c == other.c)); + } + +private: + types type_; + T c; +}; + +// Criticality ::= ENUMERATED +struct crit_opts { + enum options { reject, ignore, notify, nulltype } value; + const char* to_string() const + { + static const char* options[] = {"reject", "ignore", "notify"}; + return convert_enum_idx(options, 3, value, "crit_e"); + } +}; +typedef enumerated crit_e; + +// Presence ::= ENUMERATED +struct presence_opts { + enum options { optional, conditional, mandatory, nulltype } value; + + const char* to_string() const + { + static const char* options[] = {"optional", "conditional", "mandatory"}; + return convert_enum_idx(options, 3, value, "presence_e"); + } +}; +typedef enumerated presence_e; + +namespace detail { + +template +struct ie_field_value_item { + using obj_set_type = IEsSetParam; + using value_type = typename IEsSetParam::value_c; + const char* item_name() const { return "value"; } + void set_item(uint32_t id) { item = IEsSetParam::get_value(id); } + +protected: + value_type item; +}; + +template +struct ie_field_ext_item { + using obj_set_type = ExtensionSetParam; + using value_type = typename ExtensionSetParam::ext_c; + const char* item_name() const { return "extension"; } + void set_item(uint32_t id) { item = ExtensionSetParam::get_ext(id); } + +protected: + value_type item; +}; + +template +struct base_ie_field : public IEItem { + using obj_set_type = typename IEItem::obj_set_type; + using value_type = typename IEItem::value_type; + + uint32_t id() const { return obj_set_type::idx_to_id(value().type().value); } + crit_e crit() const { return obj_set_type::get_crit(id()); } + value_type& value() { return this->item; } + const value_type& value() const { return this->item; } + + value_type* operator->() { return &value(); } + const value_type* operator->() const { return &value(); } + value_type& operator*() { return value(); } + const value_type& operator*() const { return value(); } + + SRSASN_CODE pack(bit_ref& bref) const + { + HANDLE_CODE(pack_integer(bref, id(), (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(crit().pack(bref)); + HANDLE_CODE(value().pack(bref)); + return SRSASN_SUCCESS; + } + SRSASN_CODE unpack(cbit_ref& bref) + { + uint32_t id_val; + HANDLE_CODE(unpack_integer(id_val, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + this->set_item(id_val); + HANDLE_CODE(crit().unpack(bref)); + HANDLE_CODE(value().unpack(bref)); + return SRSASN_SUCCESS; + } + void to_json(json_writer& j) const + { + j.start_obj(); + j.write_int("id", id()); + j.write_str("criticality", crit().to_string()); + j.write_fieldname(this->item_name()); + asn1::to_json(j, value()); + j.end_obj(); + } + bool load_info_obj(const uint32_t& id_) + { + if (not obj_set_type::is_id_valid(id_)) { + return false; + } + this->set_item(id_); + return value().type().value != obj_set_type::value_c::types_opts::nulltype; + } +}; + +} // namespace detail + +// ProtocolIE-Field{LAYER-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{IEsSetParam}} +template +struct protocol_ie_field_s : public detail::base_ie_field > { +}; + +// ProtocolIE-SingleContainer{LAYER-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{IEsSetParam}} +template +struct protocol_ie_single_container_s : public protocol_ie_field_s { +}; + +// ProtocolExtensionField{LAYER-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE{{LAYER-PROTOCOL-EXTENSION}} +template +struct protocol_ext_field_s : public detail::base_ie_field > { +}; + +namespace detail { + +template +struct ie_value_item { + using value_type = T; + value_type value; + + value_type* operator->() { return &value; } + const value_type* operator->() const { return &value; } + value_type& operator*() { return value; } + const value_type& operator*() const { return value; } + const char* item_name() const { return "value"; } + +protected: + value_type& item() { return value; } + const value_type& item() const { return value; } +}; + +template +struct ie_ext_item { + using value_type = T; + value_type ext; + + value_type* operator->() { return &ext; } + const value_type* operator->() const { return &ext; } + value_type& operator*() { return ext; } + const value_type& operator*() const { return ext; } + const char* item_name() const { return "extension"; } + +protected: + value_type& item() { return ext; } + const value_type& item() const { return ext; } +}; + +template +struct base_ie_container_item : public IEItem { + using value_type = typename IEItem::value_type; + + base_ie_container_item(uint32_t id_, crit_e crit_) : id(id_), crit(crit_) {} + + uint32_t id = 0; + crit_e crit; + + value_type* operator->() { return &this->item(); } + const value_type* operator->() const { return &this->item(); } + value_type& operator*() { return this->item(); } + const value_type& operator*() const { return this->item(); } + + SRSASN_CODE pack(bit_ref& bref) const + { + HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(crit.pack(bref)); + { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(this->item().pack(bref)); + } + return SRSASN_SUCCESS; + } + SRSASN_CODE unpack(cbit_ref& bref) + { + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(crit.unpack(bref)); + { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(this->item().unpack(bref)); + } + return SRSASN_SUCCESS; + } + void to_json(json_writer& j) const + { + j.start_obj(); + j.write_int("id", id); + j.write_str("criticality", crit.to_string()); + j.write_fieldname(this->item_name()); + asn1::to_json(j, this->item()); + j.end_obj(); + } +}; + +} // namespace detail + +template +struct protocol_ie_container_item_s : public detail::base_ie_container_item > { + using base_type = detail::base_ie_container_item >; + using base_type::base_type; +}; + +template +struct protocol_ext_container_item_s : public detail::base_ie_container_item > { + using base_type = detail::base_ie_container_item >; + using base_type::base_type; +}; + +// ProtocolIE-Container{LAYER-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE (SIZE (0..65535)) OF ProtocolIE-Field +template +using protocol_ie_container_l = dyn_seq_of, 0, 65535, true>; + +// ProtocolExtensionContainer{LAYER-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE (SIZE (1..65535)) OF +// ProtocolExtensionField +template +using protocol_ext_container_l = dyn_seq_of, 1, 65535, true>; + +namespace detail { + +struct empty_obj_set_item_c { + struct types_opts { + enum options { nulltype } value; + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::nulltype; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +struct base_empty_obj_set { + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +} // namespace detail + +/// Empty Protocol IE Object Set +struct protocol_ies_empty_o : public detail::base_empty_obj_set { + using value_c = detail::empty_obj_set_item_c; + + // members lookup methods + static value_c get_value(uint32_t id) { return {}; } +}; + +/// Empty Protocol Extension Object Set +struct protocol_ext_empty_o : public detail::base_empty_obj_set { + using ext_c = detail::empty_obj_set_item_c; + + // members lookup methods + static ext_c get_ext(uint32_t id) { return {}; } +}; + +/// Empty ProtocolExtensionContainer +struct protocol_ie_container_empty_l { + template + using ie_field_s = protocol_ext_container_item_s; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const + { + uint32_t nof_ies = 0; + pack_length(bref, nof_ies, 1u, 65535u, true); + return SRSASN_SUCCESS; + } + SRSASN_CODE unpack(cbit_ref& bref) + { + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 1u, 65535u, true); + if (nof_ies > 0) { + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; + } + void to_json(json_writer& j) const + { + j.start_obj(); + j.end_obj(); + } +}; + +using protocol_ext_container_empty_l = protocol_ie_container_empty_l; + +template +class elementary_procedure_option +{ + ProtocolIEs protocol_ies; + +public: + bool ext; + // ... + + ProtocolIEs* operator->() { return &protocol_ies; } + const ProtocolIEs* operator->() const { return &protocol_ies; } + ProtocolIEs& operator*() { return protocol_ies; } + const ProtocolIEs& operator*() const { return protocol_ies; } + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const + { + bref.pack(ext, 1); + HANDLE_CODE(protocol_ies.pack(bref)); + return SRSASN_SUCCESS; + } + SRSASN_CODE unpack(cbit_ref& bref) + { + bref.unpack(ext, 1); + HANDLE_CODE(protocol_ies.unpack(bref)); + return SRSASN_SUCCESS; + } + void to_json(json_writer& j) const + { + j.start_obj(); + j.write_fieldname("protocolIEs"); + asn1::to_json(j, protocol_ies); + j.end_obj(); + } +}; + } // namespace asn1 #endif // SRSASN_COMMON_UTILS_H diff --git a/lib/include/srsran/asn1/e2ap.h b/lib/include/srsran/asn1/e2ap.h new file mode 100644 index 0000000000..bfa43d808a --- /dev/null +++ b/lib/include/srsran/asn1/e2ap.h @@ -0,0 +1,4495 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +/******************************************************************************* + * + * 3GPP TS ASN1 E2AP v15.3.0 (2019-03) + * + ******************************************************************************/ + +#ifndef SRSASN1_E2AP_H +#define SRSASN1_E2AP_H + +#include "asn1_utils.h" +#include +#include + +namespace asn1 { +namespace e2ap { + +/******************************************************************************* + * Constant Definitions + ******************************************************************************/ + +#define ASN1_E2AP_ID_E2SETUP 1 +#define ASN1_E2AP_ID_ERROR_IND 2 +#define ASN1_E2AP_ID_RESET 3 +#define ASN1_E2AP_ID_RI_CCTRL 4 +#define ASN1_E2AP_ID_RI_CIND 5 +#define ASN1_E2AP_ID_RICSERVICE_QUERY 6 +#define ASN1_E2AP_ID_RICSERVICE_UPD 7 +#define ASN1_E2AP_ID_RICSUBSCRIPTION 8 +#define ASN1_E2AP_ID_RICSUBSCRIPTION_DELETE 9 +#define ASN1_E2AP_ID_E2NODE_CFG_UPD 10 +#define ASN1_E2AP_ID_E2CONN_UPD 11 +#define ASN1_E2AP_ID_RICSUBSCRIPTION_DELETE_REQUIRED 12 +#define ASN1_E2AP_ID_E2REMOVAL 13 +#define ASN1_E2AP_MAX_PROTOCOL_IES 65535 +#define ASN1_E2AP_MAXNOOF_ERRORS 256 +#define ASN1_E2AP_MAXOF_E2NODE_COMPONENTS 1024 +#define ASN1_E2AP_MAXOF_RA_NFUNCTION_ID 256 +#define ASN1_E2AP_MAXOF_RI_CACTION_ID 16 +#define ASN1_E2AP_MAXOF_TNLA 32 +#define ASN1_E2AP_MAXOF_RI_CREQUEST_ID 1024 +#define ASN1_E2AP_ID_CAUSE 1 +#define ASN1_E2AP_ID_CRIT_DIAGNOSTICS 2 +#define ASN1_E2AP_ID_GLOBAL_E2NODE_ID 3 +#define ASN1_E2AP_ID_GLOBAL_RIC_ID 4 +#define ASN1_E2AP_ID_RA_NFUNCTION_ID 5 +#define ASN1_E2AP_ID_RA_NFUNCTION_ID_ITEM 6 +#define ASN1_E2AP_ID_RA_NFUNCTION_IECAUSE_ITEM 7 +#define ASN1_E2AP_ID_RA_NFUNCTION_ITEM 8 +#define ASN1_E2AP_ID_RA_NFUNCTIONS_ACCEPTED 9 +#define ASN1_E2AP_ID_RA_NFUNCTIONS_ADDED 10 +#define ASN1_E2AP_ID_RA_NFUNCTIONS_DELETED 11 +#define ASN1_E2AP_ID_RA_NFUNCTIONS_MODIFIED 12 +#define ASN1_E2AP_ID_RA_NFUNCTIONS_REJECTED 13 +#define ASN1_E2AP_ID_RI_CACTION_ADMITTED_ITEM 14 +#define ASN1_E2AP_ID_RI_CACTION_ID 15 +#define ASN1_E2AP_ID_RI_CACTION_NOT_ADMITTED_ITEM 16 +#define ASN1_E2AP_ID_RI_CACTIONS_ADMITTED 17 +#define ASN1_E2AP_ID_RI_CACTIONS_NOT_ADMITTED 18 +#define ASN1_E2AP_ID_RI_CACTION_TO_BE_SETUP_ITEM 19 +#define ASN1_E2AP_ID_RI_CCALL_PROCESS_ID 20 +#define ASN1_E2AP_ID_RI_CCTRL_ACK_REQUEST 21 +#define ASN1_E2AP_ID_RI_CCTRL_HDR 22 +#define ASN1_E2AP_ID_RI_CCTRL_MSG 23 +#define ASN1_E2AP_ID_RI_CCTRL_STATUS 24 +#define ASN1_E2AP_ID_RI_CIND_HDR 25 +#define ASN1_E2AP_ID_RI_CIND_MSG 26 +#define ASN1_E2AP_ID_RI_CIND_SN 27 +#define ASN1_E2AP_ID_RI_CIND_TYPE 28 +#define ASN1_E2AP_ID_RI_CREQUEST_ID 29 +#define ASN1_E2AP_ID_RICSUBSCRIPTION_DETAILS 30 +#define ASN1_E2AP_ID_TIME_TO_WAIT 31 +#define ASN1_E2AP_ID_RI_CCTRL_OUTCOME 32 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_UPD 33 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_UPD_ITEM 34 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_UPD_ACK 35 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_UPD_ACK_ITEM 36 +#define ASN1_E2AP_ID_E2CONN_SETUP 39 +#define ASN1_E2AP_ID_E2CONN_SETUP_FAILED 40 +#define ASN1_E2AP_ID_E2CONN_SETUP_FAILED_ITEM 41 +#define ASN1_E2AP_ID_E2CONN_FAILED_ITEM 42 +#define ASN1_E2AP_ID_E2CONN_UPD_ITEM 43 +#define ASN1_E2AP_ID_E2CONN_UPD_ADD 44 +#define ASN1_E2AP_ID_E2CONN_UPD_MODIFY 45 +#define ASN1_E2AP_ID_E2CONN_UPD_REM 46 +#define ASN1_E2AP_ID_E2CONN_UPD_REM_ITEM 47 +#define ASN1_E2AP_ID_TN_LINFO 48 +#define ASN1_E2AP_ID_TRANSACTION_ID 49 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_ADDITION 50 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_ADDITION_ITEM 51 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_ADDITION_ACK 52 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_ADDITION_ACK_ITEM 53 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_REMOVAL 54 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_REMOVAL_ITEM 55 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_REMOVAL_ACK 56 +#define ASN1_E2AP_ID_E2NODE_COMPONENT_CFG_REMOVAL_ACK_ITEM 57 +#define ASN1_E2AP_ID_E2NODE_TN_LASSOC_REMOVAL 58 +#define ASN1_E2AP_ID_E2NODE_TN_LASSOC_REMOVAL_ITEM 59 +#define ASN1_E2AP_ID_RICSUBSCRIPTION_TO_BE_REMD 60 +#define ASN1_E2AP_ID_RICSUBSCRIPTION_WITH_CAUSE_ITEM 61 + +/******************************************************************************* + * Struct Definitions + ******************************************************************************/ + +// CauseE2node ::= ENUMERATED +struct cause_e2node_opts { + enum options { e2node_component_unknown, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated cause_e2node_e; + +// CauseMisc ::= ENUMERATED +struct cause_misc_opts { + enum options { ctrl_processing_overload, hardware_fail, om_intervention, unspecified, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated cause_misc_e; + +// CauseProtocol ::= ENUMERATED +struct cause_protocol_opts { + enum options { + transfer_syntax_error, + abstract_syntax_error_reject, + abstract_syntax_error_ignore_and_notify, + msg_not_compatible_with_receiver_state, + semantic_error, + abstract_syntax_error_falsely_constructed_msg, + unspecified, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated cause_protocol_e; + +// CauseRICrequest ::= ENUMERATED +struct cause_ri_crequest_opts { + enum options { + ran_function_id_invalid, + action_not_supported, + excessive_actions, + duplicate_action, + duplicate_event_trigger, + function_res_limit, + request_id_unknown, + inconsistent_action_subsequent_action_seq, + ctrl_msg_invalid, + ric_call_process_id_invalid, + ctrl_timer_expired, + ctrl_failed_to_execute, + sys_not_ready, + unspecified, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated cause_ri_crequest_e; + +// CauseRICservice ::= ENUMERATED +struct cause_ricservice_opts { + enum options { ran_function_not_supported, excessive_functions, ric_res_limit, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated cause_ricservice_e; + +// CauseTransport ::= ENUMERATED +struct cause_transport_opts { + enum options { unspecified, transport_res_unavailable, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated cause_transport_e; + +// Cause ::= CHOICE +struct cause_c { + struct types_opts { + enum options { ric_request, ric_service, e2_node, transport, protocol, misc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + cause_c() = default; + cause_c(const cause_c& other); + cause_c& operator=(const cause_c& other); + ~cause_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + cause_ri_crequest_e& ric_request() + { + assert_choice_type(types::ric_request, type_, "Cause"); + return c.get(); + } + cause_ricservice_e& ric_service() + { + assert_choice_type(types::ric_service, type_, "Cause"); + return c.get(); + } + cause_e2node_e& e2_node() + { + assert_choice_type(types::e2_node, type_, "Cause"); + return c.get(); + } + cause_transport_e& transport() + { + assert_choice_type(types::transport, type_, "Cause"); + return c.get(); + } + cause_protocol_e& protocol() + { + assert_choice_type(types::protocol, type_, "Cause"); + return c.get(); + } + cause_misc_e& misc() + { + assert_choice_type(types::misc, type_, "Cause"); + return c.get(); + } + const cause_ri_crequest_e& ric_request() const + { + assert_choice_type(types::ric_request, type_, "Cause"); + return c.get(); + } + const cause_ricservice_e& ric_service() const + { + assert_choice_type(types::ric_service, type_, "Cause"); + return c.get(); + } + const cause_e2node_e& e2_node() const + { + assert_choice_type(types::e2_node, type_, "Cause"); + return c.get(); + } + const cause_transport_e& transport() const + { + assert_choice_type(types::transport, type_, "Cause"); + return c.get(); + } + const cause_protocol_e& protocol() const + { + assert_choice_type(types::protocol, type_, "Cause"); + return c.get(); + } + const cause_misc_e& misc() const + { + assert_choice_type(types::misc, type_, "Cause"); + return c.get(); + } + cause_ri_crequest_e& set_ric_request(); + cause_ricservice_e& set_ric_service(); + cause_e2node_e& set_e2_node(); + cause_transport_e& set_transport(); + cause_protocol_e& set_protocol(); + cause_misc_e& set_misc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// TypeOfError ::= ENUMERATED +struct type_of_error_opts { + enum options { not_understood, missing, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated type_of_error_e; + +// CriticalityDiagnostics-IE-Item ::= SEQUENCE +struct crit_diagnostics_ie_item_s { + bool ext = false; + crit_e iecrit; + uint32_t ie_id = 0; + type_of_error_e type_of_error; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..256)) OF CriticalityDiagnostics-IE-Item +using crit_diagnostics_ie_list_l = dyn_array; + +// RICrequestID ::= SEQUENCE +struct ri_crequest_id_s { + bool ext = false; + uint32_t ric_requestor_id = 0; + uint32_t ric_instance_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TriggeringMessage ::= ENUMERATED +struct trigger_msg_opts { + enum options { init_msg, successful_outcome, unsuccessfull_outcome, nulltype } value; + + const char* to_string() const; +}; +typedef enumerated trigger_msg_e; + +// CriticalityDiagnostics ::= SEQUENCE +struct crit_diagnostics_s { + bool ext = false; + bool proc_code_present = false; + bool trigger_msg_present = false; + bool proc_crit_present = false; + bool ric_requestor_id_present = false; + uint16_t proc_code = 0; + trigger_msg_e trigger_msg; + crit_e proc_crit; + ri_crequest_id_s ric_requestor_id; + crit_diagnostics_ie_list_l ies_crit_diagnostics; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ENB-ID-Choice ::= CHOICE +struct enb_id_choice_c { + struct types_opts { + enum options { enb_id_macro, enb_id_shortmacro, enb_id_longmacro, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_choice_c() = default; + enb_id_choice_c(const enb_id_choice_c& other); + enb_id_choice_c& operator=(const enb_id_choice_c& other); + ~enb_id_choice_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& enb_id_macro() + { + assert_choice_type(types::enb_id_macro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<18, false, true>& enb_id_shortmacro() + { + assert_choice_type(types::enb_id_shortmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<21, false, true>& enb_id_longmacro() + { + assert_choice_type(types::enb_id_longmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& enb_id_macro() const + { + assert_choice_type(types::enb_id_macro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& enb_id_shortmacro() const + { + assert_choice_type(types::enb_id_shortmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& enb_id_longmacro() const + { + assert_choice_type(types::enb_id_longmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_enb_id_macro(); + fixed_bitstring<18, false, true>& set_enb_id_shortmacro(); + fixed_bitstring<21, false, true>& set_enb_id_longmacro(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// GNB-ID-Choice ::= CHOICE +struct gnb_id_choice_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// ENB-ID ::= CHOICE +struct enb_id_c { + struct types_opts { + enum options { macro_enb_id, home_enb_id, /*...*/ short_macro_enb_id, long_macro_enb_id, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_c() = default; + enb_id_c(const enb_id_c& other); + enb_id_c& operator=(const enb_id_c& other); + ~enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_enb_id() + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<28, false, true>& home_enb_id() + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_enb_id() + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_enb_id() + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_enb_id() const + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<28, false, true>& home_enb_id() const + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_enb_id() const + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_enb_id() const + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_enb_id(); + fixed_bitstring<28, false, true>& set_home_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// ENGNB-ID ::= CHOICE +struct engnb_id_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalgNB-ID ::= SEQUENCE +struct globalg_nb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + gnb_id_choice_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalngeNB-ID ::= SEQUENCE +struct globalngenb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_choice_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalENB-ID ::= SEQUENCE +struct global_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalNG-RANNode-ID ::= CHOICE +struct global_ng_ran_node_id_c { + struct types_opts { + enum options { gnb, ng_enb, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_ng_ran_node_id_c() = default; + global_ng_ran_node_id_c(const global_ng_ran_node_id_c& other); + global_ng_ran_node_id_c& operator=(const global_ng_ran_node_id_c& other); + ~global_ng_ran_node_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + globalg_nb_id_s& gnb() + { + assert_choice_type(types::gnb, type_, "GlobalNG-RANNode-ID"); + return c.get(); + } + globalngenb_id_s& ng_enb() + { + assert_choice_type(types::ng_enb, type_, "GlobalNG-RANNode-ID"); + return c.get(); + } + const globalg_nb_id_s& gnb() const + { + assert_choice_type(types::gnb, type_, "GlobalNG-RANNode-ID"); + return c.get(); + } + const globalngenb_id_s& ng_enb() const + { + assert_choice_type(types::ng_enb, type_, "GlobalNG-RANNode-ID"); + return c.get(); + } + globalg_nb_id_s& set_gnb(); + globalngenb_id_s& set_ng_enb(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// GlobalenGNB-ID ::= SEQUENCE +struct globalen_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + engnb_id_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubsequentActionType ::= ENUMERATED +struct ricsubsequent_action_type_opts { + enum options { continuee, wait, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated ricsubsequent_action_type_e; + +// RICtimeToWait ::= ENUMERATED +struct ri_ctime_to_wait_opts { + enum options { + w1ms, + w2ms, + w5ms, + w10ms, + w20ms, + w30ms, + w40ms, + w50ms, + w100ms, + w200ms, + w500ms, + w1s, + w2s, + w5s, + w10s, + w20s, + w60s, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated ri_ctime_to_wait_e; + +// E2nodeComponentInterfaceE1 ::= SEQUENCE +struct e2node_component_interface_e1_s { + bool ext = false; + uint64_t gnb_cu_cp_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceF1 ::= SEQUENCE +struct e2node_component_interface_f1_s { + bool ext = false; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceNG ::= SEQUENCE +struct e2node_component_interface_ng_s { + bool ext = false; + printable_string<1, 150, true, true> amf_name; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceS1 ::= SEQUENCE +struct e2node_component_interface_s1_s { + bool ext = false; + printable_string<1, 150, true, true> mme_name; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceW1 ::= SEQUENCE +struct e2node_component_interface_w1_s { + bool ext = false; + uint64_t ng_enb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceX2 ::= SEQUENCE +struct e2node_component_interface_x2_s { + bool ext = false; + bool global_enb_id_present = false; + bool global_en_g_nb_id_present = false; + global_enb_id_s global_enb_id; + globalen_gnb_id_s global_en_g_nb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentInterfaceXn ::= SEQUENCE +struct e2node_component_interface_xn_s { + bool ext = false; + global_ng_ran_node_id_c global_ng_ran_node_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICactionType ::= ENUMERATED +struct ri_caction_type_opts { + enum options { report, insert, policy, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated ri_caction_type_e; + +// RICsubsequentAction ::= SEQUENCE +struct ricsubsequent_action_s { + bool ext = false; + ricsubsequent_action_type_e ric_subsequent_action_type; + ri_ctime_to_wait_e ric_time_to_wait; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfiguration ::= SEQUENCE +struct e2node_component_cfg_s { + bool ext = false; + unbounded_octstring e2node_component_request_part; + unbounded_octstring e2node_component_resp_part; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigurationAck ::= SEQUENCE +struct e2node_component_cfg_ack_s { + struct upd_outcome_opts { + enum options { success, fail, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated upd_outcome_e_; + + // member variables + bool ext = false; + bool fail_cause_present = false; + upd_outcome_e_ upd_outcome; + cause_c fail_cause; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentID ::= CHOICE +struct e2node_component_id_c { + struct types_opts { + enum options { + e2node_component_interface_type_ng, + e2node_component_interface_type_xn, + e2node_component_interface_type_e1, + e2node_component_interface_type_f1, + e2node_component_interface_type_w1, + e2node_component_interface_type_s1, + e2node_component_interface_type_x2, + // ... + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + e2node_component_id_c() = default; + e2node_component_id_c(const e2node_component_id_c& other); + e2node_component_id_c& operator=(const e2node_component_id_c& other); + ~e2node_component_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_interface_ng_s& e2node_component_interface_type_ng() + { + assert_choice_type(types::e2node_component_interface_type_ng, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_xn_s& e2node_component_interface_type_xn() + { + assert_choice_type(types::e2node_component_interface_type_xn, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_e1_s& e2node_component_interface_type_e1() + { + assert_choice_type(types::e2node_component_interface_type_e1, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_f1_s& e2node_component_interface_type_f1() + { + assert_choice_type(types::e2node_component_interface_type_f1, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_w1_s& e2node_component_interface_type_w1() + { + assert_choice_type(types::e2node_component_interface_type_w1, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_s1_s& e2node_component_interface_type_s1() + { + assert_choice_type(types::e2node_component_interface_type_s1, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_x2_s& e2node_component_interface_type_x2() + { + assert_choice_type(types::e2node_component_interface_type_x2, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_ng_s& e2node_component_interface_type_ng() const + { + assert_choice_type(types::e2node_component_interface_type_ng, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_xn_s& e2node_component_interface_type_xn() const + { + assert_choice_type(types::e2node_component_interface_type_xn, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_e1_s& e2node_component_interface_type_e1() const + { + assert_choice_type(types::e2node_component_interface_type_e1, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_f1_s& e2node_component_interface_type_f1() const + { + assert_choice_type(types::e2node_component_interface_type_f1, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_w1_s& e2node_component_interface_type_w1() const + { + assert_choice_type(types::e2node_component_interface_type_w1, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_s1_s& e2node_component_interface_type_s1() const + { + assert_choice_type(types::e2node_component_interface_type_s1, type_, "E2nodeComponentID"); + return c.get(); + } + const e2node_component_interface_x2_s& e2node_component_interface_type_x2() const + { + assert_choice_type(types::e2node_component_interface_type_x2, type_, "E2nodeComponentID"); + return c.get(); + } + e2node_component_interface_ng_s& set_e2node_component_interface_type_ng(); + e2node_component_interface_xn_s& set_e2node_component_interface_type_xn(); + e2node_component_interface_e1_s& set_e2node_component_interface_type_e1(); + e2node_component_interface_f1_s& set_e2node_component_interface_type_f1(); + e2node_component_interface_w1_s& set_e2node_component_interface_type_w1(); + e2node_component_interface_s1_s& set_e2node_component_interface_type_s1(); + e2node_component_interface_x2_s& set_e2node_component_interface_type_x2(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// E2nodeComponentInterfaceType ::= ENUMERATED +struct e2node_component_interface_type_opts { + enum options { ng, xn, e1, f1, w1, s1, x2, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated e2node_component_interface_type_e; + +// RICaction-ToBeSetup-Item ::= SEQUENCE +struct ri_caction_to_be_setup_item_s { + bool ext = false; + bool ric_subsequent_action_present = false; + uint16_t ric_action_id = 0; + ri_caction_type_e ric_action_type; + unbounded_octstring ric_action_definition; + ricsubsequent_action_s ric_subsequent_action; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TNLinformation ::= SEQUENCE +struct tn_linfo_s { + bool ext = false; + bool tnl_port_present = false; + bounded_bitstring<1, 160, true, true> tnl_address; + fixed_bitstring<16, false, true> tnl_port; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TNLusage ::= ENUMERATED +struct tn_lusage_opts { + enum options { ric_service, support_function, both, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated tn_lusage_e; + +// E2connectionSetupFailed-Item ::= SEQUENCE +struct e2conn_setup_failed_item_s { + bool ext = false; + tn_linfo_s tnl_info; + cause_c cause; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionUpdate-Item ::= SEQUENCE +struct e2conn_upd_item_s { + bool ext = false; + tn_linfo_s tnl_info; + tn_lusage_e tnl_usage; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionUpdateRemove-Item ::= SEQUENCE +struct e2conn_upd_rem_item_s { + bool ext = false; + tn_linfo_s tnl_info; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigAddition-Item ::= SEQUENCE +struct e2node_component_cfg_addition_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + e2node_component_cfg_s e2node_component_cfg; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigAdditionAck-Item ::= SEQUENCE +struct e2node_component_cfg_addition_ack_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + e2node_component_cfg_ack_s e2node_component_cfg_ack; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigRemoval-Item ::= SEQUENCE +struct e2node_component_cfg_removal_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigRemovalAck-Item ::= SEQUENCE +struct e2node_component_cfg_removal_ack_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + e2node_component_cfg_ack_s e2node_component_cfg_ack; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigUpdate-Item ::= SEQUENCE +struct e2node_component_cfg_upd_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + e2node_component_cfg_s e2node_component_cfg; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeComponentConfigUpdateAck-Item ::= SEQUENCE +struct e2node_component_cfg_upd_ack_item_s { + bool ext = false; + e2node_component_interface_type_e e2node_component_interface_type; + e2node_component_id_c e2node_component_id; + e2node_component_cfg_ack_s e2node_component_cfg_ack; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeTNLassociationRemoval-Item ::= SEQUENCE +struct e2node_tn_lassoc_removal_item_s { + bool ext = false; + tn_linfo_s tnl_info; + tn_linfo_s tnl_info_ric; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RANfunction-Item ::= SEQUENCE +struct ra_nfunction_item_s { + bool ext = false; + uint16_t ran_function_id = 0; + unbounded_octstring ran_function_definition; + uint16_t ran_function_revision = 0; + printable_string<1, 1000, true, true> ran_function_oid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RANfunctionID-Item ::= SEQUENCE +struct ra_nfunction_id_item_s { + bool ext = false; + uint16_t ran_function_id = 0; + uint16_t ran_function_revision = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RANfunctionIDcause-Item ::= SEQUENCE +struct ra_nfunction_idcause_item_s { + bool ext = false; + uint16_t ran_function_id = 0; + cause_c cause; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICaction-Admitted-Item ::= SEQUENCE +struct ri_caction_admitted_item_s { + bool ext = false; + uint16_t ric_action_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICaction-NotAdmitted-Item ::= SEQUENCE +struct ri_caction_not_admitted_item_s { + bool ext = false; + uint16_t ric_action_id = 0; + cause_c cause; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICaction-ToBeSetup-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_caction_to_be_setup_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_caction_to_be_setup_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ri_caction_to_be_setup_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_caction_to_be_setup_item_s& ri_caction_to_be_setup_item() { return c; } + const ri_caction_to_be_setup_item_s& ri_caction_to_be_setup_item() const { return c; } + + private: + ri_caction_to_be_setup_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscription-withCause-Item ::= SEQUENCE +struct ricsubscription_with_cause_item_s { + bool ext = false; + ri_crequest_id_s ric_request_id; + uint16_t ran_function_id = 0; + cause_c cause; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionSetupFailed-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_setup_failed_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2conn_setup_failed_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2conn_setup_failed_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2conn_setup_failed_item_s& e2conn_setup_failed_item() { return c; } + const e2conn_setup_failed_item_s& e2conn_setup_failed_item() const { return c; } + + private: + e2conn_setup_failed_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionUpdate-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_upd_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2conn_upd_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2conn_upd_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2conn_upd_item_s& e2conn_upd_item() { return c; } + const e2conn_upd_item_s& e2conn_upd_item() const { return c; } + + private: + e2conn_upd_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionUpdateRemove-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_upd_rem_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2conn_upd_rem_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2conn_upd_rem_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2conn_upd_rem_item_s& e2conn_upd_rem_item() { return c; } + const e2conn_upd_rem_item_s& e2conn_upd_rem_item() const { return c; } + + private: + e2conn_upd_rem_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigAddition-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_addition_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_addition_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_addition_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_addition_item_s& e2node_component_cfg_addition_item() { return c; } + const e2node_component_cfg_addition_item_s& e2node_component_cfg_addition_item() const { return c; } + + private: + e2node_component_cfg_addition_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigAdditionAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_addition_ack_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_addition_ack_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_addition_ack_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_addition_ack_item_s& e2node_component_cfg_addition_ack_item() { return c; } + const e2node_component_cfg_addition_ack_item_s& e2node_component_cfg_addition_ack_item() const { return c; } + + private: + e2node_component_cfg_addition_ack_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigRemoval-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_removal_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_removal_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_removal_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_removal_item_s& e2node_component_cfg_removal_item() { return c; } + const e2node_component_cfg_removal_item_s& e2node_component_cfg_removal_item() const { return c; } + + private: + e2node_component_cfg_removal_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigRemovalAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_removal_ack_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_removal_ack_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_removal_ack_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_removal_ack_item_s& e2node_component_cfg_removal_ack_item() { return c; } + const e2node_component_cfg_removal_ack_item_s& e2node_component_cfg_removal_ack_item() const { return c; } + + private: + e2node_component_cfg_removal_ack_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigUpdate-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_upd_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_upd_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_upd_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_upd_item_s& e2node_component_cfg_upd_item() { return c; } + const e2node_component_cfg_upd_item_s& e2node_component_cfg_upd_item() const { return c; } + + private: + e2node_component_cfg_upd_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeComponentConfigUpdateAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_component_cfg_upd_ack_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_component_cfg_upd_ack_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_component_cfg_upd_ack_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_component_cfg_upd_ack_item_s& e2node_component_cfg_upd_ack_item() { return c; } + const e2node_component_cfg_upd_ack_item_s& e2node_component_cfg_upd_ack_item() const { return c; } + + private: + e2node_component_cfg_upd_ack_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeTNLassociationRemoval-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_tn_lassoc_removal_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { e2node_tn_lassoc_removal_item, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::e2node_tn_lassoc_removal_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2node_tn_lassoc_removal_item_s& e2node_tn_lassoc_removal_item() { return c; } + const e2node_tn_lassoc_removal_item_s& e2node_tn_lassoc_removal_item() const { return c; } + + private: + e2node_tn_lassoc_removal_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// GlobalE2node-eNB-ID ::= SEQUENCE +struct global_e2node_enb_id_s { + bool ext = false; + global_enb_id_s global_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalE2node-en-gNB-ID ::= SEQUENCE +struct global_e2node_en_g_nb_id_s { + bool ext = false; + bool en_g_nb_cu_up_id_present = false; + bool en_g_nb_du_id_present = false; + globalen_gnb_id_s global_en_g_nb_id; + uint64_t en_g_nb_cu_up_id = 0; + uint64_t en_g_nb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalE2node-gNB-ID ::= SEQUENCE +struct global_e2node_g_nb_id_s { + bool ext = false; + bool global_en_g_nb_id_present = false; + bool gnb_cu_up_id_present = false; + bool gnb_du_id_present = false; + globalg_nb_id_s global_g_nb_id; + globalen_gnb_id_s global_en_g_nb_id; + uint64_t gnb_cu_up_id = 0; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalE2node-ng-eNB-ID ::= SEQUENCE +struct global_e2node_ng_enb_id_s { + bool ext = false; + bool global_enb_id_present = false; + bool ng_enb_du_id_present = false; + globalngenb_id_s global_ng_enb_id; + global_enb_id_s global_enb_id; + uint64_t ng_enb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RANfunction-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ra_nfunction_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ra_nfunction_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ra_nfunction_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ra_nfunction_item_s& ra_nfunction_item() { return c; } + const ra_nfunction_item_s& ra_nfunction_item() const { return c; } + + private: + ra_nfunction_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RANfunctionID-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ra_nfunction_id_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ra_nfunction_id_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ra_nfunction_id_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ra_nfunction_id_item_s& ra_nfunction_id_item() { return c; } + const ra_nfunction_id_item_s& ra_nfunction_id_item() const { return c; } + + private: + ra_nfunction_id_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RANfunctionIDcause-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ra_nfunction_idcause_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ra_nfunction_iecause_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ra_nfunction_iecause_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ra_nfunction_idcause_item_s& ra_nfunction_iecause_item() { return c; } + const ra_nfunction_idcause_item_s& ra_nfunction_iecause_item() const { return c; } + + private: + ra_nfunction_idcause_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICaction-Admitted-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_caction_admitted_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_caction_admitted_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ri_caction_admitted_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_caction_admitted_item_s& ri_caction_admitted_item() { return c; } + const ri_caction_admitted_item_s& ri_caction_admitted_item() const { return c; } + + private: + ri_caction_admitted_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICaction-NotAdmitted-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_caction_not_admitted_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_caction_not_admitted_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ri_caction_not_admitted_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_caction_not_admitted_item_s& ri_caction_not_admitted_item() { return c; } + const ri_caction_not_admitted_item_s& ri_caction_not_admitted_item() const { return c; } + + private: + ri_caction_not_admitted_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICactions-ToBeSetup-List ::= SEQUENCE (SIZE (1..16)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ri_cactions_to_be_setup_list_l = + bounded_array, 16>; + +// RICsubscription-withCause-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_with_cause_item_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ricsubscription_with_cause_item, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ricsubscription_with_cause_item; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ricsubscription_with_cause_item_s& ricsubscription_with_cause_item() { return c; } + const ricsubscription_with_cause_item_s& ricsubscription_with_cause_item() const { return c; } + + private: + ricsubscription_with_cause_item_s c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionSetupFailed-List ::= SEQUENCE (SIZE (1..32)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2conn_setup_failed_list_l = bounded_array, 32>; + +// E2connectionUpdate-List ::= SEQUENCE (SIZE (1..32)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using e2conn_upd_list_l = bounded_array, 32>; + +// E2connectionUpdateRemove-List ::= SEQUENCE (SIZE (1..32)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2conn_upd_rem_list_l = bounded_array, 32>; + +// E2nodeComponentConfigAddition-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_addition_list_l = + dyn_array >; + +// E2nodeComponentConfigAdditionAck-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_addition_ack_list_l = + dyn_array >; + +// E2nodeComponentConfigRemoval-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_removal_list_l = + dyn_array >; + +// E2nodeComponentConfigRemovalAck-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_removal_ack_list_l = + dyn_array >; + +// E2nodeComponentConfigUpdate-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_upd_list_l = dyn_array >; + +// E2nodeComponentConfigUpdateAck-List ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_component_cfg_upd_ack_list_l = + dyn_array >; + +// E2nodeTNLassociationRemoval-List ::= SEQUENCE (SIZE (1..32)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using e2node_tn_lassoc_removal_list_l = + bounded_array, 32>; + +// GlobalE2node-ID ::= CHOICE +struct global_e2node_id_c { + struct types_opts { + enum options { gnb, en_g_nb, ng_enb, enb, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_e2node_id_c() = default; + global_e2node_id_c(const global_e2node_id_c& other); + global_e2node_id_c& operator=(const global_e2node_id_c& other); + ~global_e2node_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_e2node_g_nb_id_s& gnb() + { + assert_choice_type(types::gnb, type_, "GlobalE2node-ID"); + return c.get(); + } + global_e2node_en_g_nb_id_s& en_g_nb() + { + assert_choice_type(types::en_g_nb, type_, "GlobalE2node-ID"); + return c.get(); + } + global_e2node_ng_enb_id_s& ng_enb() + { + assert_choice_type(types::ng_enb, type_, "GlobalE2node-ID"); + return c.get(); + } + global_e2node_enb_id_s& enb() + { + assert_choice_type(types::enb, type_, "GlobalE2node-ID"); + return c.get(); + } + const global_e2node_g_nb_id_s& gnb() const + { + assert_choice_type(types::gnb, type_, "GlobalE2node-ID"); + return c.get(); + } + const global_e2node_en_g_nb_id_s& en_g_nb() const + { + assert_choice_type(types::en_g_nb, type_, "GlobalE2node-ID"); + return c.get(); + } + const global_e2node_ng_enb_id_s& ng_enb() const + { + assert_choice_type(types::ng_enb, type_, "GlobalE2node-ID"); + return c.get(); + } + const global_e2node_enb_id_s& enb() const + { + assert_choice_type(types::enb, type_, "GlobalE2node-ID"); + return c.get(); + } + global_e2node_g_nb_id_s& set_gnb(); + global_e2node_en_g_nb_id_s& set_en_g_nb(); + global_e2node_ng_enb_id_s& set_ng_enb(); + global_e2node_enb_id_s& set_enb(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// GlobalRIC-ID ::= SEQUENCE +struct global_ric_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<20, false, true> ric_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RANfunctions-List ::= SEQUENCE (SIZE (1..256)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ra_nfunctions_list_l = dyn_array >; + +// RANfunctionsID-List ::= SEQUENCE (SIZE (1..256)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ra_nfunctions_id_list_l = dyn_array >; + +// RANfunctionsIDcause-List ::= SEQUENCE (SIZE (1..256)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ra_nfunctions_idcause_list_l = dyn_array >; + +// RICaction-Admitted-List ::= SEQUENCE (SIZE (1..16)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ri_caction_admitted_list_l = bounded_array, 16>; + +// RICaction-NotAdmitted-List ::= SEQUENCE (SIZE (0..16)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : IEsSetParam} +using ri_caction_not_admitted_list_l = + bounded_array, 16>; + +// RICcontrolAckRequest ::= ENUMERATED +struct ri_cctrl_ack_request_opts { + enum options { no_ack, ack, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated ri_cctrl_ack_request_e; + +// RICindicationType ::= ENUMERATED +struct ri_cind_type_opts { + enum options { report, insert, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated ri_cind_type_e; + +// RICsubscription-List-withCause ::= SEQUENCE (SIZE (1..1024)) OF ProtocolIE-SingleContainer{E2AP-PROTOCOL-IES : +// IEsSetParam} +using ricsubscription_list_with_cause_l = + dyn_array >; + +// RICsubscriptionDetails ::= SEQUENCE +struct ricsubscription_details_s { + bool ext = false; + unbounded_octstring ric_event_trigger_definition; + ri_cactions_to_be_setup_list_l ric_action_to_be_setup_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TimeToWait ::= ENUMERATED +struct time_to_wait_opts { + enum options { v1s, v2s, v5s, v10s, v20s, v60s, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated time_to_wait_e; + +// E2RemovalFailureIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2_removal_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2RemovalRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2_removal_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::transaction_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id() { return c; } + const uint16_t& transaction_id() const { return c; } + + private: + uint16_t c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2RemovalResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2_removal_resp_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_upd_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, e2conn_upd_add, e2conn_upd_rem, e2conn_upd_modify, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + e2conn_upd_list_l& e2conn_upd_add(); + e2conn_upd_rem_list_l& e2conn_upd_rem(); + e2conn_upd_list_l& e2conn_upd_modify(); + const uint16_t& transaction_id() const; + const e2conn_upd_list_l& e2conn_upd_add() const; + const e2conn_upd_rem_list_l& e2conn_upd_rem() const; + const e2conn_upd_list_l& e2conn_upd_modify() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionUpdateAck-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_upd_ack_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, e2conn_setup, e2conn_setup_failed, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + e2conn_upd_list_l& e2conn_setup(); + e2conn_setup_failed_list_l& e2conn_setup_failed(); + const uint16_t& transaction_id() const; + const e2conn_upd_list_l& e2conn_setup() const; + const e2conn_setup_failed_list_l& e2conn_setup_failed() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2connectionUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2conn_upd_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, time_to_wait, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + time_to_wait_e& time_to_wait(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + const time_to_wait_e& time_to_wait() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeConfigurationUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_cfg_upd_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + transaction_id, + global_e2node_id, + e2node_component_cfg_addition, + e2node_component_cfg_upd, + e2node_component_cfg_removal, + e2node_tn_lassoc_removal, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + global_e2node_id_c& global_e2node_id(); + e2node_component_cfg_addition_list_l& e2node_component_cfg_addition(); + e2node_component_cfg_upd_list_l& e2node_component_cfg_upd(); + e2node_component_cfg_removal_list_l& e2node_component_cfg_removal(); + e2node_tn_lassoc_removal_list_l& e2node_tn_lassoc_removal(); + const uint16_t& transaction_id() const; + const global_e2node_id_c& global_e2node_id() const; + const e2node_component_cfg_addition_list_l& e2node_component_cfg_addition() const; + const e2node_component_cfg_upd_list_l& e2node_component_cfg_upd() const; + const e2node_component_cfg_removal_list_l& e2node_component_cfg_removal() const; + const e2node_tn_lassoc_removal_list_l& e2node_tn_lassoc_removal() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeConfigurationUpdateAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_cfg_upd_ack_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + transaction_id, + e2node_component_cfg_addition_ack, + e2node_component_cfg_upd_ack, + e2node_component_cfg_removal_ack, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + e2node_component_cfg_addition_ack_list_l& e2node_component_cfg_addition_ack(); + e2node_component_cfg_upd_ack_list_l& e2node_component_cfg_upd_ack(); + e2node_component_cfg_removal_ack_list_l& e2node_component_cfg_removal_ack(); + const uint16_t& transaction_id() const; + const e2node_component_cfg_addition_ack_list_l& e2node_component_cfg_addition_ack() const; + const e2node_component_cfg_upd_ack_list_l& e2node_component_cfg_upd_ack() const; + const e2node_component_cfg_removal_ack_list_l& e2node_component_cfg_removal_ack() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2nodeConfigurationUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2node_cfg_upd_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, time_to_wait, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + time_to_wait_e& time_to_wait(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + const time_to_wait_e& time_to_wait() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2setupFailureIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2setup_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, time_to_wait, crit_diagnostics, tn_linfo, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + time_to_wait_e& time_to_wait(); + crit_diagnostics_s& crit_diagnostics(); + tn_linfo_s& tn_linfo(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + const time_to_wait_e& time_to_wait() const; + const crit_diagnostics_s& crit_diagnostics() const; + const tn_linfo_s& tn_linfo() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2setupRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2setup_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + transaction_id, + global_e2node_id, + ra_nfunctions_added, + e2node_component_cfg_addition, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + global_e2node_id_c& global_e2node_id(); + ra_nfunctions_list_l& ra_nfunctions_added(); + e2node_component_cfg_addition_list_l& e2node_component_cfg_addition(); + const uint16_t& transaction_id() const; + const global_e2node_id_c& global_e2node_id() const; + const ra_nfunctions_list_l& ra_nfunctions_added() const; + const e2node_component_cfg_addition_list_l& e2node_component_cfg_addition() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// E2setupResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct e2setup_resp_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + transaction_id, + global_ric_id, + ra_nfunctions_accepted, + ra_nfunctions_rejected, + e2node_component_cfg_addition_ack, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + global_ric_id_s& global_ric_id(); + ra_nfunctions_id_list_l& ra_nfunctions_accepted(); + ra_nfunctions_idcause_list_l& ra_nfunctions_rejected(); + e2node_component_cfg_addition_ack_list_l& e2node_component_cfg_addition_ack(); + const uint16_t& transaction_id() const; + const global_ric_id_s& global_ric_id() const; + const ra_nfunctions_id_list_l& ra_nfunctions_accepted() const; + const ra_nfunctions_idcause_list_l& ra_nfunctions_rejected() const; + const e2node_component_cfg_addition_ack_list_l& e2node_component_cfg_addition_ack() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// ErrorIndication-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct error_ind_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, ri_crequest_id, ra_nfunction_id, cause, crit_diagnostics, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + cause_c& cause(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const cause_c& cause() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICcontrolAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_cctrl_ack_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, ri_ccall_process_id, ri_cctrl_outcome, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + unbounded_octstring& ri_ccall_process_id(); + unbounded_octstring& ri_cctrl_outcome(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const unbounded_octstring& ri_ccall_process_id() const; + const unbounded_octstring& ri_cctrl_outcome() const; + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICcontrolFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_cctrl_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, ri_ccall_process_id, cause, ri_cctrl_outcome, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + unbounded_octstring& ri_ccall_process_id(); + cause_c& cause(); + unbounded_octstring& ri_cctrl_outcome(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const unbounded_octstring& ri_ccall_process_id() const; + const cause_c& cause() const; + const unbounded_octstring& ri_cctrl_outcome() const; + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICcontrolRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_cctrl_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + ri_crequest_id, + ra_nfunction_id, + ri_ccall_process_id, + ri_cctrl_hdr, + ri_cctrl_msg, + ri_cctrl_ack_request, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + unbounded_octstring& ri_ccall_process_id(); + unbounded_octstring& ri_cctrl_hdr(); + unbounded_octstring& ri_cctrl_msg(); + ri_cctrl_ack_request_e& ri_cctrl_ack_request(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const unbounded_octstring& ri_ccall_process_id() const; + const unbounded_octstring& ri_cctrl_hdr() const; + const unbounded_octstring& ri_cctrl_msg() const; + const ri_cctrl_ack_request_e& ri_cctrl_ack_request() const; + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICindication-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ri_cind_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + ri_crequest_id, + ra_nfunction_id, + ri_caction_id, + ri_cind_sn, + ri_cind_type, + ri_cind_hdr, + ri_cind_msg, + ri_ccall_process_id, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + uint16_t& ri_caction_id(); + uint32_t& ri_cind_sn(); + ri_cind_type_e& ri_cind_type(); + unbounded_octstring& ri_cind_hdr(); + unbounded_octstring& ri_cind_msg(); + unbounded_octstring& ri_ccall_process_id(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const uint16_t& ri_caction_id() const; + const uint32_t& ri_cind_sn() const; + const ri_cind_type_e& ri_cind_type() const; + const unbounded_octstring& ri_cind_hdr() const; + const unbounded_octstring& ri_cind_msg() const; + const unbounded_octstring& ri_ccall_process_id() const; + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICserviceQuery-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricservice_query_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, ra_nfunctions_accepted, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + ra_nfunctions_id_list_l& ra_nfunctions_accepted(); + const uint16_t& transaction_id() const; + const ra_nfunctions_id_list_l& ra_nfunctions_accepted() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICserviceUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricservice_upd_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { + transaction_id, + ra_nfunctions_added, + ra_nfunctions_modified, + ra_nfunctions_deleted, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + ra_nfunctions_list_l& ra_nfunctions_added(); + ra_nfunctions_list_l& ra_nfunctions_modified(); + ra_nfunctions_id_list_l& ra_nfunctions_deleted(); + const uint16_t& transaction_id() const; + const ra_nfunctions_list_l& ra_nfunctions_added() const; + const ra_nfunctions_list_l& ra_nfunctions_modified() const; + const ra_nfunctions_id_list_l& ra_nfunctions_deleted() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICserviceUpdateAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricservice_upd_ack_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, ra_nfunctions_accepted, ra_nfunctions_rejected, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + ra_nfunctions_id_list_l& ra_nfunctions_accepted(); + ra_nfunctions_idcause_list_l& ra_nfunctions_rejected(); + const uint16_t& transaction_id() const; + const ra_nfunctions_id_list_l& ra_nfunctions_accepted() const; + const ra_nfunctions_idcause_list_l& ra_nfunctions_rejected() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICserviceUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricservice_upd_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, time_to_wait, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + time_to_wait_e& time_to_wait(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + const time_to_wait_e& time_to_wait() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionDeleteFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_delete_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, cause, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + cause_c& cause(); + crit_diagnostics_s& crit_diagnostics(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const cause_c& cause() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionDeleteRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_delete_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionDeleteRequired-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_delete_required_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ricsubscription_to_be_remd, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ricsubscription_to_be_remd; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ricsubscription_list_with_cause_l& ricsubscription_to_be_remd() { return c; } + const ricsubscription_list_with_cause_l& ricsubscription_to_be_remd() const { return c; } + + private: + ricsubscription_list_with_cause_l c; + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionDeleteResponse-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_delete_resp_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_fail_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, cause, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + cause_c& cause(); + crit_diagnostics_s& crit_diagnostics(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const cause_c& cause() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, ricsubscription_details, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + ricsubscription_details_s& ricsubscription_details(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const ricsubscription_details_s& ricsubscription_details() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// RICsubscriptionResponse-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct ricsubscription_resp_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { ri_crequest_id, ra_nfunction_id, ri_cactions_admitted, ri_cactions_not_admitted, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ri_crequest_id_s& ri_crequest_id(); + uint16_t& ra_nfunction_id(); + ri_caction_admitted_list_l& ri_cactions_admitted(); + ri_caction_not_admitted_list_l& ri_cactions_not_admitted(); + const ri_crequest_id_s& ri_crequest_id() const; + const uint16_t& ra_nfunction_id() const; + const ri_caction_admitted_list_l& ri_cactions_admitted() const; + const ri_caction_not_admitted_list_l& ri_cactions_not_admitted() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// ResetRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct reset_request_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, cause, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + cause_c& cause(); + const uint16_t& transaction_id() const; + const cause_c& cause() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +// ResetResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +struct reset_resp_ies_o { + // Value ::= OPEN TYPE + struct value_c { + struct types_opts { + enum options { transaction_id, crit_diagnostics, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + value_c() = default; + value_c(const value_c& other); + value_c& operator=(const value_c& other); + ~value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& transaction_id(); + crit_diagnostics_s& crit_diagnostics(); + const uint16_t& transaction_id() const; + const crit_diagnostics_s& crit_diagnostics() const; + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // members lookup methods + static uint32_t idx_to_id(uint32_t idx); + static bool is_id_valid(const uint32_t& id); + static crit_e get_crit(const uint32_t& id); + static value_c get_value(const uint32_t& id); + static presence_e get_presence(const uint32_t& id); +}; + +struct e2_removal_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s cause; + ie_field_s crit_diagnostics; + + // sequence methods + e2_removal_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2RemovalFailure ::= SEQUENCE +using e2_removal_fail_s = elementary_procedure_option; + +// E2RemovalRequest ::= SEQUENCE +using e2_removal_request_s = elementary_procedure_option >; + +struct e2_removal_resp_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s crit_diagnostics; + + // sequence methods + e2_removal_resp_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2RemovalResponse ::= SEQUENCE +using e2_removal_resp_s = elementary_procedure_option; + +struct e2conn_upd_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool e2conn_upd_add_present = false; + bool e2conn_upd_rem_present = false; + bool e2conn_upd_modify_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 32, true> > e2conn_upd_add; + ie_field_s, 1, 32, true> > e2conn_upd_rem; + ie_field_s, 1, 32, true> > e2conn_upd_modify; + + // sequence methods + e2conn_upd_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionUpdate ::= SEQUENCE +using e2conn_upd_s = elementary_procedure_option; + +struct e2conn_upd_ack_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool e2conn_setup_present = false; + bool e2conn_setup_failed_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 32, true> > e2conn_setup; + ie_field_s, 1, 32, true> > + e2conn_setup_failed; + + // sequence methods + e2conn_upd_ack_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionUpdateAcknowledge ::= SEQUENCE +using e2conn_upd_ack_s = elementary_procedure_option; + +struct e2conn_upd_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool cause_present = false; + bool time_to_wait_present = false; + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s cause; + ie_field_s time_to_wait; + ie_field_s crit_diagnostics; + + // sequence methods + e2conn_upd_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2connectionUpdateFailure ::= SEQUENCE +using e2conn_upd_fail_s = elementary_procedure_option; + +struct e2node_cfg_upd_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool global_e2node_id_present = false; + bool e2node_component_cfg_addition_present = false; + bool e2node_component_cfg_upd_present = false; + bool e2node_component_cfg_removal_present = false; + bool e2node_tn_lassoc_removal_present = false; + ie_field_s > transaction_id; + ie_field_s global_e2node_id; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_addition; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_upd; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_removal; + ie_field_s, 1, 32, true> > + e2node_tn_lassoc_removal; + + // sequence methods + e2node_cfg_upd_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeConfigurationUpdate ::= SEQUENCE +using e2node_cfg_upd_s = elementary_procedure_option; + +struct e2node_cfg_upd_ack_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool e2node_component_cfg_addition_ack_present = false; + bool e2node_component_cfg_upd_ack_present = false; + bool e2node_component_cfg_removal_ack_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_addition_ack; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_upd_ack; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_removal_ack; + + // sequence methods + e2node_cfg_upd_ack_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeConfigurationUpdateAcknowledge ::= SEQUENCE +using e2node_cfg_upd_ack_s = elementary_procedure_option; + +struct e2node_cfg_upd_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool time_to_wait_present = false; + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s cause; + ie_field_s time_to_wait; + ie_field_s crit_diagnostics; + + // sequence methods + e2node_cfg_upd_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2nodeConfigurationUpdateFailure ::= SEQUENCE +using e2node_cfg_upd_fail_s = elementary_procedure_option; + +struct e2setup_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool time_to_wait_present = false; + bool crit_diagnostics_present = false; + bool tn_linfo_present = false; + ie_field_s > transaction_id; + ie_field_s cause; + ie_field_s time_to_wait; + ie_field_s crit_diagnostics; + ie_field_s tn_linfo; + + // sequence methods + e2setup_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2setupFailure ::= SEQUENCE +using e2setup_fail_s = elementary_procedure_option; + +struct e2setup_request_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + ie_field_s > transaction_id; + ie_field_s global_e2node_id; + ie_field_s, 1, 256, true> > ra_nfunctions_added; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_addition; + + // sequence methods + e2setup_request_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2setupRequest ::= SEQUENCE +using e2setup_request_s = elementary_procedure_option; + +struct e2setup_resp_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ra_nfunctions_accepted_present = false; + bool ra_nfunctions_rejected_present = false; + ie_field_s > transaction_id; + ie_field_s global_ric_id; + ie_field_s, 1, 256, true> > + ra_nfunctions_accepted; + ie_field_s, 1, 256, true> > + ra_nfunctions_rejected; + ie_field_s, 1, 1024, true> > + e2node_component_cfg_addition_ack; + + // sequence methods + e2setup_resp_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2setupResponse ::= SEQUENCE +using e2setup_resp_s = elementary_procedure_option; + +struct error_ind_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool transaction_id_present = false; + bool ri_crequest_id_present = false; + bool ra_nfunction_id_present = false; + bool cause_present = false; + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s cause; + ie_field_s crit_diagnostics; + + // sequence methods + error_ind_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ErrorIndication ::= SEQUENCE +using error_ind_s = elementary_procedure_option; + +struct ri_cctrl_ack_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ri_ccall_process_id_present = false; + bool ri_cctrl_outcome_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s > ri_ccall_process_id; + ie_field_s > ri_cctrl_outcome; + + // sequence methods + ri_cctrl_ack_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICcontrolAcknowledge ::= SEQUENCE +using ri_cctrl_ack_s = elementary_procedure_option; + +struct ri_cctrl_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ri_ccall_process_id_present = false; + bool ri_cctrl_outcome_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s > ri_ccall_process_id; + ie_field_s cause; + ie_field_s > ri_cctrl_outcome; + + // sequence methods + ri_cctrl_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICcontrolFailure ::= SEQUENCE +using ri_cctrl_fail_s = elementary_procedure_option; + +struct ri_cctrl_request_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ri_ccall_process_id_present = false; + bool ri_cctrl_ack_request_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s > ri_ccall_process_id; + ie_field_s > ri_cctrl_hdr; + ie_field_s > ri_cctrl_msg; + ie_field_s ri_cctrl_ack_request; + + // sequence methods + ri_cctrl_request_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICcontrolRequest ::= SEQUENCE +using ri_cctrl_request_s = elementary_procedure_option; + +struct ri_cind_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ri_cind_sn_present = false; + bool ri_ccall_process_id_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s > ri_caction_id; + ie_field_s > ri_cind_sn; + ie_field_s ri_cind_type; + ie_field_s > ri_cind_hdr; + ie_field_s > ri_cind_msg; + ie_field_s > ri_ccall_process_id; + + // sequence methods + ri_cind_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICindication ::= SEQUENCE +using ri_cind_s = elementary_procedure_option; + +struct ricservice_query_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ra_nfunctions_accepted_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 256, true> > + ra_nfunctions_accepted; + + // sequence methods + ricservice_query_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICserviceQuery ::= SEQUENCE +using ricservice_query_s = elementary_procedure_option; + +struct ricservice_upd_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ra_nfunctions_added_present = false; + bool ra_nfunctions_modified_present = false; + bool ra_nfunctions_deleted_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 256, true> > ra_nfunctions_added; + ie_field_s, 1, 256, true> > ra_nfunctions_modified; + ie_field_s, 1, 256, true> > + ra_nfunctions_deleted; + + // sequence methods + ricservice_upd_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICserviceUpdate ::= SEQUENCE +using ricservice_upd_s = elementary_procedure_option; + +struct ricservice_upd_ack_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ra_nfunctions_accepted_present = false; + bool ra_nfunctions_rejected_present = false; + ie_field_s > transaction_id; + ie_field_s, 1, 256, true> > + ra_nfunctions_accepted; + ie_field_s, 1, 256, true> > + ra_nfunctions_rejected; + + // sequence methods + ricservice_upd_ack_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICserviceUpdateAcknowledge ::= SEQUENCE +using ricservice_upd_ack_s = elementary_procedure_option; + +struct ricservice_upd_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool time_to_wait_present = false; + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s cause; + ie_field_s time_to_wait; + ie_field_s crit_diagnostics; + + // sequence methods + ricservice_upd_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICserviceUpdateFailure ::= SEQUENCE +using ricservice_upd_fail_s = elementary_procedure_option; + +struct ricsubscription_delete_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool crit_diagnostics_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s cause; + ie_field_s crit_diagnostics; + + // sequence methods + ricsubscription_delete_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionDeleteFailure ::= SEQUENCE +using ricsubscription_delete_fail_s = elementary_procedure_option; + +struct ricsubscription_delete_request_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + + // sequence methods + ricsubscription_delete_request_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionDeleteRequest ::= SEQUENCE +using ricsubscription_delete_request_s = elementary_procedure_option; + +// RICsubscriptionDeleteRequired ::= SEQUENCE +using ricsubscription_delete_required_s = + elementary_procedure_option >; + +struct ricsubscription_delete_resp_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + + // sequence methods + ricsubscription_delete_resp_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionDeleteResponse ::= SEQUENCE +using ricsubscription_delete_resp_s = elementary_procedure_option; + +struct ricsubscription_fail_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool crit_diagnostics_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s cause; + ie_field_s crit_diagnostics; + + // sequence methods + ricsubscription_fail_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionFailure ::= SEQUENCE +using ricsubscription_fail_s = elementary_procedure_option; + +struct ricsubscription_request_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s ricsubscription_details; + + // sequence methods + ricsubscription_request_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionRequest ::= SEQUENCE +using ricsubscription_request_s = elementary_procedure_option; + +struct ricsubscription_resp_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool ri_cactions_not_admitted_present = false; + ie_field_s ri_crequest_id; + ie_field_s > ra_nfunction_id; + ie_field_s, 1, 16, true> > + ri_cactions_admitted; + ie_field_s, 0, 16, true> > + ri_cactions_not_admitted; + + // sequence methods + ricsubscription_resp_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RICsubscriptionResponse ::= SEQUENCE +using ricsubscription_resp_s = elementary_procedure_option; + +struct reset_request_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + ie_field_s > transaction_id; + ie_field_s cause; + + // sequence methods + reset_request_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ResetRequest ::= SEQUENCE +using reset_request_s = elementary_procedure_option; + +struct reset_resp_ies_container { + template + using ie_field_s = protocol_ie_container_item_s; + + // member variables + bool crit_diagnostics_present = false; + ie_field_s > transaction_id; + ie_field_s crit_diagnostics; + + // sequence methods + reset_resp_ies_container(); + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ResetResponse ::= SEQUENCE +using reset_resp_s = elementary_procedure_option; + +// E2AP-ELEMENTARY-PROCEDURES ::= OBJECT SET OF E2AP-ELEMENTARY-PROCEDURE +struct e2_ap_elem_procs_o { + // InitiatingMessage ::= OPEN TYPE + struct init_msg_c { + struct types_opts { + enum options { + ricsubscription_request, + ricsubscription_delete_request, + ricservice_upd, + ri_cctrl_request, + e2setup_request, + e2node_cfg_upd, + e2conn_upd, + reset_request, + e2_removal_request, + ri_cind, + ricservice_query, + error_ind, + ricsubscription_delete_required, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + init_msg_c() = default; + init_msg_c(const init_msg_c& other); + init_msg_c& operator=(const init_msg_c& other); + ~init_msg_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ricsubscription_request_s& ricsubscription_request(); + ricsubscription_delete_request_s& ricsubscription_delete_request(); + ricservice_upd_s& ricservice_upd(); + ri_cctrl_request_s& ri_cctrl_request(); + e2setup_request_s& e2setup_request(); + e2node_cfg_upd_s& e2node_cfg_upd(); + e2conn_upd_s& e2conn_upd(); + reset_request_s& reset_request(); + e2_removal_request_s& e2_removal_request(); + ri_cind_s& ri_cind(); + ricservice_query_s& ricservice_query(); + error_ind_s& error_ind(); + ricsubscription_delete_required_s& ricsubscription_delete_required(); + const ricsubscription_request_s& ricsubscription_request() const; + const ricsubscription_delete_request_s& ricsubscription_delete_request() const; + const ricservice_upd_s& ricservice_upd() const; + const ri_cctrl_request_s& ri_cctrl_request() const; + const e2setup_request_s& e2setup_request() const; + const e2node_cfg_upd_s& e2node_cfg_upd() const; + const e2conn_upd_s& e2conn_upd() const; + const reset_request_s& reset_request() const; + const e2_removal_request_s& e2_removal_request() const; + const ri_cind_s& ri_cind() const; + const ricservice_query_s& ricservice_query() const; + const error_ind_s& error_ind() const; + const ricsubscription_delete_required_s& ricsubscription_delete_required() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + // SuccessfulOutcome ::= OPEN TYPE + struct successful_outcome_c { + struct types_opts { + enum options { + ricsubscription_resp, + ricsubscription_delete_resp, + ricservice_upd_ack, + ri_cctrl_ack, + e2setup_resp, + e2node_cfg_upd_ack, + e2conn_upd_ack, + reset_resp, + e2_removal_resp, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + successful_outcome_c() = default; + successful_outcome_c(const successful_outcome_c& other); + successful_outcome_c& operator=(const successful_outcome_c& other); + ~successful_outcome_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ricsubscription_resp_s& ricsubscription_resp(); + ricsubscription_delete_resp_s& ricsubscription_delete_resp(); + ricservice_upd_ack_s& ricservice_upd_ack(); + ri_cctrl_ack_s& ri_cctrl_ack(); + e2setup_resp_s& e2setup_resp(); + e2node_cfg_upd_ack_s& e2node_cfg_upd_ack(); + e2conn_upd_ack_s& e2conn_upd_ack(); + reset_resp_s& reset_resp(); + e2_removal_resp_s& e2_removal_resp(); + const ricsubscription_resp_s& ricsubscription_resp() const; + const ricsubscription_delete_resp_s& ricsubscription_delete_resp() const; + const ricservice_upd_ack_s& ricservice_upd_ack() const; + const ri_cctrl_ack_s& ri_cctrl_ack() const; + const e2setup_resp_s& e2setup_resp() const; + const e2node_cfg_upd_ack_s& e2node_cfg_upd_ack() const; + const e2conn_upd_ack_s& e2conn_upd_ack() const; + const reset_resp_s& reset_resp() const; + const e2_removal_resp_s& e2_removal_resp() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + // UnsuccessfulOutcome ::= OPEN TYPE + struct unsuccessful_outcome_c { + struct types_opts { + enum options { + ricsubscription_fail, + ricsubscription_delete_fail, + ricservice_upd_fail, + ri_cctrl_fail, + e2setup_fail, + e2node_cfg_upd_fail, + e2conn_upd_fail, + e2_removal_fail, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + unsuccessful_outcome_c() = default; + unsuccessful_outcome_c(const unsuccessful_outcome_c& other); + unsuccessful_outcome_c& operator=(const unsuccessful_outcome_c& other); + ~unsuccessful_outcome_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ricsubscription_fail_s& ricsubscription_fail(); + ricsubscription_delete_fail_s& ricsubscription_delete_fail(); + ricservice_upd_fail_s& ricservice_upd_fail(); + ri_cctrl_fail_s& ri_cctrl_fail(); + e2setup_fail_s& e2setup_fail(); + e2node_cfg_upd_fail_s& e2node_cfg_upd_fail(); + e2conn_upd_fail_s& e2conn_upd_fail(); + e2_removal_fail_s& e2_removal_fail(); + const ricsubscription_fail_s& ricsubscription_fail() const; + const ricsubscription_delete_fail_s& ricsubscription_delete_fail() const; + const ricservice_upd_fail_s& ricservice_upd_fail() const; + const ri_cctrl_fail_s& ri_cctrl_fail() const; + const e2setup_fail_s& e2setup_fail() const; + const e2node_cfg_upd_fail_s& e2node_cfg_upd_fail() const; + const e2conn_upd_fail_s& e2conn_upd_fail() const; + const e2_removal_fail_s& e2_removal_fail() const; + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + + // members lookup methods + static uint16_t idx_to_proc_code(uint32_t idx); + static bool is_proc_code_valid(const uint16_t& proc_code); + static init_msg_c get_init_msg(const uint16_t& proc_code); + static successful_outcome_c get_successful_outcome(const uint16_t& proc_code); + static unsuccessful_outcome_c get_unsuccessful_outcome(const uint16_t& proc_code); + static crit_e get_crit(const uint16_t& proc_code); +}; + +// InitiatingMessage ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +struct init_msg_s { + uint16_t proc_code = 0; + crit_e crit; + e2_ap_elem_procs_o::init_msg_c value; + + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool load_info_obj(const uint16_t& proc_code_); +}; + +// SuccessfulOutcome ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +struct successful_outcome_s { + uint16_t proc_code = 0; + crit_e crit; + e2_ap_elem_procs_o::successful_outcome_c value; + + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool load_info_obj(const uint16_t& proc_code_); +}; + +// UnsuccessfulOutcome ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +struct unsuccessful_outcome_s { + uint16_t proc_code = 0; + crit_e crit; + e2_ap_elem_procs_o::unsuccessful_outcome_c value; + + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool load_info_obj(const uint16_t& proc_code_); +}; + +// E2AP-PDU ::= CHOICE +struct e2_ap_pdu_c { + struct types_opts { + enum options { init_msg, successful_outcome, unsuccessful_outcome, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + e2_ap_pdu_c() = default; + e2_ap_pdu_c(const e2_ap_pdu_c& other); + e2_ap_pdu_c& operator=(const e2_ap_pdu_c& other); + ~e2_ap_pdu_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + init_msg_s& init_msg() + { + assert_choice_type(types::init_msg, type_, "E2AP-PDU"); + return c.get(); + } + successful_outcome_s& successful_outcome() + { + assert_choice_type(types::successful_outcome, type_, "E2AP-PDU"); + return c.get(); + } + unsuccessful_outcome_s& unsuccessful_outcome() + { + assert_choice_type(types::unsuccessful_outcome, type_, "E2AP-PDU"); + return c.get(); + } + const init_msg_s& init_msg() const + { + assert_choice_type(types::init_msg, type_, "E2AP-PDU"); + return c.get(); + } + const successful_outcome_s& successful_outcome() const + { + assert_choice_type(types::successful_outcome, type_, "E2AP-PDU"); + return c.get(); + } + const unsuccessful_outcome_s& unsuccessful_outcome() const + { + assert_choice_type(types::unsuccessful_outcome, type_, "E2AP-PDU"); + return c.get(); + } + init_msg_s& set_init_msg(); + successful_outcome_s& set_successful_outcome(); + unsuccessful_outcome_s& set_unsuccessful_outcome(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// ProtocolIE-FieldPair{E2AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE{{E2AP-PROTOCOL-IES-PAIR}} +template +struct protocol_ie_field_pair_s { + uint32_t id = 0; + crit_e first_crit; + typename ies_set_paramT_::first_value_c first_value; + crit_e second_crit; + typename ies_set_paramT_::second_value_c second_value; + + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool load_info_obj(const uint32_t& id_); +}; + +// ProtocolIE-ContainerPair{E2AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE (SIZE (0..65535)) OF ProtocolIE-FieldPair +template +using protocol_ie_container_pair_l = dyn_seq_of, 0, 65535, true>; + +} // namespace e2ap +} // namespace asn1 + +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; + +#endif // SRSASN1_E2AP_H diff --git a/lib/include/srsran/asn1/e2sm.h b/lib/include/srsran/asn1/e2sm.h new file mode 100644 index 0000000000..78a2f32e0a --- /dev/null +++ b/lib/include/srsran/asn1/e2sm.h @@ -0,0 +1,1353 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +/******************************************************************************* + * + * 3GPP TS ASN1 E2SM v15.3.0 (2019-03) + * + ******************************************************************************/ + +#ifndef SRSASN1_E2SM_H +#define SRSASN1_E2SM_H + +#include "asn1_utils.h" +#include +#include + +namespace asn1 { +namespace e2sm { + +/******************************************************************************* + * Constant Definitions + ******************************************************************************/ + +#define ASN1_E2SM_MAX_E1_APID 65535 +#define ASN1_E2SM_MAX_F1_APID 4 +#define ASN1_E2SM_MAX_EARFCN 65535 +#define ASN1_E2SM_MAX_NRARFCN 3279165 +#define ASN1_E2SM_MAXNOOF_NR_CELL_BANDS 32 + +/******************************************************************************* + * Struct Definitions + ******************************************************************************/ + +// EUTRA-CGI ::= SEQUENCE +struct eutra_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<28, false, true> eutra_cell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-CGI ::= SEQUENCE +struct nr_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<36, false, true> nrcell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CGI ::= CHOICE +struct cgi_c { + struct types_opts { + enum options { nr_cgi, eutra_cgi, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + cgi_c() = default; + cgi_c(const cgi_c& other); + cgi_c& operator=(const cgi_c& other); + ~cgi_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_cgi_s& nr_cgi() + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + eutra_cgi_s& eutra_cgi() + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + const nr_cgi_s& nr_cgi() const + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + const eutra_cgi_s& eutra_cgi() const + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + nr_cgi_s& set_nr_cgi(); + eutra_cgi_s& set_eutra_cgi(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// GUAMI ::= SEQUENCE +struct guami_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<8, false, true> amf_region_id; + fixed_bitstring<10, false, true> amf_set_id; + fixed_bitstring<6, false, true> amf_pointer; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GUMMEI ::= SEQUENCE +struct gummei_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_octstring<2, true> mme_group_id; + fixed_octstring<1, true> mme_code; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CoreCPID ::= CHOICE +struct core_cpid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + core_cpid_c() = default; + core_cpid_c(const core_cpid_c& other); + core_cpid_c& operator=(const core_cpid_c& other); + ~core_cpid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + guami_s& five_gc() + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + gummei_s& epc() + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + const guami_s& five_gc() const + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + const gummei_s& epc() const + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + guami_s& set_five_gc(); + gummei_s& set_epc(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// ENB-ID ::= CHOICE +struct enb_id_c { + struct types_opts { + enum options { macro_enb_id, home_enb_id, /*...*/ short_macro_enb_id, long_macro_enb_id, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_c() = default; + enb_id_c(const enb_id_c& other); + enb_id_c& operator=(const enb_id_c& other); + ~enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_enb_id() + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<28, false, true>& home_enb_id() + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_enb_id() + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_enb_id() + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_enb_id() const + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<28, false, true>& home_enb_id() const + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_enb_id() const + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_enb_id() const + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_enb_id(); + fixed_bitstring<28, false, true>& set_home_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// GlobalENB-ID ::= SEQUENCE +struct global_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GNB-ID ::= CHOICE +struct gnb_id_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalGNB-ID ::= SEQUENCE +struct global_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + gnb_id_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NgENB-ID ::= CHOICE +struct ng_enb_id_c { + struct types_opts { + enum options { macro_ng_enb_id, short_macro_ng_enb_id, long_macro_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ng_enb_id_c() = default; + ng_enb_id_c(const ng_enb_id_c& other); + ng_enb_id_c& operator=(const ng_enb_id_c& other); + ~ng_enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_ng_enb_id() + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_ng_enb_id() + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_ng_enb_id() + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_ng_enb_id() const + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_ng_enb_id() const + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_ng_enb_id() const + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_ng_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_ng_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_ng_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// GlobalNgENB-ID ::= SEQUENCE +struct global_ng_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + ng_enb_id_c ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalRANNodeID ::= CHOICE +struct global_ran_node_id_c { + struct types_opts { + enum options { global_gnb_id, global_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_ran_node_id_c() = default; + global_ran_node_id_c(const global_ran_node_id_c& other); + global_ran_node_id_c& operator=(const global_ran_node_id_c& other); + ~global_ran_node_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_gnb_id_s& global_gnb_id() + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_ng_enb_id_s& global_ng_enb_id() + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_gnb_id_s& global_gnb_id() const + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_ng_enb_id_s& global_ng_enb_id() const + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_gnb_id_s& set_global_gnb_id(); + global_ng_enb_id_s& set_global_ng_enb_id(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// EN-GNB-ID ::= CHOICE +struct en_gnb_id_c { + struct types_opts { + enum options { en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::en_g_nb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& en_g_nb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& en_g_nb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalenGNB-ID ::= SEQUENCE +struct globalen_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + en_gnb_id_c en_g_nb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GroupID ::= CHOICE +struct group_id_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + group_id_c() = default; + group_id_c(const group_id_c& other); + group_id_c& operator=(const group_id_c& other); + ~group_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// InterfaceID-E1 ::= SEQUENCE +struct interface_id_e1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_cu_up_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-F1 ::= SEQUENCE +struct interface_id_f1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-NG ::= SEQUENCE +struct interface_id_ng_s { + bool ext = false; + guami_s guami; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-S1 ::= SEQUENCE +struct interface_id_s1_s { + bool ext = false; + gummei_s gummei; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-W1 ::= SEQUENCE +struct interface_id_w1_s { + bool ext = false; + global_ng_enb_id_s global_ng_enb_id; + uint64_t ng_enb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-X2 ::= SEQUENCE +struct interface_id_x2_s { + struct node_type_c_ { + struct types_opts { + enum options { global_enb_id, global_en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + node_type_c_() = default; + node_type_c_(const node_type_c_& other); + node_type_c_& operator=(const node_type_c_& other); + ~node_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_enb_id_s& global_enb_id() + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + globalen_gnb_id_s& global_en_g_nb_id() + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + const global_enb_id_s& global_enb_id() const + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + const globalen_gnb_id_s& global_en_g_nb_id() const + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + global_enb_id_s& set_global_enb_id(); + globalen_gnb_id_s& set_global_en_g_nb_id(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + node_type_c_ node_type; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-Xn ::= SEQUENCE +struct interface_id_xn_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceIdentifier ::= CHOICE +struct interface_id_c { + struct types_opts { + enum options { ng, xn, f1, e1, s1, x2, w1, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + interface_id_c() = default; + interface_id_c(const interface_id_c& other); + interface_id_c& operator=(const interface_id_c& other); + ~interface_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + interface_id_ng_s& ng() + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_xn_s& xn() + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_f1_s& f1() + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_e1_s& e1() + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_s1_s& s1() + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_x2_s& x2() + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_w1_s& w1() + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_ng_s& ng() const + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_xn_s& xn() const + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_f1_s& f1() const + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_e1_s& e1() const + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_s1_s& s1() const + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_x2_s& x2() const + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_w1_s& w1() const + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_ng_s& set_ng(); + interface_id_xn_s& set_xn(); + interface_id_f1_s& set_f1(); + interface_id_e1_s& set_e1(); + interface_id_s1_s& set_s1(); + interface_id_x2_s& set_x2(); + interface_id_w1_s& set_w1(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// FreqBandNrItem ::= SEQUENCE +struct freq_band_nr_item_s { + bool ext = false; + uint16_t freq_band_ind_nr = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-ARFCN ::= SEQUENCE +struct nr_arfcn_s { + using freq_band_list_nr_l_ = dyn_array; + + // member variables + bool ext = false; + uint32_t nrarfcn = 0; + freq_band_list_nr_l_ freq_band_list_nr; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// QoSID ::= CHOICE +struct qo_sid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + qo_sid_c() = default; + qo_sid_c(const qo_sid_c& other); + qo_sid_c& operator=(const qo_sid_c& other); + ~qo_sid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// RRCclass-LTE ::= ENUMERATED +struct rr_cclass_lte_opts { + enum options { + bcch_bch, + bcch_bch_mbms, + bcch_dl_sch, + bcch_dl_sch_br, + bcch_dl_sch_mbms, + mcch, + pcch, + dl_ccch, + dl_dcch, + ul_ccch, + ul_dcch, + sc_mcch, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated rr_cclass_lte_e; + +// RRCclass-NR ::= ENUMERATED +struct rr_cclass_nr_opts { + enum options { bcch_bch, bcch_dl_sch, dl_ccch, dl_dcch, pcch, ul_ccch, ul_ccch1, ul_dcch, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated rr_cclass_nr_e; + +// RRC-MessageID ::= SEQUENCE +struct rrc_msg_id_s { + struct rrc_type_c_ { + struct types_opts { + enum options { lte, nr, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + rrc_type_c_() = default; + rrc_type_c_(const rrc_type_c_& other); + rrc_type_c_& operator=(const rrc_type_c_& other); + ~rrc_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + rr_cclass_lte_e& lte() + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + rr_cclass_nr_e& nr() + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + const rr_cclass_lte_e& lte() const + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + const rr_cclass_nr_e& nr() const + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + rr_cclass_lte_e& set_lte(); + rr_cclass_nr_e& set_nr(); + + private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + rrc_type_c_ rrc_type; + int64_t msg_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// S-NSSAI ::= SEQUENCE +struct s_nssai_s { + bool ext = false; + bool sd_present = false; + fixed_octstring<1, true> sst; + fixed_octstring<3, true> sd; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ServingCell-ARFCN ::= CHOICE +struct serving_cell_arfcn_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_arfcn_c() = default; + serving_cell_arfcn_c(const serving_cell_arfcn_c& other); + serving_cell_arfcn_c& operator=(const serving_cell_arfcn_c& other); + ~serving_cell_arfcn_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_arfcn_s& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + uint32_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + const nr_arfcn_s& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + const uint32_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + nr_arfcn_s& set_nr(); + uint32_t& set_eutra(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// ServingCell-PCI ::= CHOICE +struct serving_cell_pci_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_pci_c() = default; + serving_cell_pci_c(const serving_cell_pci_c& other); + serving_cell_pci_c& operator=(const serving_cell_pci_c& other); + ~serving_cell_pci_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& set_nr(); + uint16_t& set_eutra(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_e1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_f1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-E1AP-ID-List ::= SEQUENCE (SIZE (1..65535)) OF UEID-GNB-CU-CP-E1AP-ID-Item +using ueid_gnb_cu_cp_e1_ap_id_list_l = dyn_array; + +// UEID-GNB-CU-F1AP-ID-List ::= SEQUENCE (SIZE (1..4)) OF UEID-GNB-CU-CP-F1AP-ID-Item +using ueid_gnb_cu_f1_ap_id_list_l = dyn_array; + +// UEID-EN-GNB ::= SEQUENCE +struct ueid_en_gnb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool gnb_cu_ue_f1_ap_id_present = false; + bool ran_ueid_present = false; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + uint64_t gnb_cu_ue_f1_ap_id = 0; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-ENB ::= SEQUENCE +struct ueid_enb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_present = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool global_enb_id_present = false; + uint64_t mme_ue_s1ap_id = 0; + gummei_s gummei; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB ::= SEQUENCE +struct ueid_gnb_s { + bool ext = false; + bool ran_ueid_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_gnb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + ueid_gnb_cu_f1_ap_id_list_l gnb_cu_ue_f1_ap_id_list; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_gnb_id_s global_gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-UP ::= SEQUENCE +struct ueid_gnb_cu_up_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-DU ::= SEQUENCE +struct ueid_gnb_du_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB ::= SEQUENCE +struct ueid_ng_enb_s { + bool ext = false; + bool ng_enb_cu_ue_w1_ap_id_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_ng_enb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_ng_enb_id_s global_ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB-DU ::= SEQUENCE +struct ueid_ng_enb_du_s { + bool ext = false; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID ::= CHOICE +struct ueid_c { + struct types_opts { + enum options { + gnb_ueid, + gnb_du_ueid, + gnb_cu_up_ueid, + ng_enb_ueid, + ng_enb_du_ueid, + en_g_nb_ueid, + enb_ueid, + // ... + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ueid_c() = default; + ueid_c(const ueid_c& other); + ueid_c& operator=(const ueid_c& other); + ~ueid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ueid_gnb_s& gnb_ueid() + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_du_s& gnb_du_ueid() + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_cu_up_s& gnb_cu_up_ueid() + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_s& ng_enb_ueid() + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_du_s& ng_enb_du_ueid() + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_en_gnb_s& en_g_nb_ueid() + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + ueid_enb_s& enb_ueid() + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_s& gnb_ueid() const + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_du_s& gnb_du_ueid() const + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_cu_up_s& gnb_cu_up_ueid() const + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_s& ng_enb_ueid() const + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_du_s& ng_enb_du_ueid() const + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_en_gnb_s& en_g_nb_ueid() const + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_enb_s& enb_ueid() const + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_s& set_gnb_ueid(); + ueid_gnb_du_s& set_gnb_du_ueid(); + ueid_gnb_cu_up_s& set_gnb_cu_up_ueid(); + ueid_ng_enb_s& set_ng_enb_ueid(); + ueid_ng_enb_du_s& set_ng_enb_du_ueid(); + ueid_en_gnb_s& set_en_g_nb_ueid(); + ueid_enb_s& set_enb_ueid(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +} // namespace e2sm +} // namespace asn1 + +#endif // SRSASN1_E2SM_H diff --git a/lib/include/srsran/asn1/e2sm_kpm.h b/lib/include/srsran/asn1/e2sm_kpm.h new file mode 100644 index 0000000000..c5585729a6 --- /dev/null +++ b/lib/include/srsran/asn1/e2sm_kpm.h @@ -0,0 +1,2287 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +/******************************************************************************* + * + * 3GPP TS ASN1 E2SM KPM v15.3.0 (2019-03) + * + ******************************************************************************/ + +#pragma once + +#include "asn1_utils.h" +#include +#include + +namespace asn1 { +namespace e2sm_kpm { + +/******************************************************************************* + * Constant Definitions + ******************************************************************************/ + +#define ASN1_E2SM_KPM_MAXOF_MSG_PROTOCOL_TESTS 15 +#define ASN1_E2SM_KPM_MAXOF_RICSTYLES 63 +#define ASN1_E2SM_KPM_MAXNOOF_QCI 256 +#define ASN1_E2SM_KPM_MAXNOOF_QOSFLOWS 64 +#define ASN1_E2SM_KPM_MAXNOOF_SLICE_ITEMS 1024 +#define ASN1_E2SM_KPM_MAXNOOF_CONTAINER_LIST_ITEMS 3 +#define ASN1_E2SM_KPM_MAX_CELLING_NBDU 512 +#define ASN1_E2SM_KPM_MAXOF_CONTAINERS 8 +#define ASN1_E2SM_KPM_MAX_PLMN 12 + +/******************************************************************************* + * Struct Definitions + ******************************************************************************/ + +// EUTRA-CGI ::= SEQUENCE +struct eutra_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<28, false, true> eutra_cell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-CGI ::= SEQUENCE +struct nr_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<36, false, true> nrcell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CGI ::= CHOICE +struct cgi_c { + struct types_opts { + enum options { nr_cgi, eutra_cgi, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + cgi_c() = default; + cgi_c(const cgi_c& other); + cgi_c& operator=(const cgi_c& other); + ~cgi_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_cgi_s& nr_cgi() + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + eutra_cgi_s& eutra_cgi() + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + const nr_cgi_s& nr_cgi() const + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + const eutra_cgi_s& eutra_cgi() const + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + nr_cgi_s& set_nr_cgi(); + eutra_cgi_s& set_eutra_cgi(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// FQIPERSlicesPerPlmnListItem ::= SEQUENCE +struct fqiper_slices_per_plmn_list_item_s { + bool ext = false; + bool pdcp_bytes_dl_present = false; + bool pdcp_bytes_ul_present = false; + uint16_t five_qi = 0; + uint64_t pdcp_bytes_dl = 0; + uint64_t pdcp_bytes_ul = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SNSSAI ::= SEQUENCE +struct snssai_s { + bool sd_present = false; + fixed_octstring<1, true> sst; + fixed_octstring<3, true> sd; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PerQCIReportListItemFormat ::= SEQUENCE +struct per_qci_report_list_item_format_s { + bool ext = false; + bool pdcp_bytes_dl_present = false; + bool pdcp_bytes_ul_present = false; + uint16_t qci = 0; + uint64_t pdcp_bytes_dl = 0; + uint64_t pdcp_bytes_ul = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SliceToReportListItem ::= SEQUENCE +struct slice_to_report_list_item_s { + using fqiper_slices_per_plmn_list_l_ = dyn_array; + + // member variables + bool ext = false; + snssai_s slice_id; + fqiper_slices_per_plmn_list_l_ fqiper_slices_per_plmn_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// EPC-CUUP-PM-Format ::= SEQUENCE +struct epc_cuup_pm_format_s { + using per_qci_report_list_l_ = dyn_array; + + // member variables + bool ext = false; + per_qci_report_list_l_ per_qci_report_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// FGC-CUUP-PM-Format ::= SEQUENCE +struct fgc_cuup_pm_format_s { + using slice_to_report_list_l_ = dyn_array; + + // member variables + bool ext = false; + slice_to_report_list_l_ slice_to_report_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PlmnID-List ::= SEQUENCE +struct plmn_id_list_s { + bool ext = false; + bool cu_up_pm_minus5_gc_present = false; + bool cu_up_pm_epc_present = false; + fixed_octstring<3, true> plmn_id; + fgc_cuup_pm_format_s cu_up_pm_minus5_gc; + epc_cuup_pm_format_s cu_up_pm_epc; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CUUPMeasurement-Container ::= SEQUENCE +struct cuup_meas_container_s { + using plmn_list_l_ = dyn_array; + + // member variables + bool ext = false; + plmn_list_l_ plmn_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// FQIPERSlicesPerPlmnPerCellListItem ::= SEQUENCE +struct fqiper_slices_per_plmn_per_cell_list_item_s { + bool ext = false; + bool dl_prbusage_present = false; + bool ul_prbusage_present = false; + uint16_t five_qi = 0; + uint8_t dl_prbusage = 0; + uint8_t ul_prbusage = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PerQCIReportListItem ::= SEQUENCE +struct per_qci_report_list_item_s { + bool ext = false; + bool dl_prbusage_present = false; + bool ul_prbusage_present = false; + uint16_t qci = 0; + uint8_t dl_prbusage = 0; + uint8_t ul_prbusage = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SlicePerPlmnPerCellListItem ::= SEQUENCE +struct slice_per_plmn_per_cell_list_item_s { + using fqiper_slices_per_plmn_per_cell_list_l_ = dyn_array; + + // member variables + bool ext = false; + snssai_s slice_id; + fqiper_slices_per_plmn_per_cell_list_l_ fqiper_slices_per_plmn_per_cell_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// EPC-DU-PM-Container ::= SEQUENCE +struct epc_du_pm_container_s { + using per_qci_report_list_l_ = dyn_array; + + // member variables + bool ext = false; + per_qci_report_list_l_ per_qci_report_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// FGC-DU-PM-Container ::= SEQUENCE +struct fgc_du_pm_container_s { + using slice_per_plmn_per_cell_list_l_ = dyn_array; + + // member variables + bool ext = false; + slice_per_plmn_per_cell_list_l_ slice_per_plmn_per_cell_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NRCGI ::= SEQUENCE +struct nrcgi_s { + fixed_octstring<3, true> plmn_id; + fixed_bitstring<36, false, true> nrcell_id; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ServedPlmnPerCellListItem ::= SEQUENCE +struct served_plmn_per_cell_list_item_s { + bool ext = false; + bool du_pm_minus5_gc_present = false; + bool du_pm_epc_present = false; + fixed_octstring<3, true> plmn_id; + fgc_du_pm_container_s du_pm_minus5_gc; + epc_du_pm_container_s du_pm_epc; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CellResourceReportListItem ::= SEQUENCE +struct cell_res_report_list_item_s { + using served_plmn_per_cell_list_l_ = dyn_array; + + // member variables + bool ext = false; + bool dl_totalof_available_prbs_present = false; + bool ul_totalof_available_prbs_present = false; + nrcgi_s nrcgi; + uint8_t dl_totalof_available_prbs = 0; + uint8_t ul_totalof_available_prbs = 0; + served_plmn_per_cell_list_l_ served_plmn_per_cell_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GUAMI ::= SEQUENCE +struct guami_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<8, false, true> amf_region_id; + fixed_bitstring<10, false, true> amf_set_id; + fixed_bitstring<6, false, true> amf_pointer; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GUMMEI ::= SEQUENCE +struct gummei_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_octstring<2, true> mme_group_id; + fixed_octstring<1, true> mme_code; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CoreCPID ::= CHOICE +struct core_cpid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + core_cpid_c() = default; + core_cpid_c(const core_cpid_c& other); + core_cpid_c& operator=(const core_cpid_c& other); + ~core_cpid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + guami_s& five_gc() + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + gummei_s& epc() + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + const guami_s& five_gc() const + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + const gummei_s& epc() const + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + guami_s& set_five_gc(); + gummei_s& set_epc(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// E2SM-KPM-ActionDefinition ::= SEQUENCE +struct e2_sm_kpm_action_definition_s { + bool ext = false; + int64_t ric_style_type = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RT-Period-IE ::= ENUMERATED +struct rt_period_ie_opts { + enum options { + ms10, + ms20, + ms32, + ms40, + ms60, + ms64, + ms70, + ms80, + ms128, + ms160, + ms256, + ms320, + ms512, + ms640, + ms1024, + ms1280, + ms2048, + ms2560, + ms5120, + ms10240, + // ... + nulltype + } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; +}; +typedef enumerated rt_period_ie_e; + +// Trigger-ConditionIE-Item ::= SEQUENCE +struct trigger_condition_ie_item_s { + bool ext = false; + rt_period_ie_e report_period_ie; + // ... + + // sequence methRaods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-EventTriggerDefinition-Format1 ::= SEQUENCE +struct e2_sm_kpm_event_trigger_definition_format1_s { + using policy_test_list_l_ = dyn_array; + + // member variables + bool ext = false; + policy_test_list_l_ policy_test_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-EventTriggerDefinition ::= CHOICE +struct e2_sm_kpm_event_trigger_definition_c { + struct types_opts { + enum options { event_definition_format1, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::event_definition_format1; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_event_trigger_definition_format1_s& event_definition_format1() { return c; } + const e2_sm_kpm_event_trigger_definition_format1_s& event_definition_format1() const { return c; } + +private: + e2_sm_kpm_event_trigger_definition_format1_s c; +}; + +// ENB-ID ::= CHOICE +struct enb_id_c { + struct types_opts { + enum options { macro_enb_id, home_enb_id, /*...*/ short_macro_enb_id, long_macro_enb_id, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_c() = default; + enb_id_c(const enb_id_c& other); + enb_id_c& operator=(const enb_id_c& other); + ~enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_enb_id() + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<28, false, true>& home_enb_id() + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_enb_id() + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_enb_id() + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_enb_id() const + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<28, false, true>& home_enb_id() const + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_enb_id() const + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_enb_id() const + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_enb_id(); + fixed_bitstring<28, false, true>& set_home_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// ENB-ID-Choice ::= CHOICE +struct enb_id_choice_c { + struct types_opts { + enum options { enb_id_macro, enb_id_shortmacro, enb_id_longmacro, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_choice_c() = default; + enb_id_choice_c(const enb_id_choice_c& other); + enb_id_choice_c& operator=(const enb_id_choice_c& other); + ~enb_id_choice_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& enb_id_macro() + { + assert_choice_type(types::enb_id_macro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<18, false, true>& enb_id_shortmacro() + { + assert_choice_type(types::enb_id_shortmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<21, false, true>& enb_id_longmacro() + { + assert_choice_type(types::enb_id_longmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& enb_id_macro() const + { + assert_choice_type(types::enb_id_macro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& enb_id_shortmacro() const + { + assert_choice_type(types::enb_id_shortmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& enb_id_longmacro() const + { + assert_choice_type(types::enb_id_longmacro, type_, "ENB-ID-Choice"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_enb_id_macro(); + fixed_bitstring<18, false, true>& set_enb_id_shortmacro(); + fixed_bitstring<21, false, true>& set_enb_id_longmacro(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// ENGNB-ID ::= CHOICE +struct engnb_id_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GNB-ID-Choice ::= CHOICE +struct gnb_id_choice_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalENB-ID ::= SEQUENCE +struct global_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalenGNB-ID ::= SEQUENCE +struct globalen_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + engnb_id_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalgNB-ID ::= SEQUENCE +struct globalg_nb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + gnb_id_choice_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalngeNB-ID ::= SEQUENCE +struct globalngenb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_choice_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalKPMnode-eNB-ID ::= SEQUENCE +struct global_kp_mnode_enb_id_s { + bool ext = false; + global_enb_id_s global_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalKPMnode-en-gNB-ID ::= SEQUENCE +struct global_kp_mnode_en_g_nb_id_s { + bool ext = false; + globalen_gnb_id_s global_g_nb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalKPMnode-gNB-ID ::= SEQUENCE +struct global_kp_mnode_g_nb_id_s { + bool ext = false; + bool gnb_cu_up_id_present = false; + bool gnb_du_id_present = false; + globalg_nb_id_s global_g_nb_id; + uint64_t gnb_cu_up_id = 0; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalKPMnode-ng-eNB-ID ::= SEQUENCE +struct global_kp_mnode_ng_enb_id_s { + bool ext = false; + globalngenb_id_s global_ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalKPMnode-ID ::= CHOICE +struct global_kp_mnode_id_c { + struct types_opts { + enum options { gnb, en_g_nb, ng_enb, enb, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_kp_mnode_id_c() = default; + global_kp_mnode_id_c(const global_kp_mnode_id_c& other); + global_kp_mnode_id_c& operator=(const global_kp_mnode_id_c& other); + ~global_kp_mnode_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_kp_mnode_g_nb_id_s& gnb() + { + assert_choice_type(types::gnb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + global_kp_mnode_en_g_nb_id_s& en_g_nb() + { + assert_choice_type(types::en_g_nb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + global_kp_mnode_ng_enb_id_s& ng_enb() + { + assert_choice_type(types::ng_enb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + global_kp_mnode_enb_id_s& enb() + { + assert_choice_type(types::enb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + const global_kp_mnode_g_nb_id_s& gnb() const + { + assert_choice_type(types::gnb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + const global_kp_mnode_en_g_nb_id_s& en_g_nb() const + { + assert_choice_type(types::en_g_nb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + const global_kp_mnode_ng_enb_id_s& ng_enb() const + { + assert_choice_type(types::ng_enb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + const global_kp_mnode_enb_id_s& enb() const + { + assert_choice_type(types::enb, type_, "GlobalKPMnode-ID"); + return c.get(); + } + global_kp_mnode_g_nb_id_s& set_gnb(); + global_kp_mnode_en_g_nb_id_s& set_en_g_nb(); + global_kp_mnode_ng_enb_id_s& set_ng_enb(); + global_kp_mnode_enb_id_s& set_enb(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// E2SM-KPM-IndicationHeader-Format1 ::= SEQUENCE +struct e2_sm_kpm_ind_hdr_format1_s { + bool ext = false; + bool id_global_kp_mnode_id_present = false; + bool nrcgi_present = false; + bool plmn_id_present = false; + bool slice_id_present = false; + bool five_qi_present = false; + bool qci_present = false; + global_kp_mnode_id_c id_global_kp_mnode_id; + nrcgi_s nrcgi; + fixed_octstring<3, true> plmn_id; + snssai_s slice_id; + uint16_t five_qi = 0; + uint16_t qci = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationHeader ::= CHOICE +struct e2_sm_kpm_ind_hdr_c { + struct types_opts { + enum options { ind_hdr_format1, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ind_hdr_format1; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_ind_hdr_format1_s& ind_hdr_format1() { return c; } + const e2_sm_kpm_ind_hdr_format1_s& ind_hdr_format1() const { return c; } + +private: + e2_sm_kpm_ind_hdr_format1_s c; +}; + +// NI-Type ::= ENUMERATED +struct ni_type_opts { + enum options { x2_u, xn_u, f1_u, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated ni_type_e; + +// PF-ContainerListItem ::= SEQUENCE +struct pf_container_list_item_s { + bool ext = false; + ni_type_e interface_type; + cuup_meas_container_s o_cu_up_pm_container; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// OCUCP-PF-Container ::= SEQUENCE +struct ocucp_pf_container_s { + struct cu_cp_res_status_s_ { + bool nof_active_ues_present = false; + uint32_t nof_active_ues = 1; + }; + + // member variables + bool gnb_cu_cp_name_present = false; + printable_string<1, 150, true, true> gnb_cu_cp_name; + cu_cp_res_status_s_ cu_cp_res_status; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// OCUUP-PF-Container ::= SEQUENCE +struct ocuup_pf_container_s { + using pf_container_list_l_ = dyn_array; + + // member variables + bool ext = false; + bool gnb_cu_up_name_present = false; + printable_string<1, 150, true, true> gnb_cu_up_name; + pf_container_list_l_ pf_container_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ODU-PF-Container ::= SEQUENCE +struct odu_pf_container_s { + using cell_res_report_list_l_ = dyn_array; + + // member variables + bool ext = false; + cell_res_report_list_l_ cell_res_report_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PF-Container ::= CHOICE +struct pf_container_c { + struct types_opts { + enum options { odu, ocu_cp, ocu_up, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + pf_container_c() = default; + pf_container_c(const pf_container_c& other); + pf_container_c& operator=(const pf_container_c& other); + ~pf_container_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + odu_pf_container_s& odu() + { + assert_choice_type(types::odu, type_, "PF-Container"); + return c.get(); + } + ocucp_pf_container_s& ocu_cp() + { + assert_choice_type(types::ocu_cp, type_, "PF-Container"); + return c.get(); + } + ocuup_pf_container_s& ocu_up() + { + assert_choice_type(types::ocu_up, type_, "PF-Container"); + return c.get(); + } + const odu_pf_container_s& odu() const + { + assert_choice_type(types::odu, type_, "PF-Container"); + return c.get(); + } + const ocucp_pf_container_s& ocu_cp() const + { + assert_choice_type(types::ocu_cp, type_, "PF-Container"); + return c.get(); + } + const ocuup_pf_container_s& ocu_up() const + { + assert_choice_type(types::ocu_up, type_, "PF-Container"); + return c.get(); + } + odu_pf_container_s& set_odu(); + ocucp_pf_container_s& set_ocu_cp(); + ocuup_pf_container_s& set_ocu_up(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// PM-Containers-List ::= SEQUENCE +struct pm_containers_list_s { + bool ext = false; + bool performance_container_present = false; + pf_container_c performance_container; + unbounded_octstring the_ran_container; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationMessage-Format1 ::= SEQUENCE +struct e2_sm_kpm_ind_msg_format1_s { + using pm_containers_l_ = dyn_array; + + // member variables + bool ext = false; + pm_containers_l_ pm_containers; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationMessage ::= CHOICE +struct e2_sm_kpm_ind_msg_c { + struct types_opts { + enum options { ric_style_type, ind_msg_format1, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + e2_sm_kpm_ind_msg_c() = default; + e2_sm_kpm_ind_msg_c(const e2_sm_kpm_ind_msg_c& other); + e2_sm_kpm_ind_msg_c& operator=(const e2_sm_kpm_ind_msg_c& other); + ~e2_sm_kpm_ind_msg_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + int64_t& ric_style_type() + { + assert_choice_type(types::ric_style_type, type_, "E2SM-KPM-IndicationMessage"); + return c.get(); + } + e2_sm_kpm_ind_msg_format1_s& ind_msg_format1() + { + assert_choice_type(types::ind_msg_format1, type_, "E2SM-KPM-IndicationMessage"); + return c.get(); + } + const int64_t& ric_style_type() const + { + assert_choice_type(types::ric_style_type, type_, "E2SM-KPM-IndicationMessage"); + return c.get(); + } + const e2_sm_kpm_ind_msg_format1_s& ind_msg_format1() const + { + assert_choice_type(types::ind_msg_format1, type_, "E2SM-KPM-IndicationMessage"); + return c.get(); + } + int64_t& set_ric_style_type(); + e2_sm_kpm_ind_msg_format1_s& set_ind_msg_format1(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// RANfunction-Name ::= SEQUENCE +struct ra_nfunction_name_s { + bool ext = false; + bool ran_function_instance_present = false; + printable_string<1, 150, true, true> ran_function_short_name; + printable_string<1, 1000, true, true> ran_function_e2_sm_oid; + printable_string<1, 150, true, true> ran_function_description; + int64_t ran_function_instance = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RIC-EventTriggerStyle-List ::= SEQUENCE +struct ric_event_trigger_style_list_s { + bool ext = false; + int64_t ric_event_trigger_style_type = 0; + printable_string<1, 150, true, true> ric_event_trigger_style_name; + int64_t ric_event_trigger_format_type = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RIC-ReportStyle-List ::= SEQUENCE +struct ric_report_style_list_s { + bool ext = false; + int64_t ric_report_style_type = 0; + printable_string<1, 150, true, true> ric_report_style_name; + int64_t ric_ind_hdr_format_type = 0; + int64_t ric_ind_msg_format_type = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-RANfunction-Description ::= SEQUENCE +struct e2_sm_kpm_ra_nfunction_description_s { + struct e2_sm_kpm_ra_nfunction_item_s_ { + using ric_event_trigger_style_list_l_ = dyn_array; + using ric_report_style_list_l_ = dyn_array; + + // member variables + bool ext = false; + ric_event_trigger_style_list_l_ ric_event_trigger_style_list; + ric_report_style_list_l_ ric_report_style_list; + // ... + }; + + // member variables + bool ext = false; + ra_nfunction_name_s ran_function_name; + e2_sm_kpm_ra_nfunction_item_s_ e2_sm_kpm_ra_nfunction_item; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GNB-ID ::= CHOICE +struct gnb_id_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalGNB-ID ::= SEQUENCE +struct global_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + gnb_id_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NgENB-ID ::= CHOICE +struct ng_enb_id_c { + struct types_opts { + enum options { macro_ng_enb_id, short_macro_ng_enb_id, long_macro_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ng_enb_id_c() = default; + ng_enb_id_c(const ng_enb_id_c& other); + ng_enb_id_c& operator=(const ng_enb_id_c& other); + ~ng_enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_ng_enb_id() + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_ng_enb_id() + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_ng_enb_id() + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_ng_enb_id() const + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_ng_enb_id() const + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_ng_enb_id() const + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_ng_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_ng_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_ng_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// GlobalNgENB-ID ::= SEQUENCE +struct global_ng_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + ng_enb_id_c ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalRANNodeID ::= CHOICE +struct global_ran_node_id_c { + struct types_opts { + enum options { global_gnb_id, global_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_ran_node_id_c() = default; + global_ran_node_id_c(const global_ran_node_id_c& other); + global_ran_node_id_c& operator=(const global_ran_node_id_c& other); + ~global_ran_node_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_gnb_id_s& global_gnb_id() + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_ng_enb_id_s& global_ng_enb_id() + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_gnb_id_s& global_gnb_id() const + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_ng_enb_id_s& global_ng_enb_id() const + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_gnb_id_s& set_global_gnb_id(); + global_ng_enb_id_s& set_global_ng_enb_id(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// EN-GNB-ID ::= CHOICE +struct en_gnb_id_c { + struct types_opts { + enum options { en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::en_g_nb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& en_g_nb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& en_g_nb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GroupID ::= CHOICE +struct group_id_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + group_id_c() = default; + group_id_c(const group_id_c& other); + group_id_c& operator=(const group_id_c& other); + ~group_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// InterfaceID-E1 ::= SEQUENCE +struct interface_id_e1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_cu_up_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-F1 ::= SEQUENCE +struct interface_id_f1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-NG ::= SEQUENCE +struct interface_id_ng_s { + bool ext = false; + guami_s guami; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-S1 ::= SEQUENCE +struct interface_id_s1_s { + bool ext = false; + gummei_s gummei; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-W1 ::= SEQUENCE +struct interface_id_w1_s { + bool ext = false; + global_ng_enb_id_s global_ng_enb_id; + uint64_t ng_enb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-X2 ::= SEQUENCE +struct interface_id_x2_s { + struct node_type_c_ { + struct types_opts { + enum options { global_enb_id, global_en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + node_type_c_() = default; + node_type_c_(const node_type_c_& other); + node_type_c_& operator=(const node_type_c_& other); + ~node_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_enb_id_s& global_enb_id() + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + globalen_gnb_id_s& global_en_g_nb_id() + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + const global_enb_id_s& global_enb_id() const + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + const globalen_gnb_id_s& global_en_g_nb_id() const + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + global_enb_id_s& set_global_enb_id(); + globalen_gnb_id_s& set_global_en_g_nb_id(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + node_type_c_ node_type; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-Xn ::= SEQUENCE +struct interface_id_xn_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceIdentifier ::= CHOICE +struct interface_id_c { + struct types_opts { + enum options { ng, xn, f1, e1, s1, x2, w1, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + interface_id_c() = default; + interface_id_c(const interface_id_c& other); + interface_id_c& operator=(const interface_id_c& other); + ~interface_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + interface_id_ng_s& ng() + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_xn_s& xn() + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_f1_s& f1() + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_e1_s& e1() + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_s1_s& s1() + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_x2_s& x2() + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_w1_s& w1() + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_ng_s& ng() const + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_xn_s& xn() const + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_f1_s& f1() const + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_e1_s& e1() const + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_s1_s& s1() const + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_x2_s& x2() const + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_w1_s& w1() const + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_ng_s& set_ng(); + interface_id_xn_s& set_xn(); + interface_id_f1_s& set_f1(); + interface_id_e1_s& set_e1(); + interface_id_s1_s& set_s1(); + interface_id_x2_s& set_x2(); + interface_id_w1_s& set_w1(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// FreqBandNrItem ::= SEQUENCE +struct freq_band_nr_item_s { + bool ext = false; + uint16_t freq_band_ind_nr = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-ARFCN ::= SEQUENCE +struct nr_arfcn_s { + using freq_band_list_nr_l_ = dyn_array; + + // member variables + bool ext = false; + uint32_t nrarfcn = 0; + freq_band_list_nr_l_ freq_band_list_nr; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// QoSID ::= CHOICE +struct qo_sid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + qo_sid_c() = default; + qo_sid_c(const qo_sid_c& other); + qo_sid_c& operator=(const qo_sid_c& other); + ~qo_sid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// RRCclass-LTE ::= ENUMERATED +struct rr_cclass_lte_opts { + enum options { + bcch_bch, + bcch_bch_mbms, + bcch_dl_sch, + bcch_dl_sch_br, + bcch_dl_sch_mbms, + mcch, + pcch, + dl_ccch, + dl_dcch, + ul_ccch, + ul_dcch, + sc_mcch, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated rr_cclass_lte_e; + +// RRCclass-NR ::= ENUMERATED +struct rr_cclass_nr_opts { + enum options { bcch_bch, bcch_dl_sch, dl_ccch, dl_dcch, pcch, ul_ccch, ul_ccch1, ul_dcch, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated rr_cclass_nr_e; + +// RRC-MessageID ::= SEQUENCE +struct rrc_msg_id_s { + struct rrc_type_c_ { + struct types_opts { + enum options { lte, nr, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + rrc_type_c_() = default; + rrc_type_c_(const rrc_type_c_& other); + rrc_type_c_& operator=(const rrc_type_c_& other); + ~rrc_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + rr_cclass_lte_e& lte() + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + rr_cclass_nr_e& nr() + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + const rr_cclass_lte_e& lte() const + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + const rr_cclass_nr_e& nr() const + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + rr_cclass_lte_e& set_lte(); + rr_cclass_nr_e& set_nr(); + + private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + rrc_type_c_ rrc_type; + int64_t msg_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// S-NSSAI ::= SEQUENCE +struct s_nssai_s { + bool ext = false; + bool sd_present = false; + fixed_octstring<1, true> sst; + fixed_octstring<3, true> sd; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ServingCell-ARFCN ::= CHOICE +struct serving_cell_arfcn_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_arfcn_c() = default; + serving_cell_arfcn_c(const serving_cell_arfcn_c& other); + serving_cell_arfcn_c& operator=(const serving_cell_arfcn_c& other); + ~serving_cell_arfcn_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_arfcn_s& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + uint32_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + const nr_arfcn_s& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + const uint32_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + nr_arfcn_s& set_nr(); + uint32_t& set_eutra(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// ServingCell-PCI ::= CHOICE +struct serving_cell_pci_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_pci_c() = default; + serving_cell_pci_c(const serving_cell_pci_c& other); + serving_cell_pci_c& operator=(const serving_cell_pci_c& other); + ~serving_cell_pci_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& set_nr(); + uint16_t& set_eutra(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_e1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_f1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-E1AP-ID-List ::= SEQUENCE (SIZE (1..65535)) OF UEID-GNB-CU-CP-E1AP-ID-Item +using ueid_gnb_cu_cp_e1_ap_id_list_l = dyn_array; + +// UEID-GNB-CU-F1AP-ID-List ::= SEQUENCE (SIZE (1..4)) OF UEID-GNB-CU-CP-F1AP-ID-Item +using ueid_gnb_cu_f1_ap_id_list_l = dyn_array; + +// UEID-EN-GNB ::= SEQUENCE +struct ueid_en_gnb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool gnb_cu_ue_f1_ap_id_present = false; + bool ran_ueid_present = false; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + uint64_t gnb_cu_ue_f1_ap_id = 0; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-ENB ::= SEQUENCE +struct ueid_enb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_present = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool global_enb_id_present = false; + uint64_t mme_ue_s1ap_id = 0; + gummei_s gummei; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB ::= SEQUENCE +struct ueid_gnb_s { + bool ext = false; + bool ran_ueid_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_gnb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + ueid_gnb_cu_f1_ap_id_list_l gnb_cu_ue_f1_ap_id_list; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_gnb_id_s global_gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-UP ::= SEQUENCE +struct ueid_gnb_cu_up_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-DU ::= SEQUENCE +struct ueid_gnb_du_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB ::= SEQUENCE +struct ueid_ng_enb_s { + bool ext = false; + bool ng_enb_cu_ue_w1_ap_id_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_ng_enb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_ng_enb_id_s global_ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB-DU ::= SEQUENCE +struct ueid_ng_enb_du_s { + bool ext = false; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID ::= CHOICE +struct ueid_c { + struct types_opts { + enum options { + gnb_ueid, + gnb_du_ueid, + gnb_cu_up_ueid, + ng_enb_ueid, + ng_enb_du_ueid, + en_g_nb_ueid, + enb_ueid, + // ... + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ueid_c() = default; + ueid_c(const ueid_c& other); + ueid_c& operator=(const ueid_c& other); + ~ueid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ueid_gnb_s& gnb_ueid() + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_du_s& gnb_du_ueid() + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_cu_up_s& gnb_cu_up_ueid() + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_s& ng_enb_ueid() + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_du_s& ng_enb_du_ueid() + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_en_gnb_s& en_g_nb_ueid() + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + ueid_enb_s& enb_ueid() + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_s& gnb_ueid() const + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_du_s& gnb_du_ueid() const + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_cu_up_s& gnb_cu_up_ueid() const + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_s& ng_enb_ueid() const + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_du_s& ng_enb_du_ueid() const + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_en_gnb_s& en_g_nb_ueid() const + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_enb_s& enb_ueid() const + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_s& set_gnb_ueid(); + ueid_gnb_du_s& set_gnb_du_ueid(); + ueid_gnb_cu_up_s& set_gnb_cu_up_ueid(); + ueid_ng_enb_s& set_ng_enb_ueid(); + ueid_ng_enb_du_s& set_ng_enb_du_ueid(); + ueid_en_gnb_s& set_en_g_nb_ueid(); + ueid_enb_s& set_enb_ueid(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +} // namespace e2sm_kpm +} // namespace asn1 diff --git a/lib/include/srsran/asn1/e2sm_kpm_v2.h b/lib/include/srsran/asn1/e2sm_kpm_v2.h new file mode 100644 index 0000000000..1db0107bbb --- /dev/null +++ b/lib/include/srsran/asn1/e2sm_kpm_v2.h @@ -0,0 +1,2845 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +/******************************************************************************* + * + * 3GPP TS ASN1 E2SM KPM v15.3.0 (2019-03) + * + ******************************************************************************/ + +#pragma once + +#include "asn1_utils.h" +#include +#include + +namespace asn1 { +namespace e2sm_kpm { +/******************************************************************************* + * Constant Definitions + ******************************************************************************/ + +#define ASN1_E2SM_KPM_MAXNOOF_CELLS 16384 +#define ASN1_E2SM_KPM_MAXNOOF_RIC_STYLES 63 +#define ASN1_E2SM_KPM_MAXNOOF_MEAS_INFO 65535 +#define ASN1_E2SM_KPM_MAXNOOF_LABEL_INFO 2147483647 +#define ASN1_E2SM_KPM_MAXNOOF_MEAS_RECORD 65535 +#define ASN1_E2SM_KPM_MAXNOOF_MEAS_VALUE 2147483647 +#define ASN1_E2SM_KPM_MAXNOOF_CONDITION_INFO 32768 +#define ASN1_E2SM_KPM_MAXNOOF_UEID 65535 +#define ASN1_E2SM_KPM_MAXNOOF_CONDITION_INFO_PER_SUB 32768 +#define ASN1_E2SM_KPM_MAXNOOF_UEID_PER_SUB 65535 +#define ASN1_E2SM_KPM_MAXNOOF_UE_MEAS_REPORT 65535 +#define ASN1_E2SM_KPM_MAXNOOF_BIN 65535 + +/******************************************************************************* + * Struct Definitions + ******************************************************************************/ +#define None std::numeric_limits::max() + +struct real_s { + SRSASN_CODE pack(bit_ref& bref) const + { + printf(" WARNING using unimplemented REAL packing function\n"); + return SRSASN_SUCCESS; + }; + SRSASN_CODE unpack(cbit_ref& bref) const + { + printf(" WARNING using unimplemented REAL unpacking function\n"); + return SRSASN_SUCCESS; + }; + void to_json(json_writer& j) const { printf(" WARNING using unimplemented REAL json function\n"); }; +}; + +// BinRangeValue ::= CHOICE +struct bin_range_value_c { + struct types_opts { + enum options { value_int, value_real, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + bin_range_value_c() = default; + bin_range_value_c(const bin_range_value_c& other); + bin_range_value_c& operator=(const bin_range_value_c& other); + ~bin_range_value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + int64_t& value_int() + { + assert_choice_type(types::value_int, type_, "BinRangeValue"); + return c.get(); + } + real_s& value_real() + { + assert_choice_type(types::value_real, type_, "BinRangeValue"); + return c.get(); + } + const int64_t& value_int() const + { + assert_choice_type(types::value_int, type_, "BinRangeValue"); + return c.get(); + } + const real_s& value_real() const + { + assert_choice_type(types::value_real, type_, "BinRangeValue"); + return c.get(); + } + int64_t& set_value_int(); + real_s& set_value_real(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// BinRangeItem ::= SEQUENCE +struct bin_range_item_s { + bool ext = false; + uint32_t bin_idx = 1; + bin_range_value_c start_value; + bin_range_value_c end_value; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// BinRangeList ::= SEQUENCE (SIZE (1..65535)) OF BinRangeItem +using bin_range_list_l = dyn_array; + +// BinRangeDefinition ::= SEQUENCE +struct bin_range_definition_s { + bool ext = false; + bin_range_list_l bin_range_list_x; + bin_range_list_l bin_range_list_y; + bin_range_list_l bin_range_list_z; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// EUTRA-CGI ::= SEQUENCE +struct eutra_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<28, false, true> eutra_cell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-CGI ::= SEQUENCE +struct nr_cgi_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<36, false, true> nrcell_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CGI ::= CHOICE +struct cgi_c { + struct types_opts { + enum options { nr_cgi, eutra_cgi, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + cgi_c() = default; + cgi_c(const cgi_c& other); + cgi_c& operator=(const cgi_c& other); + ~cgi_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_cgi_s& nr_cgi() + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + eutra_cgi_s& eutra_cgi() + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + const nr_cgi_s& nr_cgi() const + { + assert_choice_type(types::nr_cgi, type_, "CGI"); + return c.get(); + } + const eutra_cgi_s& eutra_cgi() const + { + assert_choice_type(types::eutra_cgi, type_, "CGI"); + return c.get(); + } + nr_cgi_s& set_nr_cgi(); + eutra_cgi_s& set_eutra_cgi(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// GUAMI ::= SEQUENCE +struct guami_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_bitstring<8, false, true> amf_region_id; + fixed_bitstring<10, false, true> amf_set_id; + fixed_bitstring<6, false, true> amf_pointer; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GUMMEI ::= SEQUENCE +struct gummei_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + fixed_octstring<2, true> mme_group_id; + fixed_octstring<1, true> mme_code; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CoreCPID ::= CHOICE +struct core_cpid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + core_cpid_c() = default; + core_cpid_c(const core_cpid_c& other); + core_cpid_c& operator=(const core_cpid_c& other); + ~core_cpid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + guami_s& five_gc() + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + gummei_s& epc() + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + const guami_s& five_gc() const + { + assert_choice_type(types::five_gc, type_, "CoreCPID"); + return c.get(); + } + const gummei_s& epc() const + { + assert_choice_type(types::epc, type_, "CoreCPID"); + return c.get(); + } + guami_s& set_five_gc(); + gummei_s& set_epc(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// MeasurementType ::= CHOICE +struct meas_type_c { + struct types_opts { + enum options { meas_name, meas_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + meas_type_c() = default; + meas_type_c(const meas_type_c& other); + meas_type_c& operator=(const meas_type_c& other); + ~meas_type_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + printable_string<1, 150, true, true>& meas_name() + { + assert_choice_type(types::meas_name, type_, "MeasurementType"); + return c.get >(); + } + uint32_t& meas_id() + { + assert_choice_type(types::meas_id, type_, "MeasurementType"); + return c.get(); + } + const printable_string<1, 150, true, true>& meas_name() const + { + assert_choice_type(types::meas_name, type_, "MeasurementType"); + return c.get >(); + } + const uint32_t& meas_id() const + { + assert_choice_type(types::meas_id, type_, "MeasurementType"); + return c.get(); + } + printable_string<1, 150, true, true>& set_meas_name(); + uint32_t& set_meas_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// DistMeasurementBinRangeItem ::= SEQUENCE +struct dist_meas_bin_range_item_s { + bool ext = false; + meas_type_c meas_type; + bin_range_definition_s bin_range_def; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// DistMeasurementBinRangeList ::= SEQUENCE (SIZE (1..65535)) OF DistMeasurementBinRangeItem +using dist_meas_bin_range_list_l = dyn_array; + +// S-NSSAI ::= SEQUENCE +struct s_nssai_s { + bool ext = false; + bool sd_present = false; + fixed_octstring<1, true> sst; + fixed_octstring<3, true> sd; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TestCond-Expression ::= ENUMERATED +struct test_cond_expression_opts { + enum options { equal, greaterthan, lessthan, contains, present, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated test_cond_expression_e; + +// TestCond-Type ::= CHOICE +struct test_cond_type_c { + struct gbr_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated gbr_e_; + struct ambr_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated ambr_e_; + struct is_stat_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated is_stat_e_; + struct is_cat_m_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated is_cat_m_e_; + struct rsrp_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated rsrp_e_; + struct rsrq_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated rsrq_e_; + struct ul_r_srp_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated ul_r_srp_e_; + struct cqi_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated cqi_e_; + struct five_qi_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated five_qi_e_; + struct qci_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated qci_e_; + struct snssai_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated snssai_e_; + struct types_opts { + enum options { + gbr, + ambr, + is_stat, + is_cat_m, + rsrp, + rsrq, + /*...*/ ul_r_srp, + cqi, + five_qi, + qci, + snssai, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + test_cond_type_c() = default; + test_cond_type_c(const test_cond_type_c& other); + test_cond_type_c& operator=(const test_cond_type_c& other); + ~test_cond_type_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + gbr_e_& gbr() + { + assert_choice_type(types::gbr, type_, "TestCond-Type"); + return c.get(); + } + ambr_e_& ambr() + { + assert_choice_type(types::ambr, type_, "TestCond-Type"); + return c.get(); + } + is_stat_e_& is_stat() + { + assert_choice_type(types::is_stat, type_, "TestCond-Type"); + return c.get(); + } + is_cat_m_e_& is_cat_m() + { + assert_choice_type(types::is_cat_m, type_, "TestCond-Type"); + return c.get(); + } + rsrp_e_& rsrp() + { + assert_choice_type(types::rsrp, type_, "TestCond-Type"); + return c.get(); + } + rsrq_e_& rsrq() + { + assert_choice_type(types::rsrq, type_, "TestCond-Type"); + return c.get(); + } + ul_r_srp_e_& ul_r_srp() + { + assert_choice_type(types::ul_r_srp, type_, "TestCond-Type"); + return c.get(); + } + cqi_e_& cqi() + { + assert_choice_type(types::cqi, type_, "TestCond-Type"); + return c.get(); + } + five_qi_e_& five_qi() + { + assert_choice_type(types::five_qi, type_, "TestCond-Type"); + return c.get(); + } + qci_e_& qci() + { + assert_choice_type(types::qci, type_, "TestCond-Type"); + return c.get(); + } + snssai_e_& snssai() + { + assert_choice_type(types::snssai, type_, "TestCond-Type"); + return c.get(); + } + const gbr_e_& gbr() const + { + assert_choice_type(types::gbr, type_, "TestCond-Type"); + return c.get(); + } + const ambr_e_& ambr() const + { + assert_choice_type(types::ambr, type_, "TestCond-Type"); + return c.get(); + } + const is_stat_e_& is_stat() const + { + assert_choice_type(types::is_stat, type_, "TestCond-Type"); + return c.get(); + } + const is_cat_m_e_& is_cat_m() const + { + assert_choice_type(types::is_cat_m, type_, "TestCond-Type"); + return c.get(); + } + const rsrp_e_& rsrp() const + { + assert_choice_type(types::rsrp, type_, "TestCond-Type"); + return c.get(); + } + const rsrq_e_& rsrq() const + { + assert_choice_type(types::rsrq, type_, "TestCond-Type"); + return c.get(); + } + const ul_r_srp_e_& ul_r_srp() const + { + assert_choice_type(types::ul_r_srp, type_, "TestCond-Type"); + return c.get(); + } + const cqi_e_& cqi() const + { + assert_choice_type(types::cqi, type_, "TestCond-Type"); + return c.get(); + } + const five_qi_e_& five_qi() const + { + assert_choice_type(types::five_qi, type_, "TestCond-Type"); + return c.get(); + } + const qci_e_& qci() const + { + assert_choice_type(types::qci, type_, "TestCond-Type"); + return c.get(); + } + const snssai_e_& snssai() const + { + assert_choice_type(types::snssai, type_, "TestCond-Type"); + return c.get(); + } + gbr_e_& set_gbr(); + ambr_e_& set_ambr(); + is_stat_e_& set_is_stat(); + is_cat_m_e_& set_is_cat_m(); + rsrp_e_& set_rsrp(); + rsrq_e_& set_rsrq(); + ul_r_srp_e_& set_ul_r_srp(); + cqi_e_& set_cqi(); + five_qi_e_& set_five_qi(); + qci_e_& set_qci(); + snssai_e_& set_snssai(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// TestCond-Value ::= CHOICE +struct test_cond_value_c { + struct types_opts { + enum options { + value_int, + value_enum, + value_bool, + value_bit_s, + value_oct_s, + value_prt_s, + /*...*/ value_real, + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + test_cond_value_c() = default; + test_cond_value_c(const test_cond_value_c& other); + test_cond_value_c& operator=(const test_cond_value_c& other); + ~test_cond_value_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + int64_t& value_int() + { + assert_choice_type(types::value_int, type_, "TestCond-Value"); + return c.get(); + } + int64_t& value_enum() + { + assert_choice_type(types::value_enum, type_, "TestCond-Value"); + return c.get(); + } + bool& value_bool() + { + assert_choice_type(types::value_bool, type_, "TestCond-Value"); + return c.get(); + } + dyn_bitstring& value_bit_s() + { + assert_choice_type(types::value_bit_s, type_, "TestCond-Value"); + return c.get(); + } + unbounded_octstring& value_oct_s() + { + assert_choice_type(types::value_oct_s, type_, "TestCond-Value"); + return c.get >(); + } + printable_string<0, None, false, true>& value_prt_s() + { + assert_choice_type(types::value_prt_s, type_, "TestCond-Value"); + return c.get >(); + } + real_s& value_real() + { + assert_choice_type(types::value_real, type_, "TestCond-Value"); + return c.get(); + } + const int64_t& value_int() const + { + assert_choice_type(types::value_int, type_, "TestCond-Value"); + return c.get(); + } + const int64_t& value_enum() const + { + assert_choice_type(types::value_enum, type_, "TestCond-Value"); + return c.get(); + } + const bool& value_bool() const + { + assert_choice_type(types::value_bool, type_, "TestCond-Value"); + return c.get(); + } + const dyn_bitstring& value_bit_s() const + { + assert_choice_type(types::value_bit_s, type_, "TestCond-Value"); + return c.get(); + } + const unbounded_octstring& value_oct_s() const + { + assert_choice_type(types::value_oct_s, type_, "TestCond-Value"); + return c.get >(); + } + const printable_string<0, None, false, true>& value_prt_s() const + { + assert_choice_type(types::value_prt_s, type_, "TestCond-Value"); + return c.get >(); + } + const real_s& value_real() const + { + assert_choice_type(types::value_real, type_, "TestCond-Value"); + return c.get(); + } + int64_t& set_value_int(); + int64_t& set_value_enum(); + bool& set_value_bool(); + dyn_bitstring& set_value_bit_s(); + unbounded_octstring& set_value_oct_s(); + printable_string<0, None, false, true>& set_value_prt_s(); + real_s& set_value_real(); + +private: + types type_; + choice_buffer_t, real_s, unbounded_octstring > c; + + void destroy_(); +}; + +// ENB-ID ::= CHOICE +struct enb_id_c { + struct types_opts { + enum options { macro_enb_id, home_enb_id, /*...*/ short_macro_enb_id, long_macro_enb_id, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + enb_id_c() = default; + enb_id_c(const enb_id_c& other); + enb_id_c& operator=(const enb_id_c& other); + ~enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_enb_id() + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<28, false, true>& home_enb_id() + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_enb_id() + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_enb_id() + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_enb_id() const + { + assert_choice_type(types::macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<28, false, true>& home_enb_id() const + { + assert_choice_type(types::home_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_enb_id() const + { + assert_choice_type(types::short_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_enb_id() const + { + assert_choice_type(types::long_macro_enb_id, type_, "ENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_enb_id(); + fixed_bitstring<28, false, true>& set_home_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// GNB-ID ::= CHOICE +struct gnb_id_c { + struct types_opts { + enum options { gnb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::gnb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& gnb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& gnb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// MeasurementLabel ::= SEQUENCE +struct meas_label_s { + struct no_label_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated no_label_e_; + struct sum_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated sum_e_; + struct pre_label_override_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated pre_label_override_e_; + struct start_end_ind_opts { + enum options { start, end, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated start_end_ind_e_; + struct min_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated min_e_; + struct max_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated max_e_; + struct avg_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated avg_e_; + + // member variables + bool ext = false; + bool no_label_present = false; + bool plmn_id_present = false; + bool slice_id_present = false; + bool five_qi_present = false; + bool qfi_present = false; + bool qci_present = false; + bool qcimax_present = false; + bool qcimin_present = false; + bool arpmax_present = false; + bool arpmin_present = false; + bool bitrate_range_present = false; + bool layer_mu_mimo_present = false; + bool sum_present = false; + bool dist_bin_x_present = false; + bool dist_bin_y_present = false; + bool dist_bin_z_present = false; + bool pre_label_override_present = false; + bool start_end_ind_present = false; + bool min_present = false; + bool max_present = false; + bool avg_present = false; + no_label_e_ no_label; + fixed_octstring<3, true> plmn_id; + s_nssai_s slice_id; + uint16_t five_qi = 0; + uint8_t qfi = 0; + uint16_t qci = 0; + uint16_t qcimax = 0; + uint16_t qcimin = 0; + uint8_t arpmax = 1; + uint8_t arpmin = 1; + uint32_t bitrate_range = 1; + uint32_t layer_mu_mimo = 1; + sum_e_ sum; + uint32_t dist_bin_x = 1; + uint32_t dist_bin_y = 1; + uint32_t dist_bin_z = 1; + pre_label_override_e_ pre_label_override; + start_end_ind_e_ start_end_ind; + min_e_ min; + max_e_ max; + avg_e_ avg; + // ... + bool ssb_idx_present = false; + bool non_go_b_bfmode_idx_present = false; + bool mimo_mode_idx_present = false; + uint32_t ssb_idx = 1; + uint32_t non_go_b_bfmode_idx = 1; + uint8_t mimo_mode_idx = 1; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NgENB-ID ::= CHOICE +struct ng_enb_id_c { + struct types_opts { + enum options { macro_ng_enb_id, short_macro_ng_enb_id, long_macro_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ng_enb_id_c() = default; + ng_enb_id_c(const ng_enb_id_c& other); + ng_enb_id_c& operator=(const ng_enb_id_c& other); + ~ng_enb_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20, false, true>& macro_ng_enb_id() + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<18, false, true>& short_macro_ng_enb_id() + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<21, false, true>& long_macro_ng_enb_id() + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<20, false, true>& macro_ng_enb_id() const + { + assert_choice_type(types::macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<18, false, true>& short_macro_ng_enb_id() const + { + assert_choice_type(types::short_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + const fixed_bitstring<21, false, true>& long_macro_ng_enb_id() const + { + assert_choice_type(types::long_macro_ng_enb_id, type_, "NgENB-ID"); + return c.get >(); + } + fixed_bitstring<20, false, true>& set_macro_ng_enb_id(); + fixed_bitstring<18, false, true>& set_short_macro_ng_enb_id(); + fixed_bitstring<21, false, true>& set_long_macro_ng_enb_id(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// TestCondInfo ::= SEQUENCE +struct test_cond_info_s { + bool ext = false; + bool test_expr_present = false; + bool test_value_present = false; + test_cond_type_c test_type; + test_cond_expression_e test_expr; + test_cond_value_c test_value; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_e1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +struct ueid_gnb_cu_cp_f1_ap_id_item_s { + bool ext = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalENB-ID ::= SEQUENCE +struct global_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + enb_id_c enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalGNB-ID ::= SEQUENCE +struct global_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + gnb_id_c gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalNgENB-ID ::= SEQUENCE +struct global_ng_enb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + ng_enb_id_c ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// LabelInfoItem ::= SEQUENCE +struct label_info_item_s { + bool ext = false; + meas_label_s meas_label; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// LogicalOR ::= ENUMERATED +struct lc_or_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; +}; +typedef enumerated lc_or_e; + +// MatchingCondItem-Choice ::= CHOICE +struct matching_cond_item_choice_c { + struct types_opts { + enum options { meas_label, test_cond_info, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + matching_cond_item_choice_c() = default; + matching_cond_item_choice_c(const matching_cond_item_choice_c& other); + matching_cond_item_choice_c& operator=(const matching_cond_item_choice_c& other); + ~matching_cond_item_choice_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + meas_label_s& meas_label() + { + assert_choice_type(types::meas_label, type_, "MatchingCondItem-Choice"); + return c.get(); + } + test_cond_info_s& test_cond_info() + { + assert_choice_type(types::test_cond_info, type_, "MatchingCondItem-Choice"); + return c.get(); + } + const meas_label_s& meas_label() const + { + assert_choice_type(types::meas_label, type_, "MatchingCondItem-Choice"); + return c.get(); + } + const test_cond_info_s& test_cond_info() const + { + assert_choice_type(types::test_cond_info, type_, "MatchingCondItem-Choice"); + return c.get(); + } + meas_label_s& set_meas_label(); + test_cond_info_s& set_test_cond_info(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// UEID-GNB-CU-CP-E1AP-ID-List ::= SEQUENCE (SIZE (1..65535)) OF UEID-GNB-CU-CP-E1AP-ID-Item +using ueid_gnb_cu_cp_e1_ap_id_list_l = dyn_array; + +// UEID-GNB-CU-F1AP-ID-List ::= SEQUENCE (SIZE (1..4)) OF UEID-GNB-CU-CP-F1AP-ID-Item +using ueid_gnb_cu_f1_ap_id_list_l = dyn_array; + +// LabelInfoList ::= SEQUENCE (SIZE (1..2147483647)) OF LabelInfoItem +using label_info_list_l = dyn_array; + +// MatchingCondItem ::= SEQUENCE +struct matching_cond_item_s { + bool ext = false; + bool lc_or_present = false; + matching_cond_item_choice_c matching_cond_choice; + lc_or_e lc_or; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-EN-GNB ::= SEQUENCE +struct ueid_en_gnb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool gnb_cu_ue_f1_ap_id_present = false; + bool ran_ueid_present = false; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + uint64_t gnb_cu_ue_f1_ap_id = 0; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-ENB ::= SEQUENCE +struct ueid_enb_s { + bool ext = false; + bool m_enb_ue_x2ap_id_present = false; + bool m_enb_ue_x2ap_id_ext_present = false; + bool global_enb_id_present = false; + uint64_t mme_ue_s1ap_id = 0; + gummei_s gummei; + uint16_t m_enb_ue_x2ap_id = 0; + uint16_t m_enb_ue_x2ap_id_ext = 0; + global_enb_id_s global_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB ::= SEQUENCE +struct ueid_gnb_s { + bool ext = false; + bool ran_ueid_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_gnb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + ueid_gnb_cu_f1_ap_id_list_l gnb_cu_ue_f1_ap_id_list; + ueid_gnb_cu_cp_e1_ap_id_list_l gnb_cu_cp_ue_e1_ap_id_list; + fixed_octstring<8, true> ran_ueid; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_gnb_id_s global_gnb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-CU-UP ::= SEQUENCE +struct ueid_gnb_cu_up_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_cp_ue_e1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-GNB-DU ::= SEQUENCE +struct ueid_gnb_du_s { + bool ext = false; + bool ran_ueid_present = false; + uint64_t gnb_cu_ue_f1_ap_id = 0; + fixed_octstring<8, true> ran_ueid; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB ::= SEQUENCE +struct ueid_ng_enb_s { + bool ext = false; + bool ng_enb_cu_ue_w1_ap_id_present = false; + bool m_ng_ran_ue_xn_ap_id_present = false; + bool global_ng_enb_id_present = false; + uint64_t amf_ue_ngap_id = 0; + guami_s guami; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + uint64_t m_ng_ran_ue_xn_ap_id = 0; + global_ng_enb_id_s global_ng_enb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID-NG-ENB-DU ::= SEQUENCE +struct ueid_ng_enb_du_s { + bool ext = false; + uint64_t ng_enb_cu_ue_w1_ap_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingCondList ::= SEQUENCE (SIZE (1..32768)) OF MatchingCondItem +using matching_cond_list_l = dyn_array; + +// MeasurementInfoItem ::= SEQUENCE +struct meas_info_item_s { + bool ext = false; + meas_type_c meas_type; + label_info_list_l label_info_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEID ::= CHOICE +struct ueid_c { + struct types_opts { + enum options { + gnb_ueid, + gnb_du_ueid, + gnb_cu_up_ueid, + ng_enb_ueid, + ng_enb_du_ueid, + en_g_nb_ueid, + enb_ueid, + // ... + nulltype + } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ueid_c() = default; + ueid_c(const ueid_c& other); + ueid_c& operator=(const ueid_c& other); + ~ueid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ueid_gnb_s& gnb_ueid() + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_du_s& gnb_du_ueid() + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_cu_up_s& gnb_cu_up_ueid() + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_s& ng_enb_ueid() + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_ng_enb_du_s& ng_enb_du_ueid() + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + ueid_en_gnb_s& en_g_nb_ueid() + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + ueid_enb_s& enb_ueid() + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_s& gnb_ueid() const + { + assert_choice_type(types::gnb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_du_s& gnb_du_ueid() const + { + assert_choice_type(types::gnb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_gnb_cu_up_s& gnb_cu_up_ueid() const + { + assert_choice_type(types::gnb_cu_up_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_s& ng_enb_ueid() const + { + assert_choice_type(types::ng_enb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_ng_enb_du_s& ng_enb_du_ueid() const + { + assert_choice_type(types::ng_enb_du_ueid, type_, "UEID"); + return c.get(); + } + const ueid_en_gnb_s& en_g_nb_ueid() const + { + assert_choice_type(types::en_g_nb_ueid, type_, "UEID"); + return c.get(); + } + const ueid_enb_s& enb_ueid() const + { + assert_choice_type(types::enb_ueid, type_, "UEID"); + return c.get(); + } + ueid_gnb_s& set_gnb_ueid(); + ueid_gnb_du_s& set_gnb_du_ueid(); + ueid_gnb_cu_up_s& set_gnb_cu_up_ueid(); + ueid_ng_enb_s& set_ng_enb_ueid(); + ueid_ng_enb_du_s& set_ng_enb_du_ueid(); + ueid_en_gnb_s& set_en_g_nb_ueid(); + ueid_enb_s& set_enb_ueid(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// MatchingUEidPerSubItem ::= SEQUENCE +struct matching_ueid_per_sub_item_s { + bool ext = false; + ueid_c ue_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingUeCondPerSubItem ::= SEQUENCE +struct matching_ue_cond_per_sub_item_s { + bool ext = false; + test_cond_info_s test_cond_info; + // ... + bool lc_or_present = false; + lc_or_e lc_or; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementCondItem ::= SEQUENCE +struct meas_cond_item_s { + bool ext = false; + meas_type_c meas_type; + matching_cond_list_l matching_cond; + // ... + copy_ptr bin_range_def; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementInfoList ::= SEQUENCE (SIZE (1..65535)) OF MeasurementInfoItem +using meas_info_list_l = dyn_array; + +// E2SM-KPM-ActionDefinition-Format1 ::= SEQUENCE +struct e2_sm_kpm_action_definition_format1_s { + bool ext = false; + bool cell_global_id_present = false; + meas_info_list_l meas_info_list; + uint64_t granul_period = 1; + cgi_c cell_global_id; + // ... + copy_ptr dist_meas_bin_range_info; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingUEidPerSubList ::= SEQUENCE (SIZE (2..65535)) OF MatchingUEidPerSubItem +using matching_ueid_per_sub_list_l = dyn_array; + +// MatchingUeCondPerSubList ::= SEQUENCE (SIZE (1..32768)) OF MatchingUeCondPerSubItem +using matching_ue_cond_per_sub_list_l = dyn_array; + +// MeasurementCondList ::= SEQUENCE (SIZE (1..65535)) OF MeasurementCondItem +using meas_cond_list_l = dyn_array; + +// E2SM-KPM-ActionDefinition-Format2 ::= SEQUENCE +struct e2_sm_kpm_action_definition_format2_s { + bool ext = false; + ueid_c ue_id; + e2_sm_kpm_action_definition_format1_s subscript_info; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-ActionDefinition-Format3 ::= SEQUENCE +struct e2_sm_kpm_action_definition_format3_s { + bool ext = false; + bool cell_global_id_present = false; + meas_cond_list_l meas_cond_list; + uint64_t granul_period = 1; + cgi_c cell_global_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-ActionDefinition-Format4 ::= SEQUENCE +struct e2_sm_kpm_action_definition_format4_s { + bool ext = false; + matching_ue_cond_per_sub_list_l matching_ue_cond_list; + e2_sm_kpm_action_definition_format1_s subscription_info; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-ActionDefinition-Format5 ::= SEQUENCE +struct e2_sm_kpm_action_definition_format5_s { + bool ext = false; + matching_ueid_per_sub_list_l matching_ueid_list; + e2_sm_kpm_action_definition_format1_s subscription_info; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-ActionDefinition ::= SEQUENCE +struct e2_sm_kpm_action_definition_s { + struct action_definition_formats_c_ { + struct types_opts { + enum options { + action_definition_format1, + action_definition_format2, + action_definition_format3, + // ... + action_definition_format4, + action_definition_format5, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + action_definition_formats_c_() = default; + action_definition_formats_c_(const action_definition_formats_c_& other); + action_definition_formats_c_& operator=(const action_definition_formats_c_& other); + ~action_definition_formats_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_action_definition_format1_s& action_definition_format1() + { + assert_choice_type(types::action_definition_format1, type_, "actionDefinition-formats"); + return c.get(); + } + e2_sm_kpm_action_definition_format2_s& action_definition_format2() + { + assert_choice_type(types::action_definition_format2, type_, "actionDefinition-formats"); + return c.get(); + } + e2_sm_kpm_action_definition_format3_s& action_definition_format3() + { + assert_choice_type(types::action_definition_format3, type_, "actionDefinition-formats"); + return c.get(); + } + e2_sm_kpm_action_definition_format4_s& action_definition_format4() + { + assert_choice_type(types::action_definition_format4, type_, "actionDefinition-formats"); + return c.get(); + } + e2_sm_kpm_action_definition_format5_s& action_definition_format5() + { + assert_choice_type(types::action_definition_format5, type_, "actionDefinition-formats"); + return c.get(); + } + const e2_sm_kpm_action_definition_format1_s& action_definition_format1() const + { + assert_choice_type(types::action_definition_format1, type_, "actionDefinition-formats"); + return c.get(); + } + const e2_sm_kpm_action_definition_format2_s& action_definition_format2() const + { + assert_choice_type(types::action_definition_format2, type_, "actionDefinition-formats"); + return c.get(); + } + const e2_sm_kpm_action_definition_format3_s& action_definition_format3() const + { + assert_choice_type(types::action_definition_format3, type_, "actionDefinition-formats"); + return c.get(); + } + const e2_sm_kpm_action_definition_format4_s& action_definition_format4() const + { + assert_choice_type(types::action_definition_format4, type_, "actionDefinition-formats"); + return c.get(); + } + const e2_sm_kpm_action_definition_format5_s& action_definition_format5() const + { + assert_choice_type(types::action_definition_format5, type_, "actionDefinition-formats"); + return c.get(); + } + e2_sm_kpm_action_definition_format1_s& set_action_definition_format1(); + e2_sm_kpm_action_definition_format2_s& set_action_definition_format2(); + e2_sm_kpm_action_definition_format3_s& set_action_definition_format3(); + e2_sm_kpm_action_definition_format4_s& set_action_definition_format4(); + e2_sm_kpm_action_definition_format5_s& set_action_definition_format5(); + + private: + types type_; + choice_buffer_t + c; + + void destroy_(); + }; + + // member variables + bool ext = false; + int64_t ric_style_type = 0; + action_definition_formats_c_ action_definition_formats; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-EventTriggerDefinition-Format1 ::= SEQUENCE +struct e2_sm_kpm_event_trigger_definition_format1_s { + bool ext = false; + uint64_t report_period = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-EventTriggerDefinition ::= SEQUENCE +struct e2_sm_kpm_event_trigger_definition_s { + struct event_definition_formats_c_ { + struct types_opts { + enum options { event_definition_format1, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::event_definition_format1; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_event_trigger_definition_format1_s& event_definition_format1() { return c; } + const e2_sm_kpm_event_trigger_definition_format1_s& event_definition_format1() const { return c; } + + private: + e2_sm_kpm_event_trigger_definition_format1_s c; + }; + + // member variables + bool ext = false; + event_definition_formats_c_ event_definition_formats; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationHeader-Format1 ::= SEQUENCE +struct e2_sm_kpm_ind_hdr_format1_s { + bool ext = false; + bool file_formatversion_present = false; + bool sender_name_present = false; + bool sender_type_present = false; + bool vendor_name_present = false; + fixed_octstring<4, true> collet_start_time; + printable_string<0, 15, false, true> file_formatversion; + printable_string<0, 400, false, true> sender_name; + printable_string<0, 8, false, true> sender_type; + printable_string<0, 32, false, true> vendor_name; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationHeader ::= SEQUENCE +struct e2_sm_kpm_ind_hdr_s { + struct ind_hdr_formats_c_ { + struct types_opts { + enum options { ind_hdr_format1, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::ind_hdr_format1; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_ind_hdr_format1_s& ind_hdr_format1() { return c; } + const e2_sm_kpm_ind_hdr_format1_s& ind_hdr_format1() const { return c; } + + private: + e2_sm_kpm_ind_hdr_format1_s c; + }; + + // member variables + bool ext = false; + ind_hdr_formats_c_ ind_hdr_formats; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementRecordItem ::= CHOICE +struct meas_record_item_c { + struct types_opts { + enum options { integer, real, no_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + meas_record_item_c() = default; + meas_record_item_c(const meas_record_item_c& other); + meas_record_item_c& operator=(const meas_record_item_c& other); + ~meas_record_item_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint64_t& integer() + { + assert_choice_type(types::integer, type_, "MeasurementRecordItem"); + return c.get(); + } + real_s& real() + { + assert_choice_type(types::real, type_, "MeasurementRecordItem"); + return c.get(); + } + const uint64_t& integer() const + { + assert_choice_type(types::integer, type_, "MeasurementRecordItem"); + return c.get(); + } + const real_s& real() const + { + assert_choice_type(types::real, type_, "MeasurementRecordItem"); + return c.get(); + } + uint64_t& set_integer(); + real_s& set_real(); + void set_no_value(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// MatchingUEidItem-PerGP ::= SEQUENCE +struct matching_ueid_item_per_gp_s { + bool ext = false; + ueid_c ue_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementRecord ::= SEQUENCE (SIZE (1..2147483647)) OF MeasurementRecordItem +using meas_record_l = dyn_array; + +// MatchingUEidList-PerGP ::= SEQUENCE (SIZE (1..65535)) OF MatchingUEidItem-PerGP +using matching_ueid_list_per_gp_l = dyn_array; + +// MeasurementDataItem ::= SEQUENCE +struct meas_data_item_s { + struct incomplete_flag_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated incomplete_flag_e_; + + // member variables + bool ext = false; + bool incomplete_flag_present = false; + meas_record_l meas_record; + incomplete_flag_e_ incomplete_flag; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingUEidItem ::= SEQUENCE +struct matching_ueid_item_s { + bool ext = false; + ueid_c ue_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingUEidPerGP-Item ::= SEQUENCE +struct matching_ueid_per_gp_item_s { + struct matched_per_gp_c_ { + struct no_uematched_opts { + enum options { true_value, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated no_uematched_e_; + struct types_opts { + enum options { no_uematched, one_or_more_uematched, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + matched_per_gp_c_() = default; + matched_per_gp_c_(const matched_per_gp_c_& other); + matched_per_gp_c_& operator=(const matched_per_gp_c_& other); + ~matched_per_gp_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + no_uematched_e_& no_uematched() + { + assert_choice_type(types::no_uematched, type_, "matchedPerGP"); + return c.get(); + } + matching_ueid_list_per_gp_l& one_or_more_uematched() + { + assert_choice_type(types::one_or_more_uematched, type_, "matchedPerGP"); + return c.get(); + } + const no_uematched_e_& no_uematched() const + { + assert_choice_type(types::no_uematched, type_, "matchedPerGP"); + return c.get(); + } + const matching_ueid_list_per_gp_l& one_or_more_uematched() const + { + assert_choice_type(types::one_or_more_uematched, type_, "matchedPerGP"); + return c.get(); + } + no_uematched_e_& set_no_uematched(); + matching_ueid_list_per_gp_l& set_one_or_more_uematched(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + matched_per_gp_c_ matched_per_gp; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementData ::= SEQUENCE (SIZE (1..65535)) OF MeasurementDataItem +using meas_data_l = dyn_array; + +// E2SM-KPM-IndicationMessage-Format1 ::= SEQUENCE +struct e2_sm_kpm_ind_msg_format1_s { + bool ext = false; + bool granul_period_present = false; + meas_data_l meas_data; + meas_info_list_l meas_info_list; + uint64_t granul_period = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MatchingUEidList ::= SEQUENCE (SIZE (1..65535)) OF MatchingUEidItem +using matching_ueid_list_l = dyn_array; + +// MatchingUEidPerGP ::= SEQUENCE (SIZE (1..65535)) OF MatchingUEidPerGP-Item +using matching_ueid_per_gp_l = dyn_array; + +// MeasurementCondUEidItem ::= SEQUENCE +struct meas_cond_ueid_item_s { + bool ext = false; + meas_type_c meas_type; + matching_cond_list_l matching_cond; + matching_ueid_list_l matching_ueid_list; + // ... + copy_ptr matching_ueid_per_gp; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEMeasurementReportItem ::= SEQUENCE +struct ue_meas_report_item_s { + bool ext = false; + ueid_c ue_id; + e2_sm_kpm_ind_msg_format1_s meas_report; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementCondUEidList ::= SEQUENCE (SIZE (1..65535)) OF MeasurementCondUEidItem +using meas_cond_ueid_list_l = dyn_array; + +// UEMeasurementReportList ::= SEQUENCE (SIZE (1..65535)) OF UEMeasurementReportItem +using ue_meas_report_list_l = dyn_array; + +// E2SM-KPM-IndicationMessage-Format2 ::= SEQUENCE +struct e2_sm_kpm_ind_msg_format2_s { + bool ext = false; + bool granul_period_present = false; + meas_data_l meas_data; + meas_cond_ueid_list_l meas_cond_ueid_list; + uint64_t granul_period = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationMessage-Format3 ::= SEQUENCE +struct e2_sm_kpm_ind_msg_format3_s { + bool ext = false; + ue_meas_report_list_l ue_meas_report_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-IndicationMessage ::= SEQUENCE +struct e2_sm_kpm_ind_msg_s { + struct ind_msg_formats_c_ { + struct types_opts { + enum options { ind_msg_format1, ind_msg_format2, /*...*/ ind_msg_format3, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + ind_msg_formats_c_() = default; + ind_msg_formats_c_(const ind_msg_formats_c_& other); + ind_msg_formats_c_& operator=(const ind_msg_formats_c_& other); + ~ind_msg_formats_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + e2_sm_kpm_ind_msg_format1_s& ind_msg_format1() + { + assert_choice_type(types::ind_msg_format1, type_, "indicationMessage-formats"); + return c.get(); + } + e2_sm_kpm_ind_msg_format2_s& ind_msg_format2() + { + assert_choice_type(types::ind_msg_format2, type_, "indicationMessage-formats"); + return c.get(); + } + e2_sm_kpm_ind_msg_format3_s& ind_msg_format3() + { + assert_choice_type(types::ind_msg_format3, type_, "indicationMessage-formats"); + return c.get(); + } + const e2_sm_kpm_ind_msg_format1_s& ind_msg_format1() const + { + assert_choice_type(types::ind_msg_format1, type_, "indicationMessage-formats"); + return c.get(); + } + const e2_sm_kpm_ind_msg_format2_s& ind_msg_format2() const + { + assert_choice_type(types::ind_msg_format2, type_, "indicationMessage-formats"); + return c.get(); + } + const e2_sm_kpm_ind_msg_format3_s& ind_msg_format3() const + { + assert_choice_type(types::ind_msg_format3, type_, "indicationMessage-formats"); + return c.get(); + } + e2_sm_kpm_ind_msg_format1_s& set_ind_msg_format1(); + e2_sm_kpm_ind_msg_format2_s& set_ind_msg_format2(); + e2_sm_kpm_ind_msg_format3_s& set_ind_msg_format3(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + ind_msg_formats_c_ ind_msg_formats; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementInfo-Action-Item ::= SEQUENCE +struct meas_info_action_item_s { + bool ext = false; + bool meas_id_present = false; + printable_string<1, 150, true, true> meas_name; + uint32_t meas_id = 1; + // ... + copy_ptr bin_range_def; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasurementInfo-Action-List ::= SEQUENCE (SIZE (1..65535)) OF MeasurementInfo-Action-Item +using meas_info_action_list_l = dyn_array; + +// RANfunction-Name ::= SEQUENCE +struct ra_nfunction_name_s { + bool ext = false; + bool ran_function_instance_present = false; + printable_string<1, 150, true, true> ran_function_short_name; + printable_string<1, 1000, true, true> ran_function_e2_sm_oid; + printable_string<1, 150, true, true> ran_function_description; + int64_t ran_function_instance = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RIC-EventTriggerStyle-Item ::= SEQUENCE +struct ric_event_trigger_style_item_s { + bool ext = false; + int64_t ric_event_trigger_style_type = 0; + printable_string<1, 150, true, true> ric_event_trigger_style_name; + int64_t ric_event_trigger_format_type = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RIC-ReportStyle-Item ::= SEQUENCE +struct ric_report_style_item_s { + bool ext = false; + int64_t ric_report_style_type = 0; + printable_string<1, 150, true, true> ric_report_style_name; + int64_t ric_action_format_type = 0; + meas_info_action_list_l meas_info_action_list; + int64_t ric_ind_hdr_format_type = 0; + int64_t ric_ind_msg_format_type = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// E2SM-KPM-RANfunction-Description ::= SEQUENCE +struct e2_sm_kpm_ra_nfunction_description_s { + using ric_event_trigger_style_list_l_ = dyn_array; + using ric_report_style_list_l_ = dyn_array; + + // member variables + bool ext = false; + ra_nfunction_name_s ran_function_name; + ric_event_trigger_style_list_l_ ric_event_trigger_style_list; + ric_report_style_list_l_ ric_report_style_list; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GlobalRANNodeID ::= CHOICE +struct global_ran_node_id_c { + struct types_opts { + enum options { global_gnb_id, global_ng_enb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + global_ran_node_id_c() = default; + global_ran_node_id_c(const global_ran_node_id_c& other); + global_ran_node_id_c& operator=(const global_ran_node_id_c& other); + ~global_ran_node_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_gnb_id_s& global_gnb_id() + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_ng_enb_id_s& global_ng_enb_id() + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_gnb_id_s& global_gnb_id() const + { + assert_choice_type(types::global_gnb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + const global_ng_enb_id_s& global_ng_enb_id() const + { + assert_choice_type(types::global_ng_enb_id, type_, "GlobalRANNodeID"); + return c.get(); + } + global_gnb_id_s& set_global_gnb_id(); + global_ng_enb_id_s& set_global_ng_enb_id(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// EN-GNB-ID ::= CHOICE +struct en_gnb_id_c { + struct types_opts { + enum options { en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::en_g_nb_id; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + bounded_bitstring<22, 32, false, true>& en_g_nb_id() { return c; } + const bounded_bitstring<22, 32, false, true>& en_g_nb_id() const { return c; } + +private: + bounded_bitstring<22, 32, false, true> c; +}; + +// GlobalenGNB-ID ::= SEQUENCE +struct globalen_gnb_id_s { + bool ext = false; + fixed_octstring<3, true> plmn_id; + en_gnb_id_c en_g_nb_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GroupID ::= CHOICE +struct group_id_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + group_id_c() = default; + group_id_c(const group_id_c& other); + group_id_c& operator=(const group_id_c& other); + ~group_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "GroupID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "GroupID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// InterfaceID-E1 ::= SEQUENCE +struct interface_id_e1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_cu_up_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-F1 ::= SEQUENCE +struct interface_id_f1_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + uint64_t gnb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-NG ::= SEQUENCE +struct interface_id_ng_s { + bool ext = false; + guami_s guami; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-S1 ::= SEQUENCE +struct interface_id_s1_s { + bool ext = false; + gummei_s gummei; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-W1 ::= SEQUENCE +struct interface_id_w1_s { + bool ext = false; + global_ng_enb_id_s global_ng_enb_id; + uint64_t ng_enb_du_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-X2 ::= SEQUENCE +struct interface_id_x2_s { + struct node_type_c_ { + struct types_opts { + enum options { global_enb_id, global_en_g_nb_id, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + node_type_c_() = default; + node_type_c_(const node_type_c_& other); + node_type_c_& operator=(const node_type_c_& other); + ~node_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + global_enb_id_s& global_enb_id() + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + globalen_gnb_id_s& global_en_g_nb_id() + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + const global_enb_id_s& global_enb_id() const + { + assert_choice_type(types::global_enb_id, type_, "nodeType"); + return c.get(); + } + const globalen_gnb_id_s& global_en_g_nb_id() const + { + assert_choice_type(types::global_en_g_nb_id, type_, "nodeType"); + return c.get(); + } + global_enb_id_s& set_global_enb_id(); + globalen_gnb_id_s& set_global_en_g_nb_id(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + node_type_c_ node_type; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceID-Xn ::= SEQUENCE +struct interface_id_xn_s { + bool ext = false; + global_ran_node_id_c global_ng_ran_id; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterfaceIdentifier ::= CHOICE +struct interface_id_c { + struct types_opts { + enum options { ng, xn, f1, e1, s1, x2, w1, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + interface_id_c() = default; + interface_id_c(const interface_id_c& other); + interface_id_c& operator=(const interface_id_c& other); + ~interface_id_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + interface_id_ng_s& ng() + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_xn_s& xn() + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_f1_s& f1() + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_e1_s& e1() + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_s1_s& s1() + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_x2_s& x2() + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_w1_s& w1() + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_ng_s& ng() const + { + assert_choice_type(types::ng, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_xn_s& xn() const + { + assert_choice_type(types::xn, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_f1_s& f1() const + { + assert_choice_type(types::f1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_e1_s& e1() const + { + assert_choice_type(types::e1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_s1_s& s1() const + { + assert_choice_type(types::s1, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_x2_s& x2() const + { + assert_choice_type(types::x2, type_, "InterfaceIdentifier"); + return c.get(); + } + const interface_id_w1_s& w1() const + { + assert_choice_type(types::w1, type_, "InterfaceIdentifier"); + return c.get(); + } + interface_id_ng_s& set_ng(); + interface_id_xn_s& set_xn(); + interface_id_f1_s& set_f1(); + interface_id_e1_s& set_e1(); + interface_id_s1_s& set_s1(); + interface_id_x2_s& set_x2(); + interface_id_w1_s& set_w1(); + +private: + types type_; + choice_buffer_t + c; + + void destroy_(); +}; + +// FreqBandNrItem ::= SEQUENCE +struct freq_band_nr_item_s { + bool ext = false; + uint16_t freq_band_ind_nr = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NR-ARFCN ::= SEQUENCE +struct nr_arfcn_s { + using freq_band_list_nr_l_ = dyn_array; + + // member variables + bool ext = false; + uint32_t nrarfcn = 0; + freq_band_list_nr_l_ freq_band_list_nr; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// QoSID ::= CHOICE +struct qo_sid_c { + struct types_opts { + enum options { five_gc, epc, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + qo_sid_c() = default; + qo_sid_c(const qo_sid_c& other); + qo_sid_c& operator=(const qo_sid_c& other); + ~qo_sid_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& five_gc() + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + uint16_t& epc() + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + const uint16_t& five_gc() const + { + assert_choice_type(types::five_gc, type_, "QoSID"); + return c.get(); + } + const uint16_t& epc() const + { + assert_choice_type(types::epc, type_, "QoSID"); + return c.get(); + } + uint16_t& set_five_gc(); + uint16_t& set_epc(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// RRCclass-LTE ::= ENUMERATED +struct rr_cclass_lte_opts { + enum options { + bcch_bch, + bcch_bch_mbms, + bcch_dl_sch, + bcch_dl_sch_br, + bcch_dl_sch_mbms, + mcch, + pcch, + dl_ccch, + dl_dcch, + ul_ccch, + ul_dcch, + sc_mcch, + // ... + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated rr_cclass_lte_e; + +// RRCclass-NR ::= ENUMERATED +struct rr_cclass_nr_opts { + enum options { bcch_bch, bcch_dl_sch, dl_ccch, dl_dcch, pcch, ul_ccch, ul_ccch1, ul_dcch, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated rr_cclass_nr_e; + +// RRC-MessageID ::= SEQUENCE +struct rrc_msg_id_s { + struct rrc_type_c_ { + struct types_opts { + enum options { lte, nr, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + rrc_type_c_() = default; + rrc_type_c_(const rrc_type_c_& other); + rrc_type_c_& operator=(const rrc_type_c_& other); + ~rrc_type_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + rr_cclass_lte_e& lte() + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + rr_cclass_nr_e& nr() + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + const rr_cclass_lte_e& lte() const + { + assert_choice_type(types::lte, type_, "rrcType"); + return c.get(); + } + const rr_cclass_nr_e& nr() const + { + assert_choice_type(types::nr, type_, "rrcType"); + return c.get(); + } + rr_cclass_lte_e& set_lte(); + rr_cclass_nr_e& set_nr(); + + private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + rrc_type_c_ rrc_type; + int64_t msg_id = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ServingCell-ARFCN ::= CHOICE +struct serving_cell_arfcn_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_arfcn_c() = default; + serving_cell_arfcn_c(const serving_cell_arfcn_c& other); + serving_cell_arfcn_c& operator=(const serving_cell_arfcn_c& other); + ~serving_cell_arfcn_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_arfcn_s& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + uint32_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + const nr_arfcn_s& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-ARFCN"); + return c.get(); + } + const uint32_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-ARFCN"); + return c.get(); + } + nr_arfcn_s& set_nr(); + uint32_t& set_eutra(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + +// ServingCell-PCI ::= CHOICE +struct serving_cell_pci_c { + struct types_opts { + enum options { nr, eutra, /*...*/ nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + serving_cell_pci_c() = default; + serving_cell_pci_c(const serving_cell_pci_c& other); + serving_cell_pci_c& operator=(const serving_cell_pci_c& other); + ~serving_cell_pci_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint16_t& nr() + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& eutra() + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& nr() const + { + assert_choice_type(types::nr, type_, "ServingCell-PCI"); + return c.get(); + } + const uint16_t& eutra() const + { + assert_choice_type(types::eutra, type_, "ServingCell-PCI"); + return c.get(); + } + uint16_t& set_nr(); + uint16_t& set_eutra(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +} // namespace e2sm_kpm +} // namespace asn1 diff --git a/lib/include/srsran/asn1/gtpc.h b/lib/include/srsran/asn1/gtpc.h index d26a80f060..cd334cdc4c 100644 --- a/lib/include/srsran/asn1/gtpc.h +++ b/lib/include/srsran/asn1/gtpc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/asn1/gtpc_ies.h b/lib/include/srsran/asn1/gtpc_ies.h index d53a4d2171..ea96cb2b5b 100644 --- a/lib/include/srsran/asn1/gtpc_ies.h +++ b/lib/include/srsran/asn1/gtpc_ies.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/asn1/gtpc_msg.h b/lib/include/srsran/asn1/gtpc_msg.h index 539b3662f8..00fd5a1d6a 100644 --- a/lib/include/srsran/asn1/gtpc_msg.h +++ b/lib/include/srsran/asn1/gtpc_msg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/asn1/liblte_mme.h b/lib/include/srsran/asn1/liblte_mme.h index f8ba5b5e16..93d29f3488 100644 --- a/lib/include/srsran/asn1/liblte_mme.h +++ b/lib/include/srsran/asn1/liblte_mme.h @@ -2430,6 +2430,7 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_security_protected_nas_msg(LIBLTE_BYTE_MSG_STR #define LIBLTE_MME_EPS_NETWORK_FEATURE_SUPPORT_IEI 0x64 #define LIBLTE_MME_ADDITIONAL_UPDATE_RESULT_IEI 0xF #define LIBLTE_MME_T3412_EXTENDED_VALUE_IEI 0x5E +#define LIBLTE_MME_ADDITIONAL_INFORMATION_IEI 0x65 // Enums // Structs typedef struct { @@ -3649,6 +3650,8 @@ typedef struct { // Functions LIBLTE_ERROR_ENUM liblte_mme_pack_deactivate_eps_bearer_context_request_msg( LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT* deact_eps_bearer_context_req, + uint8 sec_hdr_type, + uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg); LIBLTE_ERROR_ENUM liblte_mme_unpack_deactivate_eps_bearer_context_request_msg( LIBLTE_BYTE_MSG_STRUCT* msg, diff --git a/lib/include/srsran/asn1/nas_5g_ies.h b/lib/include/srsran/asn1/nas_5g_ies.h index cd83afcb3a..95b224d575 100644 --- a/lib/include/srsran/asn1/nas_5g_ies.h +++ b/lib/include/srsran/asn1/nas_5g_ies.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -50,7 +50,7 @@ class registration_type_5gs_t reserved = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated registration_type_type; @@ -60,7 +60,7 @@ class registration_type_5gs_t follow_on_request_pending = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated follow_on_request_bit_type; @@ -83,7 +83,7 @@ class key_set_identifier_t mapped_security_context = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated security_context_flag_type; @@ -92,7 +92,7 @@ class key_set_identifier_t no_key_is_available_or_reserved = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated nas_key_set_identifier_type; @@ -122,7 +122,7 @@ class mobile_identity_5gs_t eui_64 = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated identity_types; @@ -140,7 +140,7 @@ class mobile_identity_5gs_t gli = 0b100, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated supi_format_type; @@ -151,7 +151,7 @@ class mobile_identity_5gs_t ecies_scheme_profile_b = 0b0010, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated protection_scheme_id_type; @@ -284,42 +284,42 @@ class mobile_identity_5gs_t guti_5g_s& set_guti_5g() { - set(identity_types::guti_5g); + set(identity_types::guti_5g); choice_container = srslog::detail::any{guti_5g_s()}; return *srslog::detail::any_cast(&choice_container); } imei_s& set_imei() { - set(identity_types::imei); + set(identity_types::imei); choice_container = srslog::detail::any{imei_s()}; return *srslog::detail::any_cast(&choice_container); } s_tmsi_5g_s& set_s_tmsi_5g() { - set(identity_types::s_tmsi_5g); + set(identity_types::s_tmsi_5g); choice_container = srslog::detail::any{s_tmsi_5g_s()}; return *srslog::detail::any_cast(&choice_container); } imeisv_s& set_imeisv() { - set(identity_types::imeisv); + set(identity_types::imeisv); choice_container = srslog::detail::any{imeisv_s()}; return *srslog::detail::any_cast(&choice_container); } mac_address_s& set_mac_address() { - set(identity_types::mac_address); + set(identity_types::mac_address); choice_container = srslog::detail::any{mac_address_s()}; return *srslog::detail::any_cast(&choice_container); } eui_64_s& set_eui_64() { - set(identity_types::eui_64); + set(identity_types::eui_64); choice_container = srslog::detail::any{eui_64_s()}; return *srslog::detail::any_cast(&choice_container); } @@ -424,7 +424,7 @@ class s_nssai_t sst_sd_mapped_hplmn_sst_and_mapped_hplmn_sd = 0b00001000, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated SST_type; @@ -439,8 +439,6 @@ class s_nssai_t }; // s_nssai_t - - // IE: NSSAI // Reference: 9.11.3.37 class nssai_t @@ -657,7 +655,7 @@ class ue_usage_setting_t data_centric = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated UE_usage_setting_type; @@ -682,7 +680,7 @@ class drx_parameters_5gs_t drx_cycle_parameter_t_256 = 0b0100, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated drx_value_type; @@ -710,7 +708,6 @@ class eps_nas_message_container_t class dnn_t { public: - uint32_t length; std::vector dnn_value; SRSASN_CODE pack(asn1::bit_ref& bref); @@ -748,7 +745,7 @@ class payload_container_type_t multiple_payloads = 0b1111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated Payload_container_type_type; @@ -795,7 +792,7 @@ class update_type_5gs_t sms_over_nas_supported = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated SMS_requested_type; @@ -805,7 +802,7 @@ class update_type_5gs_t ue_radio_capability_update_needed = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated NG_RAN_RCU_type; @@ -817,7 +814,7 @@ class update_type_5gs_t reserved = 0b11, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated PNB_5GS_CIoT_type; @@ -829,7 +826,7 @@ class update_type_5gs_t reserved = 0b11, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated PNB_EPS_CIoT_type; @@ -927,7 +924,7 @@ class extended_drx_parameters_t seconds_20 = 0b1111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated Paging_Time_Window_type; @@ -951,7 +948,7 @@ class extended_drx_parameters_t second_20_48 = 0b1111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated eDRX_value_type; @@ -980,7 +977,7 @@ class gprs_timer_3_t value_indicates_that_the_timer_is_deactivated = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated Unit_type; @@ -1064,7 +1061,7 @@ class nb_n1_mode_drx_parameters_t drx_cycle_parameter_t_1024 = 0b0111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated nb_n1_mode_drx_value_type; @@ -1086,7 +1083,7 @@ class registration_result_5gs_t registered_for_emergency_services = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated Emergency_registered_type; @@ -1096,7 +1093,7 @@ class registration_result_5gs_t nssaa_is_to_be_performed = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated NSSAA_to_be_performed_type; @@ -1106,7 +1103,7 @@ class registration_result_5gs_t sms_over_nas_allowed = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated SMS_allowed_type; @@ -1118,7 +1115,7 @@ class registration_result_5gs_t reserved = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated registration_result_type; @@ -1156,7 +1153,7 @@ class tracking_area_identity_list_5gs_t reserved = 0b11, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated type_of_list_type; @@ -1309,7 +1306,7 @@ class nssai_inclusion_mode_t nssai_inclusion_mode_d = 0b11, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated NSSAI_inclusion_mode_type; @@ -1353,7 +1350,7 @@ class ue_radio_capability_id_deletion_indication_t network_assigned_ue_radio_capability_i_ds_deletion_requested = 0b001, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated Deletion_request_type; @@ -1449,7 +1446,7 @@ class cause_5gmm_t protocol_error_unspecified = 0b01101111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated cause_5gmm_type; @@ -1471,7 +1468,7 @@ class de_registration_type_t switch_off = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated switch_off_type; @@ -1481,7 +1478,7 @@ class de_registration_type_t re_registration_required = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated re_registration_required_type; @@ -1492,7 +1489,7 @@ class de_registration_type_t access_3_gpp_and_non_3_gpp_access = 0b11, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated access_type_type; @@ -1537,7 +1534,7 @@ class service_type_t unused_shall_be_interpreted_as_data_2 = 0b1011, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated Service_type_value_type; @@ -1561,7 +1558,7 @@ class configuration_update_indication_t emergency_services_fallback = 0b100, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated control_plane_service_type_value_type; @@ -1588,11 +1585,6 @@ class network_name_t class time_zone_t { public: - uint8_t year; - uint8_t month; - uint8_t day; - uint8_t hour; - uint8_t second; uint8_t time_zone; SRSASN_CODE pack(asn1::bit_ref& bref); @@ -1605,6 +1597,12 @@ class time_zone_t class time_zone_and_time_t { public: + uint8_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; uint8_t time_zone; SRSASN_CODE pack(asn1::bit_ref& bref); @@ -1625,7 +1623,7 @@ class daylight_saving_time_t reserved = 0b11, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated value_type; @@ -1659,7 +1657,7 @@ class additional_configuration_indication_t release_of_n1_nas_signalling_connection_not_required = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated SCMR_type; @@ -1746,7 +1744,7 @@ class identity_type_5gs_t eui_64 = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated identity_types; @@ -1774,7 +1772,7 @@ class security_algorithms_t ia7_5g = 0b0111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated integrity_protection_algorithm_type; @@ -1790,7 +1788,7 @@ class security_algorithms_t ea7_5g = 0b0111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated ciphering_algorithm_type; @@ -1814,7 +1812,7 @@ class imeisv_request_t imeisv_requested = 0b001, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated imeisv_request_type; @@ -1842,7 +1840,7 @@ class eps_nas_security_algorithms_t eia7 = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated integrity_protection_algorithm_type; @@ -1858,7 +1856,7 @@ class eps_nas_security_algorithms_t eea7 = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated ciphering_algorithm_type; @@ -1944,7 +1942,7 @@ class access_type_t non_3_gpp_access = 0b10, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated Access_type_value_type; @@ -1983,7 +1981,7 @@ class request_type_t reserved = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated Request_type_value_type; @@ -2016,7 +2014,7 @@ class ma_pdu_session_information_t ma_pdu_session_network_upgrade_is_allowed = 0b0001, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated MA_PDU_session_information_value_type; @@ -2041,7 +2039,7 @@ class release_assistance_indication_t reserved = 0b11, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated Downlink_data_expected_type; @@ -2065,7 +2063,7 @@ class integrity_protection_maximum_data_rate_t full_data_rate = 0b11111111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated max_data_rate_UPIP_uplink_type; @@ -2076,7 +2074,7 @@ class integrity_protection_maximum_data_rate_t full_data_rate = 0b11111111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated max_data_rate_UPIP_downlink_type; @@ -2103,7 +2101,7 @@ class pdu_session_type_t reserved = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated PDU_session_type_value_type; @@ -2130,7 +2128,7 @@ class ssc_mode_t reserved = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated SSC_mode_value_type; @@ -2255,7 +2253,7 @@ class ethernet_header_compression_configuration_t bits_15 = 0b10, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated CID_Length_type; @@ -2278,15 +2276,15 @@ class pdu_address_t ipv4v6 = 0b011, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated PDU_session_type_value_type; bool si6_lla = false; PDU_session_type_value_type pdu_session_type_value = PDU_session_type_value_type_::options::ipv4; std::array ipv4; - std::array ipv6; - std::array smf_i_pv6_link_local_address; + std::array ipv6; + std::array smf_i_pv6_link_local_address; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2341,7 +2339,7 @@ class session_ambr_t inc_by_256_pbps = 0b00011001, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated unit_session_AMBR_type; @@ -2407,7 +2405,7 @@ class cause_5gsm_t protocol_error_unspecified = 0b01101111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated cause_value_type; @@ -2431,7 +2429,7 @@ class gprs_timer_t value_indicates_that_the_timer_is_deactivated = 0b111, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated Unit_type; @@ -2486,7 +2484,7 @@ class network_feature_support_5gsm_t ethernet_pdn_type_in_s1_mode_supported = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated EPT_S1_type; @@ -2558,7 +2556,7 @@ class congestion_re_attempt_indicator_5gsm_t the_back_off_timer_is_applied_in_all_plm_ns = 0b1, } value; - const char* to_string(); + const char* to_string() const; }; typedef nas_enumerated abo_type; diff --git a/lib/include/srsran/asn1/nas_5g_msg.h b/lib/include/srsran/asn1/nas_5g_msg.h index 3b6b39bc88..a2aa4fe96a 100644 --- a/lib/include/srsran/asn1/nas_5g_msg.h +++ b/lib/include/srsran/asn1/nas_5g_msg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/asn1/nas_5g_utils.h b/lib/include/srsran/asn1/nas_5g_utils.h index 0dd0211052..ec3837b78e 100644 --- a/lib/include/srsran/asn1/nas_5g_utils.h +++ b/lib/include/srsran/asn1/nas_5g_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/asn1/ngap.h b/lib/include/srsran/asn1/ngap.h index f90f1a41f0..b1792c5e16 100644 --- a/lib/include/srsran/asn1/ngap.h +++ b/lib/include/srsran/asn1/ngap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,393 +21,296 @@ /******************************************************************************* * - * 3GPP TS ASN1 NGAP NR v15.3.0 (2019-03) + * 3GPP TS ASN1 NGAP v15.3.0 (2019-03) * ******************************************************************************/ -#ifndef SRSASN1_NGAP_NR_H -#define SRSASN1_NGAP_NR_H +#ifndef SRSASN1_NGAP_H +#define SRSASN1_NGAP_H #include "asn1_utils.h" #include #include namespace asn1 { -namespace ngap_nr { +namespace ngap { /******************************************************************************* * Constant Definitions ******************************************************************************/ -#define ASN1_NGAP_NR_ID_AMF_CFG_UPD 0 -#define ASN1_NGAP_NR_ID_AMF_STATUS_IND 1 -#define ASN1_NGAP_NR_ID_CELL_TRAFFIC_TRACE 2 -#define ASN1_NGAP_NR_ID_DEACTIV_TRACE 3 -#define ASN1_NGAP_NR_ID_DL_NAS_TRANSPORT 4 -#define ASN1_NGAP_NR_ID_DL_NON_UEASSOCIATED_NRP_PA_TRANSPORT 5 -#define ASN1_NGAP_NR_ID_DL_RAN_CFG_TRANSFER 6 -#define ASN1_NGAP_NR_ID_DL_RAN_STATUS_TRANSFER 7 -#define ASN1_NGAP_NR_ID_DL_UEASSOCIATED_NRP_PA_TRANSPORT 8 -#define ASN1_NGAP_NR_ID_ERROR_IND 9 -#define ASN1_NGAP_NR_ID_HO_CANCEL 10 -#define ASN1_NGAP_NR_ID_HO_NOTIF 11 -#define ASN1_NGAP_NR_ID_HO_PREP 12 -#define ASN1_NGAP_NR_ID_HO_RES_ALLOC 13 -#define ASN1_NGAP_NR_ID_INIT_CONTEXT_SETUP 14 -#define ASN1_NGAP_NR_ID_INIT_UE_MSG 15 -#define ASN1_NGAP_NR_ID_LOCATION_REPORT_CTRL 16 -#define ASN1_NGAP_NR_ID_LOCATION_REPORT_FAIL_IND 17 -#define ASN1_NGAP_NR_ID_LOCATION_REPORT 18 -#define ASN1_NGAP_NR_ID_NAS_NON_DELIVERY_IND 19 -#define ASN1_NGAP_NR_ID_NG_RESET 20 -#define ASN1_NGAP_NR_ID_NG_SETUP 21 -#define ASN1_NGAP_NR_ID_OVERLOAD_START 22 -#define ASN1_NGAP_NR_ID_OVERLOAD_STOP 23 -#define ASN1_NGAP_NR_ID_PAGING 24 -#define ASN1_NGAP_NR_ID_PATH_SWITCH_REQUEST 25 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_MODIFY 26 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_MODIFY_IND 27 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_RELEASE 28 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_SETUP 29 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_NOTIFY 30 -#define ASN1_NGAP_NR_ID_PRIVATE_MSG 31 -#define ASN1_NGAP_NR_ID_PWS_CANCEL 32 -#define ASN1_NGAP_NR_ID_PWS_FAIL_IND 33 -#define ASN1_NGAP_NR_ID_PWS_RESTART_IND 34 -#define ASN1_NGAP_NR_ID_RAN_CFG_UPD 35 -#define ASN1_NGAP_NR_ID_REROUTE_NAS_REQUEST 36 -#define ASN1_NGAP_NR_ID_RRC_INACTIVE_TRANSITION_REPORT 37 -#define ASN1_NGAP_NR_ID_TRACE_FAIL_IND 38 -#define ASN1_NGAP_NR_ID_TRACE_START 39 -#define ASN1_NGAP_NR_ID_UE_CONTEXT_MOD 40 -#define ASN1_NGAP_NR_ID_UE_CONTEXT_RELEASE 41 -#define ASN1_NGAP_NR_ID_UE_CONTEXT_RELEASE_REQUEST 42 -#define ASN1_NGAP_NR_ID_UE_RADIO_CAP_CHECK 43 -#define ASN1_NGAP_NR_ID_UE_RADIO_CAP_INFO_IND 44 -#define ASN1_NGAP_NR_ID_UETNLA_BINDING_RELEASE 45 -#define ASN1_NGAP_NR_ID_UL_NAS_TRANSPORT 46 -#define ASN1_NGAP_NR_ID_UL_NON_UEASSOCIATED_NRP_PA_TRANSPORT 47 -#define ASN1_NGAP_NR_ID_UL_RAN_CFG_TRANSFER 48 -#define ASN1_NGAP_NR_ID_UL_RAN_STATUS_TRANSFER 49 -#define ASN1_NGAP_NR_ID_UL_UEASSOCIATED_NRP_PA_TRANSPORT 50 -#define ASN1_NGAP_NR_ID_WRITE_REPLACE_WARNING 51 -#define ASN1_NGAP_NR_ID_SECONDARY_RAT_DATA_USAGE_REPORT 52 -#define ASN1_NGAP_NR_MAX_PRIVATE_IES 65535 -#define ASN1_NGAP_NR_MAX_PROTOCOL_EXTS 65535 -#define ASN1_NGAP_NR_MAX_PROTOCOL_IES 65535 -#define ASN1_NGAP_NR_MAXNOOF_ALLOWED_AREAS 16 -#define ASN1_NGAP_NR_MAXNOOF_ALLOWED_S_NSSAIS 8 -#define ASN1_NGAP_NR_MAXNOOF_BPLMNS 12 -#define ASN1_NGAP_NR_MAXNOOF_CELL_IDFOR_WARNING 65535 -#define ASN1_NGAP_NR_MAXNOOF_CELLIN_AO_I 256 -#define ASN1_NGAP_NR_MAXNOOF_CELLIN_EAI 65535 -#define ASN1_NGAP_NR_MAXNOOF_CELLIN_TAI 65535 -#define ASN1_NGAP_NR_MAXNOOF_CELLSING_NB 16384 -#define ASN1_NGAP_NR_MAXNOOF_CELLSINNGENB 256 -#define ASN1_NGAP_NR_MAXNOOF_CELLSIN_UE_HISTORY_INFO 16 -#define ASN1_NGAP_NR_MAXNOOF_CELLS_UE_MOVING_TRAJECTORY 16 -#define ASN1_NGAP_NR_MAXNOOF_DRBS 32 -#define ASN1_NGAP_NR_MAXNOOF_EMERGENCY_AREA_ID 65535 -#define ASN1_NGAP_NR_MAXNOOF_EA_IFOR_RESTART 256 -#define ASN1_NGAP_NR_MAXNOOF_EPLMNS 15 -#define ASN1_NGAP_NR_MAXNOOF_EPLMNS_PLUS_ONE 16 -#define ASN1_NGAP_NR_MAXNOOF_ERABS 256 -#define ASN1_NGAP_NR_MAXNOOF_ERRORS 256 -#define ASN1_NGAP_NR_MAXNOOF_FORB_TACS 4096 -#define ASN1_NGAP_NR_MAXNOOF_MULTI_CONNECT 4 -#define ASN1_NGAP_NR_MAXNOOF_MULTI_CONNECT_MINUS_ONE 3 -#define ASN1_NGAP_NR_MAXNOOF_NG_CONNS_TO_RESET 65536 -#define ASN1_NGAP_NR_MAXNOOF_PDU_SESSIONS 256 -#define ASN1_NGAP_NR_MAXNOOF_PLMNS 12 -#define ASN1_NGAP_NR_MAXNOOF_QOS_FLOWS 64 -#define ASN1_NGAP_NR_MAXNOOF_RAN_NODEIN_AO_I 64 -#define ASN1_NGAP_NR_MAXNOOF_RECOMMENDED_CELLS 16 -#define ASN1_NGAP_NR_MAXNOOF_RECOMMENDED_RAN_NODES 16 -#define ASN1_NGAP_NR_MAXNOOF_AO_I 64 -#define ASN1_NGAP_NR_MAXNOOF_SERVED_GUAMIS 256 -#define ASN1_NGAP_NR_MAXNOOF_SLICE_ITEMS 1024 -#define ASN1_NGAP_NR_MAXNOOF_TACS 256 -#define ASN1_NGAP_NR_MAXNOOF_TA_IFOR_INACTIVE 16 -#define ASN1_NGAP_NR_MAXNOOF_TA_IFOR_PAGING 16 -#define ASN1_NGAP_NR_MAXNOOF_TA_IFOR_RESTART 2048 -#define ASN1_NGAP_NR_MAXNOOF_TA_IFOR_WARNING 65535 -#define ASN1_NGAP_NR_MAXNOOF_TA_IIN_AO_I 16 -#define ASN1_NGAP_NR_MAXNOOF_TIME_PERIODS 2 -#define ASN1_NGAP_NR_MAXNOOF_TNLASSOCS 32 -#define ASN1_NGAP_NR_MAXNOOF_XN_EXT_TLAS 2 -#define ASN1_NGAP_NR_MAXNOOF_XN_GTP_TLAS 16 -#define ASN1_NGAP_NR_MAXNOOF_XN_TLAS 16 -#define ASN1_NGAP_NR_ID_ALLOWED_NSSAI 0 -#define ASN1_NGAP_NR_ID_AMF_NAME 1 -#define ASN1_NGAP_NR_ID_AMF_OVERLOAD_RESP 2 -#define ASN1_NGAP_NR_ID_AMF_SET_ID 3 -#define ASN1_NGAP_NR_ID_AMF_TNLASSOC_FAILED_TO_SETUP_LIST 4 -#define ASN1_NGAP_NR_ID_AMF_TNLASSOC_SETUP_LIST 5 -#define ASN1_NGAP_NR_ID_AMF_TNLASSOC_TO_ADD_LIST 6 -#define ASN1_NGAP_NR_ID_AMF_TNLASSOC_TO_REM_LIST 7 -#define ASN1_NGAP_NR_ID_AMF_TNLASSOC_TO_UPD_LIST 8 -#define ASN1_NGAP_NR_ID_AMF_TRAFFIC_LOAD_REDUCTION_IND 9 -#define ASN1_NGAP_NR_ID_AMF_UE_NGAP_ID 10 -#define ASN1_NGAP_NR_ID_ASSIST_DATA_FOR_PAGING 11 -#define ASN1_NGAP_NR_ID_BROADCAST_CANCELLED_AREA_LIST 12 -#define ASN1_NGAP_NR_ID_BROADCAST_COMPLETED_AREA_LIST 13 -#define ASN1_NGAP_NR_ID_CANCEL_ALL_WARNING_MSGS 14 -#define ASN1_NGAP_NR_ID_CAUSE 15 -#define ASN1_NGAP_NR_ID_CELL_ID_LIST_FOR_RESTART 16 -#define ASN1_NGAP_NR_ID_CONCURRENT_WARNING_MSG_IND 17 -#define ASN1_NGAP_NR_ID_CORE_NETWORK_ASSIST_INFO 18 -#define ASN1_NGAP_NR_ID_CRIT_DIAGNOSTICS 19 -#define ASN1_NGAP_NR_ID_DATA_CODING_SCHEME 20 -#define ASN1_NGAP_NR_ID_DEFAULT_PAGING_DRX 21 -#define ASN1_NGAP_NR_ID_DIRECT_FORWARDING_PATH_AVAILABILITY 22 -#define ASN1_NGAP_NR_ID_EMERGENCY_AREA_ID_LIST_FOR_RESTART 23 -#define ASN1_NGAP_NR_ID_EMERGENCY_FALLBACK_IND 24 -#define ASN1_NGAP_NR_ID_EUTRA_CGI 25 -#define ASN1_NGAP_NR_ID_FIVE_G_S_TMSI 26 -#define ASN1_NGAP_NR_ID_GLOBAL_RAN_NODE_ID 27 -#define ASN1_NGAP_NR_ID_GUAMI 28 -#define ASN1_NGAP_NR_ID_HANDOV_TYPE 29 -#define ASN1_NGAP_NR_ID_IMS_VOICE_SUPPORT_IND 30 -#define ASN1_NGAP_NR_ID_IDX_TO_RFSP 31 -#define ASN1_NGAP_NR_ID_INFO_ON_RECOMMENDED_CELLS_AND_RAN_NODES_FOR_PAGING 32 -#define ASN1_NGAP_NR_ID_LOCATION_REPORT_REQUEST_TYPE 33 -#define ASN1_NGAP_NR_ID_MASKED_IMEISV 34 -#define ASN1_NGAP_NR_ID_MSG_ID 35 -#define ASN1_NGAP_NR_ID_MOB_RESTRICT_LIST 36 -#define ASN1_NGAP_NR_ID_NASC 37 -#define ASN1_NGAP_NR_ID_NAS_PDU 38 -#define ASN1_NGAP_NR_ID_NAS_SECURITY_PARAMS_FROM_NGRAN 39 -#define ASN1_NGAP_NR_ID_NEW_AMF_UE_NGAP_ID 40 -#define ASN1_NGAP_NR_ID_NEW_SECURITY_CONTEXT_IND 41 -#define ASN1_NGAP_NR_ID_NGAP_MSG 42 -#define ASN1_NGAP_NR_ID_NGRAN_CGI 43 -#define ASN1_NGAP_NR_ID_NGRAN_TRACE_ID 44 -#define ASN1_NGAP_NR_ID_NR_CGI 45 -#define ASN1_NGAP_NR_ID_NRP_PA_PDU 46 -#define ASN1_NGAP_NR_ID_NOF_BROADCASTS_REQUESTED 47 -#define ASN1_NGAP_NR_ID_OLD_AMF 48 -#define ASN1_NGAP_NR_ID_OVERLOAD_START_NSSAI_LIST 49 -#define ASN1_NGAP_NR_ID_PAGING_DRX 50 -#define ASN1_NGAP_NR_ID_PAGING_ORIGIN 51 -#define ASN1_NGAP_NR_ID_PAGING_PRIO 52 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_ADMITTED_LIST 53 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_FAILED_TO_MODIFY_LIST_MOD_RES 54 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_FAILED_TO_SETUP_LIST_CXT_RES 55 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_FAILED_TO_SETUP_LIST_HO_ACK 56 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_FAILED_TO_SETUP_LIST_PS_REQ 57 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_FAILED_TO_SETUP_LIST_SU_RES 58 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_HO_LIST 59 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_LIST_CXT_REL_CPL 60 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_LIST_HO_RQD 61 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_MODIFY_LIST_MOD_CFM 62 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_MODIFY_LIST_MOD_IND 63 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_MODIFY_LIST_MOD_REQ 64 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_MODIFY_LIST_MOD_RES 65 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_NOTIFY_LIST 66 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_RELEASED_LIST_NOT 67 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_RELEASED_LIST_PS_ACK 68 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_RELEASED_LIST_PS_FAIL 69 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_RELEASED_LIST_REL_RES 70 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_SETUP_LIST_CXT_REQ 71 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_SETUP_LIST_CXT_RES 72 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_SETUP_LIST_HO_REQ 73 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_SETUP_LIST_SU_REQ 74 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_SETUP_LIST_SU_RES 75 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_TO_BE_SWITCHED_DL_LIST 76 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_SWITCHED_LIST 77 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_TO_RELEASE_LIST_HO_CMD 78 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_TO_RELEASE_LIST_REL_CMD 79 -#define ASN1_NGAP_NR_ID_PLMN_SUPPORT_LIST 80 -#define ASN1_NGAP_NR_ID_PWS_FAILED_CELL_ID_LIST 81 -#define ASN1_NGAP_NR_ID_RAN_NODE_NAME 82 -#define ASN1_NGAP_NR_ID_RAN_PAGING_PRIO 83 -#define ASN1_NGAP_NR_ID_RAN_STATUS_TRANSFER_TRANSPARENT_CONTAINER 84 -#define ASN1_NGAP_NR_ID_RAN_UE_NGAP_ID 85 -#define ASN1_NGAP_NR_ID_RELATIVE_AMF_CAPACITY 86 -#define ASN1_NGAP_NR_ID_REPEAT_PERIOD 87 -#define ASN1_NGAP_NR_ID_RESET_TYPE 88 -#define ASN1_NGAP_NR_ID_ROUTING_ID 89 -#define ASN1_NGAP_NR_ID_RRCESTABLISHMENT_CAUSE 90 -#define ASN1_NGAP_NR_ID_RRC_INACTIVE_TRANSITION_REPORT_REQUEST 91 -#define ASN1_NGAP_NR_ID_RRC_STATE 92 -#define ASN1_NGAP_NR_ID_SECURITY_CONTEXT 93 -#define ASN1_NGAP_NR_ID_SECURITY_KEY 94 -#define ASN1_NGAP_NR_ID_SERIAL_NUM 95 -#define ASN1_NGAP_NR_ID_SERVED_GUAMI_LIST 96 -#define ASN1_NGAP_NR_ID_SLICE_SUPPORT_LIST 97 -#define ASN1_NGAP_NR_ID_SON_CFG_TRANSFER_DL 98 -#define ASN1_NGAP_NR_ID_SON_CFG_TRANSFER_UL 99 -#define ASN1_NGAP_NR_ID_SOURCE_AMF_UE_NGAP_ID 100 -#define ASN1_NGAP_NR_ID_SOURCE_TO_TARGET_TRANSPARENT_CONTAINER 101 -#define ASN1_NGAP_NR_ID_SUPPORTED_TA_LIST 102 -#define ASN1_NGAP_NR_ID_TAI_LIST_FOR_PAGING 103 -#define ASN1_NGAP_NR_ID_TAI_LIST_FOR_RESTART 104 -#define ASN1_NGAP_NR_ID_TARGET_ID 105 -#define ASN1_NGAP_NR_ID_TARGET_TO_SOURCE_TRANSPARENT_CONTAINER 106 -#define ASN1_NGAP_NR_ID_TIME_TO_WAIT 107 -#define ASN1_NGAP_NR_ID_TRACE_ACTIVATION 108 -#define ASN1_NGAP_NR_ID_TRACE_COLLECTION_ENTITY_IP_ADDRESS 109 -#define ASN1_NGAP_NR_ID_UE_AGGREGATE_MAXIMUM_BIT_RATE 110 -#define ASN1_NGAP_NR_ID_UE_ASSOCIATED_LC_NG_CONN_LIST 111 -#define ASN1_NGAP_NR_ID_UE_CONTEXT_REQUEST 112 -#define ASN1_NGAP_NR_ID_UE_NGAP_IDS 114 -#define ASN1_NGAP_NR_ID_UE_PAGING_ID 115 -#define ASN1_NGAP_NR_ID_UE_PRESENCE_IN_AREA_OF_INTEREST_LIST 116 -#define ASN1_NGAP_NR_ID_UE_RADIO_CAP 117 -#define ASN1_NGAP_NR_ID_UE_RADIO_CAP_FOR_PAGING 118 -#define ASN1_NGAP_NR_ID_UE_SECURITY_CAP 119 -#define ASN1_NGAP_NR_ID_UNAVAILABLE_GUAMI_LIST 120 -#define ASN1_NGAP_NR_ID_USER_LOCATION_INFO 121 -#define ASN1_NGAP_NR_ID_WARNING_AREA_LIST 122 -#define ASN1_NGAP_NR_ID_WARNING_MSG_CONTENTS 123 -#define ASN1_NGAP_NR_ID_WARNING_SECURITY_INFO 124 -#define ASN1_NGAP_NR_ID_WARNING_TYPE 125 -#define ASN1_NGAP_NR_ID_ADD_UL_NGU_UP_TNL_INFO 126 -#define ASN1_NGAP_NR_ID_DATA_FORWARDING_NOT_POSSIBLE 127 -#define ASN1_NGAP_NR_ID_DL_NGU_UP_TNL_INFO 128 -#define ASN1_NGAP_NR_ID_NETWORK_INSTANCE 129 -#define ASN1_NGAP_NR_ID_PDU_SESSION_AGGREGATE_MAXIMUM_BIT_RATE 130 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_FAILED_TO_MODIFY_LIST_MOD_CFM 131 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_FAILED_TO_SETUP_LIST_CXT_FAIL 132 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_LIST_CXT_REL_REQ 133 -#define ASN1_NGAP_NR_ID_PDU_SESSION_TYPE 134 -#define ASN1_NGAP_NR_ID_QOS_FLOW_ADD_OR_MODIFY_REQUEST_LIST 135 -#define ASN1_NGAP_NR_ID_QOS_FLOW_SETUP_REQUEST_LIST 136 -#define ASN1_NGAP_NR_ID_QOS_FLOW_TO_RELEASE_LIST 137 -#define ASN1_NGAP_NR_ID_SECURITY_IND 138 -#define ASN1_NGAP_NR_ID_UL_NGU_UP_TNL_INFO 139 -#define ASN1_NGAP_NR_ID_UL_NGU_UP_TNL_MODIFY_LIST 140 -#define ASN1_NGAP_NR_ID_WARNING_AREA_COORDINATES 141 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_SECONDARY_RATUSAGE_LIST 142 -#define ASN1_NGAP_NR_ID_HO_FLAG 143 -#define ASN1_NGAP_NR_ID_SECONDARY_RATUSAGE_INFO 144 -#define ASN1_NGAP_NR_ID_PDU_SESSION_RES_RELEASE_RESP_TRANSFER 145 -#define ASN1_NGAP_NR_ID_REDIRECTION_VOICE_FALLBACK 146 -#define ASN1_NGAP_NR_ID_UE_RETENTION_INFO 147 -#define ASN1_NGAP_NR_ID_S_NSSAI 148 -#define ASN1_NGAP_NR_ID_PS_CELL_INFO 149 -#define ASN1_NGAP_NR_ID_LAST_EUTRAN_PLMN_ID 150 -#define ASN1_NGAP_NR_ID_MAXIMUM_INTEGRITY_PROTECTED_DATA_RATE_DL 151 -#define ASN1_NGAP_NR_ID_ADD_DL_FORWARDING_UPTNL_INFO 152 -#define ASN1_NGAP_NR_ID_ADD_DLUPTNL_INFO_FOR_HO_LIST 153 -#define ASN1_NGAP_NR_ID_ADD_NGU_UP_TNL_INFO 154 -#define ASN1_NGAP_NR_ID_ADD_DL_QOS_FLOW_PER_TNL_INFO 155 -#define ASN1_NGAP_NR_ID_SECURITY_RESULT 156 -#define ASN1_NGAP_NR_ID_ENDC_SON_CFG_TRANSFER_DL 157 -#define ASN1_NGAP_NR_ID_ENDC_SON_CFG_TRANSFER_UL 158 +#define ASN1_NGAP_ID_AMF_CFG_UPD 0 +#define ASN1_NGAP_ID_AMF_STATUS_IND 1 +#define ASN1_NGAP_ID_CELL_TRAFFIC_TRACE 2 +#define ASN1_NGAP_ID_DEACTIV_TRACE 3 +#define ASN1_NGAP_ID_DL_NAS_TRANSPORT 4 +#define ASN1_NGAP_ID_DL_NON_UEASSOCIATED_NRP_PA_TRANSPORT 5 +#define ASN1_NGAP_ID_DL_RAN_CFG_TRANSFER 6 +#define ASN1_NGAP_ID_DL_RAN_STATUS_TRANSFER 7 +#define ASN1_NGAP_ID_DL_UEASSOCIATED_NRP_PA_TRANSPORT 8 +#define ASN1_NGAP_ID_ERROR_IND 9 +#define ASN1_NGAP_ID_HO_CANCEL 10 +#define ASN1_NGAP_ID_HO_NOTIF 11 +#define ASN1_NGAP_ID_HO_PREP 12 +#define ASN1_NGAP_ID_HO_RES_ALLOC 13 +#define ASN1_NGAP_ID_INIT_CONTEXT_SETUP 14 +#define ASN1_NGAP_ID_INIT_UE_MSG 15 +#define ASN1_NGAP_ID_LOCATION_REPORT_CTRL 16 +#define ASN1_NGAP_ID_LOCATION_REPORT_FAIL_IND 17 +#define ASN1_NGAP_ID_LOCATION_REPORT 18 +#define ASN1_NGAP_ID_NAS_NON_DELIVERY_IND 19 +#define ASN1_NGAP_ID_NG_RESET 20 +#define ASN1_NGAP_ID_NG_SETUP 21 +#define ASN1_NGAP_ID_OVERLOAD_START 22 +#define ASN1_NGAP_ID_OVERLOAD_STOP 23 +#define ASN1_NGAP_ID_PAGING 24 +#define ASN1_NGAP_ID_PATH_SWITCH_REQUEST 25 +#define ASN1_NGAP_ID_PDU_SESSION_RES_MODIFY 26 +#define ASN1_NGAP_ID_PDU_SESSION_RES_MODIFY_IND 27 +#define ASN1_NGAP_ID_PDU_SESSION_RES_RELEASE 28 +#define ASN1_NGAP_ID_PDU_SESSION_RES_SETUP 29 +#define ASN1_NGAP_ID_PDU_SESSION_RES_NOTIFY 30 +#define ASN1_NGAP_ID_PRIVATE_MSG 31 +#define ASN1_NGAP_ID_PWS_CANCEL 32 +#define ASN1_NGAP_ID_PWS_FAIL_IND 33 +#define ASN1_NGAP_ID_PWS_RESTART_IND 34 +#define ASN1_NGAP_ID_RAN_CFG_UPD 35 +#define ASN1_NGAP_ID_REROUTE_NAS_REQUEST 36 +#define ASN1_NGAP_ID_RRC_INACTIVE_TRANSITION_REPORT 37 +#define ASN1_NGAP_ID_TRACE_FAIL_IND 38 +#define ASN1_NGAP_ID_TRACE_START 39 +#define ASN1_NGAP_ID_UE_CONTEXT_MOD 40 +#define ASN1_NGAP_ID_UE_CONTEXT_RELEASE 41 +#define ASN1_NGAP_ID_UE_CONTEXT_RELEASE_REQUEST 42 +#define ASN1_NGAP_ID_UE_RADIO_CAP_CHECK 43 +#define ASN1_NGAP_ID_UE_RADIO_CAP_INFO_IND 44 +#define ASN1_NGAP_ID_UETNLA_BINDING_RELEASE 45 +#define ASN1_NGAP_ID_UL_NAS_TRANSPORT 46 +#define ASN1_NGAP_ID_UL_NON_UEASSOCIATED_NRP_PA_TRANSPORT 47 +#define ASN1_NGAP_ID_UL_RAN_CFG_TRANSFER 48 +#define ASN1_NGAP_ID_UL_RAN_STATUS_TRANSFER 49 +#define ASN1_NGAP_ID_UL_UEASSOCIATED_NRP_PA_TRANSPORT 50 +#define ASN1_NGAP_ID_WRITE_REPLACE_WARNING 51 +#define ASN1_NGAP_ID_SECONDARY_RAT_DATA_USAGE_REPORT 52 +#define ASN1_NGAP_MAX_PRIVATE_IES 65535 +#define ASN1_NGAP_MAX_PROTOCOL_EXTS 65535 +#define ASN1_NGAP_MAX_PROTOCOL_IES 65535 +#define ASN1_NGAP_MAXNOOF_ALLOWED_AREAS 16 +#define ASN1_NGAP_MAXNOOF_ALLOWED_S_NSSAIS 8 +#define ASN1_NGAP_MAXNOOF_BPLMNS 12 +#define ASN1_NGAP_MAXNOOF_CELL_IDFOR_WARNING 65535 +#define ASN1_NGAP_MAXNOOF_CELLIN_AO_I 256 +#define ASN1_NGAP_MAXNOOF_CELLIN_EAI 65535 +#define ASN1_NGAP_MAXNOOF_CELLIN_TAI 65535 +#define ASN1_NGAP_MAXNOOF_CELLSING_NB 16384 +#define ASN1_NGAP_MAXNOOF_CELLSINNGENB 256 +#define ASN1_NGAP_MAXNOOF_CELLSIN_UE_HISTORY_INFO 16 +#define ASN1_NGAP_MAXNOOF_CELLS_UE_MOVING_TRAJECTORY 16 +#define ASN1_NGAP_MAXNOOF_DRBS 32 +#define ASN1_NGAP_MAXNOOF_EMERGENCY_AREA_ID 65535 +#define ASN1_NGAP_MAXNOOF_EA_IFOR_RESTART 256 +#define ASN1_NGAP_MAXNOOF_EPLMNS 15 +#define ASN1_NGAP_MAXNOOF_EPLMNS_PLUS_ONE 16 +#define ASN1_NGAP_MAXNOOF_ERABS 256 +#define ASN1_NGAP_MAXNOOF_ERRORS 256 +#define ASN1_NGAP_MAXNOOF_FORB_TACS 4096 +#define ASN1_NGAP_MAXNOOF_MULTI_CONNECT 4 +#define ASN1_NGAP_MAXNOOF_MULTI_CONNECT_MINUS_ONE 3 +#define ASN1_NGAP_MAXNOOF_NG_CONNS_TO_RESET 65536 +#define ASN1_NGAP_MAXNOOF_PDU_SESSIONS 256 +#define ASN1_NGAP_MAXNOOF_PLMNS 12 +#define ASN1_NGAP_MAXNOOF_QOS_FLOWS 64 +#define ASN1_NGAP_MAXNOOF_RAN_NODEIN_AO_I 64 +#define ASN1_NGAP_MAXNOOF_RECOMMENDED_CELLS 16 +#define ASN1_NGAP_MAXNOOF_RECOMMENDED_RAN_NODES 16 +#define ASN1_NGAP_MAXNOOF_AO_I 64 +#define ASN1_NGAP_MAXNOOF_SERVED_GUAMIS 256 +#define ASN1_NGAP_MAXNOOF_SLICE_ITEMS 1024 +#define ASN1_NGAP_MAXNOOF_TACS 256 +#define ASN1_NGAP_MAXNOOF_TA_IFOR_INACTIVE 16 +#define ASN1_NGAP_MAXNOOF_TA_IFOR_PAGING 16 +#define ASN1_NGAP_MAXNOOF_TA_IFOR_RESTART 2048 +#define ASN1_NGAP_MAXNOOF_TA_IFOR_WARNING 65535 +#define ASN1_NGAP_MAXNOOF_TA_IIN_AO_I 16 +#define ASN1_NGAP_MAXNOOF_TIME_PERIODS 2 +#define ASN1_NGAP_MAXNOOF_TNLASSOCS 32 +#define ASN1_NGAP_MAXNOOF_XN_EXT_TLAS 2 +#define ASN1_NGAP_MAXNOOF_XN_GTP_TLAS 16 +#define ASN1_NGAP_MAXNOOF_XN_TLAS 16 +#define ASN1_NGAP_ID_ALLOWED_NSSAI 0 +#define ASN1_NGAP_ID_AMF_NAME 1 +#define ASN1_NGAP_ID_AMF_OVERLOAD_RESP 2 +#define ASN1_NGAP_ID_AMF_SET_ID 3 +#define ASN1_NGAP_ID_AMF_TNLASSOC_FAILED_TO_SETUP_LIST 4 +#define ASN1_NGAP_ID_AMF_TNLASSOC_SETUP_LIST 5 +#define ASN1_NGAP_ID_AMF_TNLASSOC_TO_ADD_LIST 6 +#define ASN1_NGAP_ID_AMF_TNLASSOC_TO_REM_LIST 7 +#define ASN1_NGAP_ID_AMF_TNLASSOC_TO_UPD_LIST 8 +#define ASN1_NGAP_ID_AMF_TRAFFIC_LOAD_REDUCTION_IND 9 +#define ASN1_NGAP_ID_AMF_UE_NGAP_ID 10 +#define ASN1_NGAP_ID_ASSIST_DATA_FOR_PAGING 11 +#define ASN1_NGAP_ID_BROADCAST_CANCELLED_AREA_LIST 12 +#define ASN1_NGAP_ID_BROADCAST_COMPLETED_AREA_LIST 13 +#define ASN1_NGAP_ID_CANCEL_ALL_WARNING_MSGS 14 +#define ASN1_NGAP_ID_CAUSE 15 +#define ASN1_NGAP_ID_CELL_ID_LIST_FOR_RESTART 16 +#define ASN1_NGAP_ID_CONCURRENT_WARNING_MSG_IND 17 +#define ASN1_NGAP_ID_CORE_NETWORK_ASSIST_INFO 18 +#define ASN1_NGAP_ID_CRIT_DIAGNOSTICS 19 +#define ASN1_NGAP_ID_DATA_CODING_SCHEME 20 +#define ASN1_NGAP_ID_DEFAULT_PAGING_DRX 21 +#define ASN1_NGAP_ID_DIRECT_FORWARDING_PATH_AVAILABILITY 22 +#define ASN1_NGAP_ID_EMERGENCY_AREA_ID_LIST_FOR_RESTART 23 +#define ASN1_NGAP_ID_EMERGENCY_FALLBACK_IND 24 +#define ASN1_NGAP_ID_EUTRA_CGI 25 +#define ASN1_NGAP_ID_FIVE_G_S_TMSI 26 +#define ASN1_NGAP_ID_GLOBAL_RAN_NODE_ID 27 +#define ASN1_NGAP_ID_GUAMI 28 +#define ASN1_NGAP_ID_HANDOV_TYPE 29 +#define ASN1_NGAP_ID_IMS_VOICE_SUPPORT_IND 30 +#define ASN1_NGAP_ID_IDX_TO_RFSP 31 +#define ASN1_NGAP_ID_INFO_ON_RECOMMENDED_CELLS_AND_RAN_NODES_FOR_PAGING 32 +#define ASN1_NGAP_ID_LOCATION_REPORT_REQUEST_TYPE 33 +#define ASN1_NGAP_ID_MASKED_IMEISV 34 +#define ASN1_NGAP_ID_MSG_ID 35 +#define ASN1_NGAP_ID_MOB_RESTRICT_LIST 36 +#define ASN1_NGAP_ID_NASC 37 +#define ASN1_NGAP_ID_NAS_PDU 38 +#define ASN1_NGAP_ID_NAS_SECURITY_PARAMS_FROM_NGRAN 39 +#define ASN1_NGAP_ID_NEW_AMF_UE_NGAP_ID 40 +#define ASN1_NGAP_ID_NEW_SECURITY_CONTEXT_IND 41 +#define ASN1_NGAP_ID_NGAP_MSG 42 +#define ASN1_NGAP_ID_NGRAN_CGI 43 +#define ASN1_NGAP_ID_NGRAN_TRACE_ID 44 +#define ASN1_NGAP_ID_NR_CGI 45 +#define ASN1_NGAP_ID_NRP_PA_PDU 46 +#define ASN1_NGAP_ID_NOF_BROADCASTS_REQUESTED 47 +#define ASN1_NGAP_ID_OLD_AMF 48 +#define ASN1_NGAP_ID_OVERLOAD_START_NSSAI_LIST 49 +#define ASN1_NGAP_ID_PAGING_DRX 50 +#define ASN1_NGAP_ID_PAGING_ORIGIN 51 +#define ASN1_NGAP_ID_PAGING_PRIO 52 +#define ASN1_NGAP_ID_PDU_SESSION_RES_ADMITTED_LIST 53 +#define ASN1_NGAP_ID_PDU_SESSION_RES_FAILED_TO_MODIFY_LIST_MOD_RES 54 +#define ASN1_NGAP_ID_PDU_SESSION_RES_FAILED_TO_SETUP_LIST_CXT_RES 55 +#define ASN1_NGAP_ID_PDU_SESSION_RES_FAILED_TO_SETUP_LIST_HO_ACK 56 +#define ASN1_NGAP_ID_PDU_SESSION_RES_FAILED_TO_SETUP_LIST_PS_REQ 57 +#define ASN1_NGAP_ID_PDU_SESSION_RES_FAILED_TO_SETUP_LIST_SU_RES 58 +#define ASN1_NGAP_ID_PDU_SESSION_RES_HO_LIST 59 +#define ASN1_NGAP_ID_PDU_SESSION_RES_LIST_CXT_REL_CPL 60 +#define ASN1_NGAP_ID_PDU_SESSION_RES_LIST_HO_RQD 61 +#define ASN1_NGAP_ID_PDU_SESSION_RES_MODIFY_LIST_MOD_CFM 62 +#define ASN1_NGAP_ID_PDU_SESSION_RES_MODIFY_LIST_MOD_IND 63 +#define ASN1_NGAP_ID_PDU_SESSION_RES_MODIFY_LIST_MOD_REQ 64 +#define ASN1_NGAP_ID_PDU_SESSION_RES_MODIFY_LIST_MOD_RES 65 +#define ASN1_NGAP_ID_PDU_SESSION_RES_NOTIFY_LIST 66 +#define ASN1_NGAP_ID_PDU_SESSION_RES_RELEASED_LIST_NOT 67 +#define ASN1_NGAP_ID_PDU_SESSION_RES_RELEASED_LIST_PS_ACK 68 +#define ASN1_NGAP_ID_PDU_SESSION_RES_RELEASED_LIST_PS_FAIL 69 +#define ASN1_NGAP_ID_PDU_SESSION_RES_RELEASED_LIST_REL_RES 70 +#define ASN1_NGAP_ID_PDU_SESSION_RES_SETUP_LIST_CXT_REQ 71 +#define ASN1_NGAP_ID_PDU_SESSION_RES_SETUP_LIST_CXT_RES 72 +#define ASN1_NGAP_ID_PDU_SESSION_RES_SETUP_LIST_HO_REQ 73 +#define ASN1_NGAP_ID_PDU_SESSION_RES_SETUP_LIST_SU_REQ 74 +#define ASN1_NGAP_ID_PDU_SESSION_RES_SETUP_LIST_SU_RES 75 +#define ASN1_NGAP_ID_PDU_SESSION_RES_TO_BE_SWITCHED_DL_LIST 76 +#define ASN1_NGAP_ID_PDU_SESSION_RES_SWITCHED_LIST 77 +#define ASN1_NGAP_ID_PDU_SESSION_RES_TO_RELEASE_LIST_HO_CMD 78 +#define ASN1_NGAP_ID_PDU_SESSION_RES_TO_RELEASE_LIST_REL_CMD 79 +#define ASN1_NGAP_ID_PLMN_SUPPORT_LIST 80 +#define ASN1_NGAP_ID_PWS_FAILED_CELL_ID_LIST 81 +#define ASN1_NGAP_ID_RAN_NODE_NAME 82 +#define ASN1_NGAP_ID_RAN_PAGING_PRIO 83 +#define ASN1_NGAP_ID_RAN_STATUS_TRANSFER_TRANSPARENT_CONTAINER 84 +#define ASN1_NGAP_ID_RAN_UE_NGAP_ID 85 +#define ASN1_NGAP_ID_RELATIVE_AMF_CAPACITY 86 +#define ASN1_NGAP_ID_REPEAT_PERIOD 87 +#define ASN1_NGAP_ID_RESET_TYPE 88 +#define ASN1_NGAP_ID_ROUTING_ID 89 +#define ASN1_NGAP_ID_RRCESTABLISHMENT_CAUSE 90 +#define ASN1_NGAP_ID_RRC_INACTIVE_TRANSITION_REPORT_REQUEST 91 +#define ASN1_NGAP_ID_RRC_STATE 92 +#define ASN1_NGAP_ID_SECURITY_CONTEXT 93 +#define ASN1_NGAP_ID_SECURITY_KEY 94 +#define ASN1_NGAP_ID_SERIAL_NUM 95 +#define ASN1_NGAP_ID_SERVED_GUAMI_LIST 96 +#define ASN1_NGAP_ID_SLICE_SUPPORT_LIST 97 +#define ASN1_NGAP_ID_SON_CFG_TRANSFER_DL 98 +#define ASN1_NGAP_ID_SON_CFG_TRANSFER_UL 99 +#define ASN1_NGAP_ID_SOURCE_AMF_UE_NGAP_ID 100 +#define ASN1_NGAP_ID_SOURCE_TO_TARGET_TRANSPARENT_CONTAINER 101 +#define ASN1_NGAP_ID_SUPPORTED_TA_LIST 102 +#define ASN1_NGAP_ID_TAI_LIST_FOR_PAGING 103 +#define ASN1_NGAP_ID_TAI_LIST_FOR_RESTART 104 +#define ASN1_NGAP_ID_TARGET_ID 105 +#define ASN1_NGAP_ID_TARGET_TO_SOURCE_TRANSPARENT_CONTAINER 106 +#define ASN1_NGAP_ID_TIME_TO_WAIT 107 +#define ASN1_NGAP_ID_TRACE_ACTIVATION 108 +#define ASN1_NGAP_ID_TRACE_COLLECTION_ENTITY_IP_ADDRESS 109 +#define ASN1_NGAP_ID_UE_AGGREGATE_MAXIMUM_BIT_RATE 110 +#define ASN1_NGAP_ID_UE_ASSOCIATED_LC_NG_CONN_LIST 111 +#define ASN1_NGAP_ID_UE_CONTEXT_REQUEST 112 +#define ASN1_NGAP_ID_UE_NGAP_IDS 114 +#define ASN1_NGAP_ID_UE_PAGING_ID 115 +#define ASN1_NGAP_ID_UE_PRESENCE_IN_AREA_OF_INTEREST_LIST 116 +#define ASN1_NGAP_ID_UE_RADIO_CAP 117 +#define ASN1_NGAP_ID_UE_RADIO_CAP_FOR_PAGING 118 +#define ASN1_NGAP_ID_UE_SECURITY_CAP 119 +#define ASN1_NGAP_ID_UNAVAILABLE_GUAMI_LIST 120 +#define ASN1_NGAP_ID_USER_LOCATION_INFO 121 +#define ASN1_NGAP_ID_WARNING_AREA_LIST 122 +#define ASN1_NGAP_ID_WARNING_MSG_CONTENTS 123 +#define ASN1_NGAP_ID_WARNING_SECURITY_INFO 124 +#define ASN1_NGAP_ID_WARNING_TYPE 125 +#define ASN1_NGAP_ID_ADD_UL_NGU_UP_TNL_INFO 126 +#define ASN1_NGAP_ID_DATA_FORWARDING_NOT_POSSIBLE 127 +#define ASN1_NGAP_ID_DL_NGU_UP_TNL_INFO 128 +#define ASN1_NGAP_ID_NETWORK_INSTANCE 129 +#define ASN1_NGAP_ID_PDU_SESSION_AGGREGATE_MAXIMUM_BIT_RATE 130 +#define ASN1_NGAP_ID_PDU_SESSION_RES_FAILED_TO_MODIFY_LIST_MOD_CFM 131 +#define ASN1_NGAP_ID_PDU_SESSION_RES_FAILED_TO_SETUP_LIST_CXT_FAIL 132 +#define ASN1_NGAP_ID_PDU_SESSION_RES_LIST_CXT_REL_REQ 133 +#define ASN1_NGAP_ID_PDU_SESSION_TYPE 134 +#define ASN1_NGAP_ID_QOS_FLOW_ADD_OR_MODIFY_REQUEST_LIST 135 +#define ASN1_NGAP_ID_QOS_FLOW_SETUP_REQUEST_LIST 136 +#define ASN1_NGAP_ID_QOS_FLOW_TO_RELEASE_LIST 137 +#define ASN1_NGAP_ID_SECURITY_IND 138 +#define ASN1_NGAP_ID_UL_NGU_UP_TNL_INFO 139 +#define ASN1_NGAP_ID_UL_NGU_UP_TNL_MODIFY_LIST 140 +#define ASN1_NGAP_ID_WARNING_AREA_COORDINATES 141 +#define ASN1_NGAP_ID_PDU_SESSION_RES_SECONDARY_RATUSAGE_LIST 142 +#define ASN1_NGAP_ID_HO_FLAG 143 +#define ASN1_NGAP_ID_SECONDARY_RATUSAGE_INFO 144 +#define ASN1_NGAP_ID_PDU_SESSION_RES_RELEASE_RESP_TRANSFER 145 +#define ASN1_NGAP_ID_REDIRECTION_VOICE_FALLBACK 146 +#define ASN1_NGAP_ID_UE_RETENTION_INFO 147 +#define ASN1_NGAP_ID_S_NSSAI 148 +#define ASN1_NGAP_ID_PS_CELL_INFO 149 +#define ASN1_NGAP_ID_LAST_EUTRAN_PLMN_ID 150 +#define ASN1_NGAP_ID_MAXIMUM_INTEGRITY_PROTECTED_DATA_RATE_DL 151 +#define ASN1_NGAP_ID_ADD_DL_FORWARDING_UPTNL_INFO 152 +#define ASN1_NGAP_ID_ADD_DLUPTNL_INFO_FOR_HO_LIST 153 +#define ASN1_NGAP_ID_ADD_NGU_UP_TNL_INFO 154 +#define ASN1_NGAP_ID_ADD_DL_QOS_FLOW_PER_TNL_INFO 155 +#define ASN1_NGAP_ID_SECURITY_RESULT 156 +#define ASN1_NGAP_ID_ENDC_SON_CFG_TRANSFER_DL 157 +#define ASN1_NGAP_ID_ENDC_SON_CFG_TRANSFER_UL 158 /******************************************************************************* * Struct Definitions ******************************************************************************/ -// Criticality ::= ENUMERATED -struct crit_opts { - enum options { reject, ignore, notify, nulltype } value; +// INTEGER (0..4294967295) ::= INTEGER (0..4294967295) +using ran_ue_ngap_id_t = integer; - const char* to_string() const; -}; -typedef enumerated crit_e; - -// Presence ::= ENUMERATED -struct presence_opts { - enum options { optional, conditional, mandatory, nulltype } value; - - const char* to_string() const; -}; -typedef enumerated presence_e; - -// ProtocolIE-Field{NGAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{NGAP-PROTOCOL-IES}} -template -struct protocol_ie_field_s { - uint32_t id = 0; - crit_e crit; - typename ies_set_paramT_::value_c value; - - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool load_info_obj(const uint32_t& id_); -}; - -struct ngap_protocol_ies_empty_o { - // Value ::= OPEN TYPE - struct value_c { - struct types_opts { - enum options { nulltype } value; - - const char* to_string() const; - }; - typedef enumerated types; - - // choice methods - types type() const { return types::nulltype; } - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - }; +// INTEGER (0..1099511627775) ::= INTEGER (0..1099511627775) +using amf_ue_ngap_id_t = integer; - // members lookup methods - static uint32_t idx_to_id(uint32_t idx); - static bool is_id_valid(const uint32_t& id); - static crit_e get_crit(const uint32_t& id); - static value_c get_value(const uint32_t& id); - static presence_e get_presence(const uint32_t& id); -}; // CPTransportLayerInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using cp_transport_layer_info_ext_ies_o = ngap_protocol_ies_empty_o; - -// ProtocolExtensionField{NGAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE{{NGAP-PROTOCOL-EXTENSION}} -template -struct protocol_ext_field_s { - uint32_t id = 0; - crit_e crit; - typename ext_set_paramT_::ext_c ext_value; - - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool load_info_obj(const uint32_t& id_); -}; - -// ProtocolIE-SingleContainer{NGAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{NGAP-PROTOCOL-IES}} -template -struct protocol_ie_single_container_s { - uint32_t id = 0; - crit_e crit; - typename ies_set_paramT_::value_c value; - - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool load_info_obj(const uint32_t& id_); -}; - -struct ngap_protocol_ext_empty_o { - // Extension ::= OPEN TYPE - struct ext_c { - struct types_opts { - enum options { nulltype } value; - - const char* to_string() const; - }; - typedef enumerated types; - - // choice methods - types type() const { return types::nulltype; } - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - }; +using cp_transport_layer_info_ext_ies_o = protocol_ies_empty_o; - // members lookup methods - static uint32_t idx_to_id(uint32_t idx); - static bool is_id_valid(const uint32_t& id); - static crit_e get_crit(const uint32_t& id); - static ext_c get_ext(const uint32_t& id); - static presence_e get_presence(const uint32_t& id); -}; // AMF-TNLAssociationSetupItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using amf_tnlassoc_setup_item_ext_ies_o = ngap_protocol_ext_empty_o; +using amf_tnlassoc_setup_item_ext_ies_o = protocol_ext_empty_o; // CPTransportLayerInformation ::= CHOICE struct cp_transport_layer_info_c { @@ -461,33 +364,6 @@ struct cp_transport_layer_info_c { void destroy_(); }; -// ProtocolExtensionContainer{NGAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE (SIZE (1..65535)) OF -// ProtocolExtensionField -template -using protocol_ext_container_l = dyn_seq_of, 1, 65535, true>; - -template -struct protocol_ext_container_item_s { - uint32_t id = 0; - crit_e crit; - extT_ ext; - - // sequence methods - protocol_ext_container_item_s(uint32_t id_, crit_e crit_); - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - -struct protocol_ext_container_empty_l { - template - using ie_field_s = protocol_ext_container_item_s; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; using amf_tnlassoc_setup_item_ext_ies_container = protocol_ext_container_empty_l; // AMF-TNLAssociationSetupItem ::= SEQUENCE @@ -508,7 +384,7 @@ struct amf_tnlassoc_setup_item_s { using amf_tnlassoc_setup_list_l = dyn_array; // AMF-TNLAssociationToAddItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using amf_tnlassoc_to_add_item_ext_ies_o = ngap_protocol_ext_empty_o; +using amf_tnlassoc_to_add_item_ext_ies_o = protocol_ext_empty_o; // TNLAssociationUsage ::= ENUMERATED struct tnlassoc_usage_opts { @@ -541,7 +417,7 @@ struct amf_tnlassoc_to_add_item_s { using amf_tnlassoc_to_add_list_l = dyn_array; // AMF-TNLAssociationToRemoveItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using amf_tnlassoc_to_rem_item_ext_ies_o = ngap_protocol_ext_empty_o; +using amf_tnlassoc_to_rem_item_ext_ies_o = protocol_ext_empty_o; using amf_tnlassoc_to_rem_item_ext_ies_container = protocol_ext_container_empty_l; @@ -563,7 +439,7 @@ struct amf_tnlassoc_to_rem_item_s { using amf_tnlassoc_to_rem_list_l = dyn_array; // AMF-TNLAssociationToUpdateItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using amf_tnlassoc_to_upd_item_ext_ies_o = ngap_protocol_ext_empty_o; +using amf_tnlassoc_to_upd_item_ext_ies_o = protocol_ext_empty_o; using amf_tnlassoc_to_upd_item_ext_ies_container = protocol_ext_container_empty_l; @@ -589,7 +465,7 @@ struct amf_tnlassoc_to_upd_item_s { using amf_tnlassoc_to_upd_list_l = dyn_array; // S-NSSAI-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using s_nssai_ext_ies_o = ngap_protocol_ext_empty_o; +using s_nssai_ext_ies_o = protocol_ext_empty_o; using s_nssai_ext_ies_container = protocol_ext_container_empty_l; @@ -610,10 +486,10 @@ struct s_nssai_s { }; // SliceSupportItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using slice_support_item_ext_ies_o = ngap_protocol_ext_empty_o; +using slice_support_item_ext_ies_o = protocol_ext_empty_o; // GUAMI-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using guami_ext_ies_o = ngap_protocol_ext_empty_o; +using guami_ext_ies_o = protocol_ext_empty_o; using slice_support_item_ext_ies_container = protocol_ext_container_empty_l; @@ -651,10 +527,10 @@ struct guami_s { }; // PLMNSupportItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using plmn_support_item_ext_ies_o = ngap_protocol_ext_empty_o; +using plmn_support_item_ext_ies_o = protocol_ext_empty_o; // ServedGUAMIItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using served_guami_item_ext_ies_o = ngap_protocol_ext_empty_o; +using served_guami_item_ext_ies_o = protocol_ext_empty_o; // SliceSupportList ::= SEQUENCE (SIZE (1..1024)) OF SliceSupportItem using slice_support_list_l = dyn_array; @@ -769,23 +645,6 @@ struct amf_cfg_upd_ies_o { static presence_e get_presence(const uint32_t& id); }; -// ProtocolIE-Container{NGAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE (SIZE (0..65535)) OF ProtocolIE-Field -template -using protocol_ie_container_l = dyn_seq_of, 0, 65535, true>; - -template -struct protocol_ie_container_item_s { - uint32_t id = 0; - crit_e crit; - valueT_ value; - - // sequence methods - protocol_ie_container_item_s(uint32_t id_, crit_e crit_); - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - struct amf_cfg_upd_ies_container { template using ie_field_s = protocol_ie_container_item_s; @@ -814,19 +673,10 @@ struct amf_cfg_upd_ies_container { }; // AMFConfigurationUpdate ::= SEQUENCE -struct amf_cfg_upd_s { - bool ext = false; - amf_cfg_upd_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using amf_cfg_upd_s = elementary_procedure_option; // Cause-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using cause_ext_ies_o = ngap_protocol_ies_empty_o; +using cause_ext_ies_o = protocol_ies_empty_o; // CauseMisc ::= ENUMERATED struct cause_misc_opts { @@ -938,7 +788,7 @@ struct cause_transport_opts { typedef enumerated cause_transport_e; // CriticalityDiagnostics-IE-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using crit_diagnostics_ie_item_ext_ies_o = ngap_protocol_ext_empty_o; +using crit_diagnostics_ie_item_ext_ies_o = protocol_ext_empty_o; // TypeOfError ::= ENUMERATED struct type_of_error_opts { @@ -1063,10 +913,10 @@ struct crit_diagnostics_ie_item_s { }; // TNLAssociationItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using tnlassoc_item_ext_ies_o = ngap_protocol_ext_empty_o; +using tnlassoc_item_ext_ies_o = protocol_ext_empty_o; // CriticalityDiagnostics-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using crit_diagnostics_ext_ies_o = ngap_protocol_ext_empty_o; +using crit_diagnostics_ext_ies_o = protocol_ext_empty_o; // CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..256)) OF CriticalityDiagnostics-IE-Item using crit_diagnostics_ie_list_l = dyn_array; @@ -1100,13 +950,12 @@ using crit_diagnostics_ext_ies_container = protocol_ext_container_empty_l; // CriticalityDiagnostics ::= SEQUENCE struct crit_diagnostics_s { - bool ext = false; - bool proc_code_present = false; - bool trigger_msg_present = false; - bool proc_crit_present = false; - bool ies_crit_diagnostics_present = false; - bool ie_exts_present = false; - uint16_t proc_code = 0; + bool ext = false; + bool proc_code_present = false; + bool trigger_msg_present = false; + bool proc_crit_present = false; + bool ie_exts_present = false; + uint16_t proc_code = 0; trigger_msg_e trigger_msg; crit_e proc_crit; crit_diagnostics_ie_list_l ies_crit_diagnostics; @@ -1186,16 +1035,7 @@ struct amf_cfg_upd_ack_ies_container { }; // AMFConfigurationUpdateAcknowledge ::= SEQUENCE -struct amf_cfg_upd_ack_s { - bool ext = false; - amf_cfg_upd_ack_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using amf_cfg_upd_ack_s = elementary_procedure_option; // TimeToWait ::= ENUMERATED struct time_to_wait_opts { @@ -1270,25 +1110,16 @@ struct amf_cfg_upd_fail_ies_container { }; // AMFConfigurationUpdateFailure ::= SEQUENCE -struct amf_cfg_upd_fail_s { - bool ext = false; - amf_cfg_upd_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using amf_cfg_upd_fail_s = elementary_procedure_option; // GNB-ID-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using gnb_id_ext_ies_o = ngap_protocol_ies_empty_o; +using gnb_id_ext_ies_o = protocol_ies_empty_o; // N3IWF-ID-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using n3_iwf_id_ext_ies_o = ngap_protocol_ies_empty_o; +using n3_iwf_id_ext_ies_o = protocol_ies_empty_o; // NgENB-ID-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using ng_enb_id_ext_ies_o = ngap_protocol_ies_empty_o; +using ng_enb_id_ext_ies_o = protocol_ies_empty_o; // GNB-ID ::= CHOICE struct gnb_id_c { @@ -1341,13 +1172,13 @@ struct gnb_id_c { }; // GlobalGNB-ID-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using global_gnb_id_ext_ies_o = ngap_protocol_ext_empty_o; +using global_gnb_id_ext_ies_o = protocol_ext_empty_o; // GlobalN3IWF-ID-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using global_n3_iwf_id_ext_ies_o = ngap_protocol_ext_empty_o; +using global_n3_iwf_id_ext_ies_o = protocol_ext_empty_o; // GlobalNgENB-ID-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using global_ng_enb_id_ext_ies_o = ngap_protocol_ext_empty_o; +using global_ng_enb_id_ext_ies_o = protocol_ext_empty_o; // N3IWF-ID ::= CHOICE struct n3_iwf_id_c { @@ -1525,13 +1356,13 @@ struct global_ng_enb_id_s { }; // GlobalRANNodeID-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using global_ran_node_id_ext_ies_o = ngap_protocol_ies_empty_o; +using global_ran_node_id_ext_ies_o = protocol_ies_empty_o; // TAI-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using tai_ext_ies_o = ngap_protocol_ext_empty_o; +using tai_ext_ies_o = protocol_ext_empty_o; // AMFPagingTarget-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using amf_paging_target_ext_ies_o = ngap_protocol_ies_empty_o; +using amf_paging_target_ext_ies_o = protocol_ies_empty_o; // GlobalRANNodeID ::= CHOICE struct global_ran_node_id_c { @@ -1698,7 +1529,7 @@ struct timer_approach_for_guami_removal_opts { typedef enumerated timer_approach_for_guami_removal_e; // UnavailableGUAMIItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using unavailable_guami_item_ext_ies_o = ngap_protocol_ext_empty_o; +using unavailable_guami_item_ext_ies_o = protocol_ext_empty_o; using unavailable_guami_item_ext_ies_container = protocol_ext_container_empty_l; @@ -1756,16 +1587,7 @@ struct amf_status_ind_ies_o { }; // AMFStatusIndication ::= SEQUENCE -struct amf_status_ind_s { - bool ext = false; - protocol_ie_container_l protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using amf_status_ind_s = elementary_procedure_option >; // DataForwardingAccepted ::= ENUMERATED struct data_forwarding_accepted_opts { @@ -1776,10 +1598,10 @@ struct data_forwarding_accepted_opts { typedef enumerated data_forwarding_accepted_e; // GTPTunnel-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using gtp_tunnel_ext_ies_o = ngap_protocol_ext_empty_o; +using gtp_tunnel_ext_ies_o = protocol_ext_empty_o; // QosFlowItemWithDataForwarding-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_item_with_data_forwarding_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_item_with_data_forwarding_ext_ies_o = protocol_ext_empty_o; using gtp_tunnel_ext_ies_container = protocol_ext_container_empty_l; @@ -1817,10 +1639,10 @@ struct qos_flow_item_with_data_forwarding_s { }; // UPTransportLayerInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using up_transport_layer_info_ext_ies_o = ngap_protocol_ies_empty_o; +using up_transport_layer_info_ext_ies_o = protocol_ies_empty_o; // AdditionalDLUPTNLInformationForHOItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using add_dluptnl_info_for_ho_item_ext_ies_o = ngap_protocol_ext_empty_o; +using add_dluptnl_info_for_ho_item_ext_ies_o = protocol_ext_empty_o; // QosFlowListWithDataForwarding ::= SEQUENCE (SIZE (1..64)) OF QosFlowItemWithDataForwarding using qos_flow_list_with_data_forwarding_l = dyn_array; @@ -1898,7 +1720,7 @@ struct add_dluptnl_info_for_ho_item_s { using add_dluptnl_info_for_ho_list_l = dyn_array; // AllocationAndRetentionPriority-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using alloc_and_retention_prio_ext_ies_o = ngap_protocol_ext_empty_o; +using alloc_and_retention_prio_ext_ies_o = protocol_ext_empty_o; // Pre-emptionCapability ::= ENUMERATED struct pre_emption_cap_opts { @@ -1935,7 +1757,7 @@ struct alloc_and_retention_prio_s { }; // AllowedNSSAI-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using allowed_nssai_item_ext_ies_o = ngap_protocol_ext_empty_o; +using allowed_nssai_item_ext_ies_o = protocol_ext_empty_o; using allowed_nssai_item_ext_ies_container = protocol_ext_container_empty_l; @@ -1960,10 +1782,10 @@ using allowed_nssai_l = dyn_array; using allowed_tacs_l = bounded_array, 16>; // EUTRA-CGI-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using eutra_cgi_ext_ies_o = ngap_protocol_ext_empty_o; +using eutra_cgi_ext_ies_o = protocol_ext_empty_o; // NR-CGI-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using nr_cgi_ext_ies_o = ngap_protocol_ext_empty_o; +using nr_cgi_ext_ies_o = protocol_ext_empty_o; using eutra_cgi_ext_ies_container = protocol_ext_container_empty_l; @@ -1983,7 +1805,7 @@ struct eutra_cgi_s { }; // NGRAN-CGI-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using ngran_cgi_ext_ies_o = ngap_protocol_ies_empty_o; +using ngran_cgi_ext_ies_o = protocol_ies_empty_o; using nr_cgi_ext_ies_container = protocol_ext_container_empty_l; @@ -2003,13 +1825,13 @@ struct nr_cgi_s { }; // AreaOfInterestCellItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using area_of_interest_cell_item_ext_ies_o = ngap_protocol_ext_empty_o; +using area_of_interest_cell_item_ext_ies_o = protocol_ext_empty_o; // AreaOfInterestRANNodeItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using area_of_interest_ran_node_item_ext_ies_o = ngap_protocol_ext_empty_o; +using area_of_interest_ran_node_item_ext_ies_o = protocol_ext_empty_o; // AreaOfInterestTAIItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using area_of_interest_tai_item_ext_ies_o = ngap_protocol_ext_empty_o; +using area_of_interest_tai_item_ext_ies_o = protocol_ext_empty_o; // NGRAN-CGI ::= CHOICE struct ngran_cgi_c { @@ -2121,7 +1943,7 @@ struct area_of_interest_tai_item_s { }; // AreaOfInterest-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using area_of_interest_ext_ies_o = ngap_protocol_ext_empty_o; +using area_of_interest_ext_ies_o = protocol_ext_empty_o; // AreaOfInterestCellList ::= SEQUENCE (SIZE (1..256)) OF AreaOfInterestCellItem using area_of_interest_cell_list_l = dyn_array; @@ -2136,11 +1958,8 @@ using area_of_interest_ext_ies_container = protocol_ext_container_empty_l; // AreaOfInterest ::= SEQUENCE struct area_of_interest_s { - bool ext = false; - bool area_of_interest_tai_list_present = false; - bool area_of_interest_cell_list_present = false; - bool area_of_interest_ran_node_list_present = false; - bool ie_exts_present = false; + bool ext = false; + bool ie_exts_present = false; area_of_interest_tai_list_l area_of_interest_tai_list; area_of_interest_cell_list_l area_of_interest_cell_list; area_of_interest_ran_node_list_l area_of_interest_ran_node_list; @@ -2154,7 +1973,7 @@ struct area_of_interest_s { }; // AreaOfInterestItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using area_of_interest_item_ext_ies_o = ngap_protocol_ext_empty_o; +using area_of_interest_item_ext_ies_o = protocol_ext_empty_o; using area_of_interest_item_ext_ies_container = protocol_ext_container_empty_l; @@ -2177,7 +1996,7 @@ struct area_of_interest_item_s { using area_of_interest_list_l = dyn_array; // RecommendedCellItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using recommended_cell_item_ext_ies_o = ngap_protocol_ext_empty_o; +using recommended_cell_item_ext_ies_o = protocol_ext_empty_o; using recommended_cell_item_ext_ies_container = protocol_ext_container_empty_l; @@ -2201,10 +2020,10 @@ struct recommended_cell_item_s { using recommended_cell_list_l = dyn_array; // RecommendedCellsForPaging-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using recommended_cells_for_paging_ext_ies_o = ngap_protocol_ext_empty_o; +using recommended_cells_for_paging_ext_ies_o = protocol_ext_empty_o; // AssistanceDataForRecommendedCells-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using assist_data_for_recommended_cells_ext_ies_o = ngap_protocol_ext_empty_o; +using assist_data_for_recommended_cells_ext_ies_o = protocol_ext_empty_o; // NextPagingAreaScope ::= ENUMERATED struct next_paging_area_scope_opts { @@ -2215,7 +2034,7 @@ struct next_paging_area_scope_opts { typedef enumerated next_paging_area_scope_e; // PagingAttemptInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using paging_attempt_info_ext_ies_o = ngap_protocol_ext_empty_o; +using paging_attempt_info_ext_ies_o = protocol_ext_empty_o; using recommended_cells_for_paging_ext_ies_container = protocol_ext_container_empty_l; @@ -2234,7 +2053,7 @@ struct recommended_cells_for_paging_s { }; // AssistanceDataForPaging-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using assist_data_for_paging_ext_ies_o = ngap_protocol_ext_empty_o; +using assist_data_for_paging_ext_ies_o = protocol_ext_empty_o; using assist_data_for_recommended_cells_ext_ies_container = protocol_ext_container_empty_l; @@ -2291,7 +2110,7 @@ struct assist_data_for_paging_s { }; // AssociatedQosFlowItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using associated_qos_flow_item_ext_ies_o = ngap_protocol_ext_empty_o; +using associated_qos_flow_item_ext_ies_o = protocol_ext_empty_o; using associated_qos_flow_item_ext_ies_container = protocol_ext_container_empty_l; @@ -2323,16 +2142,16 @@ struct associated_qos_flow_item_s { using associated_qos_flow_list_l = dyn_array; // CancelledCellsInEAI-EUTRA-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using cancelled_cells_in_eai_eutra_item_ext_ies_o = ngap_protocol_ext_empty_o; +using cancelled_cells_in_eai_eutra_item_ext_ies_o = protocol_ext_empty_o; // CancelledCellsInEAI-NR-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using cancelled_cells_in_eai_nr_item_ext_ies_o = ngap_protocol_ext_empty_o; +using cancelled_cells_in_eai_nr_item_ext_ies_o = protocol_ext_empty_o; // CancelledCellsInTAI-EUTRA-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using cancelled_cells_in_tai_eutra_item_ext_ies_o = ngap_protocol_ext_empty_o; +using cancelled_cells_in_tai_eutra_item_ext_ies_o = protocol_ext_empty_o; // CancelledCellsInTAI-NR-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using cancelled_cells_in_tai_nr_item_ext_ies_o = ngap_protocol_ext_empty_o; +using cancelled_cells_in_tai_nr_item_ext_ies_o = protocol_ext_empty_o; using cancelled_cells_in_eai_eutra_item_ext_ies_container = protocol_ext_container_empty_l; @@ -2415,22 +2234,22 @@ using cancelled_cells_in_tai_eutra_l = dyn_array; // CellIDCancelledEUTRA-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using cell_id_cancelled_eutra_item_ext_ies_o = ngap_protocol_ext_empty_o; +using cell_id_cancelled_eutra_item_ext_ies_o = protocol_ext_empty_o; // CellIDCancelledNR-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using cell_id_cancelled_nr_item_ext_ies_o = ngap_protocol_ext_empty_o; +using cell_id_cancelled_nr_item_ext_ies_o = protocol_ext_empty_o; // EmergencyAreaIDCancelledEUTRA-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using emergency_area_id_cancelled_eutra_item_ext_ies_o = ngap_protocol_ext_empty_o; +using emergency_area_id_cancelled_eutra_item_ext_ies_o = protocol_ext_empty_o; // EmergencyAreaIDCancelledNR-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using emergency_area_id_cancelled_nr_item_ext_ies_o = ngap_protocol_ext_empty_o; +using emergency_area_id_cancelled_nr_item_ext_ies_o = protocol_ext_empty_o; // TAICancelledEUTRA-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using tai_cancelled_eutra_item_ext_ies_o = ngap_protocol_ext_empty_o; +using tai_cancelled_eutra_item_ext_ies_o = protocol_ext_empty_o; // TAICancelledNR-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using tai_cancelled_nr_item_ext_ies_o = ngap_protocol_ext_empty_o; +using tai_cancelled_nr_item_ext_ies_o = protocol_ext_empty_o; using cell_id_cancelled_eutra_item_ext_ies_container = protocol_ext_container_empty_l; @@ -2535,7 +2354,7 @@ struct tai_cancelled_nr_item_s { }; // BroadcastCancelledAreaList-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using broadcast_cancelled_area_list_ext_ies_o = ngap_protocol_ies_empty_o; +using broadcast_cancelled_area_list_ext_ies_o = protocol_ies_empty_o; // CellIDCancelledEUTRA ::= SEQUENCE (SIZE (1..65535)) OF CellIDCancelledEUTRA-Item using cell_id_cancelled_eutra_l = dyn_array; @@ -2677,16 +2496,16 @@ struct broadcast_cancelled_area_list_c { }; // CompletedCellsInEAI-EUTRA-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using completed_cells_in_eai_eutra_item_ext_ies_o = ngap_protocol_ext_empty_o; +using completed_cells_in_eai_eutra_item_ext_ies_o = protocol_ext_empty_o; // CompletedCellsInEAI-NR-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using completed_cells_in_eai_nr_item_ext_ies_o = ngap_protocol_ext_empty_o; +using completed_cells_in_eai_nr_item_ext_ies_o = protocol_ext_empty_o; // CompletedCellsInTAI-EUTRA-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using completed_cells_in_tai_eutra_item_ext_ies_o = ngap_protocol_ext_empty_o; +using completed_cells_in_tai_eutra_item_ext_ies_o = protocol_ext_empty_o; // CompletedCellsInTAI-NR-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using completed_cells_in_tai_nr_item_ext_ies_o = ngap_protocol_ext_empty_o; +using completed_cells_in_tai_nr_item_ext_ies_o = protocol_ext_empty_o; using completed_cells_in_eai_eutra_item_ext_ies_container = protocol_ext_container_empty_l; @@ -2753,10 +2572,10 @@ struct completed_cells_in_tai_nr_item_s { }; // CellIDBroadcastEUTRA-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using cell_id_broadcast_eutra_item_ext_ies_o = ngap_protocol_ext_empty_o; +using cell_id_broadcast_eutra_item_ext_ies_o = protocol_ext_empty_o; // CellIDBroadcastNR-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using cell_id_broadcast_nr_item_ext_ies_o = ngap_protocol_ext_empty_o; +using cell_id_broadcast_nr_item_ext_ies_o = protocol_ext_empty_o; // CompletedCellsInEAI-EUTRA ::= SEQUENCE (SIZE (1..65535)) OF CompletedCellsInEAI-EUTRA-Item using completed_cells_in_eai_eutra_l = dyn_array; @@ -2771,16 +2590,16 @@ using completed_cells_in_tai_eutra_l = dyn_array; // EmergencyAreaIDBroadcastEUTRA-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using emergency_area_id_broadcast_eutra_item_ext_ies_o = ngap_protocol_ext_empty_o; +using emergency_area_id_broadcast_eutra_item_ext_ies_o = protocol_ext_empty_o; // EmergencyAreaIDBroadcastNR-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using emergency_area_id_broadcast_nr_item_ext_ies_o = ngap_protocol_ext_empty_o; +using emergency_area_id_broadcast_nr_item_ext_ies_o = protocol_ext_empty_o; // TAIBroadcastEUTRA-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using tai_broadcast_eutra_item_ext_ies_o = ngap_protocol_ext_empty_o; +using tai_broadcast_eutra_item_ext_ies_o = protocol_ext_empty_o; // TAIBroadcastNR-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using tai_broadcast_nr_item_ext_ies_o = ngap_protocol_ext_empty_o; +using tai_broadcast_nr_item_ext_ies_o = protocol_ext_empty_o; using cell_id_broadcast_eutra_item_ext_ies_container = protocol_ext_container_empty_l; @@ -2883,7 +2702,7 @@ struct tai_broadcast_nr_item_s { }; // BroadcastCompletedAreaList-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using broadcast_completed_area_list_ext_ies_o = ngap_protocol_ies_empty_o; +using broadcast_completed_area_list_ext_ies_o = protocol_ies_empty_o; // CellIDBroadcastEUTRA ::= SEQUENCE (SIZE (1..65535)) OF CellIDBroadcastEUTRA-Item using cell_id_broadcast_eutra_l = dyn_array; @@ -3025,7 +2844,7 @@ struct broadcast_completed_area_list_c { }; // BroadcastPLMNItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using broadcast_plmn_item_ext_ies_o = ngap_protocol_ext_empty_o; +using broadcast_plmn_item_ext_ies_o = protocol_ext_empty_o; using broadcast_plmn_item_ext_ies_container = protocol_ext_container_empty_l; @@ -3048,7 +2867,7 @@ struct broadcast_plmn_item_s { using broadcast_plmn_list_l = dyn_array; // COUNTValueForPDCP-SN12-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using count_value_for_pdcp_sn12_ext_ies_o = ngap_protocol_ext_empty_o; +using count_value_for_pdcp_sn12_ext_ies_o = protocol_ext_empty_o; using count_value_for_pdcp_sn12_ext_ies_container = protocol_ext_container_empty_l; @@ -3068,7 +2887,7 @@ struct count_value_for_pdcp_sn12_s { }; // COUNTValueForPDCP-SN18-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using count_value_for_pdcp_sn18_ext_ies_o = ngap_protocol_ext_empty_o; +using count_value_for_pdcp_sn18_ext_ies_o = protocol_ext_empty_o; using count_value_for_pdcp_sn18_ext_ies_container = protocol_ext_container_empty_l; @@ -3088,7 +2907,7 @@ struct count_value_for_pdcp_sn18_s { }; // CellIDListForRestart-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using cell_id_list_for_restart_ext_ies_o = ngap_protocol_ies_empty_o; +using cell_id_list_for_restart_ext_ies_o = protocol_ies_empty_o; // EUTRA-CGIList ::= SEQUENCE (SIZE (1..256)) OF EUTRA-CGI using eutra_cgi_list_l = dyn_array; @@ -3218,11 +3037,11 @@ struct cell_traffic_trace_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > ngran_trace_id; - ie_field_s ngran_cgi; - ie_field_s > trace_collection_entity_ip_address; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > ngran_trace_id; + ie_field_s ngran_cgi; + ie_field_s > trace_collection_entity_ip_address; // sequence methods cell_traffic_trace_ies_container(); @@ -3232,16 +3051,7 @@ struct cell_traffic_trace_ies_container { }; // CellTrafficTrace ::= SEQUENCE -struct cell_traffic_trace_s { - bool ext = false; - cell_traffic_trace_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using cell_traffic_trace_s = elementary_procedure_option; // CellSize ::= ENUMERATED struct cell_size_opts { @@ -3252,7 +3062,7 @@ struct cell_size_opts { typedef enumerated cell_size_e; // CellType-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using cell_type_ext_ies_o = ngap_protocol_ext_empty_o; +using cell_type_ext_ies_o = protocol_ext_empty_o; using cell_type_ext_ies_container = protocol_ext_container_empty_l; @@ -3271,10 +3081,10 @@ struct cell_type_s { }; // ExpectedUEMovingTrajectoryItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using expected_ue_moving_trajectory_item_ext_ies_o = ngap_protocol_ext_empty_o; +using expected_ue_moving_trajectory_item_ext_ies_o = protocol_ext_empty_o; // ExpectedUEActivityBehaviour-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using expected_ue_activity_behaviour_ext_ies_o = ngap_protocol_ext_empty_o; +using expected_ue_activity_behaviour_ext_ies_o = protocol_ext_empty_o; using expected_ue_moving_trajectory_item_ext_ies_container = protocol_ext_container_empty_l; @@ -3303,7 +3113,7 @@ struct source_of_ue_activity_behaviour_info_opts { typedef enumerated source_of_ue_activity_behaviour_info_e; // TAIListForInactiveItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using tai_list_for_inactive_item_ext_ies_o = ngap_protocol_ext_empty_o; +using tai_list_for_inactive_item_ext_ies_o = protocol_ext_empty_o; // ExpectedHOInterval ::= ENUMERATED struct expected_ho_interv_opts { @@ -3337,7 +3147,7 @@ struct expected_ue_activity_behaviour_s { }; // ExpectedUEBehaviour-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using expected_ue_behaviour_ext_ies_o = ngap_protocol_ext_empty_o; +using expected_ue_behaviour_ext_ies_o = protocol_ext_empty_o; // ExpectedUEMobility ::= ENUMERATED struct expected_ue_mob_opts { @@ -3367,10 +3177,10 @@ struct tai_list_for_inactive_item_s { }; // UEIdentityIndexValue-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using ue_id_idx_value_ext_ies_o = ngap_protocol_ies_empty_o; +using ue_id_idx_value_ext_ies_o = protocol_ies_empty_o; // CoreNetworkAssistanceInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using core_network_assist_info_ext_ies_o = ngap_protocol_ext_empty_o; +using core_network_assist_info_ext_ies_o = protocol_ext_empty_o; using expected_ue_behaviour_ext_ies_container = protocol_ext_container_empty_l; @@ -3380,7 +3190,6 @@ struct expected_ue_behaviour_s { bool expected_ue_activity_behaviour_present = false; bool expected_ho_interv_present = false; bool expected_ue_mob_present = false; - bool expected_ue_moving_trajectory_present = false; bool ie_exts_present = false; expected_ue_activity_behaviour_s expected_ue_activity_behaviour; expected_ho_interv_e expected_ho_interv; @@ -3493,13 +3302,13 @@ struct core_network_assist_info_s { }; // DRBStatusDL12-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using drb_status_dl12_ext_ies_o = ngap_protocol_ext_empty_o; +using drb_status_dl12_ext_ies_o = protocol_ext_empty_o; // DRBStatusDL18-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using drb_status_dl18_ext_ies_o = ngap_protocol_ext_empty_o; +using drb_status_dl18_ext_ies_o = protocol_ext_empty_o; // DRBStatusDL-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using drb_status_dl_ext_ies_o = ngap_protocol_ies_empty_o; +using drb_status_dl_ext_ies_o = protocol_ies_empty_o; using drb_status_dl12_ext_ies_container = protocol_ext_container_empty_l; @@ -3597,13 +3406,13 @@ struct drb_status_dl_c { }; // DRBStatusUL12-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using drb_status_ul12_ext_ies_o = ngap_protocol_ext_empty_o; +using drb_status_ul12_ext_ies_o = protocol_ext_empty_o; // DRBStatusUL18-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using drb_status_ul18_ext_ies_o = ngap_protocol_ext_empty_o; +using drb_status_ul18_ext_ies_o = protocol_ext_empty_o; // DRBStatusUL-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using drb_status_ul_ext_ies_o = ngap_protocol_ies_empty_o; +using drb_status_ul_ext_ies_o = protocol_ies_empty_o; using drb_status_ul12_ext_ies_container = protocol_ext_container_empty_l; @@ -3705,7 +3514,7 @@ struct drb_status_ul_c { }; // DRBsSubjectToStatusTransferItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using drbs_subject_to_status_transfer_item_ext_ies_o = ngap_protocol_ext_empty_o; +using drbs_subject_to_status_transfer_item_ext_ies_o = protocol_ext_empty_o; using drbs_subject_to_status_transfer_item_ext_ies_container = protocol_ext_container_empty_l; @@ -3729,7 +3538,7 @@ struct drbs_subject_to_status_transfer_item_s { using drbs_subject_to_status_transfer_list_l = dyn_array; // DRBsToQosFlowsMappingItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using drbs_to_qos_flows_map_item_ext_ies_o = ngap_protocol_ext_empty_o; +using drbs_to_qos_flows_map_item_ext_ies_o = protocol_ext_empty_o; using drbs_to_qos_flows_map_item_ext_ies_container = protocol_ext_container_empty_l; @@ -3752,7 +3561,7 @@ struct drbs_to_qos_flows_map_item_s { using drbs_to_qos_flows_map_list_l = dyn_array; // DataForwardingResponseDRBItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using data_forwarding_resp_drb_item_ext_ies_o = ngap_protocol_ext_empty_o; +using data_forwarding_resp_drb_item_ext_ies_o = protocol_ext_empty_o; using data_forwarding_resp_drb_item_ext_ies_container = protocol_ext_container_empty_l; @@ -3826,9 +3635,9 @@ struct deactiv_trace_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > ngran_trace_id; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > ngran_trace_id; // sequence methods deactiv_trace_ies_container(); @@ -3838,19 +3647,10 @@ struct deactiv_trace_ies_container { }; // DeactivateTrace ::= SEQUENCE -struct deactiv_trace_s { - bool ext = false; - deactiv_trace_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using deactiv_trace_s = elementary_procedure_option; // ForbiddenAreaInformation-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using forbidden_area_info_item_ext_ies_o = ngap_protocol_ext_empty_o; +using forbidden_area_info_item_ext_ies_o = protocol_ext_empty_o; // ForbiddenTACs ::= SEQUENCE (SIZE (1..4096)) OF OCTET STRING (SIZE (3)) using forbidden_tacs_l = dyn_array >; @@ -3859,10 +3659,10 @@ using forbidden_tacs_l = dyn_array >; using not_allowed_tacs_l = bounded_array, 16>; // RATRestrictions-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using rat_restricts_item_ext_ies_o = ngap_protocol_ext_empty_o; +using rat_restricts_item_ext_ies_o = protocol_ext_empty_o; // ServiceAreaInformation-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using service_area_info_item_ext_ies_o = ngap_protocol_ext_empty_o; +using service_area_info_item_ext_ies_o = protocol_ext_empty_o; using forbidden_area_info_item_ext_ies_container = protocol_ext_container_empty_l; @@ -3902,10 +3702,8 @@ using service_area_info_item_ext_ies_container = protocol_ext_container_empty_l; // ServiceAreaInformation-Item ::= SEQUENCE struct service_area_info_item_s { - bool ext = false; - bool allowed_tacs_present = false; - bool not_allowed_tacs_present = false; - bool ie_exts_present = false; + bool ext = false; + bool ie_exts_present = false; fixed_octstring<3, true> plmn_id; allowed_tacs_l allowed_tacs; not_allowed_tacs_l not_allowed_tacs; @@ -3963,16 +3761,11 @@ using rat_restricts_l = dyn_array; using service_area_info_l = dyn_array; // UEAggregateMaximumBitRate-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using ue_aggregate_maximum_bit_rate_ext_ies_o = ngap_protocol_ext_empty_o; +using ue_aggregate_maximum_bit_rate_ext_ies_o = protocol_ext_empty_o; // MobilityRestrictionList ::= SEQUENCE struct mob_restrict_list_s { - bool ext = false; - bool equivalent_plmns_present = false; - bool rat_restricts_present = false; - bool forbidden_area_info_present = false; - bool service_area_info_present = false; - bool ie_exts_present = false; + bool ext = false; fixed_octstring<3, true> serving_plmn; equivalent_plmns_l equivalent_plmns; rat_restricts_l rat_restricts; @@ -4081,21 +3874,21 @@ struct dl_nas_transport_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool old_amf_present = false; - bool ran_paging_prio_present = false; - bool mob_restrict_list_present = false; - bool idx_to_rfsp_present = false; - bool ue_aggregate_maximum_bit_rate_present = false; - bool allowed_nssai_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > old_amf; - ie_field_s > ran_paging_prio; - ie_field_s > nas_pdu; - ie_field_s mob_restrict_list; - ie_field_s > idx_to_rfsp; - ie_field_s ue_aggregate_maximum_bit_rate; - ie_field_s > allowed_nssai; + bool old_amf_present = false; + bool ran_paging_prio_present = false; + bool mob_restrict_list_present = false; + bool idx_to_rfsp_present = false; + bool ue_aggregate_maximum_bit_rate_present = false; + bool allowed_nssai_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > old_amf; + ie_field_s > ran_paging_prio; + ie_field_s > nas_pdu; + ie_field_s mob_restrict_list; + ie_field_s > idx_to_rfsp; + ie_field_s ue_aggregate_maximum_bit_rate; + ie_field_s > allowed_nssai; // sequence methods dl_nas_transport_ies_container(); @@ -4105,16 +3898,7 @@ struct dl_nas_transport_ies_container { }; // DownlinkNASTransport ::= SEQUENCE -struct dl_nas_transport_s { - bool ext = false; - dl_nas_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using dl_nas_transport_s = elementary_procedure_option; // DownlinkNonUEAssociatedNRPPaTransportIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES struct dl_non_ueassociated_nrp_pa_transport_ies_o { @@ -4174,19 +3958,11 @@ struct dl_non_ueassociated_nrp_pa_transport_ies_container { }; // DownlinkNonUEAssociatedNRPPaTransport ::= SEQUENCE -struct dl_non_ueassociated_nrp_pa_transport_s { - bool ext = false; - dl_non_ueassociated_nrp_pa_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using dl_non_ueassociated_nrp_pa_transport_s = + elementary_procedure_option; // XnExtTLA-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using xn_ext_tla_item_ext_ies_o = ngap_protocol_ext_empty_o; +using xn_ext_tla_item_ext_ies_o = protocol_ext_empty_o; // XnGTP-TLAs ::= SEQUENCE (SIZE (1..16)) OF BIT STRING (SIZE (1..160,...)) using xn_gtp_tlas_l = bounded_array, 16>; @@ -4197,7 +3973,6 @@ using xn_ext_tla_item_ext_ies_container = protocol_ext_container_empty_l; struct xn_ext_tla_item_s { bool ext = false; bool ipsec_tla_present = false; - bool gtp_tlas_present = false; bool ie_exts_present = false; bounded_bitstring<1, 160, true, true> ipsec_tla; xn_gtp_tlas_l gtp_tlas; @@ -4217,18 +3992,17 @@ using xn_ext_tlas_l = dyn_array; using xn_tlas_l = bounded_array, 16>; // XnTNLConfigurationInfo-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using xn_tnl_cfg_info_ext_ies_o = ngap_protocol_ext_empty_o; +using xn_tnl_cfg_info_ext_ies_o = protocol_ext_empty_o; // SONInformationReply-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using son_info_reply_ext_ies_o = ngap_protocol_ext_empty_o; +using son_info_reply_ext_ies_o = protocol_ext_empty_o; using xn_tnl_cfg_info_ext_ies_container = protocol_ext_container_empty_l; // XnTNLConfigurationInfo ::= SEQUENCE struct xn_tnl_cfg_info_s { - bool ext = false; - bool xn_extended_transport_layer_addresses_present = false; - bool ie_exts_present = false; + bool ext = false; + bool ie_exts_present = false; xn_tlas_l xn_transport_layer_addresses; xn_ext_tlas_l xn_extended_transport_layer_addresses; xn_tnl_cfg_info_ext_ies_container ie_exts; @@ -4241,7 +4015,7 @@ struct xn_tnl_cfg_info_s { }; // SONInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using son_info_ext_ies_o = ngap_protocol_ies_empty_o; +using son_info_ext_ies_o = protocol_ies_empty_o; using son_info_reply_ext_ies_container = protocol_ext_container_empty_l; @@ -4269,13 +4043,13 @@ struct son_info_request_opts { typedef enumerated son_info_request_e; // SourceRANNodeID-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using source_ran_node_id_ext_ies_o = ngap_protocol_ext_empty_o; +using source_ran_node_id_ext_ies_o = protocol_ext_empty_o; // TargetRANNodeID-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using target_ran_node_id_ext_ies_o = ngap_protocol_ext_empty_o; +using target_ran_node_id_ext_ies_o = protocol_ext_empty_o; // SONConfigurationTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using son_cfg_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using son_cfg_transfer_ext_ies_o = protocol_ext_empty_o; // SONInformation ::= CHOICE struct son_info_c { @@ -4452,19 +4226,10 @@ struct dl_ran_cfg_transfer_ies_container { }; // DownlinkRANConfigurationTransfer ::= SEQUENCE -struct dl_ran_cfg_transfer_s { - bool ext = false; - dl_ran_cfg_transfer_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using dl_ran_cfg_transfer_s = elementary_procedure_option; // RANStatusTransfer-TransparentContainer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using ran_status_transfer_transparent_container_ext_ies_o = ngap_protocol_ext_empty_o; +using ran_status_transfer_transparent_container_ext_ies_o = protocol_ext_empty_o; using ran_status_transfer_transparent_container_ext_ies_container = protocol_ext_container_empty_l; @@ -4531,9 +4296,9 @@ struct dl_ran_status_transfer_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s ran_status_transfer_transparent_container; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s ran_status_transfer_transparent_container; // sequence methods dl_ran_status_transfer_ies_container(); @@ -4543,16 +4308,7 @@ struct dl_ran_status_transfer_ies_container { }; // DownlinkRANStatusTransfer ::= SEQUENCE -struct dl_ran_status_transfer_s { - bool ext = false; - dl_ran_status_transfer_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using dl_ran_status_transfer_s = elementary_procedure_option; // DownlinkUEAssociatedNRPPaTransportIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES struct dl_ueassociated_nrp_pa_transport_ies_o { @@ -4605,10 +4361,10 @@ struct dl_ueassociated_nrp_pa_transport_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > routing_id; - ie_field_s > nrp_pa_pdu; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > routing_id; + ie_field_s > nrp_pa_pdu; // sequence methods dl_ueassociated_nrp_pa_transport_ies_container(); @@ -4618,19 +4374,10 @@ struct dl_ueassociated_nrp_pa_transport_ies_container { }; // DownlinkUEAssociatedNRPPaTransport ::= SEQUENCE -struct dl_ueassociated_nrp_pa_transport_s { - bool ext = false; - dl_ueassociated_nrp_pa_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using dl_ueassociated_nrp_pa_transport_s = elementary_procedure_option; // PacketErrorRate-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using packet_error_rate_ext_ies_o = ngap_protocol_ext_empty_o; +using packet_error_rate_ext_ies_o = protocol_ext_empty_o; // DelayCritical ::= ENUMERATED struct delay_crit_opts { @@ -4641,7 +4388,7 @@ struct delay_crit_opts { typedef enumerated delay_crit_e; // Dynamic5QIDescriptor-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using dynamic5_qi_descriptor_ext_ies_o = ngap_protocol_ext_empty_o; +using dynamic5_qi_descriptor_ext_ies_o = protocol_ext_empty_o; using packet_error_rate_ext_ies_container = protocol_ext_container_empty_l; @@ -4695,7 +4442,7 @@ struct dl_forwarding_opts { typedef enumerated dl_forwarding_e; // E-RABInformationItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using erab_info_item_ext_ies_o = ngap_protocol_ext_empty_o; +using erab_info_item_ext_ies_o = protocol_ext_empty_o; using erab_info_item_ext_ies_container = protocol_ext_container_empty_l; @@ -4719,7 +4466,7 @@ struct erab_info_item_s { using erab_info_list_l = dyn_array; // EPS-TAI-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using eps_tai_ext_ies_o = ngap_protocol_ext_empty_o; +using eps_tai_ext_ies_o = protocol_ext_empty_o; using eps_tai_ext_ies_container = protocol_ext_container_empty_l; @@ -4748,7 +4495,7 @@ using emergency_area_id_list_l = dyn_array >; using emergency_area_id_list_for_restart_l = dyn_array >; // EmergencyFallbackIndicator-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using emergency_fallback_ind_ext_ies_o = ngap_protocol_ext_empty_o; +using emergency_fallback_ind_ext_ies_o = protocol_ext_empty_o; // EmergencyFallbackRequestIndicator ::= ENUMERATED struct emergency_fallback_request_ind_opts { @@ -4837,14 +4584,14 @@ struct error_ind_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool amf_ue_ngap_id_present = false; - bool ran_ue_ngap_id_present = false; - bool cause_present = false; - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s cause; - ie_field_s crit_diagnostics; + bool amf_ue_ngap_id_present = false; + bool ran_ue_ngap_id_present = false; + bool cause_present = false; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s cause; + ie_field_s crit_diagnostics; // sequence methods error_ind_ies_container(); @@ -4854,19 +4601,10 @@ struct error_ind_ies_container { }; // ErrorIndication ::= SEQUENCE -struct error_ind_s { - bool ext = false; - error_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using error_ind_s = elementary_procedure_option; // FiveG-S-TMSI-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using five_g_s_tmsi_ext_ies_o = ngap_protocol_ext_empty_o; +using five_g_s_tmsi_ext_ies_o = protocol_ext_empty_o; using five_g_s_tmsi_ext_ies_container = protocol_ext_container_empty_l; @@ -4887,7 +4625,7 @@ struct five_g_s_tmsi_s { }; // GBR-QosInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using gbr_qos_info_ext_ies_o = ngap_protocol_ext_empty_o; +using gbr_qos_info_ext_ies_o = protocol_ext_empty_o; // NotificationControl ::= ENUMERATED struct notif_ctrl_opts { @@ -4971,9 +4709,9 @@ struct ho_cancel_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s cause; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s cause; // sequence methods ho_cancel_ies_container(); @@ -4983,16 +4721,7 @@ struct ho_cancel_ies_container { }; // HandoverCancel ::= SEQUENCE -struct ho_cancel_s { - bool ext = false; - ho_cancel_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_cancel_s = elementary_procedure_option; // HandoverCancelAcknowledgeIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES struct ho_cancel_ack_ies_o { @@ -5043,10 +4772,10 @@ struct ho_cancel_ack_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s crit_diagnostics; // sequence methods ho_cancel_ack_ies_container(); @@ -5056,22 +4785,13 @@ struct ho_cancel_ack_ies_container { }; // HandoverCancelAcknowledge ::= SEQUENCE -struct ho_cancel_ack_s { - bool ext = false; - ho_cancel_ack_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_cancel_ack_s = elementary_procedure_option; // PDUSessionResourceHandoverItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_ho_item_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_ho_item_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceToReleaseItemHOCmd-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_to_release_item_ho_cmd_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_to_release_item_ho_cmd_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_ho_item_ext_ies_container = protocol_ext_container_empty_l; @@ -5194,13 +4914,13 @@ struct ho_cmd_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool nas_security_params_from_ngran_present = false; - bool pdu_session_res_to_release_list_ho_cmd_present = false; - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s handov_type; - ie_field_s > nas_security_params_from_ngran; + bool nas_security_params_from_ngran_present = false; + bool pdu_session_res_to_release_list_ho_cmd_present = false; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s handov_type; + ie_field_s > nas_security_params_from_ngran; ie_field_s > pdu_session_res_ho_list; ie_field_s > pdu_session_res_to_release_list_ho_cmd; @@ -5215,19 +4935,10 @@ struct ho_cmd_ies_container { }; // HandoverCommand ::= SEQUENCE -struct ho_cmd_s { - bool ext = false; - ho_cmd_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_cmd_s = elementary_procedure_option; // QosFlowPerTNLInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_per_tnl_info_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_per_tnl_info_ext_ies_o = protocol_ext_empty_o; using qos_flow_per_tnl_info_ext_ies_container = protocol_ext_container_empty_l; @@ -5247,7 +4958,7 @@ struct qos_flow_per_tnl_info_s { }; // QosFlowPerTNLInformationItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_per_tnl_info_item_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_per_tnl_info_item_ext_ies_o = protocol_ext_empty_o; using qos_flow_per_tnl_info_item_ext_ies_container = protocol_ext_container_empty_l; @@ -5266,7 +4977,7 @@ struct qos_flow_per_tnl_info_item_s { }; // QosFlowToBeForwardedItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_to_be_forwarded_item_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_to_be_forwarded_item_ext_ies_o = protocol_ext_empty_o; // QosFlowPerTNLInformationList ::= SEQUENCE (SIZE (1..3)) OF QosFlowPerTNLInformationItem using qos_flow_per_tnl_info_list_l = dyn_array; @@ -5324,11 +5035,8 @@ using qos_flow_to_be_forwarded_list_l = dyn_array; // member variables - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s cause; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s cause; + ie_field_s crit_diagnostics; // sequence methods ho_fail_ies_container(); @@ -5405,28 +5113,19 @@ struct ho_fail_ies_container { }; // HandoverFailure ::= SEQUENCE -struct ho_fail_s { - bool ext = false; - ho_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_fail_s = elementary_procedure_option; // UserLocationInformationEUTRA-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using user_location_info_eutra_ext_ies_o = ngap_protocol_ext_empty_o; +using user_location_info_eutra_ext_ies_o = protocol_ext_empty_o; // UserLocationInformationN3IWF-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using user_location_info_n3_iwf_ext_ies_o = ngap_protocol_ext_empty_o; +using user_location_info_n3_iwf_ext_ies_o = protocol_ext_empty_o; // UserLocationInformationNR-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using user_location_info_nr_ext_ies_o = ngap_protocol_ext_empty_o; +using user_location_info_nr_ext_ies_o = protocol_ext_empty_o; // UserLocationInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using user_location_info_ext_ies_o = ngap_protocol_ies_empty_o; +using user_location_info_ext_ies_o = protocol_ies_empty_o; using user_location_info_eutra_ext_ies_container = protocol_ext_container_empty_l; @@ -5616,9 +5315,9 @@ struct ho_notify_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s user_location_info; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s user_location_info; // sequence methods ho_notify_ies_container(); @@ -5628,16 +5327,7 @@ struct ho_notify_ies_container { }; // HandoverNotify ::= SEQUENCE -struct ho_notify_s { - bool ext = false; - ho_notify_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_notify_s = elementary_procedure_option; // HandoverPreparationFailureIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES struct ho_prep_fail_ies_o { @@ -5690,11 +5380,11 @@ struct ho_prep_fail_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s cause; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s cause; + ie_field_s crit_diagnostics; // sequence methods ho_prep_fail_ies_container(); @@ -5704,19 +5394,10 @@ struct ho_prep_fail_ies_container { }; // HandoverPreparationFailure ::= SEQUENCE -struct ho_prep_fail_s { - bool ext = false; - ho_prep_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_prep_fail_s = elementary_procedure_option; // HandoverPreparationUnsuccessfulTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using ho_prep_unsuccessful_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using ho_prep_unsuccessful_transfer_ext_ies_o = protocol_ext_empty_o; using ho_prep_unsuccessful_transfer_ext_ies_container = protocol_ext_container_empty_l; @@ -5735,7 +5416,7 @@ struct ho_prep_unsuccessful_transfer_s { }; // PDUSessionResourceSetupItemHOReq-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_setup_item_ho_req_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_setup_item_ho_req_ext_ies_o = protocol_ext_empty_o; // EventType ::= ENUMERATED struct event_type_opts { @@ -5755,7 +5436,7 @@ struct event_type_opts { typedef enumerated event_type_e; // LocationReportingRequestType-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using location_report_request_type_ext_ies_o = ngap_protocol_ext_empty_o; +using location_report_request_type_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_setup_item_ho_req_ext_ies_container = protocol_ext_container_empty_l; @@ -5784,10 +5465,10 @@ struct report_area_opts { typedef enumerated report_area_e; // SecurityContext-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using security_context_ext_ies_o = ngap_protocol_ext_empty_o; +using security_context_ext_ies_o = protocol_ext_empty_o; // TraceActivation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using trace_activation_ext_ies_o = ngap_protocol_ext_empty_o; +using trace_activation_ext_ies_o = protocol_ext_empty_o; // TraceDepth ::= ENUMERATED struct trace_depth_opts { @@ -5807,14 +5488,13 @@ struct trace_depth_opts { typedef enumerated trace_depth_e; // UESecurityCapabilities-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using ue_security_cap_ext_ies_o = ngap_protocol_ext_empty_o; +using ue_security_cap_ext_ies_o = protocol_ext_empty_o; using location_report_request_type_ext_ies_container = protocol_ext_container_empty_l; // LocationReportingRequestType ::= SEQUENCE struct location_report_request_type_s { bool ext = false; - bool area_of_interest_list_present = false; bool location_report_ref_id_to_be_cancelled_present = false; bool ie_exts_present = false; event_type_e event_type; @@ -6034,24 +5714,24 @@ struct ho_request_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool core_network_assist_info_present = false; - bool new_security_context_ind_present = false; - bool nasc_present = false; - bool trace_activation_present = false; - bool masked_imeisv_present = false; - bool mob_restrict_list_present = false; - bool location_report_request_type_present = false; - bool rrc_inactive_transition_report_request_present = false; - bool redirection_voice_fallback_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s handov_type; - ie_field_s cause; - ie_field_s ue_aggregate_maximum_bit_rate; - ie_field_s core_network_assist_info; - ie_field_s ue_security_cap; - ie_field_s security_context; - ie_field_s new_security_context_ind; - ie_field_s > nasc; + bool core_network_assist_info_present = false; + bool new_security_context_ind_present = false; + bool nasc_present = false; + bool trace_activation_present = false; + bool masked_imeisv_present = false; + bool mob_restrict_list_present = false; + bool location_report_request_type_present = false; + bool rrc_inactive_transition_report_request_present = false; + bool redirection_voice_fallback_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s handov_type; + ie_field_s cause; + ie_field_s ue_aggregate_maximum_bit_rate; + ie_field_s core_network_assist_info; + ie_field_s ue_security_cap; + ie_field_s security_context; + ie_field_s new_security_context_ind; + ie_field_s > nasc; ie_field_s > pdu_session_res_setup_list_ho_req; ie_field_s > allowed_nssai; ie_field_s trace_activation; @@ -6071,22 +5751,13 @@ struct ho_request_ies_container { }; // HandoverRequest ::= SEQUENCE -struct ho_request_s { - bool ext = false; - ho_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_request_s = elementary_procedure_option; // PDUSessionResourceAdmittedItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_admitted_item_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_admitted_item_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceFailedToSetupItemHOAck-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_failed_to_setup_item_ho_ack_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_failed_to_setup_item_ho_ack_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_admitted_item_ext_ies_container = protocol_ext_container_empty_l; @@ -6195,10 +5866,10 @@ struct ho_request_ack_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool pdu_session_res_failed_to_setup_list_ho_ack_present = false; - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + bool pdu_session_res_failed_to_setup_list_ho_ack_present = false; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_admitted_list; ie_field_s > pdu_session_res_failed_to_setup_list_ho_ack; @@ -6213,19 +5884,10 @@ struct ho_request_ack_ies_container { }; // HandoverRequestAcknowledge ::= SEQUENCE -struct ho_request_ack_s { - bool ext = false; - ho_request_ack_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_request_ack_s = elementary_procedure_option; // QosFlowWithCauseItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_with_cause_item_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_with_cause_item_ext_ies_o = protocol_ext_empty_o; // ConfidentialityProtectionResult ::= ENUMERATED struct confidentiality_protection_result_opts { @@ -6261,7 +5923,7 @@ struct qos_flow_with_cause_item_s { }; // SecurityResult-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using security_result_ext_ies_o = ngap_protocol_ext_empty_o; +using security_result_ext_ies_o = protocol_ext_empty_o; // HandoverRequestAcknowledgeTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION struct ho_request_ack_transfer_ext_ies_o { @@ -6317,12 +5979,9 @@ struct security_result_s { // HandoverRequestAcknowledgeTransfer ::= SEQUENCE struct ho_request_ack_transfer_s { - bool ext = false; - bool dlforwarding_up_tnl_info_present = false; - bool security_result_present = false; - bool qos_flow_failed_to_setup_list_present = false; - bool data_forwarding_resp_drb_list_present = false; - bool ie_exts_present = false; + bool ext = false; + bool dlforwarding_up_tnl_info_present = false; + bool security_result_present = false; up_transport_layer_info_c dl_ngu_up_tnl_info; up_transport_layer_info_c dlforwarding_up_tnl_info; security_result_s security_result; @@ -6339,10 +5998,10 @@ struct ho_request_ack_transfer_s { }; // PDUSessionResourceItemHORqd-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_item_ho_rqd_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_item_ho_rqd_ext_ies_o = protocol_ext_empty_o; // TargeteNB-ID-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using targetenb_id_ext_ies_o = ngap_protocol_ext_empty_o; +using targetenb_id_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_item_ho_rqd_ext_ies_container = protocol_ext_container_empty_l; @@ -6362,7 +6021,7 @@ struct pdu_session_res_item_ho_rqd_s { }; // TargetID-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using target_id_ext_ies_o = ngap_protocol_ies_empty_o; +using target_id_ext_ies_o = protocol_ies_empty_o; using targetenb_id_ext_ies_container = protocol_ext_container_empty_l; @@ -6522,13 +6181,13 @@ struct ho_required_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool direct_forwarding_path_availability_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s handov_type; - ie_field_s cause; - ie_field_s target_id; - ie_field_s direct_forwarding_path_availability; + bool direct_forwarding_path_availability_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s handov_type; + ie_field_s cause; + ie_field_s target_id; + ie_field_s direct_forwarding_path_availability; ie_field_s > pdu_session_res_list_ho_rqd; ie_field_s > source_to_target_transparent_container; @@ -6540,19 +6199,10 @@ struct ho_required_ies_container { }; // HandoverRequired ::= SEQUENCE -struct ho_required_s { - bool ext = false; - ho_required_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_required_s = elementary_procedure_option; // HandoverRequiredTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using ho_required_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using ho_required_transfer_ext_ies_o = protocol_ext_empty_o; using ho_required_transfer_ext_ies_container = protocol_ext_container_empty_l; @@ -6572,7 +6222,7 @@ struct ho_required_transfer_s { }; // HandoverResourceAllocationUnsuccessfulTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using ho_res_alloc_unsuccessful_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using ho_res_alloc_unsuccessful_transfer_ext_ies_o = protocol_ext_empty_o; using ho_res_alloc_unsuccessful_transfer_ext_ies_container = protocol_ext_container_empty_l; @@ -6593,7 +6243,7 @@ struct ho_res_alloc_unsuccessful_transfer_s { }; // RecommendedRANNodeItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using recommended_ran_node_item_ext_ies_o = ngap_protocol_ext_empty_o; +using recommended_ran_node_item_ext_ies_o = protocol_ext_empty_o; using recommended_ran_node_item_ext_ies_container = protocol_ext_container_empty_l; @@ -6615,10 +6265,10 @@ struct recommended_ran_node_item_s { using recommended_ran_node_list_l = dyn_array; // RecommendedRANNodesForPaging-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using recommended_ran_nodes_for_paging_ext_ies_o = ngap_protocol_ext_empty_o; +using recommended_ran_nodes_for_paging_ext_ies_o = protocol_ext_empty_o; // InfoOnRecommendedCellsAndRANNodesForPaging-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using info_on_recommended_cells_and_ran_nodes_for_paging_ext_ies_o = ngap_protocol_ext_empty_o; +using info_on_recommended_cells_and_ran_nodes_for_paging_ext_ies_o = protocol_ext_empty_o; using recommended_ran_nodes_for_paging_ext_ies_container = protocol_ext_container_empty_l; @@ -6654,7 +6304,7 @@ struct info_on_recommended_cells_and_ran_nodes_for_paging_s { }; // PDUSessionResourceFailedToSetupItemCxtFail-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_failed_to_setup_item_cxt_fail_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_failed_to_setup_item_cxt_fail_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_failed_to_setup_item_cxt_fail_ext_ies_container = protocol_ext_container_empty_l; @@ -6736,10 +6386,10 @@ struct init_context_setup_fail_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool pdu_session_res_failed_to_setup_list_cxt_fail_present = false; - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + bool pdu_session_res_failed_to_setup_list_cxt_fail_present = false; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_failed_to_setup_list_cxt_fail; ie_field_s cause; @@ -6753,26 +6403,16 @@ struct init_context_setup_fail_ies_container { }; // InitialContextSetupFailure ::= SEQUENCE -struct init_context_setup_fail_s { - bool ext = false; - init_context_setup_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using init_context_setup_fail_s = elementary_procedure_option; // PDUSessionResourceSetupItemCxtReq-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_setup_item_cxt_req_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_setup_item_cxt_req_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_setup_item_cxt_req_ext_ies_container = protocol_ext_container_empty_l; // PDUSessionResourceSetupItemCxtReq ::= SEQUENCE struct pdu_session_res_setup_item_cxt_req_s { bool ext = false; - bool nas_pdu_present = false; bool ie_exts_present = false; uint16_t pdu_session_id = 0; unbounded_octstring nas_pdu; @@ -6788,7 +6428,7 @@ struct pdu_session_res_setup_item_cxt_req_s { }; // UERadioCapabilityForPaging-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using ue_radio_cap_for_paging_ext_ies_o = ngap_protocol_ext_empty_o; +using ue_radio_cap_for_paging_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceSetupListCxtReq ::= SEQUENCE (SIZE (1..256)) OF PDUSessionResourceSetupItemCxtReq using pdu_session_res_setup_list_cxt_req_l = dyn_array; @@ -6797,10 +6437,8 @@ using ue_radio_cap_for_paging_ext_ies_container = protocol_ext_container_empty_l // UERadioCapabilityForPaging ::= SEQUENCE struct ue_radio_cap_for_paging_s { - bool ext = false; - bool ueradio_cap_for_paging_of_nr_present = false; - bool ueradio_cap_for_paging_of_eutra_present = false; - bool ie_exts_present = false; + bool ext = false; + bool ie_exts_present = false; unbounded_octstring ueradio_cap_for_paging_of_nr; unbounded_octstring ueradio_cap_for_paging_of_eutra; ue_radio_cap_for_paging_ext_ies_container ie_exts; @@ -6930,26 +6568,26 @@ struct init_context_setup_request_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool old_amf_present = false; - bool ue_aggregate_maximum_bit_rate_present = false; - bool core_network_assist_info_present = false; - bool pdu_session_res_setup_list_cxt_req_present = false; - bool trace_activation_present = false; - bool mob_restrict_list_present = false; - bool ue_radio_cap_present = false; - bool idx_to_rfsp_present = false; - bool masked_imeisv_present = false; - bool nas_pdu_present = false; - bool emergency_fallback_ind_present = false; - bool rrc_inactive_transition_report_request_present = false; - bool ue_radio_cap_for_paging_present = false; - bool redirection_voice_fallback_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > old_amf; - ie_field_s ue_aggregate_maximum_bit_rate; - ie_field_s core_network_assist_info; - ie_field_s guami; + bool old_amf_present = false; + bool ue_aggregate_maximum_bit_rate_present = false; + bool core_network_assist_info_present = false; + bool pdu_session_res_setup_list_cxt_req_present = false; + bool trace_activation_present = false; + bool mob_restrict_list_present = false; + bool ue_radio_cap_present = false; + bool idx_to_rfsp_present = false; + bool masked_imeisv_present = false; + bool nas_pdu_present = false; + bool emergency_fallback_ind_present = false; + bool rrc_inactive_transition_report_request_present = false; + bool ue_radio_cap_for_paging_present = false; + bool redirection_voice_fallback_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > old_amf; + ie_field_s ue_aggregate_maximum_bit_rate; + ie_field_s core_network_assist_info; + ie_field_s guami; ie_field_s > pdu_session_res_setup_list_cxt_req; ie_field_s > allowed_nssai; ie_field_s ue_security_cap; @@ -6973,22 +6611,13 @@ struct init_context_setup_request_ies_container { }; // InitialContextSetupRequest ::= SEQUENCE -struct init_context_setup_request_s { - bool ext = false; - init_context_setup_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using init_context_setup_request_s = elementary_procedure_option; // PDUSessionResourceFailedToSetupItemCxtRes-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_failed_to_setup_item_cxt_res_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_failed_to_setup_item_cxt_res_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceSetupItemCxtRes-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_setup_item_cxt_res_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_setup_item_cxt_res_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_failed_to_setup_item_cxt_res_ext_ies_container = protocol_ext_container_empty_l; @@ -7093,11 +6722,11 @@ struct init_context_setup_resp_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool pdu_session_res_setup_list_cxt_res_present = false; - bool pdu_session_res_failed_to_setup_list_cxt_res_present = false; - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + bool pdu_session_res_setup_list_cxt_res_present = false; + bool pdu_session_res_failed_to_setup_list_cxt_res_present = false; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_setup_list_cxt_res; ie_field_s > pdu_session_res_failed_to_setup_list_cxt_res; @@ -7111,16 +6740,7 @@ struct init_context_setup_resp_ies_container { }; // InitialContextSetupResponse ::= SEQUENCE -struct init_context_setup_resp_s { - bool ext = false; - init_context_setup_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using init_context_setup_resp_s = elementary_procedure_option; // RRCEstablishmentCause ::= ENUMERATED struct rrcestablishment_cause_opts { @@ -7228,18 +6848,18 @@ struct init_ue_msg_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool five_g_s_tmsi_present = false; - bool amf_set_id_present = false; - bool ue_context_request_present = false; - bool allowed_nssai_present = false; - ie_field_s > ran_ue_ngap_id; - ie_field_s > nas_pdu; - ie_field_s user_location_info; - ie_field_s rrcestablishment_cause; - ie_field_s five_g_s_tmsi; - ie_field_s > amf_set_id; - ie_field_s ue_context_request; - ie_field_s > allowed_nssai; + bool five_g_s_tmsi_present = false; + bool amf_set_id_present = false; + bool ue_context_request_present = false; + bool allowed_nssai_present = false; + ie_field_s ran_ue_ngap_id; + ie_field_s > nas_pdu; + ie_field_s user_location_info; + ie_field_s rrcestablishment_cause; + ie_field_s five_g_s_tmsi; + ie_field_s > amf_set_id; + ie_field_s ue_context_request; + ie_field_s > allowed_nssai; // sequence methods init_ue_msg_ies_container(); @@ -7249,19 +6869,10 @@ struct init_ue_msg_ies_container { }; // InitialUEMessage ::= SEQUENCE -struct init_ue_msg_s { - bool ext = false; - init_ue_msg_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using init_ue_msg_s = elementary_procedure_option; // SliceOverloadItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using slice_overload_item_ext_ies_o = ngap_protocol_ext_empty_o; +using slice_overload_item_ext_ies_o = protocol_ext_empty_o; // OverloadAction ::= ENUMERATED struct overload_action_opts { @@ -7279,7 +6890,7 @@ struct overload_action_opts { typedef enumerated overload_action_e; // OverloadResponse-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using overload_resp_ext_ies_o = ngap_protocol_ies_empty_o; +using overload_resp_ext_ies_o = protocol_ies_empty_o; using slice_overload_item_ext_ies_container = protocol_ext_container_empty_l; @@ -7298,7 +6909,7 @@ struct slice_overload_item_s { }; // UE-associatedLogicalNG-connectionItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using ue_associated_lc_ng_conn_item_ext_ies_o = ngap_protocol_ext_empty_o; +using ue_associated_lc_ng_conn_item_ext_ies_o = protocol_ext_empty_o; // OverloadResponse ::= CHOICE struct overload_resp_c { @@ -7351,19 +6962,19 @@ struct overload_resp_c { }; // OverloadStartNSSAIItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using overload_start_nssai_item_ext_ies_o = ngap_protocol_ext_empty_o; +using overload_start_nssai_item_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceFailedToModifyItemModCfm-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_failed_to_modify_item_mod_cfm_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_failed_to_modify_item_mod_cfm_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceFailedToModifyItemModRes-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_failed_to_modify_item_mod_res_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_failed_to_modify_item_mod_res_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceFailedToSetupItemPSReq-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_failed_to_setup_item_ps_req_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_failed_to_setup_item_ps_req_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceFailedToSetupItemSURes-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_failed_to_setup_item_su_res_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_failed_to_setup_item_su_res_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceItemCxtRelCpl-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION struct pdu_session_res_item_cxt_rel_cpl_ext_ies_o { @@ -7398,13 +7009,13 @@ struct pdu_session_res_item_cxt_rel_cpl_ext_ies_o { }; // PDUSessionResourceItemCxtRelReq-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_item_cxt_rel_req_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_item_cxt_rel_req_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceModifyItemModCfm-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_modify_item_mod_cfm_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_modify_item_mod_cfm_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceModifyItemModInd-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_modify_item_mod_ind_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_modify_item_mod_ind_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceModifyItemModReq-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION struct pdu_session_res_modify_item_mod_req_ext_ies_o { @@ -7439,40 +7050,40 @@ struct pdu_session_res_modify_item_mod_req_ext_ies_o { }; // PDUSessionResourceModifyItemModRes-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_modify_item_mod_res_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_modify_item_mod_res_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceNotifyItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_notify_item_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_notify_item_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceReleasedItemNot-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_released_item_not_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_released_item_not_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceReleasedItemPSAck-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_released_item_ps_ack_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_released_item_ps_ack_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceReleasedItemPSFail-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_released_item_ps_fail_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_released_item_ps_fail_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceReleasedItemRelRes-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_released_item_rel_res_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_released_item_rel_res_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceSecondaryRATUsageItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_secondary_ratusage_item_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_secondary_ratusage_item_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceSetupItemSUReq-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_setup_item_su_req_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_setup_item_su_req_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceSetupItemSURes-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_setup_item_su_res_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_setup_item_su_res_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceSwitchedItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_switched_item_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_switched_item_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceToBeSwitchedDLItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_to_be_switched_dl_item_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_to_be_switched_dl_item_ext_ies_o = protocol_ext_empty_o; // PDUSessionResourceToReleaseItemRelCmd-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_to_release_item_rel_cmd_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_to_release_item_rel_cmd_ext_ies_o = protocol_ext_empty_o; // PrivateIE-ID ::= CHOICE struct private_ie_id_c { @@ -7513,13 +7124,13 @@ struct private_ie_id_c { using slice_overload_list_l = dyn_array; // SupportedTAItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using supported_ta_item_ext_ies_o = ngap_protocol_ext_empty_o; +using supported_ta_item_ext_ies_o = protocol_ext_empty_o; // TAIListForPagingItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using tai_list_for_paging_item_ext_ies_o = ngap_protocol_ext_empty_o; +using tai_list_for_paging_item_ext_ies_o = protocol_ext_empty_o; // UE-NGAP-ID-pair-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using ue_ngap_id_pair_ext_ies_o = ngap_protocol_ext_empty_o; +using ue_ngap_id_pair_ext_ies_o = protocol_ext_empty_o; using ue_associated_lc_ng_conn_item_ext_ies_container = protocol_ext_container_empty_l; @@ -7549,7 +7160,7 @@ struct ue_presence_opts { typedef enumerated ue_presence_e; // UEPresenceInAreaOfInterestItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using ue_presence_in_area_of_interest_item_ext_ies_o = ngap_protocol_ext_empty_o; +using ue_presence_in_area_of_interest_item_ext_ies_o = protocol_ext_empty_o; // NR-CGIListForWarning ::= SEQUENCE (SIZE (1..65535)) OF NR-CGI using nr_cgi_list_for_warning_l = dyn_array; @@ -7644,9 +7255,8 @@ struct pdu_session_res_failed_to_setup_item_su_res_s { // PDUSessionResourceItemCxtRelCpl ::= SEQUENCE struct pdu_session_res_item_cxt_rel_cpl_s { - bool ext = false; - bool ie_exts_present = false; - uint16_t pdu_session_id = 0; + bool ext = false; + uint16_t pdu_session_id = 0; protocol_ext_container_l ie_exts; // ... @@ -7708,10 +7318,8 @@ struct pdu_session_res_modify_item_mod_ind_s { // PDUSessionResourceModifyItemModReq ::= SEQUENCE struct pdu_session_res_modify_item_mod_req_s { - bool ext = false; - bool nas_pdu_present = false; - bool ie_exts_present = false; - uint16_t pdu_session_id = 0; + bool ext = false; + uint16_t pdu_session_id = 0; unbounded_octstring nas_pdu; unbounded_octstring pdu_session_res_modify_request_transfer; protocol_ext_container_l ie_exts; @@ -7846,10 +7454,9 @@ using pdu_session_res_setup_item_su_req_ext_ies_container = protocol_ext_contain // PDUSessionResourceSetupItemSUReq ::= SEQUENCE struct pdu_session_res_setup_item_su_req_s { - bool ext = false; - bool pdu_session_nas_pdu_present = false; - bool ie_exts_present = false; - uint16_t pdu_session_id = 0; + bool ext = false; + bool ie_exts_present = false; + uint16_t pdu_session_id = 0; unbounded_octstring pdu_session_nas_pdu; s_nssai_s s_nssai; unbounded_octstring pdu_session_res_setup_request_transfer; @@ -7931,7 +7538,7 @@ struct pdu_session_res_to_release_item_rel_cmd_s { }; // PWSFailedCellIDList-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using pws_failed_cell_id_list_ext_ies_o = ngap_protocol_ies_empty_o; +using pws_failed_cell_id_list_ext_ies_o = protocol_ies_empty_o; // ResetAll ::= ENUMERATED struct reset_all_opts { @@ -7942,7 +7549,7 @@ struct reset_all_opts { typedef enumerated reset_all_e; // ResetType-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using reset_type_ext_ies_o = ngap_protocol_ies_empty_o; +using reset_type_ext_ies_o = protocol_ies_empty_o; using supported_ta_item_ext_ies_container = protocol_ext_container_empty_l; @@ -7998,13 +7605,13 @@ struct ue_ngap_id_pair_s { }; // UE-NGAP-IDs-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using ue_ngap_ids_ext_ies_o = ngap_protocol_ies_empty_o; +using ue_ngap_ids_ext_ies_o = protocol_ies_empty_o; // UE-associatedLogicalNG-connectionList ::= SEQUENCE (SIZE (1..65536)) OF UE-associatedLogicalNG-connectionItem using ue_associated_lc_ng_conn_list_l = dyn_array; // UEPagingIdentity-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using ue_paging_id_ext_ies_o = ngap_protocol_ies_empty_o; +using ue_paging_id_ext_ies_o = protocol_ies_empty_o; using ue_presence_in_area_of_interest_item_ext_ies_container = protocol_ext_container_empty_l; @@ -8024,7 +7631,7 @@ struct ue_presence_in_area_of_interest_item_s { }; // WarningAreaList-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using warning_area_list_ext_ies_o = ngap_protocol_ies_empty_o; +using warning_area_list_ext_ies_o = protocol_ies_empty_o; // CancelAllWarningMessages ::= ENUMERATED struct cancel_all_warning_msgs_opts { @@ -9013,7 +8620,7 @@ struct overload_start_ies_o { }; // OverloadStopIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using overload_stop_ies_o = ngap_protocol_ies_empty_o; +using overload_stop_ies_o = protocol_ies_empty_o; // PDUSessionResourceModifyConfirmIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES struct pdu_session_res_modify_confirm_ies_o { @@ -11187,11 +10794,11 @@ struct location_report_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool ue_presence_in_area_of_interest_list_present = false; - bool ps_cell_info_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s user_location_info; + bool ue_presence_in_area_of_interest_list_present = false; + bool ps_cell_info_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s user_location_info; ie_field_s > ue_presence_in_area_of_interest_list; ie_field_s location_report_request_type; ie_field_s ps_cell_info; @@ -11204,25 +10811,16 @@ struct location_report_ies_container { }; // LocationReport ::= SEQUENCE -struct location_report_s { - bool ext = false; - location_report_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using location_report_s = elementary_procedure_option; struct location_report_ctrl_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s location_report_request_type; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s location_report_request_type; // sequence methods location_report_ctrl_ies_container(); @@ -11232,25 +10830,16 @@ struct location_report_ctrl_ies_container { }; // LocationReportingControl ::= SEQUENCE -struct location_report_ctrl_s { - bool ext = false; - location_report_ctrl_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using location_report_ctrl_s = elementary_procedure_option; struct location_report_fail_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s cause; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s cause; // sequence methods location_report_fail_ind_ies_container(); @@ -11260,26 +10849,17 @@ struct location_report_fail_ind_ies_container { }; // LocationReportingFailureIndication ::= SEQUENCE -struct location_report_fail_ind_s { - bool ext = false; - location_report_fail_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using location_report_fail_ind_s = elementary_procedure_option; struct nas_non_delivery_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > nas_pdu; - ie_field_s cause; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > nas_pdu; + ie_field_s cause; // sequence methods nas_non_delivery_ind_ies_container(); @@ -11289,16 +10869,7 @@ struct nas_non_delivery_ind_ies_container { }; // NASNonDeliveryIndication ::= SEQUENCE -struct nas_non_delivery_ind_s { - bool ext = false; - nas_non_delivery_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using nas_non_delivery_ind_s = elementary_procedure_option; struct ng_reset_ies_container { template @@ -11316,16 +10887,7 @@ struct ng_reset_ies_container { }; // NGReset ::= SEQUENCE -struct ng_reset_s { - bool ext = false; - ng_reset_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ng_reset_s = elementary_procedure_option; struct ng_reset_ack_ies_container { template @@ -11345,16 +10907,7 @@ struct ng_reset_ack_ies_container { }; // NGResetAcknowledge ::= SEQUENCE -struct ng_reset_ack_s { - bool ext = false; - ng_reset_ack_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ng_reset_ack_s = elementary_procedure_option; struct ng_setup_fail_ies_container { template @@ -11375,16 +10928,7 @@ struct ng_setup_fail_ies_container { }; // NGSetupFailure ::= SEQUENCE -struct ng_setup_fail_s { - bool ext = false; - ng_setup_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ng_setup_fail_s = elementary_procedure_option; struct ng_setup_request_ies_container { template @@ -11407,16 +10951,7 @@ struct ng_setup_request_ies_container { }; // NGSetupRequest ::= SEQUENCE -struct ng_setup_request_s { - bool ext = false; - ng_setup_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ng_setup_request_s = elementary_procedure_option; struct ng_setup_resp_ies_container { template @@ -11440,16 +10975,7 @@ struct ng_setup_resp_ies_container { }; // NGSetupResponse ::= SEQUENCE -struct ng_setup_resp_s { - bool ext = false; - ng_setup_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ng_setup_resp_s = elementary_procedure_option; struct overload_start_ies_container { template @@ -11471,49 +10997,22 @@ struct overload_start_ies_container { }; // OverloadStart ::= SEQUENCE -struct overload_start_s { - bool ext = false; - overload_start_ies_container protocol_ies; - // ... +using overload_start_s = elementary_procedure_option; - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - -struct protocol_ie_container_empty_l { - template - using ie_field_s = protocol_ie_container_item_s; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; using overload_stop_ies_container = protocol_ie_container_empty_l; // OverloadStop ::= SEQUENCE -struct overload_stop_s { - bool ext = false; - overload_stop_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using overload_stop_s = elementary_procedure_option; struct pdu_session_res_modify_confirm_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool pdu_session_res_failed_to_modify_list_mod_cfm_present = false; - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + bool pdu_session_res_failed_to_modify_list_mod_cfm_present = false; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_modify_list_mod_cfm; ie_field_s > pdu_session_res_failed_to_modify_list_mod_cfm; @@ -11527,24 +11026,15 @@ struct pdu_session_res_modify_confirm_ies_container { }; // PDUSessionResourceModifyConfirm ::= SEQUENCE -struct pdu_session_res_modify_confirm_s { - bool ext = false; - pdu_session_res_modify_confirm_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pdu_session_res_modify_confirm_s = elementary_procedure_option; struct pdu_session_res_modify_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_modify_list_mod_ind; // sequence methods @@ -11555,16 +11045,7 @@ struct pdu_session_res_modify_ind_ies_container { }; // PDUSessionResourceModifyIndication ::= SEQUENCE -struct pdu_session_res_modify_ind_s { - bool ext = false; - pdu_session_res_modify_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pdu_session_res_modify_ind_s = elementary_procedure_option; struct pdu_session_res_modify_request_ies_container { template @@ -11572,8 +11053,8 @@ struct pdu_session_res_modify_request_ies_container { // member variables bool ran_paging_prio_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > ran_paging_prio; ie_field_s > pdu_session_res_modify_list_mod_req; @@ -11585,28 +11066,19 @@ struct pdu_session_res_modify_request_ies_container { }; // PDUSessionResourceModifyRequest ::= SEQUENCE -struct pdu_session_res_modify_request_s { - bool ext = false; - pdu_session_res_modify_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pdu_session_res_modify_request_s = elementary_procedure_option; struct pdu_session_res_modify_resp_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool pdu_session_res_modify_list_mod_res_present = false; - bool pdu_session_res_failed_to_modify_list_mod_res_present = false; - bool user_location_info_present = false; - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + bool pdu_session_res_modify_list_mod_res_present = false; + bool pdu_session_res_failed_to_modify_list_mod_res_present = false; + bool user_location_info_present = false; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_modify_list_mod_res; ie_field_s > pdu_session_res_failed_to_modify_list_mod_res; @@ -11621,27 +11093,18 @@ struct pdu_session_res_modify_resp_ies_container { }; // PDUSessionResourceModifyResponse ::= SEQUENCE -struct pdu_session_res_modify_resp_s { - bool ext = false; - pdu_session_res_modify_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pdu_session_res_modify_resp_s = elementary_procedure_option; struct pdu_session_res_notify_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool pdu_session_res_notify_list_present = false; - bool pdu_session_res_released_list_not_present = false; - bool user_location_info_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + bool pdu_session_res_notify_list_present = false; + bool pdu_session_res_released_list_not_present = false; + bool user_location_info_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_notify_list; ie_field_s > pdu_session_res_released_list_not; ie_field_s user_location_info; @@ -11654,28 +11117,19 @@ struct pdu_session_res_notify_ies_container { }; // PDUSessionResourceNotify ::= SEQUENCE -struct pdu_session_res_notify_s { - bool ext = false; - pdu_session_res_notify_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pdu_session_res_notify_s = elementary_procedure_option; struct pdu_session_res_release_cmd_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool ran_paging_prio_present = false; - bool nas_pdu_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > ran_paging_prio; - ie_field_s > nas_pdu; + bool ran_paging_prio_present = false; + bool nas_pdu_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > ran_paging_prio; + ie_field_s > nas_pdu; ie_field_s > pdu_session_res_to_release_list_rel_cmd; @@ -11687,16 +11141,7 @@ struct pdu_session_res_release_cmd_ies_container { }; // PDUSessionResourceReleaseCommand ::= SEQUENCE -struct pdu_session_res_release_cmd_s { - bool ext = false; - pdu_session_res_release_cmd_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pdu_session_res_release_cmd_s = elementary_procedure_option; struct pdu_session_res_release_resp_ies_container { template @@ -11705,8 +11150,8 @@ struct pdu_session_res_release_resp_ies_container { // member variables bool user_location_info_present = false; bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_released_list_rel_res; ie_field_s user_location_info; ie_field_s crit_diagnostics; @@ -11719,29 +11164,20 @@ struct pdu_session_res_release_resp_ies_container { }; // PDUSessionResourceReleaseResponse ::= SEQUENCE -struct pdu_session_res_release_resp_s { - bool ext = false; - pdu_session_res_release_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pdu_session_res_release_resp_s = elementary_procedure_option; struct pdu_session_res_setup_request_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool ran_paging_prio_present = false; - bool nas_pdu_present = false; - bool ue_aggregate_maximum_bit_rate_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > ran_paging_prio; - ie_field_s > nas_pdu; + bool ran_paging_prio_present = false; + bool nas_pdu_present = false; + bool ue_aggregate_maximum_bit_rate_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > ran_paging_prio; + ie_field_s > nas_pdu; ie_field_s > pdu_session_res_setup_list_su_req; ie_field_s ue_aggregate_maximum_bit_rate; @@ -11753,27 +11189,18 @@ struct pdu_session_res_setup_request_ies_container { }; // PDUSessionResourceSetupRequest ::= SEQUENCE -struct pdu_session_res_setup_request_s { - bool ext = false; - pdu_session_res_setup_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pdu_session_res_setup_request_s = elementary_procedure_option; struct pdu_session_res_setup_resp_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool pdu_session_res_setup_list_su_res_present = false; - bool pdu_session_res_failed_to_setup_list_su_res_present = false; - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + bool pdu_session_res_setup_list_su_res_present = false; + bool pdu_session_res_failed_to_setup_list_su_res_present = false; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_setup_list_su_res; ie_field_s > pdu_session_res_failed_to_setup_list_su_res; @@ -11787,16 +11214,7 @@ struct pdu_session_res_setup_resp_ies_container { }; // PDUSessionResourceSetupResponse ::= SEQUENCE -struct pdu_session_res_setup_resp_s { - bool ext = false; - pdu_session_res_setup_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pdu_session_res_setup_resp_s = elementary_procedure_option; struct pws_cancel_request_ies_container { template @@ -11818,16 +11236,7 @@ struct pws_cancel_request_ies_container { }; // PWSCancelRequest ::= SEQUENCE -struct pws_cancel_request_s { - bool ext = false; - pws_cancel_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pws_cancel_request_s = elementary_procedure_option; struct pws_cancel_resp_ies_container { template @@ -11849,16 +11258,7 @@ struct pws_cancel_resp_ies_container { }; // PWSCancelResponse ::= SEQUENCE -struct pws_cancel_resp_s { - bool ext = false; - pws_cancel_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pws_cancel_resp_s = elementary_procedure_option; struct pws_fail_ind_ies_container { template @@ -11876,16 +11276,7 @@ struct pws_fail_ind_ies_container { }; // PWSFailureIndication ::= SEQUENCE -struct pws_fail_ind_s { - bool ext = false; - pws_fail_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pws_fail_ind_s = elementary_procedure_option; struct pws_restart_ind_ies_container { template @@ -11906,16 +11297,7 @@ struct pws_restart_ind_ies_container { }; // PWSRestartIndication ::= SEQUENCE -struct pws_restart_ind_s { - bool ext = false; - pws_restart_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pws_restart_ind_s = elementary_procedure_option; struct paging_ies_container { template @@ -11943,24 +11325,15 @@ struct paging_ies_container { }; // Paging ::= SEQUENCE -struct paging_s { - bool ext = false; - paging_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using paging_s = elementary_procedure_option; struct path_switch_request_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool pdu_session_res_failed_to_setup_list_ps_req_present = false; - ie_field_s > ran_ue_ngap_id; + bool pdu_session_res_failed_to_setup_list_ps_req_present = false; + ie_field_s ran_ue_ngap_id; ie_field_s > source_amf_ue_ngap_id; ie_field_s user_location_info; ie_field_s ue_security_cap; @@ -11977,34 +11350,25 @@ struct path_switch_request_ies_container { }; // PathSwitchRequest ::= SEQUENCE -struct path_switch_request_s { - bool ext = false; - path_switch_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using path_switch_request_s = elementary_procedure_option; struct path_switch_request_ack_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool ue_security_cap_present = false; - bool new_security_context_ind_present = false; - bool pdu_session_res_released_list_ps_ack_present = false; - bool core_network_assist_info_present = false; - bool rrc_inactive_transition_report_request_present = false; - bool crit_diagnostics_present = false; - bool redirection_voice_fallback_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s ue_security_cap; - ie_field_s security_context; - ie_field_s new_security_context_ind; + bool ue_security_cap_present = false; + bool new_security_context_ind_present = false; + bool pdu_session_res_released_list_ps_ack_present = false; + bool core_network_assist_info_present = false; + bool rrc_inactive_transition_report_request_present = false; + bool crit_diagnostics_present = false; + bool redirection_voice_fallback_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s ue_security_cap; + ie_field_s security_context; + ie_field_s new_security_context_ind; ie_field_s > pdu_session_res_switched_list; ie_field_s > pdu_session_res_released_list_ps_ack; ie_field_s > allowed_nssai; @@ -12021,16 +11385,7 @@ struct path_switch_request_ack_ies_container { }; // PathSwitchRequestAcknowledge ::= SEQUENCE -struct path_switch_request_ack_s { - bool ext = false; - path_switch_request_ack_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using path_switch_request_ack_s = elementary_procedure_option; struct path_switch_request_fail_ies_container { template @@ -12038,8 +11393,8 @@ struct path_switch_request_fail_ies_container { // member variables bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_released_list_ps_fail; ie_field_s crit_diagnostics; @@ -12051,16 +11406,7 @@ struct path_switch_request_fail_ies_container { }; // PathSwitchRequestFailure ::= SEQUENCE -struct path_switch_request_fail_s { - bool ext = false; - path_switch_request_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using path_switch_request_fail_s = elementary_procedure_option; template struct private_ie_container_item_s { @@ -12120,28 +11466,10 @@ struct ran_cfg_upd_ies_container { }; // RANConfigurationUpdate ::= SEQUENCE -struct ran_cfg_upd_s { - bool ext = false; - ran_cfg_upd_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ran_cfg_upd_s = elementary_procedure_option; // RANConfigurationUpdateAcknowledge ::= SEQUENCE -struct ran_cfg_upd_ack_s { - bool ext = false; - protocol_ie_container_l protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ran_cfg_upd_ack_s = elementary_procedure_option >; struct ran_cfg_upd_fail_ies_container { template @@ -12162,26 +11490,17 @@ struct ran_cfg_upd_fail_ies_container { }; // RANConfigurationUpdateFailure ::= SEQUENCE -struct ran_cfg_upd_fail_s { - bool ext = false; - ran_cfg_upd_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ran_cfg_upd_fail_s = elementary_procedure_option; struct rrc_inactive_transition_report_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s rrc_state; - ie_field_s user_location_info; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s rrc_state; + ie_field_s user_location_info; // sequence methods rrc_inactive_transition_report_ies_container(); @@ -12191,29 +11510,20 @@ struct rrc_inactive_transition_report_ies_container { }; // RRCInactiveTransitionReport ::= SEQUENCE -struct rrc_inactive_transition_report_s { - bool ext = false; - rrc_inactive_transition_report_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using rrc_inactive_transition_report_s = elementary_procedure_option; struct reroute_nas_request_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool amf_ue_ngap_id_present = false; - bool allowed_nssai_present = false; - ie_field_s > ran_ue_ngap_id; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ngap_msg; - ie_field_s > amf_set_id; - ie_field_s > allowed_nssai; + bool amf_ue_ngap_id_present = false; + bool allowed_nssai_present = false; + ie_field_s ran_ue_ngap_id; + ie_field_s amf_ue_ngap_id; + ie_field_s > ngap_msg; + ie_field_s > amf_set_id; + ie_field_s > allowed_nssai; // sequence methods reroute_nas_request_ies_container(); @@ -12223,25 +11533,16 @@ struct reroute_nas_request_ies_container { }; // RerouteNASRequest ::= SEQUENCE -struct reroute_nas_request_s { - bool ext = false; - reroute_nas_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using reroute_nas_request_s = elementary_procedure_option; struct secondary_rat_data_usage_report_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool ho_flag_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + bool ho_flag_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_secondary_ratusage_list; ie_field_s ho_flag; @@ -12254,26 +11555,17 @@ struct secondary_rat_data_usage_report_ies_container { }; // SecondaryRATDataUsageReport ::= SEQUENCE -struct secondary_rat_data_usage_report_s { - bool ext = false; - secondary_rat_data_usage_report_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using secondary_rat_data_usage_report_s = elementary_procedure_option; struct trace_fail_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > ngran_trace_id; - ie_field_s cause; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > ngran_trace_id; + ie_field_s cause; // sequence methods trace_fail_ind_ies_container(); @@ -12283,25 +11575,16 @@ struct trace_fail_ind_ies_container { }; // TraceFailureIndication ::= SEQUENCE -struct trace_fail_ind_s { - bool ext = false; - trace_fail_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using trace_fail_ind_s = elementary_procedure_option; struct trace_start_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s trace_activation; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s trace_activation; // sequence methods trace_start_ies_container(); @@ -12311,27 +11594,18 @@ struct trace_start_ies_container { }; // TraceStart ::= SEQUENCE -struct trace_start_s { - bool ext = false; - trace_start_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using trace_start_s = elementary_procedure_option; struct ue_context_mod_fail_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s cause; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s cause; + ie_field_s crit_diagnostics; // sequence methods ue_context_mod_fail_ies_container(); @@ -12341,16 +11615,7 @@ struct ue_context_mod_fail_ies_container { }; // UEContextModificationFailure ::= SEQUENCE -struct ue_context_mod_fail_s { - bool ext = false; - ue_context_mod_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_mod_fail_s = elementary_procedure_option; struct ue_context_mod_request_ies_container { template @@ -12366,8 +11631,8 @@ struct ue_context_mod_request_ies_container { bool emergency_fallback_ind_present = false; bool new_amf_ue_ngap_id_present = false; bool rrc_inactive_transition_report_request_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > ran_paging_prio; ie_field_s > security_key; ie_field_s > idx_to_rfsp; @@ -12386,30 +11651,21 @@ struct ue_context_mod_request_ies_container { }; // UEContextModificationRequest ::= SEQUENCE -struct ue_context_mod_request_s { - bool ext = false; - ue_context_mod_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_mod_request_s = elementary_procedure_option; struct ue_context_mod_resp_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool rrc_state_present = false; - bool user_location_info_present = false; - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s rrc_state; - ie_field_s user_location_info; - ie_field_s crit_diagnostics; + bool rrc_state_present = false; + bool user_location_info_present = false; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s rrc_state; + ie_field_s user_location_info; + ie_field_s crit_diagnostics; // sequence methods ue_context_mod_resp_ies_container(); @@ -12419,16 +11675,7 @@ struct ue_context_mod_resp_ies_container { }; // UEContextModificationResponse ::= SEQUENCE -struct ue_context_mod_resp_s { - bool ext = false; - ue_context_mod_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_mod_resp_s = elementary_procedure_option; struct ue_context_release_cmd_ies_container { template @@ -12446,29 +11693,20 @@ struct ue_context_release_cmd_ies_container { }; // UEContextReleaseCommand ::= SEQUENCE -struct ue_context_release_cmd_s { - bool ext = false; - ue_context_release_cmd_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_release_cmd_s = elementary_procedure_option; struct ue_context_release_complete_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool user_location_info_present = false; - bool info_on_recommended_cells_and_ran_nodes_for_paging_present = false; - bool pdu_session_res_list_cxt_rel_cpl_present = false; - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s user_location_info; + bool user_location_info_present = false; + bool info_on_recommended_cells_and_ran_nodes_for_paging_present = false; + bool pdu_session_res_list_cxt_rel_cpl_present = false; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s user_location_info; ie_field_s info_on_recommended_cells_and_ran_nodes_for_paging; ie_field_s > pdu_session_res_list_cxt_rel_cpl; ie_field_s crit_diagnostics; @@ -12481,25 +11719,16 @@ struct ue_context_release_complete_ies_container { }; // UEContextReleaseComplete ::= SEQUENCE -struct ue_context_release_complete_s { - bool ext = false; - ue_context_release_complete_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_release_complete_s = elementary_procedure_option; struct ue_context_release_request_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool pdu_session_res_list_cxt_rel_req_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + bool pdu_session_res_list_cxt_rel_req_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; ie_field_s > pdu_session_res_list_cxt_rel_req; ie_field_s cause; @@ -12511,26 +11740,17 @@ struct ue_context_release_request_ies_container { }; // UEContextReleaseRequest ::= SEQUENCE -struct ue_context_release_request_s { - bool ext = false; - ue_context_release_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_release_request_s = elementary_procedure_option; struct ue_radio_cap_check_request_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool ue_radio_cap_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > ue_radio_cap; + bool ue_radio_cap_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > ue_radio_cap; // sequence methods ue_radio_cap_check_request_ies_container(); @@ -12540,27 +11760,18 @@ struct ue_radio_cap_check_request_ies_container { }; // UERadioCapabilityCheckRequest ::= SEQUENCE -struct ue_radio_cap_check_request_s { - bool ext = false; - ue_radio_cap_check_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_radio_cap_check_request_s = elementary_procedure_option; struct ue_radio_cap_check_resp_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s ims_voice_support_ind; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s ims_voice_support_ind; + ie_field_s crit_diagnostics; // sequence methods ue_radio_cap_check_resp_ies_container(); @@ -12570,27 +11781,18 @@ struct ue_radio_cap_check_resp_ies_container { }; // UERadioCapabilityCheckResponse ::= SEQUENCE -struct ue_radio_cap_check_resp_s { - bool ext = false; - ue_radio_cap_check_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_radio_cap_check_resp_s = elementary_procedure_option; struct ue_radio_cap_info_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool ue_radio_cap_for_paging_present = false; - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > ue_radio_cap; - ie_field_s ue_radio_cap_for_paging; + bool ue_radio_cap_for_paging_present = false; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > ue_radio_cap; + ie_field_s ue_radio_cap_for_paging; // sequence methods ue_radio_cap_info_ind_ies_container(); @@ -12600,24 +11802,15 @@ struct ue_radio_cap_info_ind_ies_container { }; // UERadioCapabilityInfoIndication ::= SEQUENCE -struct ue_radio_cap_info_ind_s { - bool ext = false; - ue_radio_cap_info_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_radio_cap_info_ind_s = elementary_procedure_option; struct uetnla_binding_release_request_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; // sequence methods uetnla_binding_release_request_ies_container(); @@ -12627,26 +11820,17 @@ struct uetnla_binding_release_request_ies_container { }; // UETNLABindingReleaseRequest ::= SEQUENCE -struct uetnla_binding_release_request_s { - bool ext = false; - uetnla_binding_release_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using uetnla_binding_release_request_s = elementary_procedure_option; struct ul_nas_transport_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > nas_pdu; - ie_field_s user_location_info; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > nas_pdu; + ie_field_s user_location_info; // sequence methods ul_nas_transport_ies_container(); @@ -12656,16 +11840,7 @@ struct ul_nas_transport_ies_container { }; // UplinkNASTransport ::= SEQUENCE -struct ul_nas_transport_s { - bool ext = false; - ul_nas_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ul_nas_transport_s = elementary_procedure_option; struct ul_non_ueassociated_nrp_pa_transport_ies_container { template @@ -12683,16 +11858,8 @@ struct ul_non_ueassociated_nrp_pa_transport_ies_container { }; // UplinkNonUEAssociatedNRPPaTransport ::= SEQUENCE -struct ul_non_ueassociated_nrp_pa_transport_s { - bool ext = false; - ul_non_ueassociated_nrp_pa_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ul_non_ueassociated_nrp_pa_transport_s = + elementary_procedure_option; struct ul_ran_cfg_transfer_ies_container { template @@ -12712,25 +11879,16 @@ struct ul_ran_cfg_transfer_ies_container { }; // UplinkRANConfigurationTransfer ::= SEQUENCE -struct ul_ran_cfg_transfer_s { - bool ext = false; - ul_ran_cfg_transfer_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ul_ran_cfg_transfer_s = elementary_procedure_option; struct ul_ran_status_transfer_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s ran_status_transfer_transparent_container; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s ran_status_transfer_transparent_container; // sequence methods ul_ran_status_transfer_ies_container(); @@ -12740,26 +11898,17 @@ struct ul_ran_status_transfer_ies_container { }; // UplinkRANStatusTransfer ::= SEQUENCE -struct ul_ran_status_transfer_s { - bool ext = false; - ul_ran_status_transfer_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ul_ran_status_transfer_s = elementary_procedure_option; struct ul_ueassociated_nrp_pa_transport_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > amf_ue_ngap_id; - ie_field_s > ran_ue_ngap_id; - ie_field_s > routing_id; - ie_field_s > nrp_pa_pdu; + ie_field_s amf_ue_ngap_id; + ie_field_s ran_ue_ngap_id; + ie_field_s > routing_id; + ie_field_s > nrp_pa_pdu; // sequence methods ul_ueassociated_nrp_pa_transport_ies_container(); @@ -12769,16 +11918,7 @@ struct ul_ueassociated_nrp_pa_transport_ies_container { }; // UplinkUEAssociatedNRPPaTransport ::= SEQUENCE -struct ul_ueassociated_nrp_pa_transport_s { - bool ext = false; - ul_ueassociated_nrp_pa_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ul_ueassociated_nrp_pa_transport_s = elementary_procedure_option; struct write_replace_warning_request_ies_container { template @@ -12812,16 +11952,7 @@ struct write_replace_warning_request_ies_container { }; // WriteReplaceWarningRequest ::= SEQUENCE -struct write_replace_warning_request_s { - bool ext = false; - write_replace_warning_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using write_replace_warning_request_s = elementary_procedure_option; struct write_replace_warning_resp_ies_container { template @@ -12843,16 +11974,7 @@ struct write_replace_warning_resp_ies_container { }; // WriteReplaceWarningResponse ::= SEQUENCE -struct write_replace_warning_resp_s { - bool ext = false; - write_replace_warning_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using write_replace_warning_resp_s = elementary_procedure_option; // NGAP-ELEMENTARY-PROCEDURES ::= OBJECT SET OF NGAP-ELEMENTARY-PROCEDURE struct ngap_elem_procs_o { @@ -13282,10 +12404,10 @@ struct init_msg_s { }; // LastVisitedNGRANCellInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using last_visited_ngran_cell_info_ext_ies_o = ngap_protocol_ext_empty_o; +using last_visited_ngran_cell_info_ext_ies_o = protocol_ext_empty_o; // LastVisitedCellInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using last_visited_cell_info_ext_ies_o = ngap_protocol_ies_empty_o; +using last_visited_cell_info_ext_ies_o = protocol_ies_empty_o; using last_visited_ngran_cell_info_ext_ies_container = protocol_ext_container_empty_l; @@ -13396,7 +12518,7 @@ struct last_visited_cell_info_c { }; // LastVisitedCellItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using last_visited_cell_item_ext_ies_o = ngap_protocol_ext_empty_o; +using last_visited_cell_item_ext_ies_o = protocol_ext_empty_o; using last_visited_cell_item_ext_ies_container = protocol_ext_container_empty_l; @@ -13500,7 +12622,7 @@ struct ngap_pdu_c { }; // NonDynamic5QIDescriptor-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using non_dynamic5_qi_descriptor_ext_ies_o = ngap_protocol_ext_empty_o; +using non_dynamic5_qi_descriptor_ext_ies_o = protocol_ext_empty_o; using non_dynamic5_qi_descriptor_ext_ies_container = protocol_ext_container_empty_l; @@ -13525,7 +12647,7 @@ struct non_dynamic5_qi_descriptor_s { }; // PDUSessionAggregateMaximumBitRate-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_aggregate_maximum_bit_rate_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_aggregate_maximum_bit_rate_ext_ies_o = protocol_ext_empty_o; using pdu_session_aggregate_maximum_bit_rate_ext_ies_container = protocol_ext_container_empty_l; @@ -13545,7 +12667,7 @@ struct pdu_session_aggregate_maximum_bit_rate_s { }; // QosFlowInformationItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_info_item_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_info_item_ext_ies_o = protocol_ext_empty_o; using qos_flow_info_item_ext_ies_container = protocol_ext_container_empty_l; @@ -13566,7 +12688,7 @@ struct qos_flow_info_item_s { }; // PDUSessionResourceInformationItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_info_item_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_info_item_ext_ies_o = protocol_ext_empty_o; // QosFlowInformationList ::= SEQUENCE (SIZE (1..64)) OF QosFlowInformationItem using qos_flow_info_list_l = dyn_array; @@ -13575,10 +12697,9 @@ using pdu_session_res_info_item_ext_ies_container = protocol_ext_container_empty // PDUSessionResourceInformationItem ::= SEQUENCE struct pdu_session_res_info_item_s { - bool ext = false; - bool drbs_to_qos_flows_map_list_present = false; - bool ie_exts_present = false; - uint16_t pdu_session_id = 0; + bool ext = false; + bool ie_exts_present = false; + uint16_t pdu_session_id = 0; qos_flow_info_list_l qos_flow_info_list; drbs_to_qos_flows_map_list_l drbs_to_qos_flows_map_list; pdu_session_res_info_item_ext_ies_container ie_exts; @@ -13594,10 +12715,10 @@ struct pdu_session_res_info_item_s { using pdu_session_res_info_list_l = dyn_array; // QosFlowModifyConfirmItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_modify_confirm_item_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_modify_confirm_item_ext_ies_o = protocol_ext_empty_o; // UPTransportLayerInformationPairItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using up_transport_layer_info_pair_item_ext_ies_o = ngap_protocol_ext_empty_o; +using up_transport_layer_info_pair_item_ext_ies_o = protocol_ext_empty_o; using qos_flow_modify_confirm_item_ext_ies_container = protocol_ext_container_empty_l; @@ -13633,7 +12754,7 @@ struct up_transport_layer_info_pair_item_s { }; // PDUSessionResourceModifyConfirmTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_modify_confirm_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_modify_confirm_transfer_ext_ies_o = protocol_ext_empty_o; // QosFlowModifyConfirmList ::= SEQUENCE (SIZE (1..64)) OF QosFlowModifyConfirmItem using qos_flow_modify_confirm_list_l = dyn_array; @@ -13645,10 +12766,8 @@ using pdu_session_res_modify_confirm_transfer_ext_ies_container = protocol_ext_c // PDUSessionResourceModifyConfirmTransfer ::= SEQUENCE struct pdu_session_res_modify_confirm_transfer_s { - bool ext = false; - bool add_ng_uuptnl_info_present = false; - bool qos_flow_failed_to_modify_list_present = false; - bool ie_exts_present = false; + bool ext = false; + bool ie_exts_present = false; qos_flow_modify_confirm_list_l qos_flow_modify_confirm_list; up_transport_layer_info_c ulngu_up_tnl_info; up_transport_layer_info_pair_list_l add_ng_uuptnl_info; @@ -13663,7 +12782,7 @@ struct pdu_session_res_modify_confirm_transfer_s { }; // VolumeTimedReport-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using volume_timed_report_item_ext_ies_o = ngap_protocol_ext_empty_o; +using volume_timed_report_item_ext_ies_o = protocol_ext_empty_o; using volume_timed_report_item_ext_ies_container = protocol_ext_container_empty_l; @@ -13685,13 +12804,13 @@ struct volume_timed_report_item_s { }; // QoSFlowsUsageReport-Item-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qo_sflows_usage_report_item_ext_ies_o = ngap_protocol_ext_empty_o; +using qo_sflows_usage_report_item_ext_ies_o = protocol_ext_empty_o; // VolumeTimedReportList ::= SEQUENCE (SIZE (1..2)) OF VolumeTimedReport-Item using volume_timed_report_list_l = dyn_array; // PDUSessionUsageReport-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_usage_report_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_usage_report_ext_ies_o = protocol_ext_empty_o; using qo_sflows_usage_report_item_ext_ies_container = protocol_ext_container_empty_l; @@ -13748,16 +12867,15 @@ struct pdu_session_usage_report_s { using qo_sflows_usage_report_list_l = dyn_array; // SecondaryRATUsageInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using secondary_ratusage_info_ext_ies_o = ngap_protocol_ext_empty_o; +using secondary_ratusage_info_ext_ies_o = protocol_ext_empty_o; using secondary_ratusage_info_ext_ies_container = protocol_ext_container_empty_l; // SecondaryRATUsageInformation ::= SEQUENCE struct secondary_ratusage_info_s { - bool ext = false; - bool pdu_session_usage_report_present = false; - bool qos_flows_usage_report_list_present = false; - bool ie_ext_present = false; + bool ext = false; + bool pdu_session_usage_report_present = false; + bool ie_ext_present = false; pdu_session_usage_report_s pdu_session_usage_report; qo_sflows_usage_report_list_l qos_flows_usage_report_list; secondary_ratusage_info_ext_ies_container ie_ext; @@ -13830,9 +12948,8 @@ struct pdu_session_res_modify_ind_transfer_ext_ies_container { // PDUSessionResourceModifyIndicationTransfer ::= SEQUENCE struct pdu_session_res_modify_ind_transfer_s { - bool ext = false; - bool add_dl_qos_flow_per_tnl_info_present = false; - bool ie_exts_present = false; + bool ext = false; + bool ie_exts_present = false; qos_flow_per_tnl_info_s dlqos_flow_per_tnl_info; qos_flow_per_tnl_info_list_l add_dl_qos_flow_per_tnl_info; pdu_session_res_modify_ind_transfer_ext_ies_container ie_exts; @@ -13845,7 +12962,7 @@ struct pdu_session_res_modify_ind_transfer_s { }; // PDUSessionResourceModifyIndicationUnsuccessfulTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_modify_ind_unsuccessful_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_modify_ind_unsuccessful_transfer_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_modify_ind_unsuccessful_transfer_ext_ies_container = protocol_ext_container_empty_l; @@ -13864,7 +12981,7 @@ struct pdu_session_res_modify_ind_unsuccessful_transfer_s { }; // QosCharacteristics-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES -using qos_characteristics_ext_ies_o = ngap_protocol_ies_empty_o; +using qos_characteristics_ext_ies_o = protocol_ies_empty_o; // AdditionalQosFlowInformation ::= ENUMERATED struct add_qos_flow_info_opts { @@ -13939,7 +13056,7 @@ struct qos_characteristics_c { }; // QosFlowLevelQosParameters-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_level_qos_params_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_level_qos_params_ext_ies_o = protocol_ext_empty_o; // ReflectiveQosAttribute ::= ENUMERATED struct reflective_qos_attribute_opts { @@ -13950,7 +13067,7 @@ struct reflective_qos_attribute_opts { typedef enumerated reflective_qos_attribute_e; // QosFlowAddOrModifyRequestItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_add_or_modify_request_item_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_add_or_modify_request_item_ext_ies_o = protocol_ext_empty_o; using qos_flow_level_qos_params_ext_ies_container = protocol_ext_container_empty_l; @@ -13976,10 +13093,10 @@ struct qos_flow_level_qos_params_s { }; // UL-NGU-UP-TNLModifyItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using ul_ngu_up_tnl_modify_item_ext_ies_o = ngap_protocol_ext_empty_o; +using ul_ngu_up_tnl_modify_item_ext_ies_o = protocol_ext_empty_o; // UPTransportLayerInformationItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using up_transport_layer_info_item_ext_ies_o = ngap_protocol_ext_empty_o; +using up_transport_layer_info_item_ext_ies_o = protocol_ext_empty_o; using qos_flow_add_or_modify_request_item_ext_ies_container = protocol_ext_container_empty_l; @@ -14134,19 +13251,11 @@ struct pdu_session_res_modify_request_transfer_ies_container { }; // PDUSessionResourceModifyRequestTransfer ::= SEQUENCE -struct pdu_session_res_modify_request_transfer_s { - bool ext = false; - pdu_session_res_modify_request_transfer_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pdu_session_res_modify_request_transfer_s = + elementary_procedure_option; // QosFlowAddOrModifyResponseItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_add_or_modify_resp_item_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_add_or_modify_resp_item_ext_ies_o = protocol_ext_empty_o; using qos_flow_add_or_modify_resp_item_ext_ies_container = protocol_ext_container_empty_l; @@ -14201,18 +13310,14 @@ using qos_flow_add_or_modify_resp_list_l = dyn_array ie_exts; // ... @@ -14223,7 +13328,7 @@ struct pdu_session_res_modify_resp_transfer_s { }; // PDUSessionResourceModifyUnsuccessfulTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_modify_unsuccessful_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_modify_unsuccessful_transfer_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_modify_unsuccessful_transfer_ext_ies_container = protocol_ext_container_empty_l; @@ -14277,8 +13382,7 @@ struct pdu_session_res_notify_released_transfer_ext_ies_o { // PDUSessionResourceNotifyReleasedTransfer ::= SEQUENCE struct pdu_session_res_notify_released_transfer_s { - bool ext = false; - bool ie_exts_present = false; + bool ext = false; cause_c cause; protocol_ext_container_l ie_exts; // ... @@ -14298,7 +13402,7 @@ struct notif_cause_opts { typedef enumerated notif_cause_e; // QosFlowNotifyItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_notify_item_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_notify_item_ext_ies_o = protocol_ext_empty_o; using qos_flow_notify_item_ext_ies_container = protocol_ext_container_empty_l; @@ -14354,10 +13458,7 @@ using qos_flow_notify_list_l = dyn_array; // PDUSessionResourceNotifyTransfer ::= SEQUENCE struct pdu_session_res_notify_transfer_s { - bool ext = false; - bool qos_flow_notify_list_present = false; - bool qos_flow_released_list_present = false; - bool ie_exts_present = false; + bool ext = false; qos_flow_notify_list_l qos_flow_notify_list; qos_flow_list_with_cause_l qos_flow_released_list; protocol_ext_container_l ie_exts; @@ -14370,7 +13471,7 @@ struct pdu_session_res_notify_transfer_s { }; // PDUSessionResourceReleaseCommandTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_release_cmd_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_release_cmd_transfer_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_release_cmd_transfer_ext_ies_container = protocol_ext_container_empty_l; @@ -14422,8 +13523,7 @@ struct pdu_session_res_release_resp_transfer_ext_ies_o { // PDUSessionResourceReleaseResponseTransfer ::= SEQUENCE struct pdu_session_res_release_resp_transfer_s { - bool ext = false; - bool ie_exts_present = false; + bool ext = false; protocol_ext_container_l ie_exts; // ... @@ -14444,7 +13544,7 @@ struct maximum_integrity_protected_data_rate_opts { typedef enumerated maximum_integrity_protected_data_rate_e; // QosFlowSetupRequestItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_setup_request_item_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_setup_request_item_ext_ies_o = protocol_ext_empty_o; // ConfidentialityProtectionIndication ::= ENUMERATED struct confidentiality_protection_ind_opts { @@ -14536,7 +13636,6 @@ using qos_flow_setup_request_list_l = dyn_array; struct security_ind_s { bool ext = false; bool maximum_integrity_protected_data_rate_ul_present = false; - bool ie_exts_present = false; integrity_protection_ind_e integrity_protection_ind; confidentiality_protection_ind_e confidentiality_protection_ind; maximum_integrity_protected_data_rate_e maximum_integrity_protected_data_rate_ul; @@ -14647,29 +13746,19 @@ struct pdu_session_res_setup_request_transfer_ies_container { }; // PDUSessionResourceSetupRequestTransfer ::= SEQUENCE -struct pdu_session_res_setup_request_transfer_s { - bool ext = false; - pdu_session_res_setup_request_transfer_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pdu_session_res_setup_request_transfer_s = + elementary_procedure_option; // PDUSessionResourceSetupResponseTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_setup_resp_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_setup_resp_transfer_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_setup_resp_transfer_ext_ies_container = protocol_ext_container_empty_l; // PDUSessionResourceSetupResponseTransfer ::= SEQUENCE struct pdu_session_res_setup_resp_transfer_s { - bool ext = false; - bool add_dl_qos_flow_per_tnl_info_present = false; - bool security_result_present = false; - bool qos_flow_failed_to_setup_list_present = false; - bool ie_exts_present = false; + bool ext = false; + bool security_result_present = false; + bool ie_exts_present = false; qos_flow_per_tnl_info_s dlqos_flow_per_tnl_info; qos_flow_per_tnl_info_list_l add_dl_qos_flow_per_tnl_info; security_result_s security_result; @@ -14684,7 +13773,7 @@ struct pdu_session_res_setup_resp_transfer_s { }; // PDUSessionResourceSetupUnsuccessfulTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using pdu_session_res_setup_unsuccessful_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using pdu_session_res_setup_unsuccessful_transfer_ext_ies_o = protocol_ext_empty_o; using pdu_session_res_setup_unsuccessful_transfer_ext_ies_container = protocol_ext_container_empty_l; @@ -14741,7 +13830,6 @@ struct path_switch_request_ack_transfer_s { bool ext = false; bool ul_ngu_up_tnl_info_present = false; bool security_ind_present = false; - bool ie_exts_present = false; up_transport_layer_info_c ul_ngu_up_tnl_info; security_ind_s security_ind; protocol_ext_container_l ie_exts; @@ -14754,7 +13842,7 @@ struct path_switch_request_ack_transfer_s { }; // PathSwitchRequestSetupFailedTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using path_switch_request_setup_failed_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using path_switch_request_setup_failed_transfer_ext_ies_o = protocol_ext_empty_o; using path_switch_request_setup_failed_transfer_ext_ies_container = protocol_ext_container_empty_l; @@ -14773,7 +13861,7 @@ struct path_switch_request_setup_failed_transfer_s { }; // QosFlowAcceptedItem-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_accepted_item_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_accepted_item_ext_ies_o = protocol_ext_empty_o; using qos_flow_accepted_item_ext_ies_container = protocol_ext_container_empty_l; @@ -14792,7 +13880,7 @@ struct qos_flow_accepted_item_s { }; // UserPlaneSecurityInformation-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using user_plane_security_info_ext_ies_o = ngap_protocol_ext_empty_o; +using user_plane_security_info_ext_ies_o = protocol_ext_empty_o; // DL-NGU-TNLInformationReused ::= ENUMERATED struct dl_ngu_tnl_info_reused_opts { @@ -14859,7 +13947,6 @@ struct path_switch_request_transfer_s { bool ext = false; bool dl_ngu_tnl_info_reused_present = false; bool user_plane_security_info_present = false; - bool ie_exts_present = false; up_transport_layer_info_c dl_ngu_up_tnl_info; dl_ngu_tnl_info_reused_e dl_ngu_tnl_info_reused; user_plane_security_info_s user_plane_security_info; @@ -14874,7 +13961,7 @@ struct path_switch_request_transfer_s { }; // PathSwitchRequestUnsuccessfulTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using path_switch_request_unsuccessful_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using path_switch_request_unsuccessful_transfer_ext_ies_o = protocol_ext_empty_o; using path_switch_request_unsuccessful_transfer_ext_ies_container = protocol_ext_container_empty_l; @@ -14912,7 +13999,7 @@ template using protocol_ie_container_pair_l = dyn_seq_of, 0, 65535, true>; // QosFlowSetupResponseItemSURes-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using qos_flow_setup_resp_item_su_res_ext_ies_o = ngap_protocol_ext_empty_o; +using qos_flow_setup_resp_item_su_res_ext_ies_o = protocol_ext_empty_o; using qos_flow_setup_resp_item_su_res_ext_ies_container = protocol_ext_container_empty_l; @@ -14934,7 +14021,7 @@ struct qos_flow_setup_resp_item_su_res_s { using qos_flow_setup_resp_list_su_res_l = dyn_array; // SecondaryRATDataUsageReportTransfer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using secondary_rat_data_usage_report_transfer_ext_ies_o = ngap_protocol_ext_empty_o; +using secondary_rat_data_usage_report_transfer_ext_ies_o = protocol_ext_empty_o; using secondary_rat_data_usage_report_transfer_ext_ies_container = protocol_ext_container_empty_l; @@ -14954,7 +14041,7 @@ struct secondary_rat_data_usage_report_transfer_s { }; // SourceNGRANNode-ToTargetNGRANNode-TransparentContainer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using source_ngran_node_to_target_ngran_node_transparent_container_ext_ies_o = ngap_protocol_ext_empty_o; +using source_ngran_node_to_target_ngran_node_transparent_container_ext_ies_o = protocol_ext_empty_o; // UEHistoryInformation ::= SEQUENCE (SIZE (1..16)) OF LastVisitedCellItem using ue_history_info_l = dyn_array; @@ -14963,17 +14050,15 @@ using source_ngran_node_to_target_ngran_node_transparent_container_ext_ies_conta // SourceNGRANNode-ToTargetNGRANNode-TransparentContainer ::= SEQUENCE struct source_ngran_node_to_target_ngran_node_transparent_container_s { - bool ext = false; - bool pdu_session_res_info_list_present = false; - bool erab_info_list_present = false; - bool idx_to_rfsp_present = false; - bool ie_exts_present = false; - unbounded_octstring rrc_container; - pdu_session_res_info_list_l pdu_session_res_info_list; - erab_info_list_l erab_info_list; - ngran_cgi_c target_cell_id; - uint16_t idx_to_rfsp = 1; - ue_history_info_l uehistory_info; + bool ext = false; + bool idx_to_rfsp_present = false; + bool ie_exts_present = false; + unbounded_octstring rrc_container; + pdu_session_res_info_list_l pdu_session_res_info_list; + erab_info_list_l erab_info_list; + ngran_cgi_c target_cell_id; + uint16_t idx_to_rfsp = 1; + ue_history_info_l uehistory_info; source_ngran_node_to_target_ngran_node_transparent_container_ext_ies_container ie_exts; // ... @@ -14984,7 +14069,7 @@ struct source_ngran_node_to_target_ngran_node_transparent_container_s { }; // TargetNGRANNode-ToSourceNGRANNode-TransparentContainer-ExtIEs ::= OBJECT SET OF NGAP-PROTOCOL-EXTENSION -using target_ngran_node_to_source_ngran_node_transparent_container_ext_ies_o = ngap_protocol_ext_empty_o; +using target_ngran_node_to_source_ngran_node_transparent_container_ext_ies_o = protocol_ext_empty_o; using target_ngran_node_to_source_ngran_node_transparent_container_ext_ies_container = protocol_ext_container_empty_l; @@ -15002,7 +14087,86 @@ struct target_ngran_node_to_source_ngran_node_transparent_container_s { void to_json(json_writer& j) const; }; -} // namespace ngap_nr +} // namespace ngap } // namespace asn1 -#endif // SRSASN1_NGAP_NR_H +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; + +#endif // SRSASN1_NGAP_H diff --git a/lib/include/srsran/asn1/ngap_utils.h b/lib/include/srsran/asn1/ngap_utils.h index 57540f09a5..5f19230ed8 100644 --- a/lib/include/srsran/asn1/ngap_utils.h +++ b/lib/include/srsran/asn1/ngap_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,7 +29,7 @@ ***********************/ namespace asn1 { -namespace ngap_nr { +namespace ngap { struct rrcestablishment_cause_opts; struct cause_radio_network_opts; using rrcestablishment_cause_e = enumerated; diff --git a/lib/include/srsran/rrc/rrc_cfg_utils.h b/lib/include/srsran/asn1/obj_id_cmp_utils.h similarity index 77% rename from lib/include/srsran/rrc/rrc_cfg_utils.h rename to lib/include/srsran/asn1/obj_id_cmp_utils.h index 69faa51919..aa58260f79 100644 --- a/lib/include/srsran/rrc/rrc_cfg_utils.h +++ b/lib/include/srsran/asn1/obj_id_cmp_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,18 +19,37 @@ * */ -#ifndef SRSRAN_RRC_CFG_UTILS_H -#define SRSRAN_RRC_CFG_UTILS_H +#ifndef SRSRAN_OBJ_ID_CMP_UTILS_H +#define SRSRAN_OBJ_ID_CMP_UTILS_H -#include "srsran/asn1/rrc_utils.h" #include "srsran/common/common.h" #include #include namespace srsran { -template -using rrc_obj_id_t = decltype(asn1::rrc::get_rrc_obj_id(std::declval())); +using asn1_obj_id_t = uint8_t; + +/// Template function to generically obtain id of asn1 object (e.g. srb_id of srbs, drb_id of drbs, etc.) +template +uint8_t get_asn1_obj_id(const Asn1Obj& obj); + +/// Template function to generically set id of asn1 object (e.g. srb_id of srbs, drb_id of drbs, etc.) +template +void set_asn1_obj_id(Asn1Obj& obj, uint8_t id); + +/// helper macro to help define get_asn1_obj_id and set_asn1_obj_id for specific asn1 objects +#define ASN1_OBJ_ID_DEFINE(Asn1ObjType, member) \ + template <> \ + uint8_t get_asn1_obj_id(const Asn1ObjType& obj) \ + { \ + return obj.member; \ + } \ + template <> \ + void set_asn1_obj_id(Asn1ObjType & obj, uint8_t id) \ + { \ + obj.member = id; \ + } //! Functor to compare RRC config elements (e.g. SRB/measObj/Rep) based on ID struct rrc_obj_id_cmp { @@ -38,27 +57,27 @@ struct rrc_obj_id_cmp { typename std::enable_if::value and not std::is_integral::value, bool>::type operator()(const T& lhs, const U& rhs) const { - return asn1::rrc::get_rrc_obj_id(lhs) < asn1::rrc::get_rrc_obj_id(rhs); + return get_asn1_obj_id(lhs) < get_asn1_obj_id(rhs); } template - bool operator()(const T& lhs, rrc_obj_id_t id) const + bool operator()(const T& lhs, asn1_obj_id_t id) const { - return asn1::rrc::get_rrc_obj_id(lhs) < id; + return get_asn1_obj_id(lhs) < id; } template - bool operator()(rrc_obj_id_t id, const T& rhs) const + bool operator()(asn1_obj_id_t id, const T& rhs) const { - return id < asn1::rrc::get_rrc_obj_id(rhs); + return id < get_asn1_obj_id(rhs); } }; template struct unary_rrc_obj_id { - rrc_obj_id_t id; + asn1_obj_id_t id; template explicit unary_rrc_obj_id(T id_) : id(id_) {} - bool operator()(const typename Container::value_type& e) const { return asn1::rrc::get_rrc_obj_id(e) == id; } + bool operator()(const typename Container::value_type& e) const { return get_asn1_obj_id(e) == id; } }; /// Find rrc object in list based on ID @@ -78,13 +97,13 @@ template typename Container::iterator sorted_find_rrc_obj_id(Container& c, IdType id) { auto it = std::lower_bound(c.begin(), c.end(), id, rrc_obj_id_cmp{}); - return (it == c.end() or asn1::rrc::get_rrc_obj_id(*it) != id) ? c.end() : it; + return (it == c.end() or get_asn1_obj_id(*it) != id) ? c.end() : it; } template typename Container::const_iterator sorted_find_rrc_obj_id(const Container& c, IdType id) { auto it = std::lower_bound(c.begin(), c.end(), id, rrc_obj_id_cmp{}); - return (it == c.end() or asn1::rrc::get_rrc_obj_id(*it) != id) ? c.end() : it; + return (it == c.end() or get_asn1_obj_id(*it) != id) ? c.end() : it; } template @@ -95,7 +114,7 @@ bool equal_rrc_obj_ids(const Container& c, const Container2& c2) c2.begin(), c2.end(), [](const typename Container::value_type& e, const typename Container2::value_type& e2) { - return asn1::rrc::get_rrc_obj_id(e) == asn1::rrc::get_rrc_obj_id(e2); + return get_asn1_obj_id(e) == get_asn1_obj_id(e2); }); } @@ -107,7 +126,7 @@ typename Container::iterator add_rrc_obj_id(Container& c, IdType id) if (it == c.end()) { c.push_back({}); it = c.end() - 1; - asn1::rrc::set_rrc_obj_id(*it, id); + set_asn1_obj_id(*it, id); std::sort(c.begin(), c.end(), rrc_obj_id_cmp{}); it = sorted_find_rrc_obj_id(c, id); } @@ -117,11 +136,11 @@ typename Container::iterator add_rrc_obj_id(Container& c, IdType id) template typename Container::iterator add_rrc_obj(Container& c, const typename Container::value_type& v) { - auto it = sorted_find_rrc_obj_id(c, asn1::rrc::get_rrc_obj_id(v)); + auto it = sorted_find_rrc_obj_id(c, get_asn1_obj_id(v)); if (it == c.end()) { c.push_back(v); std::sort(c.begin(), c.end(), rrc_obj_id_cmp{}); - it = sorted_find_rrc_obj_id(c, asn1::rrc::get_rrc_obj_id(v)); + it = sorted_find_rrc_obj_id(c, get_asn1_obj_id(v)); } else { *it = v; } @@ -145,21 +164,21 @@ bool rem_rrc_obj_id(Container& c, IdType id) * @return id value */ template -auto find_rrc_obj_id_gap(const Container& c) -> decltype(asn1::rrc::get_rrc_obj_id(c[0])) +auto find_rrc_obj_id_gap(const Container& c) -> decltype(get_asn1_obj_id(c[0])) { auto id_cmp_op = rrc_obj_id_cmp{}; assert(std::is_sorted(c.begin(), c.end(), id_cmp_op)); auto prev_it = c.begin(); - if (prev_it != c.end() and asn1::rrc::get_rrc_obj_id(*prev_it) == 1) { + if (prev_it != c.end() and get_asn1_obj_id(*prev_it) == 1) { auto it = prev_it; for (++it; it != c.end(); prev_it = it, ++it) { - if (asn1::rrc::get_rrc_obj_id(*it) > asn1::rrc::get_rrc_obj_id(*prev_it) + 1) { + if (get_asn1_obj_id(*it) > get_asn1_obj_id(*prev_it) + 1) { break; } } } - return (prev_it == c.end()) ? 1 : asn1::rrc::get_rrc_obj_id(*prev_it) + 1; // starts at 1. + return (prev_it == c.end()) ? 1 : get_asn1_obj_id(*prev_it) + 1; // starts at 1. } /** @@ -316,7 +335,7 @@ void compute_cfg_diff(const toAddModList& src_list, } using it_t = typename toAddModList::const_iterator; - auto rem_func = [&rem_diff_list](it_t rem_it) { rem_diff_list.push_back(asn1::rrc::get_rrc_obj_id(*rem_it)); }; + auto rem_func = [&rem_diff_list](it_t rem_it) { rem_diff_list.push_back(get_asn1_obj_id(*rem_it)); }; auto add_func = [&add_diff_list](it_t add_it) { add_diff_list.push_back(*add_it); }; auto mod_func = [&add_diff_list](it_t src_it, it_t target_it) { if (not(*src_it == *target_it)) { @@ -328,4 +347,4 @@ void compute_cfg_diff(const toAddModList& src_list, } // namespace srsran -#endif // SRSRAN_RRC_CFG_UTILS_H +#endif // SRSRAN_OBJ_ID_CMP_UTILS_H diff --git a/lib/include/srsran/asn1/rrc.h b/lib/include/srsran/asn1/rrc.h index 9f6b8ca49e..d14c356657 100644 --- a/lib/include/srsran/asn1/rrc.h +++ b/lib/include/srsran/asn1/rrc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -55,8 +55,9 @@ struct mib_mbms_r14_s { // member variables dl_bw_mbms_r14_e_ dl_bw_mbms_r14; fixed_bitstring<6> sys_frame_num_r14; - uint8_t add_non_mbsfn_sfs_r14 = 0; - fixed_bitstring<13> spare; + uint8_t add_non_mbsfn_sfs_r14 = 0; + uint8_t semi_static_cfi_mbms_r16 = 0; + fixed_bitstring<11> spare; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -195,6 +196,71 @@ struct mbms_session_info_r9_s { void to_json(json_writer& j) const; }; +// MBSFN-SubframeConfig-v1610 ::= SEQUENCE +struct mbsfn_sf_cfg_v1610_s { + struct sf_alloc_v1610_c_ { + struct types_opts { + enum options { one_frame_v1610, four_frames_v1610, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + sf_alloc_v1610_c_() = default; + sf_alloc_v1610_c_(const sf_alloc_v1610_c_& other); + sf_alloc_v1610_c_& operator=(const sf_alloc_v1610_c_& other); + ~sf_alloc_v1610_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<2>& one_frame_v1610() + { + assert_choice_type(types::one_frame_v1610, type_, "subframeAllocation-v1610"); + return c.get >(); + } + fixed_bitstring<8>& four_frames_v1610() + { + assert_choice_type(types::four_frames_v1610, type_, "subframeAllocation-v1610"); + return c.get >(); + } + const fixed_bitstring<2>& one_frame_v1610() const + { + assert_choice_type(types::one_frame_v1610, type_, "subframeAllocation-v1610"); + return c.get >(); + } + const fixed_bitstring<8>& four_frames_v1610() const + { + assert_choice_type(types::four_frames_v1610, type_, "subframeAllocation-v1610"); + return c.get >(); + } + fixed_bitstring<2>& set_one_frame_v1610(); + fixed_bitstring<8>& set_four_frames_v1610(); + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + + // member variables + sf_alloc_v1610_c_ sf_alloc_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CommonSF-AllocPatternList-v1610 ::= SEQUENCE (SIZE (1..8)) OF MBSFN-SubframeConfig-v1610 +using common_sf_alloc_pattern_list_v1610_l = dyn_array; + // MBMS-SessionInfoList-r9 ::= SEQUENCE (SIZE (0..29)) OF MBMS-SessionInfo-r9 using mbms_session_info_list_r9_l = dyn_array; @@ -281,8 +347,20 @@ struct pmch_cfg_r12_s { void to_json(json_writer& j) const; }; -// CommonSF-AllocPatternList-r14 ::= SEQUENCE (SIZE (1..8)) OF MBSFN-SubframeConfig-v1430 -using common_sf_alloc_pattern_list_r14_l = dyn_array; +// CommonSF-AllocPatternList-v1430 ::= SEQUENCE (SIZE (1..8)) OF MBSFN-SubframeConfig-v1430 +using common_sf_alloc_pattern_list_v1430_l = dyn_array; + +// MBSFNAreaConfiguration-v1610-IEs ::= SEQUENCE +struct mbsfn_area_cfg_v1610_ies_s { + bool common_sf_alloc_v1610_present = false; + bool non_crit_ext_present = false; + common_sf_alloc_pattern_list_v1610_l common_sf_alloc_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; // PMCH-InfoExt-r12 ::= SEQUENCE struct pmch_info_ext_r12_s { @@ -299,8 +377,9 @@ struct pmch_info_ext_r12_s { // MBSFNAreaConfiguration-v1430-IEs ::= SEQUENCE struct mbsfn_area_cfg_v1430_ies_s { - bool non_crit_ext_present = false; - common_sf_alloc_pattern_list_r14_l common_sf_alloc_r14; + bool non_crit_ext_present = false; + common_sf_alloc_pattern_list_v1430_l common_sf_alloc_v1430; + mbsfn_area_cfg_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -853,6 +932,157 @@ struct sc_mtch_sched_info_br_r14_s { void to_json(json_writer& j) const; }; +// SC-MTCH-Info-BR-r14 ::= SEQUENCE +struct sc_mtch_info_br_r14_s { + struct mpdcch_num_repeat_sc_mtch_r14_opts { + enum options { r1, r2, r4, r8, r16, r32, r64, r128, r256, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated mpdcch_num_repeat_sc_mtch_r14_e_; + struct mpdcch_start_sf_sc_mtch_r14_c_ { + struct fdd_r14_opts { + enum options { v1, v1dot5, v2, v2dot5, v4, v5, v8, v10, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated fdd_r14_e_; + struct tdd_r14_opts { + enum options { v1, v2, v4, v5, v8, v10, v20, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated tdd_r14_e_; + struct types_opts { + enum options { fdd_r14, tdd_r14, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + mpdcch_start_sf_sc_mtch_r14_c_() = default; + mpdcch_start_sf_sc_mtch_r14_c_(const mpdcch_start_sf_sc_mtch_r14_c_& other); + mpdcch_start_sf_sc_mtch_r14_c_& operator=(const mpdcch_start_sf_sc_mtch_r14_c_& other); + ~mpdcch_start_sf_sc_mtch_r14_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fdd_r14_e_& fdd_r14() + { + assert_choice_type(types::fdd_r14, type_, "mpdcch-StartSF-SC-MTCH-r14"); + return c.get(); + } + tdd_r14_e_& tdd_r14() + { + assert_choice_type(types::tdd_r14, type_, "mpdcch-StartSF-SC-MTCH-r14"); + return c.get(); + } + const fdd_r14_e_& fdd_r14() const + { + assert_choice_type(types::fdd_r14, type_, "mpdcch-StartSF-SC-MTCH-r14"); + return c.get(); + } + const tdd_r14_e_& tdd_r14() const + { + assert_choice_type(types::tdd_r14, type_, "mpdcch-StartSF-SC-MTCH-r14"); + return c.get(); + } + fdd_r14_e_& set_fdd_r14(); + tdd_r14_e_& set_tdd_r14(); + + private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); + }; + struct mpdcch_pdsch_hop_cfg_sc_mtch_r14_opts { + enum options { on, off, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated mpdcch_pdsch_hop_cfg_sc_mtch_r14_e_; + struct mpdcch_pdsch_cemode_cfg_sc_mtch_r14_opts { + enum options { ce_mode_a, ce_mode_b, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated mpdcch_pdsch_cemode_cfg_sc_mtch_r14_e_; + struct mpdcch_pdsch_max_bw_sc_mtch_r14_opts { + enum options { bw1dot4, bw5, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated mpdcch_pdsch_max_bw_sc_mtch_r14_e_; + struct mpdcch_offset_sc_mtch_r14_opts { + enum options { + zero, + one_eighth, + one_quarter, + three_eighth, + one_half, + five_eighth, + three_quarter, + seven_eighth, + nulltype + } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated mpdcch_offset_sc_mtch_r14_e_; + struct p_a_r14_opts { + enum options { db_minus6, db_minus4dot77, db_minus3, db_minus1dot77, db0, db1, db2, db3, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated p_a_r14_e_; + + // member variables + bool ext = false; + bool sc_mtch_sched_info_r14_present = false; + bool sc_mtch_neighbour_cell_r14_present = false; + bool p_a_r14_present = false; + uint32_t sc_mtch_carrier_freq_r14 = 0; + mbms_session_info_r13_s mbms_session_info_r14; + fixed_bitstring<16> g_rnti_r14; + sc_mtch_sched_info_br_r14_s sc_mtch_sched_info_r14; + fixed_bitstring<8> sc_mtch_neighbour_cell_r14; + uint8_t mpdcch_nb_sc_mtch_r14 = 1; + mpdcch_num_repeat_sc_mtch_r14_e_ mpdcch_num_repeat_sc_mtch_r14; + mpdcch_start_sf_sc_mtch_r14_c_ mpdcch_start_sf_sc_mtch_r14; + mpdcch_pdsch_hop_cfg_sc_mtch_r14_e_ mpdcch_pdsch_hop_cfg_sc_mtch_r14; + mpdcch_pdsch_cemode_cfg_sc_mtch_r14_e_ mpdcch_pdsch_cemode_cfg_sc_mtch_r14; + mpdcch_pdsch_max_bw_sc_mtch_r14_e_ mpdcch_pdsch_max_bw_sc_mtch_r14; + mpdcch_offset_sc_mtch_r14_e_ mpdcch_offset_sc_mtch_r14; + p_a_r14_e_ p_a_r14; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SC-MTCH-SchedulingInfo-r13 ::= SEQUENCE struct sc_mtch_sched_info_r13_s { struct on_dur_timer_scptm_r13_opts { @@ -1155,157 +1385,6 @@ struct pci_arfcn_r13_s { void to_json(json_writer& j) const; }; -// SC-MTCH-Info-BR-r14 ::= SEQUENCE -struct sc_mtch_info_br_r14_s { - struct mpdcch_num_repeat_sc_mtch_r14_opts { - enum options { r1, r2, r4, r8, r16, r32, r64, r128, r256, nulltype } value; - typedef uint16_t number_type; - - const char* to_string() const; - uint16_t to_number() const; - }; - typedef enumerated mpdcch_num_repeat_sc_mtch_r14_e_; - struct mpdcch_start_sf_sc_mtch_r14_c_ { - struct fdd_r14_opts { - enum options { v1, v1dot5, v2, v2dot5, v4, v5, v8, v10, nulltype } value; - typedef float number_type; - - const char* to_string() const; - float to_number() const; - const char* to_number_string() const; - }; - typedef enumerated fdd_r14_e_; - struct tdd_r14_opts { - enum options { v1, v2, v4, v5, v8, v10, v20, nulltype } value; - typedef uint8_t number_type; - - const char* to_string() const; - uint8_t to_number() const; - }; - typedef enumerated tdd_r14_e_; - struct types_opts { - enum options { fdd_r14, tdd_r14, nulltype } value; - - const char* to_string() const; - }; - typedef enumerated types; - - // choice methods - mpdcch_start_sf_sc_mtch_r14_c_() = default; - mpdcch_start_sf_sc_mtch_r14_c_(const mpdcch_start_sf_sc_mtch_r14_c_& other); - mpdcch_start_sf_sc_mtch_r14_c_& operator=(const mpdcch_start_sf_sc_mtch_r14_c_& other); - ~mpdcch_start_sf_sc_mtch_r14_c_() { destroy_(); } - void set(types::options e = types::nulltype); - types type() const { return type_; } - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - // getters - fdd_r14_e_& fdd_r14() - { - assert_choice_type(types::fdd_r14, type_, "mpdcch-StartSF-SC-MTCH-r14"); - return c.get(); - } - tdd_r14_e_& tdd_r14() - { - assert_choice_type(types::tdd_r14, type_, "mpdcch-StartSF-SC-MTCH-r14"); - return c.get(); - } - const fdd_r14_e_& fdd_r14() const - { - assert_choice_type(types::fdd_r14, type_, "mpdcch-StartSF-SC-MTCH-r14"); - return c.get(); - } - const tdd_r14_e_& tdd_r14() const - { - assert_choice_type(types::tdd_r14, type_, "mpdcch-StartSF-SC-MTCH-r14"); - return c.get(); - } - fdd_r14_e_& set_fdd_r14(); - tdd_r14_e_& set_tdd_r14(); - - private: - types type_; - pod_choice_buffer_t c; - - void destroy_(); - }; - struct mpdcch_pdsch_hop_cfg_sc_mtch_r14_opts { - enum options { on, off, nulltype } value; - - const char* to_string() const; - }; - typedef enumerated mpdcch_pdsch_hop_cfg_sc_mtch_r14_e_; - struct mpdcch_pdsch_cemode_cfg_sc_mtch_r14_opts { - enum options { ce_mode_a, ce_mode_b, nulltype } value; - - const char* to_string() const; - }; - typedef enumerated mpdcch_pdsch_cemode_cfg_sc_mtch_r14_e_; - struct mpdcch_pdsch_max_bw_sc_mtch_r14_opts { - enum options { bw1dot4, bw5, nulltype } value; - typedef float number_type; - - const char* to_string() const; - float to_number() const; - const char* to_number_string() const; - }; - typedef enumerated mpdcch_pdsch_max_bw_sc_mtch_r14_e_; - struct mpdcch_offset_sc_mtch_r14_opts { - enum options { - zero, - one_eighth, - one_quarter, - three_eighth, - one_half, - five_eighth, - three_quarter, - seven_eighth, - nulltype - } value; - typedef float number_type; - - const char* to_string() const; - float to_number() const; - const char* to_number_string() const; - }; - typedef enumerated mpdcch_offset_sc_mtch_r14_e_; - struct p_a_r14_opts { - enum options { db_minus6, db_minus4dot77, db_minus3, db_minus1dot77, db0, db1, db2, db3, nulltype } value; - typedef float number_type; - - const char* to_string() const; - float to_number() const; - const char* to_number_string() const; - }; - typedef enumerated p_a_r14_e_; - - // member variables - bool ext = false; - bool sc_mtch_sched_info_r14_present = false; - bool sc_mtch_neighbour_cell_r14_present = false; - bool p_a_r14_present = false; - uint32_t sc_mtch_carrier_freq_r14 = 0; - mbms_session_info_r13_s mbms_session_info_r14; - fixed_bitstring<16> g_rnti_r14; - sc_mtch_sched_info_br_r14_s sc_mtch_sched_info_r14; - fixed_bitstring<8> sc_mtch_neighbour_cell_r14; - uint8_t mpdcch_nb_sc_mtch_r14 = 1; - mpdcch_num_repeat_sc_mtch_r14_e_ mpdcch_num_repeat_sc_mtch_r14; - mpdcch_start_sf_sc_mtch_r14_c_ mpdcch_start_sf_sc_mtch_r14; - mpdcch_pdsch_hop_cfg_sc_mtch_r14_e_ mpdcch_pdsch_hop_cfg_sc_mtch_r14; - mpdcch_pdsch_cemode_cfg_sc_mtch_r14_e_ mpdcch_pdsch_cemode_cfg_sc_mtch_r14; - mpdcch_pdsch_max_bw_sc_mtch_r14_e_ mpdcch_pdsch_max_bw_sc_mtch_r14; - mpdcch_offset_sc_mtch_r14_e_ mpdcch_offset_sc_mtch_r14; - p_a_r14_e_ p_a_r14; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - // SC-MTCH-Info-r13 ::= SEQUENCE struct sc_mtch_info_r13_s { struct p_a_r13_opts { @@ -1346,6 +1425,29 @@ using sc_mtch_info_list_r13_l = dyn_array; // SCPTM-NeighbourCellList-r13 ::= SEQUENCE (SIZE (1..8)) OF PCI-ARFCN-r13 using scptm_neighbour_cell_list_r13_l = dyn_array; +// SCPTMConfiguration-BR-v1610 ::= SEQUENCE +struct scptm_cfg_br_v1610_s { + struct multi_tb_gap_r16_opts { + enum options { sf2, sf4, sf8, sf16, sf32, sf64, sf128, spare, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated multi_tb_gap_r16_e_; + + // member variables + bool multi_tb_gap_r16_present = false; + bool non_crit_ext_present = false; + sc_mtch_info_list_br_r14_l sc_mtch_info_list_multi_tb_r16; + multi_tb_gap_r16_e_ multi_tb_gap_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SCPTMConfiguration-v1340 ::= SEQUENCE struct scptm_cfg_v1340_s { bool p_b_r13_present = false; @@ -1368,6 +1470,7 @@ struct scptm_cfg_br_r14_s { scptm_neighbour_cell_list_r13_l scptm_neighbour_cell_list_r14; uint8_t p_b_r14 = 0; dyn_octstring late_non_crit_ext; + scptm_cfg_br_v1610_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1607,30 +1710,15 @@ struct mimo_ue_params_v13e0_s { void to_json(json_writer& j) const; }; -// MeasResult3EUTRA-r15 ::= SEQUENCE -struct meas_result3_eutra_r15_s { - bool ext = false; - bool meas_result_serving_cell_r15_present = false; - bool meas_result_neigh_cell_list_r15_present = false; - uint32_t carrier_freq_r15 = 0; - meas_result_eutra_s meas_result_serving_cell_r15; - meas_result_list_eutra_l meas_result_neigh_cell_list_r15; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - -// MeasResultList3EUTRA-r15 ::= SEQUENCE (SIZE (1..8)) OF MeasResult3EUTRA-r15 -using meas_result_list3_eutra_r15_l = dyn_array; - // MeasResultSCG-FailureMRDC-r15 ::= SEQUENCE struct meas_result_scg_fail_mrdc_r15_s { bool ext = false; meas_result_list3_eutra_r15_l meas_result_freq_list_eutra_r15; // ... + // group 0 + copy_ptr location_info_r16; + copy_ptr log_meas_result_list_bt_r16; + copy_ptr log_meas_result_list_wlan_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1980,6 +2068,30 @@ using meas_result_serv_cell_list_scg_ext_r13_l = dyn_array; +// RLF-Report-NB-r16 ::= SEQUENCE +struct rlf_report_nb_r16_s { + struct meas_result_last_serv_cell_r16_s_ { + bool nrsrq_result_r16_present = false; + uint8_t nrsrp_result_r16 = 0; + int8_t nrsrq_result_r16 = -30; + }; + + // member variables + bool reest_cell_id_r16_present = false; + bool location_info_r16_present = false; + bool time_since_fail_r16_present = false; + cell_global_id_eutra_s failed_pcell_id_r16; + cell_global_id_eutra_s reest_cell_id_r16; + location_info_r10_s location_info_r16; + meas_result_last_serv_cell_r16_s_ meas_result_last_serv_cell_r16; + uint32_t time_since_fail_r16 = 0; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SBCCH-SL-BCH-MessageType ::= MasterInformationBlock-SL using sbcch_sl_bch_msg_type_s = mib_sl_s; @@ -2686,6 +2798,19 @@ struct sl_v2x_precfg_r14_s { copy_ptr v2x_packet_dupl_cfg_r15; copy_ptr sync_freq_list_r15; copy_ptr v2x_tx_profile_list_r15; + // group 1 + copy_ptr anchor_carrier_freq_list_nr_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// VarConditionalReconfiguration ::= SEQUENCE +struct var_conditional_recfg_s { + bool cond_recfg_list_r16_present = false; + cond_recfg_to_add_mod_list_r16_l cond_recfg_list_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2770,6 +2895,30 @@ struct var_log_meas_cfg_r15_s { void to_json(json_writer& j) const; }; +// VarLogMeasConfig-r17 ::= SEQUENCE +struct var_log_meas_cfg_r17_s { + bool area_cfg_r10_present = false; + bool area_cfg_v1130_present = false; + bool target_mbsfn_area_list_r12_present = false; + bool bt_name_list_r15_present = false; + bool wlan_name_list_r15_present = false; + bool logged_event_trigger_cfg_r17_present = false; + bool meas_uncom_bar_pre_r17_present = false; + area_cfg_r10_c area_cfg_r10; + area_cfg_v1130_s area_cfg_v1130; + logging_dur_r10_e logging_dur_r10; + logging_interv_r10_e logging_interv_r10; + target_mbsfn_area_list_r12_l target_mbsfn_area_list_r12; + bt_name_list_r15_l bt_name_list_r15; + wlan_name_list_r15_l wlan_name_list_r15; + logged_event_trigger_cfg_r17_s logged_event_trigger_cfg_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // VarLogMeasReport-r10 ::= SEQUENCE struct var_log_meas_report_r10_s { trace_ref_r10_s trace_ref_r10; @@ -2822,6 +2971,19 @@ struct var_meas_idle_cfg_r15_s { void to_json(json_writer& j) const; }; +// VarMeasIdleConfig-r16 ::= SEQUENCE +struct var_meas_idle_cfg_r16_s { + bool meas_idle_carrier_list_nr_r16_present = false; + bool validity_area_list_r16_present = false; + nr_carrier_list_r16_l meas_idle_carrier_list_nr_r16; + validity_area_list_r16_l validity_area_list_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // VarMeasIdleReport-r15 ::= SEQUENCE struct var_meas_idle_report_r15_s { meas_result_list_idle_r15_l meas_report_idle_r15; @@ -2832,6 +2994,19 @@ struct var_meas_idle_report_r15_s { void to_json(json_writer& j) const; }; +// VarMeasIdleReport-r16 ::= SEQUENCE +struct var_meas_idle_report_r16_s { + bool meas_report_idle_r16_present = false; + bool meas_report_idle_nr_r16_present = false; + meas_result_list_ext_idle_r16_l meas_report_idle_r16; + meas_result_list_idle_nr_r16_l meas_report_idle_nr_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // VarMeasReport ::= SEQUENCE struct var_meas_report_s { bool meas_id_v1250_present = false; @@ -2860,6 +3035,17 @@ using var_meas_report_list_r12_l = dyn_array; // VarMobilityHistoryReport-r12 ::= VisitedCellInfoList-r12 using var_mob_history_report_r12_l = visited_cell_info_list_r12_l; +// VarRLF-Report-NB-r16 ::= SEQUENCE +struct var_rlf_report_nb_r16_s { + rlf_report_nb_r16_s rlf_report_r16; + plmn_id_list3_r11_l plmn_id_list_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // VarRLF-Report-r10 ::= SEQUENCE struct var_rlf_report_r10_s { rlf_report_r9_s rlf_report_r10; diff --git a/lib/include/srsran/asn1/rrc/bcch_msg.h b/lib/include/srsran/asn1/rrc/bcch_msg.h index f9601f302a..fa0352a7f6 100644 --- a/lib/include/srsran/asn1/rrc/bcch_msg.h +++ b/lib/include/srsran/asn1/rrc/bcch_msg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -29,6 +29,7 @@ #define SRSASN1_RRC_BCCH_MSG_H #include "meascfg.h" +#include "phy_ded.h" #include "si.h" namespace asn1 { @@ -149,6 +150,46 @@ struct neigh_cells_per_bandclass_cdma2000_v920_s { void to_json(json_writer& j) const; }; +// PhysCellIdRangeNR-r16 ::= SEQUENCE +struct pci_range_nr_r16_s { + struct range_opts { + enum options { + n4, + n8, + n12, + n16, + n24, + n32, + n48, + n64, + n84, + n96, + n128, + n168, + n252, + n504, + n1008, + spare1, + nulltype + } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated range_e_; + + // member variables + bool range_present = false; + uint16_t start = 0; + range_e_ range; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RedistributionNeighCell-r13 ::= SEQUENCE struct redist_neigh_cell_r13_s { uint16_t pci_r13 = 0; @@ -179,6 +220,26 @@ struct ac_barr_cfg1_xrtt_r9_s { void to_json(json_writer& j) const; }; +// BeamMeasConfigIdleNR-r16 ::= SEQUENCE +struct beam_meas_cfg_idle_nr_r16_s { + struct report_quant_rs_idx_nr_r16_opts { + enum options { rsrp, rsrq, both, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated report_quant_rs_idx_nr_r16_e_; + + // member variables + report_quant_rs_idx_nr_r16_e_ report_quant_rs_idx_nr_r16; + uint8_t max_report_rs_idx_r16 = 0; + bool report_rs_idx_results_nr_r16 = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CSFB-RegistrationParam1XRTT ::= SEQUENCE struct csfb_regist_param1_xrtt_s { fixed_bitstring<15> sid; @@ -209,6 +270,9 @@ struct csfb_regist_param1_xrtt_v920_s { void to_json(json_writer& j) const; }; +// CellListNR-r16 ::= SEQUENCE (SIZE (1..8)) OF PhysCellIdRangeNR-r16 +using cell_list_nr_r16_l = dyn_array; + // CellReselectionParametersCDMA2000-r11 ::= SEQUENCE struct cell_resel_params_cdma2000_r11_s { using neigh_cell_list_r11_l_ = dyn_array; @@ -237,6 +301,16 @@ struct inter_freq_neigh_cell_info_s { void to_json(json_writer& j) const; }; +// InterFreqNeighCellInfo-v1610 ::= SEQUENCE +struct inter_freq_neigh_cell_info_v1610_s { + rss_meas_pwr_bias_r16_e rss_meas_pwr_bias_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // NS-PmaxList-r10 ::= SEQUENCE (SIZE (1..8)) OF NS-PmaxValue-r10 using ns_pmax_list_r10_l = dyn_array; @@ -377,18 +451,222 @@ struct uac_barr_per_cat_r15_s { void to_json(json_writer& j) const; }; -// InterFreqBlackCellList ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdRange -using inter_freq_black_cell_list_l = dyn_array; +// AllowedCellListNR-r16 ::= SEQUENCE (SIZE (1..16)) OF INTEGER (0..1007) +using allowed_cell_list_nr_r16_l = bounded_array; + +// InterFreqExcludedCellList ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdRange +using inter_freq_excluded_cell_list_l = dyn_array; // InterFreqNeighCellList ::= SEQUENCE (SIZE (1..16)) OF InterFreqNeighCellInfo using inter_freq_neigh_cell_list_l = dyn_array; +// InterFreqNeighCellList-v1610 ::= SEQUENCE (SIZE (1..16)) OF InterFreqNeighCellInfo-v1610 +using inter_freq_neigh_cell_list_v1610_l = dyn_array; + // InterFreqNeighHSDN-CellList-r15 ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdRange using inter_freq_neigh_hsdn_cell_list_r15_l = dyn_array; // MBMS-SAI-List-r11 ::= SEQUENCE (SIZE (1..64)) OF INTEGER (0..65535) using mbms_sai_list_r11_l = dyn_array; +// MBSFN-AreaInfo-r16 ::= SEQUENCE +struct mbsfn_area_info_r16_s { + struct mcch_cfg_r16_s_ { + struct mcch_repeat_period_r16_opts { + enum options { + rf1, + rf2, + rf4, + rf8, + rf16, + rf32, + rf64, + rf128, + rf256, + spare7, + spare6, + spare5, + spare4, + spare3, + spare2, + spare1, + nulltype + } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated mcch_repeat_period_r16_e_; + struct mcch_mod_period_r16_opts { + enum options { + rf1, + rf2, + rf4, + rf8, + rf16, + rf32, + rf64, + rf128, + rf256, + rf512, + rf1024, + spare5, + spare4, + spare3, + spare2, + spare1, + nulltype + } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated mcch_mod_period_r16_e_; + struct sig_mcs_r16_opts { + enum options { n2, n7, n13, n19, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated sig_mcs_r16_e_; + + // member variables + mcch_repeat_period_r16_e_ mcch_repeat_period_r16; + mcch_mod_period_r16_e_ mcch_mod_period_r16; + uint8_t mcch_offset_r16 = 0; + fixed_bitstring<10> sf_alloc_info_r16; + sig_mcs_r16_e_ sig_mcs_r16; + }; + struct subcarrier_spacing_mbms_r16_opts { + enum options { khz7dot5, khz2dot5, khz1dot25, khz0dot37, khz15_v1710, spare3, spare2, spare1, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated subcarrier_spacing_mbms_r16_e_; + struct time_separation_r16_opts { + enum options { sl2, sl4, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated time_separation_r16_e_; + + // member variables + bool ext = false; + bool time_separation_r16_present = false; + uint16_t mbsfn_area_id_r16 = 0; + uint8_t notif_ind_r16 = 0; + mcch_cfg_r16_s_ mcch_cfg_r16; + subcarrier_spacing_mbms_r16_e_ subcarrier_spacing_mbms_r16; + time_separation_r16_e_ time_separation_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MTC-SSB2-LP-NR-r16 ::= SEQUENCE +struct mtc_ssb2_lp_nr_r16_s { + using pci_list_r16_l_ = dyn_array; + struct periodicity_r16_opts { + enum options { sf10, sf20, sf40, sf80, sf160, spare3, spare2, spare1, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated periodicity_r16_e_; + + // member variables + bool pci_list_r16_present = false; + pci_list_r16_l_ pci_list_r16; + periodicity_r16_e_ periodicity_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasIdleCarrierNR-r16 ::= SEQUENCE +struct meas_idle_carrier_nr_r16_s { + struct subcarrier_spacing_ssb_r16_opts { + enum options { khz15, khz30, khz120, khz240, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated subcarrier_spacing_ssb_r16_e_; + struct report_quantities_nr_r16_opts { + enum options { rsrp, rsrq, both, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated report_quantities_nr_r16_e_; + struct quality_thres_nr_r16_s_ { + bool idle_rsrp_thres_nr_r16_present = false; + bool idle_rsrq_thres_nr_r16_present = false; + uint8_t idle_rsrp_thres_nr_r16 = 0; + uint8_t idle_rsrq_thres_nr_r16 = 0; + }; + struct ssb_meas_cfg_r16_s_ { + bool max_rs_idx_cell_qual_r16_present = false; + bool thresh_rs_idx_r16_present = false; + bool meas_timing_cfg_r16_present = false; + bool ssb_to_measure_r16_present = false; + bool ss_rssi_meas_r16_present = false; + uint8_t max_rs_idx_cell_qual_r16 = 1; + thres_list_nr_r15_s thresh_rs_idx_r16; + mtc_ssb_nr_r15_s meas_timing_cfg_r16; + ssb_to_measure_r15_c ssb_to_measure_r16; + bool derive_ssb_idx_from_cell_r16 = false; + ss_rssi_meas_r15_s ss_rssi_meas_r16; + }; + struct subcarrier_spacing_ssb_r17_opts { + enum options { khz480, spare1, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated subcarrier_spacing_ssb_r17_e_; + + // member variables + bool ext = false; + bool freq_band_list_present = false; + bool meas_cell_list_nr_r16_present = false; + bool quality_thres_nr_r16_present = false; + bool ssb_meas_cfg_r16_present = false; + bool beam_meas_cfg_idle_r16_present = false; + uint32_t carrier_freq_nr_r16 = 0; + subcarrier_spacing_ssb_r16_e_ subcarrier_spacing_ssb_r16; + multi_freq_band_list_nr_r15_l freq_band_list; + cell_list_nr_r16_l meas_cell_list_nr_r16; + report_quantities_nr_r16_e_ report_quantities_nr_r16; + quality_thres_nr_r16_s_ quality_thres_nr_r16; + ssb_meas_cfg_r16_s_ ssb_meas_cfg_r16; + beam_meas_cfg_idle_nr_r16_s beam_meas_cfg_idle_r16; + // ... + // group 0 + bool subcarrier_spacing_ssb_r17_present = false; + subcarrier_spacing_ssb_r17_e_ subcarrier_spacing_ssb_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MultiBandInfoList-v10j0 ::= SEQUENCE (SIZE (1..8)) OF NS-PmaxList-r10 using multi_band_info_list_v10j0_l = dyn_array; @@ -398,6 +676,9 @@ using multi_band_ns_pmax_list_nr_minus1_v1550_l = dyn_array; +// NR-FreqNeighHSDN-CellList-r17 ::= SEQUENCE (SIZE (1..8)) OF PhysCellIdRangeNR-r16 +using nr_freq_neigh_hsdn_cell_list_r17_l = dyn_array; + // NeighCellCDMA2000 ::= SEQUENCE struct neigh_cell_cdma2000_s { bandclass_cdma2000_e band_class; @@ -524,9 +805,76 @@ struct sl_disc_cfg_other_inter_freq_r13_s { void to_json(json_writer& j) const; }; +// TLE-EphemerisParameters-r17 ::= SEQUENCE +struct tle_ephemeris_params_r17_s { + uint32_t inclination_r17 = 0; + uint32_t argument_perigee_r17 = 0; + uint32_t right_ascension_r17 = 0; + uint32_t mean_anomaly_r17 = 0; + uint32_t eccentricity_r17 = 0; + uint64_t mean_motion_r17 = 0; + int32_t bstar_decimal_r17 = -99999; + int8_t bstar_exponent_r17 = -9; + int32_t epoch_star_r17 = -1048575; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // UAC-BarringPerCatList-r15 ::= SEQUENCE (SIZE (1..63)) OF UAC-BarringPerCat-r15 using uac_barr_per_cat_list_r15_l = dyn_array; +// CarrierFreqNBIOT-r16 ::= SEQUENCE +struct carrier_freq_nbiot_r16_s { + struct carrier_freq_offset_r16_opts { + enum options { + v_minus10, + v_minus9, + v_minus8dot5, + v_minus8, + v_minus7, + v_minus6, + v_minus5, + v_minus4dot5, + v_minus4, + v_minus3, + v_minus2, + v_minus1, + v_minus0dot5, + v0, + v1, + v2, + v3, + v3dot5, + v4, + v5, + v6, + v7, + v7dot5, + v8, + v9, + nulltype + } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated carrier_freq_offset_r16_e_; + + // member variables + uint32_t carrier_freq_r16 = 0; + carrier_freq_offset_r16_e_ carrier_freq_offset_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CarrierFreqNR-r15 ::= SEQUENCE struct carrier_freq_nr_r15_s { struct subcarrier_spacing_ssb_r15_opts { @@ -587,6 +935,56 @@ struct carrier_freq_nr_r15_s { void to_json(json_writer& j) const; }; +// CarrierFreqNR-v1610 ::= SEQUENCE +struct carrier_freq_nr_v1610_s { + bool smtc2_lp_r16_present = false; + bool ssb_position_qcl_common_nr_r16_present = false; + bool allowed_cell_list_nr_r16_present = false; + bool high_speed_carrier_nr_r16_present = false; + mtc_ssb2_lp_nr_r16_s smtc2_lp_r16; + ssb_position_qcl_relation_nr_r16_e ssb_position_qcl_common_nr_r16; + allowed_cell_list_nr_r16_l allowed_cell_list_nr_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CarrierFreqNR-v1700 ::= SEQUENCE +struct carrier_freq_nr_v1700_s { + bool nr_freq_neigh_hsdn_cell_list_r17_present = false; + nr_freq_neigh_hsdn_cell_list_r17_l nr_freq_neigh_hsdn_cell_list_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CarrierFreqNR-v1720 ::= SEQUENCE +struct carrier_freq_nr_v1720_s { + struct subcarrier_spacing_ssb_r17_opts { + enum options { khz480, spare1, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated subcarrier_spacing_ssb_r17_e_; + + // member variables + bool subcarrier_spacing_ssb_r17_present = false; + bool ssb_position_qcl_common_nr_r17_present = false; + subcarrier_spacing_ssb_r17_e_ subcarrier_spacing_ssb_r17; + ssb_position_qcl_relation_nr_r17_e ssb_position_qcl_common_nr_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CarrierFreqUTRA-FDD ::= SEQUENCE struct carrier_freq_utra_fdd_s { struct thresh_x_q_r9_s_ { @@ -726,6 +1124,36 @@ struct eab_cfg_r11_s { void to_json(json_writer& j) const; }; +// EphemerisOrbitalParameters-r17 ::= SEQUENCE +struct ephemeris_orbital_params_r17_s { + uint64_t semi_major_axis_r17 = 0; + uint32_t eccentricity_r17 = 0; + uint32_t periapsis_r17 = 0; + uint32_t longitude_r17 = 0; + int32_t inclination_r17 = -67108864; + uint32_t anomaly_r17 = 0; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// EphemerisStateVectors-r17 ::= SEQUENCE +struct ephemeris_state_vectors_r17_s { + int32_t position_x_r17 = -33554432; + int32_t position_y_r17 = -33554432; + int32_t position_z_r17 = -33554432; + int32_t velocity_vx_r17 = -131072; + int32_t velocity_vy_r17 = -131072; + int32_t velocity_vz_r17 = -131072; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // InterFreqCarrierFreqInfo ::= SEQUENCE struct inter_freq_carrier_freq_info_s { struct thresh_x_q_r9_s_ { @@ -734,27 +1162,27 @@ struct inter_freq_carrier_freq_info_s { }; // member variables - bool ext = false; - bool p_max_present = false; - bool t_resel_eutra_sf_present = false; - bool cell_resel_prio_present = false; - bool q_offset_freq_present = false; - bool inter_freq_neigh_cell_list_present = false; - bool inter_freq_black_cell_list_present = false; - uint32_t dl_carrier_freq = 0; - int8_t q_rx_lev_min = -70; - int8_t p_max = -30; - uint8_t t_resel_eutra = 0; - speed_state_scale_factors_s t_resel_eutra_sf; - uint8_t thresh_x_high = 0; - uint8_t thresh_x_low = 0; - allowed_meas_bw_e allowed_meas_bw; - bool presence_ant_port1 = false; - uint8_t cell_resel_prio = 0; - fixed_bitstring<2> neigh_cell_cfg; - q_offset_range_e q_offset_freq; - inter_freq_neigh_cell_list_l inter_freq_neigh_cell_list; - inter_freq_black_cell_list_l inter_freq_black_cell_list; + bool ext = false; + bool p_max_present = false; + bool t_resel_eutra_sf_present = false; + bool cell_resel_prio_present = false; + bool q_offset_freq_present = false; + bool inter_freq_neigh_cell_list_present = false; + bool inter_freq_excluded_cell_list_present = false; + uint32_t dl_carrier_freq = 0; + int8_t q_rx_lev_min = -70; + int8_t p_max = -30; + uint8_t t_resel_eutra = 0; + speed_state_scale_factors_s t_resel_eutra_sf; + uint8_t thresh_x_high = 0; + uint8_t thresh_x_low = 0; + allowed_meas_bw_e allowed_meas_bw; + bool presence_ant_port1 = false; + uint8_t cell_resel_prio = 0; + fixed_bitstring<2> neigh_cell_cfg; + q_offset_range_e q_offset_freq; + inter_freq_neigh_cell_list_l inter_freq_neigh_cell_list; + inter_freq_excluded_cell_list_l inter_freq_excluded_cell_list; // ... // group 0 bool q_qual_min_r9_present = false; @@ -778,38 +1206,38 @@ struct inter_freq_carrier_freq_info_r12_s { }; // member variables - bool ext = false; - bool p_max_r12_present = false; - bool t_resel_eutra_sf_r12_present = false; - bool cell_resel_prio_r12_present = false; - bool q_offset_freq_r12_present = false; - bool inter_freq_neigh_cell_list_r12_present = false; - bool inter_freq_black_cell_list_r12_present = false; - bool q_qual_min_r12_present = false; - bool thresh_x_q_r12_present = false; - bool q_qual_min_wb_r12_present = false; - bool multi_band_info_list_r12_present = false; - bool reduced_meas_performance_r12_present = false; - bool q_qual_min_rsrq_on_all_symbols_r12_present = false; - uint32_t dl_carrier_freq_r12 = 0; - int8_t q_rx_lev_min_r12 = -70; - int8_t p_max_r12 = -30; - uint8_t t_resel_eutra_r12 = 0; - speed_state_scale_factors_s t_resel_eutra_sf_r12; - uint8_t thresh_x_high_r12 = 0; - uint8_t thresh_x_low_r12 = 0; - allowed_meas_bw_e allowed_meas_bw_r12; - bool presence_ant_port1_r12 = false; - uint8_t cell_resel_prio_r12 = 0; - fixed_bitstring<2> neigh_cell_cfg_r12; - q_offset_range_e q_offset_freq_r12; - inter_freq_neigh_cell_list_l inter_freq_neigh_cell_list_r12; - inter_freq_black_cell_list_l inter_freq_black_cell_list_r12; - int8_t q_qual_min_r12 = -34; - thresh_x_q_r12_s_ thresh_x_q_r12; - int8_t q_qual_min_wb_r12 = -34; - multi_band_info_list_r11_l multi_band_info_list_r12; - int8_t q_qual_min_rsrq_on_all_symbols_r12 = -34; + bool ext = false; + bool p_max_r12_present = false; + bool t_resel_eutra_sf_r12_present = false; + bool cell_resel_prio_r12_present = false; + bool q_offset_freq_r12_present = false; + bool inter_freq_neigh_cell_list_r12_present = false; + bool inter_freq_excluded_cell_list_r12_present = false; + bool q_qual_min_r12_present = false; + bool thresh_x_q_r12_present = false; + bool q_qual_min_wb_r12_present = false; + bool multi_band_info_list_r12_present = false; + bool reduced_meas_performance_r12_present = false; + bool q_qual_min_rsrq_on_all_symbols_r12_present = false; + uint32_t dl_carrier_freq_r12 = 0; + int8_t q_rx_lev_min_r12 = -70; + int8_t p_max_r12 = -30; + uint8_t t_resel_eutra_r12 = 0; + speed_state_scale_factors_s t_resel_eutra_sf_r12; + uint8_t thresh_x_high_r12 = 0; + uint8_t thresh_x_low_r12 = 0; + allowed_meas_bw_e allowed_meas_bw_r12; + bool presence_ant_port1_r12 = false; + uint8_t cell_resel_prio_r12 = 0; + fixed_bitstring<2> neigh_cell_cfg_r12; + q_offset_range_e q_offset_freq_r12; + inter_freq_neigh_cell_list_l inter_freq_neigh_cell_list_r12; + inter_freq_excluded_cell_list_l inter_freq_excluded_cell_list_r12; + int8_t q_qual_min_r12 = -34; + thresh_x_q_r12_s_ thresh_x_q_r12; + int8_t q_qual_min_wb_r12 = -34; + multi_band_info_list_r11_l multi_band_info_list_r12; + int8_t q_qual_min_rsrq_on_all_symbols_r12 = -34; // ... // sequence methods @@ -896,6 +1324,23 @@ struct inter_freq_carrier_freq_info_v1530_s { void to_json(json_writer& j) const; }; +// InterFreqCarrierFreqInfo-v1610 ::= SEQUENCE +struct inter_freq_carrier_freq_info_v1610_s { + bool alt_cell_resel_prio_r16_present = false; + bool alt_cell_resel_sub_prio_r16_present = false; + bool rss_cfg_carrier_info_r16_present = false; + bool inter_freq_neigh_cell_list_v1610_present = false; + uint8_t alt_cell_resel_prio_r16 = 0; + cell_resel_sub_prio_r13_e alt_cell_resel_sub_prio_r16; + rss_cfg_carrier_info_r16_s rss_cfg_carrier_info_r16; + inter_freq_neigh_cell_list_v1610_l inter_freq_neigh_cell_list_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // IntraFreqNeighCellInfo ::= SEQUENCE struct intra_freq_neigh_cell_info_s { bool ext = false; @@ -909,6 +1354,16 @@ struct intra_freq_neigh_cell_info_s { void to_json(json_writer& j) const; }; +// IntraFreqNeighCellInfo-v1610 ::= SEQUENCE +struct intra_freq_neigh_cell_info_v1610_s { + rss_meas_pwr_bias_r16_e rss_meas_pwr_bias_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MBMS-CarrierType-r14 ::= SEQUENCE struct mbms_carrier_type_r14_s { struct carrier_type_r14_opts { @@ -951,6 +1406,29 @@ struct mbms_sai_inter_freq_v1140_s { void to_json(json_writer& j) const; }; +// MBSFN-AreaInfo-r17 ::= SEQUENCE +struct mbsfn_area_info_r17_s { + struct pmch_bw_r17_opts { + enum options { n40, n35, n30, spare1, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated pmch_bw_r17_e_; + + // member variables + bool ext = false; + mbsfn_area_info_r16_s mbsfn_area_info_r17; + pmch_bw_r17_e_ pmch_bw_r17; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MBSFN-AreaInfo-r9 ::= SEQUENCE struct mbsfn_area_info_r9_s { struct non_mbsfn_region_len_opts { @@ -1046,102 +1524,26 @@ struct mbsfn_area_info_r9_s { void to_json(json_writer& j) const; }; -// MBSFN-AreaInfo-r16 ::= SEQUENCE -struct mbsfn_area_info_r16_s { - struct mcch_cfg_r16_s_ { - struct mcch_repeat_period_r16_opts { - enum options { rf1, rf2, rf4, rf8, rf16, - rf32, rf64, rf128, rf256, spare7, spare6, spare5, - spare4, spare3, spare2, spare1, nulltype } value; - typedef uint16_t number_type; - - std::string to_string() const; - uint16_t to_number() const; - }; - typedef enumerated mcch_repeat_period_r16_e_; - - struct mcch_mod_period_r16_opts { - enum options { rf1, rf2, rf4, rf8, rf16, - rf32, rf64, rf128, rf256, rf512, rf1024, spare5, - spare4, spare3, spare2, spare1, nulltype } value; - typedef uint16_t number_type; - - std::string to_string() const; - uint16_t to_number() const; - }; - typedef enumerated mcch_mod_period_r16_e_; - - struct sig_mcs_r16_opts { - enum options { n2, n7, n13, n19, nulltype } value; - typedef uint8_t number_type; - - std::string to_string() const; - uint8_t to_number() const; - }; - typedef enumerated sig_mcs_r16_e_; - - // member variables - mcch_repeat_period_r16_e_ mcch_repeat_period_r16; - mcch_mod_period_r16_e_ mcch_mod_period_r16; - uint8_t mcch_offset_r16 = 0; - fixed_bitstring<10> sf_alloc_info_r16; - sig_mcs_r16_e_ sig_mcs_r16; - }; - - struct subcarrier_spacing_mbms_r16_opts { - enum options { khz_7dot5, khz_2dot5, khz_1dot25, khz0dot37, - spare4, spare3, spare2, spare1, nulltype } value; - typedef float number_type; - - std::string to_string() const; - float to_number() const; - std::string to_number_string() const; - }; - typedef enumerated subcarrier_spacing_mbms_r16_e_; - - struct time_separation_r16_opts { - enum options { s12, s14, nulltype } value; - typedef uint8_t number_type; +// NR-CarrierList-r16 ::= SEQUENCE (SIZE (1..8)) OF MeasIdleCarrierNR-r16 +using nr_carrier_list_r16_l = dyn_array; - std::string to_string() const; - uint8_t to_number() const; - std::string to_number_string() const; - }; - typedef enumerated time_separation_r16_e_; +// NeighCellListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000 +using neigh_cell_list_cdma2000_l = dyn_array; - struct pmch_bandwidth_v16xy_opts { - enum options { n30, n35, n40, spare1, nulltype } value; - typedef uint8_t number_type; +// NeighCellListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000-v920 +using neigh_cell_list_cdma2000_v920_l = dyn_array; - std::string to_string() const; - uint8_t to_number() const; - std::string to_number_string() const; - }; - typedef enumerated pmch_bandwidth_v16xy_e_; - - // member variables - bool ext = false; - uint16_t mbsfn_area_id_r16 = 0; - uint8_t notif_ind_r16 = 0; - mcch_cfg_r16_s_ mcch_cfg_r16; - subcarrier_spacing_mbms_r16_e_ subcarrier_spacing_mbms_r16; - bool time_separation_r16_present = false; - time_separation_r16_e_ time_separation_r16; - bool pmch_bandwidth_v16xy_present = false; - pmch_bandwidth_v16xy_e_ pmch_bandwidth_v16xy; +// PLMN-Info-r16 ::= SEQUENCE +struct plmn_info_r16_s { + bool nr_band_list_r16_present = false; + fixed_bitstring<10> nr_band_list_r16; // sequence methods - // SRSASN_CODE pack(bit_ref& bref) const; // not implemented + SRSASN_CODE pack(bit_ref& bref) const; SRSASN_CODE unpack(cbit_ref& bref); void to_json(json_writer& j) const; }; -// NeighCellListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000 -using neigh_cell_list_cdma2000_l = dyn_array; - -// NeighCellListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000-v920 -using neigh_cell_list_cdma2000_v920_l = dyn_array; - // ReselectionInfoRelay-r13 ::= SEQUENCE struct resel_info_relay_r13_s { struct min_hyst_r13_opts { @@ -1258,6 +1660,45 @@ struct sl_pppp_tx_cfg_idx_r15_s { void to_json(json_writer& j) const; }; +// SatelliteInfo-r17 ::= SEQUENCE +struct satellite_info_r17_s { + struct service_info_r17_s_ { + bool tle_ephemeris_params_r17_present = false; + bool t_service_start_r17_present = false; + tle_ephemeris_params_r17_s tle_ephemeris_params_r17; + uint32_t t_service_start_r17 = 0; + }; + struct footprint_info_r17_s_ { + struct ref_point_r17_s_ { + int32_t longitude_r17 = -131072; + int32_t latitude_r17 = -131072; + }; + struct elevation_angles_r17_s_ { + bool elevation_angle_left_r17_present = false; + int8_t elevation_angle_right_r17 = -14; + int8_t elevation_angle_left_r17 = -14; + }; + + // member variables + bool ref_point_r17_present = false; + bool elevation_angles_r17_present = false; + bool radius_r17_present = false; + ref_point_r17_s_ ref_point_r17; + elevation_angles_r17_s_ elevation_angles_r17; + uint16_t radius_r17 = 1; + }; + + // member variables + uint16_t satellite_id_r17 = 0; + service_info_r17_s_ service_info_r17; + footprint_info_r17_s_ footprint_info_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // UAC-BarringInfoSet-r15 ::= SEQUENCE struct uac_barr_info_set_r15_s { struct uac_barr_factor_r15_opts { @@ -1289,6 +1730,28 @@ struct uac_barr_info_set_r15_s { void to_json(json_writer& j) const; }; +// UAC-BarringInfoSet-v1700 ::= SEQUENCE +struct uac_barr_info_set_v1700_s { + struct uac_barr_factor_for_ai3_r17_opts { + enum options { p00, p05, p10, p15, p20, p25, p30, p40, p50, p60, p70, p75, p80, p85, p90, p95, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated uac_barr_factor_for_ai3_r17_e_; + + // member variables + bool uac_barr_factor_for_ai3_r17_present = false; + uac_barr_factor_for_ai3_r17_e_ uac_barr_factor_for_ai3_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // UAC-BarringPerPLMN-r15 ::= SEQUENCE struct uac_barr_per_plmn_r15_s { struct uac_ac_barr_list_type_r15_c_ { @@ -1352,6 +1815,47 @@ struct uac_barr_per_plmn_r15_s { void to_json(json_writer& j) const; }; +// ApplicableDisasterInfo-r17 ::= CHOICE +struct applicable_disaster_info_r17_c { + using ded_plmns_r17_l_ = dyn_array; + struct types_opts { + enum options { no_disaster_roaming_r17, disaster_related_ind_r17, common_plmns_r17, ded_plmns_r17, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + applicable_disaster_info_r17_c() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ded_plmns_r17_l_& ded_plmns_r17() + { + assert_choice_type(types::ded_plmns_r17, type_, "ApplicableDisasterInfo-r17"); + return c; + } + const ded_plmns_r17_l_& ded_plmns_r17() const + { + assert_choice_type(types::ded_plmns_r17, type_, "ApplicableDisasterInfo-r17"); + return c; + } + void set_no_disaster_roaming_r17(); + void set_disaster_related_ind_r17(); + void set_common_plmns_r17(); + ded_plmns_r17_l_& set_ded_plmns_r17(); + +private: + types type_; + ded_plmns_r17_l_ c; +}; + +// BandListENDC-r16 ::= SEQUENCE (SIZE (1..10)) OF INTEGER (1..1024) +using band_list_endc_r16_l = bounded_array; + // CarrierFreqInfoUTRA-v1250 ::= SEQUENCE struct carrier_freq_info_utra_v1250_s { bool reduced_meas_performance_r12_present = false; @@ -1362,9 +1866,21 @@ struct carrier_freq_info_utra_v1250_s { void to_json(json_writer& j) const; }; +// CarrierFreqListNBIOT-r16 ::= SEQUENCE (SIZE (1..8)) OF CarrierFreqNBIOT-r16 +using carrier_freq_list_nbiot_r16_l = dyn_array; + // CarrierFreqListNR-r15 ::= SEQUENCE (SIZE (1..8)) OF CarrierFreqNR-r15 using carrier_freq_list_nr_r15_l = dyn_array; +// CarrierFreqListNR-v1610 ::= SEQUENCE (SIZE (1..8)) OF CarrierFreqNR-v1610 +using carrier_freq_list_nr_v1610_l = dyn_array; + +// CarrierFreqListNR-v1700 ::= SEQUENCE (SIZE (1..8)) OF CarrierFreqNR-v1700 +using carrier_freq_list_nr_v1700_l = dyn_array; + +// CarrierFreqListNR-v1720 ::= SEQUENCE (SIZE (1..8)) OF CarrierFreqNR-v1720 +using carrier_freq_list_nr_v1720_l = dyn_array; + // CarrierFreqListUTRA-FDD ::= SEQUENCE (SIZE (1..16)) OF CarrierFreqUTRA-FDD using carrier_freq_list_utra_fdd_l = dyn_array; @@ -1444,6 +1960,19 @@ struct cell_resel_serving_freq_info_v1310_s { void to_json(json_writer& j) const; }; +// CellReselectionServingFreqInfo-v1610 ::= SEQUENCE +struct cell_resel_serving_freq_info_v1610_s { + bool alt_cell_resel_prio_r16_present = false; + bool alt_cell_resel_sub_prio_r16_present = false; + uint8_t alt_cell_resel_prio_r16 = 0; + cell_resel_sub_prio_r13_e alt_cell_resel_sub_prio_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // EAB-ConfigPLMN-r11 ::= SEQUENCE struct eab_cfg_plmn_r11_s { bool eab_cfg_r11_present = false; @@ -1470,6 +1999,9 @@ using inter_freq_carrier_freq_list_v1350_l = dyn_array; +// InterFreqCarrierFreqList-v1610 ::= SEQUENCE (SIZE (1..8)) OF InterFreqCarrierFreqInfo-v1610 +using inter_freq_carrier_freq_list_v1610_l = dyn_array; + // InterFreqCarrierFreqListExt-r12 ::= SEQUENCE (SIZE (1..8)) OF InterFreqCarrierFreqInfo-r12 using inter_freq_carrier_freq_list_ext_r12_l = dyn_array; @@ -1488,12 +2020,18 @@ using inter_freq_carrier_freq_list_ext_v1360_l = dyn_array; -// IntraFreqBlackCellList ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdRange -using intra_freq_black_cell_list_l = dyn_array; +// InterFreqCarrierFreqListExt-v1610 ::= SEQUENCE (SIZE (1..8)) OF InterFreqCarrierFreqInfo-v1610 +using inter_freq_carrier_freq_list_ext_v1610_l = dyn_array; + +// IntraFreqExcludedCellList ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdRange +using intra_freq_excluded_cell_list_l = dyn_array; // IntraFreqNeighCellList ::= SEQUENCE (SIZE (1..16)) OF IntraFreqNeighCellInfo using intra_freq_neigh_cell_list_l = dyn_array; +// IntraFreqNeighCellList-v1610 ::= SEQUENCE (SIZE (1..16)) OF IntraFreqNeighCellInfo-v1610 +using intra_freq_neigh_cell_list_v1610_l = dyn_array; + // IntraFreqNeighHSDN-CellList-r15 ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdRange using intra_freq_neigh_hsdn_cell_list_r15_l = dyn_array; @@ -1538,10 +2076,26 @@ using mbms_sai_inter_freq_list_r11_l = dyn_array; // MBMS-SAI-InterFreqList-v1140 ::= SEQUENCE (SIZE (1..8)) OF MBMS-SAI-InterFreq-v1140 using mbms_sai_inter_freq_list_v1140_l = dyn_array; +// MBSFN-AreaInfoList-r16 ::= SEQUENCE (SIZE (1..8)) OF MBSFN-AreaInfo-r16 +using mbsfn_area_info_list_r16_l = dyn_array; + +// MBSFN-AreaInfoList-r17 ::= SEQUENCE (SIZE (1..8)) OF MBSFN-AreaInfo-r17 +using mbsfn_area_info_list_r17_l = dyn_array; + // MBSFN-AreaInfoList-r9 ::= SEQUENCE (SIZE (1..8)) OF MBSFN-AreaInfo-r9 using mbsfn_area_info_list_r9_l = dyn_array; -using mbsfn_area_info_list_r16_l = dyn_array; +// MeasIdleConfigSIB-NR-r16 ::= SEQUENCE +struct meas_idle_cfg_sib_nr_r16_s { + bool ext = false; + nr_carrier_list_r16_l meas_idle_carrier_list_nr_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; // MeasIdleConfigSIB-r15 ::= SEQUENCE struct meas_idle_cfg_sib_r15_s { @@ -1555,6 +2109,9 @@ struct meas_idle_cfg_sib_r15_s { void to_json(json_writer& j) const; }; +// PLMN-InfoList-r16 ::= SEQUENCE (SIZE (0..6)) OF PLMN-Info-r16 +using plmn_info_list_r16_l = dyn_array; + // RedistributionServingInfo-r13 ::= SEQUENCE struct redist_serving_info_r13_s { struct t360_r13_opts { @@ -1930,9 +2487,104 @@ struct sl_disc_cfg_remote_ue_r13_s { void to_json(json_writer& j) const; }; +// SL-NR-AnchorCarrierFreqList-r16 ::= SEQUENCE (SIZE (1..8)) OF INTEGER (0..3279165) +using sl_nr_anchor_carrier_freq_list_r16_l = bounded_array; + // SL-SyncConfigList-r12 ::= SEQUENCE (SIZE (1..16)) OF SL-SyncConfig-r12 using sl_sync_cfg_list_r12_l = dyn_array; +// SatelliteInfoList-r17 ::= SEQUENCE (SIZE (1..4)) OF SatelliteInfo-r17 +using satellite_info_list_r17_l = dyn_array; + +// ServingSatelliteInfo-r17 ::= SEQUENCE +struct serving_satellite_info_r17_s { + struct ephemeris_info_r17_c_ { + struct types_opts { + enum options { state_vectors, orbital_params, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ephemeris_info_r17_c_() = default; + ephemeris_info_r17_c_(const ephemeris_info_r17_c_& other); + ephemeris_info_r17_c_& operator=(const ephemeris_info_r17_c_& other); + ~ephemeris_info_r17_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ephemeris_state_vectors_r17_s& state_vectors() + { + assert_choice_type(types::state_vectors, type_, "ephemerisInfo-r17"); + return c.get(); + } + ephemeris_orbital_params_r17_s& orbital_params() + { + assert_choice_type(types::orbital_params, type_, "ephemerisInfo-r17"); + return c.get(); + } + const ephemeris_state_vectors_r17_s& state_vectors() const + { + assert_choice_type(types::state_vectors, type_, "ephemerisInfo-r17"); + return c.get(); + } + const ephemeris_orbital_params_r17_s& orbital_params() const + { + assert_choice_type(types::orbital_params, type_, "ephemerisInfo-r17"); + return c.get(); + } + ephemeris_state_vectors_r17_s& set_state_vectors(); + ephemeris_orbital_params_r17_s& set_orbital_params(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + struct nta_common_params_minus17_s_ { + bool nta_common_r17_present = false; + bool nta_common_drift_r17_present = false; + bool nta_common_drift_variation_r17_present = false; + uint32_t nta_common_r17 = 0; + int32_t nta_common_drift_r17 = -261935; + uint16_t nta_common_drift_variation_r17 = 0; + }; + struct ul_sync_validity_dur_r17_opts { + enum options { s5, s10, s15, s20, s25, s30, s35, s40, s45, s50, s55, s60, s120, s180, s240, s900, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated ul_sync_validity_dur_r17_e_; + struct epoch_time_r17_s_ { + uint16_t start_sfn_r17 = 0; + uint8_t start_sub_frame_r17 = 0; + }; + + // member variables + bool ext = false; + bool epoch_time_r17_present = false; + bool k_mac_r17_present = false; + ephemeris_info_r17_c_ ephemeris_info_r17; + nta_common_params_minus17_s_ nta_common_params_minus17; + ul_sync_validity_dur_r17_e_ ul_sync_validity_dur_r17; + epoch_time_r17_s_ epoch_time_r17; + uint16_t k_offset_r17 = 0; + uint16_t k_mac_r17 = 1; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // UAC-AC1-SelectAssistInfo-r15 ::= ENUMERATED struct uac_ac1_select_assist_info_r15_opts { enum options { a, b, c, nulltype } value; @@ -1941,9 +2593,20 @@ struct uac_ac1_select_assist_info_r15_opts { }; typedef enumerated uac_ac1_select_assist_info_r15_e; +// UAC-AC1-SelectAssistInfo-r16 ::= ENUMERATED +struct uac_ac1_select_assist_info_r16_opts { + enum options { a, b, c, not_cfgured, nulltype } value; + + const char* to_string() const; +}; +typedef enumerated uac_ac1_select_assist_info_r16_e; + // UAC-BarringInfoSetList-r15 ::= SEQUENCE (SIZE (1..8)) OF UAC-BarringInfoSet-r15 using uac_barr_info_set_list_r15_l = dyn_array; +// UAC-BarringInfoSetList-v1700 ::= SEQUENCE (SIZE (1..8)) OF UAC-BarringInfoSet-v1700 +using uac_barr_info_set_list_v1700_l = dyn_array; + // UAC-BarringPerPLMN-List-r15 ::= SEQUENCE (SIZE (1..6)) OF UAC-BarringPerPLMN-r15 using uac_barr_per_plmn_list_r15_l = dyn_array; @@ -2060,9 +2723,10 @@ struct sib_type13_r9_s { // ... // group 0 copy_ptr notif_cfg_v1430; - - bool mbsfn_area_info_list_r16_present = false; - mbsfn_area_info_list_r16_l mbsfn_area_info_list_r16; + // group 1 + copy_ptr mbsfn_area_info_list_r16; + // group 2 + copy_ptr mbsfn_area_info_list_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2504,6 +3168,8 @@ struct sib_type21_r14_s { sl_v2x_cfg_common_r14_s sl_v2x_cfg_common_r14; dyn_octstring late_non_crit_ext; // ... + // group 0 + copy_ptr anchor_carrier_freq_list_nr_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2522,6 +3188,12 @@ struct sib_type24_r15_s { speed_state_scale_factors_s t_resel_nr_sf_r15; dyn_octstring late_non_crit_ext; // ... + // group 0 + copy_ptr carrier_freq_list_nr_v1610; + // group 1 + copy_ptr carrier_freq_list_nr_v1700; + // group 2 + copy_ptr carrier_freq_list_nr_v1720; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2580,6 +3252,15 @@ struct sib_type25_r15_s { void destroy_(); }; + struct ab_per_rsrp_r16_opts { + enum options { thresh0, thresh1, thresh2, thresh3, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated ab_per_rsrp_r16_e_; + using uac_ac1_select_assist_info_r16_l_ = bounded_array; // member variables bool ext = false; @@ -2593,6 +3274,13 @@ struct sib_type25_r15_s { uac_ac1_select_assist_info_r15_c_ uac_ac1_select_assist_info_r15; dyn_octstring late_non_crit_ext; // ... + // group 0 + bool ab_per_rsrp_r16_present = false; + ab_per_rsrp_r16_e_ ab_per_rsrp_r16; + // group 1 + copy_ptr uac_ac1_select_assist_info_r16; + // group 2 + copy_ptr uac_barr_info_set_list_v1700; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2626,6 +3314,77 @@ struct sib_type26_r15_s { void to_json(json_writer& j) const; }; +// SystemInformationBlockType26a-r16 ::= SEQUENCE +struct sib_type26a_r16_s { + bool ext = false; + bool late_non_crit_ext_present = false; + plmn_info_list_r16_l plmn_info_list_r16; + band_list_endc_r16_l band_list_endc_r16; + dyn_octstring late_non_crit_ext; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SystemInformationBlockType27-r16 ::= SEQUENCE +struct sib_type27_r16_s { + bool ext = false; + bool carrier_freq_list_nbiot_r16_present = false; + bool late_non_crit_ext_present = false; + carrier_freq_list_nbiot_r16_l carrier_freq_list_nbiot_r16; + dyn_octstring late_non_crit_ext; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SystemInformationBlockType28-r16 ::= SEQUENCE +struct sib_type28_r16_s { + struct segment_type_r16_opts { + enum options { not_last_segment, last_segment, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated segment_type_r16_e_; + + // member variables + bool ext = false; + bool late_non_crit_ext_present = false; + uint8_t segment_num_r16 = 0; + segment_type_r16_e_ segment_type_r16; + dyn_octstring segment_container_r16; + dyn_octstring late_non_crit_ext; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SystemInformationBlockType29-r16 ::= SEQUENCE +struct sib_type29_r16_s { + bool ext = false; + bool res_reserv_cfg_common_dl_r16_present = false; + bool res_reserv_cfg_common_ul_r16_present = false; + bool late_non_crit_ext_present = false; + res_reserv_cfg_dl_r16_s res_reserv_cfg_common_dl_r16; + res_reserv_cfg_ul_r16_s res_reserv_cfg_common_ul_r16; + dyn_octstring late_non_crit_ext; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SystemInformationBlockType3 ::= SEQUENCE struct sib_type3_s { struct cell_resel_info_common_s_ { @@ -2755,6 +3514,61 @@ struct sib_type3_s { bool crs_intf_mitig_neigh_cells_ce_r15_present = false; copy_ptr cell_resel_info_hsdn_r15; copy_ptr cell_sel_info_ce_v1530; + // group 8 + copy_ptr cell_resel_serving_freq_info_v1610; + // group 9 + bool t_service_r17_present = false; + uint32_t t_service_r17 = 0; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SystemInformationBlockType30-r17 ::= SEQUENCE +struct sib_type30_r17_s { + using common_plmns_with_disaster_condition_r17_l_ = dyn_array; + using applicable_disaster_info_list_r17_l_ = dyn_array; + + // member variables + bool ext = false; + bool common_plmns_with_disaster_condition_r17_present = false; + bool applicable_disaster_info_list_r17_present = false; + bool late_non_crit_ext_present = false; + common_plmns_with_disaster_condition_r17_l_ common_plmns_with_disaster_condition_r17; + applicable_disaster_info_list_r17_l_ applicable_disaster_info_list_r17; + dyn_octstring late_non_crit_ext; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SystemInformationBlockType31-r17 ::= SEQUENCE +struct sib_type31_r17_s { + bool ext = false; + bool late_non_crit_ext_present = false; + serving_satellite_info_r17_s serving_satellite_info_r17; + dyn_octstring late_non_crit_ext; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SystemInformationBlockType32-r17 ::= SEQUENCE +struct sib_type32_r17_s { + bool ext = false; + bool satellite_info_list_r17_present = false; + bool late_non_crit_ext_present = false; + satellite_info_list_r17_l satellite_info_list_r17; + dyn_octstring late_non_crit_ext; + // ... // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2764,18 +3578,21 @@ struct sib_type3_s { // SystemInformationBlockType4 ::= SEQUENCE struct sib_type4_s { - bool ext = false; - bool intra_freq_neigh_cell_list_present = false; - bool intra_freq_black_cell_list_present = false; - bool csg_pci_range_present = false; - intra_freq_neigh_cell_list_l intra_freq_neigh_cell_list; - intra_freq_black_cell_list_l intra_freq_black_cell_list; - pci_range_s csg_pci_range; + bool ext = false; + bool intra_freq_neigh_cell_list_present = false; + bool intra_freq_excluded_cell_list_present = false; + bool csg_pci_range_present = false; + intra_freq_neigh_cell_list_l intra_freq_neigh_cell_list; + intra_freq_excluded_cell_list_l intra_freq_excluded_cell_list; + pci_range_s csg_pci_range; // ... bool late_non_crit_ext_present = false; dyn_octstring late_non_crit_ext; // group 0 copy_ptr intra_freq_neigh_hsdn_cell_list_r15; + // group 1 + copy_ptr rss_cfg_carrier_info_r16; + copy_ptr intra_freq_neigh_cell_list_v1610; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2810,6 +3627,10 @@ struct sib_type5_s { copy_ptr inter_freq_carrier_freq_list_v1530; copy_ptr inter_freq_carrier_freq_list_ext_v1530; copy_ptr meas_idle_cfg_sib_r15; + // group 7 + copy_ptr inter_freq_carrier_freq_list_v1610; + copy_ptr inter_freq_carrier_freq_list_ext_v1610; + copy_ptr meas_idle_cfg_sib_nr_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2959,12 +3780,23 @@ struct pos_sys_info_r15_ies_s { pos_sib2_minus19_r15, pos_sib3_minus1_r15, // ... + pos_sib1_minus8_v1610, + pos_sib2_minus20_v1610, + pos_sib2_minus21_v1610, + pos_sib2_minus22_v1610, + pos_sib2_minus23_v1610, + pos_sib2_minus24_v1610, + pos_sib2_minus25_v1610, + pos_sib4_minus1_v1610, + pos_sib5_minus1_v1610, + pos_sib1_minus9_v1700, + pos_sib1_minus10_v1700, nulltype } value; const char* to_string() const; }; - typedef enumerated types; + typedef enumerated types; // choice methods pos_sib_type_and_info_r15_item_c_() = default; @@ -3112,6 +3944,61 @@ struct pos_sys_info_r15_ies_s { assert_choice_type(types::pos_sib3_minus1_r15, type_, "posSIB-TypeAndInfo-r15-item"); return c.get(); } + sib_pos_r15_s& pos_sib1_minus8_v1610() + { + assert_choice_type(types::pos_sib1_minus8_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + sib_pos_r15_s& pos_sib2_minus20_v1610() + { + assert_choice_type(types::pos_sib2_minus20_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + sib_pos_r15_s& pos_sib2_minus21_v1610() + { + assert_choice_type(types::pos_sib2_minus21_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + sib_pos_r15_s& pos_sib2_minus22_v1610() + { + assert_choice_type(types::pos_sib2_minus22_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + sib_pos_r15_s& pos_sib2_minus23_v1610() + { + assert_choice_type(types::pos_sib2_minus23_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + sib_pos_r15_s& pos_sib2_minus24_v1610() + { + assert_choice_type(types::pos_sib2_minus24_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + sib_pos_r15_s& pos_sib2_minus25_v1610() + { + assert_choice_type(types::pos_sib2_minus25_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + sib_pos_r15_s& pos_sib4_minus1_v1610() + { + assert_choice_type(types::pos_sib4_minus1_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + sib_pos_r15_s& pos_sib5_minus1_v1610() + { + assert_choice_type(types::pos_sib5_minus1_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + sib_pos_r15_s& pos_sib1_minus9_v1700() + { + assert_choice_type(types::pos_sib1_minus9_v1700, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + sib_pos_r15_s& pos_sib1_minus10_v1700() + { + assert_choice_type(types::pos_sib1_minus10_v1700, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } const sib_pos_r15_s& pos_sib1_minus1_r15() const { assert_choice_type(types::pos_sib1_minus1_r15, type_, "posSIB-TypeAndInfo-r15-item"); @@ -3247,6 +4134,61 @@ struct pos_sys_info_r15_ies_s { assert_choice_type(types::pos_sib3_minus1_r15, type_, "posSIB-TypeAndInfo-r15-item"); return c.get(); } + const sib_pos_r15_s& pos_sib1_minus8_v1610() const + { + assert_choice_type(types::pos_sib1_minus8_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + const sib_pos_r15_s& pos_sib2_minus20_v1610() const + { + assert_choice_type(types::pos_sib2_minus20_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + const sib_pos_r15_s& pos_sib2_minus21_v1610() const + { + assert_choice_type(types::pos_sib2_minus21_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + const sib_pos_r15_s& pos_sib2_minus22_v1610() const + { + assert_choice_type(types::pos_sib2_minus22_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + const sib_pos_r15_s& pos_sib2_minus23_v1610() const + { + assert_choice_type(types::pos_sib2_minus23_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + const sib_pos_r15_s& pos_sib2_minus24_v1610() const + { + assert_choice_type(types::pos_sib2_minus24_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + const sib_pos_r15_s& pos_sib2_minus25_v1610() const + { + assert_choice_type(types::pos_sib2_minus25_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + const sib_pos_r15_s& pos_sib4_minus1_v1610() const + { + assert_choice_type(types::pos_sib4_minus1_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + const sib_pos_r15_s& pos_sib5_minus1_v1610() const + { + assert_choice_type(types::pos_sib5_minus1_v1610, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + const sib_pos_r15_s& pos_sib1_minus9_v1700() const + { + assert_choice_type(types::pos_sib1_minus9_v1700, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } + const sib_pos_r15_s& pos_sib1_minus10_v1700() const + { + assert_choice_type(types::pos_sib1_minus10_v1700, type_, "posSIB-TypeAndInfo-r15-item"); + return c.get(); + } sib_pos_r15_s& set_pos_sib1_minus1_r15(); sib_pos_r15_s& set_pos_sib1_minus2_r15(); sib_pos_r15_s& set_pos_sib1_minus3_r15(); @@ -3274,6 +4216,17 @@ struct pos_sys_info_r15_ies_s { sib_pos_r15_s& set_pos_sib2_minus18_r15(); sib_pos_r15_s& set_pos_sib2_minus19_r15(); sib_pos_r15_s& set_pos_sib3_minus1_r15(); + sib_pos_r15_s& set_pos_sib1_minus8_v1610(); + sib_pos_r15_s& set_pos_sib2_minus20_v1610(); + sib_pos_r15_s& set_pos_sib2_minus21_v1610(); + sib_pos_r15_s& set_pos_sib2_minus22_v1610(); + sib_pos_r15_s& set_pos_sib2_minus23_v1610(); + sib_pos_r15_s& set_pos_sib2_minus24_v1610(); + sib_pos_r15_s& set_pos_sib2_minus25_v1610(); + sib_pos_r15_s& set_pos_sib4_minus1_v1610(); + sib_pos_r15_s& set_pos_sib5_minus1_v1610(); + sib_pos_r15_s& set_pos_sib1_minus9_v1700(); + sib_pos_r15_s& set_pos_sib1_minus10_v1700(); private: types type_; @@ -3322,14 +4275,19 @@ struct sib_info_item_c { sib24_v1530, sib25_v1530, sib26_v1530, + sib26a_v1610, + sib27_v1610, + sib28_v1610, + sib29_v1610, + sib30_v1700, + sib31_v1700, + sib32_v1700, nulltype } value; - typedef uint8_t number_type; const char* to_string() const; - uint8_t to_number() const; }; - typedef enumerated types; + typedef enumerated types; // choice methods sib_info_item_c() = default; @@ -3457,6 +4415,41 @@ struct sib_info_item_c { assert_choice_type(types::sib26_v1530, type_, "sib-TypeAndInfo-item"); return c.get(); } + sib_type26a_r16_s& sib26a_v1610() + { + assert_choice_type(types::sib26a_v1610, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + sib_type27_r16_s& sib27_v1610() + { + assert_choice_type(types::sib27_v1610, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + sib_type28_r16_s& sib28_v1610() + { + assert_choice_type(types::sib28_v1610, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + sib_type29_r16_s& sib29_v1610() + { + assert_choice_type(types::sib29_v1610, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + sib_type30_r17_s& sib30_v1700() + { + assert_choice_type(types::sib30_v1700, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + sib_type31_r17_s& sib31_v1700() + { + assert_choice_type(types::sib31_v1700, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + sib_type32_r17_s& sib32_v1700() + { + assert_choice_type(types::sib32_v1700, type_, "sib-TypeAndInfo-item"); + return c.get(); + } const sib_type2_s& sib2() const { assert_choice_type(types::sib2, type_, "sib-TypeAndInfo-item"); @@ -3572,29 +4565,71 @@ struct sib_info_item_c { assert_choice_type(types::sib26_v1530, type_, "sib-TypeAndInfo-item"); return c.get(); } - sib_type2_s& set_sib2(); - sib_type3_s& set_sib3(); - sib_type4_s& set_sib4(); - sib_type5_s& set_sib5(); - sib_type6_s& set_sib6(); - sib_type7_s& set_sib7(); - sib_type8_s& set_sib8(); - sib_type9_s& set_sib9(); - sib_type10_s& set_sib10(); - sib_type11_s& set_sib11(); - sib_type12_r9_s& set_sib12_v920(); - sib_type13_r9_s& set_sib13_v920(); - sib_type14_r11_s& set_sib14_v1130(); - sib_type15_r11_s& set_sib15_v1130(); - sib_type16_r11_s& set_sib16_v1130(); - sib_type17_r12_s& set_sib17_v1250(); - sib_type18_r12_s& set_sib18_v1250(); - sib_type19_r12_s& set_sib19_v1250(); - sib_type20_r13_s& set_sib20_v1310(); - sib_type21_r14_s& set_sib21_v1430(); - sib_type24_r15_s& set_sib24_v1530(); - sib_type25_r15_s& set_sib25_v1530(); - sib_type26_r15_s& set_sib26_v1530(); + const sib_type26a_r16_s& sib26a_v1610() const + { + assert_choice_type(types::sib26a_v1610, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + const sib_type27_r16_s& sib27_v1610() const + { + assert_choice_type(types::sib27_v1610, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + const sib_type28_r16_s& sib28_v1610() const + { + assert_choice_type(types::sib28_v1610, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + const sib_type29_r16_s& sib29_v1610() const + { + assert_choice_type(types::sib29_v1610, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + const sib_type30_r17_s& sib30_v1700() const + { + assert_choice_type(types::sib30_v1700, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + const sib_type31_r17_s& sib31_v1700() const + { + assert_choice_type(types::sib31_v1700, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + const sib_type32_r17_s& sib32_v1700() const + { + assert_choice_type(types::sib32_v1700, type_, "sib-TypeAndInfo-item"); + return c.get(); + } + sib_type2_s& set_sib2(); + sib_type3_s& set_sib3(); + sib_type4_s& set_sib4(); + sib_type5_s& set_sib5(); + sib_type6_s& set_sib6(); + sib_type7_s& set_sib7(); + sib_type8_s& set_sib8(); + sib_type9_s& set_sib9(); + sib_type10_s& set_sib10(); + sib_type11_s& set_sib11(); + sib_type12_r9_s& set_sib12_v920(); + sib_type13_r9_s& set_sib13_v920(); + sib_type14_r11_s& set_sib14_v1130(); + sib_type15_r11_s& set_sib15_v1130(); + sib_type16_r11_s& set_sib16_v1130(); + sib_type17_r12_s& set_sib17_v1250(); + sib_type18_r12_s& set_sib18_v1250(); + sib_type19_r12_s& set_sib19_v1250(); + sib_type20_r13_s& set_sib20_v1310(); + sib_type21_r14_s& set_sib21_v1430(); + sib_type24_r15_s& set_sib24_v1530(); + sib_type25_r15_s& set_sib25_v1530(); + sib_type26_r15_s& set_sib26_v1530(); + sib_type26a_r16_s& set_sib26a_v1610(); + sib_type27_r16_s& set_sib27_v1610(); + sib_type28_r16_s& set_sib28_v1610(); + sib_type29_r16_s& set_sib29_v1610(); + sib_type30_r17_s& set_sib30_v1700(); + sib_type31_r17_s& set_sib31_v1700(); + sib_type32_r17_s& set_sib32_v1700(); private: types type_; @@ -3613,7 +4648,14 @@ struct sib_info_item_c { sib_type24_r15_s, sib_type25_r15_s, sib_type26_r15_s, + sib_type26a_r16_s, + sib_type27_r16_s, + sib_type28_r16_s, + sib_type29_r16_s, sib_type2_s, + sib_type30_r17_s, + sib_type31_r17_s, + sib_type32_r17_s, sib_type3_s, sib_type4_s, sib_type5_s, @@ -4143,23 +5185,21 @@ struct sib_type_v12j0_opts { sib_type24_v1530, sib_type25_v1530, sib_type26_v1530, - spare10, - spare9, - spare8, - spare7, - spare6, - spare5, - spare4, + sib_type26a_v1610, + sib_type27_v1610, + sib_type28_v1610, + sib_type29_v1610, + sib_type30_v1700, + sib_type31_v1700, + sib_type32_v1700, spare3, spare2, spare1, // ... nulltype } value; - typedef uint8_t number_type; const char* to_string() const; - uint8_t to_number() const; }; typedef enumerated sib_type_v12j0_e; @@ -4194,6 +5234,23 @@ using sched_info_list_v12j0_l = dyn_array; // SchedulingInfoListExt-r12 ::= SEQUENCE (SIZE (1..32)) OF SchedulingInfoExt-r12 using sched_info_list_ext_r12_l = dyn_array; +// SystemInformationBlockType1-v15g0-IEs ::= SEQUENCE +struct sib_type1_v15g0_ies_s { + struct bw_reduced_access_related_info_v15g0_s_ { + sched_info_list_br_r13_l pos_sched_info_list_br_r15; + }; + + // member variables + bool bw_reduced_access_related_info_v15g0_present = false; + bool non_crit_ext_present = false; + bw_reduced_access_related_info_v15g0_s_ bw_reduced_access_related_info_v15g0; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SystemInformationBlockType1-v12j0-IEs ::= SEQUENCE struct sib_type1_v12j0_ies_s { bool sched_info_list_v12j0_present = false; @@ -4201,6 +5258,7 @@ struct sib_type1_v12j0_ies_s { bool non_crit_ext_present = false; sched_info_list_v12j0_l sched_info_list_v12j0; sched_info_list_ext_r12_l sched_info_list_ext_r12; + sib_type1_v15g0_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; diff --git a/lib/include/srsran/asn1/rrc/common.h b/lib/include/srsran/asn1/rrc/common.h index c8dd034e7f..f3f47903aa 100644 --- a/lib/include/srsran/asn1/rrc/common.h +++ b/lib/include/srsran/asn1/rrc/common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -42,11 +42,14 @@ namespace rrc { #define ASN1_RRC_MAX_ACCESS_CAT_MINUS1_R15 63 #define ASN1_RRC_MAX_ACDC_CAT_R13 16 #define ASN1_RRC_MAX_AVAIL_NARROW_BANDS_R13 16 +#define ASN1_RRC_MAX_AVAIL_NARROW_BANDS_MINUS1_R16 15 #define ASN1_RRC_MAX_BAND_COMB_R10 128 #define ASN1_RRC_MAX_BAND_COMB_R11 256 #define ASN1_RRC_MAX_BAND_COMB_R13 384 +#define ASN1_RRC_MAX_BAND_COMB_SIDELINK_NR_R16 512 #define ASN1_RRC_MAX_BANDS 64 #define ASN1_RRC_MAX_BANDS_NR_R15 1024 +#define ASN1_RRC_MAX_BANDS_ENDC_R16 10 #define ASN1_RRC_MAX_BW_CLASS_R10 16 #define ASN1_RRC_MAX_BW_COMB_SET_R10 32 #define ASN1_RRC_MAX_BARR_INFO_SET_R15 8 @@ -57,11 +60,12 @@ namespace rrc { #define ASN1_RRC_MAX_CBR_REPORT_R14 72 #define ASN1_RRC_MAX_CDMA_BAND_CLASS 32 #define ASN1_RRC_MAX_CE_LEVEL_R13 4 -#define ASN1_RRC_MAX_CELL_BLACK 16 +#define ASN1_RRC_MAX_EXCLUDED_CELL 16 #define ASN1_RRC_MAX_CELL_HISTORY_R12 16 #define ASN1_RRC_MAX_CELL_INFO_GERAN_R9 32 #define ASN1_RRC_MAX_CELL_INFO_UTRA_R9 16 #define ASN1_RRC_MAX_CELL_MEAS_IDLE_R15 8 +#define ASN1_RRC_MAX_CELL_NR_R17 8 #define ASN1_RRC_MAX_COMB_IDC_R11 128 #define ASN1_RRC_MAX_CSI_IM_R11 3 #define ASN1_RRC_MAX_CSI_IM_R12 4 @@ -82,6 +86,8 @@ namespace rrc { #define ASN1_RRC_MAX_CELL_MEAS 32 #define ASN1_RRC_MAX_CELL_REPORT 8 #define ASN1_RRC_MAX_CELL_SFTD 3 +#define ASN1_RRC_MAX_CELL_ALLOWED_NR_R16 16 +#define ASN1_RRC_MAX_COND_CFG_R16 8 #define ASN1_RRC_MAX_CFG_SPS_R14 8 #define ASN1_RRC_MAX_CFG_SPS_R15 6 #define ASN1_RRC_MAX_CSI_RS_MEAS_R12 96 @@ -101,15 +107,23 @@ namespace rrc { #define ASN1_RRC_MAX_FEATURE_SETS_R15 256 #define ASN1_RRC_MAX_PER_CC_FEATURE_SETS_R15 32 #define ASN1_RRC_MAX_FREQ 8 +#define ASN1_RRC_MAX_FREQ_MINUS1_R16 7 #define ASN1_RRC_MAX_FREQ_IDC_R11 32 #define ASN1_RRC_MAX_FREQ_IDLE_R15 8 #define ASN1_RRC_MAX_FREQ_MBMS_R11 5 +#define ASN1_RRC_MAX_FREQ_NBIOT_R16 8 #define ASN1_RRC_MAX_FREQ_NR_R15 5 +#define ASN1_RRC_MAX_FREQ_SL_NR_R16 8 #define ASN1_RRC_MAX_FREQ_V2X_R14 8 #define ASN1_RRC_MAX_FREQ_V2X_MINUS1_R14 7 #define ASN1_RRC_MAX_GERAN_SI 10 #define ASN1_RRC_MAX_GNFG 16 +#define ASN1_RRC_MAX_GWUS_GROUPS_MINUS1_R16 31 +#define ASN1_RRC_MAX_GWUS_RES_R16 4 +#define ASN1_RRC_MAX_GWUS_PROB_THRESS_R16 3 #define ASN1_RRC_MAX_IDLE_MEAS_CARRIERS_R15 3 +#define ASN1_RRC_MAX_IDLE_MEAS_CARRIERS_EXT_R16 5 +#define ASN1_RRC_MAX_IDLE_MEAS_CARRIERS_R16 8 #define ASN1_RRC_MAX_LCG_R13 4 #define ASN1_RRC_MAX_LOG_MEAS_REPORT_R10 520 #define ASN1_RRC_MAX_MBSFN_ALLOCS 8 @@ -126,6 +140,7 @@ namespace rrc { #define ASN1_RRC_MAX_NAICS_ENTRIES_R12 8 #define ASN1_RRC_MAX_NEIGH_CELL_R12 8 #define ASN1_RRC_MAX_NEIGH_CELL_SCPTM_R13 8 +#define ASN1_RRC_MAX_NROF_PCI_PER_SMTC_R16 64 #define ASN1_RRC_MAX_NROF_S_NSSAI_R15 8 #define ASN1_RRC_MAX_OBJ_ID 32 #define ASN1_RRC_MAX_OBJ_ID_PLUS1_R13 33 @@ -152,6 +167,7 @@ namespace rrc { #define ASN1_RRC_MAX_RS_IDX_REPORT_R15 32 #define ASN1_RRC_MAX_RSTD_FREQ_R10 3 #define ASN1_RRC_MAX_SAI_MBMS_R11 64 +#define ASN1_RRC_MAX_SAT_R17 4 #define ASN1_RRC_MAX_SCELL_R10 4 #define ASN1_RRC_MAX_SCELL_R13 31 #define ASN1_RRC_MAX_SCELL_GROUPS_R15 4 @@ -203,6 +219,7 @@ namespace rrc { #define ASN1_RRC_MAX_SI_MSG 32 #define ASN1_RRC_MAX_SIMUL_BANDS_R10 64 #define ASN1_RRC_MAX_SF_PATTERN_IDC_R11 8 +#define ASN1_RRC_MAX_TAC_R17 12 #define ASN1_RRC_MAX_TRAFFIC_PATTERN_R14 8 #define ASN1_RRC_MAX_UTRA_FDD_CARRIER 16 #define ASN1_RRC_MAX_UTRA_TDD_CARRIER 16 @@ -216,6 +233,12 @@ namespace rrc { #define ASN1_RRC_MAX_WLAN_NAME_R15 4 #define ASN1_RRC_MAX_LOG_MEAS_R10 4060 #define ASN1_RRC_MAX_REESTAB_INFO 32 +#define ASN1_RRC_MAX_FREQ_ANR_NB_R16 2 +#define ASN1_RRC_MAX_FREQ_EUTRA_NB_R16 8 +#define ASN1_RRC_MAX_FREQS_GERAN_NB_R16 8 +#define ASN1_RRC_MAX_GWUS_GROUPS_MINUS1_NB_R16 15 +#define ASN1_RRC_MAX_GWUS_RES_NB_R16 2 +#define ASN1_RRC_MAX_GWUS_PROB_THRESS_NB_R16 3 #define ASN1_RRC_MAX_NPRACH_RES_NB_R13 3 #define ASN1_RRC_MAX_NON_ANCHOR_CARRIERS_NB_R14 15 #define ASN1_RRC_MAX_DRB_NB_R13 2 @@ -223,6 +246,7 @@ namespace rrc { #define ASN1_RRC_MAX_NS_PMAX_NB_R13 4 #define ASN1_RRC_MAX_SC_MTCH_NB_R14 64 #define ASN1_RRC_MAX_SI_MSG_NB_R13 8 +#define ASN1_RRC_MAX_TAC_NB_R17 12 /******************************************************************************* * Struct Definitions diff --git a/lib/include/srsran/asn1/rrc/common_ext.h b/lib/include/srsran/asn1/rrc/common_ext.h index fb44490e19..bb40ec1be7 100644 --- a/lib/include/srsran/asn1/rrc/common_ext.h +++ b/lib/include/srsran/asn1/rrc/common_ext.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ diff --git a/lib/include/srsran/asn1/rrc/dl_ccch_msg.h b/lib/include/srsran/asn1/rrc/dl_ccch_msg.h index 7ac072608e..3df35f7e23 100644 --- a/lib/include/srsran/asn1/rrc/dl_ccch_msg.h +++ b/lib/include/srsran/asn1/rrc/dl_ccch_msg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -242,6 +242,18 @@ struct rrc_conn_reject_v1020_ies_s { void to_json(json_writer& j) const; }; +// RRCConnectionSetup-v1610-IEs ::= SEQUENCE +struct rrc_conn_setup_v1610_ies_s { + bool ded_info_nas_r16_present = false; + bool non_crit_ext_present = false; + dyn_octstring ded_info_nas_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // IdleModeMobilityControlInfo ::= SEQUENCE struct idle_mode_mob_ctrl_info_s { struct t320_opts { @@ -336,9 +348,10 @@ struct rrc_conn_reject_v8a0_ies_s { // RRCConnectionSetup-v8a0-IEs ::= SEQUENCE struct rrc_conn_setup_v8a0_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - dyn_octstring late_non_crit_ext; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + dyn_octstring late_non_crit_ext; + rrc_conn_setup_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -361,15 +374,7 @@ struct rrc_early_data_complete_v1590_ies_s { // RedirectedCarrierInfo-r15-IEs ::= CHOICE struct redirected_carrier_info_r15_ies_c { struct types_opts { - enum options { - eutra_r15, - geran_r15, - utra_fdd_r15, - cdma2000_hrpd_r15, - cdma2000_minus1x_rtt_r15, - utra_tdd_r15, - nulltype - } value; + enum options { eutra, geran, utra_fdd, cdma2000_hrpd, cdma2000_minus1x_rtt, utra_tdd, nulltype } value; const char* to_string() const; }; @@ -386,72 +391,72 @@ struct redirected_carrier_info_r15_ies_c { SRSASN_CODE unpack(cbit_ref& bref); void to_json(json_writer& j) const; // getters - uint32_t& eutra_r15() + uint32_t& eutra() { - assert_choice_type(types::eutra_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::eutra, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - carrier_freqs_geran_s& geran_r15() + carrier_freqs_geran_s& geran() { - assert_choice_type(types::geran_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::geran, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - uint16_t& utra_fdd_r15() + uint16_t& utra_fdd() { - assert_choice_type(types::utra_fdd_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::utra_fdd, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - carrier_freq_cdma2000_s& cdma2000_hrpd_r15() + carrier_freq_cdma2000_s& cdma2000_hrpd() { - assert_choice_type(types::cdma2000_hrpd_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::cdma2000_hrpd, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - carrier_freq_cdma2000_s& cdma2000_minus1x_rtt_r15() + carrier_freq_cdma2000_s& cdma2000_minus1x_rtt() { - assert_choice_type(types::cdma2000_minus1x_rtt_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::cdma2000_minus1x_rtt, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - carrier_freq_list_utra_tdd_r10_l& utra_tdd_r15() + carrier_freq_list_utra_tdd_r10_l& utra_tdd() { - assert_choice_type(types::utra_tdd_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::utra_tdd, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - const uint32_t& eutra_r15() const + const uint32_t& eutra() const { - assert_choice_type(types::eutra_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::eutra, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - const carrier_freqs_geran_s& geran_r15() const + const carrier_freqs_geran_s& geran() const { - assert_choice_type(types::geran_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::geran, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - const uint16_t& utra_fdd_r15() const + const uint16_t& utra_fdd() const { - assert_choice_type(types::utra_fdd_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::utra_fdd, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - const carrier_freq_cdma2000_s& cdma2000_hrpd_r15() const + const carrier_freq_cdma2000_s& cdma2000_hrpd() const { - assert_choice_type(types::cdma2000_hrpd_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::cdma2000_hrpd, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - const carrier_freq_cdma2000_s& cdma2000_minus1x_rtt_r15() const + const carrier_freq_cdma2000_s& cdma2000_minus1x_rtt() const { - assert_choice_type(types::cdma2000_minus1x_rtt_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::cdma2000_minus1x_rtt, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - const carrier_freq_list_utra_tdd_r10_l& utra_tdd_r15() const + const carrier_freq_list_utra_tdd_r10_l& utra_tdd() const { - assert_choice_type(types::utra_tdd_r15, type_, "RedirectedCarrierInfo-r15-IEs"); + assert_choice_type(types::utra_tdd, type_, "RedirectedCarrierInfo-r15-IEs"); return c.get(); } - uint32_t& set_eutra_r15(); - carrier_freqs_geran_s& set_geran_r15(); - uint16_t& set_utra_fdd_r15(); - carrier_freq_cdma2000_s& set_cdma2000_hrpd_r15(); - carrier_freq_cdma2000_s& set_cdma2000_minus1x_rtt_r15(); - carrier_freq_list_utra_tdd_r10_l& set_utra_tdd_r15(); + uint32_t& set_eutra(); + carrier_freqs_geran_s& set_geran(); + uint16_t& set_utra_fdd(); + carrier_freq_cdma2000_s& set_cdma2000_hrpd(); + carrier_freq_cdma2000_s& set_cdma2000_minus1x_rtt(); + carrier_freq_list_utra_tdd_r10_l& set_utra_tdd(); private: types type_; diff --git a/lib/include/srsran/asn1/rrc/dl_dcch_msg.h b/lib/include/srsran/asn1/rrc/dl_dcch_msg.h index fb29422de2..3568090a1c 100644 --- a/lib/include/srsran/asn1/rrc/dl_dcch_msg.h +++ b/lib/include/srsran/asn1/rrc/dl_dcch_msg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,13 +21,14 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ #ifndef SRSASN1_RRC_DLDCCH_MSG_H #define SRSASN1_RRC_DLDCCH_MSG_H +#include "bcch_msg.h" #include "dl_ccch_msg.h" #include "security.h" #include "si.h" @@ -40,6 +41,34 @@ namespace rrc { * Struct Definitions ******************************************************************************/ +// CondReconfigurationAddMod-r16 ::= SEQUENCE +struct cond_recfg_add_mod_r16_s { + using trigger_condition_r16_l_ = bounded_array; + + // member variables + bool ext = false; + bool trigger_condition_r16_present = false; + bool cond_recfg_to_apply_r16_present = false; + uint8_t cond_recfg_id_r16 = 1; + trigger_condition_r16_l_ trigger_condition_r16; + dyn_octstring cond_recfg_to_apply_r16; + // ... + // group 0 + bool trigger_condition_sn_r17_present = false; + dyn_octstring trigger_condition_sn_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CondReconfigurationToAddModList-r16 ::= SEQUENCE (SIZE (1..8)) OF CondReconfigurationAddMod-r16 +using cond_recfg_to_add_mod_list_r16_l = dyn_array; + +// CondReconfigurationToRemoveList-r16 ::= SEQUENCE (SIZE (1..8)) OF INTEGER (1..8) +using cond_recfg_to_rem_list_r16_l = bounded_array; + // SCellConfigCommon-r15 ::= SEQUENCE struct scell_cfg_common_r15_s { bool rr_cfg_common_scell_r15_present = false; @@ -82,6 +111,73 @@ struct sl_tf_idx_pair_r12b_s { void to_json(json_writer& j) const; }; +// SubframeAssignment-r15 ::= ENUMERATED +struct sf_assign_r15_opts { + enum options { sa0, sa1, sa2, sa3, sa4, sa5, sa6, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated sf_assign_r15_e; + +// ConditionalReconfiguration-r16 ::= SEQUENCE +struct conditional_recfg_r16_s { + bool ext = false; + bool cond_recfg_to_add_mod_list_r16_present = false; + bool cond_recfg_to_rem_list_r16_present = false; + bool attempt_cond_reconf_r16_present = false; + cond_recfg_to_add_mod_list_r16_l cond_recfg_to_add_mod_list_r16; + cond_recfg_to_rem_list_r16_l cond_recfg_to_rem_list_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionReconfiguration-v1700-IEs ::= SEQUENCE +struct rrc_conn_recfg_v1700_ies_s { + bool sib_type31_ded_r17_present = false; + bool scg_state_r17_present = false; + bool non_crit_ext_present = false; + dyn_octstring sib_type31_ded_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RSRP-ChangeThresh-r16 ::= ENUMERATED +struct rsrp_change_thresh_r16_opts { + enum options { + db4, + db6, + db8, + db10, + db14, + db18, + db22, + db26, + db30, + db34, + spare6, + spare5, + spare4, + spare3, + spare2, + spare1, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated rsrp_change_thresh_r16_e; + // SCellGroupToAddMod-r15 ::= SEQUENCE struct scell_group_to_add_mod_r15_s { bool scell_cfg_common_r15_present = false; @@ -129,6 +225,40 @@ using sl_tf_idx_pair_list_r12b_l = dyn_array; // SL-TxPoolToReleaseList-r12 ::= SEQUENCE (SIZE (1..4)) OF INTEGER (1..4) using sl_tx_pool_to_release_list_r12_l = bounded_array; +// TDM-PatternConfig-r15 ::= CHOICE +struct tdm_pattern_cfg_r15_c { + struct setup_s_ { + sf_assign_r15_e sf_assign_r15; + uint8_t harq_offset_r15 = 0; + }; + using types = setup_e; + + // choice methods + tdm_pattern_cfg_r15_c() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + setup_s_& setup() + { + assert_choice_type(types::setup, type_, "TDM-PatternConfig-r15"); + return c; + } + const setup_s_& setup() const + { + assert_choice_type(types::setup, type_, "TDM-PatternConfig-r15"); + return c; + } + void set_release(); + setup_s_& set_setup(); + +private: + types type_; + setup_s_ c; +}; + // IKE-Identity-r13 ::= SEQUENCE struct ike_id_r13_s { dyn_octstring id_i_r13; @@ -191,6 +321,253 @@ struct ip_address_r13_c { void destroy_(); }; +// PUR-MPDCCH-Config-r16 ::= SEQUENCE +struct pur_mpdcch_cfg_r16_s { + struct mpdcch_prb_pairs_cfg_r16_s_ { + struct num_prb_pairs_r16_opts { + enum options { n2, n4, n6, spare1, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated num_prb_pairs_r16_e_; + + // member variables + num_prb_pairs_r16_e_ num_prb_pairs_r16; + fixed_bitstring<4> res_block_assign_r16; + }; + struct mpdcch_num_repeat_r16_opts { + enum options { r1, r2, r4, r8, r16, r32, r64, r128, r256, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated mpdcch_num_repeat_r16_e_; + struct mpdcch_start_sf_uess_r16_c_ { + struct fdd_opts { + enum options { v1, v1dot5, v2, v2dot5, v4, v5, v8, v10, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated fdd_e_; + struct tdd_opts { + enum options { v1, v2, v4, v5, v8, v10, v20, spare1, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated tdd_e_; + struct types_opts { + enum options { fdd, tdd, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + mpdcch_start_sf_uess_r16_c_() = default; + mpdcch_start_sf_uess_r16_c_(const mpdcch_start_sf_uess_r16_c_& other); + mpdcch_start_sf_uess_r16_c_& operator=(const mpdcch_start_sf_uess_r16_c_& other); + ~mpdcch_start_sf_uess_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fdd_e_& fdd() + { + assert_choice_type(types::fdd, type_, "mpdcch-StartSF-UESS-r16"); + return c.get(); + } + tdd_e_& tdd() + { + assert_choice_type(types::tdd, type_, "mpdcch-StartSF-UESS-r16"); + return c.get(); + } + const fdd_e_& fdd() const + { + assert_choice_type(types::fdd, type_, "mpdcch-StartSF-UESS-r16"); + return c.get(); + } + const tdd_e_& tdd() const + { + assert_choice_type(types::tdd, type_, "mpdcch-StartSF-UESS-r16"); + return c.get(); + } + fdd_e_& set_fdd(); + tdd_e_& set_tdd(); + + private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); + }; + struct mpdcch_offset_pur_ss_r16_opts { + enum options { + zero, + one_eighth, + one_quarter, + three_eighth, + one_half, + five_eighth, + three_quarter, + seven_eighth, + nulltype + } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated mpdcch_offset_pur_ss_r16_e_; + + // member variables + bool mpdcch_freq_hop_r16 = false; + uint8_t mpdcch_nb_r16 = 1; + mpdcch_prb_pairs_cfg_r16_s_ mpdcch_prb_pairs_cfg_r16; + mpdcch_num_repeat_r16_e_ mpdcch_num_repeat_r16; + mpdcch_start_sf_uess_r16_c_ mpdcch_start_sf_uess_r16; + mpdcch_offset_pur_ss_r16_e_ mpdcch_offset_pur_ss_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PUR-PUCCH-Config-r16 ::= SEQUENCE +struct pur_pucch_cfg_r16_s { + struct pucch_num_repeat_ce_format1_r16_opts { + enum options { n1, n2, n4, n8, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated pucch_num_repeat_ce_format1_r16_e_; + + // member variables + bool n1_pucch_an_r16_present = false; + bool pucch_num_repeat_ce_format1_r16_present = false; + uint16_t n1_pucch_an_r16 = 0; + pucch_num_repeat_ce_format1_r16_e_ pucch_num_repeat_ce_format1_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PUR-PUSCH-Config-r16 ::= SEQUENCE +struct pur_pusch_cfg_r16_s { + struct pur_grant_info_r16_c_ { + struct ce_mode_a_s_ { + fixed_bitstring<2> num_rus_r16; + fixed_bitstring<10> prb_alloc_info_r16; + fixed_bitstring<4> mcs_r16; + fixed_bitstring<3> num_repeats_r16; + }; + struct ce_mode_b_s_ { + bool sub_prb_alloc_r16 = false; + bool num_rus_r16 = false; + fixed_bitstring<8> prb_alloc_info_r16; + fixed_bitstring<4> mcs_r16; + fixed_bitstring<3> num_repeats_r16; + }; + struct types_opts { + enum options { ce_mode_a, ce_mode_b, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + pur_grant_info_r16_c_() = default; + pur_grant_info_r16_c_(const pur_grant_info_r16_c_& other); + pur_grant_info_r16_c_& operator=(const pur_grant_info_r16_c_& other); + ~pur_grant_info_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ce_mode_a_s_& ce_mode_a() + { + assert_choice_type(types::ce_mode_a, type_, "pur-GrantInfo-r16"); + return c.get(); + } + ce_mode_b_s_& ce_mode_b() + { + assert_choice_type(types::ce_mode_b, type_, "pur-GrantInfo-r16"); + return c.get(); + } + const ce_mode_a_s_& ce_mode_a() const + { + assert_choice_type(types::ce_mode_a, type_, "pur-GrantInfo-r16"); + return c.get(); + } + const ce_mode_b_s_& ce_mode_b() const + { + assert_choice_type(types::ce_mode_b, type_, "pur-GrantInfo-r16"); + return c.get(); + } + ce_mode_a_s_& set_ce_mode_a(); + ce_mode_b_s_& set_ce_mode_b(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + struct pusch_cyclic_shift_r16_opts { + enum options { n0, n6, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated pusch_cyclic_shift_r16_e_; + + // member variables + bool pur_grant_info_r16_present = false; + bool location_ce_mode_b_r16_present = false; + pur_grant_info_r16_c_ pur_grant_info_r16; + bool pur_pusch_freq_hop_r16 = false; + int8_t p0_ue_pusch_r16 = -8; + alpha_r12_e alpha_r16; + pusch_cyclic_shift_r16_e_ pusch_cyclic_shift_r16; + bool pusch_nb_max_tbs_r16 = false; + uint8_t location_ce_mode_b_r16 = 0; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PUR-RSRP-ChangeThreshold-r16 ::= SEQUENCE +struct pur_rsrp_change_thres_r16_s { + bool decrease_thresh_r16_present = false; + rsrp_change_thresh_r16_e increase_thresh_r16; + rsrp_change_thresh_r16_e decrease_thresh_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PhysicalConfigDedicated-v1370 ::= SEQUENCE struct phys_cfg_ded_v1370_s { bool pucch_cfg_ded_v1370_present = false; @@ -217,6 +594,26 @@ struct ran_area_cfg_r15_s { void to_json(json_writer& j) const; }; +// RRCConnectionReconfiguration-v1610-IEs ::= SEQUENCE +struct rrc_conn_recfg_v1610_ies_s { + bool conditional_recfg_r16_present = false; + bool daps_source_release_r16_present = false; + bool tdm_pattern_cfg2_r16_present = false; + bool sl_cfg_ded_for_nr_r16_present = false; + bool sl_ssb_prio_eutra_r16_present = false; + bool non_crit_ext_present = false; + conditional_recfg_r16_s conditional_recfg_r16; + tdm_pattern_cfg_r15_c tdm_pattern_cfg2_r16; + dyn_octstring sl_cfg_ded_for_nr_r16; + uint8_t sl_ssb_prio_eutra_r16 = 1; + rrc_conn_recfg_v1700_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RadioResourceConfigCommonSCell-v1440 ::= SEQUENCE struct rr_cfg_common_scell_v1440_s { struct ul_cfg_v1440_s_ { @@ -284,16 +681,6 @@ struct sl_tx_pool_to_add_mod_r14_s { void to_json(json_writer& j) const; }; -// SubframeAssignment-r15 ::= ENUMERATED -struct sf_assign_r15_opts { - enum options { sa0, sa1, sa2, sa3, sa4, sa5, sa6, nulltype } value; - typedef uint8_t number_type; - - const char* to_string() const; - uint8_t to_number() const; -}; -typedef enumerated sf_assign_r15_e; - // UplinkPowerControlCommonPSCell-r12 ::= SEQUENCE struct ul_pwr_ctrl_common_ps_cell_r12_s { struct delta_f_pucch_format3_r12_opts { @@ -396,6 +783,94 @@ struct plmn_ran_area_cfg_r15_s { void to_json(json_writer& j) const; }; +// PUR-Config-r16 ::= SEQUENCE +struct pur_cfg_r16_s { + struct pur_implicit_release_after_r16_opts { + enum options { n2, n4, n8, spare, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated pur_implicit_release_after_r16_e_; + struct pur_start_time_params_r16_s_ { + pur_periodicity_and_offset_r16_c periodicity_and_offset_r16; + uint16_t start_sfn_r16 = 0; + uint8_t start_sub_frame_r16 = 0; + fixed_bitstring<1> hsfn_lsb_info_r16; + }; + struct pur_num_occasions_r16_opts { + enum options { one, infinite, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated pur_num_occasions_r16_e_; + struct pur_resp_win_timer_r16_opts { + enum options { sf240, sf480, sf960, sf1920, sf3840, sf5760, sf7680, sf10240, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated pur_resp_win_timer_r16_e_; + + // member variables + bool ext = false; + bool pur_cfg_id_r16_present = false; + bool pur_implicit_release_after_r16_present = false; + bool pur_start_time_params_r16_present = false; + bool pur_rnti_r16_present = false; + bool pur_time_align_timer_r16_present = false; + bool pur_rsrp_change_thres_r16_present = false; + bool pur_resp_win_timer_r16_present = false; + bool pur_mpdcch_cfg_r16_present = false; + bool pur_pucch_cfg_r16_present = false; + bool pur_pusch_cfg_r16_present = false; + fixed_bitstring<20> pur_cfg_id_r16; + pur_implicit_release_after_r16_e_ pur_implicit_release_after_r16; + pur_start_time_params_r16_s_ pur_start_time_params_r16; + pur_num_occasions_r16_e_ pur_num_occasions_r16; + fixed_bitstring<16> pur_rnti_r16; + uint8_t pur_time_align_timer_r16 = 1; + setup_release_c pur_rsrp_change_thres_r16; + pur_resp_win_timer_r16_e_ pur_resp_win_timer_r16; + pur_mpdcch_cfg_r16_s pur_mpdcch_cfg_r16; + bool pur_pdsch_freq_hop_r16 = false; + pur_pucch_cfg_r16_s pur_pucch_cfg_r16; + pur_pusch_cfg_r16_s pur_pusch_cfg_r16; + // ... + // group 0 + bool pur_pdsch_max_tbs_r17_present = false; + bool pur_pdsch_max_tbs_r17 = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRC-InactiveConfig-v1610 ::= SEQUENCE +struct rrc_inactive_cfg_v1610_s { + struct ran_paging_cycle_v1610_opts { + enum options { rf512, rf1024, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated ran_paging_cycle_v1610_e_; + + // member variables + ran_paging_cycle_v1610_e_ ran_paging_cycle_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionReconfiguration-v1530-IEs ::= SEQUENCE struct rrc_conn_recfg_v1530_ies_s { using ded_info_nas_list_r15_l_ = bounded_array; @@ -414,6 +889,18 @@ struct rrc_conn_recfg_v1530_ies_s { ded_info_nas_list_r15_l_ ded_info_nas_list_r15; int8_t p_max_ue_fr1_r15 = -30; mtc_ssb_nr_r15_s smtc_r15; + rrc_conn_recfg_v1610_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionRelease-v1650-IEs ::= SEQUENCE +struct rrc_conn_release_v1650_ies_s { + bool mps_prio_ind_r16_present = false; + bool non_crit_ext_present = false; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -618,40 +1105,6 @@ using sl_tx_pool_to_add_mod_list_v2x_r14_l = dyn_array; -// TDM-PatternConfig-r15 ::= CHOICE -struct tdm_pattern_cfg_r15_c { - struct setup_s_ { - sf_assign_r15_e sf_assign_r15; - uint8_t harq_offset_r15 = 0; - }; - using types = setup_e; - - // choice methods - tdm_pattern_cfg_r15_c() = default; - void set(types::options e = types::nulltype); - types type() const { return type_; } - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - // getters - setup_s_& setup() - { - assert_choice_type(types::setup, type_, "TDM-PatternConfig-r15"); - return c; - } - const setup_s_& setup() const - { - assert_choice_type(types::setup, type_, "TDM-PatternConfig-r15"); - return c; - } - void set_release(); - setup_s_& set_setup(); - -private: - types type_; - setup_s_ c; -}; - // TunnelConfigLWIP-r13 ::= SEQUENCE struct tunnel_cfg_lwip_r13_s { bool ext = false; @@ -668,6 +1121,9 @@ struct tunnel_cfg_lwip_r13_s { void to_json(json_writer& j) const; }; +// ValidityCellList-r16 ::= SEQUENCE (SIZE (1..8)) OF PhysCellIdRange +using validity_cell_list_r16_l = dyn_array; + // WLAN-MobilityConfig-r13 ::= SEQUENCE struct wlan_mob_cfg_r13_s { struct assoc_timer_r13_opts { @@ -920,6 +1376,39 @@ struct rrc_conn_recfg_v1510_ies_s { void to_json(json_writer& j) const; }; +// RRCConnectionRelease-v1610-IEs ::= SEQUENCE +struct rrc_conn_release_v1610_ies_s { + struct t323_r16_opts { + enum options { min5, min10, min20, min30, min60, min120, min180, min720, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated t323_r16_e_; + + // member variables + bool full_i_rnti_r16_present = false; + bool short_i_rnti_r16_present = false; + bool pur_cfg_r16_present = false; + bool rrc_inactive_cfg_v1610_present = false; + bool release_idle_meas_cfg_r16_present = false; + bool alt_freq_priorities_r16_present = false; + bool t323_r16_present = false; + bool non_crit_ext_present = false; + fixed_bitstring<40> full_i_rnti_r16; + fixed_bitstring<24> short_i_rnti_r16; + setup_release_c pur_cfg_r16; + rrc_inactive_cfg_v1610_s rrc_inactive_cfg_v1610; + t323_r16_e_ t323_r16; + rrc_conn_release_v1650_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SCellToReleaseList-r10 ::= SEQUENCE (SIZE (1..4)) OF INTEGER (1..7) using scell_to_release_list_r10_l = bounded_array; @@ -1192,6 +1681,18 @@ struct sl_v2x_cfg_ded_r14_s { void to_json(json_writer& j) const; }; +// ValidityArea-r16 ::= SEQUENCE +struct validity_area_r16_s { + bool validity_cell_list_r16_present = false; + uint32_t carrier_freq_r16 = 0; + validity_cell_list_r16_l validity_cell_list_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // LWA-Configuration-r13 ::= CHOICE struct lwa_cfg_r13_c { struct setup_s_ { @@ -1273,7 +1774,7 @@ struct pwr_coordination_info_r12_s { // RAN-NotificationAreaInfo-r15 ::= CHOICE struct ran_notif_area_info_r15_c { struct types_opts { - enum options { cell_list_r15, ran_area_cfg_list_r15, nulltype } value; + enum options { cell_list, ran_area_cfg_list, nulltype } value; const char* to_string() const; }; @@ -1290,28 +1791,28 @@ struct ran_notif_area_info_r15_c { SRSASN_CODE unpack(cbit_ref& bref); void to_json(json_writer& j) const; // getters - plmn_ran_area_cell_list_r15_l& cell_list_r15() + plmn_ran_area_cell_list_r15_l& cell_list() { - assert_choice_type(types::cell_list_r15, type_, "RAN-NotificationAreaInfo-r15"); + assert_choice_type(types::cell_list, type_, "RAN-NotificationAreaInfo-r15"); return c.get(); } - plmn_ran_area_cfg_list_r15_l& ran_area_cfg_list_r15() + plmn_ran_area_cfg_list_r15_l& ran_area_cfg_list() { - assert_choice_type(types::ran_area_cfg_list_r15, type_, "RAN-NotificationAreaInfo-r15"); + assert_choice_type(types::ran_area_cfg_list, type_, "RAN-NotificationAreaInfo-r15"); return c.get(); } - const plmn_ran_area_cell_list_r15_l& cell_list_r15() const + const plmn_ran_area_cell_list_r15_l& cell_list() const { - assert_choice_type(types::cell_list_r15, type_, "RAN-NotificationAreaInfo-r15"); + assert_choice_type(types::cell_list, type_, "RAN-NotificationAreaInfo-r15"); return c.get(); } - const plmn_ran_area_cfg_list_r15_l& ran_area_cfg_list_r15() const + const plmn_ran_area_cfg_list_r15_l& ran_area_cfg_list() const { - assert_choice_type(types::ran_area_cfg_list_r15, type_, "RAN-NotificationAreaInfo-r15"); + assert_choice_type(types::ran_area_cfg_list, type_, "RAN-NotificationAreaInfo-r15"); return c.get(); } - plmn_ran_area_cell_list_r15_l& set_cell_list_r15(); - plmn_ran_area_cfg_list_r15_l& set_ran_area_cfg_list_r15(); + plmn_ran_area_cell_list_r15_l& set_cell_list(); + plmn_ran_area_cfg_list_r15_l& set_ran_area_cfg_list(); private: types type_; @@ -1373,8 +1874,9 @@ struct rrc_conn_recfg_v1430_ies_s { // RRCConnectionRelease-v15b0-IEs ::= SEQUENCE struct rrc_conn_release_v15b0_ies_s { - bool no_last_cell_upd_r15_present = false; - bool non_crit_ext_present = false; + bool no_last_cell_upd_r15_present = false; + bool non_crit_ext_present = false; + rrc_conn_release_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1463,6 +1965,9 @@ using sl_tf_idx_pair_list_r12_l = dyn_array; // SL-TxPoolToReleaseListExt-r13 ::= SEQUENCE (SIZE (1..4)) OF INTEGER (5..8) using sl_tx_pool_to_release_list_ext_r13_l = bounded_array; +// ValidityAreaList-r16 ::= SEQUENCE (SIZE (1..8)) OF ValidityArea-r16 +using validity_area_list_r16_l = dyn_array; + // FlightPathInfoReportConfig-r15 ::= SEQUENCE struct flight_path_info_report_cfg_r15_s { bool include_time_stamp_r15_present = false; @@ -1491,6 +1996,9 @@ struct meas_idle_cfg_ded_r15_s { eutra_carrier_list_r15_l meas_idle_carrier_list_eutra_r15; meas_idle_dur_r15_e_ meas_idle_dur_r15; // ... + // group 0 + copy_ptr meas_idle_carrier_list_nr_r16; + copy_ptr validity_area_list_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1616,6 +2124,42 @@ struct scg_cfg_r12_c { setup_s_ c; }; +// SCellToAddMod-r16 ::= SEQUENCE +struct scell_to_add_mod_r16_s { + struct cell_identif_r16_s_ { + uint16_t pci_r16 = 0; + uint32_t dl_carrier_freq_r16 = 0; + }; + struct scell_state_r16_opts { + enum options { activ, dormant, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated scell_state_r16_e_; + + // member variables + bool ext = false; + bool cell_identif_r16_present = false; + bool rr_cfg_common_scell_r16_present = false; + bool rr_cfg_ded_scell_r16_present = false; + bool ant_info_ded_scell_r16_present = false; + bool srs_switch_from_serv_cell_idx_r16_present = false; + bool scell_state_r16_present = false; + uint8_t scell_idx_r16 = 1; + cell_identif_r16_s_ cell_identif_r16; + rr_cfg_common_scell_r10_s rr_cfg_common_scell_r16; + rr_cfg_ded_scell_r10_s rr_cfg_ded_scell_r16; + ant_info_ded_v10i0_s ant_info_ded_scell_r16; + uint8_t srs_switch_from_serv_cell_idx_r16 = 0; + scell_state_r16_e_ scell_state_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SL-CommConfig-r12 ::= SEQUENCE struct sl_comm_cfg_r12_s { struct comm_tx_res_r12_c_ { @@ -2190,6 +2734,17 @@ struct sl_sync_tx_ctrl_r12_s { void to_json(json_writer& j) const; }; +// UEInformationRequest-v1710-IEs ::= SEQUENCE +struct ue_info_request_v1710_ies_s { + bool coarse_location_req_r17_present = false; + bool non_crit_ext_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CandidateServingFreqListNR-r15 ::= SEQUENCE (SIZE (1..32)) OF INTEGER (0..3279165) using candidate_serving_freq_list_nr_r15_l = bounded_array; @@ -2289,6 +2844,20 @@ struct rrc_conn_release_v1530_ies_s { void to_json(json_writer& j) const; }; +// RRCConnectionResume-v1700-IEs ::= SEQUENCE +struct rrc_conn_resume_v1700_ies_s { + bool scg_state_r17_present = false; + bool non_crit_ext_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SCellToAddModList-r16 ::= SEQUENCE (SIZE (1..31)) OF SCellToAddMod-r16 +using scell_to_add_mod_list_r16_l = dyn_array; + // SystemInfoListGERAN ::= SEQUENCE (SIZE (1..10)) OF OCTET STRING (SIZE (1..23)) using sys_info_list_geran_l = bounded_array, 10>; @@ -2312,6 +2881,7 @@ struct ue_info_request_v1530_ies_s { bool flight_path_info_req_r15_present = false; bool non_crit_ext_present = false; flight_path_info_report_cfg_r15_s flight_path_info_req_r15; + ue_info_request_v1710_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2547,6 +3117,38 @@ struct rrc_conn_release_v1320_ies_s { void to_json(json_writer& j) const; }; +// RRCConnectionResume-v1610-IEs ::= SEQUENCE +struct rrc_conn_resume_v1610_ies_s { + bool idle_mode_meas_req_r16_present = false; + bool restore_mcg_scells_r16_present = false; + bool restore_scg_r16_present = false; + bool scell_to_add_mod_list_r16_present = false; + bool scell_to_release_list_r16_present = false; + bool scell_group_to_release_list_r16_present = false; + bool scell_group_to_add_mod_list_r16_present = false; + bool nr_secondary_cell_group_cfg_r16_present = false; + bool p_max_eutra_r16_present = false; + bool p_max_ue_fr1_r16_present = false; + bool tdm_pattern_cfg_r16_present = false; + bool tdm_pattern_cfg2_r16_present = false; + bool non_crit_ext_present = false; + scell_to_add_mod_list_r16_l scell_to_add_mod_list_r16; + scell_to_release_list_ext_r13_l scell_to_release_list_r16; + scell_group_to_release_list_r15_l scell_group_to_release_list_r16; + scell_group_to_add_mod_list_r15_l scell_group_to_add_mod_list_r16; + dyn_octstring nr_secondary_cell_group_cfg_r16; + int8_t p_max_eutra_r16 = -30; + int8_t p_max_ue_fr1_r16 = -30; + tdm_pattern_cfg_r15_c tdm_pattern_cfg_r16; + tdm_pattern_cfg_r15_c tdm_pattern_cfg2_r16; + rrc_conn_resume_v1700_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // ReportProximityConfig-r9 ::= SEQUENCE struct report_proximity_cfg_r9_s { bool proximity_ind_eutra_r9_present = false; @@ -2558,6 +3160,26 @@ struct report_proximity_cfg_r9_s { void to_json(json_writer& j) const; }; +// SCG-DeactivationPreferenceConfig-r17 ::= SEQUENCE +struct scg_deactivation_pref_cfg_r17_s { + struct scg_deactivation_pref_prohibit_timer_r17_opts { + enum options { s0, s1, s2, s4, s8, s10, s20, s30, s60, s120, s180, s240, s300, s600, s900, s1800, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated scg_deactivation_pref_prohibit_timer_r17_e_; + + // member variables + scg_deactivation_pref_prohibit_timer_r17_e_ scg_deactivation_pref_prohibit_timer_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // TargetMBSFN-AreaList-r12 ::= SEQUENCE (SIZE (0..8)) OF TargetMBSFN-Area-r12 using target_mbsfn_area_list_r12_l = dyn_array; @@ -2906,6 +3528,13 @@ struct other_cfg_r9_s { bool ailc_bit_cfg_r15 = false; copy_ptr bt_name_list_cfg_r15; copy_ptr wlan_name_list_cfg_r15; + // group 4 + bool overheat_assist_cfg_for_scg_r16_present = false; + bool overheat_assist_cfg_for_scg_r16 = false; + // group 5 + bool meas_uncom_bar_pre_r17_present = false; + bool meas_uncom_bar_pre_r17 = false; + copy_ptr > scg_deactivation_pref_cfg_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2946,8 +3575,9 @@ struct rrc_conn_release_v1020_ies_s { // RRCConnectionResume-v1530-IEs ::= SEQUENCE struct rrc_conn_resume_v1530_ies_s { - bool full_cfg_r15_present = false; - bool non_crit_ext_present = false; + bool full_cfg_r15_present = false; + bool non_crit_ext_present = false; + rrc_conn_resume_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2990,6 +3620,29 @@ struct carrier_info_nr_r15_s { void to_json(json_writer& j) const; }; +// CarrierInfoNR-r17 ::= SEQUENCE +struct carrier_info_nr_r17_s { + struct subcarrier_spacing_ssb_r17_opts { + enum options { khz15, khz30, khz120, khz240, khz480, spare1, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated subcarrier_spacing_ssb_r17_e_; + + // member variables + bool smtc_r17_present = false; + uint32_t carrier_freq_r17 = 0; + subcarrier_spacing_ssb_r17_e_ subcarrier_spacing_ssb_r17; + mtc_ssb_nr_r15_s smtc_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CellGlobalIdList-r10 ::= SEQUENCE (SIZE (1..32)) OF CellGlobalIdEUTRA using cell_global_id_list_r10_l = dyn_array; @@ -3005,6 +3658,18 @@ struct counter_check_v1530_ies_s { void to_json(json_writer& j) const; }; +// DLInformationTransfer-v1610-IEs ::= SEQUENCE +struct dl_info_transfer_v1610_ies_s { + bool ded_info_f1c_r16_present = false; + bool non_crit_ext_present = false; + dyn_octstring ded_info_f1c_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // HandoverFromEUTRAPreparationRequest-v920-IEs ::= SEQUENCE struct ho_from_eutra_prep_request_v920_ies_s { bool concurr_prep_cdma2000_hrpd_r9_present = false; @@ -3369,9 +4034,10 @@ struct counter_check_v8a0_ies_s { // DLInformationTransfer-v8a0-IEs ::= SEQUENCE struct dl_info_transfer_v8a0_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - dyn_octstring late_non_crit_ext; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + dyn_octstring late_non_crit_ext; + dl_info_transfer_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -4053,12 +4719,13 @@ struct redirected_carrier_info_c { // ... utra_tdd_r10, nr_r15, + nr_r17, nulltype } value; const char* to_string() const; }; - typedef enumerated types; + typedef enumerated types; // choice methods redirected_carrier_info_c() = default; @@ -4111,6 +4778,11 @@ struct redirected_carrier_info_c { assert_choice_type(types::nr_r15, type_, "RedirectedCarrierInfo"); return c.get(); } + carrier_info_nr_r17_s& nr_r17() + { + assert_choice_type(types::nr_r17, type_, "RedirectedCarrierInfo"); + return c.get(); + } const uint32_t& eutra() const { assert_choice_type(types::eutra, type_, "RedirectedCarrierInfo"); @@ -4151,6 +4823,11 @@ struct redirected_carrier_info_c { assert_choice_type(types::nr_r15, type_, "RedirectedCarrierInfo"); return c.get(); } + const carrier_info_nr_r17_s& nr_r17() const + { + assert_choice_type(types::nr_r17, type_, "RedirectedCarrierInfo"); + return c.get(); + } uint32_t& set_eutra(); carrier_freqs_geran_s& set_geran(); uint16_t& set_utra_fdd(); @@ -4159,13 +4836,15 @@ struct redirected_carrier_info_c { carrier_freq_cdma2000_s& set_cdma2000_minus1x_rtt(); carrier_freq_list_utra_tdd_r10_l& set_utra_tdd_r10(); carrier_info_nr_r15_s& set_nr_r15(); + carrier_info_nr_r17_s& set_nr_r17(); private: types type_; choice_buffer_t + carrier_info_nr_r15_s, + carrier_info_nr_r17_s> c; void destroy_(); @@ -4217,11 +4896,34 @@ struct counter_check_r8_ies_s { void to_json(json_writer& j) const; }; +// DLDedicatedMessageSegment-r16-IEs ::= SEQUENCE +struct dl_ded_msg_segment_r16_ies_s { + struct rrc_msg_segment_type_r16_opts { + enum options { not_last_segment, last_segment, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated rrc_msg_segment_type_r16_e_; + + // member variables + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + uint8_t segment_num_r16 = 0; + dyn_octstring rrc_msg_segment_container_r16; + rrc_msg_segment_type_r16_e_ rrc_msg_segment_type_r16; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // DLInformationTransfer-r15-IEs ::= SEQUENCE struct dl_info_transfer_r15_ies_s { struct ded_info_type_r15_c_ { struct types_opts { - enum options { ded_info_nas_r15, ded_info_cdma2000_minus1_xrtt_r15, ded_info_cdma2000_hrpd_r15, nulltype } value; + enum options { ded_info_nas, ded_info_cdma2000_minus1_xrtt, ded_info_cdma2000_hrpd, nulltype } value; const char* to_string() const; }; @@ -4238,39 +4940,39 @@ struct dl_info_transfer_r15_ies_s { SRSASN_CODE unpack(cbit_ref& bref); void to_json(json_writer& j) const; // getters - dyn_octstring& ded_info_nas_r15() + dyn_octstring& ded_info_nas() { - assert_choice_type(types::ded_info_nas_r15, type_, "dedicatedInfoType-r15"); + assert_choice_type(types::ded_info_nas, type_, "dedicatedInfoType-r15"); return c.get(); } - dyn_octstring& ded_info_cdma2000_minus1_xrtt_r15() + dyn_octstring& ded_info_cdma2000_minus1_xrtt() { - assert_choice_type(types::ded_info_cdma2000_minus1_xrtt_r15, type_, "dedicatedInfoType-r15"); + assert_choice_type(types::ded_info_cdma2000_minus1_xrtt, type_, "dedicatedInfoType-r15"); return c.get(); } - dyn_octstring& ded_info_cdma2000_hrpd_r15() + dyn_octstring& ded_info_cdma2000_hrpd() { - assert_choice_type(types::ded_info_cdma2000_hrpd_r15, type_, "dedicatedInfoType-r15"); + assert_choice_type(types::ded_info_cdma2000_hrpd, type_, "dedicatedInfoType-r15"); return c.get(); } - const dyn_octstring& ded_info_nas_r15() const + const dyn_octstring& ded_info_nas() const { - assert_choice_type(types::ded_info_nas_r15, type_, "dedicatedInfoType-r15"); + assert_choice_type(types::ded_info_nas, type_, "dedicatedInfoType-r15"); return c.get(); } - const dyn_octstring& ded_info_cdma2000_minus1_xrtt_r15() const + const dyn_octstring& ded_info_cdma2000_minus1_xrtt() const { - assert_choice_type(types::ded_info_cdma2000_minus1_xrtt_r15, type_, "dedicatedInfoType-r15"); + assert_choice_type(types::ded_info_cdma2000_minus1_xrtt, type_, "dedicatedInfoType-r15"); return c.get(); } - const dyn_octstring& ded_info_cdma2000_hrpd_r15() const + const dyn_octstring& ded_info_cdma2000_hrpd() const { - assert_choice_type(types::ded_info_cdma2000_hrpd_r15, type_, "dedicatedInfoType-r15"); + assert_choice_type(types::ded_info_cdma2000_hrpd, type_, "dedicatedInfoType-r15"); return c.get(); } - dyn_octstring& set_ded_info_nas_r15(); - dyn_octstring& set_ded_info_cdma2000_minus1_xrtt_r15(); - dyn_octstring& set_ded_info_cdma2000_hrpd_r15(); + dyn_octstring& set_ded_info_nas(); + dyn_octstring& set_ded_info_cdma2000_minus1_xrtt(); + dyn_octstring& set_ded_info_cdma2000_hrpd(); private: types type_; @@ -4752,6 +5454,51 @@ struct counter_check_s { void to_json(json_writer& j) const; }; +// DLDedicatedMessageSegment-r16 ::= SEQUENCE +struct dl_ded_msg_segment_r16_s { + struct crit_exts_c_ { + struct types_opts { + enum options { dl_ded_msg_segment_r16, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + crit_exts_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + dl_ded_msg_segment_r16_ies_s& dl_ded_msg_segment_r16() + { + assert_choice_type(types::dl_ded_msg_segment_r16, type_, "criticalExtensions"); + return c; + } + const dl_ded_msg_segment_r16_ies_s& dl_ded_msg_segment_r16() const + { + assert_choice_type(types::dl_ded_msg_segment_r16, type_, "criticalExtensions"); + return c; + } + dl_ded_msg_segment_r16_ies_s& set_dl_ded_msg_segment_r16(); + void set_crit_exts_future(); + + private: + types type_; + dl_ded_msg_segment_r16_ies_s c; + }; + + // member variables + crit_exts_c_ crit_exts; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // DLInformationTransfer ::= SEQUENCE struct dl_info_transfer_s { struct crit_exts_c_ { @@ -5487,7 +6234,7 @@ struct dl_dcch_msg_type_c { logged_meas_cfg_r10, rn_recfg_r10, rrc_conn_resume_r13, - spare3, + dl_ded_msg_segment_r16, spare2, spare1, nulltype @@ -5575,6 +6322,11 @@ struct dl_dcch_msg_type_c { assert_choice_type(types::rrc_conn_resume_r13, type_, "c1"); return c.get(); } + dl_ded_msg_segment_r16_s& dl_ded_msg_segment_r16() + { + assert_choice_type(types::dl_ded_msg_segment_r16, type_, "c1"); + return c.get(); + } const csfb_params_resp_cdma2000_s& csfb_params_resp_cdma2000() const { assert_choice_type(types::csfb_params_resp_cdma2000, type_, "c1"); @@ -5640,6 +6392,11 @@ struct dl_dcch_msg_type_c { assert_choice_type(types::rrc_conn_resume_r13, type_, "c1"); return c.get(); } + const dl_ded_msg_segment_r16_s& dl_ded_msg_segment_r16() const + { + assert_choice_type(types::dl_ded_msg_segment_r16, type_, "c1"); + return c.get(); + } csfb_params_resp_cdma2000_s& set_csfb_params_resp_cdma2000(); dl_info_transfer_s& set_dl_info_transfer(); ho_from_eutra_prep_request_s& set_ho_from_eutra_prep_request(); @@ -5653,7 +6410,7 @@ struct dl_dcch_msg_type_c { logged_meas_cfg_r10_s& set_logged_meas_cfg_r10(); rn_recfg_r10_s& set_rn_recfg_r10(); rrc_conn_resume_r13_s& set_rrc_conn_resume_r13(); - void set_spare3(); + dl_ded_msg_segment_r16_s& set_dl_ded_msg_segment_r16(); void set_spare2(); void set_spare1(); @@ -5661,6 +6418,7 @@ struct dl_dcch_msg_type_c { types type_; choice_buffer_t as_cfg_v1550; // group 5 copy_ptr as_cfg_nr_v1570; + // group 6 + copy_ptr as_cfg_nr_v1620; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -357,10 +369,10 @@ struct as_context_v1130_s { bool ext = false; bool idc_ind_r11_present = false; bool mbms_interest_ind_r11_present = false; - bool pwr_pref_ind_r11_present = false; + bool ue_assist_info_r11_present = false; dyn_octstring idc_ind_r11; dyn_octstring mbms_interest_ind_r11; - dyn_octstring pwr_pref_ind_r11; + dyn_octstring ue_assist_info_r11; // ... // group 0 bool sidelink_ue_info_r12_present = false; @@ -389,6 +401,56 @@ struct as_context_v1320_s { void to_json(json_writer& j) const; }; +// ConfigRestrictInfoDAPS-r16 ::= SEQUENCE +struct cfg_restrict_info_daps_r16_s { + bool max_sch_tb_bits_dl_r16_present = false; + bool max_sch_tb_bits_ul_r16_present = false; + uint8_t max_sch_tb_bits_dl_r16 = 1; + uint8_t max_sch_tb_bits_ul_r16 = 1; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// AS-Context-v1610 ::= SEQUENCE +struct as_context_v1610_s { + bool sidelink_ue_info_nr_r16_present = false; + bool ue_assist_info_nr_r16_present = false; + bool cfg_restrict_info_daps_r16_present = false; + dyn_octstring sidelink_ue_info_nr_r16; + dyn_octstring ue_assist_info_nr_r16; + cfg_restrict_info_daps_r16_s cfg_restrict_info_daps_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ConfigRestrictInfoDAPS-v1630 ::= SEQUENCE +struct cfg_restrict_info_daps_v1630_s { + bool daps_pwr_coordination_info_r16_present = false; + daps_pwr_coordination_info_r16_s daps_pwr_coordination_info_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// AS-Context-v1630 ::= SEQUENCE +struct as_context_v1630_s { + bool cfg_restrict_info_daps_v1630_present = false; + cfg_restrict_info_daps_v1630_s cfg_restrict_info_daps_v1630; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CandidateCellInfo-r10 ::= SEQUENCE struct candidate_cell_info_r10_s { bool ext = false; @@ -508,11 +570,84 @@ struct ho_cmd_s { void to_json(json_writer& j) const; }; +// AS-Config-v1700 ::= SEQUENCE +struct as_cfg_v1700_s { + bool scg_state_r17_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// HandoverPreparationInformation-v1700-IEs ::= SEQUENCE +struct ho_prep_info_v1700_ies_s { + bool as_cfg_v1700_present = false; + bool non_crit_ext_present = false; + as_cfg_v1700_s as_cfg_v1700; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// AS-Context-v1620 ::= SEQUENCE +struct as_context_v1620_s { + bool ue_assist_info_nr_scg_r16_present = false; + dyn_octstring ue_assist_info_nr_scg_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// HandoverPreparationInformation-v1630-IEs ::= SEQUENCE +struct ho_prep_info_v1630_ies_s { + bool as_context_v1630_present = false; + bool non_crit_ext_present = false; + as_context_v1630_s as_context_v1630; + ho_prep_info_v1700_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// HandoverPreparationInformation-v1620-IEs ::= SEQUENCE +struct ho_prep_info_v1620_ies_s { + bool as_context_v1620_present = false; + bool non_crit_ext_present = false; + as_context_v1620_s as_context_v1620; + ho_prep_info_v1630_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// HandoverPreparationInformation-v1610-IEs ::= SEQUENCE +struct ho_prep_info_v1610_ies_s { + bool as_context_v1610_present = false; + bool non_crit_ext_present = false; + as_context_v1610_s as_context_v1610; + ho_prep_info_v1620_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // HandoverPreparationInformation-v1540-IEs ::= SEQUENCE struct ho_prep_info_v1540_ies_s { - bool source_rb_cfg_intra5_gc_r15_present = false; - bool non_crit_ext_present = false; - dyn_octstring source_rb_cfg_intra5_gc_r15; + bool source_rb_cfg_intra5_gc_r15_present = false; + bool non_crit_ext_present = false; + dyn_octstring source_rb_cfg_intra5_gc_r15; + ho_prep_info_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -619,11 +754,25 @@ struct ho_prep_info_v9d0_ies_s { // HandoverPreparationInformation-v920-IEs ::= SEQUENCE struct ho_prep_info_v920_ies_s { struct ue_cfg_release_r9_opts { - enum options { rel9, rel10, rel11, rel12, v10j0, v11e0, v1280, rel13, /*...*/ rel14, rel15, nulltype } value; + enum options { + rel9, + rel10, + rel11, + rel12, + v10j0, + v11e0, + v1280, + rel13, + /*...*/ rel14, + rel15, + rel16, + rel17, + nulltype + } value; const char* to_string() const; }; - typedef enumerated ue_cfg_release_r9_e_; + typedef enumerated ue_cfg_release_r9_e_; // member variables bool ue_cfg_release_r9_present = false; diff --git a/lib/include/srsran/asn1/rrc/meascfg.h b/lib/include/srsran/asn1/rrc/meascfg.h index 50df4845b1..d98352fff4 100644 --- a/lib/include/srsran/asn1/rrc/meascfg.h +++ b/lib/include/srsran/asn1/rrc/meascfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -81,6 +81,16 @@ struct q_offset_range_opts { }; typedef enumerated q_offset_range_e; +// RSS-MeasPowerBias-r16 ::= ENUMERATED +struct rss_meas_pwr_bias_r16_opts { + enum options { db_minus6, db_minus3, db0, db3, db6, db9, db12, rss_not_used, nulltype } value; + typedef int8_t number_type; + + const char* to_string() const; + int8_t to_number() const; +}; +typedef enumerated rss_meas_pwr_bias_r16_e; + // SecondaryPreRegistrationZoneIdListHRPD ::= SEQUENCE (SIZE (1..2)) OF INTEGER (0..255) using secondary_pre_regist_zone_id_list_hrpd_l = bounded_array; @@ -128,112 +138,6 @@ typedef enumerated band_ind_geran_e; // ExplicitListOfARFCNs ::= SEQUENCE (SIZE (0..31)) OF INTEGER (0..1023) using explicit_list_of_arfcns_l = bounded_array; -// PreRegistrationInfoHRPD ::= SEQUENCE -struct pre_regist_info_hrpd_s { - bool pre_regist_zone_id_present = false; - bool secondary_pre_regist_zone_id_list_present = false; - bool pre_regist_allowed = false; - uint16_t pre_regist_zone_id = 0; - secondary_pre_regist_zone_id_list_hrpd_l secondary_pre_regist_zone_id_list; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - -// CarrierFreqsGERAN ::= SEQUENCE -struct carrier_freqs_geran_s { - struct following_arfcns_c_ { - struct equally_spaced_arfcns_s_ { - uint8_t arfcn_spacing = 1; - uint8_t nof_following_arfcns = 0; - }; - struct types_opts { - enum options { explicit_list_of_arfcns, equally_spaced_arfcns, variable_bit_map_of_arfcns, nulltype } value; - - const char* to_string() const; - }; - typedef enumerated types; - - // choice methods - following_arfcns_c_() = default; - following_arfcns_c_(const following_arfcns_c_& other); - following_arfcns_c_& operator=(const following_arfcns_c_& other); - ~following_arfcns_c_() { destroy_(); } - void set(types::options e = types::nulltype); - types type() const { return type_; } - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool operator==(const following_arfcns_c_& other) const; - bool operator!=(const following_arfcns_c_& other) const { return not(*this == other); } - // getters - explicit_list_of_arfcns_l& explicit_list_of_arfcns() - { - assert_choice_type(types::explicit_list_of_arfcns, type_, "followingARFCNs"); - return c.get(); - } - equally_spaced_arfcns_s_& equally_spaced_arfcns() - { - assert_choice_type(types::equally_spaced_arfcns, type_, "followingARFCNs"); - return c.get(); - } - bounded_octstring<1, 16>& variable_bit_map_of_arfcns() - { - assert_choice_type(types::variable_bit_map_of_arfcns, type_, "followingARFCNs"); - return c.get >(); - } - const explicit_list_of_arfcns_l& explicit_list_of_arfcns() const - { - assert_choice_type(types::explicit_list_of_arfcns, type_, "followingARFCNs"); - return c.get(); - } - const equally_spaced_arfcns_s_& equally_spaced_arfcns() const - { - assert_choice_type(types::equally_spaced_arfcns, type_, "followingARFCNs"); - return c.get(); - } - const bounded_octstring<1, 16>& variable_bit_map_of_arfcns() const - { - assert_choice_type(types::variable_bit_map_of_arfcns, type_, "followingARFCNs"); - return c.get >(); - } - explicit_list_of_arfcns_l& set_explicit_list_of_arfcns(); - equally_spaced_arfcns_s_& set_equally_spaced_arfcns(); - bounded_octstring<1, 16>& set_variable_bit_map_of_arfcns(); - - private: - types type_; - choice_buffer_t, equally_spaced_arfcns_s_, explicit_list_of_arfcns_l> c; - - void destroy_(); - }; - - // member variables - uint16_t start_arfcn = 0; - band_ind_geran_e band_ind; - following_arfcns_c_ following_arfcns; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool operator==(const carrier_freqs_geran_s& other) const; - bool operator!=(const carrier_freqs_geran_s& other) const { return not(*this == other); } -}; - -// CellReselectionSubPriority-r13 ::= ENUMERATED -struct cell_resel_sub_prio_r13_opts { - enum options { odot2, odot4, odot6, odot8, nulltype } value; - typedef float number_type; - - const char* to_string() const; - float to_number() const; - const char* to_number_string() const; -}; -typedef enumerated cell_resel_sub_prio_r13_e; - // MTC-SSB-NR-r15 ::= SEQUENCE struct mtc_ssb_nr_r15_s { struct periodicity_and_offset_r15_c_ { @@ -353,12 +257,23 @@ struct mtc_ssb_nr_r15_s { bool operator!=(const mtc_ssb_nr_r15_s& other) const { return not(*this == other); } }; -// MultiBandInfoList-r11 ::= SEQUENCE (SIZE (1..8)) OF INTEGER (1..256) -using multi_band_info_list_r11_l = bounded_array; - // MultiFrequencyBandListNR-r15 ::= SEQUENCE (SIZE (1..32)) OF INTEGER (1..1024) using multi_freq_band_list_nr_r15_l = bounded_array; +// PreRegistrationInfoHRPD ::= SEQUENCE +struct pre_regist_info_hrpd_s { + bool pre_regist_zone_id_present = false; + bool secondary_pre_regist_zone_id_list_present = false; + bool pre_regist_allowed = false; + uint16_t pre_regist_zone_id = 0; + secondary_pre_regist_zone_id_list_hrpd_l secondary_pre_regist_zone_id_list; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SS-RSSI-Measurement-r15 ::= SEQUENCE struct ss_rssi_meas_r15_s { bounded_bitstring<1, 80> meas_slots_r15; @@ -452,6 +367,144 @@ struct thres_list_nr_r15_s { bool operator!=(const thres_list_nr_r15_s& other) const { return not(*this == other); } }; +// CarrierFreqsGERAN ::= SEQUENCE +struct carrier_freqs_geran_s { + struct following_arfcns_c_ { + struct equally_spaced_arfcns_s_ { + uint8_t arfcn_spacing = 1; + uint8_t nof_following_arfcns = 0; + }; + struct types_opts { + enum options { explicit_list_of_arfcns, equally_spaced_arfcns, variable_bit_map_of_arfcns, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + following_arfcns_c_() = default; + following_arfcns_c_(const following_arfcns_c_& other); + following_arfcns_c_& operator=(const following_arfcns_c_& other); + ~following_arfcns_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const following_arfcns_c_& other) const; + bool operator!=(const following_arfcns_c_& other) const { return not(*this == other); } + // getters + explicit_list_of_arfcns_l& explicit_list_of_arfcns() + { + assert_choice_type(types::explicit_list_of_arfcns, type_, "followingARFCNs"); + return c.get(); + } + equally_spaced_arfcns_s_& equally_spaced_arfcns() + { + assert_choice_type(types::equally_spaced_arfcns, type_, "followingARFCNs"); + return c.get(); + } + bounded_octstring<1, 16>& variable_bit_map_of_arfcns() + { + assert_choice_type(types::variable_bit_map_of_arfcns, type_, "followingARFCNs"); + return c.get >(); + } + const explicit_list_of_arfcns_l& explicit_list_of_arfcns() const + { + assert_choice_type(types::explicit_list_of_arfcns, type_, "followingARFCNs"); + return c.get(); + } + const equally_spaced_arfcns_s_& equally_spaced_arfcns() const + { + assert_choice_type(types::equally_spaced_arfcns, type_, "followingARFCNs"); + return c.get(); + } + const bounded_octstring<1, 16>& variable_bit_map_of_arfcns() const + { + assert_choice_type(types::variable_bit_map_of_arfcns, type_, "followingARFCNs"); + return c.get >(); + } + explicit_list_of_arfcns_l& set_explicit_list_of_arfcns(); + equally_spaced_arfcns_s_& set_equally_spaced_arfcns(); + bounded_octstring<1, 16>& set_variable_bit_map_of_arfcns(); + + private: + types type_; + choice_buffer_t, equally_spaced_arfcns_s_, explicit_list_of_arfcns_l> c; + + void destroy_(); + }; + + // member variables + uint16_t start_arfcn = 0; + band_ind_geran_e band_ind; + following_arfcns_c_ following_arfcns; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const carrier_freqs_geran_s& other) const; + bool operator!=(const carrier_freqs_geran_s& other) const { return not(*this == other); } +}; + +// CellReselectionSubPriority-r13 ::= ENUMERATED +struct cell_resel_sub_prio_r13_opts { + enum options { odot2, odot4, odot6, odot8, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; +}; +typedef enumerated cell_resel_sub_prio_r13_e; + +// MultiBandInfoList-r11 ::= SEQUENCE (SIZE (1..8)) OF INTEGER (1..256) +using multi_band_info_list_r11_l = bounded_array; + +// RSS-ConfigCarrierInfo-r16 ::= SEQUENCE +struct rss_cfg_carrier_info_r16_s { + struct time_offset_granularity_r16_opts { + enum options { g1, g2, g4, g8, g16, g32, g64, g128, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated time_offset_granularity_r16_e_; + + // member variables + bounded_bitstring<1, 15> nb_idx_r16; + time_offset_granularity_r16_e_ time_offset_granularity_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const rss_cfg_carrier_info_r16_s& other) const; + bool operator!=(const rss_cfg_carrier_info_r16_s& other) const { return not(*this == other); } +}; + +// SSB-PositionQCL-RelationNR-r16 ::= ENUMERATED +struct ssb_position_qcl_relation_nr_r16_opts { + enum options { n1, n2, n4, n8, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated ssb_position_qcl_relation_nr_r16_e; + +// SSB-PositionQCL-RelationNR-r17 ::= ENUMERATED +struct ssb_position_qcl_relation_nr_r17_opts { + enum options { n32, n64, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated ssb_position_qcl_relation_nr_r17_e; + // MobilityStateParameters ::= SEQUENCE struct mob_state_params_s { struct t_eval_opts { @@ -496,6 +549,18 @@ struct carrier_freq_cdma2000_s { bool operator!=(const carrier_freq_cdma2000_s& other) const { return not(*this == other); } }; +// CellsToAddMod-v1610 ::= SEQUENCE +struct cells_to_add_mod_v1610_s { + rss_meas_pwr_bias_r16_e rss_meas_pwr_bias_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const cells_to_add_mod_v1610_s& other) const; + bool operator!=(const cells_to_add_mod_v1610_s& other) const { return not(*this == other); } +}; + // MeasCSI-RS-Config-r12 ::= SEQUENCE struct meas_csi_rs_cfg_r12_s { bool ext = false; @@ -529,6 +594,45 @@ struct pci_range_utra_fdd_r9_s { bool operator!=(const pci_range_utra_fdd_r9_s& other) const { return not(*this == other); } }; +// SSB-PositionQCL-CellsToAddNR-r16 ::= SEQUENCE +struct ssb_position_qcl_cells_to_add_nr_r16_s { + uint16_t pci_r16 = 0; + ssb_position_qcl_relation_nr_r16_e ssb_position_qcl_nr_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const ssb_position_qcl_cells_to_add_nr_r16_s& other) const; + bool operator!=(const ssb_position_qcl_cells_to_add_nr_r16_s& other) const { return not(*this == other); } +}; + +// SSB-PositionQCL-CellsToAddNR-r17 ::= SEQUENCE +struct ssb_position_qcl_cells_to_add_nr_r17_s { + uint16_t pci_nr_r17 = 0; + ssb_position_qcl_relation_nr_r17_e ssb_position_qcl_nr_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const ssb_position_qcl_cells_to_add_nr_r17_s& other) const; + bool operator!=(const ssb_position_qcl_cells_to_add_nr_r17_s& other) const { return not(*this == other); } +}; + +// AllowedCellsToAddMod-r13 ::= SEQUENCE +struct allowed_cells_to_add_mod_r13_s { + uint8_t cell_idx_r13 = 1; + pci_range_s pci_range_r13; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const allowed_cells_to_add_mod_r13_s& other) const; + bool operator!=(const allowed_cells_to_add_mod_r13_s& other) const { return not(*this == other); } +}; + // AltTTT-CellsToAddMod-r12 ::= SEQUENCE struct alt_ttt_cells_to_add_mod_r12_s { uint8_t cell_idx_r12 = 1; @@ -545,19 +649,6 @@ struct alt_ttt_cells_to_add_mod_r12_s { // BT-NameList-r15 ::= SEQUENCE (SIZE (1..4)) OF OCTET STRING (SIZE (1..248)) using bt_name_list_r15_l = bounded_array, 4>; -// BlackCellsToAddMod ::= SEQUENCE -struct black_cells_to_add_mod_s { - uint8_t cell_idx = 1; - pci_range_s pci_range; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool operator==(const black_cells_to_add_mod_s& other) const; - bool operator!=(const black_cells_to_add_mod_s& other) const { return not(*this == other); } -}; - // CellsToAddMod ::= SEQUENCE struct cells_to_add_mod_s { uint8_t cell_idx = 1; @@ -585,6 +676,9 @@ struct cells_to_add_mod_cdma2000_s { bool operator!=(const cells_to_add_mod_cdma2000_s& other) const { return not(*this == other); } }; +// CellsToAddModList-v1610 ::= SEQUENCE (SIZE (1..32)) OF CellsToAddMod-v1610 +using cells_to_add_mod_list_v1610_l = dyn_array; + // CellsToAddModNR-r15 ::= SEQUENCE struct cells_to_add_mod_nr_r15_s { uint8_t cell_idx_r15 = 1; @@ -598,6 +692,20 @@ struct cells_to_add_mod_nr_r15_s { bool operator!=(const cells_to_add_mod_nr_r15_s& other) const { return not(*this == other); } }; +// CellsToAddModNR-r16 ::= SEQUENCE +struct cells_to_add_mod_nr_r16_s { + uint8_t cell_idx_r16 = 1; + uint16_t pci_r16 = 0; + q_offset_range_e cell_individual_offset_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const cells_to_add_mod_nr_r16_s& other) const; + bool operator!=(const cells_to_add_mod_nr_r16_s& other) const { return not(*this == other); } +}; + // CellsToAddModUTRA-FDD ::= SEQUENCE struct cells_to_add_mod_utra_fdd_s { uint8_t cell_idx = 1; @@ -624,17 +732,179 @@ struct cells_to_add_mod_utra_tdd_s { bool operator!=(const cells_to_add_mod_utra_tdd_s& other) const { return not(*this == other); } }; +// ExcludedCellsToAddMod ::= SEQUENCE +struct excluded_cells_to_add_mod_s { + uint8_t cell_idx = 1; + pci_range_s pci_range; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const excluded_cells_to_add_mod_s& other) const; + bool operator!=(const excluded_cells_to_add_mod_s& other) const { return not(*this == other); } +}; + // MeasCSI-RS-ToAddModList-r12 ::= SEQUENCE (SIZE (1..96)) OF MeasCSI-RS-Config-r12 using meas_csi_rs_to_add_mod_list_r12_l = dyn_array; -// MeasCSI-RS-ToRemoveList-r12 ::= SEQUENCE (SIZE (1..96)) OF INTEGER (1..96) -using meas_csi_rs_to_rem_list_r12_l = dyn_array; +// MeasCSI-RS-ToRemoveList-r12 ::= SEQUENCE (SIZE (1..96)) OF INTEGER (1..96) +using meas_csi_rs_to_rem_list_r12_l = dyn_array; + +// MeasSubframeCellList-r10 ::= SEQUENCE (SIZE (1..32)) OF PhysCellIdRange +using meas_sf_cell_list_r10_l = dyn_array; + +// PhysCellIdRangeUTRA-FDDList-r9 ::= SEQUENCE (SIZE (1..4)) OF PhysCellIdRangeUTRA-FDD-r9 +using pci_range_utra_fdd_list_r9_l = dyn_array; + +// SSB-PositionQCL-CellsToAddModListNR-r16 ::= SEQUENCE (SIZE (1..32)) OF SSB-PositionQCL-CellsToAddNR-r16 +using ssb_position_qcl_cells_to_add_mod_list_nr_r16_l = dyn_array; + +// SSB-PositionQCL-CellsToAddModListNR-r17 ::= SEQUENCE (SIZE (1..32)) OF SSB-PositionQCL-CellsToAddNR-r17 +using ssb_position_qcl_cells_to_add_mod_list_nr_r17_l = dyn_array; + +// ThresholdEUTRA ::= CHOICE +struct thres_eutra_c { + struct types_opts { + enum options { thres_rsrp, thres_rsrq, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + thres_eutra_c() = default; + thres_eutra_c(const thres_eutra_c& other); + thres_eutra_c& operator=(const thres_eutra_c& other); + ~thres_eutra_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const thres_eutra_c& other) const; + bool operator!=(const thres_eutra_c& other) const { return not(*this == other); } + // getters + uint8_t& thres_rsrp() + { + assert_choice_type(types::thres_rsrp, type_, "ThresholdEUTRA"); + return c.get(); + } + uint8_t& thres_rsrq() + { + assert_choice_type(types::thres_rsrq, type_, "ThresholdEUTRA"); + return c.get(); + } + const uint8_t& thres_rsrp() const + { + assert_choice_type(types::thres_rsrp, type_, "ThresholdEUTRA"); + return c.get(); + } + const uint8_t& thres_rsrq() const + { + assert_choice_type(types::thres_rsrq, type_, "ThresholdEUTRA"); + return c.get(); + } + uint8_t& set_thres_rsrp(); + uint8_t& set_thres_rsrq(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// ThresholdNR-r15 ::= CHOICE +struct thres_nr_r15_c { + struct types_opts { + enum options { nr_rsrp_r15, nr_rsrq_r15, nr_sinr_r15, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + thres_nr_r15_c() = default; + thres_nr_r15_c(const thres_nr_r15_c& other); + thres_nr_r15_c& operator=(const thres_nr_r15_c& other); + ~thres_nr_r15_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const thres_nr_r15_c& other) const; + bool operator!=(const thres_nr_r15_c& other) const { return not(*this == other); } + // getters + uint8_t& nr_rsrp_r15() + { + assert_choice_type(types::nr_rsrp_r15, type_, "ThresholdNR-r15"); + return c.get(); + } + uint8_t& nr_rsrq_r15() + { + assert_choice_type(types::nr_rsrq_r15, type_, "ThresholdNR-r15"); + return c.get(); + } + uint8_t& nr_sinr_r15() + { + assert_choice_type(types::nr_sinr_r15, type_, "ThresholdNR-r15"); + return c.get(); + } + const uint8_t& nr_rsrp_r15() const + { + assert_choice_type(types::nr_rsrp_r15, type_, "ThresholdNR-r15"); + return c.get(); + } + const uint8_t& nr_rsrq_r15() const + { + assert_choice_type(types::nr_rsrq_r15, type_, "ThresholdNR-r15"); + return c.get(); + } + const uint8_t& nr_sinr_r15() const + { + assert_choice_type(types::nr_sinr_r15, type_, "ThresholdNR-r15"); + return c.get(); + } + uint8_t& set_nr_rsrp_r15(); + uint8_t& set_nr_rsrq_r15(); + uint8_t& set_nr_sinr_r15(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; -// MeasSubframeCellList-r10 ::= SEQUENCE (SIZE (1..32)) OF PhysCellIdRange -using meas_sf_cell_list_r10_l = dyn_array; +// TimeToTrigger ::= ENUMERATED +struct time_to_trigger_opts { + enum options { + ms0, + ms40, + ms64, + ms80, + ms100, + ms128, + ms160, + ms256, + ms320, + ms480, + ms512, + ms640, + ms1024, + ms1280, + ms2560, + ms5120, + nulltype + } value; + typedef uint16_t number_type; -// PhysCellIdRangeUTRA-FDDList-r9 ::= SEQUENCE (SIZE (1..4)) OF PhysCellIdRangeUTRA-FDD-r9 -using pci_range_utra_fdd_list_r9_l = dyn_array; + const char* to_string() const; + uint16_t to_number() const; +}; +typedef enumerated time_to_trigger_e; // WLAN-ChannelList-r13 ::= SEQUENCE (SIZE (1..16)) OF INTEGER (0..255) using wlan_ch_list_r13_l = bounded_array; @@ -642,18 +912,8 @@ using wlan_ch_list_r13_l = bounded_array; // WLAN-NameList-r15 ::= SEQUENCE (SIZE (1..4)) OF OCTET STRING (SIZE (1..32)) using wlan_name_list_r15_l = bounded_array, 4>; -// WhiteCellsToAddMod-r13 ::= SEQUENCE -struct white_cells_to_add_mod_r13_s { - uint8_t cell_idx_r13 = 1; - pci_range_s pci_range_r13; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool operator==(const white_cells_to_add_mod_r13_s& other) const; - bool operator!=(const white_cells_to_add_mod_r13_s& other) const { return not(*this == other); } -}; +// AllowedCellsToAddModList-r13 ::= SEQUENCE (SIZE (1..32)) OF AllowedCellsToAddMod-r13 +using allowed_cells_to_add_mod_list_r13_l = dyn_array; // AltTTT-CellsToAddModList-r12 ::= SEQUENCE (SIZE (1..32)) OF AltTTT-CellsToAddMod-r12 using alt_ttt_cells_to_add_mod_list_r12_l = dyn_array; @@ -690,9 +950,6 @@ struct bt_name_list_cfg_r15_c { bt_name_list_r15_l c; }; -// BlackCellsToAddModList ::= SEQUENCE (SIZE (1..32)) OF BlackCellsToAddMod -using black_cells_to_add_mod_list_l = dyn_array; - // CDMA2000-Type ::= ENUMERATED struct cdma2000_type_opts { enum options { type1_xrtt, type_hrpd, nulltype } value; @@ -728,12 +985,138 @@ using cells_to_add_mod_list_cdma2000_l = dyn_array; // CellsToAddModListNR-r15 ::= SEQUENCE (SIZE (1..32)) OF CellsToAddModNR-r15 using cells_to_add_mod_list_nr_r15_l = dyn_array; +// CellsToAddModListNR-r16 ::= SEQUENCE (SIZE (1..32)) OF CellsToAddModNR-r16 +using cells_to_add_mod_list_nr_r16_l = dyn_array; + // CellsToAddModListUTRA-FDD ::= SEQUENCE (SIZE (1..32)) OF CellsToAddModUTRA-FDD using cells_to_add_mod_list_utra_fdd_l = dyn_array; // CellsToAddModListUTRA-TDD ::= SEQUENCE (SIZE (1..32)) OF CellsToAddModUTRA-TDD using cells_to_add_mod_list_utra_tdd_l = dyn_array; +// CondReconfigurationTriggerEUTRA-r16 ::= SEQUENCE +struct cond_recfg_trigger_eutra_r16_s { + struct cond_event_id_r16_c_ { + struct cond_event_a3_r16_s_ { + int8_t a3_offset_r16 = -30; + uint8_t hysteresis_r16 = 0; + time_to_trigger_e time_to_trigger_r16; + }; + struct cond_event_a5_r16_s_ { + thres_eutra_c a5_thres1_r16; + thres_eutra_c a5_thres2_r16; + uint8_t hysteresis_r16 = 0; + time_to_trigger_e time_to_trigger_r16; + }; + struct types_opts { + enum options { cond_event_a3_r16, cond_event_a5_r16, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + cond_event_id_r16_c_() = default; + cond_event_id_r16_c_(const cond_event_id_r16_c_& other); + cond_event_id_r16_c_& operator=(const cond_event_id_r16_c_& other); + ~cond_event_id_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const cond_event_id_r16_c_& other) const; + bool operator!=(const cond_event_id_r16_c_& other) const { return not(*this == other); } + // getters + cond_event_a3_r16_s_& cond_event_a3_r16() + { + assert_choice_type(types::cond_event_a3_r16, type_, "condEventId-r16"); + return c.get(); + } + cond_event_a5_r16_s_& cond_event_a5_r16() + { + assert_choice_type(types::cond_event_a5_r16, type_, "condEventId-r16"); + return c.get(); + } + const cond_event_a3_r16_s_& cond_event_a3_r16() const + { + assert_choice_type(types::cond_event_a3_r16, type_, "condEventId-r16"); + return c.get(); + } + const cond_event_a5_r16_s_& cond_event_a5_r16() const + { + assert_choice_type(types::cond_event_a5_r16, type_, "condEventId-r16"); + return c.get(); + } + cond_event_a3_r16_s_& set_cond_event_a3_r16(); + cond_event_a5_r16_s_& set_cond_event_a5_r16(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + cond_event_id_r16_c_ cond_event_id_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const cond_recfg_trigger_eutra_r16_s& other) const; + bool operator!=(const cond_recfg_trigger_eutra_r16_s& other) const { return not(*this == other); } +}; + +// CondReconfigurationTriggerNR-r17 ::= SEQUENCE +struct cond_recfg_trigger_nr_r17_s { + struct cond_event_id_r17_c_ { + struct cond_event_b1_nr_r17_s_ { + thres_nr_r15_c b1_thres_nr_r17; + uint8_t hysteresis_r17 = 0; + time_to_trigger_e time_to_trigger_r17; + }; + struct types_opts { + enum options { cond_event_b1_nr_r17, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + types type() const { return types::cond_event_b1_nr_r17; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const cond_event_id_r17_c_& other) const; + bool operator!=(const cond_event_id_r17_c_& other) const { return not(*this == other); } + // getters + cond_event_b1_nr_r17_s_& cond_event_b1_nr_r17() { return c; } + const cond_event_b1_nr_r17_s_& cond_event_b1_nr_r17() const { return c; } + + private: + cond_event_b1_nr_r17_s_ c; + }; + + // member variables + cond_event_id_r17_c_ cond_event_id_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const cond_recfg_trigger_nr_r17_s& other) const; + bool operator!=(const cond_recfg_trigger_nr_r17_s& other) const { return not(*this == other); } +}; + +// ExcludedCellsToAddModList ::= SEQUENCE (SIZE (1..32)) OF ExcludedCellsToAddMod +using excluded_cells_to_add_mod_list_l = dyn_array; + // MeasCycleSCell-r10 ::= ENUMERATED struct meas_cycle_scell_r10_opts { enum options { sf160, sf256, sf320, sf512, sf640, sf1024, sf1280, spare1, nulltype } value; @@ -1205,6 +1588,21 @@ struct meas_gap_cfg_c { setup_s_ c; }; +// MeasRSS-DedicatedConfig-r16 ::= SEQUENCE +struct meas_rss_ded_cfg_r16_s { + bool rss_cfg_carrier_info_r16_present = false; + bool cells_to_add_mod_list_v1610_present = false; + rss_cfg_carrier_info_r16_s rss_cfg_carrier_info_r16; + cells_to_add_mod_list_v1610_l cells_to_add_mod_list_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const meas_rss_ded_cfg_r16_s& other) const; + bool operator!=(const meas_rss_ded_cfg_r16_s& other) const { return not(*this == other); } +}; + // MeasRSSI-ReportConfig-r13 ::= SEQUENCE struct meas_rssi_report_cfg_r13_s { bool ch_occupancy_thres_r13_present = false; @@ -1368,6 +1766,80 @@ struct rmtc_cfg_r13_c { setup_s_ c; }; +// RMTC-ConfigNR-r16 ::= SEQUENCE +struct rmtc_cfg_nr_r16_s { + struct rmtc_periodicity_nr_r16_opts { + enum options { ms40, ms80, ms160, ms320, ms640, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated rmtc_periodicity_nr_r16_e_; + struct meas_dur_nr_r16_opts { + enum options { sym1, sym14or12, sym28or24, sym42or36, sym70or60, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated meas_dur_nr_r16_e_; + struct ref_scs_cp_nr_r16_opts { + enum options { khz15, khz30, khz60_ncp, khz60_ecp, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated ref_scs_cp_nr_r16_e_; + struct rmtc_bw_nr_r17_opts { + enum options { mhz100, mhz400, mhz800, mhz1600, mhz2000, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated rmtc_bw_nr_r17_e_; + struct meas_dur_nr_r17_opts { + enum options { sym140, sym560, sym1120, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated meas_dur_nr_r17_e_; + struct ref_scs_cp_nr_r17_opts { + enum options { khz120, khz480, khz960, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated ref_scs_cp_nr_r17_e_; + + // member variables + bool ext = false; + bool rmtc_sf_offset_nr_r16_present = false; + rmtc_periodicity_nr_r16_e_ rmtc_periodicity_nr_r16; + uint16_t rmtc_sf_offset_nr_r16 = 0; + meas_dur_nr_r16_e_ meas_dur_nr_r16; + uint32_t rmtc_freq_nr_r16 = 0; + ref_scs_cp_nr_r16_e_ ref_scs_cp_nr_r16; + // ... + // group 0 + bool rmtc_bw_nr_r17_present = false; + bool meas_dur_nr_r17_present = false; + bool ref_scs_cp_nr_r17_present = false; + rmtc_bw_nr_r17_e_ rmtc_bw_nr_r17; + meas_dur_nr_r17_e_ meas_dur_nr_r17; + ref_scs_cp_nr_r17_e_ ref_scs_cp_nr_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const rmtc_cfg_nr_r16_s& other) const; + bool operator!=(const rmtc_cfg_nr_r16_s& other) const { return not(*this == other); } +}; + // RS-ConfigSSB-NR-r15 ::= SEQUENCE struct rs_cfg_ssb_nr_r15_s { struct subcarrier_spacing_ssb_r15_opts { @@ -1408,6 +1880,16 @@ struct rs_cfg_ssb_nr_r15_s { types type_; ssb_to_measure_r15_c c; }; + using ssb_position_qcl_cells_to_rem_list_nr_r16_l_ = bounded_array; + struct subcarrier_spacing_ssb_r17_opts { + enum options { khz480, khz960, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated subcarrier_spacing_ssb_r17_e_; + using ssb_position_qcl_cells_to_rem_list_nr_r17_l_ = bounded_array; // member variables bool ext = false; @@ -1416,6 +1898,18 @@ struct rs_cfg_ssb_nr_r15_s { // ... // group 0 copy_ptr ssb_to_measure_r15; + // group 1 + bool ssb_position_qcl_common_nr_r16_present = false; + ssb_position_qcl_relation_nr_r16_e ssb_position_qcl_common_nr_r16; + copy_ptr ssb_position_qcl_cells_to_add_mod_list_nr_r16; + copy_ptr ssb_position_qcl_cells_to_rem_list_nr_r16; + // group 2 + bool subcarrier_spacing_ssb_r17_present = false; + bool ssb_position_qcl_common_nr_r17_present = false; + subcarrier_spacing_ssb_r17_e_ subcarrier_spacing_ssb_r17; + ssb_position_qcl_relation_nr_r17_e ssb_position_qcl_common_nr_r17; + copy_ptr ssb_position_qcl_cells_to_add_mod_list_nr_r17; + copy_ptr ssb_position_qcl_cells_to_rem_list_nr_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1488,150 +1982,35 @@ typedef enumerated report_interv_e; // ReportQuantityNR-r15 ::= SEQUENCE struct report_quant_nr_r15_s { bool ss_rsrp = false; - bool ss_rsrq = false; - bool ss_sinr = false; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool operator==(const report_quant_nr_r15_s& other) const; - bool operator!=(const report_quant_nr_r15_s& other) const { return not(*this == other); } -}; - -// ReportQuantityWLAN-r13 ::= SEQUENCE -struct report_quant_wlan_r13_s { - bool ext = false; - bool band_request_wlan_r13_present = false; - bool carrier_info_request_wlan_r13_present = false; - bool available_admission_capacity_request_wlan_r13_present = false; - bool backhaul_dl_bw_request_wlan_r13_present = false; - bool backhaul_ul_bw_request_wlan_r13_present = false; - bool ch_utilization_request_wlan_r13_present = false; - bool station_count_request_wlan_r13_present = false; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool operator==(const report_quant_wlan_r13_s& other) const; - bool operator!=(const report_quant_wlan_r13_s& other) const { return not(*this == other); } -}; - -// ThresholdEUTRA ::= CHOICE -struct thres_eutra_c { - struct types_opts { - enum options { thres_rsrp, thres_rsrq, nulltype } value; - - const char* to_string() const; - }; - typedef enumerated types; - - // choice methods - thres_eutra_c() = default; - thres_eutra_c(const thres_eutra_c& other); - thres_eutra_c& operator=(const thres_eutra_c& other); - ~thres_eutra_c() { destroy_(); } - void set(types::options e = types::nulltype); - types type() const { return type_; } - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool operator==(const thres_eutra_c& other) const; - bool operator!=(const thres_eutra_c& other) const { return not(*this == other); } - // getters - uint8_t& thres_rsrp() - { - assert_choice_type(types::thres_rsrp, type_, "ThresholdEUTRA"); - return c.get(); - } - uint8_t& thres_rsrq() - { - assert_choice_type(types::thres_rsrq, type_, "ThresholdEUTRA"); - return c.get(); - } - const uint8_t& thres_rsrp() const - { - assert_choice_type(types::thres_rsrp, type_, "ThresholdEUTRA"); - return c.get(); - } - const uint8_t& thres_rsrq() const - { - assert_choice_type(types::thres_rsrq, type_, "ThresholdEUTRA"); - return c.get(); - } - uint8_t& set_thres_rsrp(); - uint8_t& set_thres_rsrq(); - -private: - types type_; - pod_choice_buffer_t c; - - void destroy_(); -}; - -// ThresholdNR-r15 ::= CHOICE -struct thres_nr_r15_c { - struct types_opts { - enum options { nr_rsrp_r15, nr_rsrq_r15, nr_sinr_r15, nulltype } value; - - const char* to_string() const; - }; - typedef enumerated types; + bool ss_rsrq = false; + bool ss_sinr = false; - // choice methods - thres_nr_r15_c() = default; - thres_nr_r15_c(const thres_nr_r15_c& other); - thres_nr_r15_c& operator=(const thres_nr_r15_c& other); - ~thres_nr_r15_c() { destroy_(); } - void set(types::options e = types::nulltype); - types type() const { return type_; } + // sequence methods SRSASN_CODE pack(bit_ref& bref) const; SRSASN_CODE unpack(cbit_ref& bref); void to_json(json_writer& j) const; - bool operator==(const thres_nr_r15_c& other) const; - bool operator!=(const thres_nr_r15_c& other) const { return not(*this == other); } - // getters - uint8_t& nr_rsrp_r15() - { - assert_choice_type(types::nr_rsrp_r15, type_, "ThresholdNR-r15"); - return c.get(); - } - uint8_t& nr_rsrq_r15() - { - assert_choice_type(types::nr_rsrq_r15, type_, "ThresholdNR-r15"); - return c.get(); - } - uint8_t& nr_sinr_r15() - { - assert_choice_type(types::nr_sinr_r15, type_, "ThresholdNR-r15"); - return c.get(); - } - const uint8_t& nr_rsrp_r15() const - { - assert_choice_type(types::nr_rsrp_r15, type_, "ThresholdNR-r15"); - return c.get(); - } - const uint8_t& nr_rsrq_r15() const - { - assert_choice_type(types::nr_rsrq_r15, type_, "ThresholdNR-r15"); - return c.get(); - } - const uint8_t& nr_sinr_r15() const - { - assert_choice_type(types::nr_sinr_r15, type_, "ThresholdNR-r15"); - return c.get(); - } - uint8_t& set_nr_rsrp_r15(); - uint8_t& set_nr_rsrq_r15(); - uint8_t& set_nr_sinr_r15(); + bool operator==(const report_quant_nr_r15_s& other) const; + bool operator!=(const report_quant_nr_r15_s& other) const { return not(*this == other); } +}; -private: - types type_; - pod_choice_buffer_t c; +// ReportQuantityWLAN-r13 ::= SEQUENCE +struct report_quant_wlan_r13_s { + bool ext = false; + bool band_request_wlan_r13_present = false; + bool carrier_info_request_wlan_r13_present = false; + bool available_admission_capacity_request_wlan_r13_present = false; + bool backhaul_dl_bw_request_wlan_r13_present = false; + bool backhaul_ul_bw_request_wlan_r13_present = false; + bool ch_utilization_request_wlan_r13_present = false; + bool station_count_request_wlan_r13_present = false; + // ... - void destroy_(); + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const report_quant_wlan_r13_s& other) const; + bool operator!=(const report_quant_wlan_r13_s& other) const { return not(*this == other); } }; // ThresholdUTRA ::= CHOICE @@ -1688,34 +2067,6 @@ struct thres_utra_c { void destroy_(); }; -// TimeToTrigger ::= ENUMERATED -struct time_to_trigger_opts { - enum options { - ms0, - ms40, - ms64, - ms80, - ms100, - ms128, - ms160, - ms256, - ms320, - ms480, - ms512, - ms640, - ms1024, - ms1280, - ms2560, - ms5120, - nulltype - } value; - typedef uint16_t number_type; - - const char* to_string() const; - uint16_t to_number() const; -}; -typedef enumerated time_to_trigger_e; - // Tx-ResourcePoolMeasList-r14 ::= SEQUENCE (SIZE (1..72)) OF INTEGER (1..72) using tx_res_pool_meas_list_r14_l = dyn_array; @@ -1782,6 +2133,44 @@ struct ul_delay_cfg_r13_c { setup_s_ c; }; +// UL-DelayValueConfig-r16 ::= CHOICE +struct ul_delay_value_cfg_r16_c { + struct setup_s_ { + using delay_dr_blist_r16_l_ = bounded_array; + + // member variables + delay_dr_blist_r16_l_ delay_dr_blist_r16; + }; + using types = setup_e; + + // choice methods + ul_delay_value_cfg_r16_c() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const ul_delay_value_cfg_r16_c& other) const; + bool operator!=(const ul_delay_value_cfg_r16_c& other) const { return not(*this == other); } + // getters + setup_s_& setup() + { + assert_choice_type(types::setup, type_, "UL-DelayValueConfig-r16"); + return c; + } + const setup_s_& setup() const + { + assert_choice_type(types::setup, type_, "UL-DelayValueConfig-r16"); + return c; + } + void set_release(); + setup_s_& set_setup(); + +private: + types type_; + setup_s_ c; +}; + // WLAN-CarrierInfo-r13 ::= SEQUENCE struct wlan_carrier_info_r13_s { struct country_code_r13_opts { @@ -1844,9 +2233,6 @@ struct wlan_name_list_cfg_r15_c { wlan_name_list_r15_l c; }; -// WhiteCellsToAddModList-r13 ::= SEQUENCE (SIZE (1..32)) OF WhiteCellsToAddMod-r13 -using white_cells_to_add_mod_list_r13_l = dyn_array; - // MeasGapConfigPerCC-r14 ::= SEQUENCE struct meas_gap_cfg_per_cc_r14_s { uint8_t serv_cell_id_r14 = 0; @@ -1925,23 +2311,23 @@ struct meas_obj_eutra_s { }; // member variables - bool ext = false; - bool offset_freq_present = false; - bool cells_to_rem_list_present = false; - bool cells_to_add_mod_list_present = false; - bool black_cells_to_rem_list_present = false; - bool black_cells_to_add_mod_list_present = false; - bool cell_for_which_to_report_cgi_present = false; - uint32_t carrier_freq = 0; - allowed_meas_bw_e allowed_meas_bw; - bool presence_ant_port1 = false; - fixed_bitstring<2> neigh_cell_cfg; - q_offset_range_e offset_freq; - cell_idx_list_l cells_to_rem_list; - cells_to_add_mod_list_l cells_to_add_mod_list; - cell_idx_list_l black_cells_to_rem_list; - black_cells_to_add_mod_list_l black_cells_to_add_mod_list; - uint16_t cell_for_which_to_report_cgi = 0; + bool ext = false; + bool offset_freq_present = false; + bool cells_to_rem_list_present = false; + bool cells_to_add_mod_list_present = false; + bool excluded_cells_to_rem_list_present = false; + bool excluded_cells_to_add_mod_list_present = false; + bool cell_for_which_to_report_cgi_present = false; + uint32_t carrier_freq = 0; + allowed_meas_bw_e allowed_meas_bw; + bool presence_ant_port1 = false; + fixed_bitstring<2> neigh_cell_cfg; + q_offset_range_e offset_freq; + cell_idx_list_l cells_to_rem_list; + cells_to_add_mod_list_l cells_to_add_mod_list; + cell_idx_list_l excluded_cells_to_rem_list; + excluded_cells_to_add_mod_list_l excluded_cells_to_add_mod_list; + uint16_t cell_for_which_to_report_cgi = 0; // ... // group 0 bool meas_cycle_scell_r10_present = false; @@ -1958,11 +2344,11 @@ struct meas_obj_eutra_s { bool reduced_meas_performance_r12 = false; copy_ptr meas_ds_cfg_r12; // group 3 - bool carrier_freq_r13_present = false; - copy_ptr white_cells_to_rem_list_r13; - copy_ptr white_cells_to_add_mod_list_r13; - copy_ptr rmtc_cfg_r13; - uint32_t carrier_freq_r13 = 65536; + bool carrier_freq_r13_present = false; + copy_ptr allowed_cells_to_rem_list_r13; + copy_ptr allowed_cells_to_add_mod_list_r13; + copy_ptr rmtc_cfg_r13; + uint32_t carrier_freq_r13 = 65536; // group 4 bool fembms_mixed_carrier_r14_present = false; copy_ptr tx_res_pool_to_rem_list_r14; @@ -1970,6 +2356,8 @@ struct meas_obj_eutra_s { bool fembms_mixed_carrier_r14 = false; // group 5 copy_ptr meas_sensing_cfg_r15; + // group 6 + copy_ptr > meas_rss_ded_cfg_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2048,16 +2436,16 @@ struct meas_obj_nr_r15_s { bool thresh_rs_idx_r15_present = false; bool max_rs_idx_cell_qual_r15_present = false; bool offset_freq_r15_present = false; - bool black_cells_to_rem_list_r15_present = false; - bool black_cells_to_add_mod_list_r15_present = false; + bool excluded_cells_to_rem_list_r15_present = false; + bool excluded_cells_to_add_mod_list_r15_present = false; bool cells_for_which_to_report_sftd_r15_present = false; uint32_t carrier_freq_r15 = 0; rs_cfg_ssb_nr_r15_s rs_cfg_ssb_r15; thres_list_nr_r15_s thresh_rs_idx_r15; uint8_t max_rs_idx_cell_qual_r15 = 1; int8_t offset_freq_r15 = -15; - cell_idx_list_l black_cells_to_rem_list_r15; - cells_to_add_mod_list_nr_r15_l black_cells_to_add_mod_list_r15; + cell_idx_list_l excluded_cells_to_rem_list_r15; + cells_to_add_mod_list_nr_r15_l excluded_cells_to_add_mod_list_r15; uint8_t quant_cfg_set_r15 = 1; cells_for_which_to_report_sftd_r15_l_ cells_for_which_to_report_sftd_r15; // ... @@ -2068,6 +2456,11 @@ struct meas_obj_nr_r15_s { bool derive_ssb_idx_from_cell_r15 = false; copy_ptr ss_rssi_meas_r15; copy_ptr band_nr_r15; + // group 1 + copy_ptr > rmtc_cfg_nr_r16; + // group 2 + copy_ptr cells_to_rem_list_r16; + copy_ptr cells_to_add_mod_list_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2737,11 +3130,11 @@ struct report_cfg_eutra_s { bool trigger_quant_csi_rs_r12 = false; // group 3 bool report_sstd_meas_r13_present = false; - bool use_white_cell_list_r13_present = false; + bool use_allowed_cell_list_r13_present = false; bool include_multi_band_info_r13_present = false; bool report_sstd_meas_r13 = false; copy_ptr rs_sinr_cfg_r13; - bool use_white_cell_list_r13 = false; + bool use_allowed_cell_list_r13 = false; copy_ptr meas_rssi_report_cfg_r13; copy_ptr ul_delay_cfg_r13; // group 4 @@ -2761,6 +3154,13 @@ struct report_cfg_eutra_s { copy_ptr include_wlan_meas_r15; uint8_t nof_trigger_cells_r15 = 2; bool a4_a5_report_on_leave_r15 = false; + // group 8 + copy_ptr cond_recfg_trigger_eutra_r16; + copy_ptr ul_delay_value_cfg_r16; + // group 9 + bool include_uncom_bar_pre_meas_r17_present = false; + bool coarse_location_req_r17_present = false; + bool include_uncom_bar_pre_meas_r17 = false; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3189,6 +3589,11 @@ struct report_cfg_inter_rat_s { copy_ptr report_quant_rs_idx_nr_r15; bool report_rs_idx_results_nr = false; report_sftd_meas_r15_e_ report_sftd_meas_r15; + // group 7 + bool use_autonomous_gaps_nr_r16_present = false; + copy_ptr meas_rssi_report_cfg_nr_r16; + // group 8 + copy_ptr cond_recfg_trigger_nr_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3500,6 +3905,170 @@ struct meas_obj_to_add_mod_ext_r13_s { void to_json(json_writer& j) const; }; +// PUR-PeriodicityAndOffset-r16 ::= CHOICE +struct pur_periodicity_and_offset_r16_c { + struct types_opts { + enum options { + periodicity8, + periodicity16, + periodicity32, + periodicity64, + periodicity128, + periodicity256, + periodicity512, + periodicity1024, + periodicity2048, + periodicity4096, + periodicity8192, + nulltype + } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated types; + + // choice methods + pur_periodicity_and_offset_r16_c() = default; + pur_periodicity_and_offset_r16_c(const pur_periodicity_and_offset_r16_c& other); + pur_periodicity_and_offset_r16_c& operator=(const pur_periodicity_and_offset_r16_c& other); + ~pur_periodicity_and_offset_r16_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint8_t& periodicity8() + { + assert_choice_type(types::periodicity8, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + uint8_t& periodicity16() + { + assert_choice_type(types::periodicity16, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + uint8_t& periodicity32() + { + assert_choice_type(types::periodicity32, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + uint8_t& periodicity64() + { + assert_choice_type(types::periodicity64, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + uint8_t& periodicity128() + { + assert_choice_type(types::periodicity128, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + uint16_t& periodicity256() + { + assert_choice_type(types::periodicity256, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + uint16_t& periodicity512() + { + assert_choice_type(types::periodicity512, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + uint16_t& periodicity1024() + { + assert_choice_type(types::periodicity1024, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + uint16_t& periodicity2048() + { + assert_choice_type(types::periodicity2048, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + uint16_t& periodicity4096() + { + assert_choice_type(types::periodicity4096, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + uint16_t& periodicity8192() + { + assert_choice_type(types::periodicity8192, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + const uint8_t& periodicity8() const + { + assert_choice_type(types::periodicity8, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + const uint8_t& periodicity16() const + { + assert_choice_type(types::periodicity16, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + const uint8_t& periodicity32() const + { + assert_choice_type(types::periodicity32, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + const uint8_t& periodicity64() const + { + assert_choice_type(types::periodicity64, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + const uint8_t& periodicity128() const + { + assert_choice_type(types::periodicity128, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + const uint16_t& periodicity256() const + { + assert_choice_type(types::periodicity256, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + const uint16_t& periodicity512() const + { + assert_choice_type(types::periodicity512, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + const uint16_t& periodicity1024() const + { + assert_choice_type(types::periodicity1024, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + const uint16_t& periodicity2048() const + { + assert_choice_type(types::periodicity2048, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + const uint16_t& periodicity4096() const + { + assert_choice_type(types::periodicity4096, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + const uint16_t& periodicity8192() const + { + assert_choice_type(types::periodicity8192, type_, "PUR-PeriodicityAndOffset-r16"); + return c.get(); + } + uint8_t& set_periodicity8(); + uint8_t& set_periodicity16(); + uint8_t& set_periodicity32(); + uint8_t& set_periodicity64(); + uint8_t& set_periodicity128(); + uint16_t& set_periodicity256(); + uint16_t& set_periodicity512(); + uint16_t& set_periodicity1024(); + uint16_t& set_periodicity2048(); + uint16_t& set_periodicity4096(); + uint16_t& set_periodicity8192(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + // QuantityConfigCDMA2000 ::= SEQUENCE struct quant_cfg_cdma2000_s { struct meas_quant_cdma2000_opts { @@ -4413,10 +4982,75 @@ struct meas_cfg_s { void to_json(json_writer& j) const; }; -// CarrierFreqGERAN ::= SEQUENCE -struct carrier_freq_geran_s { - uint16_t arfcn = 0; - band_ind_geran_e band_ind; +// EventType-r17 ::= CHOICE +struct event_type_r17_c { + struct event_l1_s_ { + thres_eutra_c l1_thres_r17; + uint8_t hysteresis_r17 = 0; + time_to_trigger_e time_to_trigger_r17; + }; + struct types_opts { + enum options { out_of_coverage, event_l1, /*...*/ nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + event_type_r17_c() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + event_l1_s_& event_l1() + { + assert_choice_type(types::event_l1, type_, "EventType-r17"); + return c; + } + const event_l1_s_& event_l1() const + { + assert_choice_type(types::event_l1, type_, "EventType-r17"); + return c; + } + void set_out_of_coverage(); + event_l1_s_& set_event_l1(); + +private: + types type_; + event_l1_s_ c; +}; + +// LoggedEventTriggerConfig-r17 ::= SEQUENCE +struct logged_event_trigger_cfg_r17_s { + event_type_r17_c event_type_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CarrierFreqGERAN ::= SEQUENCE +struct carrier_freq_geran_s { + uint16_t arfcn = 0; + band_ind_geran_e band_ind; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// LoggedMeasurementConfiguration-v1700-IEs ::= SEQUENCE +struct logged_meas_cfg_v1700_ies_s { + bool logged_event_trigger_cfg_r17_present = false; + bool meas_uncom_bar_pre_r17_present = false; + bool non_crit_ext_present = false; + logged_event_trigger_cfg_r17_s logged_event_trigger_cfg_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -4426,11 +5060,12 @@ struct carrier_freq_geran_s { // LoggedMeasurementConfiguration-v1530-IEs ::= SEQUENCE struct logged_meas_cfg_v1530_ies_s { - bool bt_name_list_r15_present = false; - bool wlan_name_list_r15_present = false; - bool non_crit_ext_present = false; - bt_name_list_r15_l bt_name_list_r15; - wlan_name_list_r15_l wlan_name_list_r15; + bool bt_name_list_r15_present = false; + bool wlan_name_list_r15_present = false; + bool non_crit_ext_present = false; + bt_name_list_r15_l bt_name_list_r15; + wlan_name_list_r15_l wlan_name_list_r15; + logged_meas_cfg_v1700_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -4449,6 +5084,18 @@ struct cell_global_id_eutra_s { void to_json(json_writer& j) const; }; +// DAPS-PowerCoordinationInfo-r16 ::= SEQUENCE +struct daps_pwr_coordination_info_r16_s { + uint8_t p_daps_source_r16 = 1; + uint8_t p_daps_target_r16 = 1; + uint8_t pwr_ctrl_mode_r16 = 1; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CarrierBandwidthEUTRA ::= SEQUENCE struct carrier_bw_eutra_s { struct dl_bw_opts { @@ -4539,6 +5186,19 @@ struct carrier_freq_eutra_v9e0_s { void to_json(json_writer& j) const; }; +// DAPS-Config-r16 ::= SEQUENCE +struct daps_cfg_r16_s { + bool ext = false; + bool daps_pwr_coordination_info_r16_present = false; + daps_pwr_coordination_info_r16_s daps_pwr_coordination_info_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MobilityControlInfoV2X-r14 ::= SEQUENCE struct mob_ctrl_info_v2x_r14_s { bool v2x_comm_tx_pool_exceptional_r14_present = false; @@ -4604,6 +5264,8 @@ struct mob_ctrl_info_s { bool sched_info_sib1_br_r14_present = false; bool mib_repeat_status_r14 = false; uint8_t sched_info_sib1_br_r14 = 0; + // group 4 + copy_ptr daps_cfg_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -4622,6 +5284,52 @@ struct trace_ref_r10_s { void to_json(json_writer& j) const; }; +// PLMN-IdentityListNR-r15 ::= SEQUENCE (SIZE (1..12)) OF PLMN-Identity +using plmn_id_list_nr_r15_l = dyn_array; + +// MeasResultNR-r15 ::= SEQUENCE +struct meas_result_nr_r15_s { + bool ext = false; + bool rsrp_result_r15_present = false; + bool rsrq_result_r15_present = false; + bool rs_sinr_result_r15_present = false; + uint8_t rsrp_result_r15 = 0; + uint8_t rsrq_result_r15 = 0; + uint8_t rs_sinr_result_r15 = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PLMN-IdentityInfoNR-r15 ::= SEQUENCE +struct plmn_id_info_nr_r15_s { + bool tac_r15_present = false; + bool ran_area_code_r15_present = false; + plmn_id_list_nr_r15_l plmn_id_list_r15; + fixed_bitstring<24> tac_r15; + uint16_t ran_area_code_r15 = 0; + fixed_bitstring<36> cell_id_r15; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PLMN-IdentityInfoNR-v1710 ::= SEQUENCE +struct plmn_id_info_nr_v1710_s { + bool gnb_id_len_r17_present = false; + uint8_t gnb_id_len_r17 = 22; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CellGlobalIdCDMA2000 ::= CHOICE struct cell_global_id_cdma2000_c { struct types_opts { @@ -4674,6 +5382,26 @@ struct cell_global_id_cdma2000_c { void destroy_(); }; +// MeasResultSSB-Index-r15 ::= SEQUENCE +struct meas_result_ssb_idx_r15_s { + bool ext = false; + bool meas_result_ssb_idx_r15_present = false; + uint8_t ssb_idx_r15 = 0; + meas_result_nr_r15_s meas_result_ssb_idx_r15; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PLMN-IdentityInfoListNR-r15 ::= SEQUENCE (SIZE (1..12)) OF PLMN-IdentityInfoNR-r15 +using plmn_id_info_list_nr_r15_l = dyn_array; + +// PLMN-IdentityInfoListNR-v1710 ::= SEQUENCE (SIZE (1..12)) OF PLMN-IdentityInfoNR-v1710 +using plmn_id_info_list_nr_v1710_l = dyn_array; + // AdditionalSI-Info-r9 ::= SEQUENCE struct add_si_info_r9_s { bool csg_member_status_r9_present = false; @@ -4703,6 +5431,31 @@ struct bler_result_r12_s { void to_json(json_writer& j) const; }; +// CGI-InfoNR-r15 ::= SEQUENCE +struct cgi_info_nr_r15_s { + struct no_sib1_r15_s_ { + uint8_t ssb_subcarrier_offset_r15 = 0; + uint16_t pdcch_cfg_sib1_r15 = 0; + }; + + // member variables + bool ext = false; + bool plmn_id_info_list_r15_present = false; + bool freq_band_list_r15_present = false; + bool no_sib1_r15_present = false; + plmn_id_info_list_nr_r15_l plmn_id_info_list_r15; + multi_freq_band_list_nr_r15_l freq_band_list_r15; + no_sib1_r15_s_ no_sib1_r15; + // ... + // group 0 + copy_ptr plmn_id_info_list_v1710; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CellGlobalIdUTRA ::= SEQUENCE struct cell_global_id_utra_s { plmn_id_s plmn_id; @@ -4736,6 +5489,9 @@ struct meas_result_cdma2000_s { void to_json(json_writer& j) const; }; +// MeasResultSSB-IndexList-r15 ::= SEQUENCE (SIZE (1..32)) OF MeasResultSSB-Index-r15 +using meas_result_ssb_idx_list_r15_l = dyn_array; + // PLMN-IdentityList2 ::= SEQUENCE (SIZE (1..5)) OF PLMN-Identity using plmn_id_list2_l = dyn_array; @@ -4762,6 +5518,23 @@ struct data_bler_mch_result_r12_s { void to_json(json_writer& j) const; }; +// MeasResultCellNR-r15 ::= SEQUENCE +struct meas_result_cell_nr_r15_s { + bool ext = false; + bool meas_result_rs_idx_list_r15_present = false; + uint16_t pci_r15 = 0; + meas_result_nr_r15_s meas_result_cell_r15; + meas_result_ssb_idx_list_r15_l meas_result_rs_idx_list_r15; + // ... + // group 0 + copy_ptr cgi_info_r15; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MeasResultEUTRA ::= SEQUENCE struct meas_result_eutra_s { struct cgi_info_s_ { @@ -4913,9 +5686,6 @@ struct meas_result_utra_s { void to_json(json_writer& j) const; }; -// PLMN-IdentityListNR-r15 ::= SEQUENCE (SIZE (1..12)) OF PLMN-Identity -using plmn_id_list_nr_r15_l = dyn_array; - // DataBLER-MCH-ResultList-r12 ::= SEQUENCE (SIZE (1..15)) OF DataBLER-MCH-Result-r12 using data_bler_mch_result_list_r12_l = dyn_array; @@ -5102,6 +5872,9 @@ struct location_info_r10_s { void to_json(json_writer& j) const; }; +// MeasResultCellListNR-r15 ::= SEQUENCE (SIZE (1..8)) OF MeasResultCellNR-r15 +using meas_result_cell_list_nr_r15_l = dyn_array; + // MeasResultGERAN ::= SEQUENCE struct meas_result_geran_s { struct cgi_info_s_ { @@ -5134,23 +5907,6 @@ using meas_result_list_eutra_l = dyn_array; // MeasResultListUTRA ::= SEQUENCE (SIZE (1..8)) OF MeasResultUTRA using meas_result_list_utra_l = dyn_array; -// MeasResultNR-r15 ::= SEQUENCE -struct meas_result_nr_r15_s { - bool ext = false; - bool rsrp_result_r15_present = false; - bool rsrq_result_r15_present = false; - bool rs_sinr_result_r15_present = false; - uint8_t rsrp_result_r15 = 0; - uint8_t rsrq_result_r15 = 0; - uint8_t rs_sinr_result_r15 = 0; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - // MeasResultsCDMA2000 ::= SEQUENCE struct meas_results_cdma2000_s { bool pre_regist_status_hrpd = false; @@ -5162,21 +5918,6 @@ struct meas_results_cdma2000_s { void to_json(json_writer& j) const; }; -// PLMN-IdentityInfoNR-r15 ::= SEQUENCE -struct plmn_id_info_nr_r15_s { - bool tac_r15_present = false; - bool ran_area_code_r15_present = false; - plmn_id_list_nr_r15_l plmn_id_list_r15; - fixed_bitstring<24> tac_r15; - uint16_t ran_area_code_r15 = 0; - fixed_bitstring<36> cell_id_r15; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - // RSRQ-Type-r12 ::= SEQUENCE struct rsrq_type_r12_s { bool all_symbols_r12 = false; @@ -5303,6 +6044,20 @@ struct meas_result2_utra_r9_s { void to_json(json_writer& j) const; }; +// MeasResultFreqFailNR-r15 ::= SEQUENCE +struct meas_result_freq_fail_nr_r15_s { + bool ext = false; + bool meas_result_cell_list_r15_present = false; + uint32_t carrier_freq_r15 = 0; + meas_result_cell_list_nr_r15_l meas_result_cell_list_r15; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MeasResultListGERAN ::= SEQUENCE (SIZE (1..8)) OF MeasResultGERAN using meas_result_list_geran_l = dyn_array; @@ -5330,52 +6085,15 @@ struct meas_result_mbsfn_r12_s { void to_json(json_writer& j) const; }; -// MeasResultSSB-Index-r15 ::= SEQUENCE -struct meas_result_ssb_idx_r15_s { - bool ext = false; - bool meas_result_ssb_idx_r15_present = false; - uint8_t ssb_idx_r15 = 0; - meas_result_nr_r15_s meas_result_ssb_idx_r15; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - -// PLMN-IdentityInfoListNR-r15 ::= SEQUENCE (SIZE (1..12)) OF PLMN-IdentityInfoNR-r15 -using plmn_id_info_list_nr_r15_l = dyn_array; - -// CGI-InfoNR-r15 ::= SEQUENCE -struct cgi_info_nr_r15_s { - struct no_sib1_r15_s_ { - uint8_t ssb_subcarrier_offset_r15 = 0; - uint16_t pdcch_cfg_sib1_r15 = 0; - }; - - // member variables - bool ext = false; - bool plmn_id_info_list_r15_present = false; - bool freq_band_list_r15_present = false; - bool no_sib1_r15_present = false; - plmn_id_info_list_nr_r15_l plmn_id_info_list_r15; - multi_freq_band_list_nr_r15_l freq_band_list_r15; - no_sib1_r15_s_ no_sib1_r15; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - // LogMeasResultListBT-r15 ::= SEQUENCE (SIZE (1..32)) OF LogMeasResultBT-r15 using log_meas_result_list_bt_r15_l = dyn_array; // LogMeasResultListWLAN-r15 ::= SEQUENCE (SIZE (1..32)) OF LogMeasResultWLAN-r15 using log_meas_result_list_wlan_r15_l = dyn_array; +// MeasResultFreqListNR-r16 ::= SEQUENCE (SIZE (1..7)) OF MeasResultFreqFailNR-r15 +using meas_result_freq_list_nr_r16_l = dyn_array; + // MeasResultList2CDMA2000-r9 ::= SEQUENCE (SIZE (1..8)) OF MeasResult2CDMA2000-r9 using meas_result_list2_cdma2000_r9_l = dyn_array; @@ -5397,9 +6115,6 @@ using meas_result_list2_utra_r9_l = dyn_array; // MeasResultListMBSFN-r12 ::= SEQUENCE (SIZE (1..8)) OF MeasResultMBSFN-r12 using meas_result_list_mbsfn_r12_l = dyn_array; -// MeasResultSSB-IndexList-r15 ::= SEQUENCE (SIZE (1..32)) OF MeasResultSSB-Index-r15 -using meas_result_ssb_idx_list_r15_l = dyn_array; - // LogMeasInfo-r10 ::= SEQUENCE struct log_meas_info_r10_s { struct meas_result_serv_cell_r10_s_ { @@ -5416,6 +6131,9 @@ struct log_meas_info_r10_s { meas_result_list2_geran_r10_l meas_result_list_geran_r10; meas_result_list2_cdma2000_r9_l meas_result_list_cdma2000_r10; }; + struct meas_result_list_nr_v1640_s_ { + uint32_t carrier_freq_nr_r16 = 0; + }; // member variables bool ext = false; @@ -5445,23 +6163,14 @@ struct log_meas_info_r10_s { copy_ptr log_meas_result_list_wlan_r15; // group 5 bool any_cell_sel_detected_r15_present = false; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - -// MeasResultCellNR-r15 ::= SEQUENCE -struct meas_result_cell_nr_r15_s { - bool ext = false; - bool meas_result_rs_idx_list_r15_present = false; - uint16_t pci_r15 = 0; - meas_result_nr_r15_s meas_result_cell_r15; - meas_result_ssb_idx_list_r15_l meas_result_rs_idx_list_r15; - // ... - // group 0 - copy_ptr cgi_info_r15; + // group 6 + copy_ptr meas_result_list_nr_r16; + // group 7 + copy_ptr meas_result_list_nr_v1640; + copy_ptr meas_result_list_ext_nr_r16; + // group 8 + bool uncom_bar_pre_meas_result_r17_present = false; + dyn_octstring uncom_bar_pre_meas_result_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -5472,9 +6181,6 @@ struct meas_result_cell_nr_r15_s { // LogMeasInfoList-r10 ::= SEQUENCE (SIZE (1..520)) OF LogMeasInfo-r10 using log_meas_info_list_r10_l = dyn_array; -// MeasResultCellListNR-r15 ::= SEQUENCE (SIZE (1..8)) OF MeasResultCellNR-r15 -using meas_result_cell_list_nr_r15_l = dyn_array; - // LogMeasReport-r10 ::= SEQUENCE struct log_meas_report_r10_s { bool ext = false; @@ -5689,6 +6395,19 @@ struct ul_pdcp_delay_result_r13_s { void to_json(json_writer& j) const; }; +// UL-PDCP-DelayValueResult-r16 ::= SEQUENCE +struct ul_pdcp_delay_value_result_r16_s { + bool ext = false; + uint8_t drb_id_r16 = 1; + uint16_t average_delay_r16 = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MeasResultCSI-RS-List-r12 ::= SEQUENCE (SIZE (1..8)) OF MeasResultCSI-RS-r12 using meas_result_csi_rs_list_r12_l = dyn_array; @@ -5706,6 +6425,19 @@ struct meas_result_for_ecid_r9_s { void to_json(json_writer& j) const; }; +// MeasResultForRSSI-NR-r16 ::= SEQUENCE +struct meas_result_for_rssi_nr_r16_s { + bool ext = false; + uint8_t rssi_result_nr_r16 = 0; + uint8_t ch_occupancy_nr_r16 = 0; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MeasResultForRSSI-r13 ::= SEQUENCE struct meas_result_for_rssi_r13_s { bool ext = false; @@ -5766,6 +6498,9 @@ using meas_result_serv_freq_list_nr_r15_l = dyn_array; +// UL-PDCP-DelayValueResultList-r16 ::= SEQUENCE (SIZE (1..11)) OF UL-PDCP-DelayValueResult-r16 +using ul_pdcp_delay_value_result_list_r16_l = dyn_array; + // MeasResults ::= SEQUENCE struct meas_results_s { struct meas_result_pcell_s_ { @@ -5912,6 +6647,14 @@ struct meas_results_s { copy_ptr log_meas_result_list_wlan_r15; copy_ptr meas_result_sensing_r15; int16_t height_ue_r15 = -400; + // group 8 + copy_ptr ul_pdcp_delay_value_result_list_r16; + copy_ptr meas_result_for_rssi_nr_r16; + // group 9 + bool uncom_bar_pre_meas_result_r17_present = false; + bool coarse_location_info_r17_present = false; + dyn_octstring uncom_bar_pre_meas_result_r17; + dyn_octstring coarse_location_info_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; diff --git a/lib/include/srsran/asn1/rrc/paging.h b/lib/include/srsran/asn1/rrc/paging.h index f4ec707db6..7dfa6e5b82 100644 --- a/lib/include/srsran/asn1/rrc/paging.h +++ b/lib/include/srsran/asn1/rrc/paging.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -37,10 +37,64 @@ namespace rrc { * Struct Definitions ******************************************************************************/ +// PagingRecord-v1700 ::= SEQUENCE +struct paging_record_v1700_s { + bool paging_cause_r17_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PagingRecord-v1610 ::= SEQUENCE +struct paging_record_v1610_s { + bool access_type_r16_present = false; + bool mt_edt_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PagingRecordList-v1700 ::= SEQUENCE (SIZE (1..16)) OF PagingRecord-v1700 +using paging_record_list_v1700_l = dyn_array; + +// Paging-v1700-IEs ::= SEQUENCE +struct paging_v1700_ies_s { + bool paging_record_list_v1700_present = false; + bool non_crit_ext_present = false; + paging_record_list_v1700_l paging_record_list_v1700; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PagingRecordList-v1610 ::= SEQUENCE (SIZE (1..16)) OF PagingRecord-v1610 +using paging_record_list_v1610_l = dyn_array; + +// Paging-v1610-IEs ::= SEQUENCE +struct paging_v1610_ies_s { + bool paging_record_list_v1610_present = false; + bool uac_param_mod_r16_present = false; + bool non_crit_ext_present = false; + paging_record_list_v1610_l paging_record_list_v1610; + paging_v1700_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // Paging-v1530-IEs ::= SEQUENCE struct paging_v1530_ies_s { - bool access_type_present = false; - bool non_crit_ext_present = false; + bool access_type_present = false; + bool non_crit_ext_present = false; + paging_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -393,6 +447,17 @@ struct ue_paging_coverage_info_s { void to_json(json_writer& j) const; }; +// UERadioPagingInformation-v1610-IEs ::= SEQUENCE +struct ue_radio_paging_info_v1610_ies_s { + bool access_stratum_release_r16_present = false; + bool non_crit_ext_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // UERadioPagingInformation-v1310-IEs ::= SEQUENCE struct ue_radio_paging_info_v1310_ies_s { using supported_band_list_eutra_for_paging_r13_l_ = dyn_array; @@ -401,6 +466,7 @@ struct ue_radio_paging_info_v1310_ies_s { bool supported_band_list_eutra_for_paging_r13_present = false; bool non_crit_ext_present = false; supported_band_list_eutra_for_paging_r13_l_ supported_band_list_eutra_for_paging_r13; + ue_radio_paging_info_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; diff --git a/lib/include/srsran/asn1/rrc/phy_ded.h b/lib/include/srsran/asn1/rrc/phy_ded.h index 1d99d14144..304228705c 100644 --- a/lib/include/srsran/asn1/rrc/phy_ded.h +++ b/lib/include/srsran/asn1/rrc/phy_ded.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,14 +21,14 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ #ifndef SRSASN1_RRC_PHYCFG_H #define SRSASN1_RRC_PHYCFG_H -#include "common.h" +#include "rr_common.h" namespace asn1 { namespace rrc { @@ -37,6 +37,338 @@ namespace rrc { * Struct Definitions ******************************************************************************/ +// PeriodicityStartPos-r16 ::= CHOICE +struct periodicity_start_pos_r16_c { + struct types_opts { + enum options { + periodicity10ms, + periodicity20ms, + periodicity40ms, + periodicity80ms, + periodicity160ms, + spare3, + spare2, + spare1, + nulltype + } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + periodicity_start_pos_r16_c() = default; + periodicity_start_pos_r16_c(const periodicity_start_pos_r16_c& other); + periodicity_start_pos_r16_c& operator=(const periodicity_start_pos_r16_c& other); + ~periodicity_start_pos_r16_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint8_t& periodicity20ms() + { + assert_choice_type(types::periodicity20ms, type_, "PeriodicityStartPos-r16"); + return c.get(); + } + uint8_t& periodicity40ms() + { + assert_choice_type(types::periodicity40ms, type_, "PeriodicityStartPos-r16"); + return c.get(); + } + uint8_t& periodicity80ms() + { + assert_choice_type(types::periodicity80ms, type_, "PeriodicityStartPos-r16"); + return c.get(); + } + uint8_t& periodicity160ms() + { + assert_choice_type(types::periodicity160ms, type_, "PeriodicityStartPos-r16"); + return c.get(); + } + const uint8_t& periodicity20ms() const + { + assert_choice_type(types::periodicity20ms, type_, "PeriodicityStartPos-r16"); + return c.get(); + } + const uint8_t& periodicity40ms() const + { + assert_choice_type(types::periodicity40ms, type_, "PeriodicityStartPos-r16"); + return c.get(); + } + const uint8_t& periodicity80ms() const + { + assert_choice_type(types::periodicity80ms, type_, "PeriodicityStartPos-r16"); + return c.get(); + } + const uint8_t& periodicity160ms() const + { + assert_choice_type(types::periodicity160ms, type_, "PeriodicityStartPos-r16"); + return c.get(); + } + void set_periodicity10ms(); + uint8_t& set_periodicity20ms(); + uint8_t& set_periodicity40ms(); + uint8_t& set_periodicity80ms(); + uint8_t& set_periodicity160ms(); + void set_spare3(); + void set_spare2(); + void set_spare1(); + +private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); +}; + +// ResourceReservationConfigDL-r16 ::= SEQUENCE +struct res_reserv_cfg_dl_r16_s { + struct res_reserv_freq_r16_c_ { + struct types_opts { + enum options { + rbg_bitmap1dot4, + rbg_bitmap3, + rbg_bitmap5, + rbg_bitmap10, + rbg_bitmap15, + rbg_bitmap20, + nulltype + } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated types; + + // choice methods + res_reserv_freq_r16_c_() = default; + res_reserv_freq_r16_c_(const res_reserv_freq_r16_c_& other); + res_reserv_freq_r16_c_& operator=(const res_reserv_freq_r16_c_& other); + ~res_reserv_freq_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<6>& rbg_bitmap1dot4() + { + assert_choice_type(types::rbg_bitmap1dot4, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + fixed_bitstring<8>& rbg_bitmap3() + { + assert_choice_type(types::rbg_bitmap3, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + fixed_bitstring<13>& rbg_bitmap5() + { + assert_choice_type(types::rbg_bitmap5, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + fixed_bitstring<17>& rbg_bitmap10() + { + assert_choice_type(types::rbg_bitmap10, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + fixed_bitstring<19>& rbg_bitmap15() + { + assert_choice_type(types::rbg_bitmap15, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + fixed_bitstring<25>& rbg_bitmap20() + { + assert_choice_type(types::rbg_bitmap20, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + const fixed_bitstring<6>& rbg_bitmap1dot4() const + { + assert_choice_type(types::rbg_bitmap1dot4, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + const fixed_bitstring<8>& rbg_bitmap3() const + { + assert_choice_type(types::rbg_bitmap3, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + const fixed_bitstring<13>& rbg_bitmap5() const + { + assert_choice_type(types::rbg_bitmap5, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + const fixed_bitstring<17>& rbg_bitmap10() const + { + assert_choice_type(types::rbg_bitmap10, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + const fixed_bitstring<19>& rbg_bitmap15() const + { + assert_choice_type(types::rbg_bitmap15, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + const fixed_bitstring<25>& rbg_bitmap20() const + { + assert_choice_type(types::rbg_bitmap20, type_, "resourceReservationFreq-r16"); + return c.get >(); + } + fixed_bitstring<6>& set_rbg_bitmap1dot4(); + fixed_bitstring<8>& set_rbg_bitmap3(); + fixed_bitstring<13>& set_rbg_bitmap5(); + fixed_bitstring<17>& set_rbg_bitmap10(); + fixed_bitstring<19>& set_rbg_bitmap15(); + fixed_bitstring<25>& set_rbg_bitmap20(); + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + struct slot_bitmap_r16_c_ { + struct types_opts { + enum options { slot_pattern10ms, slot_pattern40ms, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + slot_bitmap_r16_c_() = default; + slot_bitmap_r16_c_(const slot_bitmap_r16_c_& other); + slot_bitmap_r16_c_& operator=(const slot_bitmap_r16_c_& other); + ~slot_bitmap_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20>& slot_pattern10ms() + { + assert_choice_type(types::slot_pattern10ms, type_, "slotBitmap-r16"); + return c.get >(); + } + fixed_bitstring<80>& slot_pattern40ms() + { + assert_choice_type(types::slot_pattern40ms, type_, "slotBitmap-r16"); + return c.get >(); + } + const fixed_bitstring<20>& slot_pattern10ms() const + { + assert_choice_type(types::slot_pattern10ms, type_, "slotBitmap-r16"); + return c.get >(); + } + const fixed_bitstring<80>& slot_pattern40ms() const + { + assert_choice_type(types::slot_pattern40ms, type_, "slotBitmap-r16"); + return c.get >(); + } + fixed_bitstring<20>& set_slot_pattern10ms(); + fixed_bitstring<80>& set_slot_pattern40ms(); + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + + // member variables + bool ext = false; + bool res_reserv_freq_r16_present = false; + bool symbol_bitmap1_r16_present = false; + bool symbol_bitmap2_r16_present = false; + periodicity_start_pos_r16_c periodicity_start_pos_r16; + res_reserv_freq_r16_c_ res_reserv_freq_r16; + slot_bitmap_r16_c_ slot_bitmap_r16; + fixed_bitstring<7> symbol_bitmap1_r16; + fixed_bitstring<7> symbol_bitmap2_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ResourceReservationConfigUL-r16 ::= SEQUENCE +struct res_reserv_cfg_ul_r16_s { + struct slot_bitmap_r16_c_ { + struct types_opts { + enum options { slot_pattern10ms, slot_pattern40ms, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + slot_bitmap_r16_c_() = default; + slot_bitmap_r16_c_(const slot_bitmap_r16_c_& other); + slot_bitmap_r16_c_& operator=(const slot_bitmap_r16_c_& other); + ~slot_bitmap_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20>& slot_pattern10ms() + { + assert_choice_type(types::slot_pattern10ms, type_, "slotBitmap-r16"); + return c.get >(); + } + fixed_bitstring<80>& slot_pattern40ms() + { + assert_choice_type(types::slot_pattern40ms, type_, "slotBitmap-r16"); + return c.get >(); + } + const fixed_bitstring<20>& slot_pattern10ms() const + { + assert_choice_type(types::slot_pattern10ms, type_, "slotBitmap-r16"); + return c.get >(); + } + const fixed_bitstring<80>& slot_pattern40ms() const + { + assert_choice_type(types::slot_pattern40ms, type_, "slotBitmap-r16"); + return c.get >(); + } + fixed_bitstring<20>& set_slot_pattern10ms(); + fixed_bitstring<80>& set_slot_pattern40ms(); + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + + // member variables + bool ext = false; + bool slot_bitmap_r16_present = false; + bool symbol_bitmap1_r16_present = false; + bool symbol_bitmap2_r16_present = false; + periodicity_start_pos_r16_c periodicity_start_pos_r16; + slot_bitmap_r16_c_ slot_bitmap_r16; + fixed_bitstring<7> symbol_bitmap1_r16; + fixed_bitstring<7> symbol_bitmap2_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // NZP-FrequencyDensity-r14 ::= ENUMERATED struct nzp_freq_density_r14_opts { enum options { d1, d2, d3, nulltype } value; @@ -3502,6 +3834,47 @@ struct ant_info_ul_stti_r15_s { bool operator!=(const ant_info_ul_stti_r15_s& other) const { return not(*this == other); } }; +// CE-PDSCH-14HARQ-Config-r17 ::= SEQUENCE +struct ce_pdsch_minus14_harq_cfg_r17_s { + struct ce_harq_ack_delay_r17_opts { + enum options { alt_minus1, alt_minus2e, nulltype } value; + typedef int8_t number_type; + + const char* to_string() const; + int8_t to_number() const; + }; + typedef enumerated ce_harq_ack_delay_r17_e_; + + // member variables + ce_harq_ack_delay_r17_e_ ce_harq_ack_delay_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CE-PDSCH-MultiTB-Config-r16 ::= SEQUENCE +struct ce_pdsch_multi_tb_cfg_r16_s { + bool interleaving_r16_present = false; + bool harq_ack_bundling_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CE-PUSCH-MultiTB-Config-r16 ::= SEQUENCE +struct ce_pusch_multi_tb_cfg_r16_s { + bool interleaving_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CQI-ReportConfig-r15 ::= CHOICE struct cqi_report_cfg_r15_c { struct setup_s_ { @@ -4206,6 +4579,71 @@ struct srs_cc_set_idx_r14_s { bool operator!=(const srs_cc_set_idx_r14_s& other) const { return not(*this == other); } }; +// SRS-ConfigAdd-r16 ::= SEQUENCE +struct srs_cfg_add_r16_s { + struct srs_rep_num_add_r16_opts { + enum options { n1, n2, n3, n4, n6, n7, n8, n9, n12, n13, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated srs_rep_num_add_r16_e_; + struct srs_bw_add_r16_opts { + enum options { bw0, bw1, bw2, bw3, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated srs_bw_add_r16_e_; + struct srs_hop_bw_add_r16_opts { + enum options { hbw0, hbw1, hbw2, hbw3, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated srs_hop_bw_add_r16_e_; + struct srs_cyclic_shift_add_r16_opts { + enum options { cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, cs8, cs9, cs10, cs11, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated srs_cyclic_shift_add_r16_e_; + struct srs_tx_comb_num_add_r16_opts { + enum options { n2, n4, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated srs_tx_comb_num_add_r16_e_; + + // member variables + bool srs_guard_symbol_as_add_r16_present = false; + bool srs_guard_symbol_fh_add_r16_present = false; + srs_rep_num_add_r16_e_ srs_rep_num_add_r16; + srs_bw_add_r16_e_ srs_bw_add_r16; + srs_hop_bw_add_r16_e_ srs_hop_bw_add_r16; + uint8_t srs_freq_domain_pos_add_r16 = 0; + srs_ant_port_e srs_ant_port_add_r16; + srs_cyclic_shift_add_r16_e_ srs_cyclic_shift_add_r16; + srs_tx_comb_num_add_r16_e_ srs_tx_comb_num_add_r16; + uint8_t srs_tx_comb_add_r16 = 0; + uint8_t srs_start_pos_add_r16 = 1; + uint8_t srs_dur_add_r16 = 1; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const srs_cfg_add_r16_s& other) const; + bool operator!=(const srs_cfg_add_r16_s& other) const { return not(*this == other); } +}; + // SRS-ConfigAp-r10 ::= SEQUENCE struct srs_cfg_ap_r10_s { struct srs_bw_ap_r10_opts { @@ -5429,6 +5867,28 @@ struct pdsch_cfg_ded_v1530_s { bool operator!=(const pdsch_cfg_ded_v1530_s& other) const { return not(*this == other); } }; +// PDSCH-ConfigDedicated-v1610 ::= SEQUENCE +struct pdsch_cfg_ded_v1610_s { + setup_release_c ce_pdsch_multi_tb_cfg_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PDSCH-ConfigDedicated-v1700 ::= SEQUENCE +struct pdsch_cfg_ded_v1700_s { + bool ce_pdsch_minus14_harq_cfg_r17_present = false; + bool ce_pdsch_max_tbs_r17_present = false; + setup_release_c ce_pdsch_minus14_harq_cfg_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PUCCH-ConfigDedicated ::= SEQUENCE struct pucch_cfg_ded_s { struct ack_nack_repeat_c_ { @@ -6551,6 +7011,16 @@ struct pusch_cfg_ded_v1530_s { void to_json(json_writer& j) const; }; +// PUSCH-ConfigDedicated-v1610 ::= SEQUENCE +struct pusch_cfg_ded_v1610_s { + setup_release_c ce_pusch_multi_tb_cfg_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PUSCH-EnhancementsConfig-r14 ::= CHOICE struct pusch_enhance_cfg_r14_c { struct setup_s_ { @@ -6728,6 +7198,28 @@ struct phys_cfg_ded_stti_r15_c { setup_s_ c; }; +// ResourceReservationConfigDedicatedDL-r16 ::= SEQUENCE +struct res_reserv_cfg_ded_dl_r16_s { + bool res_reserv_ded_dl_r16_present = false; + res_reserv_cfg_dl_r16_s res_reserv_ded_dl_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ResourceReservationConfigDedicatedUL-r16 ::= SEQUENCE +struct res_reserv_cfg_ded_ul_r16_s { + bool res_reserv_ded_ul_r16_present = false; + res_reserv_cfg_ul_r16_s res_reserv_ded_ul_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SPUCCH-Config-v1550 ::= CHOICE struct spucch_cfg_v1550_c { struct setup_s_ { @@ -7006,6 +7498,59 @@ struct srs_ul_cfg_ded_v1310_c { setup_s_ c; }; +// SoundingRS-UL-ConfigDedicatedAdd-r16 ::= SEQUENCE +struct srs_ul_cfg_ded_add_r16_s { + using srs_cfg_ap_dci_format4_r16_l_ = dyn_array; + struct srs_activ_ap_r13_c_ { + struct setup_s_ { + srs_cfg_add_r16_s srs_cfg_ap_dci_format0_r16; + srs_cfg_add_r16_s srs_cfg_ap_dci_format1a2b2c_r16; + }; + using types = setup_e; + + // choice methods + srs_activ_ap_r13_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const srs_activ_ap_r13_c_& other) const; + bool operator!=(const srs_activ_ap_r13_c_& other) const { return not(*this == other); } + // getters + setup_s_& setup() + { + assert_choice_type(types::setup, type_, "srs-ActivateAp-r13"); + return c; + } + const setup_s_& setup() const + { + assert_choice_type(types::setup, type_, "srs-ActivateAp-r13"); + return c; + } + void set_release(); + setup_s_& set_setup(); + + private: + types type_; + setup_s_ c; + }; + + // member variables + bool srs_cfg_ap_dci_format4_r16_present = false; + bool srs_activ_ap_r13_present = false; + uint8_t srs_cfg_idx_ap_r16 = 0; + srs_cfg_ap_dci_format4_r16_l_ srs_cfg_ap_dci_format4_r16; + srs_activ_ap_r13_c_ srs_activ_ap_r13; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const srs_ul_cfg_ded_add_r16_s& other) const; + bool operator!=(const srs_ul_cfg_ded_add_r16_s& other) const { return not(*this == other); } +}; + // SoundingRS-UL-ConfigDedicatedAperiodic-r10 ::= CHOICE struct srs_ul_cfg_ded_aperiodic_r10_c { struct setup_s_ { @@ -7332,6 +7877,39 @@ struct srs_ul_cfg_ded_up_pts_ext_r13_c { setup_s_ c; }; +// SoundingRS-VirtualCellID-r16 ::= SEQUENCE +struct srs_virtual_cell_id_r16_s { + uint16_t srs_virtual_cell_id_r16 = 0; + bool srs_virtual_cell_id_all_srs_r16 = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const srs_virtual_cell_id_r16_s& other) const; + bool operator!=(const srs_virtual_cell_id_r16_s& other) const { return not(*this == other); } +}; + +// UplinkPowerControlAddSRS-r16 ::= SEQUENCE +struct ul_pwr_ctrl_add_srs_r16_s { + bool tpc_idx_srs_add_r16_present = false; + bool start_bit_of_format3_b_srs_add_r16_present = false; + bool field_type_format3_b_srs_add_r16_present = false; + bool p0_ue_srs_add_r16_present = false; + tpc_idx_c tpc_idx_srs_add_r16; + uint8_t start_bit_of_format3_b_srs_add_r16 = 0; + uint8_t field_type_format3_b_srs_add_r16 = 1; + int8_t p0_ue_srs_add_r16 = -16; + bool accumulation_enabled_srs_add_r16 = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const ul_pwr_ctrl_add_srs_r16_s& other) const; + bool operator!=(const ul_pwr_ctrl_add_srs_r16_s& other) const { return not(*this == other); } +}; + // UplinkPowerControlDedicated ::= SEQUENCE struct ul_pwr_ctrl_ded_s { struct delta_mcs_enabled_opts { @@ -7453,6 +8031,19 @@ struct ul_pwr_ctrl_ded_v1530_s { bool operator!=(const ul_pwr_ctrl_ded_v1530_s& other) const { return not(*this == other); } }; +// WidebandPRG-r16 ::= SEQUENCE +struct wideband_prg_r16_s { + bool wideband_prg_sf_r16 = false; + bool wideband_prg_slot_subslot_r16 = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const wideband_prg_r16_s& other) const; + bool operator!=(const wideband_prg_r16_s& other) const { return not(*this == other); } +}; + // PhysicalConfigDedicated ::= SEQUENCE struct phys_cfg_ded_s { struct ant_info_c_ { @@ -7846,6 +8437,18 @@ struct phys_cfg_ded_s { types type_; setup_s_ c; }; + struct ntn_cfg_ded_r17_s_ { + bool pucch_tx_dur_r17_present = false; + bool pusch_tx_dur_r17_present = false; + setup_release_c pucch_tx_dur_r17; + setup_release_c pusch_tx_dur_r17; + }; + struct ul_segmented_precompensation_gap_r17_opts { + enum options { sym1, sl1, sf1, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated ul_segmented_precompensation_gap_r17_e_; // member variables bool ext = false; @@ -7958,6 +8561,22 @@ struct phys_cfg_ded_s { copy_ptr blind_pdsch_repeat_cfg_r15; // group 11 copy_ptr spucch_cfg_v1550; + // group 12 + bool ce_csi_rs_feedback_r16_present = false; + copy_ptr pdsch_cfg_ded_v1610; + copy_ptr pusch_cfg_ded_v1610; + copy_ptr > res_reserv_cfg_ded_dl_r16; + copy_ptr > res_reserv_cfg_ded_ul_r16; + copy_ptr > srs_ul_cfg_ded_add_r16; + copy_ptr > ul_pwr_ctrl_add_srs_r16; + copy_ptr > srs_virtual_cell_id_r16; + copy_ptr > wideband_prg_r16; + // group 13 + copy_ptr pdsch_cfg_ded_v1700; + copy_ptr ntn_cfg_ded_r17; + // group 14 + bool ul_segmented_precompensation_gap_r17_present = false; + ul_segmented_precompensation_gap_r17_e_ ul_segmented_precompensation_gap_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; diff --git a/lib/include/srsran/asn1/rrc/rr_common.h b/lib/include/srsran/asn1/rrc/rr_common.h index f7453e150f..382cc75a2b 100644 --- a/lib/include/srsran/asn1/rrc/rr_common.h +++ b/lib/include/srsran/asn1/rrc/rr_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -277,6 +277,32 @@ struct tdd_cfg_v1130_s { bool operator!=(const tdd_cfg_v1130_s& other) const { return not(*this == other); } }; +// GWUS-NumGroups-r16 ::= ENUMERATED +struct gwus_num_groups_r16_opts { + enum options { n1, n2, n4, n8, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated gwus_num_groups_r16_e; + +// GWUS-GroupsForServiceList-r16 ::= SEQUENCE (SIZE (1..3)) OF INTEGER (1..31) +using gwus_groups_for_service_list_r16_l = bounded_array; + +// GWUS-NumGroupsList-r16 ::= SEQUENCE (SIZE (1..4)) OF GWUS-NumGroups-r16 +using gwus_num_groups_list_r16_l = bounded_array; + +// GWUS-PagingProbThresh-r16 ::= ENUMERATED +struct gwus_paging_prob_thresh_r16_opts { + enum options { p20, p30, p40, p50, p60, p70, p80, p90, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated gwus_paging_prob_thresh_r16_e; + // PRACH-ParametersCE-r13 ::= SEQUENCE struct prach_params_ce_r13_s { struct prach_start_sf_r13_opts { @@ -704,6 +730,173 @@ struct edt_prach_params_ce_r15_s { void to_json(json_writer& j) const; }; +// GWUS-GroupNarrowBandList-r16 ::= SEQUENCE (SIZE (1..16)) OF BOOLEAN +using gwus_group_narrow_band_list_r16_l = bounded_array; + +// GWUS-ProbThreshList-r16 ::= SEQUENCE (SIZE (1..3)) OF GWUS-PagingProbThresh-r16 +using gwus_prob_thresh_list_r16_l = bounded_array; + +// GWUS-ResourceConfig-r16 ::= SEQUENCE +struct gwus_res_cfg_r16_s { + struct res_map_pattern_r16_c_ { + struct res_location_with_wus_opts { + enum options { primary, secondary, primary3_fdm, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated res_location_with_wus_e_; + struct res_location_without_wus_opts { + enum options { n0, n2, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated res_location_without_wus_e_; + struct types_opts { + enum options { res_location_with_wus, res_location_without_wus, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + res_map_pattern_r16_c_() = default; + res_map_pattern_r16_c_(const res_map_pattern_r16_c_& other); + res_map_pattern_r16_c_& operator=(const res_map_pattern_r16_c_& other); + ~res_map_pattern_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + res_location_with_wus_e_& res_location_with_wus() + { + assert_choice_type(types::res_location_with_wus, type_, "resourceMappingPattern-r16"); + return c.get(); + } + res_location_without_wus_e_& res_location_without_wus() + { + assert_choice_type(types::res_location_without_wus, type_, "resourceMappingPattern-r16"); + return c.get(); + } + const res_location_with_wus_e_& res_location_with_wus() const + { + assert_choice_type(types::res_location_with_wus, type_, "resourceMappingPattern-r16"); + return c.get(); + } + const res_location_without_wus_e_& res_location_without_wus() const + { + assert_choice_type(types::res_location_without_wus, type_, "resourceMappingPattern-r16"); + return c.get(); + } + res_location_with_wus_e_& set_res_location_with_wus(); + res_location_without_wus_e_& set_res_location_without_wus(); + + private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool num_groups_list_r16_present = false; + bool groups_for_service_list_r16_present = false; + res_map_pattern_r16_c_ res_map_pattern_r16; + gwus_num_groups_list_r16_l num_groups_list_r16; + gwus_groups_for_service_list_r16_l groups_for_service_list_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GWUS-TimeParameters-r16 ::= SEQUENCE +struct gwus_time_params_r16_s { + struct max_dur_factor_r16_opts { + enum options { one32th, one16th, one8th, one4th, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated max_dur_factor_r16_e_; + struct num_pos_r16_opts { + enum options { n1, n2, n4, spare1, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated num_pos_r16_e_; + struct time_offset_drx_r16_opts { + enum options { ms40, ms80, ms160, ms240, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated time_offset_drx_r16_e_; + struct time_offset_e_drx_short_r16_opts { + enum options { ms40, ms80, ms160, ms240, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated time_offset_e_drx_short_r16_e_; + struct time_offset_e_drx_long_r16_opts { + enum options { ms1000, ms2000, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated time_offset_e_drx_long_r16_e_; + struct num_drx_cycles_relaxed_r16_opts { + enum options { n1, n2, n4, n8, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated num_drx_cycles_relaxed_r16_e_; + struct pwr_boost_r16_opts { + enum options { db0, db1dot8, db3, db4dot8, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated pwr_boost_r16_e_; + + // member variables + bool ext = false; + bool num_pos_r16_present = false; + bool time_offset_e_drx_long_r16_present = false; + bool num_drx_cycles_relaxed_r16_present = false; + bool pwr_boost_r16_present = false; + max_dur_factor_r16_e_ max_dur_factor_r16; + num_pos_r16_e_ num_pos_r16; + time_offset_drx_r16_e_ time_offset_drx_r16; + time_offset_e_drx_short_r16_e_ time_offset_e_drx_short_r16; + time_offset_e_drx_long_r16_e_ time_offset_e_drx_long_r16; + num_drx_cycles_relaxed_r16_e_ num_drx_cycles_relaxed_r16; + pwr_boost_r16_e_ pwr_boost_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // N1PUCCH-AN-InfoList-r13 ::= SEQUENCE (SIZE (1..4)) OF INTEGER (0..2047) using n1_pucch_an_info_list_r13_l = bounded_array; @@ -833,6 +1026,27 @@ struct bcch_cfg_v1310_s { void to_json(json_writer& j) const; }; +// CRS-ChEstMPDCCH-ConfigCommon-r16 ::= SEQUENCE +struct crs_ch_est_mpdcch_cfg_common_r16_s { + struct pwr_ratio_r16_opts { + enum options { db_minus4dot77, db_minus3, db_minus1dot77, db0, db1, db2, db3, db4dot77, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated pwr_ratio_r16_e_; + + // member variables + pwr_ratio_r16_e_ pwr_ratio_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // FreqHoppingParameters-r13 ::= SEQUENCE struct freq_hop_params_r13_s { struct dummy_opts { @@ -1120,6 +1334,39 @@ struct freq_hop_params_r13_s { void to_json(json_writer& j) const; }; +// GWUS-Config-r16 ::= SEQUENCE +struct gwus_cfg_r16_s { + struct common_seq_r16_opts { + enum options { g0, g126, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated common_seq_r16_e_; + + // member variables + bool group_alternation_r16_present = false; + bool common_seq_r16_present = false; + bool time_params_r16_present = false; + bool res_cfg_e_drx_short_r16_present = false; + bool res_cfg_e_drx_long_r16_present = false; + bool prob_thresh_list_r16_present = false; + bool group_narrow_band_list_r16_present = false; + common_seq_r16_e_ common_seq_r16; + gwus_time_params_r16_s time_params_r16; + gwus_res_cfg_r16_s res_cfg_drx_r16; + gwus_res_cfg_r16_s res_cfg_e_drx_short_r16; + gwus_res_cfg_r16_s res_cfg_e_drx_long_r16; + gwus_prob_thresh_list_r16_l prob_thresh_list_r16; + gwus_group_narrow_band_list_r16_l group_narrow_band_list_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // HighSpeedConfig-r14 ::= SEQUENCE struct high_speed_cfg_r14_s { bool high_speed_enhanced_meas_flag_r14_present = false; @@ -1139,6 +1386,17 @@ struct high_speed_cfg_v1530_s { void to_json(json_writer& j) const; }; +// HighSpeedConfig-v1610 ::= SEQUENCE +struct high_speed_cfg_v1610_s { + bool high_speed_enh_meas_flag2_r16_present = false; + bool high_speed_enh_demod_flag2_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PCCH-Config ::= SEQUENCE struct pcch_cfg_s { struct default_paging_cycle_opts { @@ -1210,6 +1468,14 @@ struct pcch_cfg_v1310_s { void to_json(json_writer& j) const; }; +// PCCH-Config-v1700 ::= SEQUENCE +struct pcch_cfg_v1700_s { + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PDSCH-ConfigCommon ::= SEQUENCE struct pdsch_cfg_common_s { int8_t ref_sig_pwr = -60; @@ -1375,6 +1641,26 @@ struct prach_cfg_sib_v1530_s { void to_json(json_writer& j) const; }; +// PRACH-TxDuration-r17 ::= SEQUENCE +struct prach_tx_dur_r17_s { + struct prach_tx_dur_r17_opts { + enum options { n1, n2, n4, n8, n16, n32, n64, n128, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated prach_tx_dur_r17_e_; + + // member variables + prach_tx_dur_r17_e_ prach_tx_dur_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PUCCH-ConfigCommon ::= SEQUENCE struct pucch_cfg_common_s { struct delta_pucch_shift_opts { @@ -1474,6 +1760,26 @@ struct pucch_cfg_common_v1430_s { void to_json(json_writer& j) const; }; +// PUCCH-TxDuration-r17 ::= SEQUENCE +struct pucch_tx_dur_r17_s { + struct pucch_tx_dur_r17_opts { + enum options { sf2, sf4, sf8, sf16, sf32, sf64, sf128, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated pucch_tx_dur_r17_e_; + + // member variables + pucch_tx_dur_r17_e_ pucch_tx_dur_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PUSCH-ConfigCommon ::= SEQUENCE struct pusch_cfg_common_s { struct pusch_cfg_basic_s_ { @@ -1546,6 +1852,26 @@ struct pusch_cfg_common_v1310_s { void to_json(json_writer& j) const; }; +// PUSCH-TxDuration-r17 ::= SEQUENCE +struct pusch_tx_dur_r17_s { + struct pusch_tx_dur_r17_opts { + enum options { n2, n4, n8, n16, n32, n64, n128, n256, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated pusch_tx_dur_r17_e_; + + // member variables + pusch_tx_dur_r17_e_ pusch_tx_dur_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RACH-ConfigCommon ::= SEQUENCE struct rach_cfg_common_s { struct preamb_info_s_ { @@ -1866,6 +2192,17 @@ struct ul_pwr_ctrl_common_v1530_s { bool operator!=(const ul_pwr_ctrl_common_v1530_s& other) const { return not(*this == other); } }; +// UplinkPowerControlCommon-v1610 ::= SEQUENCE +struct ul_pwr_ctrl_common_v1610_s { + alpha_r12_e alpha_srs_add_r16; + int8_t p0_nominal_srs_add_r16 = -126; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // WUS-Config-r15 ::= SEQUENCE struct wus_cfg_r15_s { struct max_dur_factor_r15_opts { @@ -1954,8 +2291,50 @@ struct wus_cfg_v1560_s { void to_json(json_writer& j) const; }; +// WUS-Config-v1610 ::= SEQUENCE +struct wus_cfg_v1610_s { + struct num_drx_cycles_relaxed_r16_opts { + enum options { n1, n2, n4, n8, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated num_drx_cycles_relaxed_r16_e_; + + // member variables + num_drx_cycles_relaxed_r16_e_ num_drx_cycles_relaxed_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RadioResourceConfigCommonSIB ::= SEQUENCE struct rr_cfg_common_sib_s { + struct ntn_cfg_common_r17_s_ { + struct t318_r17_opts { + enum options { ms0, ms50, ms100, ms200, ms500, ms1000, ms2000, ms4000, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated t318_r17_e_; + + // member variables + bool ta_report_r17_present = false; + bool prach_tx_dur_r17_present = false; + bool pucch_tx_dur_r17_present = false; + bool pusch_tx_dur_r17_present = false; + t318_r17_e_ t318_r17; + prach_tx_dur_r17_s prach_tx_dur_r17; + pucch_tx_dur_r17_s pucch_tx_dur_r17; + pusch_tx_dur_r17_s pusch_tx_dur_r17; + }; + + // member variables bool ext = false; rach_cfg_common_s rach_cfg_common; bcch_cfg_s bcch_cfg; @@ -1995,6 +2374,21 @@ struct rr_cfg_common_sib_s { copy_ptr ul_pwr_ctrl_common_v1540; // group 7 copy_ptr wus_cfg_v1560; + // group 8 + bool rss_meas_cfg_r16_present = false; + bool rss_meas_non_ncl_r16_present = false; + bool punctured_subcarriers_dl_r16_present = false; + bool high_speed_inter_rat_nr_r16_present = false; + copy_ptr wus_cfg_v1610; + copy_ptr high_speed_cfg_v1610; + copy_ptr crs_ch_est_mpdcch_cfg_common_r16; + copy_ptr gwus_cfg_r16; + copy_ptr ul_pwr_ctrl_common_v1610; + fixed_bitstring<2> punctured_subcarriers_dl_r16; + bool high_speed_inter_rat_nr_r16 = false; + // group 9 + copy_ptr pcch_cfg_v1700; + copy_ptr ntn_cfg_common_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2330,6 +2724,9 @@ struct rr_cfg_common_scell_r10_s { copy_ptr mbsfn_sf_cfg_list_v1430; // group 6 copy_ptr ul_pwr_ctrl_common_scell_v1530; + // group 7 + bool high_speed_enh_meas_flag_scell_r16_present = false; + bool high_speed_enh_meas_flag_scell_r16 = false; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2468,6 +2865,28 @@ struct prach_cfg_v1310_s { // RadioResourceConfigCommon ::= SEQUENCE struct rr_cfg_common_s { + struct ntn_cfg_common_r17_s_ { + struct t318_r17_opts { + enum options { ms0, ms50, ms100, ms200, ms500, ms1000, ms2000, ms4000, ms6000, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated t318_r17_e_; + + // member variables + bool ta_report_r17_present = false; + bool prach_tx_dur_r17_present = false; + bool pucch_tx_dur_r17_present = false; + bool pusch_tx_dur_r17_present = false; + t318_r17_e_ t318_r17; + prach_tx_dur_r17_s prach_tx_dur_r17; + pucch_tx_dur_r17_s pucch_tx_dur_r17; + pusch_tx_dur_r17_s pusch_tx_dur_r17; + }; + + // member variables bool ext = false; bool rach_cfg_common_present = false; bool pdsch_cfg_common_present = false; @@ -2514,6 +2933,13 @@ struct rr_cfg_common_s { // group 6 copy_ptr ul_pwr_ctrl_common_v1530; copy_ptr high_speed_cfg_v1530; + // group 7 + bool high_speed_inter_rat_nr_r16_present = false; + copy_ptr high_speed_cfg_v1610; + copy_ptr ul_pwr_ctrl_common_v1610; + bool high_speed_inter_rat_nr_r16 = false; + // group 8 + copy_ptr ntn_cfg_common_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; diff --git a/lib/include/srsran/asn1/rrc/rr_ded.h b/lib/include/srsran/asn1/rrc/rr_ded.h index 813931f033..72b2de58e8 100644 --- a/lib/include/srsran/asn1/rrc/rr_ded.h +++ b/lib/include/srsran/asn1/rrc/rr_ded.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -455,6 +455,56 @@ struct dl_um_rlc_s { bool operator!=(const dl_um_rlc_s& other) const { return not(*this == other); } }; +// DiscardTimerExt-r17 ::= ENUMERATED +struct discard_timer_ext_r17_opts { + enum options { ms2000, spare, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; +}; +typedef enumerated discard_timer_ext_r17_e; + +// EthernetHeaderCompression-r16 ::= SEQUENCE +struct ethernet_hdr_compress_r16_s { + struct ehc_common_r16_s_ { + struct ehc_cid_len_r16_opts { + enum options { bits7, bits15, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated ehc_cid_len_r16_e_; + + // member variables + ehc_cid_len_r16_e_ ehc_cid_len_r16; + }; + struct ehc_dl_r16_s_ { + bool drb_continue_ehc_dl_r16_present = false; + }; + struct ehc_ul_r16_s_ { + bool drb_continue_ehc_ul_r16_present = false; + uint16_t max_cid_ehc_ul_r16 = 1; + }; + + // member variables + bool ext = false; + bool ehc_dl_r16_present = false; + bool ehc_ul_r16_present = false; + ehc_common_r16_s_ ehc_common_r16; + ehc_dl_r16_s_ ehc_dl_r16; + ehc_ul_r16_s_ ehc_ul_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const ethernet_hdr_compress_r16_s& other) const; + bool operator!=(const ethernet_hdr_compress_r16_s& other) const { return not(*this == other); } +}; + // LogicalChannelConfig ::= SEQUENCE struct lc_ch_cfg_s { struct ul_specific_params_s_ { @@ -609,6 +659,14 @@ struct lc_ch_cfg_s { types type_; uint8_t c; }; + struct bit_rate_multiplier_r16_opts { + enum options { x40, x70, x100, x200, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated bit_rate_multiplier_r16_e_; // member variables bool ext = false; @@ -631,6 +689,9 @@ struct lc_ch_cfg_s { copy_ptr lc_ch_sr_restrict_r15; copy_ptr ch_access_prio_r15; fixed_bitstring<32> lch_cell_restrict_r15; + // group 4 + bool bit_rate_multiplier_r16_present = false; + bit_rate_multiplier_r16_e_ bit_rate_multiplier_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -765,6 +826,16 @@ struct rlc_cfg_r15_s { bool operator!=(const rlc_cfg_r15_s& other) const { return not(*this == other); } }; +// T-ReorderingExt-r17 ::= ENUMERATED +struct t_reordering_ext_r17_opts { + enum options { ms2200, ms3200, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; +}; +typedef enumerated t_reordering_ext_r17_e; + // UL-AM-RLC ::= SEQUENCE struct ul_am_rlc_s { struct max_retx_thres_opts { @@ -1398,6 +1469,10 @@ struct pdcp_cfg_s { // group 5 copy_ptr ul_data_compress_r15; copy_ptr pdcp_dupl_cfg_r15; + // group 6 + copy_ptr > ethernet_hdr_compress_r16; + // group 7 + copy_ptr > discard_timer_ext_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1681,6 +1756,18 @@ struct rlc_cfg_v1530_c { types type_; }; +// RLC-Config-v1700 ::= SEQUENCE +struct rlc_cfg_v1700_s { + setup_release_c t_reordering_ext_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const rlc_cfg_v1700_s& other) const; + bool operator!=(const rlc_cfg_v1700_s& other) const { return not(*this == other); } +}; + // SPS-ConfigSL-r14 ::= SEQUENCE struct sps_cfg_sl_r14_s { struct semi_persist_sched_interv_sl_r14_opts { @@ -2159,6 +2246,10 @@ struct drb_to_add_mod_s { copy_ptr rlc_cfg_v1530; copy_ptr rlc_bearer_cfg_secondary_r15; uint8_t lc_ch_id_r15 = 32; + // group 5 + bool daps_ho_r16_present = false; + // group 6 + copy_ptr rlc_cfg_v1700; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2745,6 +2836,35 @@ using neigh_cells_to_add_mod_list_r12_l = dyn_array; // NeighCellsToReleaseList-r12 ::= SEQUENCE (SIZE (1..8)) OF INTEGER (0..503) using neigh_cells_to_release_list_r12_l = bounded_array; +// OffsetThresholdTA-r17 ::= ENUMERATED +struct offset_thres_ta_r17_opts { + enum options { + ms0dot5, + ms1, + ms2, + ms3, + ms4, + ms5, + ms6, + ms7, + ms8, + ms9, + ms10, + ms11, + ms12, + ms13, + ms14, + ms15, + nulltype + } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; +}; +typedef enumerated offset_thres_ta_r17_e; + // PeriodicBSR-Timer-r12 ::= ENUMERATED struct periodic_bsr_timer_r12_opts { enum options { @@ -3016,6 +3136,16 @@ using sps_cfg_ul_to_release_list_r14_l = bounded_array; // SPS-ConfigUL-ToReleaseList-r15 ::= SEQUENCE (SIZE (1..6)) OF INTEGER (1..6) using sps_cfg_ul_to_release_list_r15_l = bounded_array; +// SR-ProhibitTimerOffset-r17 ::= ENUMERATED +struct sr_prohibit_timer_offset_r17_opts { + enum options { ms90, ms180, ms270, ms360, ms450, ms540, ms1080, spare, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; +}; +typedef enumerated sr_prohibit_timer_offset_r17_e; + // SRB-ToAddMod ::= SEQUENCE struct srb_to_add_mod_s { struct rlc_cfg_c_ { @@ -3105,6 +3235,8 @@ struct srb_to_add_mod_s { uint8_t srb_id_v1530 = 4; // group 1 copy_ptr rlc_cfg_v1560; + // group 2 + copy_ptr rlc_cfg_v1700; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3120,6 +3252,36 @@ using stag_to_add_mod_list_r11_l = dyn_array; // STAG-ToReleaseList-r11 ::= SEQUENCE (SIZE (1..3)) OF INTEGER (1..3) using stag_to_release_list_r11_l = bounded_array; +// CRS-ChEstMPDCCH-ConfigDedicated-r16 ::= SEQUENCE +struct crs_ch_est_mpdcch_cfg_ded_r16_s { + struct pwr_ratio_r16_opts { + enum options { db_minus4dot77, db_minus3, db_minus1dot77, db0, db1, db2, db3, db4dot77, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated pwr_ratio_r16_e_; + struct localized_map_type_r16_opts { + enum options { predefined, csi_based, reciprocity_based, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated localized_map_type_r16_e_; + + // member variables + bool pwr_ratio_r16_present = false; + bool localized_map_type_r16_present = false; + pwr_ratio_r16_e_ pwr_ratio_r16; + localized_map_type_r16_e_ localized_map_type_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // DRB-ToAddModList ::= SEQUENCE (SIZE (1..11)) OF DRB-ToAddMod using drb_to_add_mod_list_l = dyn_array; @@ -3660,6 +3822,11 @@ struct mac_main_cfg_s { copy_ptr short_tti_and_spt_r15; bool mpdcch_ul_harq_ack_feedback_cfg_r15 = false; copy_ptr dormant_state_timers_r15; + // group 9 + bool ce_etws_cmas_rx_in_conn_r16_present = false; + // group 10 + copy_ptr > offset_thres_ta_r17; + copy_ptr > sr_prohibit_timer_offset_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3973,6 +4140,51 @@ struct rlf_timers_and_consts_r9_c { setup_s_ c; }; +// RLF-TimersAndConstantsMCG-Failure-r16 ::= CHOICE +struct rlf_timers_and_consts_mcg_fail_r16_c { + struct setup_s_ { + struct t316_r16_opts { + enum options { ms50, ms100, ms200, ms300, ms400, ms500, ms600, ms1000, ms1500, ms2000, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated t316_r16_e_; + + // member variables + bool ext = false; + t316_r16_e_ t316_r16; + // ... + }; + using types = setup_e; + + // choice methods + rlf_timers_and_consts_mcg_fail_r16_c() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + setup_s_& setup() + { + assert_choice_type(types::setup, type_, "RLF-TimersAndConstantsMCG-Failure-r16"); + return c; + } + const setup_s_& setup() const + { + assert_choice_type(types::setup, type_, "RLF-TimersAndConstantsMCG-Failure-r16"); + return c; + } + void set_release(); + setup_s_& set_setup(); + +private: + types type_; + setup_s_ c; +}; + // SPS-Config ::= SEQUENCE struct sps_cfg_s { bool semi_persist_sched_c_rnti_present = false; @@ -4195,6 +4407,11 @@ struct rr_cfg_ded_s { copy_ptr dummy; // group 7 copy_ptr sps_cfg_v1540; + // group 8 + bool new_ue_id_r16_present = false; + copy_ptr rlf_timers_and_consts_mcg_fail_r16; + copy_ptr > crs_ch_est_mpdcch_cfg_ded_r16; + fixed_bitstring<16> new_ue_id_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -4713,6 +4930,20 @@ struct cqi_report_cfg_scell_r15_s { bool operator!=(const cqi_report_cfg_scell_r15_s& other) const { return not(*this == other); } }; +// CQI-ReportPeriodicSCell-v1730 ::= SEQUENCE +struct cqi_report_periodic_scell_v1730_s { + bool ri_cfg_idx2_dormant_r17_present = false; + uint16_t cqi_pmi_cfg_idx2_dormant_r17 = 0; + uint16_t ri_cfg_idx2_dormant_r17 = 0; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const cqi_report_periodic_scell_v1730_s& other) const; + bool operator!=(const cqi_report_periodic_scell_v1730_s& other) const { return not(*this == other); } +}; + // CQI-ShortConfigSCell-r15 ::= CHOICE struct cqi_short_cfg_scell_r15_c { struct setup_s_ { @@ -5793,6 +6024,11 @@ struct phys_cfg_ded_scell_r10_s { copy_ptr blind_pdsch_repeat_cfg_r15; // group 8 copy_ptr spucch_cfg_v1550; + // group 9 + copy_ptr > srs_ul_cfg_ded_add_r16; + copy_ptr > ul_pwr_ctrl_add_srs_r16; + copy_ptr > srs_virtual_cell_id_r16; + copy_ptr > wideband_prg_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -5850,6 +6086,18 @@ struct phys_cfg_ded_scell_v1370_s { bool operator!=(const phys_cfg_ded_scell_v1370_s& other) const { return not(*this == other); } }; +// PhysicalConfigDedicatedSCell-v1730 ::= SEQUENCE +struct phys_cfg_ded_scell_v1730_s { + setup_release_c cqi_report_periodic_scell_v1730; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + bool operator==(const phys_cfg_ded_scell_v1730_s& other) const; + bool operator!=(const phys_cfg_ded_scell_v1730_s& other) const { return not(*this == other); } +}; + // AntennaInfoDedicated-v10i0 ::= SEQUENCE struct ant_info_ded_v10i0_s { struct max_layers_mimo_r10_opts { @@ -5892,6 +6140,8 @@ struct rr_cfg_ded_scell_r10_s { bool crs_intf_mitig_enabled_r15 = false; copy_ptr neigh_cells_crs_info_r15; copy_ptr sps_cfg_v1530; + // group 5 + copy_ptr phys_cfg_ded_scell_v1730; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; diff --git a/lib/include/srsran/asn1/rrc/rrc_asn1.h b/lib/include/srsran/asn1/rrc/rrc_asn1.h index b279416795..6d781ba678 100644 --- a/lib/include/srsran/asn1/rrc/rrc_asn1.h +++ b/lib/include/srsran/asn1/rrc/rrc_asn1.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/asn1/rrc/security.h b/lib/include/srsran/asn1/rrc/security.h index bc17acc5b0..5d4f317eba 100644 --- a/lib/include/srsran/asn1/rrc/security.h +++ b/lib/include/srsran/asn1/rrc/security.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -61,7 +61,7 @@ struct security_algorithm_cfg_s { // SecurityConfigHO-v1530 ::= SEQUENCE struct security_cfg_ho_v1530_s { struct handov_type_v1530_c_ { - struct intra5_gc_r15_s_ { + struct intra5_gc_s_ { bool security_algorithm_cfg_r15_present = false; bool nas_container_r15_present = false; security_algorithm_cfg_s security_algorithm_cfg_r15; @@ -69,16 +69,16 @@ struct security_cfg_ho_v1530_s { uint8_t next_hop_chaining_count_r15 = 0; dyn_octstring nas_container_r15; }; - struct fivegc_to_epc_r15_s_ { + struct fivegc_to_epc_s_ { security_algorithm_cfg_s security_algorithm_cfg_r15; uint8_t next_hop_chaining_count_r15 = 0; }; - struct epc_to5_gc_r15_s_ { + struct epc_to5_gc_s_ { security_algorithm_cfg_s security_algorithm_cfg_r15; dyn_octstring nas_container_r15; }; struct types_opts { - enum options { intra5_gc_r15, fivegc_to_epc_r15, epc_to5_gc_r15, nulltype } value; + enum options { intra5_gc, fivegc_to_epc, epc_to5_gc, nulltype } value; const char* to_string() const; }; @@ -95,43 +95,43 @@ struct security_cfg_ho_v1530_s { SRSASN_CODE unpack(cbit_ref& bref); void to_json(json_writer& j) const; // getters - intra5_gc_r15_s_& intra5_gc_r15() + intra5_gc_s_& intra5_gc() { - assert_choice_type(types::intra5_gc_r15, type_, "handoverType-v1530"); - return c.get(); + assert_choice_type(types::intra5_gc, type_, "handoverType-v1530"); + return c.get(); } - fivegc_to_epc_r15_s_& fivegc_to_epc_r15() + fivegc_to_epc_s_& fivegc_to_epc() { - assert_choice_type(types::fivegc_to_epc_r15, type_, "handoverType-v1530"); - return c.get(); + assert_choice_type(types::fivegc_to_epc, type_, "handoverType-v1530"); + return c.get(); } - epc_to5_gc_r15_s_& epc_to5_gc_r15() + epc_to5_gc_s_& epc_to5_gc() { - assert_choice_type(types::epc_to5_gc_r15, type_, "handoverType-v1530"); - return c.get(); + assert_choice_type(types::epc_to5_gc, type_, "handoverType-v1530"); + return c.get(); } - const intra5_gc_r15_s_& intra5_gc_r15() const + const intra5_gc_s_& intra5_gc() const { - assert_choice_type(types::intra5_gc_r15, type_, "handoverType-v1530"); - return c.get(); + assert_choice_type(types::intra5_gc, type_, "handoverType-v1530"); + return c.get(); } - const fivegc_to_epc_r15_s_& fivegc_to_epc_r15() const + const fivegc_to_epc_s_& fivegc_to_epc() const { - assert_choice_type(types::fivegc_to_epc_r15, type_, "handoverType-v1530"); - return c.get(); + assert_choice_type(types::fivegc_to_epc, type_, "handoverType-v1530"); + return c.get(); } - const epc_to5_gc_r15_s_& epc_to5_gc_r15() const + const epc_to5_gc_s_& epc_to5_gc() const { - assert_choice_type(types::epc_to5_gc_r15, type_, "handoverType-v1530"); - return c.get(); + assert_choice_type(types::epc_to5_gc, type_, "handoverType-v1530"); + return c.get(); } - intra5_gc_r15_s_& set_intra5_gc_r15(); - fivegc_to_epc_r15_s_& set_fivegc_to_epc_r15(); - epc_to5_gc_r15_s_& set_epc_to5_gc_r15(); + intra5_gc_s_& set_intra5_gc(); + fivegc_to_epc_s_& set_fivegc_to_epc(); + epc_to5_gc_s_& set_epc_to5_gc(); private: - types type_; - choice_buffer_t c; + types type_; + choice_buffer_t c; void destroy_(); }; diff --git a/lib/include/srsran/asn1/rrc/si.h b/lib/include/srsran/asn1/rrc/si.h index 832afc27b9..01b116251f 100644 --- a/lib/include/srsran/asn1/rrc/si.h +++ b/lib/include/srsran/asn1/rrc/si.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -47,14 +47,63 @@ struct mib_s { uint8_t to_number() const; }; typedef enumerated dl_bw_e_; + struct part_earfcn_minus17_c_ { + struct types_opts { + enum options { spare, earfcn_lsb, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + part_earfcn_minus17_c_() = default; + part_earfcn_minus17_c_(const part_earfcn_minus17_c_& other); + part_earfcn_minus17_c_& operator=(const part_earfcn_minus17_c_& other); + ~part_earfcn_minus17_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<2>& spare() + { + assert_choice_type(types::spare, type_, "partEARFCN-17"); + return c.get >(); + } + fixed_bitstring<2>& earfcn_lsb() + { + assert_choice_type(types::earfcn_lsb, type_, "partEARFCN-17"); + return c.get >(); + } + const fixed_bitstring<2>& spare() const + { + assert_choice_type(types::spare, type_, "partEARFCN-17"); + return c.get >(); + } + const fixed_bitstring<2>& earfcn_lsb() const + { + assert_choice_type(types::earfcn_lsb, type_, "partEARFCN-17"); + return c.get >(); + } + fixed_bitstring<2>& set_spare(); + fixed_bitstring<2>& set_earfcn_lsb(); + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; // member variables - dl_bw_e_ dl_bw; - phich_cfg_s phich_cfg; - fixed_bitstring<8> sys_frame_num; - uint8_t sched_info_sib1_br_r13 = 0; - bool sys_info_unchanged_br_r15 = false; - fixed_bitstring<4> spare; + dl_bw_e_ dl_bw; + phich_cfg_s phich_cfg; + fixed_bitstring<8> sys_frame_num; + uint8_t sched_info_sib1_br_r13 = 0; + bool sys_info_unchanged_br_r15 = false; + part_earfcn_minus17_c_ part_earfcn_minus17; + fixed_bitstring<1> spare; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -62,14 +111,17 @@ struct mib_s { void to_json(json_writer& j) const; }; +// TrackingAreaList-r17 ::= SEQUENCE (SIZE (1..12)) OF BIT STRING (SIZE (16)) +using tracking_area_list_r17_l = bounded_array, 12>; + // GNSS-ID-r15 ::= SEQUENCE struct gnss_id_r15_s { struct gnss_id_r15_opts { - enum options { gps, sbas, qzss, galileo, glonass, bds, /*...*/ nulltype } value; + enum options { gps, sbas, qzss, galileo, glonass, bds, /*...*/ navic_v1610, nulltype } value; const char* to_string() const; }; - typedef enumerated gnss_id_r15_e_; + typedef enumerated gnss_id_r15_e_; // member variables bool ext = false; @@ -82,6 +134,17 @@ struct gnss_id_r15_s { void to_json(json_writer& j) const; }; +// PLMN-IdentityInfo-v1700 ::= SEQUENCE +struct plmn_id_info_v1700_s { + bool tracking_area_list_r17_present = false; + tracking_area_list_r17_l tracking_area_list_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SBAS-ID-r15 ::= SEQUENCE struct sbas_id_r15_s { struct sbas_id_r15_opts { @@ -102,6 +165,21 @@ struct sbas_id_r15_s { void to_json(json_writer& j) const; }; +// PLMN-IdentityInfo-v1610 ::= SEQUENCE +struct plmn_id_info_v1610_s { + bool cp_cio_t_minus5_gs_optim_r16_present = false; + bool up_cio_t_minus5_gs_optim_r16_present = false; + bool iab_support_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PLMN-IdentityList-v1700 ::= SEQUENCE (SIZE (1..6)) OF PLMN-IdentityInfo-v1700 +using plmn_id_list_v1700_l = dyn_array; + // PosSIB-Type-r15 ::= SEQUENCE struct pos_sib_type_r15_s { struct pos_sib_type_r15_opts { @@ -134,12 +212,23 @@ struct pos_sib_type_r15_s { pos_sib_type2_minus19, pos_sib_type3_minus1, // ... + pos_sib_type1_minus8_v1610, + pos_sib_type2_minus20_v1610, + pos_sib_type2_minus21_v1610, + pos_sib_type2_minus22_v1610, + pos_sib_type2_minus23_v1610, + pos_sib_type2_minus24_v1610, + pos_sib_type2_minus25_v1610, + pos_sib_type4_minus1_v1610, + pos_sib_type5_minus1_v1610, + pos_sib_type1_minus9_v1700, + pos_sib_type1_minus10_v1700, nulltype } value; const char* to_string() const; }; - typedef enumerated pos_sib_type_r15_e_; + typedef enumerated pos_sib_type_r15_e_; // member variables bool ext = false; @@ -157,9 +246,39 @@ struct pos_sib_type_r15_s { void to_json(json_writer& j) const; }; +// PLMN-IdentityList-v1610 ::= SEQUENCE (SIZE (1..6)) OF PLMN-IdentityInfo-v1610 +using plmn_id_list_v1610_l = dyn_array; + // PosSIB-MappingInfo-r15 ::= SEQUENCE (SIZE (1..32)) OF PosSIB-Type-r15 using pos_sib_map_info_r15_l = dyn_array; +// SystemInformationBlockType1-v1700-IEs ::= SEQUENCE +struct sib_type1_v1700_ies_s { + struct cell_access_related_info_ntn_r17_s_ { + struct cell_barred_ntn_r17_opts { + enum options { barred, not_barred, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated cell_barred_ntn_r17_e_; + + // member variables + bool plmn_id_list_v1700_present = false; + cell_barred_ntn_r17_e_ cell_barred_ntn_r17; + plmn_id_list_v1700_l plmn_id_list_v1700; + }; + + // member variables + bool cell_access_related_info_ntn_r17_present = false; + bool non_crit_ext_present = false; + cell_access_related_info_ntn_r17_s_ cell_access_related_info_ntn_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PLMN-IdentityInfo-v1530 ::= SEQUENCE struct plmn_id_info_v1530_s { struct cell_reserved_for_oper_crs_r15_opts { @@ -199,6 +318,22 @@ struct pos_sched_info_r15_s { void to_json(json_writer& j) const; }; +// SystemInformationBlockType1-v1610-IEs ::= SEQUENCE +struct sib_type1_v1610_ies_s { + bool edrx_allowed_minus5_gc_r16_present = false; + bool tx_in_ctrl_ch_region_r16_present = false; + bool camping_allowed_in_ce_r16_present = false; + bool plmn_id_list_v1610_present = false; + bool non_crit_ext_present = false; + plmn_id_list_v1610_l plmn_id_list_v1610; + sib_type1_v1700_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CellSelectionInfoCE-v1530 ::= SEQUENCE struct cell_sel_info_ce_v1530_s { struct pwr_class14dbm_offset_r15_opts { @@ -227,8 +362,9 @@ using pos_sched_info_list_r15_l = dyn_array; // SystemInformationBlockType1-v1540-IEs ::= SEQUENCE struct sib_type1_v1540_ies_s { - bool si_pos_offset_r15_present = false; - bool non_crit_ext_present = false; + bool si_pos_offset_r15_present = false; + bool non_crit_ext_present = false; + sib_type1_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -936,14 +1072,16 @@ struct sib_type_opts { sib_type24_v1530, sib_type25_v1530, sib_type26_v1530, + sib_type26a_v1610, + sib_type27_v1610, + sib_type28_v1610, + sib_type29_v1610, nulltype } value; - typedef uint8_t number_type; const char* to_string() const; - uint8_t to_number() const; }; -typedef enumerated sib_type_e; +typedef enumerated sib_type_e; // SystemInformationBlockType1-v1250-IEs ::= SEQUENCE struct sib_type1_v1250_ies_s { @@ -1204,6 +1342,14 @@ struct sib_type2_s { ul_bw_e_ ul_bw; uint8_t add_spec_emission = 1; }; + struct mpdcch_cqi_report_r16_opts { + enum options { four_bits, both, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated mpdcch_cqi_report_r16_e_; // member variables bool ext = false; @@ -1252,6 +1398,19 @@ struct sib_type2_s { bool reduced_cp_latency_enabled_r15_present = false; // group 10 bool mbms_rom_service_ind_r15_present = false; + // group 11 + bool rlos_enabled_r16_present = false; + bool early_security_reactivation_r16_present = false; + bool cp_edt_minus5_gc_r16_present = false; + bool up_edt_minus5_gc_r16_present = false; + bool cp_pur_epc_r16_present = false; + bool up_pur_epc_r16_present = false; + bool cp_pur_minus5_gc_r16_present = false; + bool up_pur_minus5_gc_r16_present = false; + bool mpdcch_cqi_report_r16_present = false; + bool rai_activation_enh_r16_present = false; + bool idle_mode_meass_nr_r16_present = false; + mpdcch_cqi_report_r16_e_ mpdcch_cqi_report_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; diff --git a/lib/include/srsran/asn1/rrc/uecap.h b/lib/include/srsran/asn1/rrc/uecap.h index ae9b8aecde..32f1b83938 100644 --- a/lib/include/srsran/asn1/rrc/uecap.h +++ b/lib/include/srsran/asn1/rrc/uecap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -37,6 +37,29 @@ namespace rrc { * Struct Definitions ******************************************************************************/ +// UECapabilityEnquiry-v1710-IEs ::= SEQUENCE +struct ue_cap_enquiry_v1710_ies_s { + bool sidelink_request_r17_present = false; + bool non_crit_ext_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UECapabilityEnquiry-v1610-IEs ::= SEQUENCE +struct ue_cap_enquiry_v1610_ies_s { + bool rrc_seg_allowed_r16_present = false; + bool non_crit_ext_present = false; + ue_cap_enquiry_v1710_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CA-BandwidthClass-r10 ::= ENUMERATED struct ca_bw_class_r10_opts { enum options { a, b, c, d, e, f, /*...*/ nulltype } value; @@ -47,9 +70,10 @@ typedef enumerated ca_bw_class_r10_e; // UECapabilityEnquiry-v1560-IEs ::= SEQUENCE struct ue_cap_enquiry_v1560_ies_s { - bool requested_cap_common_r15_present = false; - bool non_crit_ext_present = false; - dyn_octstring requested_cap_common_r15; + bool requested_cap_common_r15_present = false; + bool non_crit_ext_present = false; + dyn_octstring requested_cap_common_r15; + ue_cap_enquiry_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -311,6 +335,14 @@ struct ue_radio_paging_info_r12_s { bool wake_up_signal_min_gap_e_drx_tdd_r15_present = false; wake_up_signal_min_gap_e_drx_r15_e_ wake_up_signal_min_gap_e_drx_r15; wake_up_signal_min_gap_e_drx_tdd_r15_e_ wake_up_signal_min_gap_e_drx_tdd_r15; + // group 2 + bool ue_category_dl_v1610_present = false; + bool group_wake_up_signal_r16_present = false; + bool group_wake_up_signal_tdd_r16_present = false; + bool group_wake_up_signal_alternation_r16_present = false; + bool group_wake_up_signal_alternation_tdd_r16_present = false; + // group 3 + bool inactive_state_po_determination_r17_present = false; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1529,6 +1561,125 @@ struct band_combination_params_v1530_s { void to_json(json_writer& j) const; }; +// InterRAT-BandInfoNR-r16 ::= SEQUENCE +struct inter_rat_band_info_nr_r16_s { + bool inter_rat_need_for_gaps_nr_r16 = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterRAT-BandListNR-r16 ::= SEQUENCE (SIZE (1..1024)) OF InterRAT-BandInfoNR-r16 +using inter_rat_band_list_nr_r16_l = dyn_array; + +// SRS-CapabilityPerBandPair-v1610 ::= SEQUENCE +struct srs_cap_per_band_pair_v1610_s { + bool add_srs_carrier_switching_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// BandParameters-v1610 ::= SEQUENCE +struct band_params_v1610_s { + struct intra_freq_daps_r16_s_ { + bool intra_freq_async_daps_r16_present = false; + bool dummy_present = false; + bool intra_freq_two_tags_daps_r16_present = false; + }; + struct add_srs_ant_switching_r16_s_ { + bool add_srs_minus1_t2_r_r16_present = false; + bool add_srs_minus1_t4_r_r16_present = false; + bool add_srs_minus2_t4_r_minus2pairs_r16_present = false; + bool add_srs_minus2_t4_r_minus3pairs_r16_present = false; + }; + using srs_cap_per_band_pair_list_v1610_l_ = dyn_array; + + // member variables + bool intra_freq_daps_r16_present = false; + bool add_srs_freq_hop_r16_present = false; + bool add_srs_ant_switching_r16_present = false; + bool srs_cap_per_band_pair_list_v1610_present = false; + intra_freq_daps_r16_s_ intra_freq_daps_r16; + add_srs_ant_switching_r16_s_ add_srs_ant_switching_r16; + srs_cap_per_band_pair_list_v1610_l_ srs_cap_per_band_pair_list_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasGapInfoNR-r16 ::= SEQUENCE +struct meas_gap_info_nr_r16_s { + bool inter_rat_band_list_nr_en_dc_r16_present = false; + bool inter_rat_band_list_nr_sa_r16_present = false; + inter_rat_band_list_nr_r16_l inter_rat_band_list_nr_en_dc_r16; + inter_rat_band_list_nr_r16_l inter_rat_band_list_nr_sa_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// BandCombinationParameters-v1610 ::= SEQUENCE +struct band_combination_params_v1610_s { + using band_param_list_v1610_l_ = dyn_array; + struct inter_freq_daps_r16_s_ { + bool inter_freq_async_daps_r16_present = false; + bool inter_freq_multi_ul_tx_daps_r16_present = false; + }; + + // member variables + bool meas_gap_info_nr_r16_present = false; + bool band_param_list_v1610_present = false; + bool inter_freq_daps_r16_present = false; + meas_gap_info_nr_r16_s meas_gap_info_nr_r16; + band_param_list_v1610_l_ band_param_list_v1610; + inter_freq_daps_r16_s_ inter_freq_daps_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ScalingFactorSidelink-r16 ::= ENUMERATED +struct scaling_factor_sidelink_r16_opts { + enum options { f0p4, f0p75, f0p8, f1, nulltype } value; + + const char* to_string() const; +}; +typedef enumerated scaling_factor_sidelink_r16_e; + +// BandCombinationParameters-v1630 ::= SEQUENCE +struct band_combination_params_v1630_s { + using scaling_factor_tx_sidelink_r16_l_ = dyn_array; + using scaling_factor_rx_sidelink_r16_l_ = dyn_array; + + // member variables + bool v2x_supported_tx_band_comb_list_per_bc_v1630_present = false; + bool v2x_supported_rx_band_comb_list_per_bc_v1630_present = false; + bool scaling_factor_tx_sidelink_r16_present = false; + bool scaling_factor_rx_sidelink_r16_present = false; + bool inter_band_pwr_sharing_sync_daps_r16_present = false; + bool inter_band_pwr_sharing_async_daps_r16_present = false; + bounded_bitstring<1, 512> v2x_supported_tx_band_comb_list_per_bc_v1630; + bounded_bitstring<1, 512> v2x_supported_rx_band_comb_list_per_bc_v1630; + scaling_factor_tx_sidelink_r16_l_ scaling_factor_tx_sidelink_r16; + scaling_factor_rx_sidelink_r16_l_ scaling_factor_rx_sidelink_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // BandCombinationParametersExt-r10 ::= SEQUENCE struct band_combination_params_ext_r10_s { bool supported_bw_combination_set_r10_present = false; @@ -2042,6 +2193,83 @@ struct mac_params_v1530_s { void to_json(json_writer& j) const; }; +// MBMS-SupportedBandInfo-r16 ::= SEQUENCE +struct mbms_supported_band_info_r16_s { + struct subcarrier_spacing_mbms_khz0dot37_r16_s_ { + bool time_separation_slot2_r16_present = false; + bool time_separation_slot4_r16_present = false; + }; + + // member variables + bool subcarrier_spacing_mbms_khz2dot5_r16_present = false; + bool subcarrier_spacing_mbms_khz0dot37_r16_present = false; + subcarrier_spacing_mbms_khz0dot37_r16_s_ subcarrier_spacing_mbms_khz0dot37_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MBMS-Parameters-v1610 ::= SEQUENCE +struct mbms_params_v1610_s { + struct mbms_scaling_factor2dot5_r16_opts { + enum options { n2, n4, n6, n8, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated mbms_scaling_factor2dot5_r16_e_; + struct mbms_scaling_factor0dot37_r16_opts { + enum options { n12, n16, n20, n24, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated mbms_scaling_factor0dot37_r16_e_; + using mbms_supported_band_info_list_r16_l_ = dyn_array; + + // member variables + bool mbms_scaling_factor2dot5_r16_present = false; + bool mbms_scaling_factor0dot37_r16_present = false; + mbms_scaling_factor2dot5_r16_e_ mbms_scaling_factor2dot5_r16; + mbms_scaling_factor0dot37_r16_e_ mbms_scaling_factor0dot37_r16; + mbms_supported_band_info_list_r16_l_ mbms_supported_band_info_list_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MBMS-SupportedBandInfo-v1700 ::= SEQUENCE +struct mbms_supported_band_info_v1700_s { + bool pmch_bw_n40_r17_present = false; + bool pmch_bw_n35_r17_present = false; + bool pmch_bw_n30_r17_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MBMS-Parameters-v1700 ::= SEQUENCE +struct mbms_params_v1700_s { + using mbms_supported_band_info_list_v1700_l_ = dyn_array; + + // member variables + bool mbms_supported_band_info_list_v1700_present = false; + mbms_supported_band_info_list_v1700_l_ mbms_supported_band_info_list_v1700; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MIMO-UE-BeamformedCapabilities-r13 ::= SEQUENCE struct mimo_ue_bf_cap_r13_s { bool alt_codebook_r13_present = false; @@ -2089,7 +2317,7 @@ struct mimo_ue_params_r13_s { struct mimo_ue_params_per_tm_v1430_s { struct nzp_csi_rs_aperiodic_info_r14_s_ { struct nmax_res_r14_opts { - enum options { ffs1, ffs2, ffs3, ffs4, nulltype } value; + enum options { n1, n2, n4, n8, nulltype } value; typedef uint8_t number_type; const char* to_string() const; @@ -2103,7 +2331,7 @@ struct mimo_ue_params_per_tm_v1430_s { }; struct nzp_csi_rs_periodic_info_r14_s_ { struct nmax_res_r14_opts { - enum options { ffs1, ffs2, ffs3, ffs4, nulltype } value; + enum options { n1, n2, n4, n8, nulltype } value; typedef uint8_t number_type; const char* to_string() const; @@ -2200,6 +2428,56 @@ struct meas_params_v1020_s { void to_json(json_writer& j) const; }; +// MeasParameters-v1610 ::= SEQUENCE +struct meas_params_v1610_s { + using band_info_nr_v1610_l_ = dyn_array; + + // member variables + bool band_info_nr_v1610_present = false; + bool alt_freq_prio_r16_present = false; + bool ce_dl_ch_quality_report_r16_present = false; + bool ce_meas_rss_ded_r16_present = false; + bool eutra_idle_inactive_meass_r16_present = false; + bool nr_idle_inactive_meas_fr1_r16_present = false; + bool nr_idle_inactive_meas_fr2_r16_present = false; + bool idle_inactive_validity_area_list_r16_present = false; + bool meas_gap_patterns_nronly_r16_present = false; + bool meas_gap_patterns_nronly_endc_r16_present = false; + band_info_nr_v1610_l_ band_info_nr_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SharedSpectrumMeasNR-r17 ::= SEQUENCE +struct shared_spec_meas_nr_r17_s { + bool nr_rssi_ch_occupancy_report_r17 = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasParameters-v1700 ::= SEQUENCE +struct meas_params_v1700_s { + using shared_spec_meas_nr_en_dc_r17_l_ = dyn_array; + using shared_spec_meas_nr_sa_r17_l_ = dyn_array; + + // member variables + bool shared_spec_meas_nr_en_dc_r17_present = false; + bool shared_spec_meas_nr_sa_r17_present = false; + shared_spec_meas_nr_en_dc_r17_l_ shared_spec_meas_nr_en_dc_r17; + shared_spec_meas_nr_sa_r17_l_ shared_spec_meas_nr_sa_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // NAICS-Capability-Entry-r12 ::= SEQUENCE struct naics_cap_entry_r12_s { struct nof_aggregated_prb_r12_opts { @@ -2659,6 +2937,87 @@ struct phy_layer_params_v1530_s { void to_json(json_writer& j) const; }; +// CE-MultiTB-Parameters-r16 ::= SEQUENCE +struct ce_multi_tb_params_r16_s { + bool pdsch_multi_tb_ce_mode_a_r16_present = false; + bool pdsch_multi_tb_ce_mode_b_r16_present = false; + bool pusch_multi_tb_ce_mode_a_r16_present = false; + bool pusch_multi_tb_ce_mode_b_r16_present = false; + bool ce_multi_tb_minus64_qam_r16_present = false; + bool ce_multi_tb_early_termination_r16_present = false; + bool ce_multi_tb_freq_hop_r16_present = false; + bool ce_multi_tb_harq_ack_bundling_r16_present = false; + bool ce_multi_tb_interleaving_r16_present = false; + bool ce_multi_tb_sub_prb_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CE-ResourceResvParameters-r16 ::= SEQUENCE +struct ce_res_resv_params_r16_s { + bool sf_res_resv_dl_ce_mode_a_r16_present = false; + bool sf_res_resv_dl_ce_mode_b_r16_present = false; + bool sf_res_resv_ul_ce_mode_a_r16_present = false; + bool sf_res_resv_ul_ce_mode_b_r16_present = false; + bool slot_symbol_res_resv_dl_ce_mode_a_r16_present = false; + bool slot_symbol_res_resv_dl_ce_mode_b_r16_present = false; + bool slot_symbol_res_resv_ul_ce_mode_a_r16_present = false; + bool slot_symbol_res_resv_ul_ce_mode_b_r16_present = false; + bool subcarrier_puncturing_ce_mode_a_r16_present = false; + bool subcarrier_puncturing_ce_mode_b_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PhyLayerParameters-v1610 ::= SEQUENCE +struct phy_layer_params_v1610_s { + struct ce_cap_v1610_s_ { + bool ce_csi_rs_feedback_r16_present = false; + bool ce_csi_rs_feedback_codebook_restrict_r16_present = false; + bool crs_ch_est_mpdcch_ce_mode_a_r16_present = false; + bool crs_ch_est_mpdcch_ce_mode_b_r16_present = false; + bool crs_ch_est_mpdcch_csi_r16_present = false; + bool crs_ch_est_mpdcch_reciprocity_tdd_r16_present = false; + bool etws_cmas_rx_in_conn_ce_mode_a_r16_present = false; + bool etws_cmas_rx_in_conn_ce_mode_b_r16_present = false; + bool mpdcch_in_lte_ctrl_region_ce_mode_a_r16_present = false; + bool mpdcch_in_lte_ctrl_region_ce_mode_b_r16_present = false; + bool pdsch_in_lte_ctrl_region_ce_mode_a_r16_present = false; + bool pdsch_in_lte_ctrl_region_ce_mode_b_r16_present = false; + bool multi_tb_params_r16_present = false; + bool res_resv_params_r16_present = false; + ce_multi_tb_params_r16_s multi_tb_params_r16; + ce_res_resv_params_r16_s res_resv_params_r16; + }; + struct add_srs_r16_s_ { + bool add_srs_freq_hop_r16_present = false; + bool add_srs_ant_switching_r16_present = false; + bool add_srs_carrier_switching_r16_present = false; + }; + + // member variables + bool ce_cap_v1610_present = false; + bool wideband_prg_slot_r16_present = false; + bool wideband_prg_subslot_r16_present = false; + bool wideband_prg_sf_r16_present = false; + bool add_srs_r16_present = false; + bool virtual_cell_id_basic_srs_r16_present = false; + bool virtual_cell_id_add_srs_r16_present = false; + ce_cap_v1610_s_ ce_cap_v1610; + add_srs_r16_s_ add_srs_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SupportedBandEUTRA ::= SEQUENCE struct supported_band_eutra_s { uint8_t band_eutra = 1; @@ -3123,6 +3482,54 @@ struct rf_params_v1530_s { void to_json(json_writer& j) const; }; +// SupportedBandCombination-v1610 ::= SEQUENCE (SIZE (1..128)) OF BandCombinationParameters-v1610 +using supported_band_combination_v1610_l = dyn_array; + +// SupportedBandCombinationAdd-v1610 ::= SEQUENCE (SIZE (1..256)) OF BandCombinationParameters-v1610 +using supported_band_combination_add_v1610_l = dyn_array; + +// SupportedBandCombinationReduced-v1610 ::= SEQUENCE (SIZE (1..384)) OF BandCombinationParameters-v1610 +using supported_band_combination_reduced_v1610_l = dyn_array; + +// RF-Parameters-v1610 ::= SEQUENCE +struct rf_params_v1610_s { + bool supported_band_combination_v1610_present = false; + bool supported_band_combination_add_v1610_present = false; + bool supported_band_combination_reduced_v1610_present = false; + supported_band_combination_v1610_l supported_band_combination_v1610; + supported_band_combination_add_v1610_l supported_band_combination_add_v1610; + supported_band_combination_reduced_v1610_l supported_band_combination_reduced_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SupportedBandCombination-v1630 ::= SEQUENCE (SIZE (1..128)) OF BandCombinationParameters-v1630 +using supported_band_combination_v1630_l = dyn_array; + +// SupportedBandCombinationAdd-v1630 ::= SEQUENCE (SIZE (1..256)) OF BandCombinationParameters-v1630 +using supported_band_combination_add_v1630_l = dyn_array; + +// SupportedBandCombinationReduced-v1630 ::= SEQUENCE (SIZE (1..384)) OF BandCombinationParameters-v1630 +using supported_band_combination_reduced_v1630_l = dyn_array; + +// RF-Parameters-v1630 ::= SEQUENCE +struct rf_params_v1630_s { + bool supported_band_combination_v1630_present = false; + bool supported_band_combination_add_v1630_present = false; + bool supported_band_combination_reduced_v1630_present = false; + supported_band_combination_v1630_l supported_band_combination_v1630; + supported_band_combination_add_v1630_l supported_band_combination_add_v1630; + supported_band_combination_reduced_v1630_l supported_band_combination_reduced_v1630; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SupportedBandEUTRA-v9e0 ::= SEQUENCE struct supported_band_eutra_v9e0_s { bool band_eutra_v9e0_present = false; @@ -3282,24 +3689,75 @@ struct sl_params_v1530_s { void to_json(json_writer& j) const; }; -// NeighCellSI-AcquisitionParameters-v15a0 ::= SEQUENCE -struct neigh_cell_si_acquisition_params_v15a0_s { - bool eutra_cgi_report_nedc_r15_present = false; +// V2X-BandParametersEUTRA-NR-r16 ::= CHOICE +struct v2x_band_params_eutra_nr_r16_c { + struct eutra_s_ { + bool v2x_band_params1_r16_present = false; + bool v2x_band_params2_r16_present = false; + v2x_band_params_r14_s v2x_band_params1_r16; + v2x_band_params_v1530_s v2x_band_params2_r16; + }; + struct nr_s_ { + bool v2x_band_params_nr_r16_present = false; + dyn_octstring v2x_band_params_nr_r16; + }; + struct types_opts { + enum options { eutra, nr, nulltype } value; - // sequence methods + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + v2x_band_params_eutra_nr_r16_c() = default; + v2x_band_params_eutra_nr_r16_c(const v2x_band_params_eutra_nr_r16_c& other); + v2x_band_params_eutra_nr_r16_c& operator=(const v2x_band_params_eutra_nr_r16_c& other); + ~v2x_band_params_eutra_nr_r16_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } SRSASN_CODE pack(bit_ref& bref) const; SRSASN_CODE unpack(cbit_ref& bref); void to_json(json_writer& j) const; + // getters + eutra_s_& eutra() + { + assert_choice_type(types::eutra, type_, "V2X-BandParametersEUTRA-NR-r16"); + return c.get(); + } + nr_s_& nr() + { + assert_choice_type(types::nr, type_, "V2X-BandParametersEUTRA-NR-r16"); + return c.get(); + } + const eutra_s_& eutra() const + { + assert_choice_type(types::eutra, type_, "V2X-BandParametersEUTRA-NR-r16"); + return c.get(); + } + const nr_s_& nr() const + { + assert_choice_type(types::nr, type_, "V2X-BandParametersEUTRA-NR-r16"); + return c.get(); + } + eutra_s_& set_eutra(); + nr_s_& set_nr(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); }; -// PhyLayerParameters-v1540 ::= SEQUENCE -struct phy_layer_params_v1540_s { - struct stti_spt_cap_v1540_s_ {}; +// V2X-SupportedBandCombinationEUTRA-NR-r16 ::= SEQUENCE (SIZE (1..512)) OF V2X-BandParametersEUTRA-NR-r16 +using v2x_supported_band_combination_eutra_nr_r16_l = dyn_array; - // member variables - bool stti_spt_cap_v1540_present = false; - bool crs_im_tm1_to_tm9_one_rx_port_v1540_present = false; - bool cch_im_ref_rec_type_a_one_rx_port_v1540_present = false; +// SL-Parameters-v1610 ::= SEQUENCE +struct sl_params_v1610_s { + bool sl_param_nr_r16_present = false; + bool dummy_present = false; + dyn_octstring sl_param_nr_r16; + v2x_supported_band_combination_eutra_nr_r16_l dummy; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3307,9 +3765,53 @@ struct phy_layer_params_v1540_s { void to_json(json_writer& j) const; }; -// PhyLayerParameters-v1550 ::= SEQUENCE -struct phy_layer_params_v1550_s { - bool dmrs_overhead_reduction_r15_present = false; +// V2X-BandParametersEUTRA-NR-v1630 ::= CHOICE +struct v2x_band_params_eutra_nr_v1630_c { + struct nr_s_ { + bool tx_sidelink_r16_present = false; + bool rx_sidelink_r16_present = false; + }; + struct types_opts { + enum options { eutra, nr, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + v2x_band_params_eutra_nr_v1630_c() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + nr_s_& nr() + { + assert_choice_type(types::nr, type_, "V2X-BandParametersEUTRA-NR-v1630"); + return c; + } + const nr_s_& nr() const + { + assert_choice_type(types::nr, type_, "V2X-BandParametersEUTRA-NR-v1630"); + return c; + } + void set_eutra(); + nr_s_& set_nr(); + +private: + types type_; + nr_s_ c; +}; + +// V2X-BandCombinationParametersEUTRA-NR-v1630 ::= SEQUENCE +struct v2x_band_combination_params_eutra_nr_v1630_s { + using band_list_sidelink_eutra_nr_r16_l_ = dyn_array; + using band_list_sidelink_eutra_nr_v1630_l_ = dyn_array; + + // member variables + band_list_sidelink_eutra_nr_r16_l_ band_list_sidelink_eutra_nr_r16; + band_list_sidelink_eutra_nr_v1630_l_ band_list_sidelink_eutra_nr_v1630; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3317,15 +3819,14 @@ struct phy_layer_params_v1550_s { void to_json(json_writer& j) const; }; -// EUTRA-5GC-Parameters-r15 ::= SEQUENCE -struct eutra_minus5_gc_params_r15_s { - bool eutra_minus5_gc_r15_present = false; - bool eutra_epc_ho_eutra_minus5_gc_r15_present = false; - bool ho_eutra_minus5_gc_fdd_tdd_r15_present = false; - bool ho_interfreq_eutra_minus5_gc_r15_present = false; - bool ims_voice_over_mcg_bearer_eutra_minus5_gc_r15_present = false; - bool inactive_state_r15_present = false; - bool reflective_qos_r15_present = false; +// V2X-SupportedBandCombinationEUTRA-NR-v1630 ::= SEQUENCE (SIZE (1..512)) OF +// V2X-BandCombinationParametersEUTRA-NR-v1630 +using v2x_supported_band_combination_eutra_nr_v1630_l = dyn_array; + +// SL-Parameters-v1630 ::= SEQUENCE +struct sl_params_v1630_s { + bool v2x_supported_band_combination_list_eutra_nr_r16_present = false; + v2x_supported_band_combination_eutra_nr_v1630_l v2x_supported_band_combination_list_eutra_nr_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3333,15 +3834,10 @@ struct eutra_minus5_gc_params_r15_s { void to_json(json_writer& j) const; }; -// UE-EUTRA-CapabilityAddXDD-Mode-v15a0 ::= SEQUENCE -struct ue_eutra_cap_add_xdd_mode_v15a0_s { - bool phy_layer_params_v1530_present = false; - bool phy_layer_params_v1540_present = false; - bool phy_layer_params_v1550_present = false; - phy_layer_params_v1530_s phy_layer_params_v1530; - phy_layer_params_v1540_s phy_layer_params_v1540; - phy_layer_params_v1550_s phy_layer_params_v1550; - neigh_cell_si_acquisition_params_v15a0_s neigh_cell_si_acquisition_params_v15a0; +// V2X-BandParametersEUTRA-NR-v1710 ::= SEQUENCE +struct v2x_band_params_eutra_nr_v1710_s { + bool v2x_band_params_eutra_nr_v1710_present = false; + dyn_octstring v2x_band_params_eutra_nr_v1710; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3349,10 +3845,17 @@ struct ue_eutra_cap_add_xdd_mode_v15a0_s { void to_json(json_writer& j) const; }; -// IRAT-ParametersNR-v1570 ::= SEQUENCE -struct irat_params_nr_v1570_s { - bool ss_sinr_meas_nr_fr1_r15_present = false; - bool ss_sinr_meas_nr_fr2_r15_present = false; +// V2X-BandCombinationParametersEUTRA-NR-v1710 ::= SEQUENCE (SIZE (1..64)) OF V2X-BandParametersEUTRA-NR-v1710 +using v2x_band_combination_params_eutra_nr_v1710_l = dyn_array; + +// V2X-SupportedBandCombinationEUTRA-NR-v1710 ::= SEQUENCE (SIZE (1..512)) OF +// V2X-BandCombinationParametersEUTRA-NR-v1710 +using v2x_supported_band_combination_eutra_nr_v1710_l = dyn_array; + +// SL-Parameters-v1710 ::= SEQUENCE +struct sl_params_v1710_s { + bool v2x_supported_band_combination_list_eutra_nr_v1710_present = false; + v2x_supported_band_combination_eutra_nr_v1710_l v2x_supported_band_combination_list_eutra_nr_v1710; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3360,9 +3863,9 @@ struct irat_params_nr_v1570_s { void to_json(json_writer& j) const; }; -// PDCP-ParametersNR-v1560 ::= SEQUENCE -struct pdcp_params_nr_v1560_s { - bool ims_vo_nr_pdcp_scg_ngendc_r15_present = false; +// PhyLayerParameters-v1730 ::= SEQUENCE +struct phy_layer_params_v1730_s { + bool csi_sf_set2_for_dormant_scell_r17_present = false; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3370,17 +3873,641 @@ struct pdcp_params_nr_v1560_s { void to_json(json_writer& j) const; }; -// RF-Parameters-v1570 ::= SEQUENCE -struct rf_params_v1570_s { - struct dl_minus1024_qam_scaling_factor_r15_opts { - enum options { v1, v1dot2, v1dot25, nulltype } value; - typedef float number_type; +// NTN-Parameters-v1720 ::= SEQUENCE +struct ntn_params_v1720_s { + struct ntn_segmented_precompensation_gaps_r17_opts { + enum options { sym1, sl1, sf1, nulltype } value; const char* to_string() const; - float to_number() const; - const char* to_number_string() const; }; - typedef enumerated dl_minus1024_qam_scaling_factor_r15_e_; + typedef enumerated ntn_segmented_precompensation_gaps_r17_e_; + + // member variables + bool ntn_segmented_precompensation_gaps_r17_present = false; + ntn_segmented_precompensation_gaps_r17_e_ ntn_segmented_precompensation_gaps_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v1730-IEs ::= SEQUENCE +struct ue_eutra_cap_v1730_ies_s { + bool non_crit_ext_present = false; + phy_layer_params_v1730_s phy_layer_params_v1730; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// IRAT-ParametersNR-v1710 ::= SEQUENCE +struct irat_params_nr_v1710_s { + bool extended_band_n77_minus2_r17_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NeighCellSI-AcquisitionParameters-v1710 ::= SEQUENCE +struct neigh_cell_si_acquisition_params_v1710_s { + bool gnb_id_len_report_nr_en_dc_r17_present = false; + bool gnb_id_len_report_nr_no_en_dc_r17_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v1720-IEs ::= SEQUENCE +struct ue_eutra_cap_v1720_ies_s { + bool non_crit_ext_present = false; + ntn_params_v1720_s ntn_params_v1720; + ue_eutra_cap_v1730_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// IRAT-ParametersNR-v1700 ::= SEQUENCE +struct irat_params_nr_v1700_s { + bool eutra_minus5_gc_ho_to_nr_tdd_fr2_minus2_r17_present = false; + bool eutra_epc_ho_to_nr_tdd_fr2_minus2_r17_present = false; + bool ce_eutra_minus5_gc_ho_to_nr_tdd_fr2_minus2_r17_present = false; + bool ims_voice_over_nr_fr2_minus2_r17_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NTN-Parameters-r17 ::= SEQUENCE +struct ntn_params_r17_s { + struct ntn_scenario_support_r17_opts { + enum options { ngso, gso, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated ntn_scenario_support_r17_e_; + + // member variables + bool ntn_connect_epc_r17_present = false; + bool ntn_ta_report_r17_present = false; + bool ntn_pur_timer_delay_r17_present = false; + bool ntn_offset_timing_enh_r17_present = false; + bool ntn_scenario_support_r17_present = false; + ntn_scenario_support_r17_e_ ntn_scenario_support_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PhyLayerParameters-v1700 ::= SEQUENCE +struct phy_layer_params_v1700_s { + struct ce_cap_v1700_s_ { + bool ce_pdsch_minus14_harq_processes_r17_present = false; + bool ce_pdsch_minus14_harq_processes_alt2_r17_present = false; + bool ce_pdsch_max_tbs_r17_present = false; + }; + + // member variables + bool ce_cap_v1700_present = false; + ce_cap_v1700_s_ ce_cap_v1700; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-BasedNetwPerfMeasParameters-v1700 ::= SEQUENCE +struct ue_based_netw_perf_meas_params_v1700_s { + bool logged_meas_idle_event_l1_r17_present = false; + bool logged_meas_idle_event_out_of_coverage_r17_present = false; + bool logged_meas_uncom_bar_pre_r17_present = false; + bool imm_meas_uncom_bar_pre_r17_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v1710-IEs ::= SEQUENCE +struct ue_eutra_cap_v1710_ies_s { + bool neigh_cell_si_acquisition_params_v1710_present = false; + bool sl_params_v1710_present = false; + bool sidelink_requested_r17_present = false; + bool non_crit_ext_present = false; + irat_params_nr_v1710_s irat_params_nr_v1710; + neigh_cell_si_acquisition_params_v1710_s neigh_cell_si_acquisition_params_v1710; + sl_params_v1710_s sl_params_v1710; + ue_eutra_cap_v1720_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// Other-Parameters-v1690 ::= SEQUENCE +struct other_params_v1690_s { + bool ul_rrc_segmentation_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v1700-IEs ::= SEQUENCE +struct ue_eutra_cap_v1700_ies_s { + bool meas_params_v1700_present = false; + bool ue_based_netw_perf_meas_params_v1700_present = false; + bool ntn_params_r17_present = false; + bool irat_params_nr_v1700_present = false; + bool non_crit_ext_present = false; + meas_params_v1700_s meas_params_v1700; + ue_based_netw_perf_meas_params_v1700_s ue_based_netw_perf_meas_params_v1700; + phy_layer_params_v1700_s phy_layer_params_v1700; + ntn_params_r17_s ntn_params_r17; + irat_params_nr_v1700_s irat_params_nr_v1700; + mbms_params_v1700_s mbms_params_v1700; + ue_eutra_cap_v1710_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// IRAT-ParametersNR-v1660 ::= SEQUENCE +struct irat_params_nr_v1660_s { + bool extended_band_n77_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v1690-IEs ::= SEQUENCE +struct ue_eutra_cap_v1690_ies_s { + bool non_crit_ext_present = false; + other_params_v1690_s other_params_v1690; + ue_eutra_cap_v1700_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasParameters-v1630 ::= SEQUENCE +struct meas_params_v1630_s { + bool nr_idle_inactive_beam_meas_fr1_r16_present = false; + bool nr_idle_inactive_beam_meas_fr2_r16_present = false; + bool ce_meas_rss_ded_same_rbs_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// Other-Parameters-v1650 ::= SEQUENCE +struct other_params_v1650_s { + bool mps_prio_ind_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v1660-IEs ::= SEQUENCE +struct ue_eutra_cap_v1660_ies_s { + bool non_crit_ext_present = false; + irat_params_nr_v1660_s irat_params_nr_v1660; + ue_eutra_cap_v1690_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// EUTRA-5GC-Parameters-v1610 ::= SEQUENCE +struct eutra_minus5_gc_params_v1610_s { + bool ce_inactive_state_r16_present = false; + bool ce_eutra_minus5_gc_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// IRAT-ParametersNR-v1610 ::= SEQUENCE +struct irat_params_nr_v1610_s { + bool nr_ho_to_en_dc_r16_present = false; + bool ce_eutra_minus5_gc_ho_to_nr_fdd_fr1_r16_present = false; + bool ce_eutra_minus5_gc_ho_to_nr_tdd_fr1_r16_present = false; + bool ce_eutra_minus5_gc_ho_to_nr_fdd_fr2_r16_present = false; + bool ce_eutra_minus5_gc_ho_to_nr_tdd_fr2_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MAC-Parameters-v1630 ::= SEQUENCE +struct mac_params_v1630_s { + bool direct_scg_scell_activation_nedc_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MobilityParameters-v1610 ::= SEQUENCE +struct mob_params_v1610_s { + bool cho_r16_present = false; + bool cho_fdd_tdd_r16_present = false; + bool cho_fail_r16_present = false; + bool cho_two_trigger_events_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NeighCellSI-AcquisitionParameters-v1610 ::= SEQUENCE +struct neigh_cell_si_acquisition_params_v1610_s { + bool eutra_si_acquisition_for_ho_endc_r16_present = false; + bool nr_autonomous_gaps_endc_fr1_r16_present = false; + bool nr_autonomous_gaps_endc_fr2_r16_present = false; + bool nr_autonomous_gaps_fr1_r16_present = false; + bool nr_autonomous_gaps_fr2_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PUR-Parameters-r16 ::= SEQUENCE +struct pur_params_r16_s { + bool pur_cp_minus5_gc_ce_mode_a_r16_present = false; + bool pur_cp_minus5_gc_ce_mode_b_r16_present = false; + bool pur_up_minus5_gc_ce_mode_a_r16_present = false; + bool pur_up_minus5_gc_ce_mode_b_r16_present = false; + bool pur_cp_epc_ce_mode_a_r16_present = false; + bool pur_cp_epc_ce_mode_b_r16_present = false; + bool pur_up_epc_ce_mode_a_r16_present = false; + bool pur_up_epc_ce_mode_b_r16_present = false; + bool pur_cp_l1_ack_r16_present = false; + bool pur_freq_hop_r16_present = false; + bool pur_pusch_nb_max_tbs_r16_present = false; + bool pur_rsrp_validation_r16_present = false; + bool pur_sub_prb_ce_mode_a_r16_present = false; + bool pur_sub_prb_ce_mode_b_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v1650-IEs ::= SEQUENCE +struct ue_eutra_cap_v1650_ies_s { + bool other_params_v1650_present = false; + bool non_crit_ext_present = false; + other_params_v1650_s other_params_v1650; + ue_eutra_cap_v1660_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-CapabilityAddXDD-Mode-v1630 ::= SEQUENCE +struct ue_eutra_cap_add_xdd_mode_v1630_s { + meas_params_v1630_s meas_params_v1630; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// HighSpeedEnhParameters-v1610 ::= SEQUENCE +struct high_speed_enh_params_v1610_s { + bool meas_enhance_scell_r16_present = false; + bool meas_enhance2_r16_present = false; + bool demod_enhance2_r16_present = false; + bool inter_rat_enhancement_nr_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MAC-Parameters-v1610 ::= SEQUENCE +struct mac_params_v1610_s { + bool direct_mcg_scell_activation_resume_r16_present = false; + bool direct_scg_scell_activation_resume_r16_present = false; + bool early_data_up_minus5_gc_r16_present = false; + bool rai_support_enh_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MMTEL-Parameters-v1610 ::= SEQUENCE +struct mmtel_params_v1610_s { + bool recommended_bit_rate_multiplier_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NeighCellSI-AcquisitionParameters-v15a0 ::= SEQUENCE +struct neigh_cell_si_acquisition_params_v15a0_s { + bool eutra_cgi_report_nedc_r15_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// Other-Parameters-v1610 ::= SEQUENCE +struct other_params_v1610_s { + bool resume_with_stored_mcg_scells_r16_present = false; + bool resume_with_mcg_scell_cfg_r16_present = false; + bool resume_with_stored_scg_r16_present = false; + bool resume_with_scg_cfg_r16_present = false; + bool mcg_rlf_recovery_via_scg_r16_present = false; + bool overheat_ind_for_scg_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PDCP-Parameters-v1610 ::= SEQUENCE +struct pdcp_params_v1610_s { + struct max_num_ehc_contexts_r16_opts { + enum options { + cs2, + cs4, + cs8, + cs16, + cs32, + cs64, + cs128, + cs256, + cs512, + cs1024, + cs2048, + cs4096, + cs8192, + cs16384, + cs32768, + cs65536, + nulltype + } value; + typedef uint32_t number_type; + + const char* to_string() const; + uint32_t to_number() const; + }; + typedef enumerated max_num_ehc_contexts_r16_e_; + + // member variables + bool pdcp_version_change_without_ho_r16_present = false; + bool ehc_r16_present = false; + bool continue_ehc_context_r16_present = false; + bool max_num_ehc_contexts_r16_present = false; + bool joint_ehc_rohc_cfg_r16_present = false; + max_num_ehc_contexts_r16_e_ max_num_ehc_contexts_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PhyLayerParameters-v1540 ::= SEQUENCE +struct phy_layer_params_v1540_s { + struct stti_spt_cap_v1540_s_ {}; + + // member variables + bool stti_spt_cap_v1540_present = false; + bool crs_im_tm1_to_tm9_one_rx_port_v1540_present = false; + bool cch_im_ref_rec_type_a_one_rx_port_v1540_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PhyLayerParameters-v1550 ::= SEQUENCE +struct phy_layer_params_v1550_s { + bool dmrs_overhead_reduction_r15_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-BasedNetwPerfMeasParameters-v1610 ::= SEQUENCE +struct ue_based_netw_perf_meas_params_v1610_s { + bool ul_pdcp_avg_delay_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v1630-IEs ::= SEQUENCE +struct ue_eutra_cap_v1630_ies_s { + bool rf_params_v1630_present = false; + bool sl_params_v1630_present = false; + bool early_security_reactivation_r16_present = false; + bool meas_params_v1630_present = false; + bool non_crit_ext_present = false; + rf_params_v1630_s rf_params_v1630; + sl_params_v1630_s sl_params_v1630; + mac_params_v1630_s mac_params_v1630; + meas_params_v1630_s meas_params_v1630; + ue_eutra_cap_add_xdd_mode_v1630_s fdd_add_ue_eutra_cap_v1630; + ue_eutra_cap_add_xdd_mode_v1630_s tdd_add_ue_eutra_cap_v1630; + ue_eutra_cap_v1650_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-CapabilityAddXDD-Mode-v1610 ::= SEQUENCE +struct ue_eutra_cap_add_xdd_mode_v1610_s { + bool phy_layer_params_v1610_present = false; + bool pur_params_r16_present = false; + bool meas_params_v1610_present = false; + bool eutra_minus5_gc_params_v1610_present = false; + bool irat_params_nr_v1610_present = false; + bool neigh_cell_si_acquisition_params_v1610_present = false; + bool mob_params_v1610_present = false; + phy_layer_params_v1610_s phy_layer_params_v1610; + pur_params_r16_s pur_params_r16; + meas_params_v1610_s meas_params_v1610; + eutra_minus5_gc_params_v1610_s eutra_minus5_gc_params_v1610; + irat_params_nr_v1610_s irat_params_nr_v1610; + neigh_cell_si_acquisition_params_v1610_s neigh_cell_si_acquisition_params_v1610; + mob_params_v1610_s mob_params_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// EUTRA-5GC-Parameters-r15 ::= SEQUENCE +struct eutra_minus5_gc_params_r15_s { + bool eutra_minus5_gc_r15_present = false; + bool eutra_epc_ho_eutra_minus5_gc_r15_present = false; + bool ho_eutra_minus5_gc_fdd_tdd_r15_present = false; + bool ho_interfreq_eutra_minus5_gc_r15_present = false; + bool ims_voice_over_mcg_bearer_eutra_minus5_gc_r15_present = false; + bool inactive_state_r15_present = false; + bool reflective_qos_r15_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v1610-IEs ::= SEQUENCE +struct ue_eutra_cap_v1610_ies_s { + bool high_speed_enh_params_v1610_present = false; + bool neigh_cell_si_acquisition_params_v1610_present = false; + bool mbms_params_v1610_present = false; + bool pdcp_params_v1610_present = false; + bool mac_params_v1610_present = false; + bool phy_layer_params_v1610_present = false; + bool meas_params_v1610_present = false; + bool pur_params_r16_present = false; + bool eutra_minus5_gc_params_v1610_present = false; + bool other_params_v1610_present = false; + bool dl_ded_msg_segmentation_r16_present = false; + bool irat_params_nr_v1610_present = false; + bool rf_params_v1610_present = false; + bool mob_params_v1610_present = false; + bool sl_params_v1610_present = false; + bool fdd_add_ue_eutra_cap_v1610_present = false; + bool tdd_add_ue_eutra_cap_v1610_present = false; + bool non_crit_ext_present = false; + high_speed_enh_params_v1610_s high_speed_enh_params_v1610; + neigh_cell_si_acquisition_params_v1610_s neigh_cell_si_acquisition_params_v1610; + mbms_params_v1610_s mbms_params_v1610; + pdcp_params_v1610_s pdcp_params_v1610; + mac_params_v1610_s mac_params_v1610; + phy_layer_params_v1610_s phy_layer_params_v1610; + meas_params_v1610_s meas_params_v1610; + pur_params_r16_s pur_params_r16; + eutra_minus5_gc_params_v1610_s eutra_minus5_gc_params_v1610; + other_params_v1610_s other_params_v1610; + mmtel_params_v1610_s mmtel_params_v1610; + irat_params_nr_v1610_s irat_params_nr_v1610; + rf_params_v1610_s rf_params_v1610; + mob_params_v1610_s mob_params_v1610; + ue_based_netw_perf_meas_params_v1610_s ue_based_netw_perf_meas_params_v1610; + sl_params_v1610_s sl_params_v1610; + ue_eutra_cap_add_xdd_mode_v1610_s fdd_add_ue_eutra_cap_v1610; + ue_eutra_cap_add_xdd_mode_v1610_s tdd_add_ue_eutra_cap_v1610; + ue_eutra_cap_v1630_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-CapabilityAddXDD-Mode-v15a0 ::= SEQUENCE +struct ue_eutra_cap_add_xdd_mode_v15a0_s { + bool phy_layer_params_v1530_present = false; + bool phy_layer_params_v1540_present = false; + bool phy_layer_params_v1550_present = false; + phy_layer_params_v1530_s phy_layer_params_v1530; + phy_layer_params_v1540_s phy_layer_params_v1540; + phy_layer_params_v1550_s phy_layer_params_v1550; + neigh_cell_si_acquisition_params_v15a0_s neigh_cell_si_acquisition_params_v15a0; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// IRAT-ParametersNR-v1570 ::= SEQUENCE +struct irat_params_nr_v1570_s { + bool ss_sinr_meas_nr_fr1_r15_present = false; + bool ss_sinr_meas_nr_fr2_r15_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PDCP-ParametersNR-v1560 ::= SEQUENCE +struct pdcp_params_nr_v1560_s { + bool ims_vo_nr_pdcp_scg_ngendc_r15_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RF-Parameters-v1570 ::= SEQUENCE +struct rf_params_v1570_s { + struct dl_minus1024_qam_scaling_factor_r15_opts { + enum options { v1, v1dot2, v1dot25, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated dl_minus1024_qam_scaling_factor_r15_e_; // member variables dl_minus1024_qam_scaling_factor_r15_e_ dl_minus1024_qam_scaling_factor_r15; @@ -3402,6 +4529,7 @@ struct ue_eutra_cap_v15a0_ies_s { eutra_minus5_gc_params_r15_s eutra_minus5_gc_params_r15; ue_eutra_cap_add_xdd_mode_v15a0_s fdd_add_ue_eutra_cap_v15a0; ue_eutra_cap_add_xdd_mode_v15a0_s tdd_add_ue_eutra_cap_v15a0; + ue_eutra_cap_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -4361,7 +5489,7 @@ struct mac_params_v1310_s { // MeasParameters-v1310 ::= SEQUENCE struct meas_params_v1310_s { bool rs_sinr_meas_r13_present = false; - bool white_cell_list_r13_present = false; + bool allowed_cell_list_r13_present = false; bool extended_max_obj_id_r13_present = false; bool ul_pdcp_delay_r13_present = false; bool extended_freq_priorities_r13_present = false; @@ -5082,13 +6210,13 @@ struct ue_eutra_cap_v940_ies_s { // AccessStratumRelease ::= ENUMERATED struct access_stratum_release_opts { - enum options { rel8, rel9, rel10, rel11, rel12, rel13, rel14, rel15, /*...*/ nulltype } value; + enum options { rel8, rel9, rel10, rel11, rel12, rel13, rel14, rel15, /*...*/ rel16, rel17, nulltype } value; typedef uint8_t number_type; const char* to_string() const; uint8_t to_number() const; }; -typedef enumerated access_stratum_release_e; +typedef enumerated access_stratum_release_e; // PhyLayerParameters ::= SEQUENCE struct phy_layer_params_s { @@ -5160,6 +6288,55 @@ struct ue_eutra_cap_s { void to_json(json_writer& j) const; }; +// MeasParameters-v16c0 ::= SEQUENCE +struct meas_params_v16c0_s { + bool nr_cell_individual_offset_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v16c0-IEs ::= SEQUENCE +struct ue_eutra_cap_v16c0_ies_s { + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + meas_params_v16c0_s meas_params_v16c0; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v15x0-IEs ::= SEQUENCE +struct ue_eutra_cap_v15x0_ies_s { + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + dyn_octstring late_non_crit_ext; + ue_eutra_cap_v16c0_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-EUTRA-Capability-v14x0-IEs ::= SEQUENCE +struct ue_eutra_cap_v14x0_ies_s { + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + dyn_octstring late_non_crit_ext; + ue_eutra_cap_v15x0_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PhyLayerParameters-v14a0 ::= SEQUENCE struct phy_layer_params_v14a0_s { bool ssp10_tdd_only_r14_present = false; @@ -5172,9 +6349,10 @@ struct phy_layer_params_v14a0_s { // UE-EUTRA-Capability-v14b0-IEs ::= SEQUENCE struct ue_eutra_cap_v14b0_ies_s { - bool rf_params_v14b0_present = false; - bool non_crit_ext_present = false; - rf_params_v14b0_s rf_params_v14b0; + bool rf_params_v14b0_present = false; + bool non_crit_ext_present = false; + rf_params_v14b0_s rf_params_v14b0; + ue_eutra_cap_v14x0_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; diff --git a/lib/include/srsran/asn1/rrc/ul_ccch_msg.h b/lib/include/srsran/asn1/rrc/ul_ccch_msg.h index bca30021e0..9f3e54b330 100644 --- a/lib/include/srsran/asn1/rrc/ul_ccch_msg.h +++ b/lib/include/srsran/asn1/rrc/ul_ccch_msg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -37,6 +37,25 @@ namespace rrc { * Struct Definitions ******************************************************************************/ +// RRCEarlyDataRequest-v1610-IEs ::= SEQUENCE +struct rrc_early_data_request_v1610_ies_s { + struct establishment_cause_v1610_opts { + enum options { mt_access, spare3, spare2, spare1, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated establishment_cause_v1610_e_; + + // member variables + bool non_crit_ext_present = false; + establishment_cause_v1610_e_ establishment_cause_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // EstablishmentCause ::= ENUMERATED struct establishment_cause_opts { enum options { @@ -55,8 +74,8 @@ struct establishment_cause_opts { }; typedef enumerated establishment_cause_e; -// EstablishmentCause-5GC ::= ENUMERATED -struct establishment_cause_minus5_gc_opts { +// EstablishmentCause-5GC-r15 ::= ENUMERATED +struct establishment_cause_minus5_gc_r15_opts { enum options { emergency, high_prio_access, @@ -71,7 +90,7 @@ struct establishment_cause_minus5_gc_opts { const char* to_string() const; }; -typedef enumerated establishment_cause_minus5_gc_e; +typedef enumerated establishment_cause_minus5_gc_r15_e; // InitialUE-Identity ::= CHOICE struct init_ue_id_c { @@ -123,8 +142,8 @@ struct init_ue_id_c { void destroy_(); }; -// InitialUE-Identity-5GC ::= CHOICE -struct init_ue_id_minus5_gc_c { +// InitialUE-Identity-5GC-r15 ::= CHOICE +struct init_ue_id_minus5_gc_r15_c { struct types_opts { enum options { ng_minus5_g_s_tmsi_part1, random_value, nulltype } value; typedef int8_t number_type; @@ -135,10 +154,10 @@ struct init_ue_id_minus5_gc_c { typedef enumerated types; // choice methods - init_ue_id_minus5_gc_c() = default; - init_ue_id_minus5_gc_c(const init_ue_id_minus5_gc_c& other); - init_ue_id_minus5_gc_c& operator=(const init_ue_id_minus5_gc_c& other); - ~init_ue_id_minus5_gc_c() { destroy_(); } + init_ue_id_minus5_gc_r15_c() = default; + init_ue_id_minus5_gc_r15_c(const init_ue_id_minus5_gc_r15_c& other); + init_ue_id_minus5_gc_r15_c& operator=(const init_ue_id_minus5_gc_r15_c& other); + ~init_ue_id_minus5_gc_r15_c() { destroy_(); } void set(types::options e = types::nulltype); types type() const { return type_; } SRSASN_CODE pack(bit_ref& bref) const; @@ -147,22 +166,22 @@ struct init_ue_id_minus5_gc_c { // getters fixed_bitstring<40>& ng_minus5_g_s_tmsi_part1() { - assert_choice_type(types::ng_minus5_g_s_tmsi_part1, type_, "InitialUE-Identity-5GC"); + assert_choice_type(types::ng_minus5_g_s_tmsi_part1, type_, "InitialUE-Identity-5GC-r15"); return c.get >(); } fixed_bitstring<40>& random_value() { - assert_choice_type(types::random_value, type_, "InitialUE-Identity-5GC"); + assert_choice_type(types::random_value, type_, "InitialUE-Identity-5GC-r15"); return c.get >(); } const fixed_bitstring<40>& ng_minus5_g_s_tmsi_part1() const { - assert_choice_type(types::ng_minus5_g_s_tmsi_part1, type_, "InitialUE-Identity-5GC"); + assert_choice_type(types::ng_minus5_g_s_tmsi_part1, type_, "InitialUE-Identity-5GC-r15"); return c.get >(); } const fixed_bitstring<40>& random_value() const { - assert_choice_type(types::random_value, type_, "InitialUE-Identity-5GC"); + assert_choice_type(types::random_value, type_, "InitialUE-Identity-5GC-r15"); return c.get >(); } fixed_bitstring<40>& set_ng_minus5_g_s_tmsi_part1(); @@ -177,9 +196,10 @@ struct init_ue_id_minus5_gc_c { // RRCEarlyDataRequest-v1590-IEs ::= SEQUENCE struct rrc_early_data_request_v1590_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - dyn_octstring late_non_crit_ext; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + dyn_octstring late_non_crit_ext; + rrc_early_data_request_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -217,7 +237,7 @@ struct resume_cause_opts { mo_data, delay_tolerant_access_v1020, mo_voice_call_v1280, - spare1, + mt_edt_v1610, nulltype } value; @@ -257,9 +277,9 @@ struct rrc_conn_reest_request_r8_ies_s { // RRCConnectionRequest-5GC-r15-IEs ::= SEQUENCE struct rrc_conn_request_minus5_gc_r15_ies_s { - init_ue_id_minus5_gc_c ue_id; - establishment_cause_minus5_gc_e establishment_cause; - fixed_bitstring<1> spare; + init_ue_id_minus5_gc_r15_c ue_id_r15; + establishment_cause_minus5_gc_r15_e establishment_cause_r15; + fixed_bitstring<1> spare; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -405,6 +425,29 @@ struct rrc_conn_resume_request_r13_ies_s { void to_json(json_writer& j) const; }; +// RRCEarlyDataRequest-5GC-r16-IEs ::= SEQUENCE +struct rrc_early_data_request_minus5_gc_r16_ies_s { + struct establishment_cause_r16_opts { + enum options { mo_data, spare3, spare2, spare1, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated establishment_cause_r16_e_; + + // member variables + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + fixed_bitstring<48> ng_minus5_g_s_tmsi_r16; + establishment_cause_r16_e_ establishment_cause_r16; + dyn_octstring ded_info_nas_r16; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCEarlyDataRequest-r15-IEs ::= SEQUENCE struct rrc_early_data_request_r15_ies_s { struct establishment_cause_r15_opts { @@ -595,6 +638,41 @@ struct rrc_conn_resume_request_r13_s { // RRCEarlyDataRequest-r15 ::= SEQUENCE struct rrc_early_data_request_r15_s { struct crit_exts_c_ { + struct crit_exts_future_c_ { + struct types_opts { + enum options { rrc_early_data_request_minus5_gc_r16, crit_exts_future_r16, nulltype } value; + typedef int8_t number_type; + + const char* to_string() const; + int8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + crit_exts_future_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + rrc_early_data_request_minus5_gc_r16_ies_s& rrc_early_data_request_minus5_gc_r16() + { + assert_choice_type(types::rrc_early_data_request_minus5_gc_r16, type_, "criticalExtensionsFuture"); + return c; + } + const rrc_early_data_request_minus5_gc_r16_ies_s& rrc_early_data_request_minus5_gc_r16() const + { + assert_choice_type(types::rrc_early_data_request_minus5_gc_r16, type_, "criticalExtensionsFuture"); + return c; + } + rrc_early_data_request_minus5_gc_r16_ies_s& set_rrc_early_data_request_minus5_gc_r16(); + void set_crit_exts_future_r16(); + + private: + types type_; + rrc_early_data_request_minus5_gc_r16_ies_s c; + }; struct types_opts { enum options { rrc_early_data_request_r15, crit_exts_future, nulltype } value; @@ -604,6 +682,9 @@ struct rrc_early_data_request_r15_s { // choice methods crit_exts_c_() = default; + crit_exts_c_(const crit_exts_c_& other); + crit_exts_c_& operator=(const crit_exts_c_& other); + ~crit_exts_c_() { destroy_(); } void set(types::options e = types::nulltype); types type() const { return type_; } SRSASN_CODE pack(bit_ref& bref) const; @@ -613,19 +694,31 @@ struct rrc_early_data_request_r15_s { rrc_early_data_request_r15_ies_s& rrc_early_data_request_r15() { assert_choice_type(types::rrc_early_data_request_r15, type_, "criticalExtensions"); - return c; + return c.get(); + } + crit_exts_future_c_& crit_exts_future() + { + assert_choice_type(types::crit_exts_future, type_, "criticalExtensions"); + return c.get(); } const rrc_early_data_request_r15_ies_s& rrc_early_data_request_r15() const { assert_choice_type(types::rrc_early_data_request_r15, type_, "criticalExtensions"); - return c; + return c.get(); + } + const crit_exts_future_c_& crit_exts_future() const + { + assert_choice_type(types::crit_exts_future, type_, "criticalExtensions"); + return c.get(); } rrc_early_data_request_r15_ies_s& set_rrc_early_data_request_r15(); - void set_crit_exts_future(); + crit_exts_future_c_& set_crit_exts_future(); private: - types type_; - rrc_early_data_request_r15_ies_s c; + types type_; + choice_buffer_t c; + + void destroy_(); }; // member variables diff --git a/lib/include/srsran/asn1/rrc/ul_dcch_msg.h b/lib/include/srsran/asn1/rrc/ul_dcch_msg.h index d1cdedd756..bd2453677a 100644 --- a/lib/include/srsran/asn1/rrc/ul_dcch_msg.h +++ b/lib/include/srsran/asn1/rrc/ul_dcch_msg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -101,6 +101,97 @@ struct tmgi_r9_s { void to_json(json_writer& j) const; }; +// GNSS-ValidityDuration-r17 ::= ENUMERATED +struct gnss_validity_dur_r17_opts { + enum options { + s10, + s20, + s30, + s40, + s50, + s60, + min5, + min10, + min15, + min20, + min25, + min30, + min50, + min90, + min120, + infinity, + nulltype + } value; + + const char* to_string() const; +}; +typedef enumerated gnss_validity_dur_r17_e; + +// RRCConnectionSetupComplete-v1710-IEs ::= SEQUENCE +struct rrc_conn_setup_complete_v1710_ies_s { + bool gnss_validity_dur_r17_present = false; + bool non_crit_ext_present = false; + gnss_validity_dur_r17_e gnss_validity_dur_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionSetupComplete-v1690-IEs ::= SEQUENCE +struct rrc_conn_setup_complete_v1690_ies_s { + bool ul_rrc_segmentation_r16_present = false; + bool non_crit_ext_present = false; + rrc_conn_setup_complete_v1710_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ResultsPerSSB-IndexIdle-r16 ::= SEQUENCE +struct results_per_ssb_idx_idle_r16_s { + struct ssb_results_r16_s_ { + bool ssb_rsrp_result_r16_present = false; + bool ssb_rsrq_result_r16_present = false; + uint8_t ssb_rsrp_result_r16 = 0; + uint8_t ssb_rsrq_result_r16 = 0; + }; + + // member variables + bool ssb_results_r16_present = false; + uint8_t ssb_idx_r16 = 0; + ssb_results_r16_s_ ssb_results_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionSetupComplete-v1610-IEs ::= SEQUENCE +struct rrc_conn_setup_complete_v1610_ies_s { + bool rlos_request_r16_present = false; + bool cp_cio_t_minus5_gs_optim_r16_present = false; + bool up_cio_t_minus5_gs_optim_r16_present = false; + bool pur_cfg_id_r16_present = false; + bool lte_m_r16_present = false; + bool iab_node_ind_r16_present = false; + bool non_crit_ext_present = false; + fixed_bitstring<20> pur_cfg_id_r16; + rrc_conn_setup_complete_v1690_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ResultsPerSSB-IndexList-r16 ::= SEQUENCE (SIZE (1..32)) OF ResultsPerSSB-IndexIdle-r16 +using results_per_ssb_idx_list_r16_l = dyn_array; + // MeasResultIdleEUTRA-r15 ::= SEQUENCE struct meas_result_idle_eutra_r15_s { struct meas_result_r15_s_ { @@ -121,6 +212,41 @@ struct meas_result_idle_eutra_r15_s { void to_json(json_writer& j) const; }; +// MeasResultsPerCellIdleNR-r16 ::= SEQUENCE +struct meas_results_per_cell_idle_nr_r16_s { + struct meas_idle_result_nr_r16_s_ { + bool rsrp_result_nr_r16_present = false; + bool rsrq_result_nr_r16_present = false; + bool result_rs_idx_list_r16_present = false; + uint8_t rsrp_result_nr_r16 = 0; + uint8_t rsrq_result_nr_r16 = 0; + results_per_ssb_idx_list_r16_l result_rs_idx_list_r16; + }; + + // member variables + bool ext = false; + uint16_t pci_nr_r16 = 0; + meas_idle_result_nr_r16_s_ meas_idle_result_nr_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionReconfigurationComplete-v1710-IEs ::= SEQUENCE +struct rrc_conn_recfg_complete_v1710_ies_s { + bool gnss_validity_dur_r17_present = false; + bool non_crit_ext_present = false; + gnss_validity_dur_r17_e gnss_validity_dur_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionSetupComplete-v1540-IEs ::= SEQUENCE struct rrc_conn_setup_complete_v1540_ies_s { struct guami_type_r15_opts { @@ -131,10 +257,11 @@ struct rrc_conn_setup_complete_v1540_ies_s { typedef enumerated guami_type_r15_e_; // member variables - bool gummei_type_v1540_present = false; - bool guami_type_r15_present = false; - bool non_crit_ext_present = false; - guami_type_r15_e_ guami_type_r15; + bool gummei_type_v1540_present = false; + bool guami_type_r15_present = false; + bool non_crit_ext_present = false; + guami_type_r15_e_ guami_type_r15; + rrc_conn_setup_complete_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -207,6 +334,35 @@ struct s_nssai_r15_c { // MeasResultIdleListEUTRA-r15 ::= SEQUENCE (SIZE (1..8)) OF MeasResultIdleEUTRA-r15 using meas_result_idle_list_eutra_r15_l = dyn_array; +// MeasResultIdleNR-r16 ::= SEQUENCE +struct meas_result_idle_nr_r16_s { + using meas_results_per_cell_list_idle_nr_r16_l_ = dyn_array; + + // member variables + bool ext = false; + uint32_t carrier_freq_nr_r16 = 0; + meas_results_per_cell_list_idle_nr_r16_l_ meas_results_per_cell_list_idle_nr_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionReconfigurationComplete-v1700-IEs ::= SEQUENCE +struct rrc_conn_recfg_complete_v1700_ies_s { + bool sel_cond_recfg_to_apply_r17_present = false; + bool non_crit_ext_present = false; + uint8_t sel_cond_recfg_to_apply_r17 = 1; + rrc_conn_recfg_complete_v1710_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionSetupComplete-v1530-IEs ::= SEQUENCE struct rrc_conn_setup_complete_v1530_ies_s { using s_nssai_list_r15_l_ = dyn_array; @@ -326,6 +482,22 @@ struct meas_result_idle_r15_s { void to_json(json_writer& j) const; }; +// MeasResultListExtIdle-r16 ::= SEQUENCE (SIZE (1..5)) OF MeasResultIdleListEUTRA-r15 +using meas_result_list_ext_idle_r16_l = dyn_array; + +// MeasResultListIdleNR-r16 ::= SEQUENCE (SIZE (1..8)) OF MeasResultIdleNR-r16 +using meas_result_list_idle_nr_r16_l = dyn_array; + +// OverheatingAssistance-v1710 ::= SEQUENCE +struct overheat_assist_v1710_s { + dyn_octstring overheat_assist_for_scg_fr2_minus2_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PerCC-GapIndication-r14 ::= SEQUENCE struct per_cc_gap_ind_r14_s { struct gap_ind_r14_opts { @@ -345,12 +517,36 @@ struct per_cc_gap_ind_r14_s { void to_json(json_writer& j) const; }; +// RACH-Report-v1610 ::= SEQUENCE +struct rach_report_v1610_s { + uint8_t init_cel_r16 = 0; + bool edt_fallback_r16 = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionReconfigurationComplete-v1530-IEs ::= SEQUENCE struct rrc_conn_recfg_complete_v1530_ies_s { - bool log_meas_available_bt_r15_present = false; - bool log_meas_available_wlan_r15_present = false; - bool flight_path_info_available_r15_present = false; - bool non_crit_ext_present = false; + bool log_meas_available_bt_r15_present = false; + bool log_meas_available_wlan_r15_present = false; + bool flight_path_info_available_r15_present = false; + bool non_crit_ext_present = false; + rrc_conn_recfg_complete_v1700_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionReestablishmentComplete-v1710-IEs ::= SEQUENCE +struct rrc_conn_reest_complete_v1710_ies_s { + bool gnss_validity_dur_r17_present = false; + bool non_crit_ext_present = false; + gnss_validity_dur_r17_e gnss_validity_dur_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -371,6 +567,18 @@ struct rrc_conn_setup_complete_v1430_ies_s { void to_json(json_writer& j) const; }; +// UEInformationResponse-v1710-IEs ::= SEQUENCE +struct ue_info_resp_v1710_ies_s { + bool coarse_location_info_r17_present = false; + bool non_crit_ext_present = false; + dyn_octstring coarse_location_info_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // VictimSystemType-r11 ::= SEQUENCE struct victim_sys_type_r11_s { bool gps_r11_present = false; @@ -498,7 +706,7 @@ struct flight_path_info_report_r15_s { // member variables bool flight_path_r15_present = false; - bool non_crit_ext_present = false; + bool dummy_present = false; flight_path_r15_l_ flight_path_r15; // sequence methods @@ -528,10 +736,11 @@ struct rrc_conn_recfg_complete_v1510_ies_s { // RRCConnectionReestablishmentComplete-v1530-IEs ::= SEQUENCE struct rrc_conn_reest_complete_v1530_ies_s { - bool log_meas_available_bt_r15_present = false; - bool log_meas_available_wlan_r15_present = false; - bool flight_path_info_available_r15_present = false; - bool non_crit_ext_present = false; + bool log_meas_available_bt_r15_present = false; + bool log_meas_available_wlan_r15_present = false; + bool flight_path_info_available_r15_present = false; + bool non_crit_ext_present = false; + rrc_conn_reest_complete_v1710_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -551,17 +760,71 @@ struct rrc_conn_setup_complete_v1330_ies_s { void to_json(json_writer& j) const; }; +// UEAssistanceInformation-v1710-IEs ::= SEQUENCE +struct ueassist_info_v1710_ies_s { + bool overheat_assist_v1710_present = false; + bool non_crit_ext_present = false; + overheat_assist_v1710_s overheat_assist_v1710; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEInformationResponse-v1610-IEs ::= SEQUENCE +struct ue_info_resp_v1610_ies_s { + bool rach_report_v1610_present = false; + bool meas_result_list_ext_idle_r16_present = false; + bool meas_result_list_idle_nr_r16_present = false; + bool non_crit_ext_present = false; + rach_report_v1610_s rach_report_v1610; + meas_result_list_ext_idle_r16_l meas_result_list_ext_idle_r16; + meas_result_list_idle_nr_r16_l meas_result_list_idle_nr_r16; + ue_info_resp_v1710_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// VictimSystemType-v1610 ::= SEQUENCE +struct victim_sys_type_v1610_s { + bool navic_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // VisitedCellInfoList-r12 ::= SEQUENCE (SIZE (1..16)) OF VisitedCellInfo-r12 using visited_cell_info_list_r12_l = dyn_array; +// InDeviceCoexIndication-v1610-IEs ::= SEQUENCE +struct in_dev_coex_ind_v1610_ies_s { + bool victim_sys_type_v1610_present = false; + bool non_crit_ext_present = false; + victim_sys_type_v1610_s victim_sys_type_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MRDC-AssistanceInfo-r15 ::= SEQUENCE struct mrdc_assist_info_r15_s { - using affected_carrier_freq_comb_info_list_mrdc_r15_l_ = dyn_array; + using affected_carrier_freq_comb_info_list_mrdc_r15_l_ = dyn_array; + using affected_carrier_freq_comb_info_list_mrdc_v1610_l_ = dyn_array; // member variables bool ext = false; affected_carrier_freq_comb_info_list_mrdc_r15_l_ affected_carrier_freq_comb_info_list_mrdc_r15; // ... + // group 0 + copy_ptr affected_carrier_freq_comb_info_list_mrdc_v1610; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -572,6 +835,16 @@ struct mrdc_assist_info_r15_s { // MobilityHistoryReport-r12 ::= VisitedCellInfoList-r12 using mob_history_report_r12_l = visited_cell_info_list_r12_l; +// OverheatingAssistance-v1610 ::= SEQUENCE +struct overheat_assist_v1610_s { + dyn_octstring overheat_assist_for_scg_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionReconfigurationComplete-v1430-IEs ::= SEQUENCE struct rrc_conn_recfg_complete_v1430_ies_s { bool per_cc_gap_ind_list_r14_present = false; @@ -631,6 +904,28 @@ struct traffic_pattern_info_v1530_s { void to_json(json_writer& j) const; }; +// UEAssistanceInformation-v1700-IEs ::= SEQUENCE +struct ueassist_info_v1700_ies_s { + struct scg_deactivation_pref_r17_opts { + enum options { scg_deactivation_preferred, no_pref, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated scg_deactivation_pref_r17_e_; + + // member variables + bool ul_data_r17_present = false; + bool scg_deactivation_pref_r17_present = false; + bool non_crit_ext_present = false; + scg_deactivation_pref_r17_e_ scg_deactivation_pref_r17; + ueassist_info_v1710_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // UEInformationResponse-v1530-IEs ::= SEQUENCE struct ue_info_resp_v1530_ies_s { bool meas_result_list_idle_r15_present = false; @@ -638,6 +933,7 @@ struct ue_info_resp_v1530_ies_s { bool non_crit_ext_present = false; meas_result_list_idle_r15_l meas_result_list_idle_r15; flight_path_info_report_r15_s flight_path_info_report_r15; + ue_info_resp_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -676,6 +972,9 @@ struct conn_est_fail_report_r11_s { meas_result_list_geran_l meas_result_list_geran_r11; meas_result_list2_cdma2000_r9_l meas_results_cdma2000_r11; }; + struct meas_result_list_nr_v1640_s_ { + uint32_t carrier_freq_nr_r16 = 0; + }; // member variables bool ext = false; @@ -703,6 +1002,11 @@ struct conn_est_fail_report_r11_s { // group 2 copy_ptr log_meas_result_list_bt_r15; copy_ptr log_meas_result_list_wlan_r15; + // group 3 + copy_ptr meas_result_list_nr_r16; + // group 4 + copy_ptr meas_result_list_nr_v1640; + copy_ptr meas_result_list_ext_nr_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -724,9 +1028,41 @@ struct drb_count_info_s { // InDeviceCoexIndication-v1530-IEs ::= SEQUENCE struct in_dev_coex_ind_v1530_ies_s { - bool mrdc_assist_info_r15_present = false; - bool non_crit_ext_present = false; - mrdc_assist_info_r15_s mrdc_assist_info_r15; + bool mrdc_assist_info_r15_present = false; + bool non_crit_ext_present = false; + mrdc_assist_info_r15_s mrdc_assist_info_r15; + in_dev_coex_ind_v1610_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MBMS-ROM-Info-r16 ::= SEQUENCE +struct mbms_rom_info_r16_s { + struct mbms_rom_subcarrier_spacing_r16_opts { + enum options { khz2dot5, khz0dot37, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated mbms_rom_subcarrier_spacing_r16_e_; + struct mbms_bw_r16_opts { + enum options { n6, n15, n25, n50, n75, n100, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated mbms_bw_r16_e_; + + // member variables + uint32_t mbms_rom_freq_r16 = 0; + mbms_rom_subcarrier_spacing_r16_e_ mbms_rom_subcarrier_spacing_r16; + mbms_bw_r16_e_ mbms_bw_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -799,6 +1135,19 @@ struct sl_v2x_comm_tx_res_req_r14_s { // TrafficPatternInfoList-v1530 ::= SEQUENCE (SIZE (1..8)) OF TrafficPatternInfo-v1530 using traffic_pattern_info_list_v1530_l = dyn_array; +// UEAssistanceInformation-v1610-IEs ::= SEQUENCE +struct ueassist_info_v1610_ies_s { + bool overheat_assist_v1610_present = false; + bool non_crit_ext_present = false; + overheat_assist_v1610_s overheat_assist_v1610; + ueassist_info_v1700_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // UEInformationResponse-v1250-IEs ::= SEQUENCE struct ue_info_resp_v1250_ies_s { bool mob_history_report_r12_present = false; @@ -988,12 +1337,29 @@ struct mbms_service_info_r13_s { void to_json(json_writer& j) const; }; -// MeasResultFreqFailNR-r15 ::= SEQUENCE -struct meas_result_freq_fail_nr_r15_s { - bool ext = false; - bool meas_result_cell_list_r15_present = false; - uint32_t carrier_freq_r15 = 0; - meas_result_cell_list_nr_r15_l meas_result_cell_list_r15; +// MBMSInterestIndication-v1610-IEs ::= SEQUENCE +struct mbms_interest_ind_v1610_ies_s { + using mbms_rom_info_list_r16_l_ = dyn_array; + + // member variables + bool mbms_rom_info_list_r16_present = false; + bool non_crit_ext_present = false; + mbms_rom_info_list_r16_l_ mbms_rom_info_list_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasResult3EUTRA-r15 ::= SEQUENCE +struct meas_result3_eutra_r15_s { + bool ext = false; + bool meas_result_serving_cell_r15_present = false; + bool meas_result_neigh_cell_list_r15_present = false; + uint32_t carrier_freq_r15 = 0; + meas_result_eutra_s meas_result_serving_cell_r15; + meas_result_list_eutra_l meas_result_neigh_cell_list_r15; // ... // sequence methods @@ -1049,6 +1415,18 @@ struct rrc_conn_reest_complete_v1020_ies_s { void to_json(json_writer& j) const; }; +// RRCConnectionResumeComplete-v1710-IEs ::= SEQUENCE +struct rrc_conn_resume_complete_v1710_ies_s { + bool gnss_validity_dur_r17_present = false; + bool non_crit_ext_present = false; + gnss_validity_dur_r17_e gnss_validity_dur_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionSetupComplete-v1130-IEs ::= SEQUENCE struct rrc_conn_setup_complete_v1130_ies_s { bool conn_est_fail_info_available_r11_present = false; @@ -1236,9 +1614,10 @@ struct ueassist_info_v1530_ies_s { }; // member variables - bool sps_assist_info_v1530_present = false; - bool non_crit_ext_present = false; - sps_assist_info_v1530_s_ sps_assist_info_v1530; + bool sps_assist_info_v1530_present = false; + bool non_crit_ext_present = false; + sps_assist_info_v1530_s_ sps_assist_info_v1530; + ueassist_info_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1314,6 +1693,19 @@ struct bw_pref_r14_s { void to_json(json_writer& j) const; }; +// CellGlobalIdNR-r16 ::= SEQUENCE +struct cell_global_id_nr_r16_s { + bool tac_r16_present = false; + plmn_id_s plmn_id_r16; + fixed_bitstring<36> cell_id_r16; + fixed_bitstring<24> tac_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CounterCheckResponse-v1530-IEs ::= SEQUENCE struct counter_check_resp_v1530_ies_s { bool drb_count_info_list_ext_r15_present = false; @@ -1470,9 +1862,10 @@ struct mbms_interest_ind_v1540_ies_s { using mbms_rom_info_list_r15_l_ = dyn_array; // member variables - bool mbms_rom_info_list_r15_present = false; - bool non_crit_ext_present = false; - mbms_rom_info_list_r15_l_ mbms_rom_info_list_r15; + bool mbms_rom_info_list_r15_present = false; + bool non_crit_ext_present = false; + mbms_rom_info_list_r15_l_ mbms_rom_info_list_r15; + mbms_interest_ind_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1483,6 +1876,9 @@ struct mbms_interest_ind_v1540_ies_s { // MeasResultFreqListFailNR-r15 ::= SEQUENCE (SIZE (1..5)) OF MeasResultFreqFailNR-r15 using meas_result_freq_list_fail_nr_r15_l = dyn_array; +// MeasResultList3EUTRA-r15 ::= SEQUENCE (SIZE (1..8)) OF MeasResult3EUTRA-r15 +using meas_result_list3_eutra_r15_l = dyn_array; + // RRCConnectionReconfigurationComplete-v1020-IEs ::= SEQUENCE struct rrc_conn_recfg_complete_v1020_ies_s { bool rlf_info_available_r10_present = false; @@ -1509,6 +1905,25 @@ struct rrc_conn_reest_complete_v8a0_ies_s { void to_json(json_writer& j) const; }; +// RRCConnectionResumeComplete-v1610-IEs ::= SEQUENCE +struct rrc_conn_resume_complete_v1610_ies_s { + bool meas_result_list_idle_r16_present = false; + bool meas_result_list_ext_idle_r16_present = false; + bool meas_result_list_idle_nr_r16_present = false; + bool scg_cfg_resp_nr_r16_present = false; + bool non_crit_ext_present = false; + meas_result_list_idle_r15_l meas_result_list_idle_r16; + meas_result_list_ext_idle_r16_l meas_result_list_ext_idle_r16; + meas_result_list_idle_nr_r16_l meas_result_list_idle_nr_r16; + dyn_octstring scg_cfg_resp_nr_r16; + rrc_conn_resume_complete_v1710_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionSetupComplete-v1020-IEs ::= SEQUENCE struct rrc_conn_setup_complete_v1020_ies_s { struct gummei_type_r10_opts { @@ -1953,6 +2368,71 @@ using count_resp_list_r10_l = dyn_array; // DRB-CountInfoList ::= SEQUENCE (SIZE (0..11)) OF DRB-CountInfo using drb_count_info_list_l = dyn_array; +// FailedLogicalChannelIdentity-r16 ::= SEQUENCE +struct failed_lc_ch_id_r16_s { + struct cell_group_ind_r16_opts { + enum options { mn, sn, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated cell_group_ind_r16_e_; + + // member variables + bool lc_ch_id_r16_present = false; + bool lc_ch_id_ext_r16_present = false; + cell_group_ind_r16_e_ cell_group_ind_r16; + uint8_t lc_ch_id_r16 = 1; + uint8_t lc_ch_id_ext_r16 = 32; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// FailureReportMCG-r16 ::= SEQUENCE +struct fail_report_mcg_r16_s { + struct fail_type_r16_opts { + enum options { + t310_expiry, + random_access_problem, + rlc_max_num_retx, + t312_expiry, + spare4, + spare3, + spare2, + spare1, + nulltype + } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated fail_type_r16_e_; + + // member variables + bool ext = false; + bool fail_type_r16_present = false; + bool meas_result_freq_list_eutra_r16_present = false; + bool meas_result_freq_list_nr_r16_present = false; + bool meas_result_freq_list_geran_r16_present = false; + bool meas_result_freq_list_utra_r16_present = false; + bool meas_result_scg_r16_present = false; + fail_type_r16_e_ fail_type_r16; + meas_result_list3_eutra_r15_l meas_result_freq_list_eutra_r16; + meas_result_freq_list_fail_nr_r15_l meas_result_freq_list_nr_r16; + meas_result_list2_geran_r10_l meas_result_freq_list_geran_r16; + meas_result_list2_utra_r9_l meas_result_freq_list_utra_r16; + dyn_octstring meas_result_scg_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // FailureReportSCG-NR-r15 ::= SEQUENCE struct fail_report_scg_nr_r15_s { struct fail_type_r15_opts { @@ -1963,6 +2443,7 @@ struct fail_report_scg_nr_r15_s { synch_recfg_fail_scg, scg_recfg_fail, srb3_integrity_fail, + dummy, nulltype } value; typedef uint16_t number_type; @@ -1971,6 +2452,24 @@ struct fail_report_scg_nr_r15_s { uint16_t to_number() const; }; typedef enumerated fail_type_r15_e_; + struct fail_type_v1610_opts { + enum options { + t312_expiry, + scg_lbt_fail, + beam_fail_recovery_fail, + bh_rlf_r16, + beam_fail_r17, + spare3, + spare2, + spare1, + nulltype + } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated fail_type_v1610_e_; // member variables bool ext = false; @@ -1980,6 +2479,12 @@ struct fail_report_scg_nr_r15_s { meas_result_freq_list_fail_nr_r15_l meas_result_freq_list_nr_r15; dyn_octstring meas_result_scg_r15; // ... + // group 0 + bool fail_type_v1610_present = false; + copy_ptr location_info_r16; + copy_ptr log_meas_result_list_bt_r16; + copy_ptr log_meas_result_list_wlan_r16; + fail_type_v1610_e_ fail_type_v1610; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2074,6 +2579,17 @@ struct proximity_ind_v930_ies_s { void to_json(json_writer& j) const; }; +// RACH-Report-r16 ::= SEQUENCE +struct rach_report_r16_s { + uint8_t nof_preambs_sent_r16 = 1; + bool contention_detected_r16 = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RLF-Report-r9 ::= SEQUENCE struct rlf_report_r9_s { struct meas_result_last_serv_cell_r9_s_ { @@ -2280,6 +2796,116 @@ struct rlf_report_r9_s { struct failed_pcell_id_v1250_s_ { fixed_bitstring<16> tac_failed_pcell_r12; }; + struct failed_nr_pcell_id_r16_c_ { + struct pci_arfcn_s_ { + uint16_t pci_r16 = 0; + uint32_t carrier_freq_r16 = 0; + }; + struct types_opts { + enum options { cell_global_id, pci_arfcn, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + failed_nr_pcell_id_r16_c_() = default; + failed_nr_pcell_id_r16_c_(const failed_nr_pcell_id_r16_c_& other); + failed_nr_pcell_id_r16_c_& operator=(const failed_nr_pcell_id_r16_c_& other); + ~failed_nr_pcell_id_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + cell_global_id_nr_r16_s& cell_global_id() + { + assert_choice_type(types::cell_global_id, type_, "failedNR-PCellId-r16"); + return c.get(); + } + pci_arfcn_s_& pci_arfcn() + { + assert_choice_type(types::pci_arfcn, type_, "failedNR-PCellId-r16"); + return c.get(); + } + const cell_global_id_nr_r16_s& cell_global_id() const + { + assert_choice_type(types::cell_global_id, type_, "failedNR-PCellId-r16"); + return c.get(); + } + const pci_arfcn_s_& pci_arfcn() const + { + assert_choice_type(types::pci_arfcn, type_, "failedNR-PCellId-r16"); + return c.get(); + } + cell_global_id_nr_r16_s& set_cell_global_id(); + pci_arfcn_s_& set_pci_arfcn(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + struct reconnect_cell_id_r16_c_ { + struct eutra_reconnect_cell_id_s_ { + bool tac_epc_r16_present = false; + bool tac_minus5_gc_r16_present = false; + cell_global_id_eutra_s cell_global_id_r16; + fixed_bitstring<16> tac_epc_r16; + fixed_bitstring<24> tac_minus5_gc_r16; + }; + struct types_opts { + enum options { nr_reconnect_cell_id, eutra_reconnect_cell_id, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + reconnect_cell_id_r16_c_() = default; + reconnect_cell_id_r16_c_(const reconnect_cell_id_r16_c_& other); + reconnect_cell_id_r16_c_& operator=(const reconnect_cell_id_r16_c_& other); + ~reconnect_cell_id_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + cell_global_id_nr_r16_s& nr_reconnect_cell_id() + { + assert_choice_type(types::nr_reconnect_cell_id, type_, "reconnectCellId-r16"); + return c.get(); + } + eutra_reconnect_cell_id_s_& eutra_reconnect_cell_id() + { + assert_choice_type(types::eutra_reconnect_cell_id, type_, "reconnectCellId-r16"); + return c.get(); + } + const cell_global_id_nr_r16_s& nr_reconnect_cell_id() const + { + assert_choice_type(types::nr_reconnect_cell_id, type_, "reconnectCellId-r16"); + return c.get(); + } + const eutra_reconnect_cell_id_s_& eutra_reconnect_cell_id() const + { + assert_choice_type(types::eutra_reconnect_cell_id, type_, "reconnectCellId-r16"); + return c.get(); + } + cell_global_id_nr_r16_s& set_nr_reconnect_cell_id(); + eutra_reconnect_cell_id_s_& set_eutra_reconnect_cell_id(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + struct meas_result_list_nr_v1640_s_ { + uint32_t carrier_freq_nr_r16 = 0; + }; // member variables bool ext = false; @@ -2316,6 +2942,16 @@ struct rlf_report_r9_s { // group 6 copy_ptr log_meas_result_list_bt_r15; copy_ptr log_meas_result_list_wlan_r15; + // group 7 + bool time_until_reconn_r16_present = false; + copy_ptr meas_result_list_nr_r16; + copy_ptr prev_nr_pcell_id_r16; + copy_ptr failed_nr_pcell_id_r16; + copy_ptr reconnect_cell_id_r16; + uint32_t time_until_reconn_r16 = 0; + // group 8 + copy_ptr meas_result_list_nr_v1640; + copy_ptr meas_result_list_ext_nr_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2350,11 +2986,12 @@ struct rrc_conn_reest_complete_v920_ies_s { // RRCConnectionResumeComplete-v1530-IEs ::= SEQUENCE struct rrc_conn_resume_complete_v1530_ies_s { - bool log_meas_available_bt_r15_present = false; - bool log_meas_available_wlan_r15_present = false; - bool idle_meas_available_r15_present = false; - bool flight_path_info_available_r15_present = false; - bool non_crit_ext_present = false; + bool log_meas_available_bt_r15_present = false; + bool log_meas_available_wlan_r15_present = false; + bool idle_meas_available_r15_present = false; + bool flight_path_info_available_r15_present = false; + bool non_crit_ext_present = false; + rrc_conn_resume_complete_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2698,6 +3335,28 @@ struct failed_lc_ch_info_r15_s { void to_json(json_writer& j) const; }; +// FailureInformation-r16-IEs ::= SEQUENCE +struct fail_info_r16_ies_s { + struct fail_type_r16_opts { + enum options { dupl, daps_ho_fail, spare2, spare1, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated fail_type_r16_e_; + + // member variables + bool failed_lc_ch_id_r16_present = false; + bool fail_type_r16_present = false; + bool non_crit_ext_present = false; + failed_lc_ch_id_r16_s failed_lc_ch_id_r16; + fail_type_r16_e_ fail_type_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // InDeviceCoexIndication-r11-IEs ::= SEQUENCE struct in_dev_coex_ind_r11_ies_s { bool affected_carrier_freq_list_r11_present = false; @@ -2798,6 +3457,20 @@ struct mbms_interest_ind_r11_ies_s { void to_json(json_writer& j) const; }; +// MCGFailureInformation-r16-IEs ::= SEQUENCE +struct mcg_fail_info_r16_ies_s { + bool fail_report_mcg_r16_present = false; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + fail_report_mcg_r16_s fail_report_mcg_r16; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MeasReportAppLayer-r15-IEs ::= SEQUENCE struct meas_report_app_layer_r15_ies_s { struct service_type_r15_opts { @@ -2821,6 +3494,146 @@ struct meas_report_app_layer_r15_ies_s { void to_json(json_writer& j) const; }; +// PURConfigurationRequest-r16-IEs ::= SEQUENCE +struct pur_cfg_request_r16_ies_s { + struct pur_cfg_request_r16_c_ { + struct pur_setup_request_s_ { + struct requested_num_occasions_r16_opts { + enum options { one, infinite, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated requested_num_occasions_r16_e_; + struct requested_tbs_r16_opts { + enum options { + b328, + b344, + b376, + b392, + b408, + b424, + b440, + b456, + b472, + b488, + b504, + b536, + b568, + b584, + b616, + b648, + b680, + b712, + b744, + b776, + b808, + b840, + b872, + b904, + b936, + b968, + b1000, + b1032, + b1064, + b1096, + b1128, + b1160, + b1192, + b1224, + b1256, + b1288, + b1320, + b1352, + b1384, + b1416, + b1480, + b1544, + b1608, + b1672, + b1736, + b1800, + b1864, + b1928, + b1992, + b2024, + b2088, + b2152, + b2216, + b2280, + b2344, + b2408, + b2472, + b2536, + b2600, + b2664, + b2728, + b2792, + b2856, + b2984, + nulltype + } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated requested_tbs_r16_e_; + + // member variables + bool requested_periodicity_and_offset_r16_present = false; + bool rrc_ack_r16_present = false; + requested_num_occasions_r16_e_ requested_num_occasions_r16; + pur_periodicity_and_offset_r16_c requested_periodicity_and_offset_r16; + requested_tbs_r16_e_ requested_tbs_r16; + }; + struct types_opts { + enum options { pur_release_request, pur_setup_request, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + pur_cfg_request_r16_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + pur_setup_request_s_& pur_setup_request() + { + assert_choice_type(types::pur_setup_request, type_, "pur-ConfigRequest-r16"); + return c; + } + const pur_setup_request_s_& pur_setup_request() const + { + assert_choice_type(types::pur_setup_request, type_, "pur-ConfigRequest-r16"); + return c; + } + void set_pur_release_request(); + pur_setup_request_s_& set_pur_setup_request(); + + private: + types type_; + pur_setup_request_s_ c; + }; + + // member variables + bool pur_cfg_request_r16_present = false; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + pur_cfg_request_r16_c_ pur_cfg_request_r16; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // ProximityIndication-r9-IEs ::= SEQUENCE struct proximity_ind_r9_ies_s { struct type_r9_opts { @@ -3055,16 +3868,10 @@ struct ueassist_info_r11_ies_s { // UEInformationResponse-r9-IEs ::= SEQUENCE struct ue_info_resp_r9_ies_s { - struct rach_report_r9_s_ { - uint8_t nof_preambs_sent_r9 = 1; - bool contention_detected_r9 = false; - }; - - // member variables bool rach_report_r9_present = false; bool rlf_report_r9_present = false; bool non_crit_ext_present = false; - rach_report_r9_s_ rach_report_r9; + rach_report_r16_s rach_report_r9; rlf_report_r9_s rlf_report_r9; ue_info_resp_v930_ies_s non_crit_ext; @@ -3074,14 +3881,113 @@ struct ue_info_resp_r9_ies_s { void to_json(json_writer& j) const; }; -// ULHandoverPreparationTransfer-r8-IEs ::= SEQUENCE -struct ul_ho_prep_transfer_r8_ies_s { - bool meid_present = false; - bool non_crit_ext_present = false; - cdma2000_type_e cdma2000_type; - fixed_bitstring<56> meid; - dyn_octstring ded_info; - ul_ho_prep_transfer_v8a0_ies_s non_crit_ext; +// ULDedicatedMessageSegment-r16-IEs ::= SEQUENCE +struct ul_ded_msg_segment_r16_ies_s { + struct rrc_msg_segment_type_r16_opts { + enum options { not_last_segment, last_segment, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated rrc_msg_segment_type_r16_e_; + + // member variables + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + uint8_t segment_num_r16 = 0; + dyn_octstring rrc_msg_segment_container_r16; + rrc_msg_segment_type_r16_e_ rrc_msg_segment_type_r16; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ULHandoverPreparationTransfer-r8-IEs ::= SEQUENCE +struct ul_ho_prep_transfer_r8_ies_s { + bool meid_present = false; + bool non_crit_ext_present = false; + cdma2000_type_e cdma2000_type; + fixed_bitstring<56> meid; + dyn_octstring ded_info; + ul_ho_prep_transfer_v8a0_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ULInformationTransfer-r16-IEs ::= SEQUENCE +struct ul_info_transfer_r16_ies_s { + struct ded_info_type_r16_c_ { + struct types_opts { + enum options { ded_info_nas_r16, ded_info_cdma2000_minus1_xrtt_r16, ded_info_cdma2000_hrpd_r16, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + ded_info_type_r16_c_() = default; + ded_info_type_r16_c_(const ded_info_type_r16_c_& other); + ded_info_type_r16_c_& operator=(const ded_info_type_r16_c_& other); + ~ded_info_type_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + dyn_octstring& ded_info_nas_r16() + { + assert_choice_type(types::ded_info_nas_r16, type_, "dedicatedInfoType-r16"); + return c.get(); + } + dyn_octstring& ded_info_cdma2000_minus1_xrtt_r16() + { + assert_choice_type(types::ded_info_cdma2000_minus1_xrtt_r16, type_, "dedicatedInfoType-r16"); + return c.get(); + } + dyn_octstring& ded_info_cdma2000_hrpd_r16() + { + assert_choice_type(types::ded_info_cdma2000_hrpd_r16, type_, "dedicatedInfoType-r16"); + return c.get(); + } + const dyn_octstring& ded_info_nas_r16() const + { + assert_choice_type(types::ded_info_nas_r16, type_, "dedicatedInfoType-r16"); + return c.get(); + } + const dyn_octstring& ded_info_cdma2000_minus1_xrtt_r16() const + { + assert_choice_type(types::ded_info_cdma2000_minus1_xrtt_r16, type_, "dedicatedInfoType-r16"); + return c.get(); + } + const dyn_octstring& ded_info_cdma2000_hrpd_r16() const + { + assert_choice_type(types::ded_info_cdma2000_hrpd_r16, type_, "dedicatedInfoType-r16"); + return c.get(); + } + dyn_octstring& set_ded_info_nas_r16(); + dyn_octstring& set_ded_info_cdma2000_minus1_xrtt_r16(); + dyn_octstring& set_ded_info_cdma2000_hrpd_r16(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ded_info_type_r16_present = false; + bool ded_info_f1c_r16_present = false; + bool non_crit_ext_present = false; + ded_info_type_r16_c_ ded_info_type_r16; + dyn_octstring ded_info_f1c_r16; + ul_info_transfer_v8a0_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3162,6 +4068,20 @@ struct ul_info_transfer_r8_ies_s { void to_json(json_writer& j) const; }; +// ULInformationTransferIRAT-r16-IEs ::= SEQUENCE +struct ul_info_transfer_irat_r16_ies_s { + bool ul_dcch_msg_nr_r16_present = false; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + dyn_octstring ul_dcch_msg_nr_r16; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // ULInformationTransferMRDC-r15-IEs ::= SEQUENCE struct ul_info_transfer_mrdc_r15_ies_s { bool ul_dcch_msg_nr_r15_present = false; @@ -3294,6 +4214,51 @@ struct fail_info_r15_s { void to_json(json_writer& j) const; }; +// FailureInformation-r16 ::= SEQUENCE +struct fail_info_r16_s { + struct crit_exts_c_ { + struct types_opts { + enum options { fail_info_r16, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + crit_exts_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fail_info_r16_ies_s& fail_info_r16() + { + assert_choice_type(types::fail_info_r16, type_, "criticalExtensions"); + return c; + } + const fail_info_r16_ies_s& fail_info_r16() const + { + assert_choice_type(types::fail_info_r16, type_, "criticalExtensions"); + return c; + } + fail_info_r16_ies_s& set_fail_info_r16(); + void set_crit_exts_future(); + + private: + types type_; + fail_info_r16_ies_s c; + }; + + // member variables + crit_exts_c_ crit_exts; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // InDeviceCoexIndication-r11 ::= SEQUENCE struct in_dev_coex_ind_r11_s { struct crit_exts_c_ { @@ -3594,6 +4559,51 @@ struct mbms_interest_ind_r11_s { void to_json(json_writer& j) const; }; +// MCGFailureInformation-r16 ::= SEQUENCE +struct mcg_fail_info_r16_s { + struct crit_exts_c_ { + struct types_opts { + enum options { mcg_fail_info, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + crit_exts_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + mcg_fail_info_r16_ies_s& mcg_fail_info() + { + assert_choice_type(types::mcg_fail_info, type_, "criticalExtensions"); + return c; + } + const mcg_fail_info_r16_ies_s& mcg_fail_info() const + { + assert_choice_type(types::mcg_fail_info, type_, "criticalExtensions"); + return c; + } + mcg_fail_info_r16_ies_s& set_mcg_fail_info(); + void set_crit_exts_future(); + + private: + types type_; + mcg_fail_info_r16_ies_s c; + }; + + // member variables + crit_exts_c_ crit_exts; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MeasReportAppLayer-r15 ::= SEQUENCE struct meas_report_app_layer_r15_s { struct crit_exts_c_ { @@ -3639,6 +4649,51 @@ struct meas_report_app_layer_r15_s { void to_json(json_writer& j) const; }; +// PURConfigurationRequest-r16 ::= SEQUENCE +struct pur_cfg_request_r16_s { + struct crit_exts_c_ { + struct types_opts { + enum options { pur_cfg_request, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + crit_exts_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + pur_cfg_request_r16_ies_s& pur_cfg_request() + { + assert_choice_type(types::pur_cfg_request, type_, "criticalExtensions"); + return c; + } + const pur_cfg_request_r16_ies_s& pur_cfg_request() const + { + assert_choice_type(types::pur_cfg_request, type_, "criticalExtensions"); + return c; + } + pur_cfg_request_r16_ies_s& set_pur_cfg_request(); + void set_crit_exts_future(); + + private: + types type_; + pur_cfg_request_r16_ies_s c; + }; + + // member variables + crit_exts_c_ crit_exts; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // ProximityIndication-r9 ::= SEQUENCE struct proximity_ind_r9_s { struct crit_exts_c_ { @@ -4380,6 +5435,51 @@ struct ue_info_resp_r9_s { void to_json(json_writer& j) const; }; +// ULDedicatedMessageSegment-r16 ::= SEQUENCE +struct ul_ded_msg_segment_r16_s { + struct crit_exts_c_ { + struct types_opts { + enum options { ul_ded_msg_segment_r16, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + crit_exts_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ul_ded_msg_segment_r16_ies_s& ul_ded_msg_segment_r16() + { + assert_choice_type(types::ul_ded_msg_segment_r16, type_, "criticalExtensions"); + return c; + } + const ul_ded_msg_segment_r16_ies_s& ul_ded_msg_segment_r16() const + { + assert_choice_type(types::ul_ded_msg_segment_r16, type_, "criticalExtensions"); + return c; + } + ul_ded_msg_segment_r16_ies_s& set_ul_ded_msg_segment_r16(); + void set_crit_exts_future(); + + private: + types type_; + ul_ded_msg_segment_r16_ies_s c; + }; + + // member variables + crit_exts_c_ crit_exts; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // ULHandoverPreparationTransfer ::= SEQUENCE struct ul_ho_prep_transfer_s { struct crit_exts_c_ { @@ -4460,7 +5560,7 @@ struct ul_info_transfer_s { struct crit_exts_c_ { struct c1_c_ { struct types_opts { - enum options { ul_info_transfer_r8, spare3, spare2, spare1, nulltype } value; + enum options { ul_info_transfer_r8, ul_info_transfer_r16, spare2, spare1, nulltype } value; const char* to_string() const; }; @@ -4468,6 +5568,9 @@ struct ul_info_transfer_s { // choice methods c1_c_() = default; + c1_c_(const c1_c_& other); + c1_c_& operator=(const c1_c_& other); + ~c1_c_() { destroy_(); } void set(types::options e = types::nulltype); types type() const { return type_; } SRSASN_CODE pack(bit_ref& bref) const; @@ -4477,21 +5580,108 @@ struct ul_info_transfer_s { ul_info_transfer_r8_ies_s& ul_info_transfer_r8() { assert_choice_type(types::ul_info_transfer_r8, type_, "c1"); - return c; + return c.get(); + } + ul_info_transfer_r16_ies_s& ul_info_transfer_r16() + { + assert_choice_type(types::ul_info_transfer_r16, type_, "c1"); + return c.get(); } const ul_info_transfer_r8_ies_s& ul_info_transfer_r8() const { assert_choice_type(types::ul_info_transfer_r8, type_, "c1"); + return c.get(); + } + const ul_info_transfer_r16_ies_s& ul_info_transfer_r16() const + { + assert_choice_type(types::ul_info_transfer_r16, type_, "c1"); + return c.get(); + } + ul_info_transfer_r8_ies_s& set_ul_info_transfer_r8(); + ul_info_transfer_r16_ies_s& set_ul_info_transfer_r16(); + void set_spare2(); + void set_spare1(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + using types = c1_or_crit_ext_e; + + // choice methods + crit_exts_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + c1_c_& c1() + { + assert_choice_type(types::c1, type_, "criticalExtensions"); + return c; + } + const c1_c_& c1() const + { + assert_choice_type(types::c1, type_, "criticalExtensions"); + return c; + } + c1_c_& set_c1(); + void set_crit_exts_future(); + + private: + types type_; + c1_c_ c; + }; + + // member variables + crit_exts_c_ crit_exts; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ULInformationTransferIRAT-r16 ::= SEQUENCE +struct ul_info_transfer_irat_r16_s { + struct crit_exts_c_ { + struct c1_c_ { + struct types_opts { + enum options { ul_info_transfer_irat_r16, spare3, spare2, spare1, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + c1_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ul_info_transfer_irat_r16_ies_s& ul_info_transfer_irat_r16() + { + assert_choice_type(types::ul_info_transfer_irat_r16, type_, "c1"); return c; } - ul_info_transfer_r8_ies_s& set_ul_info_transfer_r8(); - void set_spare3(); - void set_spare2(); - void set_spare1(); + const ul_info_transfer_irat_r16_ies_s& ul_info_transfer_irat_r16() const + { + assert_choice_type(types::ul_info_transfer_irat_r16, type_, "c1"); + return c; + } + ul_info_transfer_irat_r16_ies_s& set_ul_info_transfer_irat_r16(); + void set_spare3(); + void set_spare2(); + void set_spare1(); private: - types type_; - ul_info_transfer_r8_ies_s c; + types type_; + ul_info_transfer_irat_r16_ies_s c; }; using types = c1_or_crit_ext_e; @@ -4935,11 +6125,11 @@ struct ul_dcch_msg_type_c { scg_fail_info_nr_r15, meas_report_app_layer_r15, fail_info_r15, - spare5, - spare4, - spare3, - spare2, - spare1, + ul_ded_msg_segment_r16, + pur_cfg_request_r16, + fail_info_r16, + mcg_fail_info_r16, + ul_info_transfer_irat_r16, nulltype } value; @@ -5013,6 +6203,31 @@ struct ul_dcch_msg_type_c { assert_choice_type(types::fail_info_r15, type_, "c2"); return c.get(); } + ul_ded_msg_segment_r16_s& ul_ded_msg_segment_r16() + { + assert_choice_type(types::ul_ded_msg_segment_r16, type_, "c2"); + return c.get(); + } + pur_cfg_request_r16_s& pur_cfg_request_r16() + { + assert_choice_type(types::pur_cfg_request_r16, type_, "c2"); + return c.get(); + } + fail_info_r16_s& fail_info_r16() + { + assert_choice_type(types::fail_info_r16, type_, "c2"); + return c.get(); + } + mcg_fail_info_r16_s& mcg_fail_info_r16() + { + assert_choice_type(types::mcg_fail_info_r16, type_, "c2"); + return c.get(); + } + ul_info_transfer_irat_r16_s& ul_info_transfer_irat_r16() + { + assert_choice_type(types::ul_info_transfer_irat_r16, type_, "c2"); + return c.get(); + } const ueassist_info_r11_s& ue_assist_info_r11() const { assert_choice_type(types::ue_assist_info_r11, type_, "c2"); @@ -5068,6 +6283,31 @@ struct ul_dcch_msg_type_c { assert_choice_type(types::fail_info_r15, type_, "c2"); return c.get(); } + const ul_ded_msg_segment_r16_s& ul_ded_msg_segment_r16() const + { + assert_choice_type(types::ul_ded_msg_segment_r16, type_, "c2"); + return c.get(); + } + const pur_cfg_request_r16_s& pur_cfg_request_r16() const + { + assert_choice_type(types::pur_cfg_request_r16, type_, "c2"); + return c.get(); + } + const fail_info_r16_s& fail_info_r16() const + { + assert_choice_type(types::fail_info_r16, type_, "c2"); + return c.get(); + } + const mcg_fail_info_r16_s& mcg_fail_info_r16() const + { + assert_choice_type(types::mcg_fail_info_r16, type_, "c2"); + return c.get(); + } + const ul_info_transfer_irat_r16_s& ul_info_transfer_irat_r16() const + { + assert_choice_type(types::ul_info_transfer_irat_r16, type_, "c2"); + return c.get(); + } ueassist_info_r11_s& set_ue_assist_info_r11(); in_dev_coex_ind_r11_s& set_in_dev_coex_ind_r11(); mbms_interest_ind_r11_s& set_mbms_interest_ind_r11(); @@ -5079,23 +6319,28 @@ struct ul_dcch_msg_type_c { scg_fail_info_nr_r15_s& set_scg_fail_info_nr_r15(); meas_report_app_layer_r15_s& set_meas_report_app_layer_r15(); fail_info_r15_s& set_fail_info_r15(); - void set_spare5(); - void set_spare4(); - void set_spare3(); - void set_spare2(); - void set_spare1(); + ul_ded_msg_segment_r16_s& set_ul_ded_msg_segment_r16(); + pur_cfg_request_r16_s& set_pur_cfg_request_r16(); + fail_info_r16_s& set_fail_info_r16(); + mcg_fail_info_r16_s& set_mcg_fail_info_r16(); + ul_info_transfer_irat_r16_s& set_ul_info_transfer_irat_r16(); private: types type_; choice_buffer_t c; diff --git a/lib/include/srsran/asn1/rrc_nbiot.h b/lib/include/srsran/asn1/rrc_nbiot.h index c0be0ca0a2..3df29d957b 100644 --- a/lib/include/srsran/asn1/rrc_nbiot.h +++ b/lib/include/srsran/asn1/rrc_nbiot.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ /******************************************************************************* * - * 3GPP TS ASN1 RRC v15.11.0 (2020-09) + * 3GPP TS ASN1 RRC v17.4.0 (2023-03) * ******************************************************************************/ @@ -69,33 +69,38 @@ struct ab_cfg_plmn_nb_r13_s { void to_json(json_writer& j) const; }; -// T-PollRetransmit-NB-r13 ::= ENUMERATED -struct t_poll_retx_nb_r13_opts { - enum options { - ms250, - ms500, - ms1000, - ms2000, - ms3000, - ms4000, - ms6000, - ms10000, - ms15000, - ms25000, - ms40000, - ms60000, - ms90000, - ms120000, - ms180000, - ms300000_v1530, - nulltype - } value; - typedef uint32_t number_type; +// ANR-ExcludedCellList-NB-r16 ::= SEQUENCE (SIZE (1..16)) OF INTEGER (0..503) +using anr_excluded_cell_list_nb_r16_l = bounded_array; - const char* to_string() const; - uint32_t to_number() const; +// ANR-Carrier-NB-r16 ::= SEQUENCE +struct anr_carrier_nb_r16_s { + bool ext = false; + bool excluded_cell_list_r16_present = false; + uint8_t carrier_freq_idx_r16 = 1; + anr_excluded_cell_list_nb_r16_l excluded_cell_list_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ANR-CarrierList-NB-r16 ::= SEQUENCE (SIZE (1..2)) OF ANR-Carrier-NB-r16 +using anr_carrier_list_nb_r16_l = dyn_array; + +// ANR-MeasConfig-NB-r16 ::= SEQUENCE +struct anr_meas_cfg_nb_r16_s { + bool ext = false; + uint8_t anr_quality_thres_r16 = 0; + anr_carrier_list_nb_r16_l anr_carrier_list_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; }; -typedef enumerated t_poll_retx_nb_r13_e; // CarrierFreq-NB-r13 ::= SEQUENCE struct carrier_freq_nb_r13_s { @@ -143,6 +148,89 @@ struct carrier_freq_nb_r13_s { void to_json(json_writer& j) const; }; +// MeasResultServCell-NB-r14 ::= SEQUENCE +struct meas_result_serv_cell_nb_r14_s { + uint8_t nrsrp_result_r14 = 0; + int8_t nrsrq_result_r14 = -30; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ANR-MeasResult-NB-r16 ::= SEQUENCE +struct anr_meas_result_nb_r16_s { + struct cgi_info_r16_s_ { + bool plmn_id_list_r16_present = false; + cell_global_id_eutra_s cell_global_id_r16; + fixed_bitstring<16> tac_r16; + plmn_id_list2_l plmn_id_list_r16; + }; + + // member variables + bool pci_r16_present = false; + bool meas_result_r16_present = false; + bool cgi_info_r16_present = false; + carrier_freq_nb_r13_s carrier_freq_r16; + uint16_t pci_r16 = 0; + meas_result_serv_cell_nb_r14_s meas_result_last_serv_cell_r16; + uint8_t meas_result_r16 = 0; + cgi_info_r16_s_ cgi_info_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ANR-MeasReport-NB-r16 ::= SEQUENCE +struct anr_meas_report_nb_r16_s { + using meas_result_list_r16_l_ = dyn_array; + + // member variables + bool ext = false; + bool serv_cell_id_r16_present = false; + cell_global_id_eutra_s serv_cell_id_r16; + meas_result_serv_cell_nb_r14_s meas_result_serv_cell_r16; + uint8_t relative_time_stamp_r16 = 0; + meas_result_list_r16_l_ meas_result_list_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// T-PollRetransmit-NB-r13 ::= ENUMERATED +struct t_poll_retx_nb_r13_opts { + enum options { + ms250, + ms500, + ms1000, + ms2000, + ms3000, + ms4000, + ms6000, + ms10000, + ms15000, + ms25000, + ms40000, + ms60000, + ms90000, + ms120000, + ms180000, + ms300000_v1530, + nulltype + } value; + typedef uint32_t number_type; + + const char* to_string() const; + uint32_t to_number() const; +}; +typedef enumerated t_poll_retx_nb_r13_e; + // CarrierFreq-NB-v1550 ::= SEQUENCE struct carrier_freq_nb_v1550_s { struct carrier_freq_offset_v1550_opts { @@ -514,6 +602,58 @@ struct lc_ch_cfg_nb_r13_s { void to_json(json_writer& j) const; }; +// NPDSCH-16QAM-Config-NB-r17 ::= SEQUENCE +struct npdsch_minus16_qam_cfg_nb_r17_s { + struct nrs_pwr_ratio_r17_opts { + enum options { db_minus6, db_minus4dot77, db_minus3, db_minus1dot77, db0, db1, db2, db3, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated nrs_pwr_ratio_r17_e_; + struct nrs_pwr_ratio_with_crs_r17_opts { + enum options { db_minus6, db_minus4dot77, db_minus3, db_minus1dot77, db0, db1, db2, db3, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated nrs_pwr_ratio_with_crs_r17_e_; + + // member variables + bool nrs_pwr_ratio_r17_present = false; + bool nrs_pwr_ratio_with_crs_r17_present = false; + nrs_pwr_ratio_r17_e_ nrs_pwr_ratio_r17; + nrs_pwr_ratio_with_crs_r17_e_ nrs_pwr_ratio_with_crs_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NPDSCH-MultiTB-Config-NB-r16 ::= SEQUENCE +struct npdsch_multi_tb_cfg_nb_r16_s { + struct multi_tb_cfg_r16_opts { + enum options { interleaved, non_interleaved, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated multi_tb_cfg_r16_e_; + + // member variables + bool harq_ack_bundling_r16_present = false; + multi_tb_cfg_r16_e_ multi_tb_cfg_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PDCP-Config-NB-r13 ::= SEQUENCE struct pdcp_cfg_nb_r13_s { struct discard_timer_r13_opts { @@ -582,6 +722,8 @@ struct pdcp_cfg_nb_r13_s { discard_timer_r13_e_ discard_timer_r13; hdr_compress_r13_c_ hdr_compress_r13; // ... + // group 0 + bool ciphering_disabled_r16_present = false; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -641,6 +783,16 @@ struct rlc_cfg_nb_v1430_s { void to_json(json_writer& j) const; }; +// RLC-Config-NB-v1700 ::= SEQUENCE +struct rlc_cfg_nb_v1700_s { + setup_release_c t_reordering_ext_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SR-NPRACH-Resource-NB-r15 ::= SEQUENCE struct sr_nprach_res_nb_r15_s { struct nprach_sub_carrier_idx_r15_c_ { @@ -716,6 +868,16 @@ struct sr_nprach_res_nb_r15_s { void to_json(json_writer& j) const; }; +// SR-ProhibitTimerOffset-NB-r17 ::= ENUMERATED +struct sr_prohibit_timer_offset_nb_r17_opts { + enum options { ms90, ms180, ms270, ms360, ms450, ms540, ms1080, spare, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; +}; +typedef enumerated sr_prohibit_timer_offset_nb_r17_e; + // UL-CarrierConfigDedicated-NB-r13 ::= SEQUENCE struct ul_carrier_cfg_ded_nb_r13_s { bool ext = false; @@ -760,6 +922,11 @@ struct drb_to_add_mod_nb_r13_s { // ... // group 0 copy_ptr rlc_cfg_v1430; + // group 1 + bool pdu_session_r16_present = false; + uint16_t pdu_session_r16 = 0; + // group 2 + copy_ptr rlc_cfg_v1700; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -980,6 +1147,27 @@ struct npdcch_cfg_ded_nb_v1530_s { void to_json(json_writer& j) const; }; +// NPDSCH-ConfigDedicated-NB-r16 ::= SEQUENCE +struct npdsch_cfg_ded_nb_r16_s { + bool npdsch_multi_tb_cfg_r16_present = false; + npdsch_multi_tb_cfg_nb_r16_s npdsch_multi_tb_cfg_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NPDSCH-ConfigDedicated-NB-v1710 ::= SEQUENCE +struct npdsch_cfg_ded_nb_v1710_s { + setup_release_c npdsch_minus16_qam_cfg_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // NPUSCH-ConfigDedicated-NB-r13 ::= SEQUENCE struct npusch_cfg_ded_nb_r13_s { bool ack_nack_num_repeats_r13_present = false; @@ -994,106 +1182,432 @@ struct npusch_cfg_ded_nb_r13_s { void to_json(json_writer& j) const; }; -// PeriodicBSR-Timer-NB-r13 ::= ENUMERATED -struct periodic_bsr_timer_nb_r13_opts { - enum options { pp2, pp4, pp8, pp16, pp64, pp128, infinity, spare, nulltype } value; - typedef int16_t number_type; +// NPUSCH-ConfigDedicated-NB-v1610 ::= SEQUENCE +struct npusch_cfg_ded_nb_v1610_s { + struct npusch_multi_tb_cfg_r16_opts { + enum options { interleaved, non_interleaved, nulltype } value; - const char* to_string() const; - int16_t to_number() const; -}; -typedef enumerated periodic_bsr_timer_nb_r13_e; + const char* to_string() const; + }; + typedef enumerated npusch_multi_tb_cfg_r16_e_; -// RetxBSR-Timer-NB-r13 ::= ENUMERATED -struct retx_bsr_timer_nb_r13_opts { - enum options { pp4, pp16, pp64, pp128, pp256, pp512, infinity, spare, nulltype } value; - typedef int16_t number_type; + // member variables + npusch_multi_tb_cfg_r16_e_ npusch_multi_tb_cfg_r16; - const char* to_string() const; - int16_t to_number() const; + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; }; -typedef enumerated retx_bsr_timer_nb_r13_e; - -// SR-SPS-BSR-Config-NB-r15 ::= CHOICE -struct sr_sps_bsr_cfg_nb_r15_c { - struct setup_s_ { - struct semi_persist_sched_interv_ul_r15_opts { - enum options { sf128, sf256, sf512, sf1024, sf1280, sf2048, sf2560, sf5120, nulltype } value; - typedef uint16_t number_type; - - const char* to_string() const; - uint16_t to_number() const; - }; - typedef enumerated semi_persist_sched_interv_ul_r15_e_; - // member variables - fixed_bitstring<16> semi_persist_sched_c_rnti_r15; - semi_persist_sched_interv_ul_r15_e_ semi_persist_sched_interv_ul_r15; - }; - using types = setup_e; +// NPUSCH-ConfigDedicated-NB-v1700 ::= SEQUENCE +struct npusch_cfg_ded_nb_v1700_s { + bool npusch_minus16_qam_cfg_r17_present = false; - // choice methods - sr_sps_bsr_cfg_nb_r15_c() = default; - void set(types::options e = types::nulltype); - types type() const { return type_; } + // sequence methods SRSASN_CODE pack(bit_ref& bref) const; SRSASN_CODE unpack(cbit_ref& bref); void to_json(json_writer& j) const; - // getters - setup_s_& setup() - { - assert_choice_type(types::setup, type_, "SR-SPS-BSR-Config-NB-r15"); - return c; - } - const setup_s_& setup() const - { - assert_choice_type(types::setup, type_, "SR-SPS-BSR-Config-NB-r15"); - return c; - } - void set_release(); - setup_s_& set_setup(); - -private: - types type_; - setup_s_ c; }; -// SR-WithoutHARQ-ACK-Config-NB-r15 ::= CHOICE -struct sr_without_harq_ack_cfg_nb_r15_c { - struct setup_s_ { - bool sr_prohibit_timer_r15_present = false; - bool sr_nprach_res_r15_present = false; - uint8_t sr_prohibit_timer_r15 = 0; - sr_nprach_res_nb_r15_s sr_nprach_res_r15; +// NPUSCH-TxDuration-NB-r17 ::= SEQUENCE +struct npusch_tx_dur_nb_r17_s { + struct npusch_tx_dur_r17_opts { + enum options { ms2, ms4, ms8, ms16, ms32, ms64, ms128, ms256, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; }; - using types = setup_e; + typedef enumerated npusch_tx_dur_r17_e_; - // choice methods - sr_without_harq_ack_cfg_nb_r15_c() = default; - void set(types::options e = types::nulltype); - types type() const { return type_; } + // member variables + npusch_tx_dur_r17_e_ npusch_tx_dur_r17; + + // sequence methods SRSASN_CODE pack(bit_ref& bref) const; SRSASN_CODE unpack(cbit_ref& bref); void to_json(json_writer& j) const; - // getters - setup_s_& setup() - { - assert_choice_type(types::setup, type_, "SR-WithoutHARQ-ACK-Config-NB-r15"); - return c; - } - const setup_s_& setup() const - { - assert_choice_type(types::setup, type_, "SR-WithoutHARQ-ACK-Config-NB-r15"); - return c; - } - void set_release(); - setup_s_& set_setup(); +}; -private: - types type_; +// OffsetThresholdTA-NB-r17 ::= ENUMERATED +struct offset_thres_ta_nb_r17_opts { + enum options { + ms0dot5, + ms1, + ms2, + ms3, + ms4, + ms5, + ms6, + ms7, + ms8, + ms9, + ms10, + ms11, + ms12, + ms13, + ms14, + ms15, + nulltype + } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; +}; +typedef enumerated offset_thres_ta_nb_r17_e; + +// PeriodicBSR-Timer-NB-r13 ::= ENUMERATED +struct periodic_bsr_timer_nb_r13_opts { + enum options { pp2, pp4, pp8, pp16, pp64, pp128, infinity, spare, nulltype } value; + typedef int16_t number_type; + + const char* to_string() const; + int16_t to_number() const; +}; +typedef enumerated periodic_bsr_timer_nb_r13_e; + +// ResourceReservationConfig-NB-r16 ::= SEQUENCE +struct res_reserv_cfg_nb_r16_s { + struct periodicity_r16_opts { + enum options { ms10, ms20, ms40, ms80, ms160, spare3, spare2, spare1, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated periodicity_r16_e_; + struct res_reserv_r16_c_ { + struct sf_bitmap_r16_c_ { + struct types_opts { + enum options { sf_pattern10ms, sf_pattern40ms, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + sf_bitmap_r16_c_() = default; + sf_bitmap_r16_c_(const sf_bitmap_r16_c_& other); + sf_bitmap_r16_c_& operator=(const sf_bitmap_r16_c_& other); + ~sf_bitmap_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<10>& sf_pattern10ms() + { + assert_choice_type(types::sf_pattern10ms, type_, "subframeBitmap-r16"); + return c.get >(); + } + fixed_bitstring<40>& sf_pattern40ms() + { + assert_choice_type(types::sf_pattern40ms, type_, "subframeBitmap-r16"); + return c.get >(); + } + const fixed_bitstring<10>& sf_pattern10ms() const + { + assert_choice_type(types::sf_pattern10ms, type_, "subframeBitmap-r16"); + return c.get >(); + } + const fixed_bitstring<40>& sf_pattern40ms() const + { + assert_choice_type(types::sf_pattern40ms, type_, "subframeBitmap-r16"); + return c.get >(); + } + fixed_bitstring<10>& set_sf_pattern10ms(); + fixed_bitstring<40>& set_sf_pattern40ms(); + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + struct slot_cfg_r16_s_ { + struct slot_bitmap_r16_c_ { + struct types_opts { + enum options { slot_pattern10ms, slot_pattern40ms, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + slot_bitmap_r16_c_() = default; + slot_bitmap_r16_c_(const slot_bitmap_r16_c_& other); + slot_bitmap_r16_c_& operator=(const slot_bitmap_r16_c_& other); + ~slot_bitmap_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<20>& slot_pattern10ms() + { + assert_choice_type(types::slot_pattern10ms, type_, "slotBitmap-r16"); + return c.get >(); + } + fixed_bitstring<80>& slot_pattern40ms() + { + assert_choice_type(types::slot_pattern40ms, type_, "slotBitmap-r16"); + return c.get >(); + } + const fixed_bitstring<20>& slot_pattern10ms() const + { + assert_choice_type(types::slot_pattern10ms, type_, "slotBitmap-r16"); + return c.get >(); + } + const fixed_bitstring<80>& slot_pattern40ms() const + { + assert_choice_type(types::slot_pattern40ms, type_, "slotBitmap-r16"); + return c.get >(); + } + fixed_bitstring<20>& set_slot_pattern10ms(); + fixed_bitstring<80>& set_slot_pattern40ms(); + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; + struct symbol_bitmap_r16_c_ { + struct symbol_bitmap_fdd_dl_s_ { + bool symbol_bitmap1_r16_present = false; + bool symbol_bitmap2_r16_present = false; + fixed_bitstring<5> symbol_bitmap1_r16; + fixed_bitstring<5> symbol_bitmap2_r16; + }; + struct symbol_bitmap_fdd_ul_or_tdd_s_ { + bool symbol_bitmap1_r16_present = false; + bool symbol_bitmap2_r16_present = false; + fixed_bitstring<7> symbol_bitmap1_r16; + fixed_bitstring<7> symbol_bitmap2_r16; + }; + struct types_opts { + enum options { symbol_bitmap_fdd_dl, symbol_bitmap_fdd_ul_or_tdd, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + symbol_bitmap_r16_c_() = default; + symbol_bitmap_r16_c_(const symbol_bitmap_r16_c_& other); + symbol_bitmap_r16_c_& operator=(const symbol_bitmap_r16_c_& other); + ~symbol_bitmap_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + symbol_bitmap_fdd_dl_s_& symbol_bitmap_fdd_dl() + { + assert_choice_type(types::symbol_bitmap_fdd_dl, type_, "symbolBitmap-r16"); + return c.get(); + } + symbol_bitmap_fdd_ul_or_tdd_s_& symbol_bitmap_fdd_ul_or_tdd() + { + assert_choice_type(types::symbol_bitmap_fdd_ul_or_tdd, type_, "symbolBitmap-r16"); + return c.get(); + } + const symbol_bitmap_fdd_dl_s_& symbol_bitmap_fdd_dl() const + { + assert_choice_type(types::symbol_bitmap_fdd_dl, type_, "symbolBitmap-r16"); + return c.get(); + } + const symbol_bitmap_fdd_ul_or_tdd_s_& symbol_bitmap_fdd_ul_or_tdd() const + { + assert_choice_type(types::symbol_bitmap_fdd_ul_or_tdd, type_, "symbolBitmap-r16"); + return c.get(); + } + symbol_bitmap_fdd_dl_s_& set_symbol_bitmap_fdd_dl(); + symbol_bitmap_fdd_ul_or_tdd_s_& set_symbol_bitmap_fdd_ul_or_tdd(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + slot_bitmap_r16_c_ slot_bitmap_r16; + symbol_bitmap_r16_c_ symbol_bitmap_r16; + }; + struct types_opts { + enum options { sf_bitmap_r16, slot_cfg_r16, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + res_reserv_r16_c_() = default; + res_reserv_r16_c_(const res_reserv_r16_c_& other); + res_reserv_r16_c_& operator=(const res_reserv_r16_c_& other); + ~res_reserv_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + sf_bitmap_r16_c_& sf_bitmap_r16() + { + assert_choice_type(types::sf_bitmap_r16, type_, "resourceReservation-r16"); + return c.get(); + } + slot_cfg_r16_s_& slot_cfg_r16() + { + assert_choice_type(types::slot_cfg_r16, type_, "resourceReservation-r16"); + return c.get(); + } + const sf_bitmap_r16_c_& sf_bitmap_r16() const + { + assert_choice_type(types::sf_bitmap_r16, type_, "resourceReservation-r16"); + return c.get(); + } + const slot_cfg_r16_s_& slot_cfg_r16() const + { + assert_choice_type(types::slot_cfg_r16, type_, "resourceReservation-r16"); + return c.get(); + } + sf_bitmap_r16_c_& set_sf_bitmap_r16(); + slot_cfg_r16_s_& set_slot_cfg_r16(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + + // member variables + bool ext = false; + periodicity_r16_e_ periodicity_r16; + uint8_t start_position_r16 = 0; + res_reserv_r16_c_ res_reserv_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RetxBSR-Timer-NB-r13 ::= ENUMERATED +struct retx_bsr_timer_nb_r13_opts { + enum options { pp4, pp16, pp64, pp128, pp256, pp512, infinity, spare, nulltype } value; + typedef int16_t number_type; + + const char* to_string() const; + int16_t to_number() const; +}; +typedef enumerated retx_bsr_timer_nb_r13_e; + +// SR-SPS-BSR-Config-NB-r15 ::= CHOICE +struct sr_sps_bsr_cfg_nb_r15_c { + struct setup_s_ { + struct semi_persist_sched_interv_ul_r15_opts { + enum options { sf128, sf256, sf512, sf1024, sf1280, sf2048, sf2560, sf5120, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated semi_persist_sched_interv_ul_r15_e_; + + // member variables + fixed_bitstring<16> semi_persist_sched_c_rnti_r15; + semi_persist_sched_interv_ul_r15_e_ semi_persist_sched_interv_ul_r15; + }; + using types = setup_e; + + // choice methods + sr_sps_bsr_cfg_nb_r15_c() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + setup_s_& setup() + { + assert_choice_type(types::setup, type_, "SR-SPS-BSR-Config-NB-r15"); + return c; + } + const setup_s_& setup() const + { + assert_choice_type(types::setup, type_, "SR-SPS-BSR-Config-NB-r15"); + return c; + } + void set_release(); + setup_s_& set_setup(); + +private: + types type_; + setup_s_ c; +}; + +// SR-WithoutHARQ-ACK-Config-NB-r15 ::= CHOICE +struct sr_without_harq_ack_cfg_nb_r15_c { + struct setup_s_ { + bool sr_prohibit_timer_r15_present = false; + bool sr_nprach_res_r15_present = false; + uint8_t sr_prohibit_timer_r15 = 0; + sr_nprach_res_nb_r15_s sr_nprach_res_r15; + }; + using types = setup_e; + + // choice methods + sr_without_harq_ack_cfg_nb_r15_c() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + setup_s_& setup() + { + assert_choice_type(types::setup, type_, "SR-WithoutHARQ-ACK-Config-NB-r15"); + return c; + } + const setup_s_& setup() const + { + assert_choice_type(types::setup, type_, "SR-WithoutHARQ-ACK-Config-NB-r15"); + return c; + } + void set_release(); + setup_s_& set_setup(); + +private: + types type_; setup_s_ c; }; +// SR-WithoutHARQ-ACK-Config-NB-v1700 ::= SEQUENCE +struct sr_without_harq_ack_cfg_nb_v1700_s { + bool sr_prohibit_timer_offset_r17_present = false; + setup_release_c sr_prohibit_timer_offset_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SRB-ToAddMod-NB-r13 ::= SEQUENCE struct srb_to_add_mod_nb_r13_s { struct rlc_cfg_r13_c_ { @@ -1172,6 +1686,8 @@ struct srb_to_add_mod_nb_r13_s { // ... // group 0 copy_ptr rlc_cfg_v1430; + // group 1 + copy_ptr rlc_cfg_v1700; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1189,6 +1705,26 @@ struct ul_pwr_ctrl_ded_nb_r13_s { void to_json(json_writer& j) const; }; +// UplinkPowerControlDedicated-NB-v1700 ::= SEQUENCE +struct ul_pwr_ctrl_ded_nb_v1700_s { + struct delta_mcs_enabled_r17_opts { + enum options { en0, en1, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated delta_mcs_enabled_r17_e_; + + // member variables + delta_mcs_enabled_r17_e_ delta_mcs_enabled_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // DRB-ToAddModList-NB-r13 ::= SEQUENCE (SIZE (1..2)) OF DRB-ToAddMod-NB-r13 using drb_to_add_mod_list_nb_r13_l = dyn_array; @@ -1301,6 +1837,8 @@ struct mac_main_cfg_nb_r13_s { drx_cycle_v1430_e_ drx_cycle_v1430; // group 2 bool ra_cfra_cfg_r14_present = false; + // group 3 + copy_ptr > offset_thres_ta_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1310,6 +1848,17 @@ struct mac_main_cfg_nb_r13_s { // PhysicalConfigDedicated-NB-r13 ::= SEQUENCE struct phys_cfg_ded_nb_r13_s { + struct ntn_cfg_ded_r17_s_ { + setup_release_c npusch_tx_dur_r17; + }; + struct ul_segmented_precompensation_gap_r17_opts { + enum options { sym1, sl1, sl2, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated ul_segmented_precompensation_gap_r17_e_; + + // member variables bool ext = false; bool carrier_cfg_ded_r13_present = false; bool npdcch_cfg_ded_r13_present = false; @@ -1328,6 +1877,20 @@ struct phys_cfg_ded_nb_r13_s { copy_ptr npdcch_cfg_ded_v1530; // group 3 bool add_tx_sib1_cfg_v1540_present = false; + // group 4 + copy_ptr npusch_cfg_ded_v1610; + copy_ptr npdsch_cfg_ded_r16; + copy_ptr > res_reserv_cfg_dl_r16; + copy_ptr > res_reserv_cfg_ul_r16; + // group 5 + copy_ptr ntn_cfg_ded_r17; + copy_ptr npdsch_cfg_ded_v1700; + copy_ptr ul_pwr_ctrl_ded_v1700; + // group 6 + bool ul_segmented_precompensation_gap_r17_present = false; + ul_segmented_precompensation_gap_r17_e_ ul_segmented_precompensation_gap_r17; + // group 7 + copy_ptr npusch_cfg_ded_v1740; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1465,6 +2028,8 @@ struct sched_request_cfg_nb_r15_s { sr_without_harq_ack_cfg_nb_r15_c sr_without_harq_ack_cfg_r15; sr_sps_bsr_cfg_nb_r15_c sr_sps_bsr_cfg_r15; // ... + // group 0 + copy_ptr sr_without_harq_ack_cfg_v1700; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1525,6 +2090,9 @@ struct rr_cfg_ded_nb_r13_s { // ... // group 0 copy_ptr sched_request_cfg_r15; + // group 1 + bool new_ue_id_r16_present = false; + fixed_bitstring<16> new_ue_id_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -1718,6 +2286,54 @@ struct mib_nb_s { void destroy_(); }; + struct part_earfcn_minus17_c_ { + struct types_opts { + enum options { spare, earfcn_lsb, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + part_earfcn_minus17_c_() = default; + part_earfcn_minus17_c_(const part_earfcn_minus17_c_& other); + part_earfcn_minus17_c_& operator=(const part_earfcn_minus17_c_& other); + ~part_earfcn_minus17_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<2>& spare() + { + assert_choice_type(types::spare, type_, "partEARFCN-17"); + return c.get >(); + } + fixed_bitstring<2>& earfcn_lsb() + { + assert_choice_type(types::earfcn_lsb, type_, "partEARFCN-17"); + return c.get >(); + } + const fixed_bitstring<2>& spare() const + { + assert_choice_type(types::spare, type_, "partEARFCN-17"); + return c.get >(); + } + const fixed_bitstring<2>& earfcn_lsb() const + { + assert_choice_type(types::earfcn_lsb, type_, "partEARFCN-17"); + return c.get >(); + } + fixed_bitstring<2>& set_spare(); + fixed_bitstring<2>& set_earfcn_lsb(); + + private: + types type_; + choice_buffer_t > c; + + void destroy_(); + }; // member variables fixed_bitstring<4> sys_frame_num_msb_r13; @@ -1726,8 +2342,10 @@ struct mib_nb_s { uint8_t sys_info_value_tag_r13 = 0; bool ab_enabled_r13 = false; operation_mode_info_r13_c_ operation_mode_info_r13; - bool add_tx_sib1_r15 = false; - fixed_bitstring<10> spare; + bool add_tx_sib1_r15 = false; + bool ab_enabled_minus5_gc_r16 = false; + part_earfcn_minus17_c_ part_earfcn_minus17; + fixed_bitstring<6> spare; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2068,7 +2686,8 @@ struct mib_tdd_nb_r15_s { bool ab_enabled_r15 = false; operation_mode_info_r15_c_ operation_mode_info_r15; sib1_carrier_info_r15_e_ sib1_carrier_info_r15; - fixed_bitstring<9> spare; + bool ab_enabled_minus5_gc_r16 = false; + fixed_bitstring<8> spare; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -2089,6 +2708,9 @@ struct bcch_bch_msg_tdd_nb_s { void to_json(json_writer& j) const; }; +// TrackingAreaList-NB-r17 ::= SEQUENCE (SIZE (1..12)) OF BIT STRING (SIZE (16)) +using tracking_area_list_nb_r17_l = bounded_array, 12>; + // NS-PmaxValue-NB-r13 ::= SEQUENCE struct ns_pmax_value_nb_r13_s { bool add_pmax_r13_present = false; @@ -2101,9 +2723,30 @@ struct ns_pmax_value_nb_r13_s { void to_json(json_writer& j) const; }; +// PLMN-IdentityInfo-NB-v1700 ::= SEQUENCE +struct plmn_id_info_nb_v1700_s { + bool tracking_area_list_r17_present = false; + tracking_area_list_nb_r17_l tracking_area_list_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SIB-Type-NB-v1530 ::= ENUMERATED struct sib_type_nb_v1530_opts { - enum options { sib_type23_nb_r15, spare7, spare6, spare5, spare4, spare3, spare2, spare1, nulltype } value; + enum options { + sib_type23_nb_r15, + sib_type27_nb_r16, + sib_type31_nb_r17, + sib_type32_nb_r17, + spare4, + spare3, + spare2, + spare1, + nulltype + } value; typedef uint8_t number_type; const char* to_string() const; @@ -2111,6 +2754,16 @@ struct sib_type_nb_v1530_opts { }; typedef enumerated sib_type_nb_v1530_e; +// GWUS-NumGroups-NB-r16 ::= ENUMERATED +struct gwus_num_groups_nb_r16_opts { + enum options { n1, n2, n4, n8, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated gwus_num_groups_nb_r16_e; + // NS-PmaxList-NB-r13 ::= SEQUENCE (SIZE (1..4)) OF NS-PmaxValue-NB-r13 using ns_pmax_list_nb_r13_l = dyn_array; @@ -2144,6 +2797,78 @@ struct nsss_rrm_cfg_nb_r15_s { void to_json(json_writer& j) const; }; +// PLMN-IdentityInfo-5GC-NB-r16 ::= SEQUENCE +struct plmn_id_info_minus5_gc_nb_r16_s { + struct plmn_id_minus5_gc_r16_c_ { + struct types_opts { + enum options { plmn_id_r16, plmn_idx_r16, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + plmn_id_minus5_gc_r16_c_() = default; + plmn_id_minus5_gc_r16_c_(const plmn_id_minus5_gc_r16_c_& other); + plmn_id_minus5_gc_r16_c_& operator=(const plmn_id_minus5_gc_r16_c_& other); + ~plmn_id_minus5_gc_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + plmn_id_s& plmn_id_r16() + { + assert_choice_type(types::plmn_id_r16, type_, "plmn-Identity-5GC-r16"); + return c.get(); + } + uint8_t& plmn_idx_r16() + { + assert_choice_type(types::plmn_idx_r16, type_, "plmn-Identity-5GC-r16"); + return c.get(); + } + const plmn_id_s& plmn_id_r16() const + { + assert_choice_type(types::plmn_id_r16, type_, "plmn-Identity-5GC-r16"); + return c.get(); + } + const uint8_t& plmn_idx_r16() const + { + assert_choice_type(types::plmn_idx_r16, type_, "plmn-Identity-5GC-r16"); + return c.get(); + } + plmn_id_s& set_plmn_id_r16(); + uint8_t& set_plmn_idx_r16(); + + private: + types type_; + choice_buffer_t c; + + void destroy_(); + }; + struct cell_reserved_for_oper_r16_opts { + enum options { reserved, not_reserved, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated cell_reserved_for_oper_r16_e_; + + // member variables + bool ng_u_data_transfer_r16_present = false; + bool up_cio_t_minus5_gs_optim_r16_present = false; + plmn_id_minus5_gc_r16_c_ plmn_id_minus5_gc_r16; + cell_reserved_for_oper_r16_e_ cell_reserved_for_oper_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PLMN-IdentityList-NB-v1700 ::= SEQUENCE (SIZE (1..6)) OF PLMN-IdentityInfo-NB-v1700 +using plmn_id_list_nb_v1700_l = dyn_array; + // SIB-MappingInfo-NB-v1530 ::= SEQUENCE (SIZE (1..8)) OF SIB-Type-NB-v1530 using sib_map_info_nb_v1530_l = bounded_array; @@ -2168,6 +2893,22 @@ struct edt_tbs_nb_r15_s { void to_json(json_writer& j) const; }; +// GWUS-GroupsForServiceList-NB-r16 ::= SEQUENCE (SIZE (1..3)) OF INTEGER (1..15) +using gwus_groups_for_service_list_nb_r16_l = bounded_array; + +// GWUS-NumGroupsList-NB-r16 ::= SEQUENCE (SIZE (1..2)) OF GWUS-NumGroups-NB-r16 +using gwus_num_groups_list_nb_r16_l = bounded_array; + +// GWUS-Paging-ProbThresh-NB-r16 ::= ENUMERATED +struct gwus_paging_prob_thresh_nb_r16_opts { + enum options { p20, p30, p40, p50, p60, p70, p80, p90, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; +}; +typedef enumerated gwus_paging_prob_thresh_nb_r16_e; + // InterFreqNeighCellInfo-NB-v1530 ::= SEQUENCE struct inter_freq_neigh_cell_info_nb_v1530_s { bool nsss_rrm_cfg_r15_present = false; @@ -2792,6 +3533,9 @@ struct nprach_params_tdd_nb_v1550_s { void to_json(json_writer& j) const; }; +// PLMN-IdentityList-5GC-NB-r16 ::= SEQUENCE (SIZE (1..6)) OF PLMN-IdentityInfo-5GC-NB-r16 +using plmn_id_list_minus5_gc_nb_r16_l = dyn_array; + // PagingWeight-NB-r14 ::= ENUMERATED struct paging_weight_nb_r14_opts { enum options { w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15, w16, nulltype } value; @@ -2862,6 +3606,64 @@ struct sched_info_nb_v1530_s { void to_json(json_writer& j) const; }; +// SystemInformationBlockType1-NB-v1700 ::= SEQUENCE +struct sib_type1_nb_v1700_s { + struct cell_access_related_info_ntn_r17_s_ { + struct cell_barred_ntn_r17_opts { + enum options { barred, not_barred, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated cell_barred_ntn_r17_e_; + + // member variables + bool plmn_id_list_v1700_present = false; + cell_barred_ntn_r17_e_ cell_barred_ntn_r17; + plmn_id_list_nb_v1700_l plmn_id_list_v1700; + }; + + // member variables + bool cell_access_related_info_ntn_r17_present = false; + bool non_crit_ext_present = false; + cell_access_related_info_ntn_r17_s_ cell_access_related_info_ntn_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UAC-BarringPerCat-NB-r16 ::= SEQUENCE +struct uac_barr_per_cat_nb_r16_s { + struct uac_barr_factor_r16_opts { + enum options { p00, p05, p10, p15, p20, p25, p30, p40, p50, p60, p70, p75, p80, p85, p90, p95, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated uac_barr_factor_r16_e_; + struct uac_barr_time_r16_opts { + enum options { s4, s8, s16, s32, s64, s128, s256, s512, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated uac_barr_time_r16_e_; + + // member variables + uint8_t uac_access_category_r16 = 1; + uac_barr_factor_r16_e_ uac_barr_factor_r16; + uac_barr_time_r16_e_ uac_barr_time_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // WUS-MaxDurationFactor-NB-r15 ::= ENUMERATED struct wus_max_dur_factor_nb_r15_opts { enum options { one128th, one64th, one32th, one16th, one_eighth, one_quarter, one_half, nulltype } value; @@ -3055,8 +3857,33 @@ struct dl_carrier_cfg_common_nb_r14_s { // EDT-TBS-InfoList-NB-r15 ::= SEQUENCE (SIZE (1..3)) OF EDT-TBS-NB-r15 using edt_tbs_info_list_nb_r15_l = dyn_array; -// InterFreqBlackCellList-NB-r13 ::= SEQUENCE (SIZE (1..16)) OF INTEGER (0..503) -using inter_freq_black_cell_list_nb_r13_l = bounded_array; +// GWUS-ProbThreshList-NB-r16 ::= SEQUENCE (SIZE (1..3)) OF GWUS-Paging-ProbThresh-NB-r16 +using gwus_prob_thresh_list_nb_r16_l = bounded_array; + +// GWUS-ResourceConfig-NB-r16 ::= SEQUENCE +struct gwus_res_cfg_nb_r16_s { + struct res_position_r16_opts { + enum options { primary, secondary, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated res_position_r16_e_; + + // member variables + bool num_groups_list_r16_present = false; + bool groups_for_service_list_r16_present = false; + res_position_r16_e_ res_position_r16; + gwus_num_groups_list_nb_r16_l num_groups_list_r16; + gwus_groups_for_service_list_nb_r16_l groups_for_service_list_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterFreqExcludedCellList-NB-r13 ::= SEQUENCE (SIZE (1..16)) OF INTEGER (0..503) +using inter_freq_excluded_cell_list_nb_r13_l = bounded_array; // InterFreqNeighCellList-NB-r13 ::= SEQUENCE (SIZE (1..16)) OF INTEGER (0..503) using inter_freq_neigh_cell_list_nb_r13_l = bounded_array; @@ -3128,6 +3955,31 @@ struct pcch_cfg_nb_r14_s { void to_json(json_writer& j) const; }; +// PCCH-Config-NB-r17 ::= SEQUENCE +struct pcch_cfg_nb_r17_s { + struct npdcch_num_repeat_paging_r17_opts { + enum options { r1, r2, r4, r8, r16, r32, r64, r128, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated npdcch_num_repeat_paging_r17_e_; + + // member variables + bool ext = false; + bool paging_weight_r17_present = false; + uint8_t cbp_idx_r17 = 1; + npdcch_num_repeat_paging_r17_e_ npdcch_num_repeat_paging_r17; + paging_weight_nb_r14_e paging_weight_r17; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PowerRampingParameters-NB-v1450 ::= SEQUENCE struct pwr_ramp_params_nb_v1450_s { struct preamb_init_rx_target_pwr_v1450_opts { @@ -3225,6 +4077,36 @@ using rsrp_thress_nprach_info_list_nb_r13_l = bounded_array; // SchedulingInfoList-NB-v1530 ::= SEQUENCE (SIZE (1..8)) OF SchedulingInfo-NB-v1530 using sched_info_list_nb_v1530_l = dyn_array; +// SystemInformationBlockType1-NB-v1610 ::= SEQUENCE +struct sib_type1_nb_v1610_s { + struct cell_access_related_info_minus5_gc_r16_s_ { + struct cell_barred_minus5_gc_r16_opts { + enum options { barred, not_barred, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated cell_barred_minus5_gc_r16_e_; + + // member variables + bool cell_id_r16_present = false; + plmn_id_list_minus5_gc_nb_r16_l plmn_id_list_r16; + fixed_bitstring<24> tac_minus5_gc_r16; + fixed_bitstring<28> cell_id_r16; + cell_barred_minus5_gc_r16_e_ cell_barred_minus5_gc_r16; + }; + + // member variables + bool cell_access_related_info_minus5_gc_r16_present = false; + bool non_crit_ext_present = false; + cell_access_related_info_minus5_gc_r16_s_ cell_access_related_info_minus5_gc_r16; + sib_type1_nb_v1700_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // TDD-Config-NB-r15 ::= SEQUENCE struct tdd_cfg_nb_r15_s { struct sf_assign_r15_opts { @@ -3266,6 +4148,9 @@ struct tdd_cfg_nb_r15_s { void to_json(json_writer& j) const; }; +// UAC-BarringPerCatList-NB-r16 ::= SEQUENCE (SIZE (1..63)) OF UAC-BarringPerCat-NB-r16 +using uac_barr_per_cat_list_nb_r16_l = dyn_array; + // UL-ReferenceSignalsNPUSCH-NB-r13 ::= SEQUENCE struct ul_ref_sigs_npusch_nb_r13_s { bool group_hop_enabled_r13 = false; @@ -3277,6 +4162,67 @@ struct ul_ref_sigs_npusch_nb_r13_s { void to_json(json_writer& j) const; }; +// WUS-Config-NB-r15 ::= SEQUENCE +struct wus_cfg_nb_r15_s { + struct num_pos_r15_opts { + enum options { n1, n2, n4, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated num_pos_r15_e_; + struct num_drx_cycles_relaxed_r15_opts { + enum options { n1, n2, n4, n8, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated num_drx_cycles_relaxed_r15_e_; + struct time_offset_drx_r15_opts { + enum options { ms40, ms80, ms160, ms240, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated time_offset_drx_r15_e_; + struct time_offset_e_drx_short_r15_opts { + enum options { ms40, ms80, ms160, ms240, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated time_offset_e_drx_short_r15_e_; + struct time_offset_e_drx_long_r15_opts { + enum options { ms1000, ms2000, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated time_offset_e_drx_long_r15_e_; + + // member variables + bool ext = false; + bool num_pos_r15_present = false; + bool time_offset_e_drx_long_r15_present = false; + wus_max_dur_factor_nb_r15_e max_dur_factor_r15; + num_pos_r15_e_ num_pos_r15; + num_drx_cycles_relaxed_r15_e_ num_drx_cycles_relaxed_r15; + time_offset_drx_r15_e_ time_offset_drx_r15; + time_offset_e_drx_short_r15_e_ time_offset_e_drx_short_r15; + time_offset_e_drx_long_r15_e_ time_offset_e_drx_long_r15; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // WUS-ConfigPerCarrier-NB-r15 ::= SEQUENCE struct wus_cfg_per_carrier_nb_r15_s { wus_max_dur_factor_nb_r15_e max_dur_factor_r15; @@ -3307,15 +4253,50 @@ struct bcch_cfg_nb_r13_s { void to_json(json_writer& j) const; }; -// DL-ConfigCommon-NB-r14 ::= SEQUENCE -struct dl_cfg_common_nb_r14_s { - bool ext = false; - bool pcch_cfg_r14_present = false; - dl_carrier_cfg_common_nb_r14_s dl_carrier_cfg_r14; - pcch_cfg_nb_r14_s pcch_cfg_r14; - // ... - // group 0 - copy_ptr wus_cfg_r15; +// CBP-Config-NB-r17 ::= SEQUENCE +struct cbp_cfg_nb_r17_s { + struct nb_r17_opts { + enum options { + four_t, + two_t, + one_t, + half_t, + quarter_t, + one8th_t, + one16th_t, + one32nd_t, + one64th_t, + one128th_t, + one256th_t, + one512th_t, + one1024th_t, + spare3, + spare2, + spare1, + nulltype + } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated nb_r17_e_; + struct ue_specific_drx_cycle_min_r17_opts { + enum options { rf32, rf64, rf128, rf256, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated ue_specific_drx_cycle_min_r17_e_; + + // member variables + bool nb_r17_present = false; + bool ue_specific_drx_cycle_min_r17_present = false; + uint8_t nrsrp_min_r17 = 0; + nb_r17_e_ nb_r17; + ue_specific_drx_cycle_min_r17_e_ ue_specific_drx_cycle_min_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3323,16 +4304,97 @@ struct dl_cfg_common_nb_r14_s { void to_json(json_writer& j) const; }; -// InterFreqCarrierFreqInfo-NB-r13 ::= SEQUENCE -struct inter_freq_carrier_freq_info_nb_r13_s { - struct pwr_class14dbm_offset_r14_opts { - enum options { db_minus6, db_minus3, db3, db6, db9, db12, nulltype } value; - typedef int8_t number_type; +// CarrierFreqEUTRA-NB-r16 ::= SEQUENCE +struct carrier_freq_eutra_nb_r16_s { + bool ext = false; + bool sib1_r16_present = false; + bool sib1_br_r16_present = false; + uint32_t carrier_freq_r16 = 0; + // ... - const char* to_string() const; - int8_t to_number() const; - }; - typedef enumerated pwr_class14dbm_offset_r14_e_; + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CarrierFreqsGERAN-NB-r16 ::= SEQUENCE +struct carrier_freqs_geran_nb_r16_s { + bool ext = false; + bool ec_gsm_iot_r16_present = false; + bool peo_r16_present = false; + carrier_freqs_geran_s carrier_freqs_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// DL-ConfigCommon-NB-r14 ::= SEQUENCE +struct dl_cfg_common_nb_r14_s { + bool ext = false; + bool pcch_cfg_r14_present = false; + dl_carrier_cfg_common_nb_r14_s dl_carrier_cfg_r14; + pcch_cfg_nb_r14_s pcch_cfg_r14; + // ... + // group 0 + copy_ptr wus_cfg_r15; + // group 1 + copy_ptr gwus_cfg_r16; + // group 2 + copy_ptr pcch_cfg_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// GWUS-Config-NB-r16 ::= SEQUENCE +struct gwus_cfg_nb_r16_s { + struct common_seq_r16_opts { + enum options { g0, g126, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated common_seq_r16_e_; + + // member variables + bool ext = false; + bool group_alternation_r16_present = false; + bool common_seq_r16_present = false; + bool time_params_r16_present = false; + bool res_cfg_e_drx_short_r16_present = false; + bool res_cfg_e_drx_long_r16_present = false; + bool prob_thresh_list_r16_present = false; + common_seq_r16_e_ common_seq_r16; + wus_cfg_nb_r15_s time_params_r16; + gwus_res_cfg_nb_r16_s res_cfg_drx_r16; + gwus_res_cfg_nb_r16_s res_cfg_e_drx_short_r16; + gwus_res_cfg_nb_r16_s res_cfg_e_drx_long_r16; + gwus_prob_thresh_list_nb_r16_l prob_thresh_list_r16; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// InterFreqCarrierFreqInfo-NB-r13 ::= SEQUENCE +struct inter_freq_carrier_freq_info_nb_r13_s { + struct pwr_class14dbm_offset_r14_opts { + enum options { db_minus6, db_minus3, db3, db6, db9, db12, nulltype } value; + typedef int8_t number_type; + + const char* to_string() const; + int8_t to_number() const; + }; + typedef enumerated pwr_class14dbm_offset_r14_e_; struct ce_authorisation_offset_r14_opts { enum options { db5, db10, db15, db20, db25, db30, db35, nulltype } value; typedef uint8_t number_type; @@ -3343,21 +4405,21 @@ struct inter_freq_carrier_freq_info_nb_r13_s { typedef enumerated ce_authorisation_offset_r14_e_; // member variables - bool ext = false; - bool q_qual_min_r13_present = false; - bool p_max_r13_present = false; - bool q_offset_freq_r13_present = false; - bool inter_freq_neigh_cell_list_r13_present = false; - bool inter_freq_black_cell_list_r13_present = false; - bool multi_band_info_list_r13_present = false; - carrier_freq_nb_r13_s dl_carrier_freq_r13; - int8_t q_rx_lev_min_r13 = -70; - int8_t q_qual_min_r13 = -34; - int8_t p_max_r13 = -30; - q_offset_range_e q_offset_freq_r13; - inter_freq_neigh_cell_list_nb_r13_l inter_freq_neigh_cell_list_r13; - inter_freq_black_cell_list_nb_r13_l inter_freq_black_cell_list_r13; - multi_band_info_list_nb_r13_l multi_band_info_list_r13; + bool ext = false; + bool q_qual_min_r13_present = false; + bool p_max_r13_present = false; + bool q_offset_freq_r13_present = false; + bool inter_freq_neigh_cell_list_r13_present = false; + bool inter_freq_excluded_cell_list_r13_present = false; + bool multi_band_info_list_r13_present = false; + carrier_freq_nb_r13_s dl_carrier_freq_r13; + int8_t q_rx_lev_min_r13 = -70; + int8_t q_qual_min_r13 = -34; + int8_t p_max_r13 = -30; + q_offset_range_e q_offset_freq_r13; + inter_freq_neigh_cell_list_nb_r13_l inter_freq_neigh_cell_list_r13; + inter_freq_excluded_cell_list_nb_r13_l inter_freq_excluded_cell_list_r13; + multi_band_info_list_nb_r13_l multi_band_info_list_r13; // ... // group 0 bool delta_rx_lev_min_v1350_present = false; @@ -3572,6 +4634,46 @@ struct nprach_probability_anchor_nb_r14_s { void to_json(json_writer& j) const; }; +// NPRACH-TxDurationFmt01-NB-r17 ::= SEQUENCE +struct nprach_tx_dur_fmt01_nb_r17_s { + struct nprach_tx_dur_fmt01_r17_opts { + enum options { n2, n4, n8, n16, n32, n64, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated nprach_tx_dur_fmt01_r17_e_; + + // member variables + nprach_tx_dur_fmt01_r17_e_ nprach_tx_dur_fmt01_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NPRACH-TxDurationFmt2-NB-r17 ::= SEQUENCE +struct nprach_tx_dur_fmt2_nb_r17_s { + struct nprach_tx_dur_fmt2_r17_opts { + enum options { n1, n2, n4, n8, n16, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated nprach_tx_dur_fmt2_r17_e_; + + // member variables + nprach_tx_dur_fmt2_r17_e_ nprach_tx_dur_fmt2_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // NPUSCH-ConfigCommon-NB-r13 ::= SEQUENCE struct npusch_cfg_common_nb_r13_s { using ack_nack_num_repeats_msg4_r13_l_ = bounded_array; @@ -3764,6 +4866,21 @@ struct sib_type1_nb_v1530_s { bool non_crit_ext_present = false; tdd_params_r15_s_ tdd_params_r15; sched_info_list_nb_v1530_l sched_info_list_v1530; + sib_type1_nb_v1610_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UAC-Barring-NB-r16 ::= SEQUENCE +struct uac_barr_nb_r16_s { + bool uac_barr_per_cat_list_r16_present = false; + bool uac_ac1_select_assist_info_r16_present = false; + uac_barr_per_cat_list_nb_r16_l uac_barr_per_cat_list_r16; + uac_ac1_select_assist_info_r15_e uac_ac1_select_assist_info_r16; + fixed_bitstring<7> uac_barr_for_access_id_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3780,6 +4897,8 @@ struct ul_cfg_common_nb_r14_s { // ... // group 0 copy_ptr nprach_params_list_edt_r15; + // group 1 + copy_ptr rsrp_thress_prach_info_list_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -3839,66 +4958,11 @@ struct ul_pwr_ctrl_common_nb_r13_s { void to_json(json_writer& j) const; }; -// WUS-Config-NB-r15 ::= SEQUENCE -struct wus_cfg_nb_r15_s { - struct num_pos_r15_opts { - enum options { n1, n2, n4, nulltype } value; - typedef uint8_t number_type; - - const char* to_string() const; - uint8_t to_number() const; - }; - typedef enumerated num_pos_r15_e_; - struct num_drx_cycles_relaxed_r15_opts { - enum options { n1, n2, n4, n8, nulltype } value; - typedef uint8_t number_type; - - const char* to_string() const; - uint8_t to_number() const; - }; - typedef enumerated num_drx_cycles_relaxed_r15_e_; - struct time_offset_drx_r15_opts { - enum options { ms40, ms80, ms160, ms240, nulltype } value; - typedef uint8_t number_type; - - const char* to_string() const; - uint8_t to_number() const; - }; - typedef enumerated time_offset_drx_r15_e_; - struct time_offset_e_drx_short_r15_opts { - enum options { ms40, ms80, ms160, ms240, nulltype } value; - typedef uint8_t number_type; - - const char* to_string() const; - uint8_t to_number() const; - }; - typedef enumerated time_offset_e_drx_short_r15_e_; - struct time_offset_e_drx_long_r15_opts { - enum options { ms1000, ms2000, nulltype } value; - typedef uint16_t number_type; - - const char* to_string() const; - uint16_t to_number() const; - }; - typedef enumerated time_offset_e_drx_long_r15_e_; - - // member variables - bool ext = false; - bool num_pos_r15_present = false; - bool time_offset_e_drx_long_r15_present = false; - wus_max_dur_factor_nb_r15_e max_dur_factor_r15; - num_pos_r15_e_ num_pos_r15; - num_drx_cycles_relaxed_r15_e_ num_drx_cycles_relaxed_r15; - time_offset_drx_r15_e_ time_offset_drx_r15; - time_offset_e_drx_short_r15_e_ time_offset_e_drx_short_r15; - time_offset_e_drx_long_r15_e_ time_offset_e_drx_long_r15; - // ... +// CarrierFreqListEUTRA-NB-r16 ::= SEQUENCE (SIZE (1..8)) OF CarrierFreqEUTRA-NB-r16 +using carrier_freq_list_eutra_nb_r16_l = dyn_array; - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +// CarrierFreqsListGERAN-NB-r16 ::= SEQUENCE (SIZE (1..8)) OF CarrierFreqsGERAN-NB-r16 +using carrier_freqs_list_geran_nb_r16_l = dyn_array; // CellReselectionInfoCommon-NB-v1450 ::= SEQUENCE struct cell_resel_info_common_nb_v1450_s { @@ -3951,6 +5015,66 @@ struct cell_sel_info_nb_v1430_s { void to_json(json_writer& j) const; }; +// ConnMeasConfig-NB-r17 ::= SEQUENCE +struct conn_meas_cfg_nb_r17_s { + struct neigh_cell_meas_criteria_r17_s_ { + struct s_measure_delta_p_r17_opts { + enum options { db6, db9, db12, db15, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated s_measure_delta_p_r17_e_; + struct t_measure_delta_p_r17_opts { + enum options { s15, s30, s45, s60, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated t_measure_delta_p_r17_e_; + + // member variables + s_measure_delta_p_r17_e_ s_measure_delta_p_r17; + t_measure_delta_p_r17_e_ t_measure_delta_p_r17; + }; + + // member variables + bool s_measure_inter_r17_present = false; + bool neigh_cell_meas_criteria_r17_present = false; + uint8_t s_measure_intra_r17 = 0; + uint8_t s_measure_inter_r17 = 0; + neigh_cell_meas_criteria_r17_s_ neigh_cell_meas_criteria_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// CoverageBasedPagingConfig-NB-r17 ::= SEQUENCE +struct coverage_based_paging_cfg_nb_r17_s { + struct cbp_hyst_timer_r17_opts { + enum options { ms2560, ms7680, ms12800, ms17920, ms23040, ms28160, ms33280, ms40960, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated cbp_hyst_timer_r17_e_; + using cbp_cfg_list_r17_l_ = dyn_array; + + // member variables + cbp_hyst_timer_r17_e_ cbp_hyst_timer_r17; + cbp_cfg_list_r17_l_ cbp_cfg_list_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // DL-ConfigCommonList-NB-r14 ::= SEQUENCE (SIZE (1..15)) OF DL-ConfigCommon-NB-r14 using dl_cfg_common_list_nb_r14_l = dyn_array; @@ -4069,6 +5193,36 @@ using nprach_probability_anchor_list_nb_r14_l = dyn_array ue_specific_drx_cycle_min_r16_e_; + struct ntn_cfg_common_r17_s_ { + struct t318_r17_opts { + enum options { ms0, ms200, ms500, ms1000, ms2000, ms4000, ms8000, nulltype } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated t318_r17_e_; + + // member variables + bool ta_report_r17_present = false; + bool nprach_tx_dur_fmt01_r17_present = false; + bool nprach_tx_dur_fmt2_r17_present = false; + bool npusch_tx_dur_r17_present = false; + t318_r17_e_ t318_r17; + nprach_tx_dur_fmt01_nb_r17_s nprach_tx_dur_fmt01_r17; + nprach_tx_dur_fmt2_nb_r17_s nprach_tx_dur_fmt2_r17; + npusch_tx_dur_nb_r17_s npusch_tx_dur_r17; + }; + + // member variables bool ext = false; bool dl_gap_r13_present = false; rach_cfg_common_nb_r13_s rach_cfg_common_r13; @@ -4090,6 +5244,13 @@ struct rr_cfg_common_sib_nb_r13_s { copy_ptr wus_cfg_r15; // group 3 copy_ptr nprach_cfg_v1550; + // group 4 + bool nrs_non_anchor_cfg_r16_present = false; + bool ue_specific_drx_cycle_min_r16_present = false; + copy_ptr gwus_cfg_r16; + ue_specific_drx_cycle_min_r16_e_ ue_specific_drx_cycle_min_r16; + // group 5 + copy_ptr ntn_cfg_common_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -4406,6 +5567,57 @@ struct t_resel_nb_r13_opts { }; typedef enumerated t_resel_nb_r13_e; +// UAC-Param-NB-r16 ::= CHOICE +struct uac_param_nb_r16_c { + using uac_barr_per_plmn_list_l_ = dyn_array; + struct types_opts { + enum options { uac_barr_common, uac_barr_per_plmn_list, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + uac_param_nb_r16_c() = default; + uac_param_nb_r16_c(const uac_param_nb_r16_c& other); + uac_param_nb_r16_c& operator=(const uac_param_nb_r16_c& other); + ~uac_param_nb_r16_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uac_barr_nb_r16_s& uac_barr_common() + { + assert_choice_type(types::uac_barr_common, type_, "UAC-Param-NB-r16"); + return c.get(); + } + uac_barr_per_plmn_list_l_& uac_barr_per_plmn_list() + { + assert_choice_type(types::uac_barr_per_plmn_list, type_, "UAC-Param-NB-r16"); + return c.get(); + } + const uac_barr_nb_r16_s& uac_barr_common() const + { + assert_choice_type(types::uac_barr_common, type_, "UAC-Param-NB-r16"); + return c.get(); + } + const uac_barr_per_plmn_list_l_& uac_barr_per_plmn_list() const + { + assert_choice_type(types::uac_barr_per_plmn_list, type_, "UAC-Param-NB-r16"); + return c.get(); + } + uac_barr_nb_r16_s& set_uac_barr_common(); + uac_barr_per_plmn_list_l_& set_uac_barr_per_plmn_list(); + +private: + types type_; + choice_buffer_t c; + + void destroy_(); +}; + // UE-TimersAndConstants-NB-r13 ::= SEQUENCE struct ue_timers_and_consts_nb_r13_s { struct t300_r13_opts { @@ -4686,6 +5898,8 @@ struct sib_type14_nb_r13_s { // group 0 bool ab_per_nrsrp_r15_present = false; ab_per_nrsrp_r15_e_ ab_per_nrsrp_r15; + // group 1 + copy_ptr uac_param_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -4743,6 +5957,15 @@ struct sib_type2_nb_r13_s { bool cp_edt_r15_present = false; bool up_edt_r15_present = false; copy_ptr freq_info_v1530; + // group 3 + bool early_security_reactivation_r16_present = false; + bool cp_edt_minus5_gc_r16_present = false; + bool up_edt_minus5_gc_r16_present = false; + bool cp_pur_epc_r16_present = false; + bool up_pur_epc_r16_present = false; + bool cp_pur_minus5_gc_r16_present = false; + bool up_pur_minus5_gc_r16_present = false; + bool rai_activation_enh_r16_present = false; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -4881,6 +6104,8 @@ struct sib_type22_nb_r14_s { // group 0 copy_ptr mixed_operation_mode_cfg_r15; copy_ptr ul_cfg_list_r15; + // group 1 + copy_ptr coverage_based_paging_cfg_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -4905,6 +6130,23 @@ struct sib_type23_nb_r15_s { void to_json(json_writer& j) const; }; +// SystemInformationBlockType27-NB-r16 ::= SEQUENCE +struct sib_type27_nb_r16_s { + bool ext = false; + bool carrier_freq_list_eutra_r16_present = false; + bool carrier_freqs_list_geran_r16_present = false; + bool late_non_crit_ext_present = false; + carrier_freq_list_eutra_nb_r16_l carrier_freq_list_eutra_r16; + carrier_freqs_list_geran_nb_r16_l carrier_freqs_list_geran_r16; + dyn_octstring late_non_crit_ext; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SystemInformationBlockType3-NB-r13 ::= SEQUENCE struct sib_type3_nb_r13_s { struct cell_resel_info_common_r13_s_ { @@ -4975,6 +6217,10 @@ struct sib_type3_nb_r13_s { // group 4 bool npbch_rrm_cfg_r15_present = false; copy_ptr nsss_rrm_cfg_r15; + // group 5 + bool t_service_r17_present = false; + copy_ptr conn_meas_cfg_r17; + uint32_t t_service_r17 = 0; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -4982,19 +6228,13 @@ struct sib_type3_nb_r13_s { void to_json(json_writer& j) const; }; -// SystemInformationBlockType4-NB-r13 ::= SEQUENCE -struct sib_type4_nb_r13_s { - bool ext = false; - bool intra_freq_neigh_cell_list_r13_present = false; - bool intra_freq_black_cell_list_r13_present = false; - bool late_non_crit_ext_present = false; - intra_freq_neigh_cell_list_l intra_freq_neigh_cell_list_r13; - intra_freq_black_cell_list_l intra_freq_black_cell_list_r13; +// SystemInformationBlockType31-NB-r17 ::= SEQUENCE +struct sib_type31_nb_r17_s { + bool ext = false; + bool late_non_crit_ext_present = false; + serving_satellite_info_r17_s serving_satellite_info_r17; dyn_octstring late_non_crit_ext; // ... - // group 0 - copy_ptr nsss_rrm_cfg_r15; - copy_ptr intra_freq_neigh_cell_list_v1530; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -5002,11 +6242,46 @@ struct sib_type4_nb_r13_s { void to_json(json_writer& j) const; }; -// SystemInformationBlockType5-NB-r13 ::= SEQUENCE -struct sib_type5_nb_r13_s { - bool ext = false; - bool late_non_crit_ext_present = false; - inter_freq_carrier_freq_list_nb_r13_l inter_freq_carrier_freq_list_r13; +// SystemInformationBlockType32-NB-r17 ::= SEQUENCE +struct sib_type32_nb_r17_s { + bool ext = false; + bool satellite_info_list_r17_present = false; + bool late_non_crit_ext_present = false; + satellite_info_list_r17_l satellite_info_list_r17; + dyn_octstring late_non_crit_ext; + // ... + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SystemInformationBlockType4-NB-r13 ::= SEQUENCE +struct sib_type4_nb_r13_s { + bool ext = false; + bool intra_freq_neigh_cell_list_r13_present = false; + bool intra_freq_excluded_cell_list_r13_present = false; + bool late_non_crit_ext_present = false; + intra_freq_neigh_cell_list_l intra_freq_neigh_cell_list_r13; + intra_freq_excluded_cell_list_l intra_freq_excluded_cell_list_r13; + dyn_octstring late_non_crit_ext; + // ... + // group 0 + copy_ptr nsss_rrm_cfg_r15; + copy_ptr intra_freq_neigh_cell_list_v1530; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SystemInformationBlockType5-NB-r13 ::= SEQUENCE +struct sib_type5_nb_r13_s { + bool ext = false; + bool late_non_crit_ext_present = false; + inter_freq_carrier_freq_list_nb_r13_l inter_freq_carrier_freq_list_r13; t_resel_nb_r13_e t_resel_r13; dyn_octstring late_non_crit_ext; // ... @@ -5045,6 +6320,9 @@ struct sys_info_nb_r13_ies_s { sib20_v1430, sib22_v1430, sib23_v1530, + sib27_v1610, + sib31_v1700, + sib32_v1700, nulltype } value; typedef uint8_t number_type; @@ -5052,7 +6330,7 @@ struct sys_info_nb_r13_ies_s { const char* to_string() const; uint8_t to_number() const; }; - typedef enumerated types; + typedef enumerated types; // choice methods sib_type_and_info_r13_item_c_() = default; @@ -5115,6 +6393,21 @@ struct sys_info_nb_r13_ies_s { assert_choice_type(types::sib23_v1530, type_, "sib-TypeAndInfo-r13-item"); return c.get(); } + sib_type27_nb_r16_s& sib27_v1610() + { + assert_choice_type(types::sib27_v1610, type_, "sib-TypeAndInfo-r13-item"); + return c.get(); + } + sib_type31_nb_r17_s& sib31_v1700() + { + assert_choice_type(types::sib31_v1700, type_, "sib-TypeAndInfo-r13-item"); + return c.get(); + } + sib_type32_nb_r17_s& sib32_v1700() + { + assert_choice_type(types::sib32_v1700, type_, "sib-TypeAndInfo-r13-item"); + return c.get(); + } const sib_type2_nb_r13_s& sib2_r13() const { assert_choice_type(types::sib2_r13, type_, "sib-TypeAndInfo-r13-item"); @@ -5165,6 +6458,21 @@ struct sys_info_nb_r13_ies_s { assert_choice_type(types::sib23_v1530, type_, "sib-TypeAndInfo-r13-item"); return c.get(); } + const sib_type27_nb_r16_s& sib27_v1610() const + { + assert_choice_type(types::sib27_v1610, type_, "sib-TypeAndInfo-r13-item"); + return c.get(); + } + const sib_type31_nb_r17_s& sib31_v1700() const + { + assert_choice_type(types::sib31_v1700, type_, "sib-TypeAndInfo-r13-item"); + return c.get(); + } + const sib_type32_nb_r17_s& sib32_v1700() const + { + assert_choice_type(types::sib32_v1700, type_, "sib-TypeAndInfo-r13-item"); + return c.get(); + } sib_type2_nb_r13_s& set_sib2_r13(); sib_type3_nb_r13_s& set_sib3_r13(); sib_type4_nb_r13_s& set_sib4_r13(); @@ -5175,6 +6483,9 @@ struct sys_info_nb_r13_ies_s { sib_type20_nb_r14_s& set_sib20_v1430(); sib_type22_nb_r14_s& set_sib22_v1430(); sib_type23_nb_r15_s& set_sib23_v1530(); + sib_type27_nb_r16_s& set_sib27_v1610(); + sib_type31_nb_r17_s& set_sib31_v1700(); + sib_type32_nb_r17_s& set_sib32_v1700(); private: types type_; @@ -5184,7 +6495,10 @@ struct sys_info_nb_r13_ies_s { sib_type20_nb_r14_s, sib_type22_nb_r14_s, sib_type23_nb_r15_s, + sib_type27_nb_r16_s, sib_type2_nb_r13_s, + sib_type31_nb_r17_s, + sib_type32_nb_r17_s, sib_type3_nb_r13_s, sib_type4_nb_r13_s, sib_type5_nb_r13_s> @@ -5466,6 +6780,18 @@ struct bcch_dl_sch_msg_nb_s { void to_json(json_writer& j) const; }; +// RRCEarlyDataComplete-NB-v1700-IEs ::= SEQUENCE +struct rrc_early_data_complete_nb_v1700_ies_s { + bool cbp_idx_r17_present = false; + bool non_crit_ext_present = false; + uint8_t cbp_idx_r17 = 1; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionReestablishment-NB-v1430-IEs ::= SEQUENCE struct rrc_conn_reest_nb_v1430_ies_s { bool dl_nas_mac_present = false; @@ -5478,11 +6804,24 @@ struct rrc_conn_reest_nb_v1430_ies_s { void to_json(json_writer& j) const; }; +// RRCConnectionSetup-NB-v1610-IEs ::= SEQUENCE +struct rrc_conn_setup_nb_v1610_ies_s { + bool ded_info_nas_r16_present = false; + bool non_crit_ext_present = false; + dyn_octstring ded_info_nas_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCEarlyDataComplete-NB-v1590-IEs ::= SEQUENCE struct rrc_early_data_complete_nb_v1590_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - dyn_octstring late_non_crit_ext; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + dyn_octstring late_non_crit_ext; + rrc_early_data_complete_nb_v1700_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -5571,10 +6910,11 @@ struct rrc_conn_reject_nb_r13_ies_s { // RRCConnectionSetup-NB-r13-IEs ::= SEQUENCE struct rrc_conn_setup_nb_r13_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - rr_cfg_ded_nb_r13_s rr_cfg_ded_r13; - dyn_octstring late_non_crit_ext; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + rr_cfg_ded_nb_r13_s rr_cfg_ded_r13; + dyn_octstring late_non_crit_ext; + rrc_conn_setup_nb_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -6013,76 +7353,39 @@ struct dl_ccch_msg_nb_s { void to_json(json_writer& j) const; }; -// RRCConnectionRelease-NB-v15b0-IEs ::= SEQUENCE -struct rrc_conn_release_nb_v15b0_ies_s { - bool no_last_cell_upd_r15_present = false; - bool non_crit_ext_present = false; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - -// RedirectedCarrierInfo-NB-v1550 ::= CarrierFreq-NB-v1550 -using redirected_carrier_info_nb_v1550_s = carrier_freq_nb_v1550_s; - -// RRCConnectionRelease-NB-v1550-IEs ::= SEQUENCE -struct rrc_conn_release_nb_v1550_ies_s { - bool redirected_carrier_info_v1550_present = false; - bool non_crit_ext_present = false; - redirected_carrier_info_nb_v1550_s redirected_carrier_info_v1550; - rrc_conn_release_nb_v15b0_ies_s non_crit_ext; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - -// RRCConnectionRelease-NB-v1530-IEs ::= SEQUENCE -struct rrc_conn_release_nb_v1530_ies_s { - bool drb_continue_rohc_r15_present = false; - bool next_hop_chaining_count_r15_present = false; - bool non_crit_ext_present = false; - uint8_t next_hop_chaining_count_r15 = 0; - rrc_conn_release_nb_v1550_ies_s non_crit_ext; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - -// RRCConnectionRelease-NB-v1430-IEs ::= SEQUENCE -struct rrc_conn_release_nb_v1430_ies_s { - bool redirected_carrier_info_v1430_present = false; - bool extended_wait_time_cpdata_r14_present = false; - bool non_crit_ext_present = false; - redirected_carrier_info_nb_v1430_s redirected_carrier_info_v1430; - uint16_t extended_wait_time_cpdata_r14 = 1; - rrc_conn_release_nb_v1530_ies_s non_crit_ext; - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - -// ReleaseCause-NB-r13 ::= ENUMERATED -struct release_cause_nb_r13_opts { - enum options { load_balancing_ta_urequired, other, rrc_suspend, spare1, nulltype } value; +// NRSRP-ChangeThresh-NB-r16 ::= ENUMERATED +struct nrsrp_change_thresh_nb_r16_opts { + enum options { + db4, + db6, + db8, + db10, + db14, + db18, + db22, + db26, + db30, + db34, + spare6, + spare5, + spare4, + spare3, + spare2, + spare1, + nulltype + } value; + typedef uint8_t number_type; const char* to_string() const; + uint8_t to_number() const; }; -typedef enumerated release_cause_nb_r13_e; +typedef enumerated nrsrp_change_thresh_nb_r16_e; -// DLInformationTransfer-NB-r13-IEs ::= SEQUENCE -struct dl_info_transfer_nb_r13_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - dyn_octstring ded_info_nas_r13; - dyn_octstring late_non_crit_ext; +// PUR-NRSRP-ChangeThreshold-NB-r16 ::= SEQUENCE +struct pur_nrsrp_change_thres_nb_r16_s { + bool decrease_thresh_r16_present = false; + nrsrp_change_thresh_nb_r16_e increase_thresh_r16; + nrsrp_change_thresh_nb_r16_e decrease_thresh_r16; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -6090,55 +7393,173 @@ struct dl_info_transfer_nb_r13_ies_s { void to_json(json_writer& j) const; }; -// RRCConnectionReconfiguration-NB-r13-IEs ::= SEQUENCE -struct rrc_conn_recfg_nb_r13_ies_s { - using ded_info_nas_list_r13_l_ = bounded_array; +// PUR-PeriodicityAndOffset-NB-r16 ::= CHOICE +struct pur_periodicity_and_offset_nb_r16_c { + struct types_opts { + enum options { + periodicity8, + periodicity16, + periodicity32, + periodicity64, + periodicity128, + periodicity256, + periodicity512, + periodicity1024, + periodicity2048, + periodicity4096, + periodicity8192, + nulltype + } value; + typedef uint16_t number_type; - // member variables - bool ded_info_nas_list_r13_present = false; - bool rr_cfg_ded_r13_present = false; - bool full_cfg_r13_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - ded_info_nas_list_r13_l_ ded_info_nas_list_r13; - rr_cfg_ded_nb_r13_s rr_cfg_ded_r13; - dyn_octstring late_non_crit_ext; + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated types; - // sequence methods + // choice methods + pur_periodicity_and_offset_nb_r16_c() = default; + pur_periodicity_and_offset_nb_r16_c(const pur_periodicity_and_offset_nb_r16_c& other); + pur_periodicity_and_offset_nb_r16_c& operator=(const pur_periodicity_and_offset_nb_r16_c& other); + ~pur_periodicity_and_offset_nb_r16_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } SRSASN_CODE pack(bit_ref& bref) const; SRSASN_CODE unpack(cbit_ref& bref); void to_json(json_writer& j) const; -}; + // getters + uint8_t& periodicity8() + { + assert_choice_type(types::periodicity8, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + uint8_t& periodicity16() + { + assert_choice_type(types::periodicity16, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + uint8_t& periodicity32() + { + assert_choice_type(types::periodicity32, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + uint8_t& periodicity64() + { + assert_choice_type(types::periodicity64, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + uint8_t& periodicity128() + { + assert_choice_type(types::periodicity128, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + uint16_t& periodicity256() + { + assert_choice_type(types::periodicity256, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + uint16_t& periodicity512() + { + assert_choice_type(types::periodicity512, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + uint16_t& periodicity1024() + { + assert_choice_type(types::periodicity1024, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + uint16_t& periodicity2048() + { + assert_choice_type(types::periodicity2048, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + uint16_t& periodicity4096() + { + assert_choice_type(types::periodicity4096, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + uint16_t& periodicity8192() + { + assert_choice_type(types::periodicity8192, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + const uint8_t& periodicity8() const + { + assert_choice_type(types::periodicity8, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + const uint8_t& periodicity16() const + { + assert_choice_type(types::periodicity16, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + const uint8_t& periodicity32() const + { + assert_choice_type(types::periodicity32, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + const uint8_t& periodicity64() const + { + assert_choice_type(types::periodicity64, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + const uint8_t& periodicity128() const + { + assert_choice_type(types::periodicity128, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + const uint16_t& periodicity256() const + { + assert_choice_type(types::periodicity256, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + const uint16_t& periodicity512() const + { + assert_choice_type(types::periodicity512, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + const uint16_t& periodicity1024() const + { + assert_choice_type(types::periodicity1024, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + const uint16_t& periodicity2048() const + { + assert_choice_type(types::periodicity2048, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + const uint16_t& periodicity4096() const + { + assert_choice_type(types::periodicity4096, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + const uint16_t& periodicity8192() const + { + assert_choice_type(types::periodicity8192, type_, "PUR-PeriodicityAndOffset-NB-r16"); + return c.get(); + } + uint8_t& set_periodicity8(); + uint8_t& set_periodicity16(); + uint8_t& set_periodicity32(); + uint8_t& set_periodicity64(); + uint8_t& set_periodicity128(); + uint16_t& set_periodicity256(); + uint16_t& set_periodicity512(); + uint16_t& set_periodicity1024(); + uint16_t& set_periodicity2048(); + uint16_t& set_periodicity4096(); + uint16_t& set_periodicity8192(); -// RRCConnectionRelease-NB-r13-IEs ::= SEQUENCE -struct rrc_conn_release_nb_r13_ies_s { - bool resume_id_r13_present = false; - bool extended_wait_time_r13_present = false; - bool redirected_carrier_info_r13_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - release_cause_nb_r13_e release_cause_r13; - fixed_bitstring<40> resume_id_r13; - uint16_t extended_wait_time_r13 = 1; - redirected_carrier_info_nb_r13_s redirected_carrier_info_r13; - dyn_octstring late_non_crit_ext; - rrc_conn_release_nb_v1430_ies_s non_crit_ext; +private: + types type_; + pod_choice_buffer_t c; - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; + void destroy_(); }; -// RRCConnectionResume-NB-r13-IEs ::= SEQUENCE -struct rrc_conn_resume_nb_r13_ies_s { - bool rr_cfg_ded_r13_present = false; - bool drb_continue_rohc_r13_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - rr_cfg_ded_nb_r13_s rr_cfg_ded_r13; - uint8_t next_hop_chaining_count_r13 = 0; - dyn_octstring late_non_crit_ext; +// PUR-UL-16QAM-Config-NB-r17 ::= SEQUENCE +struct pur_ul_minus16_qam_cfg_nb_r17_s { + ul_pwr_ctrl_ded_nb_v1700_s ul_pwr_ctrl_ded_r17; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -6146,24 +7567,416 @@ struct rrc_conn_resume_nb_r13_ies_s { void to_json(json_writer& j) const; }; -// UECapabilityEnquiry-NB-r13-IEs ::= SEQUENCE -struct ue_cap_enquiry_nb_r13_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - dyn_octstring late_non_crit_ext; +// PUR-Config-NB-r16 ::= SEQUENCE +struct pur_cfg_nb_r16_s { + struct pur_implicit_release_after_r16_opts { + enum options { n2, n4, n8, spare, nulltype } value; + typedef uint8_t number_type; - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated pur_implicit_release_after_r16_e_; + struct pur_resp_win_timer_r16_opts { + enum options { pp1, pp2, pp3, pp4, pp8, pp16, pp32, pp64, nulltype } value; + typedef uint8_t number_type; -// DLInformationTransfer-NB ::= SEQUENCE -struct dl_info_transfer_nb_s { - struct crit_exts_c_ { - struct c1_c_ { + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated pur_resp_win_timer_r16_e_; + struct pur_start_time_params_r16_s_ { + pur_periodicity_and_offset_nb_r16_c periodicity_and_offset_r16; + uint16_t start_sfn_r16 = 0; + uint8_t start_sf_r16 = 0; + fixed_bitstring<1> hsfn_lsb_info_r16; + }; + struct pur_num_occasions_r16_opts { + enum options { one, infinite, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated pur_num_occasions_r16_e_; + struct pur_phys_cfg_r16_s_ { + struct npusch_sub_carrier_set_idx_r16_c_ { struct types_opts { - enum options { dl_info_transfer_r13, spare1, nulltype } value; + enum options { khz15, khz3dot75, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated types; + + // choice methods + npusch_sub_carrier_set_idx_r16_c_() = default; + npusch_sub_carrier_set_idx_r16_c_(const npusch_sub_carrier_set_idx_r16_c_& other); + npusch_sub_carrier_set_idx_r16_c_& operator=(const npusch_sub_carrier_set_idx_r16_c_& other); + ~npusch_sub_carrier_set_idx_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint8_t& khz15() + { + assert_choice_type(types::khz15, type_, "npusch-SubCarrierSetIndex-r16"); + return c.get(); + } + uint8_t& khz3dot75() + { + assert_choice_type(types::khz3dot75, type_, "npusch-SubCarrierSetIndex-r16"); + return c.get(); + } + const uint8_t& khz15() const + { + assert_choice_type(types::khz15, type_, "npusch-SubCarrierSetIndex-r16"); + return c.get(); + } + const uint8_t& khz3dot75() const + { + assert_choice_type(types::khz3dot75, type_, "npusch-SubCarrierSetIndex-r16"); + return c.get(); + } + uint8_t& set_khz15(); + uint8_t& set_khz3dot75(); + + private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); + }; + struct npusch_mcs_r16_c_ { + struct types_opts { + enum options { single_tone, multi_tone, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + npusch_mcs_r16_c_() = default; + npusch_mcs_r16_c_(const npusch_mcs_r16_c_& other); + npusch_mcs_r16_c_& operator=(const npusch_mcs_r16_c_& other); + ~npusch_mcs_r16_c_() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + uint8_t& single_tone() + { + assert_choice_type(types::single_tone, type_, "npusch-MCS-r16"); + return c.get(); + } + uint8_t& multi_tone() + { + assert_choice_type(types::multi_tone, type_, "npusch-MCS-r16"); + return c.get(); + } + const uint8_t& single_tone() const + { + assert_choice_type(types::single_tone, type_, "npusch-MCS-r16"); + return c.get(); + } + const uint8_t& multi_tone() const + { + assert_choice_type(types::multi_tone, type_, "npusch-MCS-r16"); + return c.get(); + } + uint8_t& set_single_tone(); + uint8_t& set_multi_tone(); + + private: + types type_; + pod_choice_buffer_t c; + + void destroy_(); + }; + struct alpha_r16_opts { + enum options { al0, al04, al05, al06, al07, al08, al09, al1, nulltype } value; + typedef float number_type; + + const char* to_string() const; + float to_number() const; + const char* to_number_string() const; + }; + typedef enumerated alpha_r16_e_; + struct npusch_cyclic_shift_r16_opts { + enum options { n0, n6, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated npusch_cyclic_shift_r16_e_; + + // member variables + carrier_cfg_ded_nb_r13_s carrier_cfg_r16; + uint8_t npusch_num_rus_idx_r16 = 0; + uint8_t npusch_num_repeats_idx_r16 = 0; + npusch_sub_carrier_set_idx_r16_c_ npusch_sub_carrier_set_idx_r16; + npusch_mcs_r16_c_ npusch_mcs_r16; + int8_t p0_ue_npusch_r16 = -8; + alpha_r16_e_ alpha_r16; + npusch_cyclic_shift_r16_e_ npusch_cyclic_shift_r16; + npdcch_cfg_ded_nb_r13_s npdcch_cfg_r16; + }; + struct pur_phys_cfg_v1650_s_ { + ack_nack_num_repeats_nb_r13_e ack_nack_num_repeats_r16; + }; + struct pur_phys_cfg_v1700_s_ { + bool pur_ul_minus16_qam_cfg_r17_present = false; + bool pur_dl_minus16_qam_cfg_r17_present = false; + setup_release_c pur_ul_minus16_qam_cfg_r17; + setup_release_c pur_dl_minus16_qam_cfg_r17; + }; + + // member variables + bool ext = false; + bool pur_cfg_id_r16_present = false; + bool pur_time_align_timer_r16_present = false; + bool pur_nrsrp_change_thres_r16_present = false; + bool pur_implicit_release_after_r16_present = false; + bool pur_rnti_r16_present = false; + bool pur_resp_win_timer_r16_present = false; + bool pur_start_time_params_r16_present = false; + bool pur_phys_cfg_r16_present = false; + fixed_bitstring<20> pur_cfg_id_r16; + uint8_t pur_time_align_timer_r16 = 1; + setup_release_c pur_nrsrp_change_thres_r16; + pur_implicit_release_after_r16_e_ pur_implicit_release_after_r16; + fixed_bitstring<16> pur_rnti_r16; + pur_resp_win_timer_r16_e_ pur_resp_win_timer_r16; + pur_start_time_params_r16_s_ pur_start_time_params_r16; + pur_num_occasions_r16_e_ pur_num_occasions_r16; + pur_phys_cfg_r16_s_ pur_phys_cfg_r16; + // ... + // group 0 + copy_ptr pur_phys_cfg_v1650; + // group 1 + copy_ptr pur_phys_cfg_v1700; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionRelease-NB-v1700-IEs ::= SEQUENCE +struct rrc_conn_release_nb_v1700_ies_s { + bool cbp_idx_r17_present = false; + bool non_crit_ext_present = false; + uint8_t cbp_idx_r17 = 1; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionRelease-NB-v1610-IEs ::= SEQUENCE +struct rrc_conn_release_nb_v1610_ies_s { + bool resume_id_r16_present = false; + bool anr_meas_cfg_r16_present = false; + bool pur_cfg_r16_present = false; + bool non_crit_ext_present = false; + fixed_bitstring<40> resume_id_r16; + anr_meas_cfg_nb_r16_s anr_meas_cfg_r16; + setup_release_c pur_cfg_r16; + rrc_conn_release_nb_v1700_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionRelease-NB-v15b0-IEs ::= SEQUENCE +struct rrc_conn_release_nb_v15b0_ies_s { + bool no_last_cell_upd_r15_present = false; + bool non_crit_ext_present = false; + rrc_conn_release_nb_v1610_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RedirectedCarrierInfo-NB-v1550 ::= CarrierFreq-NB-v1550 +using redirected_carrier_info_nb_v1550_s = carrier_freq_nb_v1550_s; + +// RRCConnectionRelease-NB-v1550-IEs ::= SEQUENCE +struct rrc_conn_release_nb_v1550_ies_s { + bool redirected_carrier_info_v1550_present = false; + bool non_crit_ext_present = false; + redirected_carrier_info_nb_v1550_s redirected_carrier_info_v1550; + rrc_conn_release_nb_v15b0_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionRelease-NB-v1530-IEs ::= SEQUENCE +struct rrc_conn_release_nb_v1530_ies_s { + bool drb_continue_rohc_r15_present = false; + bool next_hop_chaining_count_r15_present = false; + bool non_crit_ext_present = false; + uint8_t next_hop_chaining_count_r15 = 0; + rrc_conn_release_nb_v1550_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionRelease-NB-v1430-IEs ::= SEQUENCE +struct rrc_conn_release_nb_v1430_ies_s { + bool redirected_carrier_info_v1430_present = false; + bool extended_wait_time_cpdata_r14_present = false; + bool non_crit_ext_present = false; + redirected_carrier_info_nb_v1430_s redirected_carrier_info_v1430; + uint16_t extended_wait_time_cpdata_r14 = 1; + rrc_conn_release_nb_v1530_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionResume-NB-v1610-IEs ::= SEQUENCE +struct rrc_conn_resume_nb_v1610_ies_s { + bool full_cfg_r16_present = false; + bool non_crit_ext_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ReleaseCause-NB-r13 ::= ENUMERATED +struct release_cause_nb_r13_opts { + enum options { load_balancing_ta_urequired, other, rrc_suspend, spare1, nulltype } value; + + const char* to_string() const; +}; +typedef enumerated release_cause_nb_r13_e; + +// DLInformationTransfer-NB-r13-IEs ::= SEQUENCE +struct dl_info_transfer_nb_r13_ies_s { + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + dyn_octstring ded_info_nas_r13; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionReconfiguration-NB-r13-IEs ::= SEQUENCE +struct rrc_conn_recfg_nb_r13_ies_s { + using ded_info_nas_list_r13_l_ = bounded_array; + + // member variables + bool ded_info_nas_list_r13_present = false; + bool rr_cfg_ded_r13_present = false; + bool full_cfg_r13_present = false; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + ded_info_nas_list_r13_l_ ded_info_nas_list_r13; + rr_cfg_ded_nb_r13_s rr_cfg_ded_r13; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionRelease-NB-r13-IEs ::= SEQUENCE +struct rrc_conn_release_nb_r13_ies_s { + bool resume_id_r13_present = false; + bool extended_wait_time_r13_present = false; + bool redirected_carrier_info_r13_present = false; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + release_cause_nb_r13_e release_cause_r13; + fixed_bitstring<40> resume_id_r13; + uint16_t extended_wait_time_r13 = 1; + redirected_carrier_info_nb_r13_s redirected_carrier_info_r13; + dyn_octstring late_non_crit_ext; + rrc_conn_release_nb_v1430_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionResume-NB-r13-IEs ::= SEQUENCE +struct rrc_conn_resume_nb_r13_ies_s { + bool rr_cfg_ded_r13_present = false; + bool drb_continue_rohc_r13_present = false; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + rr_cfg_ded_nb_r13_s rr_cfg_ded_r13; + uint8_t next_hop_chaining_count_r13 = 0; + dyn_octstring late_non_crit_ext; + rrc_conn_resume_nb_v1610_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UECapabilityEnquiry-NB-r13-IEs ::= SEQUENCE +struct ue_cap_enquiry_nb_r13_ies_s { + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEInformationRequest-NB-r16-IEs ::= SEQUENCE +struct ue_info_request_nb_r16_ies_s { + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + bool rach_report_req_r16 = false; + bool rlf_report_req_r16 = false; + bool anr_report_req_r16 = false; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// DLInformationTransfer-NB ::= SEQUENCE +struct dl_info_transfer_nb_s { + struct crit_exts_c_ { + struct c1_c_ { + struct types_opts { + enum options { dl_info_transfer_r13, spare1, nulltype } value; const char* to_string() const; }; @@ -6528,6 +8341,52 @@ struct ue_cap_enquiry_nb_s { void to_json(json_writer& j) const; }; +// UEInformationRequest-NB-r16 ::= SEQUENCE +struct ue_info_request_nb_r16_s { + struct crit_exts_c_ { + struct types_opts { + enum options { ue_info_request_r16, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + crit_exts_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ue_info_request_nb_r16_ies_s& ue_info_request_r16() + { + assert_choice_type(types::ue_info_request_r16, type_, "criticalExtensions"); + return c; + } + const ue_info_request_nb_r16_ies_s& ue_info_request_r16() const + { + assert_choice_type(types::ue_info_request_r16, type_, "criticalExtensions"); + return c; + } + ue_info_request_nb_r16_ies_s& set_ue_info_request_r16(); + void set_crit_exts_future(); + + private: + types type_; + ue_info_request_nb_r16_ies_s c; + }; + + // member variables + uint8_t rrc_transaction_id = 0; + crit_exts_c_ crit_exts; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // DL-DCCH-MessageType-NB ::= CHOICE struct dl_dcch_msg_type_nb_c { struct c1_c_ { @@ -6539,7 +8398,7 @@ struct dl_dcch_msg_type_nb_c { security_mode_cmd_r13, ue_cap_enquiry_r13, rrc_conn_resume_r13, - spare2, + ue_info_request_r16, spare1, nulltype } value; @@ -6589,6 +8448,11 @@ struct dl_dcch_msg_type_nb_c { assert_choice_type(types::rrc_conn_resume_r13, type_, "c1"); return c.get(); } + ue_info_request_nb_r16_s& ue_info_request_r16() + { + assert_choice_type(types::ue_info_request_r16, type_, "c1"); + return c.get(); + } const dl_info_transfer_nb_s& dl_info_transfer_r13() const { assert_choice_type(types::dl_info_transfer_r13, type_, "c1"); @@ -6619,14 +8483,19 @@ struct dl_dcch_msg_type_nb_c { assert_choice_type(types::rrc_conn_resume_r13, type_, "c1"); return c.get(); } - dl_info_transfer_nb_s& set_dl_info_transfer_r13(); - rrc_conn_recfg_nb_s& set_rrc_conn_recfg_r13(); - rrc_conn_release_nb_s& set_rrc_conn_release_r13(); - security_mode_cmd_s& set_security_mode_cmd_r13(); - ue_cap_enquiry_nb_s& set_ue_cap_enquiry_r13(); - rrc_conn_resume_nb_s& set_rrc_conn_resume_r13(); - void set_spare2(); - void set_spare1(); + const ue_info_request_nb_r16_s& ue_info_request_r16() const + { + assert_choice_type(types::ue_info_request_r16, type_, "c1"); + return c.get(); + } + dl_info_transfer_nb_s& set_dl_info_transfer_r13(); + rrc_conn_recfg_nb_s& set_rrc_conn_recfg_r13(); + rrc_conn_release_nb_s& set_rrc_conn_release_r13(); + security_mode_cmd_s& set_security_mode_cmd_r13(); + ue_cap_enquiry_nb_s& set_ue_cap_enquiry_r13(); + rrc_conn_resume_nb_s& set_rrc_conn_resume_r13(); + ue_info_request_nb_r16_s& set_ue_info_request_r16(); + void set_spare1(); private: types type_; @@ -6635,7 +8504,8 @@ struct dl_dcch_msg_type_nb_c { rrc_conn_release_nb_s, rrc_conn_resume_nb_s, security_mode_cmd_s, - ue_cap_enquiry_nb_s> + ue_cap_enquiry_nb_s, + ue_info_request_nb_r16_s> c; void destroy_(); @@ -6701,7 +8571,7 @@ using supported_band_list_nb_r13_l = dyn_array; // AccessStratumRelease-NB-r13 ::= ENUMERATED struct access_stratum_release_nb_r13_opts { - enum options { rel13, rel14, rel15, spare5, spare4, spare3, spare2, spare1, /*...*/ nulltype } value; + enum options { rel13, rel14, rel15, rel16, rel17, spare3, spare2, spare1, /*...*/ nulltype } value; typedef uint8_t number_type; const char* to_string() const; @@ -6985,10 +8855,61 @@ struct ho_prep_info_nb_s { void to_json(json_writer& j) const; }; -// MeasResultServCell-NB-r14 ::= SEQUENCE -struct meas_result_serv_cell_nb_r14_s { - uint8_t nrsrp_result_r14 = 0; - int8_t nrsrq_result_r14 = -30; +// InitialUE-Identity-5GC-NB-r16 ::= CHOICE +struct init_ue_id_minus5_gc_nb_r16_c { + struct types_opts { + enum options { ng_minus5_g_s_tmsi_r16, random_value, nulltype } value; + typedef int8_t number_type; + + const char* to_string() const; + int8_t to_number() const; + }; + typedef enumerated types; + + // choice methods + init_ue_id_minus5_gc_nb_r16_c() = default; + init_ue_id_minus5_gc_nb_r16_c(const init_ue_id_minus5_gc_nb_r16_c& other); + init_ue_id_minus5_gc_nb_r16_c& operator=(const init_ue_id_minus5_gc_nb_r16_c& other); + ~init_ue_id_minus5_gc_nb_r16_c() { destroy_(); } + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + fixed_bitstring<48>& ng_minus5_g_s_tmsi_r16() + { + assert_choice_type(types::ng_minus5_g_s_tmsi_r16, type_, "InitialUE-Identity-5GC-NB-r16"); + return c.get >(); + } + fixed_bitstring<48>& random_value() + { + assert_choice_type(types::random_value, type_, "InitialUE-Identity-5GC-NB-r16"); + return c.get >(); + } + const fixed_bitstring<48>& ng_minus5_g_s_tmsi_r16() const + { + assert_choice_type(types::ng_minus5_g_s_tmsi_r16, type_, "InitialUE-Identity-5GC-NB-r16"); + return c.get >(); + } + const fixed_bitstring<48>& random_value() const + { + assert_choice_type(types::random_value, type_, "InitialUE-Identity-5GC-NB-r16"); + return c.get >(); + } + fixed_bitstring<48>& set_ng_minus5_g_s_tmsi_r16(); + fixed_bitstring<48>& set_random_value(); + +private: + types type_; + choice_buffer_t > c; + + void destroy_(); +}; + +// PagingRecord-NB-v1610 ::= SEQUENCE +struct paging_record_nb_v1610_s { + bool mt_edt_r16_present = false; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -7008,6 +8929,21 @@ struct paging_record_nb_r13_s { void to_json(json_writer& j) const; }; +// PagingRecordList-NB-v1610 ::= SEQUENCE (SIZE (1..16)) OF PagingRecord-NB-v1610 +using paging_record_list_nb_v1610_l = dyn_array; + +// Paging-NB-v1610-IEs ::= SEQUENCE +struct paging_nb_v1610_ies_s { + bool paging_record_list_v1610_present = false; + bool non_crit_ext_present = false; + paging_record_list_nb_v1610_l paging_record_list_v1610; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // PagingRecordList-NB-r13 ::= SEQUENCE (SIZE (1..16)) OF PagingRecord-NB-r13 using paging_record_list_nb_r13_l = dyn_array; @@ -7018,6 +8954,7 @@ struct paging_nb_s { bool sys_info_mod_e_drx_r13_present = false; bool non_crit_ext_present = false; paging_record_list_nb_r13_l paging_record_list_r13; + paging_nb_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -7092,11 +9029,187 @@ struct pcch_msg_nb_s { void to_json(json_writer& j) const; }; -// PCI-ARFCN-NB-r14 ::= SEQUENCE -struct pci_arfcn_nb_r14_s { - bool carrier_freq_r14_present = false; - uint16_t pci_r14 = 0; - carrier_freq_nb_r13_s carrier_freq_r14; +// PCI-ARFCN-NB-r14 ::= SEQUENCE +struct pci_arfcn_nb_r14_s { + bool carrier_freq_r14_present = false; + uint16_t pci_r14 = 0; + carrier_freq_nb_r13_s carrier_freq_r14; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PUR-ConfigRequest-NB-r16 ::= CHOICE +struct pur_cfg_request_nb_r16_c { + struct pur_setup_request_s_ { + struct requested_num_occasions_r16_opts { + enum options { one, infinite, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated requested_num_occasions_r16_e_; + struct requested_tbs_r16_opts { + enum options { + b328, + b376, + b424, + b472, + b504, + b552, + b584, + b616, + b680, + b744, + b776, + b808, + b872, + b904, + b936, + b968, + b1000, + b1032, + b1096, + b1128, + b1192, + b1224, + b1256, + b1352, + b1384, + b1544, + b1608, + b1736, + b1800, + b2024, + b2280, + b2536, + nulltype + } value; + typedef uint16_t number_type; + + const char* to_string() const; + uint16_t to_number() const; + }; + typedef enumerated requested_tbs_r16_e_; + + // member variables + bool rrc_ack_r16_present = false; + requested_num_occasions_r16_e_ requested_num_occasions_r16; + pur_periodicity_and_offset_nb_r16_c requested_periodicity_and_offset_r16; + requested_tbs_r16_e_ requested_tbs_r16; + }; + struct types_opts { + enum options { pur_release_request, pur_setup_request, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + pur_cfg_request_nb_r16_c() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + pur_setup_request_s_& pur_setup_request() + { + assert_choice_type(types::pur_setup_request, type_, "PUR-ConfigRequest-NB-r16"); + return c; + } + const pur_setup_request_s_& pur_setup_request() const + { + assert_choice_type(types::pur_setup_request, type_, "PUR-ConfigRequest-NB-r16"); + return c; + } + void set_pur_release_request(); + pur_setup_request_s_& set_pur_setup_request(); + +private: + types type_; + pur_setup_request_s_ c; +}; + +// PURConfigurationRequest-NB-r16-IEs ::= SEQUENCE +struct pur_cfg_request_nb_r16_ies_s { + bool pur_cfg_request_r16_present = false; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + pur_cfg_request_nb_r16_c pur_cfg_request_r16; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PURConfigurationRequest-NB-r16 ::= SEQUENCE +struct pur_cfg_request_nb_r16_s { + struct crit_exts_c_ { + struct types_opts { + enum options { pur_cfg_request_r16, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + crit_exts_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + pur_cfg_request_nb_r16_ies_s& pur_cfg_request_r16() + { + assert_choice_type(types::pur_cfg_request_r16, type_, "criticalExtensions"); + return c; + } + const pur_cfg_request_nb_r16_ies_s& pur_cfg_request_r16() const + { + assert_choice_type(types::pur_cfg_request_r16, type_, "criticalExtensions"); + return c; + } + pur_cfg_request_nb_r16_ies_s& set_pur_cfg_request_r16(); + void set_crit_exts_future(); + + private: + types type_; + pur_cfg_request_nb_r16_ies_s c; + }; + + // member variables + crit_exts_c_ crit_exts; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SupportedBand-NB-v1710 ::= SEQUENCE +struct supported_band_nb_v1710_s { + bool npusch_minus16_qam_r17_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SupportedBandList-NB-v1710 ::= SEQUENCE (SIZE (1..64)) OF SupportedBand-NB-v1710 +using supported_band_list_nb_v1710_l = dyn_array; + +// RF-Parameters-NB-v1710 ::= SEQUENCE +struct rf_params_nb_v1710_s { + bool supported_band_list_v1710_present = false; + supported_band_list_nb_v1710_l supported_band_list_v1710; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -7162,11 +9275,37 @@ struct rrc_conn_recfg_complete_nb_s { void to_json(json_writer& j) const; }; +// RRCConnectionReestablishmentComplete-NB-v1710-IEs ::= SEQUENCE +struct rrc_conn_reest_complete_nb_v1710_ies_s { + bool gnss_validity_dur_r17_present = false; + bool non_crit_ext_present = false; + gnss_validity_dur_r17_e gnss_validity_dur_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionReestablishmentComplete-NB-v1610-IEs ::= SEQUENCE +struct rrc_conn_reest_complete_nb_v1610_ies_s { + bool rlf_info_available_r16_present = false; + bool anr_info_available_r16_present = false; + bool non_crit_ext_present = false; + rrc_conn_reest_complete_nb_v1710_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionReestablishmentComplete-NB-v1470-IEs ::= SEQUENCE struct rrc_conn_reest_complete_nb_v1470_ies_s { - bool meas_result_serv_cell_r14_present = false; - bool non_crit_ext_present = false; - meas_result_serv_cell_nb_r14_s meas_result_serv_cell_r14; + bool meas_result_serv_cell_r14_present = false; + bool non_crit_ext_present = false; + meas_result_serv_cell_nb_r14_s meas_result_serv_cell_r14; + rrc_conn_reest_complete_nb_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -7233,6 +9372,49 @@ struct rrc_conn_reest_complete_nb_s { void to_json(json_writer& j) const; }; +// CQI-NPDCCH-Short-NB-r14 ::= ENUMERATED +struct cqi_npdcch_short_nb_r14_opts { + enum options { no_meass, candidate_rep_minus1, candidate_rep_minus2, candidate_rep_minus3, nulltype } value; + typedef int8_t number_type; + + const char* to_string() const; + int8_t to_number() const; +}; +typedef enumerated cqi_npdcch_short_nb_r14_e; + +// ReestabUE-Identity-CP-5GC-NB-r16 ::= SEQUENCE +struct reestab_ue_id_cp_minus5_gc_nb_r16_s { + fixed_bitstring<40> truncated5_g_s_tmsi_r16; + fixed_bitstring<16> ul_nas_mac_r16; + fixed_bitstring<5> ul_nas_count_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// ReestablishmentCause-NB-r13 ::= ENUMERATED +struct reest_cause_nb_r13_opts { + enum options { recfg_fail, other_fail, spare2, spare1, nulltype } value; + + const char* to_string() const; +}; +typedef enumerated reest_cause_nb_r13_e; + +// RRCConnectionReestablishmentRequest-5GC-NB-r16-IEs ::= SEQUENCE +struct rrc_conn_reest_request_minus5_gc_nb_r16_ies_s { + reestab_ue_id_cp_minus5_gc_nb_r16_s ue_id_r16; + reest_cause_nb_r13_e reest_cause_r16; + cqi_npdcch_short_nb_r14_e cqi_npdcch_r16; + fixed_bitstring<1> spare; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // CQI-NPDCCH-NB-r14 ::= ENUMERATED struct cqi_npdcch_nb_r14_opts { enum options { @@ -7256,16 +9438,6 @@ struct cqi_npdcch_nb_r14_opts { }; typedef enumerated cqi_npdcch_nb_r14_e; -// CQI-NPDCCH-Short-NB-r14 ::= ENUMERATED -struct cqi_npdcch_short_nb_r14_opts { - enum options { no_meass, candidate_rep_minus1, candidate_rep_minus2, candidate_rep_minus3, nulltype } value; - typedef int8_t number_type; - - const char* to_string() const; - int8_t to_number() const; -}; -typedef enumerated cqi_npdcch_short_nb_r14_e; - // ReestabUE-Identity-CP-NB-r14 ::= SEQUENCE struct reestab_ue_id_cp_nb_r14_s { s_tmsi_s s_tmsi_r14; @@ -7278,14 +9450,6 @@ struct reestab_ue_id_cp_nb_r14_s { void to_json(json_writer& j) const; }; -// ReestablishmentCause-NB-r13 ::= ENUMERATED -struct reest_cause_nb_r13_opts { - enum options { recfg_fail, other_fail, spare2, spare1, nulltype } value; - - const char* to_string() const; -}; -typedef enumerated reest_cause_nb_r13_e; - // RRCConnectionReestablishmentRequest-NB-r13-IEs ::= SEQUENCE struct rrc_conn_reest_request_nb_r13_ies_s { reestab_ue_id_s ue_id_r13; @@ -7318,8 +9482,41 @@ struct rrc_conn_reest_request_nb_r14_ies_s { struct rrc_conn_reest_request_nb_s { struct crit_exts_c_ { struct later_c_ { + struct later_c__ { + struct types_opts { + enum options { rrc_conn_reest_request_r16, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + later_c__() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + rrc_conn_reest_request_minus5_gc_nb_r16_ies_s& rrc_conn_reest_request_r16() + { + assert_choice_type(types::rrc_conn_reest_request_r16, type_, "later"); + return c; + } + const rrc_conn_reest_request_minus5_gc_nb_r16_ies_s& rrc_conn_reest_request_r16() const + { + assert_choice_type(types::rrc_conn_reest_request_r16, type_, "later"); + return c; + } + rrc_conn_reest_request_minus5_gc_nb_r16_ies_s& set_rrc_conn_reest_request_r16(); + void set_crit_exts_future(); + + private: + types type_; + rrc_conn_reest_request_minus5_gc_nb_r16_ies_s c; + }; struct types_opts { - enum options { rrc_conn_reest_request_r14, crit_exts_future, nulltype } value; + enum options { rrc_conn_reest_request_r14, later, nulltype } value; const char* to_string() const; }; @@ -7327,6 +9524,9 @@ struct rrc_conn_reest_request_nb_s { // choice methods later_c_() = default; + later_c_(const later_c_& other); + later_c_& operator=(const later_c_& other); + ~later_c_() { destroy_(); } void set(types::options e = types::nulltype); types type() const { return type_; } SRSASN_CODE pack(bit_ref& bref) const; @@ -7336,19 +9536,31 @@ struct rrc_conn_reest_request_nb_s { rrc_conn_reest_request_nb_r14_ies_s& rrc_conn_reest_request_r14() { assert_choice_type(types::rrc_conn_reest_request_r14, type_, "later"); - return c; + return c.get(); + } + later_c__& later() + { + assert_choice_type(types::later, type_, "later"); + return c.get(); } const rrc_conn_reest_request_nb_r14_ies_s& rrc_conn_reest_request_r14() const { assert_choice_type(types::rrc_conn_reest_request_r14, type_, "later"); - return c; + return c.get(); + } + const later_c__& later() const + { + assert_choice_type(types::later, type_, "later"); + return c.get(); } rrc_conn_reest_request_nb_r14_ies_s& set_rrc_conn_reest_request_r14(); - void set_crit_exts_future(); + later_c__& set_later(); private: - types type_; - rrc_conn_reest_request_nb_r14_ies_s c; + types type_; + choice_buffer_t c; + + void destroy_(); }; struct types_opts { enum options { rrc_conn_reest_request_r13, later, nulltype } value; @@ -7407,6 +9619,27 @@ struct rrc_conn_reest_request_nb_s { void to_json(json_writer& j) const; }; +// RRCConnectionRequest-5GC-NB-r16-IEs ::= SEQUENCE +struct rrc_conn_request_minus5_gc_nb_r16_ies_s { + struct establishment_cause_r16_opts { + enum options { mt_access, mo_sig, mo_data, mo_exception_data, spare4, spare3, spare2, spare1, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated establishment_cause_r16_e_; + + // member variables + init_ue_id_minus5_gc_nb_r16_c ue_id_r16; + establishment_cause_r16_e_ establishment_cause_r16; + cqi_npdcch_nb_r14_e cqi_npdcch_r16; + fixed_bitstring<11> spare; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // EstablishmentCause-NB-r13 ::= ENUMERATED struct establishment_cause_nb_r13_opts { enum options { @@ -7415,7 +9648,7 @@ struct establishment_cause_nb_r13_opts { mo_data, mo_exception_data, delay_tolerant_access_v1330, - spare3, + mt_edt_v1610, spare2, spare1, nulltype @@ -7444,8 +9677,41 @@ struct rrc_conn_request_nb_r13_ies_s { // RRCConnectionRequest-NB ::= SEQUENCE struct rrc_conn_request_nb_s { struct crit_exts_c_ { + struct later_c_ { + struct types_opts { + enum options { rrc_conn_request_r16, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + later_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + rrc_conn_request_minus5_gc_nb_r16_ies_s& rrc_conn_request_r16() + { + assert_choice_type(types::rrc_conn_request_r16, type_, "later"); + return c; + } + const rrc_conn_request_minus5_gc_nb_r16_ies_s& rrc_conn_request_r16() const + { + assert_choice_type(types::rrc_conn_request_r16, type_, "later"); + return c; + } + rrc_conn_request_minus5_gc_nb_r16_ies_s& set_rrc_conn_request_r16(); + void set_crit_exts_future(); + + private: + types type_; + rrc_conn_request_minus5_gc_nb_r16_ies_s c; + }; struct types_opts { - enum options { rrc_conn_request_r13, crit_exts_future, nulltype } value; + enum options { rrc_conn_request_r13, later, nulltype } value; const char* to_string() const; }; @@ -7453,6 +9719,9 @@ struct rrc_conn_request_nb_s { // choice methods crit_exts_c_() = default; + crit_exts_c_(const crit_exts_c_& other); + crit_exts_c_& operator=(const crit_exts_c_& other); + ~crit_exts_c_() { destroy_(); } void set(types::options e = types::nulltype); types type() const { return type_; } SRSASN_CODE pack(bit_ref& bref) const; @@ -7462,19 +9731,31 @@ struct rrc_conn_request_nb_s { rrc_conn_request_nb_r13_ies_s& rrc_conn_request_r13() { assert_choice_type(types::rrc_conn_request_r13, type_, "criticalExtensions"); - return c; + return c.get(); + } + later_c_& later() + { + assert_choice_type(types::later, type_, "criticalExtensions"); + return c.get(); } const rrc_conn_request_nb_r13_ies_s& rrc_conn_request_r13() const { assert_choice_type(types::rrc_conn_request_r13, type_, "criticalExtensions"); - return c; + return c.get(); + } + const later_c_& later() const + { + assert_choice_type(types::later, type_, "criticalExtensions"); + return c.get(); } rrc_conn_request_nb_r13_ies_s& set_rrc_conn_request_r13(); - void set_crit_exts_future(); + later_c_& set_later(); private: - types type_; - rrc_conn_request_nb_r13_ies_s c; + types type_; + choice_buffer_t c; + + void destroy_(); }; // member variables @@ -7486,11 +9767,37 @@ struct rrc_conn_request_nb_s { void to_json(json_writer& j) const; }; +// RRCConnectionResumeComplete-NB-v1710-IEs ::= SEQUENCE +struct rrc_conn_resume_complete_nb_v1710_ies_s { + bool gnss_validity_dur_r17_present = false; + bool non_crit_ext_present = false; + gnss_validity_dur_r17_e gnss_validity_dur_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionResumeComplete-NB-v1610-IEs ::= SEQUENCE +struct rrc_conn_resume_complete_nb_v1610_ies_s { + bool rlf_info_available_r16_present = false; + bool anr_info_available_r16_present = false; + bool non_crit_ext_present = false; + rrc_conn_resume_complete_nb_v1710_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionResumeComplete-NB-v1470-IEs ::= SEQUENCE struct rrc_conn_resume_complete_nb_v1470_ies_s { - bool meas_result_serv_cell_r14_present = false; - bool non_crit_ext_present = false; - meas_result_serv_cell_nb_r14_s meas_result_serv_cell_r14; + bool meas_result_serv_cell_r14_present = false; + bool non_crit_ext_present = false; + meas_result_serv_cell_nb_r14_s meas_result_serv_cell_r14; + rrc_conn_resume_complete_nb_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -7561,6 +9868,20 @@ struct rrc_conn_resume_complete_nb_s { void to_json(json_writer& j) const; }; +// RRCConnectionResumeRequest-5GC-NB-r16-IEs ::= SEQUENCE +struct rrc_conn_resume_request_minus5_gc_nb_r16_ies_s { + fixed_bitstring<40> resume_id_r16; + fixed_bitstring<16> short_resume_mac_i_r16; + establishment_cause_nb_r13_e resume_cause_r16; + cqi_npdcch_nb_r14_e cqi_npdcch_r16; + fixed_bitstring<4> spare; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionResumeRequest-NB-r13-IEs ::= SEQUENCE struct rrc_conn_resume_request_nb_r13_ies_s { fixed_bitstring<40> resume_id_r13; @@ -7568,7 +9889,8 @@ struct rrc_conn_resume_request_nb_r13_ies_s { establishment_cause_nb_r13_e resume_cause_r13; bool early_contention_resolution_r14 = false; cqi_npdcch_nb_r14_e cqi_npdcch_r14; - fixed_bitstring<4> spare; + bool anr_info_available_r16 = false; + fixed_bitstring<3> spare; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -7579,8 +9901,41 @@ struct rrc_conn_resume_request_nb_r13_ies_s { // RRCConnectionResumeRequest-NB ::= SEQUENCE struct rrc_conn_resume_request_nb_s { struct crit_exts_c_ { + struct later_c_ { + struct types_opts { + enum options { rrc_conn_resume_request_r16, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + later_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + rrc_conn_resume_request_minus5_gc_nb_r16_ies_s& rrc_conn_resume_request_r16() + { + assert_choice_type(types::rrc_conn_resume_request_r16, type_, "later"); + return c; + } + const rrc_conn_resume_request_minus5_gc_nb_r16_ies_s& rrc_conn_resume_request_r16() const + { + assert_choice_type(types::rrc_conn_resume_request_r16, type_, "later"); + return c; + } + rrc_conn_resume_request_minus5_gc_nb_r16_ies_s& set_rrc_conn_resume_request_r16(); + void set_crit_exts_future(); + + private: + types type_; + rrc_conn_resume_request_minus5_gc_nb_r16_ies_s c; + }; struct types_opts { - enum options { rrc_conn_resume_request_r13, crit_exts_future, nulltype } value; + enum options { rrc_conn_resume_request_r13, later, nulltype } value; const char* to_string() const; }; @@ -7588,6 +9943,9 @@ struct rrc_conn_resume_request_nb_s { // choice methods crit_exts_c_() = default; + crit_exts_c_(const crit_exts_c_& other); + crit_exts_c_& operator=(const crit_exts_c_& other); + ~crit_exts_c_() { destroy_(); } void set(types::options e = types::nulltype); types type() const { return type_; } SRSASN_CODE pack(bit_ref& bref) const; @@ -7597,19 +9955,31 @@ struct rrc_conn_resume_request_nb_s { rrc_conn_resume_request_nb_r13_ies_s& rrc_conn_resume_request_r13() { assert_choice_type(types::rrc_conn_resume_request_r13, type_, "criticalExtensions"); - return c; + return c.get(); + } + later_c_& later() + { + assert_choice_type(types::later, type_, "criticalExtensions"); + return c.get(); } const rrc_conn_resume_request_nb_r13_ies_s& rrc_conn_resume_request_r13() const { assert_choice_type(types::rrc_conn_resume_request_r13, type_, "criticalExtensions"); - return c; + return c.get(); + } + const later_c_& later() const + { + assert_choice_type(types::later, type_, "criticalExtensions"); + return c.get(); } rrc_conn_resume_request_nb_r13_ies_s& set_rrc_conn_resume_request_r13(); - void set_crit_exts_future(); + later_c_& set_later(); private: - types type_; - rrc_conn_resume_request_nb_r13_ies_s c; + types type_; + choice_buffer_t c; + + void destroy_(); }; // member variables @@ -7621,11 +9991,59 @@ struct rrc_conn_resume_request_nb_s { void to_json(json_writer& j) const; }; +// RRCConnectionSetupComplete-NB-v1710-IEs ::= SEQUENCE +struct rrc_conn_setup_complete_nb_v1710_ies_s { + bool gnss_validity_dur_r17_present = false; + bool non_crit_ext_present = false; + gnss_validity_dur_r17_e gnss_validity_dur_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// RRCConnectionSetupComplete-NB-v1610-IEs ::= SEQUENCE +struct rrc_conn_setup_complete_nb_v1610_ies_s { + struct guami_type_r16_opts { + enum options { native, mapped, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated guami_type_r16_e_; + using s_nssai_list_r16_l_ = dyn_array; + + // member variables + bool ng_minus5_g_s_tmsi_r16_present = false; + bool registered_amf_r16_present = false; + bool gummei_type_v1610_present = false; + bool guami_type_r16_present = false; + bool s_nssai_list_r16_present = false; + bool ng_u_data_transfer_r16_present = false; + bool up_cio_t_minus5_gs_optim_r16_present = false; + bool rlf_info_available_r16_present = false; + bool anr_info_available_r16_present = false; + bool pur_cfg_id_r16_present = false; + bool non_crit_ext_present = false; + fixed_bitstring<48> ng_minus5_g_s_tmsi_r16; + registered_amf_r15_s registered_amf_r16; + guami_type_r16_e_ guami_type_r16; + s_nssai_list_r16_l_ s_nssai_list_r16; + fixed_bitstring<20> pur_cfg_id_r16; + rrc_conn_setup_complete_nb_v1710_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCConnectionSetupComplete-NB-v1470-IEs ::= SEQUENCE struct rrc_conn_setup_complete_nb_v1470_ies_s { - bool meas_result_serv_cell_r14_present = false; - bool non_crit_ext_present = false; - meas_result_serv_cell_nb_r14_s meas_result_serv_cell_r14; + bool meas_result_serv_cell_r14_present = false; + bool non_crit_ext_present = false; + meas_result_serv_cell_nb_r14_s meas_result_serv_cell_r14; + rrc_conn_setup_complete_nb_v1610_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -7714,6 +10132,31 @@ struct rrc_conn_setup_complete_nb_s { void to_json(json_writer& j) const; }; +// RRCEarlyDataRequest-5GC-NB-r16-IEs ::= SEQUENCE +struct rrc_early_data_request_minus5_gc_nb_r16_ies_s { + struct establishment_cause_r16_opts { + enum options { mo_data, mo_exception_data, mt_access, spare1, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated establishment_cause_r16_e_; + + // member variables + bool cqi_npdcch_r16_present = false; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + fixed_bitstring<48> ng_minus5_g_s_tmsi_r16; + establishment_cause_r16_e_ establishment_cause_r16; + cqi_npdcch_nb_r14_e cqi_npdcch_r16; + dyn_octstring ded_info_nas_r16; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // RRCEarlyDataRequest-NB-v1590-IEs ::= SEQUENCE struct rrc_early_data_request_nb_v1590_ies_s { bool late_non_crit_ext_present = false; @@ -7729,7 +10172,7 @@ struct rrc_early_data_request_nb_v1590_ies_s { // RRCEarlyDataRequest-NB-r15-IEs ::= SEQUENCE struct rrc_early_data_request_nb_r15_ies_s { struct establishment_cause_r15_opts { - enum options { mo_data, mo_exception_data, delay_tolerant_access, spare1, nulltype } value; + enum options { mo_data, mo_exception_data, delay_tolerant_access, mt_access_v1610, nulltype } value; const char* to_string() const; }; @@ -7753,8 +10196,41 @@ struct rrc_early_data_request_nb_r15_ies_s { // RRCEarlyDataRequest-NB-r15 ::= SEQUENCE struct rrc_early_data_request_nb_r15_s { struct crit_exts_c_ { + struct later_c_ { + struct types_opts { + enum options { rrc_early_data_request_r16, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + later_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + rrc_early_data_request_minus5_gc_nb_r16_ies_s& rrc_early_data_request_r16() + { + assert_choice_type(types::rrc_early_data_request_r16, type_, "later"); + return c; + } + const rrc_early_data_request_minus5_gc_nb_r16_ies_s& rrc_early_data_request_r16() const + { + assert_choice_type(types::rrc_early_data_request_r16, type_, "later"); + return c; + } + rrc_early_data_request_minus5_gc_nb_r16_ies_s& set_rrc_early_data_request_r16(); + void set_crit_exts_future(); + + private: + types type_; + rrc_early_data_request_minus5_gc_nb_r16_ies_s c; + }; struct types_opts { - enum options { rrc_early_data_request_r15, crit_exts_future, nulltype } value; + enum options { rrc_early_data_request_r15, later, nulltype } value; const char* to_string() const; }; @@ -7762,6 +10238,9 @@ struct rrc_early_data_request_nb_r15_s { // choice methods crit_exts_c_() = default; + crit_exts_c_(const crit_exts_c_& other); + crit_exts_c_& operator=(const crit_exts_c_& other); + ~crit_exts_c_() { destroy_(); } void set(types::options e = types::nulltype); types type() const { return type_; } SRSASN_CODE pack(bit_ref& bref) const; @@ -7771,19 +10250,31 @@ struct rrc_early_data_request_nb_r15_s { rrc_early_data_request_nb_r15_ies_s& rrc_early_data_request_r15() { assert_choice_type(types::rrc_early_data_request_r15, type_, "criticalExtensions"); - return c; + return c.get(); + } + later_c_& later() + { + assert_choice_type(types::later, type_, "criticalExtensions"); + return c.get(); } const rrc_early_data_request_nb_r15_ies_s& rrc_early_data_request_r15() const { assert_choice_type(types::rrc_early_data_request_r15, type_, "criticalExtensions"); - return c; + return c.get(); + } + const later_c_& later() const + { + assert_choice_type(types::later, type_, "criticalExtensions"); + return c.get(); } rrc_early_data_request_nb_r15_ies_s& set_rrc_early_data_request_r15(); - void set_crit_exts_future(); + later_c_& set_later(); private: - types type_; - rrc_early_data_request_nb_r15_ies_s c; + types type_; + choice_buffer_t c; + + void destroy_(); }; // member variables @@ -8189,6 +10680,29 @@ using sc_mtch_info_list_nb_r14_l = dyn_array; // SCPTM-NeighbourCellList-NB-r14 ::= SEQUENCE (SIZE (1..8)) OF PCI-ARFCN-NB-r14 using scptm_neighbour_cell_list_nb_r14_l = dyn_array; +// SCPTMConfiguration-NB-v1610 ::= SEQUENCE +struct scptm_cfg_nb_v1610_s { + struct multi_tb_gap_r16_opts { + enum options { sf16, sf32, sf64, sf128, nulltype } value; + typedef uint8_t number_type; + + const char* to_string() const; + uint8_t to_number() const; + }; + typedef enumerated multi_tb_gap_r16_e_; + + // member variables + bool multi_tb_gap_r16_present = false; + bool non_crit_ext_present = false; + sc_mtch_info_list_nb_r14_l sc_mtch_info_list_multi_tb_r16; + multi_tb_gap_r16_e_ multi_tb_gap_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // SCPTMConfiguration-NB-r14 ::= SEQUENCE struct scptm_cfg_nb_r14_s { bool scptm_neighbour_cell_list_r14_present = false; @@ -8197,6 +10711,7 @@ struct scptm_cfg_nb_r14_s { sc_mtch_info_list_nb_r14_l sc_mtch_info_list_r14; scptm_neighbour_cell_list_nb_r14_l scptm_neighbour_cell_list_r14; dyn_octstring late_non_crit_ext; + scptm_cfg_nb_v1610_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -8315,6 +10830,234 @@ struct tdd_ue_cap_nb_r15_s { void to_json(json_writer& j) const; }; +// PhyLayerParameters-NB-v1700 ::= SEQUENCE +struct phy_layer_params_nb_v1700_s { + bool npdsch_minus16_qam_r17_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TDD-UE-Capability-NB-v1710 ::= SEQUENCE +struct tdd_ue_cap_nb_v1710_s { + bool phy_layer_params_v1710_present = false; + phy_layer_params_nb_v1700_s phy_layer_params_v1710; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NTN-Parameters-NB-v1720 ::= SEQUENCE +struct ntn_params_nb_v1720_s { + struct ntn_segmented_precompensation_gaps_r17_opts { + enum options { sym1, sl1, sl2, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated ntn_segmented_precompensation_gaps_r17_e_; + + // member variables + bool ntn_segmented_precompensation_gaps_r17_present = false; + ntn_segmented_precompensation_gaps_r17_e_ ntn_segmented_precompensation_gaps_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasParameters-NB-v1710 ::= SEQUENCE +struct meas_params_nb_v1710_s { + bool conn_mode_meas_intra_freq_r17_present = false; + bool conn_mode_meas_inter_freq_r17_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-Capability-NB-v1720-IEs ::= SEQUENCE +struct ue_cap_nb_v1720_ies_s { + bool non_crit_ext_present = false; + ntn_params_nb_v1720_s ntn_params_v1720; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// NTN-Parameters-NB-r17 ::= SEQUENCE +struct ntn_params_nb_r17_s { + struct ntn_scenario_support_r17_opts { + enum options { ngso, gso, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated ntn_scenario_support_r17_e_; + + // member variables + bool ntn_connect_epc_r17_present = false; + bool ntn_ta_report_r17_present = false; + bool ntn_pur_timer_delay_r17_present = false; + bool ntn_offset_timing_enh_r17_present = false; + bool ntn_scenario_support_r17_present = false; + ntn_scenario_support_r17_e_ ntn_scenario_support_r17; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-Capability-NB-v1710-IEs ::= SEQUENCE +struct ue_cap_nb_v1710_ies_s { + bool meas_params_v1710_present = false; + bool non_crit_ext_present = false; + meas_params_nb_v1710_s meas_params_v1710; + rf_params_nb_v1710_s rf_params_v1710; + tdd_ue_cap_nb_v1710_s tdd_ue_cap_v1710; + ue_cap_nb_v1720_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-Capability-NB-v1700-IEs ::= SEQUENCE +struct ue_cap_nb_v1700_ies_s { + bool coverage_based_paging_r17_present = false; + bool ntn_params_r17_present = false; + bool non_crit_ext_present = false; + phy_layer_params_nb_v1700_s phy_layer_params_v1700; + ntn_params_nb_r17_s ntn_params_r17; + ue_cap_nb_v1710_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MAC-Parameters-NB-v1610 ::= SEQUENCE +struct mac_params_nb_v1610_s { + bool rai_support_enh_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// MeasParameters-NB-r16 ::= SEQUENCE +struct meas_params_nb_r16_s { + bool dl_ch_quality_report_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PUR-Parameters-NB-r16 ::= SEQUENCE +struct pur_params_nb_r16_s { + bool pur_cp_epc_r16_present = false; + bool pur_cp_minus5_gc_r16_present = false; + bool pur_up_epc_r16_present = false; + bool pur_up_minus5_gc_r16_present = false; + bool pur_nrsrp_validation_r16_present = false; + bool pur_cp_l1_ack_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// PhyLayerParameters-NB-v1610 ::= SEQUENCE +struct phy_layer_params_nb_v1610_s { + bool npdsch_multi_tb_r16_present = false; + bool npdsch_multi_tb_interleaving_r16_present = false; + bool npusch_multi_tb_r16_present = false; + bool npusch_multi_tb_interleaving_r16_present = false; + bool multi_tb_harq_ack_bundling_r16_present = false; + bool slot_symbol_res_resv_dl_r16_present = false; + bool slot_symbol_res_resv_ul_r16_present = false; + bool sf_res_resv_dl_r16_present = false; + bool sf_res_resv_ul_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// SON-Parameters-NB-r16 ::= SEQUENCE +struct son_params_nb_r16_s { + bool anr_report_r16_present = false; + bool rach_report_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// TDD-UE-Capability-NB-v1610 ::= SEQUENCE +struct tdd_ue_cap_nb_v1610_s { + bool slot_symbol_res_resv_dl_r16_present = false; + bool slot_symbol_res_resv_ul_r16_present = false; + bool sf_res_resv_dl_r16_present = false; + bool sf_res_resv_ul_r16_present = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-Capability-NB-v16x0-IEs ::= SEQUENCE +struct ue_cap_nb_v16x0_ies_s { + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + dyn_octstring late_non_crit_ext; + ue_cap_nb_v1700_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UE-Capability-NB-v1610-IEs ::= SEQUENCE +struct ue_cap_nb_v1610_ies_s { + bool early_security_reactivation_r16_present = false; + bool early_data_up_minus5_gc_r16_present = false; + bool pur_params_r16_present = false; + bool phy_layer_params_v1610_present = false; + bool son_params_r16_present = false; + bool tdd_ue_cap_v1610_present = false; + bool non_crit_ext_present = false; + pur_params_nb_r16_s pur_params_r16; + mac_params_nb_v1610_s mac_params_v1610; + phy_layer_params_nb_v1610_s phy_layer_params_v1610; + son_params_nb_r16_s son_params_r16; + meas_params_nb_r16_s meas_params_r16; + tdd_ue_cap_nb_v1610_s tdd_ue_cap_v1610; + ue_cap_nb_v16x0_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // MAC-Parameters-NB-v1530 ::= SEQUENCE struct mac_params_nb_v1530_s { bool sr_sps_bsr_r15_present = false; @@ -8335,6 +11078,19 @@ struct rlc_params_nb_r15_s { void to_json(json_writer& j) const; }; +// UE-Capability-NB-v15x0-IEs ::= SEQUENCE +struct ue_cap_nb_v15x0_ies_s { + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + dyn_octstring late_non_crit_ext; + ue_cap_nb_v1610_ies_s non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // UE-Capability-NB-v1530-IEs ::= SEQUENCE struct ue_cap_nb_v1530_ies_s { bool early_data_up_r15_present = false; @@ -8345,6 +11101,7 @@ struct ue_cap_nb_v1530_ies_s { mac_params_nb_v1530_s mac_params_v1530; phy_layer_params_nb_v1530_s phy_layer_params_v1530; tdd_ue_cap_nb_r15_s tdd_ue_cap_r15; + ue_cap_nb_v15x0_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -8449,6 +11206,10 @@ struct ue_radio_paging_info_nb_r13_s { bool wake_up_signal_min_gap_e_drx_r15_present = false; bool multi_carrier_paging_tdd_r15_present = false; wake_up_signal_min_gap_e_drx_r15_e_ wake_up_signal_min_gap_e_drx_r15; + // group 2 + bool ue_category_nb_r16_present = false; + bool group_wake_up_signal_r16_present = false; + bool group_wake_up_signal_alternation_r16_present = false; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -8528,11 +11289,101 @@ struct ue_cap_info_nb_s { void to_json(json_writer& j) const; }; +// RACH-Report-NB-r16 ::= SEQUENCE +struct rach_report_nb_r16_s { + uint8_t nof_preambs_sent_r16 = 1; + bool contention_detected_r16 = false; + uint8_t init_nrsrp_level_r16 = 0; + bool edt_fallback_r16 = false; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEInformationResponse-NB-r16-IEs ::= SEQUENCE +struct ue_info_resp_nb_r16_ies_s { + bool rach_report_r16_present = false; + bool rlf_report_r16_present = false; + bool anr_meas_report_r16_present = false; + bool late_non_crit_ext_present = false; + bool non_crit_ext_present = false; + rach_report_nb_r16_s rach_report_r16; + rlf_report_nb_r16_s rlf_report_r16; + anr_meas_report_nb_r16_s anr_meas_report_r16; + dyn_octstring late_non_crit_ext; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEInformationResponse-NB-r16 ::= SEQUENCE +struct ue_info_resp_nb_r16_s { + struct crit_exts_c_ { + struct types_opts { + enum options { ue_info_resp_r16, crit_exts_future, nulltype } value; + + const char* to_string() const; + }; + typedef enumerated types; + + // choice methods + crit_exts_c_() = default; + void set(types::options e = types::nulltype); + types type() const { return type_; } + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; + // getters + ue_info_resp_nb_r16_ies_s& ue_info_resp_r16() + { + assert_choice_type(types::ue_info_resp_r16, type_, "criticalExtensions"); + return c; + } + const ue_info_resp_nb_r16_ies_s& ue_info_resp_r16() const + { + assert_choice_type(types::ue_info_resp_r16, type_, "criticalExtensions"); + return c; + } + ue_info_resp_nb_r16_ies_s& set_ue_info_resp_r16(); + void set_crit_exts_future(); + + private: + types type_; + ue_info_resp_nb_r16_ies_s c; + }; + + // member variables + uint8_t rrc_transaction_id = 0; + crit_exts_c_ crit_exts; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// UEPagingCoverageInformation-NB-v1700-IEs ::= SEQUENCE +struct ue_paging_coverage_info_nb_v1700_ies_s { + bool cbp_idx_r17_present = false; + bool non_crit_ext_present = false; + uint8_t cbp_idx_r17 = 1; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + // UEPagingCoverageInformation-NB-IEs ::= SEQUENCE struct ue_paging_coverage_info_nb_ies_s { - bool npdcch_num_repeat_paging_r13_present = false; - bool non_crit_ext_present = false; - uint16_t npdcch_num_repeat_paging_r13 = 1; + bool npdcch_num_repeat_paging_r13_present = false; + bool non_crit_ext_present = false; + uint16_t npdcch_num_repeat_paging_r13 = 1; + ue_paging_coverage_info_nb_v1700_ies_s non_crit_ext; // sequence methods SRSASN_CODE pack(bit_ref& bref) const; @@ -9011,8 +11862,8 @@ struct ul_dcch_msg_type_nb_c { ue_cap_info_r13, ul_info_transfer_r13, rrc_conn_resume_complete_r13, - spare8, - spare7, + ue_info_resp_r16, + pur_cfg_request_r16, spare6, spare5, spare4, @@ -9077,6 +11928,16 @@ struct ul_dcch_msg_type_nb_c { assert_choice_type(types::rrc_conn_resume_complete_r13, type_, "c1"); return c.get(); } + ue_info_resp_nb_r16_s& ue_info_resp_r16() + { + assert_choice_type(types::ue_info_resp_r16, type_, "c1"); + return c.get(); + } + pur_cfg_request_nb_r16_s& pur_cfg_request_r16() + { + assert_choice_type(types::pur_cfg_request_r16, type_, "c1"); + return c.get(); + } const rrc_conn_recfg_complete_nb_s& rrc_conn_recfg_complete_r13() const { assert_choice_type(types::rrc_conn_recfg_complete_r13, type_, "c1"); @@ -9117,6 +11978,16 @@ struct ul_dcch_msg_type_nb_c { assert_choice_type(types::rrc_conn_resume_complete_r13, type_, "c1"); return c.get(); } + const ue_info_resp_nb_r16_s& ue_info_resp_r16() const + { + assert_choice_type(types::ue_info_resp_r16, type_, "c1"); + return c.get(); + } + const pur_cfg_request_nb_r16_s& pur_cfg_request_r16() const + { + assert_choice_type(types::pur_cfg_request_r16, type_, "c1"); + return c.get(); + } rrc_conn_recfg_complete_nb_s& set_rrc_conn_recfg_complete_r13(); rrc_conn_reest_complete_nb_s& set_rrc_conn_reest_complete_r13(); rrc_conn_setup_complete_nb_s& set_rrc_conn_setup_complete_r13(); @@ -9125,8 +11996,8 @@ struct ul_dcch_msg_type_nb_c { ue_cap_info_nb_s& set_ue_cap_info_r13(); ul_info_transfer_nb_s& set_ul_info_transfer_r13(); rrc_conn_resume_complete_nb_s& set_rrc_conn_resume_complete_r13(); - void set_spare8(); - void set_spare7(); + ue_info_resp_nb_r16_s& set_ue_info_resp_r16(); + pur_cfg_request_nb_r16_s& set_pur_cfg_request_r16(); void set_spare6(); void set_spare5(); void set_spare4(); @@ -9136,13 +12007,15 @@ struct ul_dcch_msg_type_nb_c { private: types type_; - choice_buffer_t c; @@ -9193,6 +12066,34 @@ struct ul_dcch_msg_nb_s { void to_json(json_writer& j) const; }; +// VarANR-MeasConfig-NB-r16 ::= SEQUENCE +struct var_anr_meas_cfg_nb_r16_s { + uint8_t anr_quality_thres_r16 = 0; + anr_carrier_list_nb_r16_l anr_carrier_list_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + +// VarANR-MeasReport-NB-r16 ::= SEQUENCE +struct var_anr_meas_report_nb_r16_s { + using meas_result_list_r16_l_ = dyn_array; + + // member variables + plmn_id_list3_r11_l plmn_id_list_r16; + cell_global_id_eutra_s serv_cell_id_r16; + meas_result_serv_cell_nb_r14_s meas_result_serv_cell_r16; + uint8_t relative_time_stamp_r16 = 0; + meas_result_list_r16_l_ meas_result_list_r16; + + // sequence methods + SRSASN_CODE pack(bit_ref& bref) const; + SRSASN_CODE unpack(cbit_ref& bref); + void to_json(json_writer& j) const; +}; + } // namespace rrc } // namespace asn1 diff --git a/lib/include/srsran/asn1/rrc_nr.h b/lib/include/srsran/asn1/rrc_nr.h index b7088d9deb..524769cf55 100644 --- a/lib/include/srsran/asn1/rrc_nr.h +++ b/lib/include/srsran/asn1/rrc_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -445,8 +445,7 @@ struct eutra_freq_neigh_cell_info_s { // EUTRA-MultiBandInfo ::= SEQUENCE struct eutra_multi_band_info_s { - bool eutra_ns_pmax_list_present = false; - uint16_t eutra_freq_band_ind = 1; + uint16_t eutra_freq_band_ind = 1; eutra_ns_pmax_list_l eutra_ns_pmax_list; // sequence methods @@ -517,7 +516,6 @@ struct inter_freq_neigh_cell_info_s { // NR-MultiBandInfo ::= SEQUENCE struct nr_multi_band_info_s { bool freq_band_ind_nr_present = false; - bool nr_ns_pmax_list_present = false; uint16_t freq_band_ind_nr = 1; nr_ns_pmax_list_l nr_ns_pmax_list; @@ -689,12 +687,10 @@ struct ctrl_res_set_s { using tci_states_pdcch_to_release_list_l_ = dyn_array; // member variables - bool ext = false; - bool tci_states_pdcch_to_add_list_present = false; - bool tci_states_pdcch_to_release_list_present = false; - bool tci_present_in_dci_present = false; - bool pdcch_dmrs_scrambling_id_present = false; - uint8_t ctrl_res_set_id = 0; + bool ext = false; + bool tci_present_in_dci_present = false; + bool pdcch_dmrs_scrambling_id_present = false; + uint8_t ctrl_res_set_id = 0; fixed_bitstring<45> freq_domain_res; uint8_t dur = 1; cce_reg_map_type_c_ cce_reg_map_type; @@ -1512,13 +1508,10 @@ struct carrier_freq_eutra_s { }; // member variables - bool eutra_multi_band_info_list_present = false; - bool eutra_freq_neigh_cell_list_present = false; - bool eutra_black_cell_list_present = false; - bool cell_resel_prio_present = false; - bool cell_resel_sub_prio_present = false; - bool thresh_x_q_present = false; - uint32_t carrier_freq = 0; + bool cell_resel_prio_present = false; + bool cell_resel_sub_prio_present = false; + bool thresh_x_q_present = false; + uint32_t carrier_freq = 0; eutra_multi_band_info_list_l eutra_multi_band_info_list; eutra_freq_neigh_cell_list_l eutra_freq_neigh_cell_list; eutra_freq_black_cell_list_l eutra_black_cell_list; @@ -1548,8 +1541,6 @@ struct inter_freq_carrier_freq_info_s { // member variables bool ext = false; - bool freq_band_list_present = false; - bool freq_band_list_sul_present = false; bool nrof_ss_blocks_to_average_present = false; bool abs_thresh_ss_blocks_consolidation_present = false; bool smtc_present = false; @@ -1563,8 +1554,6 @@ struct inter_freq_carrier_freq_info_s { bool cell_resel_prio_present = false; bool cell_resel_sub_prio_present = false; bool q_offset_freq_present = false; - bool inter_freq_neigh_cell_list_present = false; - bool inter_freq_black_cell_list_present = false; uint32_t dl_carrier_freq = 0; multi_freq_band_list_nr_sib_l freq_band_list; multi_freq_band_list_nr_sib_l freq_band_list_sul; @@ -1793,7 +1782,6 @@ struct pdcch_cfg_common_s { bool ctrl_res_set_zero_present = false; bool common_ctrl_res_set_present = false; bool search_space_zero_present = false; - bool common_search_space_list_present = false; bool search_space_sib1_present = false; bool search_space_other_sys_info_present = false; bool paging_search_space_present = false; @@ -1818,8 +1806,7 @@ struct pdcch_cfg_common_s { // PDSCH-ConfigCommon ::= SEQUENCE struct pdsch_cfg_common_s { - bool ext = false; - bool pdsch_time_domain_alloc_list_present = false; + bool ext = false; pdsch_time_domain_res_alloc_list_l pdsch_time_domain_alloc_list; // ... @@ -1871,7 +1858,6 @@ struct pucch_cfg_common_s { struct pusch_cfg_common_s { bool ext = false; bool group_hop_enabled_transform_precoding_present = false; - bool pusch_time_domain_alloc_list_present = false; bool msg3_delta_preamb_present = false; bool p0_nominal_with_grant_present = false; pusch_time_domain_res_alloc_list_l pusch_time_domain_alloc_list; @@ -2247,101 +2233,6 @@ struct sib_type_info_s { void to_json(json_writer& j) const; }; -// SetupRelease{ElementTypeParam} ::= CHOICE -template -struct setup_release_c { - struct types_opts { - enum options { release, setup, nulltype } value; - - const char* to_string() const - { - static const char* options[] = {"release", "setup"}; - return convert_enum_idx(options, 2, value, "setup_release_c::types"); - } - }; - typedef enumerated types; - - // choice methods - setup_release_c() = default; - types type() const { return type_; } - - // getters - elem_type_paramT_& setup() - { - assert_choice_type(types::setup, type_, "SetupRelease"); - return c; - } - const elem_type_paramT_& setup() const - { - assert_choice_type(types::setup, type_, "SetupRelease"); - return c; - } - void set_release() { set(types::release); } - - void set(typename types::options e) { type_ = e; } - - void to_json(json_writer& j) const - { - j.start_obj(); - switch (type_) { - case types::release: - j.write_null("release"); - break; - case types::setup: - j.write_fieldname("setup"); - asn1::to_json(j, setup()); - break; - default: - log_invalid_choice_id(type_, "setup_release_c"); - } - j.end_obj(); - } - - SRSASN_CODE pack(bit_ref& bref) const - { - type_.pack(bref); - switch (type_) { - case types::release: - break; - case types::setup: - HANDLE_CODE(c.pack(bref)); - break; - default: - log_invalid_choice_id(type_, "setup_release_c"); - return SRSASN_ERROR_ENCODE_FAIL; - } - return SRSASN_SUCCESS; - } - - SRSASN_CODE unpack(cbit_ref& bref) - { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::release: - break; - case types::setup: - HANDLE_CODE(c.unpack(bref)); - break; - default: - log_invalid_choice_id(type_, "setup_release_c"); - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; - } - - elem_type_paramT_& set_setup() - { - set(types::setup); - return c; - } - -private: - types type_; - elem_type_paramT_ c; -}; - // UAC-BarringPerCat ::= SEQUENCE struct uac_barr_per_cat_s { uint8_t access_category = 1; @@ -2433,7 +2324,6 @@ struct freq_info_ul_sib_s { // member variables bool ext = false; - bool freq_band_list_present = false; bool absolute_freq_point_a_present = false; bool p_max_present = false; bool freq_shift7p5khz_present = false; @@ -2994,22 +2884,20 @@ struct sib2_s { // ... }; struct intra_freq_cell_resel_info_s_ { - bool ext = false; - bool q_rx_lev_min_sul_present = false; - bool q_qual_min_present = false; - bool s_intra_search_q_present = false; - bool freq_band_list_present = false; - bool freq_band_list_sul_present = false; - bool p_max_present = false; - bool smtc_present = false; - bool ss_rssi_meas_present = false; - bool ssb_to_measure_present = false; - int8_t q_rx_lev_min = -70; - int8_t q_rx_lev_min_sul = -70; - int8_t q_qual_min = -43; - uint8_t s_intra_search_p = 0; - uint8_t s_intra_search_q = 0; - uint8_t t_resel_nr = 0; + bool ext = false; + bool q_rx_lev_min_sul_present = false; + bool q_qual_min_present = false; + bool s_intra_search_q_present = false; + bool p_max_present = false; + bool smtc_present = false; + bool ss_rssi_meas_present = false; + bool ssb_to_measure_present = false; + int8_t q_rx_lev_min = -70; + int8_t q_rx_lev_min_sul = -70; + int8_t q_qual_min = -43; + uint8_t s_intra_search_p = 0; + uint8_t s_intra_search_q = 0; + uint8_t t_resel_nr = 0; multi_freq_band_list_nr_sib_l freq_band_list; multi_freq_band_list_nr_sib_l freq_band_list_sul; int8_t p_max = -30; @@ -3042,10 +2930,7 @@ struct sib2_s { // SIB3 ::= SEQUENCE struct sib3_s { - bool ext = false; - bool intra_freq_neigh_cell_list_present = false; - bool intra_freq_black_cell_list_present = false; - bool late_non_crit_ext_present = false; + bool ext = false; intra_freq_neigh_cell_list_l intra_freq_neigh_cell_list; intra_freq_black_cell_list_l intra_freq_black_cell_list; dyn_octstring late_non_crit_ext; @@ -3059,8 +2944,7 @@ struct sib3_s { // SIB4 ::= SEQUENCE struct sib4_s { - bool ext = false; - bool late_non_crit_ext_present = false; + bool ext = false; inter_freq_carrier_freq_list_l inter_freq_carrier_freq_list; dyn_octstring late_non_crit_ext; // ... @@ -3073,10 +2957,8 @@ struct sib4_s { // SIB5 ::= SEQUENCE struct sib5_s { - bool ext = false; - bool carrier_freq_list_eutra_present = false; - bool t_resel_eutra_sf_present = false; - bool late_non_crit_ext_present = false; + bool ext = false; + bool t_resel_eutra_sf_present = false; carrier_freq_list_eutra_l carrier_freq_list_eutra; uint8_t t_resel_eutra = 0; speed_state_scale_factors_s t_resel_eutra_sf; @@ -3091,8 +2973,7 @@ struct sib5_s { // SIB6 ::= SEQUENCE struct sib6_s { - bool ext = false; - bool late_non_crit_ext_present = false; + bool ext = false; fixed_bitstring<16> msg_id; fixed_bitstring<16> serial_num; fixed_octstring<2> warning_type; @@ -3117,7 +2998,6 @@ struct sib7_s { // member variables bool ext = false; bool data_coding_scheme_present = false; - bool late_non_crit_ext_present = false; fixed_bitstring<16> msg_id; fixed_bitstring<16> serial_num; warning_msg_segment_type_e_ warning_msg_segment_type; @@ -3143,10 +3023,8 @@ struct sib8_s { typedef enumerated warning_msg_segment_type_e_; // member variables - bool ext = false; - bool data_coding_scheme_present = false; - bool warning_area_coordinates_segment_present = false; - bool late_non_crit_ext_present = false; + bool ext = false; + bool data_coding_scheme_present = false; fixed_bitstring<16> msg_id; fixed_bitstring<16> serial_num; warning_msg_segment_type_e_ warning_msg_segment_type; @@ -3176,9 +3054,8 @@ struct sib9_s { }; // member variables - bool ext = false; - bool time_info_present = false; - bool late_non_crit_ext_present = false; + bool ext = false; + bool time_info_present = false; time_info_s_ time_info; dyn_octstring late_non_crit_ext; // ... @@ -3579,8 +3456,7 @@ struct sys_info_ies_s { using sib_type_and_info_l_ = dyn_array; // member variables - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; sib_type_and_info_l_ sib_type_and_info; dyn_octstring late_non_crit_ext; @@ -3745,8 +3621,6 @@ struct sib1_s { }; // member variables - bool uac_barr_for_common_present = false; - bool uac_barr_per_plmn_list_present = false; bool uac_access_category1_sel_assist_info_present = false; uac_barr_per_cat_list_l uac_barr_for_common; uac_barr_per_plmn_list_l uac_barr_per_plmn_list; @@ -3764,7 +3638,6 @@ struct sib1_s { bool ue_timers_and_consts_present = false; bool uac_barr_info_present = false; bool use_full_resume_id_present = false; - bool late_non_crit_ext_present = false; bool non_crit_ext_present = false; cell_sel_info_s_ cell_sel_info; cell_access_related_info_s cell_access_related_info; @@ -4250,10 +4123,8 @@ struct sdap_cfg_s { using mapped_qos_flows_to_release_l_ = dyn_array; // member variables - bool ext = false; - bool mapped_qos_flows_to_add_present = false; - bool mapped_qos_flows_to_release_present = false; - uint16_t pdu_session = 0; + bool ext = false; + uint16_t pdu_session = 0; sdap_hdr_dl_e_ sdap_hdr_dl; sdap_hdr_ul_e_ sdap_hdr_ul; bool default_drb = false; @@ -4399,12 +4270,9 @@ struct security_cfg_s { // RadioBearerConfig ::= SEQUENCE struct radio_bearer_cfg_s { - bool ext = false; - bool srb_to_add_mod_list_present = false; - bool srb3_to_release_present = false; - bool drb_to_add_mod_list_present = false; - bool drb_to_release_list_present = false; - bool security_cfg_present = false; + bool ext = false; + bool srb3_to_release_present = false; + bool security_cfg_present = false; srb_to_add_mod_list_l srb_to_add_mod_list; drb_to_add_mod_list_l drb_to_add_mod_list; drb_to_release_list_l drb_to_release_list; @@ -4419,10 +4287,9 @@ struct radio_bearer_cfg_s { // RRCReject-IEs ::= SEQUENCE struct rrc_reject_ies_s { - bool wait_time_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - uint8_t wait_time = 1; + bool wait_time_present = false; + bool non_crit_ext_present = false; + uint8_t wait_time = 1; dyn_octstring late_non_crit_ext; // sequence methods @@ -4433,8 +4300,7 @@ struct rrc_reject_ies_s { // RRCSetup-IEs ::= SEQUENCE struct rrc_setup_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; radio_bearer_cfg_s radio_bearer_cfg; dyn_octstring master_cell_group; dyn_octstring late_non_crit_ext; @@ -5566,7 +5432,6 @@ struct ran_area_cfg_s { using ran_area_code_list_l_ = bounded_array; // member variables - bool ran_area_code_list_present = false; fixed_bitstring<24> tac; ran_area_code_list_l_ ran_area_code_list; @@ -5659,7 +5524,6 @@ struct ssb_mtc2_s { typedef enumerated periodicity_e_; // member variables - bool pci_list_present = false; pci_list_l_ pci_list; periodicity_e_ periodicity; @@ -5736,13 +5600,9 @@ struct meas_obj_eutra_s { using black_cells_to_add_mod_list_eutran_l_ = dyn_array; // member variables - bool ext = false; - bool cells_to_rem_list_eutran_present = false; - bool cells_to_add_mod_list_eutran_present = false; - bool black_cells_to_rem_list_eutran_present = false; - bool black_cells_to_add_mod_list_eutran_present = false; - bool eutra_q_offset_range_present = false; - uint32_t carrier_freq = 0; + bool ext = false; + bool eutra_q_offset_range_present = false; + uint32_t carrier_freq = 0; eutra_allowed_meas_bw_e allowed_meas_bw; eutra_cell_idx_list_l cells_to_rem_list_eutran; cells_to_add_mod_list_eutran_l_ cells_to_add_mod_list_eutran; @@ -5783,12 +5643,6 @@ struct meas_obj_nr_s { bool abs_thresh_csi_rs_consolidation_present = false; bool nrof_ss_blocks_to_average_present = false; bool nrof_csi_rs_res_to_average_present = false; - bool cells_to_rem_list_present = false; - bool cells_to_add_mod_list_present = false; - bool black_cells_to_rem_list_present = false; - bool black_cells_to_add_mod_list_present = false; - bool white_cells_to_rem_list_present = false; - bool white_cells_to_add_mod_list_present = false; uint32_t ssb_freq = 0; subcarrier_spacing_e ssb_subcarrier_spacing; ssb_mtc_s smtc1; @@ -6274,7 +6128,6 @@ typedef enumerated rat_type_e; // RRCReconfiguration-v1560-IEs ::= SEQUENCE struct rrc_recfg_v1560_ies_s { bool mrdc_secondary_cell_group_cfg_present = false; - bool radio_bearer_cfg2_present = false; bool sk_counter_present = false; bool non_crit_ext_present = false; setup_release_c mrdc_secondary_cell_group_cfg; @@ -6384,7 +6237,6 @@ using freq_prio_list_nr_l = dyn_array; // MasterKeyUpdate ::= SEQUENCE struct master_key_upd_s { bool ext = false; - bool nas_container_present = false; bool key_set_change_ind = false; uint8_t next_hop_chaining_count = 0; dyn_octstring nas_container; @@ -6515,8 +6367,7 @@ struct quant_cfg_s { using quant_cfg_nr_list_l_ = dyn_array; // member variables - bool ext = false; - bool quant_cfg_nr_list_present = false; + bool ext = false; quant_cfg_nr_list_l_ quant_cfg_nr_list; // ... // group 0 @@ -6621,8 +6472,7 @@ using report_cfg_to_rem_list_l = dyn_array; // UE-CapabilityRAT-Request ::= SEQUENCE struct ue_cap_rat_request_s { - bool ext = false; - bool cap_request_filt_present = false; + bool ext = false; rat_type_e rat_type; dyn_octstring cap_request_filt; // ... @@ -6645,10 +6495,8 @@ struct cell_resel_priorities_s { typedef enumerated t320_e_; // member variables - bool ext = false; - bool freq_prio_list_eutra_present = false; - bool freq_prio_list_nr_present = false; - bool t320_present = false; + bool ext = false; + bool t320_present = false; freq_prio_list_eutra_l freq_prio_list_eutra; freq_prio_list_nr_l freq_prio_list_nr; t320_e_ t320; @@ -6715,17 +6563,11 @@ struct meas_cfg_s { }; // member variables - bool ext = false; - bool meas_obj_to_rem_list_present = false; - bool meas_obj_to_add_mod_list_present = false; - bool report_cfg_to_rem_list_present = false; - bool report_cfg_to_add_mod_list_present = false; - bool meas_id_to_rem_list_present = false; - bool meas_id_to_add_mod_list_present = false; - bool s_measure_cfg_present = false; - bool quant_cfg_present = false; - bool meas_gap_cfg_present = false; - bool meas_gap_sharing_cfg_present = false; + bool ext = false; + bool s_measure_cfg_present = false; + bool quant_cfg_present = false; + bool meas_gap_cfg_present = false; + bool meas_gap_sharing_cfg_present = false; meas_obj_to_rem_list_l meas_obj_to_rem_list; meas_obj_to_add_mod_list_l meas_obj_to_add_mod_list; report_cfg_to_rem_list_l report_cfg_to_rem_list; @@ -6749,14 +6591,10 @@ struct rrc_recfg_v1530_ies_s { using ded_nas_msg_list_l_ = bounded_array; // member variables - bool master_cell_group_present = false; - bool full_cfg_present = false; - bool ded_nas_msg_list_present = false; - bool master_key_upd_present = false; - bool ded_sib1_delivery_present = false; - bool ded_sys_info_delivery_present = false; - bool other_cfg_present = false; - bool non_crit_ext_present = false; + bool full_cfg_present = false; + bool master_key_upd_present = false; + bool other_cfg_present = false; + bool non_crit_ext_present = false; dyn_octstring master_cell_group; ded_nas_msg_list_l_ ded_nas_msg_list; master_key_upd_s master_key_upd; @@ -6785,9 +6623,8 @@ struct rrc_release_v1540_ies_s { // RRCResume-v1560-IEs ::= SEQUENCE struct rrc_resume_v1560_ies_s { - bool radio_bearer_cfg2_present = false; - bool sk_counter_present = false; - bool non_crit_ext_present = false; + bool sk_counter_present = false; + bool non_crit_ext_present = false; dyn_octstring radio_bearer_cfg2; uint32_t sk_counter = 0; @@ -6883,8 +6720,7 @@ using ue_cap_rat_request_list_l = dyn_array; // CounterCheck-IEs ::= SEQUENCE struct counter_check_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; drb_count_msb_info_list_l drb_count_msb_info_list; dyn_octstring late_non_crit_ext; @@ -6896,9 +6732,7 @@ struct counter_check_ies_s { // DLInformationTransfer-IEs ::= SEQUENCE struct dl_info_transfer_ies_s { - bool ded_nas_msg_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; dyn_octstring ded_nas_msg; dyn_octstring late_non_crit_ext; @@ -6918,9 +6752,7 @@ struct mob_from_nr_cmd_ies_s { typedef enumerated target_rat_type_e_; // member variables - bool nas_security_param_from_nr_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; target_rat_type_e_ target_rat_type; dyn_octstring target_rat_msg_container; dyn_octstring nas_security_param_from_nr; @@ -6934,11 +6766,9 @@ struct mob_from_nr_cmd_ies_s { // RRCReconfiguration-IEs ::= SEQUENCE struct rrc_recfg_ies_s { - bool radio_bearer_cfg_present = false; - bool secondary_cell_group_present = false; - bool meas_cfg_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool radio_bearer_cfg_present = false; + bool meas_cfg_present = false; + bool non_crit_ext_present = false; radio_bearer_cfg_s radio_bearer_cfg; dyn_octstring secondary_cell_group; meas_cfg_s meas_cfg; @@ -6953,9 +6783,8 @@ struct rrc_recfg_ies_s { // RRCReestablishment-IEs ::= SEQUENCE struct rrc_reest_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; - uint8_t next_hop_chaining_count = 0; + bool non_crit_ext_present = false; + uint8_t next_hop_chaining_count = 0; dyn_octstring late_non_crit_ext; // sequence methods @@ -6992,7 +6821,6 @@ struct rrc_release_ies_s { bool cell_resel_priorities_present = false; bool suspend_cfg_present = false; bool depriorit_req_present = false; - bool late_non_crit_ext_present = false; bool non_crit_ext_present = false; redirected_carrier_info_c redirected_carrier_info; cell_resel_priorities_s cell_resel_priorities; @@ -7009,12 +6837,10 @@ struct rrc_release_ies_s { // RRCResume-IEs ::= SEQUENCE struct rrc_resume_ies_s { - bool radio_bearer_cfg_present = false; - bool master_cell_group_present = false; - bool meas_cfg_present = false; - bool full_cfg_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool radio_bearer_cfg_present = false; + bool meas_cfg_present = false; + bool full_cfg_present = false; + bool non_crit_ext_present = false; radio_bearer_cfg_s radio_bearer_cfg; dyn_octstring master_cell_group; meas_cfg_s meas_cfg; @@ -7029,8 +6855,7 @@ struct rrc_resume_ies_s { // SecurityModeCommand-IEs ::= SEQUENCE struct security_mode_cmd_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; security_cfg_smc_s security_cfg_smc; dyn_octstring late_non_crit_ext; @@ -7042,8 +6867,6 @@ struct security_mode_cmd_ies_s { // UECapabilityEnquiry-IEs ::= SEQUENCE struct ue_cap_enquiry_ies_s { - bool late_non_crit_ext_present = false; - bool ue_cap_enquiry_ext_present = false; ue_cap_rat_request_list_l ue_cap_rat_request_list; dyn_octstring late_non_crit_ext; dyn_octstring ue_cap_enquiry_ext; @@ -7744,9 +7567,7 @@ using paging_record_list_l = dyn_array; // Paging ::= SEQUENCE struct paging_s { - bool paging_record_list_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; paging_record_list_l paging_record_list; dyn_octstring late_non_crit_ext; @@ -8465,10 +8286,8 @@ struct cgi_info_nr_s { }; // member variables - bool ext = false; - bool plmn_id_info_list_present = false; - bool freq_band_list_present = false; - bool no_sib1_present = false; + bool ext = false; + bool no_sib1_present = false; plmn_id_info_list_l plmn_id_info_list; multi_freq_band_list_nr_l freq_band_list; no_sib1_s_ no_sib1; @@ -8521,17 +8340,14 @@ struct cgi_info_eutra_s { using cgi_info_epc_list_l_ = dyn_array; // member variables - bool cgi_info_epc_list_present = false; cell_access_related_info_eutra_epc_s cgi_info_epc_legacy; cgi_info_epc_list_l_ cgi_info_epc_list; }; using cgi_info_minus5_gc_l_ = dyn_array; // member variables - bool cgi_info_epc_present = false; - bool cgi_info_minus5_gc_present = false; - bool multi_band_info_list_present = false; - bool freq_band_ind_prio_present = false; + bool cgi_info_epc_present = false; + bool freq_band_ind_prio_present = false; cgi_info_epc_s_ cgi_info_epc; cgi_info_minus5_gc_l_ cgi_info_minus5_gc; uint16_t freq_band_ind = 1; @@ -8568,8 +8384,6 @@ struct meas_result_nr_s { meas_quant_results_s results_csi_rs_cell; }; struct rs_idx_results_s_ { - bool results_ssb_idxes_present = false; - bool results_csi_rs_idxes_present = false; results_per_ssb_idx_list_l results_ssb_idxes; results_per_csi_rs_idx_list_l results_csi_rs_idxes; }; @@ -8676,13 +8490,12 @@ struct meas_result2_eutra_s { // MeasResult2NR ::= SEQUENCE struct meas_result2_nr_s { - bool ext = false; - bool ssb_freq_present = false; - bool ref_freq_csi_rs_present = false; - bool meas_result_serving_cell_present = false; - bool meas_result_neigh_cell_list_nr_present = false; - uint32_t ssb_freq = 0; - uint32_t ref_freq_csi_rs = 0; + bool ext = false; + bool ssb_freq_present = false; + bool ref_freq_csi_rs_present = false; + bool meas_result_serving_cell_present = false; + uint32_t ssb_freq = 0; + uint32_t ref_freq_csi_rs = 0; meas_result_nr_s meas_result_serving_cell; meas_result_list_nr_l meas_result_neigh_cell_list_nr; // ... @@ -9028,9 +8841,7 @@ struct fail_report_scg_s { typedef enumerated fail_type_e_; // member variables - bool ext = false; - bool meas_result_freq_list_present = false; - bool meas_result_scg_fail_present = false; + bool ext = false; fail_type_e_ fail_type; meas_result_freq_list_l meas_result_freq_list; dyn_octstring meas_result_scg_fail; @@ -9064,9 +8875,7 @@ struct fail_report_scg_eutra_s { typedef enumerated fail_type_e_; // member variables - bool ext = false; - bool meas_result_freq_list_mrdc_present = false; - bool meas_result_scg_fail_mrdc_present = false; + bool ext = false; fail_type_e_ fail_type; meas_result_freq_list_fail_mrdc_l meas_result_freq_list_mrdc; dyn_octstring meas_result_scg_fail_mrdc; @@ -9187,8 +8996,7 @@ struct meas_results_s { // RRCReconfigurationComplete-v1530-IEs ::= SEQUENCE struct rrc_recfg_complete_v1530_ies_s { - bool ul_tx_direct_current_list_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; ul_tx_direct_current_list_l ul_tx_direct_current_list; rrc_recfg_complete_v1560_ies_s non_crit_ext; @@ -9262,8 +9070,7 @@ struct s_nssai_c { // SCGFailureInformation-v1590-IEs ::= SEQUENCE struct scg_fail_info_v1590_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; dyn_octstring late_non_crit_ext; // sequence methods @@ -9274,8 +9081,7 @@ struct scg_fail_info_v1590_ies_s { // SCGFailureInformationEUTRA-v1590-IEs ::= SEQUENCE struct scg_fail_info_eutra_v1590_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; dyn_octstring late_non_crit_ext; // sequence methods @@ -9301,8 +9107,7 @@ struct ueassist_info_v1540_ies_s { // CounterCheckResponse-IEs ::= SEQUENCE struct counter_check_resp_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; drb_count_info_list_l drb_count_info_list; dyn_octstring late_non_crit_ext; @@ -9315,7 +9120,6 @@ struct counter_check_resp_ies_s { // FailureInformation-IEs ::= SEQUENCE struct fail_info_ies_s { bool fail_info_rlc_bearer_present = false; - bool late_non_crit_ext_present = false; bool non_crit_ext_present = false; fail_info_rlc_bearer_s fail_info_rlc_bearer; dyn_octstring late_non_crit_ext; @@ -9328,8 +9132,7 @@ struct fail_info_ies_s { // LocationMeasurementIndication-IEs ::= SEQUENCE struct location_meas_ind_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; setup_release_c meas_ind; dyn_octstring late_non_crit_ext; @@ -9341,8 +9144,7 @@ struct location_meas_ind_ies_s { // MeasurementReport-IEs ::= SEQUENCE struct meas_report_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; meas_results_s meas_results; dyn_octstring late_non_crit_ext; @@ -9354,8 +9156,7 @@ struct meas_report_ies_s { // RRCReconfigurationComplete-IEs ::= SEQUENCE struct rrc_recfg_complete_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; dyn_octstring late_non_crit_ext; rrc_recfg_complete_v1530_ies_s non_crit_ext; @@ -9367,8 +9168,7 @@ struct rrc_recfg_complete_ies_s { // RRCReestablishmentComplete-IEs ::= SEQUENCE struct rrc_reest_complete_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; dyn_octstring late_non_crit_ext; // sequence methods @@ -9379,11 +9179,8 @@ struct rrc_reest_complete_ies_s { // RRCResumeComplete-IEs ::= SEQUENCE struct rrc_resume_complete_ies_s { - bool ded_nas_msg_present = false; - bool sel_plmn_id_present = false; - bool ul_tx_direct_current_list_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool sel_plmn_id_present = false; + bool non_crit_ext_present = false; dyn_octstring ded_nas_msg; uint8_t sel_plmn_id = 1; ul_tx_direct_current_list_l ul_tx_direct_current_list; @@ -9456,9 +9253,7 @@ struct rrc_setup_complete_ies_s { // member variables bool registered_amf_present = false; bool guami_type_present = false; - bool s_nssai_list_present = false; bool ng_minus5_g_s_tmsi_value_present = false; - bool late_non_crit_ext_present = false; bool non_crit_ext_present = false; uint8_t sel_plmn_id = 1; registered_amf_s registered_amf; @@ -9502,8 +9297,7 @@ struct scg_fail_info_eutra_ies_s { // SecurityModeComplete-IEs ::= SEQUENCE struct security_mode_complete_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; dyn_octstring late_non_crit_ext; // sequence methods @@ -9514,8 +9308,7 @@ struct security_mode_complete_ies_s { // SecurityModeFailure-IEs ::= SEQUENCE struct security_mode_fail_ies_s { - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; dyn_octstring late_non_crit_ext; // sequence methods @@ -9527,7 +9320,6 @@ struct security_mode_fail_ies_s { // UEAssistanceInformation-IEs ::= SEQUENCE struct ueassist_info_ies_s { bool delay_budget_report_present = false; - bool late_non_crit_ext_present = false; bool non_crit_ext_present = false; delay_budget_report_c delay_budget_report; dyn_octstring late_non_crit_ext; @@ -9542,7 +9334,6 @@ struct ueassist_info_ies_s { // UECapabilityInformation-IEs ::= SEQUENCE struct ue_cap_info_ies_s { bool ue_cap_rat_container_list_present = false; - bool late_non_crit_ext_present = false; bool non_crit_ext_present = false; ue_cap_rat_container_list_l ue_cap_rat_container_list; dyn_octstring late_non_crit_ext; @@ -9555,9 +9346,7 @@ struct ue_cap_info_ies_s { // ULInformationTransfer-IEs ::= SEQUENCE struct ul_info_transfer_ies_s { - bool ded_nas_msg_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; dyn_octstring ded_nas_msg; dyn_octstring late_non_crit_ext; @@ -9569,10 +9358,7 @@ struct ul_info_transfer_ies_s { // ULInformationTransferMRDC-IEs ::= SEQUENCE struct ul_info_transfer_mrdc_ies_s { - bool ul_dcch_msg_nr_present = false; - bool ul_dcch_msg_eutra_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; dyn_octstring ul_dcch_msg_nr; dyn_octstring ul_dcch_msg_eutra; dyn_octstring late_non_crit_ext; @@ -10636,10 +10422,9 @@ struct bfr_csirs_res_s { using ra_occasion_list_l_ = dyn_array; // member variables - bool ext = false; - bool ra_occasion_list_present = false; - bool ra_preamb_idx_present = false; - uint8_t csi_rs = 0; + bool ext = false; + bool ra_preamb_idx_present = false; + uint8_t csi_rs = 0; ra_occasion_list_l_ ra_occasion_list; uint8_t ra_preamb_idx = 0; // ... @@ -11652,15 +11437,11 @@ struct pdcch_cfg_s { using search_spaces_to_release_list_l_ = bounded_array; // member variables - bool ext = false; - bool ctrl_res_set_to_add_mod_list_present = false; - bool ctrl_res_set_to_release_list_present = false; - bool search_spaces_to_add_mod_list_present = false; - bool search_spaces_to_release_list_present = false; - bool dl_preemption_present = false; - bool tpc_pusch_present = false; - bool tpc_pucch_present = false; - bool tpc_srs_present = false; + bool ext = false; + bool dl_preemption_present = false; + bool tpc_pusch_present = false; + bool tpc_pucch_present = false; + bool tpc_srs_present = false; ctrl_res_set_to_add_mod_list_l_ ctrl_res_set_to_add_mod_list; ctrl_res_set_to_release_list_l_ ctrl_res_set_to_release_list; search_spaces_to_add_mod_list_l_ search_spaces_to_add_mod_list; @@ -11823,35 +11604,23 @@ struct pdsch_cfg_s { using sp_zp_csi_rs_res_sets_to_release_list_l_ = bounded_array; // member variables - bool ext = false; - bool data_scrambling_id_pdsch_present = false; - bool dmrs_dl_for_pdsch_map_type_a_present = false; - bool dmrs_dl_for_pdsch_map_type_b_present = false; - bool tci_states_to_add_mod_list_present = false; - bool tci_states_to_release_list_present = false; - bool vrb_to_prb_interleaver_present = false; - bool pdsch_time_domain_alloc_list_present = false; - bool pdsch_aggregation_factor_present = false; - bool rate_match_pattern_to_add_mod_list_present = false; - bool rate_match_pattern_to_release_list_present = false; - bool rate_match_pattern_group1_present = false; - bool rate_match_pattern_group2_present = false; - bool mcs_table_present = false; - bool max_nrof_code_words_sched_by_dci_present = false; - bool zp_csi_rs_res_to_add_mod_list_present = false; - bool zp_csi_rs_res_to_release_list_present = false; - bool aperiodic_zp_csi_rs_res_sets_to_add_mod_list_present = false; - bool aperiodic_zp_csi_rs_res_sets_to_release_list_present = false; - bool sp_zp_csi_rs_res_sets_to_add_mod_list_present = false; - bool sp_zp_csi_rs_res_sets_to_release_list_present = false; - bool p_zp_csi_rs_res_set_present = false; - uint16_t data_scrambling_id_pdsch = 0; - setup_release_c dmrs_dl_for_pdsch_map_type_a; - setup_release_c dmrs_dl_for_pdsch_map_type_b; - tci_states_to_add_mod_list_l_ tci_states_to_add_mod_list; - tci_states_to_release_list_l_ tci_states_to_release_list; - vrb_to_prb_interleaver_e_ vrb_to_prb_interleaver; - res_alloc_e_ res_alloc; + bool ext = false; + bool data_scrambling_id_pdsch_present = false; + bool dmrs_dl_for_pdsch_map_type_a_present = false; + bool dmrs_dl_for_pdsch_map_type_b_present = false; + bool vrb_to_prb_interleaver_present = false; + bool pdsch_time_domain_alloc_list_present = false; + bool pdsch_aggregation_factor_present = false; + bool mcs_table_present = false; + bool max_nrof_code_words_sched_by_dci_present = false; + bool p_zp_csi_rs_res_set_present = false; + uint16_t data_scrambling_id_pdsch = 0; + setup_release_c dmrs_dl_for_pdsch_map_type_a; + setup_release_c dmrs_dl_for_pdsch_map_type_b; + tci_states_to_add_mod_list_l_ tci_states_to_add_mod_list; + tci_states_to_release_list_l_ tci_states_to_release_list; + vrb_to_prb_interleaver_e_ vrb_to_prb_interleaver; + res_alloc_e_ res_alloc; setup_release_c > pdsch_time_domain_alloc_list; pdsch_aggregation_factor_e_ pdsch_aggregation_factor; rate_match_pattern_to_add_mod_list_l_ rate_match_pattern_to_add_mod_list; @@ -11899,11 +11668,9 @@ struct radio_link_monitoring_cfg_s { typedef enumerated beam_fail_detection_timer_e_; // member variables - bool ext = false; - bool fail_detection_res_to_add_mod_list_present = false; - bool fail_detection_res_to_release_list_present = false; - bool beam_fail_instance_max_count_present = false; - bool beam_fail_detection_timer_present = false; + bool ext = false; + bool beam_fail_instance_max_count_present = false; + bool beam_fail_detection_timer_present = false; fail_detection_res_to_add_mod_list_l_ fail_detection_res_to_add_mod_list; fail_detection_res_to_release_list_l_ fail_detection_res_to_release_list; beam_fail_instance_max_count_e_ beam_fail_instance_max_count; @@ -12844,8 +12611,6 @@ struct pucch_pwr_ctrl_s { bool delta_f_pucch_f2_present = false; bool delta_f_pucch_f3_present = false; bool delta_f_pucch_f4_present = false; - bool p0_set_present = false; - bool pathloss_ref_rss_present = false; bool two_pucch_pc_adjustment_states_present = false; int8_t delta_f_pucch_f0 = -16; int8_t delta_f_pucch_f1 = -16; @@ -13076,16 +12841,11 @@ struct pusch_pwr_ctrl_s { using sri_pusch_map_to_release_list_l_ = bounded_array; // member variables - bool tpc_accumulation_present = false; - bool msg3_alpha_present = false; - bool p0_nominal_without_grant_present = false; - bool p0_alpha_sets_present = false; - bool pathloss_ref_rs_to_add_mod_list_present = false; - bool pathloss_ref_rs_to_release_list_present = false; - bool two_pusch_pc_adjustment_states_present = false; - bool delta_mcs_present = false; - bool sri_pusch_map_to_add_mod_list_present = false; - bool sri_pusch_map_to_release_list_present = false; + bool tpc_accumulation_present = false; + bool msg3_alpha_present = false; + bool p0_nominal_without_grant_present = false; + bool two_pusch_pc_adjustment_states_present = false; + bool delta_mcs_present = false; alpha_e msg3_alpha; int16_t p0_nominal_without_grant = -202; p0_alpha_sets_l_ p0_alpha_sets; @@ -13498,7 +13258,6 @@ struct srs_res_set_s { // member variables bool ext = false; - bool srs_res_id_list_present = false; bool alpha_present = false; bool p0_present = false; bool pathloss_ref_rs_present = false; @@ -13809,7 +13568,6 @@ struct beam_fail_recovery_cfg_s { bool root_seq_idx_bfr_present = false; bool rach_cfg_bfr_present = false; bool rsrp_thres_ssb_present = false; - bool candidate_beam_rs_list_present = false; bool ssb_per_rach_occasion_present = false; bool ra_ssb_occasion_mask_idx_present = false; bool recovery_search_space_id_present = false; @@ -14016,22 +13774,12 @@ struct pucch_cfg_s { using spatial_relation_info_to_release_list_l_ = bounded_array; // member variables - bool ext = false; - bool res_set_to_add_mod_list_present = false; - bool res_set_to_release_list_present = false; - bool res_to_add_mod_list_present = false; - bool res_to_release_list_present = false; - bool format1_present = false; - bool format2_present = false; - bool format3_present = false; - bool format4_present = false; - bool sched_request_res_to_add_mod_list_present = false; - bool sched_request_res_to_release_list_present = false; - bool multi_csi_pucch_res_list_present = false; - bool dl_data_to_ul_ack_present = false; - bool spatial_relation_info_to_add_mod_list_present = false; - bool spatial_relation_info_to_release_list_present = false; - bool pucch_pwr_ctrl_present = false; + bool ext = false; + bool format1_present = false; + bool format2_present = false; + bool format3_present = false; + bool format4_present = false; + bool pucch_pwr_ctrl_present = false; res_set_to_add_mod_list_l_ res_set_to_add_mod_list; res_set_to_release_list_l_ res_set_to_release_list; res_to_add_mod_list_l_ res_to_add_mod_list; @@ -14123,7 +13871,6 @@ struct pusch_cfg_s { bool dmrs_ul_for_pusch_map_type_b_present = false; bool pusch_pwr_ctrl_present = false; bool freq_hop_present = false; - bool freq_hop_offset_lists_present = false; bool pusch_time_domain_alloc_list_present = false; bool pusch_aggregation_factor_present = false; bool mcs_table_present = false; @@ -14166,12 +13913,8 @@ struct srs_cfg_s { using srs_res_to_add_mod_list_l_ = dyn_array; // member variables - bool ext = false; - bool srs_res_set_to_release_list_present = false; - bool srs_res_set_to_add_mod_list_present = false; - bool srs_res_to_release_list_present = false; - bool srs_res_to_add_mod_list_present = false; - bool tpc_accumulation_present = false; + bool ext = false; + bool tpc_accumulation_present = false; srs_res_set_to_release_list_l_ srs_res_set_to_release_list; srs_res_set_to_add_mod_list_l_ srs_res_set_to_add_mod_list; srs_res_to_release_list_l_ srs_res_to_release_list; @@ -15905,8 +15648,7 @@ struct csi_associated_report_cfg_info_s { using qcl_info_l_ = bounded_array; // member variables - bool qcl_info_present = false; - uint8_t res_set = 1; + uint8_t res_set = 1; qcl_info_l_ qcl_info; }; struct types_opts { @@ -17703,7 +17445,6 @@ struct csi_report_cfg_s { bool codebook_cfg_present = false; bool dummy_present = false; bool cqi_table_present = false; - bool non_pmi_port_ind_present = false; uint8_t report_cfg_id = 0; uint8_t carrier = 0; uint8_t res_for_ch_meas = 0; @@ -17738,8 +17479,7 @@ struct csi_res_cfg_s { using csi_ssb_res_set_list_l_ = std::array; // member variables - bool nzp_csi_rs_res_set_list_present = false; - bool csi_ssb_res_set_list_present = false; + bool csi_ssb_res_set_list_present = false; nzp_csi_rs_res_set_list_l_ nzp_csi_rs_res_set_list; csi_ssb_res_set_list_l_ csi_ssb_res_set_list; }; @@ -17908,20 +17648,6 @@ struct csi_meas_cfg_s { // member variables bool ext = false; - bool nzp_csi_rs_res_to_add_mod_list_present = false; - bool nzp_csi_rs_res_to_release_list_present = false; - bool nzp_csi_rs_res_set_to_add_mod_list_present = false; - bool nzp_csi_rs_res_set_to_release_list_present = false; - bool csi_im_res_to_add_mod_list_present = false; - bool csi_im_res_to_release_list_present = false; - bool csi_im_res_set_to_add_mod_list_present = false; - bool csi_im_res_set_to_release_list_present = false; - bool csi_ssb_res_set_to_add_mod_list_present = false; - bool csi_ssb_res_set_to_release_list_present = false; - bool csi_res_cfg_to_add_mod_list_present = false; - bool csi_res_cfg_to_release_list_present = false; - bool csi_report_cfg_to_add_mod_list_present = false; - bool csi_report_cfg_to_release_list_present = false; bool report_trigger_size_present = false; bool aperiodic_trigger_state_list_present = false; bool semi_persistent_on_pusch_trigger_state_list_present = false; @@ -18132,7 +17858,6 @@ struct freq_info_ul_s { // member variables bool ext = false; - bool freq_band_list_present = false; bool absolute_freq_point_a_present = false; bool add_spec_emission_present = false; bool p_max_present = false; @@ -18177,7 +17902,6 @@ struct srs_tpc_pdcch_cfg_s { using srs_cc_set_idxlist_l_ = dyn_array; // member variables - bool srs_cc_set_idxlist_present = false; srs_cc_set_idxlist_l_ srs_cc_set_idxlist; // sequence methods @@ -18191,11 +17915,10 @@ struct slot_format_combinations_per_cell_s { using slot_format_combinations_l_ = dyn_array; // member variables - bool ext = false; - bool subcarrier_spacing2_present = false; - bool slot_format_combinations_present = false; - bool position_in_dci_present = false; - uint8_t serving_cell_id = 0; + bool ext = false; + bool subcarrier_spacing2_present = false; + bool position_in_dci_present = false; + uint8_t serving_cell_id = 0; subcarrier_spacing_e subcarrier_spacing; subcarrier_spacing_e subcarrier_spacing2; slot_format_combinations_l_ slot_format_combinations; @@ -18425,8 +18148,7 @@ struct rate_match_pattern_lte_crs_s { typedef enumerated v_shift_e_; // member variables - bool mbsfn_sf_cfg_list_present = false; - uint16_t carrier_freq_dl = 0; + uint16_t carrier_freq_dl = 0; carrier_bw_dl_e_ carrier_bw_dl; eutra_mbsfn_sf_cfg_list_l mbsfn_sf_cfg_list; nrof_crs_ports_e_ nrof_crs_ports; @@ -18521,7 +18243,6 @@ struct srs_carrier_switching_s { bool ext = false; bool srs_switch_from_serv_cell_idx_present = false; bool srs_tpc_pdcch_group_present = false; - bool monitoring_cells_present = false; uint8_t srs_switch_from_serv_cell_idx = 0; srs_switch_from_carrier_e_ srs_switch_from_carrier; srs_tpc_pdcch_group_c_ srs_tpc_pdcch_group; @@ -18540,11 +18261,9 @@ struct slot_format_ind_s { using slot_format_comb_to_release_list_l_ = bounded_array; // member variables - bool ext = false; - bool slot_format_comb_to_add_mod_list_present = false; - bool slot_format_comb_to_release_list_present = false; - uint32_t sfi_rnti = 0; - uint8_t dci_payload_size = 1; + bool ext = false; + uint32_t sfi_rnti = 0; + uint8_t dci_payload_size = 1; slot_format_comb_to_add_mod_list_l_ slot_format_comb_to_add_mod_list; slot_format_comb_to_release_list_l_ slot_format_comb_to_release_list; // ... @@ -19102,20 +18821,18 @@ struct serving_cell_cfg_common_s { using rate_match_pattern_to_release_list_l_ = bounded_array; // member variables - bool ext = false; - bool pci_present = false; - bool dl_cfg_common_present = false; - bool ul_cfg_common_present = false; - bool supplementary_ul_cfg_present = false; - bool n_timing_advance_offset_present = false; - bool ssb_positions_in_burst_present = false; - bool ssb_periodicity_serving_cell_present = false; - bool lte_crs_to_match_around_present = false; - bool rate_match_pattern_to_add_mod_list_present = false; - bool rate_match_pattern_to_release_list_present = false; - bool ssb_subcarrier_spacing_present = false; - bool tdd_ul_dl_cfg_common_present = false; - uint16_t pci = 0; + bool ext = false; + bool pci_present = false; + bool dl_cfg_common_present = false; + bool ul_cfg_common_present = false; + bool supplementary_ul_cfg_present = false; + bool n_timing_advance_offset_present = false; + bool ssb_positions_in_burst_present = false; + bool ssb_periodicity_serving_cell_present = false; + bool lte_crs_to_match_around_present = false; + bool ssb_subcarrier_spacing_present = false; + bool tdd_ul_dl_cfg_common_present = false; + uint16_t pci = 0; dl_cfg_common_s dl_cfg_common; ul_cfg_common_s ul_cfg_common; ul_cfg_common_s supplementary_ul_cfg; @@ -19156,9 +18873,7 @@ struct tdd_ul_dl_cfg_ded_s { using slot_specific_cfgs_to_release_list_l_ = dyn_array; // member variables - bool ext = false; - bool slot_specific_cfgs_to_add_mod_list_present = false; - bool slot_specific_cfgs_to_release_list_present = false; + bool ext = false; slot_specific_cfgs_to_add_mod_list_l_ slot_specific_cfgs_to_add_mod_list; slot_specific_cfgs_to_release_list_l_ slot_specific_cfgs_to_release_list; // ... @@ -19214,8 +18929,6 @@ struct ul_cfg_s { // member variables bool ext = false; bool init_ul_bwp_present = false; - bool ul_bwp_to_release_list_present = false; - bool ul_bwp_to_add_mod_list_present = false; bool first_active_ul_bwp_id_present = false; bool pusch_serving_cell_cfg_present = false; bool carrier_switching_present = false; @@ -19954,8 +19667,6 @@ struct lc_ch_cfg_s { // member variables bool ext = false; - bool allowed_serving_cells_present = false; - bool allowed_scs_list_present = false; bool max_pusch_dur_present = false; bool cfgured_grant_type1_allowed_present = false; bool lc_ch_group_present = false; @@ -20261,8 +19972,6 @@ struct sched_request_cfg_s { using sched_request_to_release_list_l_ = bounded_array; // member variables - bool sched_request_to_add_mod_list_present = false; - bool sched_request_to_release_list_present = false; sched_request_to_add_mod_list_l_ sched_request_to_add_mod_list; sched_request_to_release_list_l_ sched_request_to_release_list; @@ -20357,8 +20066,6 @@ struct serving_cell_cfg_s { bool ext = false; bool tdd_ul_dl_cfg_ded_present = false; bool init_dl_bwp_present = false; - bool dl_bwp_to_release_list_present = false; - bool dl_bwp_to_add_mod_list_present = false; bool first_active_dl_bwp_id_present = false; bool bwp_inactivity_timer_present = false; bool default_dl_bwp_id_present = false; @@ -20408,8 +20115,6 @@ struct tag_cfg_s { using tag_to_add_mod_list_l_ = dyn_array; // member variables - bool tag_to_release_list_present = false; - bool tag_to_add_mod_list_present = false; tag_to_release_list_l_ tag_to_release_list; tag_to_add_mod_list_l_ tag_to_add_mod_list; @@ -20612,15 +20317,11 @@ struct cell_group_cfg_s { using scell_to_release_list_l_ = bounded_array; // member variables - bool ext = false; - bool rlc_bearer_to_add_mod_list_present = false; - bool rlc_bearer_to_release_list_present = false; - bool mac_cell_group_cfg_present = false; - bool phys_cell_group_cfg_present = false; - bool sp_cell_cfg_present = false; - bool scell_to_add_mod_list_present = false; - bool scell_to_release_list_present = false; - uint8_t cell_group_id = 0; + bool ext = false; + bool mac_cell_group_cfg_present = false; + bool phys_cell_group_cfg_present = false; + bool sp_cell_cfg_present = false; + uint8_t cell_group_id = 0; rlc_bearer_to_add_mod_list_l_ rlc_bearer_to_add_mod_list; rlc_bearer_to_release_list_l_ rlc_bearer_to_release_list; mac_cell_group_cfg_s mac_cell_group_cfg; @@ -21153,10 +20854,6 @@ struct feature_set_dl_s { bool time_dur_for_qcl_present = false; bool pdsch_processing_type1_different_tb_per_slot_present = false; bool dummy3_present = false; - bool dummy4_present = false; - bool dummy5_present = false; - bool dummy6_present = false; - bool dummy7_present = false; feature_set_list_per_dl_cc_l_ feature_set_list_per_dl_cc; freq_separation_class_e intra_band_freq_separation_dl; scaling_factor_e_ scaling_factor; @@ -21592,11 +21289,7 @@ struct feature_sets_s { using feature_sets_dl_v15a0_l_ = dyn_array; // member variables - bool ext = false; - bool feature_sets_dl_present = false; - bool feature_sets_dl_per_cc_present = false; - bool feature_sets_ul_present = false; - bool feature_sets_ul_per_cc_present = false; + bool ext = false; feature_sets_dl_l_ feature_sets_dl; feature_sets_dl_per_cc_l_ feature_sets_dl_per_cc; feature_sets_ul_l_ feature_sets_ul; @@ -22073,7 +21766,6 @@ struct nrdc_params_s { bool tdd_add_ue_nrdc_cap_present = false; bool fr1_add_ue_nrdc_cap_present = false; bool fr2_add_ue_nrdc_cap_present = false; - bool late_non_crit_ext_present = false; bool dummy_present = false; meas_and_mob_params_mrdc_s meas_and_mob_params_nrdc; general_params_mrdc_xdd_diff_s general_params_nrdc; @@ -22461,8 +22153,7 @@ struct phy_params_mrdc_s { using naics_cap_list_l_ = dyn_array; // member variables - bool ext = false; - bool naics_cap_list_present = false; + bool ext = false; naics_cap_list_l_ naics_cap_list; // ... // group 0 @@ -22479,9 +22170,7 @@ struct rf_params_s { using supported_band_list_nr_l_ = dyn_array; // member variables - bool ext = false; - bool supported_band_combination_list_present = false; - bool applied_freq_band_list_filt_present = false; + bool ext = false; supported_band_list_nr_l_ supported_band_list_nr; band_combination_list_l supported_band_combination_list; freq_band_list_l applied_freq_band_list_filt; @@ -22503,11 +22192,6 @@ struct rf_params_s { // RF-ParametersMRDC ::= SEQUENCE struct rf_params_mrdc_s { struct supported_band_combination_list_nedc_only_v15a0_s_ { - bool supported_band_combination_list_v1540_present = false; - bool supported_band_combination_list_v1560_present = false; - bool supported_band_combination_list_v1570_present = false; - bool supported_band_combination_list_v1580_present = false; - bool supported_band_combination_list_v1590_present = false; band_combination_list_v1540_l supported_band_combination_list_v1540; band_combination_list_v1560_l supported_band_combination_list_v1560; band_combination_list_v1570_l supported_band_combination_list_v1570; @@ -22516,9 +22200,7 @@ struct rf_params_mrdc_s { }; // member variables - bool ext = false; - bool supported_band_combination_list_present = false; - bool applied_freq_band_list_filt_present = false; + bool ext = false; band_combination_list_l supported_band_combination_list; freq_band_list_l applied_freq_band_list_filt; // ... @@ -22558,8 +22240,7 @@ struct ue_cap_request_filt_nr_v1540_s { // UE-CapabilityRequestFilterNR ::= SEQUENCE struct ue_cap_request_filt_nr_s { - bool freq_band_list_filt_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; freq_band_list_l freq_band_list_filt; ue_cap_request_filt_nr_v1540_s non_crit_ext; @@ -22593,7 +22274,6 @@ struct pdcp_params_mrdc_s { // UE-MRDC-Capability-v1560 ::= SEQUENCE struct ue_mrdc_cap_v1560_s { - bool rx_filts_present = false; bool meas_and_mob_params_mrdc_v1560_present = false; bool fdd_add_ue_mrdc_cap_v1560_present = false; bool tdd_add_ue_mrdc_cap_v1560_present = false; @@ -22621,9 +22301,7 @@ struct ue_mrdc_cap_s { bool tdd_add_ue_mrdc_cap_present = false; bool fr1_add_ue_mrdc_cap_present = false; bool fr2_add_ue_mrdc_cap_present = false; - bool feature_set_combinations_present = false; bool pdcp_params_mrdc_v1530_present = false; - bool late_non_crit_ext_present = false; bool non_crit_ext_present = false; meas_and_mob_params_mrdc_s meas_and_mob_params_mrdc; phy_params_mrdc_s phy_params_mrdc_v1530; @@ -22669,7 +22347,6 @@ struct ue_nr_cap_v1570_s { // UE-NR-Capability-v1560 ::= SEQUENCE struct ue_nr_cap_v1560_s { bool nrdc_params_present = false; - bool rx_filts_present = false; bool non_crit_ext_present = false; nrdc_params_s nrdc_params; dyn_octstring rx_filts; @@ -22884,17 +22561,15 @@ struct ue_nr_cap_s { using feature_set_combinations_l_ = dyn_array; // member variables - bool rlc_params_present = false; - bool mac_params_present = false; - bool meas_and_mob_params_present = false; - bool fdd_add_ue_nr_cap_present = false; - bool tdd_add_ue_nr_cap_present = false; - bool fr1_add_ue_nr_cap_present = false; - bool fr2_add_ue_nr_cap_present = false; - bool feature_sets_present = false; - bool feature_set_combinations_present = false; - bool late_non_crit_ext_present = false; - bool non_crit_ext_present = false; + bool rlc_params_present = false; + bool mac_params_present = false; + bool meas_and_mob_params_present = false; + bool fdd_add_ue_nr_cap_present = false; + bool tdd_add_ue_nr_cap_present = false; + bool fr1_add_ue_nr_cap_present = false; + bool fr2_add_ue_nr_cap_present = false; + bool feature_sets_present = false; + bool non_crit_ext_present = false; access_stratum_release_e access_stratum_release; pdcp_params_s pdcp_params; rlc_params_s rlc_params; @@ -22955,9 +22630,6 @@ struct as_cfg_s { dyn_octstring rrc_recfg; // ... // group 0 - bool source_rb_sn_cfg_present = false; - bool source_scg_nr_cfg_present = false; - bool source_scg_eutra_cfg_present = false; dyn_octstring source_rb_sn_cfg; dyn_octstring source_scg_nr_cfg; dyn_octstring source_scg_eutra_cfg; @@ -23034,7 +22706,6 @@ struct cfg_restrict_info_scg_s { // member variables bool ext = false; - bool allowed_bc_list_mrdc_present = false; bool pwr_coordination_fr1_present = false; bool serv_cell_idx_range_scg_present = false; bool max_meas_freqs_scg_present = false; @@ -23065,8 +22736,7 @@ struct cfg_restrict_info_scg_s { // ReestablishmentInfo ::= SEQUENCE struct reest_info_s { - bool add_reestab_info_list_present = false; - uint16_t source_pci = 0; + uint16_t source_pci = 0; fixed_bitstring<16> target_cell_short_mac_i; reestab_ncell_info_list_l add_reestab_info_list; @@ -23087,7 +22757,6 @@ struct as_context_s { // group 0 copy_ptr ran_notif_area_info; // group 1 - bool ue_assist_info_present = false; dyn_octstring ue_assist_info; // group 2 copy_ptr sel_band_combination_sn; @@ -23128,7 +22797,6 @@ struct affected_carrier_freq_comb_info_mrdc_s { }; typedef enumerated interference_direction_mrdc_e_; struct affected_carrier_freq_comb_mrdc_s_ { - bool affected_carrier_freq_comb_eutra_present = false; affected_carrier_freq_comb_eutra_l affected_carrier_freq_comb_eutra; affected_carrier_freq_comb_nr_l affected_carrier_freq_comb_nr; }; @@ -23173,9 +22841,7 @@ struct cg_cfg_v1590_ies_s { using scell_frequencies_sn_eutra_l_ = bounded_array; // member variables - bool scell_frequencies_sn_nr_present = false; - bool scell_frequencies_sn_eutra_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; scell_frequencies_sn_nr_l_ scell_frequencies_sn_nr; scell_frequencies_sn_eutra_l_ scell_frequencies_sn_eutra; @@ -23217,15 +22883,12 @@ struct cg_cfg_v1560_ies_s { }; // member variables - bool pscell_freq_eutra_present = false; - bool scg_cell_group_cfg_eutra_present = false; - bool candidate_cell_info_list_sn_eutra_present = false; - bool candidate_serving_freq_list_eutra_present = false; - bool need_for_gaps_present = false; - bool drx_cfg_scg_present = false; - bool report_cgi_request_eutra_present = false; - bool non_crit_ext_present = false; - uint32_t pscell_freq_eutra = 0; + bool pscell_freq_eutra_present = false; + bool need_for_gaps_present = false; + bool drx_cfg_scg_present = false; + bool report_cgi_request_eutra_present = false; + bool non_crit_ext_present = false; + uint32_t pscell_freq_eutra = 0; dyn_octstring scg_cell_group_cfg_eutra; dyn_octstring candidate_cell_info_list_sn_eutra; candidate_serving_freq_list_eutra_l candidate_serving_freq_list_eutra; @@ -23292,7 +22955,6 @@ struct cg_cfg_v1540_ies_s { // member variables bool pscell_freq_present = false; bool report_cgi_request_nr_present = false; - bool ph_info_scg_present = false; bool non_crit_ext_present = false; uint32_t pscell_freq = 0; report_cgi_request_nr_s_ report_cgi_request_nr; @@ -23668,8 +23330,7 @@ struct meas_cfg_sn_s { using measured_frequencies_sn_l_ = dyn_array; // member variables - bool ext = false; - bool measured_frequencies_sn_present = false; + bool ext = false; measured_frequencies_sn_l_ measured_frequencies_sn; // ... @@ -23681,16 +23342,11 @@ struct meas_cfg_sn_s { // CG-Config-IEs ::= SEQUENCE struct cg_cfg_ies_s { - bool scg_cell_group_cfg_present = false; - bool scg_rb_cfg_present = false; - bool cfg_restrict_mod_req_present = false; - bool drx_info_scg_present = false; - bool candidate_cell_info_list_sn_present = false; - bool meas_cfg_sn_present = false; - bool sel_band_combination_present = false; - bool fr_info_list_scg_present = false; - bool candidate_serving_freq_list_nr_present = false; - bool non_crit_ext_present = false; + bool cfg_restrict_mod_req_present = false; + bool drx_info_scg_present = false; + bool meas_cfg_sn_present = false; + bool sel_band_combination_present = false; + bool non_crit_ext_present = false; dyn_octstring scg_cell_group_cfg; dyn_octstring scg_rb_cfg; cfg_restrict_mod_req_scg_s cfg_restrict_mod_req; @@ -23795,8 +23451,7 @@ struct cg_cfg_info_v1590_ies_s { using serv_frequencies_mn_nr_l_ = bounded_array; // member variables - bool serv_frequencies_mn_nr_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; serv_frequencies_mn_nr_l_ serv_frequencies_mn_nr; // sequence methods @@ -23835,9 +23490,7 @@ using sftd_freq_list_nr_l = bounded_array; // CG-ConfigInfo-v1570-IEs ::= SEQUENCE struct cg_cfg_info_v1570_ies_s { - bool sftd_freq_list_nr_present = false; - bool sftd_freq_list_eutra_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; sftd_freq_list_nr_l sftd_freq_list_nr; sftd_freq_list_eutra_l sftd_freq_list_eutra; cg_cfg_info_v1590_ies_s non_crit_ext; @@ -23886,15 +23539,10 @@ struct cg_cfg_info_v1560_ies_s { }; // member variables - bool candidate_cell_info_list_mn_eutra_present = false; - bool candidate_cell_info_list_sn_eutra_present = false; - bool source_cfg_scg_eutra_present = false; - bool scg_fail_info_eutra_present = false; - bool drx_cfg_mcg_present = false; - bool meas_result_report_cgi_eutra_present = false; - bool meas_result_cell_list_sftd_eutra_present = false; - bool fr_info_list_mcg_present = false; - bool non_crit_ext_present = false; + bool scg_fail_info_eutra_present = false; + bool drx_cfg_mcg_present = false; + bool meas_result_report_cgi_eutra_present = false; + bool non_crit_ext_present = false; dyn_octstring candidate_cell_info_list_mn_eutra; dyn_octstring candidate_cell_info_list_sn_eutra; dyn_octstring source_cfg_scg_eutra; @@ -23923,7 +23571,6 @@ struct cg_cfg_info_v1540_ies_s { }; // member variables - bool ph_info_mcg_present = false; bool meas_result_report_cgi_present = false; bool non_crit_ext_present = false; ph_type_list_mcg_l ph_info_mcg; @@ -23964,10 +23611,9 @@ struct meas_cfg_mn_s { typedef enumerated gap_purpose_e_; // member variables - bool ext = false; - bool measured_frequencies_mn_present = false; - bool meas_gap_cfg_present = false; - bool gap_purpose_present = false; + bool ext = false; + bool meas_gap_cfg_present = false; + bool gap_purpose_present = false; measured_frequencies_mn_l_ measured_frequencies_mn; setup_release_c meas_gap_cfg; gap_purpose_e_ gap_purpose; @@ -24007,19 +23653,12 @@ struct cg_cfg_info_ies_s { }; // member variables - bool ue_cap_info_present = false; - bool candidate_cell_info_list_mn_present = false; - bool candidate_cell_info_list_sn_present = false; - bool meas_result_cell_list_sftd_nr_present = false; - bool scg_fail_info_present = false; - bool cfg_restrict_info_present = false; - bool drx_info_mcg_present = false; - bool meas_cfg_mn_present = false; - bool source_cfg_scg_present = false; - bool scg_rb_cfg_present = false; - bool mcg_rb_cfg_present = false; - bool mrdc_assist_info_present = false; - bool non_crit_ext_present = false; + bool scg_fail_info_present = false; + bool cfg_restrict_info_present = false; + bool drx_info_mcg_present = false; + bool meas_cfg_mn_present = false; + bool mrdc_assist_info_present = false; + bool non_crit_ext_present = false; dyn_octstring ue_cap_info; meas_result_list2_nr_l candidate_cell_info_list_mn; dyn_octstring candidate_cell_info_list_sn; @@ -24343,9 +23982,8 @@ struct rrm_cfg_s { typedef enumerated ue_inactive_time_e_; // member variables - bool ext = false; - bool ue_inactive_time_present = false; - bool candidate_cell_info_list_present = false; + bool ext = false; + bool ue_inactive_time_present = false; ue_inactive_time_e_ ue_inactive_time; meas_result_list2_nr_l candidate_cell_info_list; // ... @@ -24500,7 +24138,6 @@ struct meas_timing_cfg_v1550_ies_s { // MeasurementTimingConfiguration-IEs ::= SEQUENCE struct meas_timing_cfg_ies_s { - bool meas_timing_present = false; bool non_crit_ext_present = false; meas_timing_list_l meas_timing; meas_timing_cfg_v1550_ies_s non_crit_ext; @@ -24705,8 +24342,7 @@ struct ue_radio_paging_info_ies_s { using supported_band_list_nr_for_paging_l_ = dyn_array; // member variables - bool supported_band_list_nr_for_paging_present = false; - bool non_crit_ext_present = false; + bool non_crit_ext_present = false; supported_band_list_nr_for_paging_l_ supported_band_list_nr_for_paging; // sequence methods @@ -24853,11 +24489,8 @@ struct var_meas_cfg_s { }; // member variables - bool meas_id_list_present = false; - bool meas_obj_list_present = false; - bool report_cfg_list_present = false; - bool quant_cfg_present = false; - bool s_measure_cfg_present = false; + bool quant_cfg_present = false; + bool s_measure_cfg_present = false; meas_id_to_add_mod_list_l meas_id_list; meas_obj_to_add_mod_list_l meas_obj_list; report_cfg_to_add_mod_list_l report_cfg_list; @@ -24872,8 +24505,7 @@ struct var_meas_cfg_s { // VarMeasReport ::= SEQUENCE struct var_meas_report_s { - bool cells_triggered_list_present = false; - uint8_t meas_id = 1; + uint8_t meas_id = 1; cells_triggered_list_l cells_triggered_list; int64_t nof_reports_sent = 0; diff --git a/lib/include/srsran/asn1/rrc_nr_utils.h b/lib/include/srsran/asn1/rrc_nr_utils.h index 6aa1608499..87f8ae80a1 100644 --- a/lib/include/srsran/asn1/rrc_nr_utils.h +++ b/lib/include/srsran/asn1/rrc_nr_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,7 +22,6 @@ #ifndef SRSRAN_RRC_NR_UTILS_H #define SRSRAN_RRC_NR_UTILS_H -#include "srsenb/hdr/stack/mac/sched_interface.h" #include "srsran/common/phy_cfg_nr.h" #include "srsran/interfaces/mac_interface_types.h" #include "srsran/interfaces/pdcp_interface_types.h" @@ -65,9 +64,18 @@ struct nzp_csi_rs_res_s; struct pdsch_serving_cell_cfg_s; struct freq_info_dl_s; struct serving_cell_cfg_common_s; +struct serving_cell_cfg_common_sib_s; struct serving_cell_cfg_s; struct pdcch_cfg_common_s; struct pdcch_cfg_s; +struct pdsch_cfg_common_s; +struct pucch_cfg_common_s; +struct pucch_cfg_s; +struct pusch_cfg_common_s; +struct mib_s; + +struct srb_to_add_mod_s; +struct drb_to_add_mod_s; } // namespace rrc_nr } // namespace asn1 @@ -82,13 +90,20 @@ void to_asn1(asn1::rrc_nr::plmn_id_s* asn1_type, const plmn_id_t& cfg); /*************************** * PHY Config **************************/ -bool make_phy_rach_cfg(const asn1::rrc_nr::rach_cfg_common_s& asn1_type, srsran_prach_cfg_t* prach_cfg); +bool make_phy_rach_cfg(const asn1::rrc_nr::rach_cfg_common_s& asn1_type, + srsran_duplex_mode_t duplex_mode, + srsran_prach_cfg_t* prach_cfg); +bool fill_rach_cfg_common(const srsran_prach_cfg_t& prach_cfg, asn1::rrc_nr::rach_cfg_common_s& asn1_type); bool make_phy_tdd_cfg(const asn1::rrc_nr::tdd_ul_dl_cfg_common_s& tdd_ul_dl_cfg_common, srsran_duplex_config_nr_t* srsran_duplex_config_nr); +bool make_phy_tdd_cfg(const srsran_duplex_config_nr_t& srsran_duplex_config_nr, + srsran_subcarrier_spacing_t scs, + asn1::rrc_nr::tdd_ul_dl_cfg_common_s* tdd_ul_dl_cfg_common); bool make_phy_harq_ack_cfg(const asn1::rrc_nr::phys_cell_group_cfg_s& phys_cell_group_cfg, srsran_harq_ack_cfg_hl_t* srsran_ue_dl_nr_harq_ack_cfg); bool make_phy_coreset_cfg(const asn1::rrc_nr::ctrl_res_set_s& ctrl_res_set, srsran_coreset_t* srsran_coreset); +void make_phy_search_space0_cfg(srsran_search_space_t* in_srsran_search_space); bool make_phy_search_space_cfg(const asn1::rrc_nr::search_space_s& search_space, srsran_search_space_t* srsran_search_space); bool make_phy_csi_report(const asn1::rrc_nr::csi_report_cfg_s& csi_report_cfg, @@ -122,39 +137,68 @@ bool make_phy_zp_csi_rs_resource(const asn1::rrc_nr::zp_csi_rs_res_s& zp_csi_rs_ bool make_phy_nzp_csi_rs_resource(const asn1::rrc_nr::nzp_csi_rs_res_s& nzp_csi_rs_res, srsran_csi_rs_nzp_resource_t* csi_rs_nzp_resource); bool make_phy_carrier_cfg(const asn1::rrc_nr::freq_info_dl_s& freq_info_dl, srsran_carrier_nr_t* carrier_nr); +bool fill_phy_ssb_cfg(const srsran_carrier_nr_t& carrier, + const asn1::rrc_nr::serving_cell_cfg_common_sib_s& serv_cell_cfg, + phy_cfg_nr_t::ssb_cfg_t* out_ssb); +void fill_ssb_pos_in_burst(const asn1::rrc_nr::serving_cell_cfg_common_sib_s& ssb_pos, + phy_cfg_nr_t::ssb_cfg_t* out_ssb); +bool fill_ssb_pattern_scs(const srsran_carrier_nr_t& carrier, + srsran_ssb_pattern_t* pattern, + srsran_subcarrier_spacing_t* ssb_scs); +bool fill_phy_ssb_cfg(const srsran_carrier_nr_t& carrier, + const asn1::rrc_nr::serving_cell_cfg_common_sib_s& serv_cell_cfg, + srsran_ssb_cfg_t* out_ssb); bool make_phy_ssb_cfg(const srsran_carrier_nr_t& carrier, const asn1::rrc_nr::serving_cell_cfg_common_s& serv_cell_cfg, phy_cfg_nr_t::ssb_cfg_t* ssb); +bool make_phy_mib(const asn1::rrc_nr::mib_s& mib_cfg, srsran_mib_nr_t* mib); bool make_pdsch_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_sch_hl_cfg_nr_t* sch_hl); bool make_csi_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_csi_hl_cfg_t* csi_hl); bool make_duplex_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_common_s& serv_cell, srsran_duplex_config_nr_t* duplex_cfg); bool fill_phy_pdcch_cfg_common(const asn1::rrc_nr::pdcch_cfg_common_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch); bool fill_phy_pdcch_cfg(const asn1::rrc_nr::pdcch_cfg_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch); +bool fill_phy_pdsch_cfg_common(const asn1::rrc_nr::pdsch_cfg_common_s& pdsch_cfg, srsran_sch_hl_cfg_nr_t* pdsch); +void fill_phy_pucch_cfg_common(const asn1::rrc_nr::pucch_cfg_common_s& pucch_cfg, srsran_pucch_nr_common_cfg_t* pucch); +bool fill_phy_pucch_cfg(const asn1::rrc_nr::pucch_cfg_s& pucch_cfg, srsran_pucch_nr_hl_cfg_t* pucch); +bool fill_phy_pucch_hl_cfg(const asn1::rrc_nr::pucch_cfg_s& pucch_cfg, srsran_pucch_nr_hl_cfg_t* pucch); +bool fill_phy_pusch_cfg_common(const asn1::rrc_nr::pusch_cfg_common_s& pusch_cfg, srsran_sch_hl_cfg_nr_t* pusch); +void fill_phy_carrier_cfg(const asn1::rrc_nr::serving_cell_cfg_common_sib_s& serv_cell_cfg, + srsran_carrier_nr_t* carrier_nr); +void fill_phy_ssb_cfg(const asn1::rrc_nr::serving_cell_cfg_common_sib_s& serv_cell_cfg, phy_cfg_nr_t::ssb_cfg_t* ssb); /*************************** * MAC Config **************************/ logical_channel_config_t make_mac_logical_channel_cfg_t(uint8_t lcid, const asn1::rrc_nr::lc_ch_cfg_s& asn1_type); -rach_nr_cfg_t make_mac_rach_cfg(const asn1::rrc_nr::rach_cfg_common_s& asn1_type); -bool make_mac_phr_cfg_t(const asn1::rrc_nr::phr_cfg_s& asn1_type, phr_cfg_nr_t* phr_cfg_nr); -bool make_mac_dl_harq_cfg_nr_t(const asn1::rrc_nr::pdsch_serving_cell_cfg_s& asn1_type, - dl_harq_cfg_nr_t* out_dl_harq_cfg_nr); +void make_mac_rach_cfg(const asn1::rrc_nr::rach_cfg_common_s& asn1_type, rach_cfg_nr_t* rach_cfg_nr); +bool make_mac_phr_cfg_t(const asn1::rrc_nr::phr_cfg_s& asn1_type, phr_cfg_nr_t* phr_cfg_nr); +bool make_mac_dl_harq_cfg_nr_t(const asn1::rrc_nr::pdsch_serving_cell_cfg_s& asn1_type, + dl_harq_cfg_nr_t* out_dl_harq_cfg_nr); /*************************** * RLC Config **************************/ -int make_rlc_config_t(const asn1::rrc_nr::rlc_cfg_c& asn1_type, rlc_config_t* rlc_config_out); +int make_rlc_config_t(const asn1::rrc_nr::rlc_cfg_c& asn1_type, uint8_t bearer_id, rlc_config_t* rlc_config_out); /*************************** * PDCP Config **************************/ +pdcp_config_t make_srb_pdcp_config_t(const uint8_t bearer_id, bool is_ue); +pdcp_config_t make_nr_srb_pdcp_config_t(const uint8_t bearer_id, bool is_ue); pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue, const asn1::rrc_nr::pdcp_cfg_s& pdcp_cfg); } // namespace srsran -namespace srsenb { +/************************ + * ASN1 RRC extensions + ***********************/ +namespace asn1 { + +namespace rrc_nr { +bool operator==(const srb_to_add_mod_s& lhs, const srb_to_add_mod_s& rhs); +bool operator==(const drb_to_add_mod_s& lhs, const drb_to_add_mod_s& rhs); +} // namespace rrc_nr -int set_sched_cell_cfg_sib1(srsenb::sched_interface::cell_cfg_t* sched_cfg, const asn1::rrc_nr::sib1_s& sib1); -} +} // namespace asn1 #endif // SRSRAN_RRC_NR_UTILS_H diff --git a/lib/include/srsran/asn1/rrc_utils.h b/lib/include/srsran/asn1/rrc_utils.h index 3dd44ec107..05cd55eb44 100644 --- a/lib/include/srsran/asn1/rrc_utils.h +++ b/lib/include/srsran/asn1/rrc_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -67,7 +67,7 @@ struct sib_type13_r9_s; // MeasConfig struct cells_to_add_mod_s; struct cells_to_add_mod_nr_r15_s; -struct black_cells_to_add_mod_s; +struct excluded_cells_to_add_mod_s; struct report_cfg_eutra_s; struct meas_obj_to_add_mod_s; struct report_cfg_to_add_mod_s; @@ -80,6 +80,12 @@ struct ue_eutra_cap_s; } // namespace rrc } // namespace asn1 +namespace srsenb { + +struct ue_cell_ded; + +} // namespace srsenb + /************************ * Conversion Helpers ***********************/ @@ -139,7 +145,8 @@ int get_carrier_freq(const asn1::rrc::meas_obj_to_add_mod_s& obj); /*************************** * EUTRA UE Capabilities **************************/ -rrc_ue_capabilities_t make_rrc_ue_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_cap_s); +rrc_ue_capabilities_t make_rrc_ue_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_cap_s, + const srsenb::ue_cell_ded& pcell); // mbms mbms_notif_cfg_t make_mbms_notif_cfg(const asn1::rrc::mbms_notif_cfg_r9_s& asn1_type); @@ -150,37 +157,4 @@ sib13_t make_sib13(const asn1::rrc::sib_type13_r9_s& asn1_type); } // namespace srsran -/************************ - * ASN1 RRC extensions - ***********************/ -namespace asn1 { -namespace rrc { - -/************************** - * RRC Obj Id - *************************/ - -uint8_t get_rrc_obj_id(const srb_to_add_mod_s& srb); -uint8_t get_rrc_obj_id(const drb_to_add_mod_s& drb); -uint8_t get_rrc_obj_id(const cells_to_add_mod_s& obj); -uint8_t get_rrc_obj_id(const cells_to_add_mod_nr_r15_s& obj); -uint8_t get_rrc_obj_id(const black_cells_to_add_mod_s& obj); -uint8_t get_rrc_obj_id(const meas_obj_to_add_mod_s& obj); -uint8_t get_rrc_obj_id(const report_cfg_to_add_mod_s& obj); -uint8_t get_rrc_obj_id(const meas_id_to_add_mod_s& obj); -uint8_t get_rrc_obj_id(const scell_to_add_mod_r10_s& obj); - -void set_rrc_obj_id(srb_to_add_mod_s& srb, uint8_t id); -void set_rrc_obj_id(drb_to_add_mod_s& drb, uint8_t id); -void set_rrc_obj_id(cells_to_add_mod_s& obj, uint8_t id); -void set_rrc_obj_id(cells_to_add_mod_nr_r15_s& obj, uint8_t id); -void set_rrc_obj_id(black_cells_to_add_mod_s& obj, uint8_t id); -void set_rrc_obj_id(meas_obj_to_add_mod_s& obj, uint8_t id); -void set_rrc_obj_id(report_cfg_to_add_mod_s& obj, uint8_t id); -void set_rrc_obj_id(meas_id_to_add_mod_s& obj, uint8_t id); -void set_rrc_obj_id(scell_to_add_mod_r10_s& obj, uint8_t id); - -} // namespace rrc -} // namespace asn1 - #endif // SRSRAN_RRC_UTILS_H diff --git a/lib/include/srsran/asn1/s1ap.h b/lib/include/srsran/asn1/s1ap.h index b77f5a704a..d8976597e0 100644 --- a/lib/include/srsran/asn1/s1ap.h +++ b/lib/include/srsran/asn1/s1ap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -437,21 +437,11 @@ namespace s1ap { * Struct Definitions ******************************************************************************/ -// Criticality ::= ENUMERATED -struct crit_opts { - enum options { reject, ignore, notify, nulltype } value; +// INTEGER (0..16777215) ::= INTEGER (0..16777215) +using enb_ue_s1ap_id_t = integer; - const char* to_string() const; -}; -typedef enumerated crit_e; - -// Presence ::= ENUMERATED -struct presence_opts { - enum options { optional, conditional, mandatory, nulltype } value; - - const char* to_string() const; -}; -typedef enumerated presence_e; +// INTEGER (0..4294967295) ::= INTEGER (0..4294967295) +using mme_ue_s1ap_id_t = integer; // PrivateIE-ID ::= CHOICE struct private_ie_id_c { @@ -504,54 +494,6 @@ struct private_ie_field_s { template using private_ie_container_l = dyn_seq_of, 1, 65535, true>; -// ProtocolExtensionField{S1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE{{S1AP-PROTOCOL-EXTENSION}} -template -struct protocol_ext_field_s { - uint32_t id = 0; - crit_e crit; - typename ext_set_paramT_::ext_c ext_value; - - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool load_info_obj(const uint32_t& id_); -}; - -// ProtocolExtensionContainer{S1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE (SIZE (1..65535)) OF -// ProtocolExtensionField -template -using protocol_ext_container_l = dyn_seq_of, 1, 65535, true>; - -// ProtocolIE-Field{S1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{S1AP-PROTOCOL-IES}} -template -struct protocol_ie_field_s { - uint32_t id = 0; - crit_e crit; - typename ies_set_paramT_::value_c value; - - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool load_info_obj(const uint32_t& id_); -}; - -// ProtocolIE-Container{S1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE (SIZE (0..65535)) OF ProtocolIE-Field -template -using protocol_ie_container_l = dyn_seq_of, 0, 65535, true>; - -// ProtocolIE-SingleContainer{S1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{S1AP-PROTOCOL-IES}} -template -struct protocol_ie_single_container_s { - uint32_t id = 0; - crit_e crit; - typename ies_set_paramT_::value_c value; - - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - bool load_info_obj(const uint32_t& id_); -}; - // ProtocolIE-FieldPair{S1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE{{S1AP-PROTOCOL-IES-PAIR}} template struct protocol_ie_field_pair_s { @@ -586,61 +528,15 @@ struct activ_cells_list_item_s { // ActivatedCellsList ::= SEQUENCE (SIZE (0..256)) OF ActivatedCellsList-Item using activ_cells_list_l = dyn_array; -struct s1ap_protocol_ext_empty_o { - // Extension ::= OPEN TYPE - struct ext_c { - struct types_opts { - enum options { nulltype } value; - - const char* to_string() const; - }; - typedef enumerated types; - - // choice methods - types type() const { return types::nulltype; } - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; - }; - - // members lookup methods - static uint32_t idx_to_id(uint32_t idx); - static bool is_id_valid(const uint32_t& id); - static crit_e get_crit(const uint32_t& id); - static ext_c get_ext(const uint32_t& id); - static presence_e get_presence(const uint32_t& id); -}; // GUMMEI-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using gummei_ext_ies_o = s1ap_protocol_ext_empty_o; +using gummei_ext_ies_o = protocol_ext_empty_o; // PLMNidentity ::= OCTET STRING using plm_nid = fixed_octstring<3, true>; // Additional-GUTI-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using add_guti_ext_ies_o = s1ap_protocol_ext_empty_o; - -template -struct protocol_ext_container_item_s { - uint32_t id = 0; - crit_e crit; - extT_ ext; - - // sequence methods - protocol_ext_container_item_s(uint32_t id_, crit_e crit_); - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - -struct protocol_ext_container_empty_l { - template - using ie_field_s = protocol_ext_container_item_s; +using add_guti_ext_ies_o = protocol_ext_empty_o; - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; using gummei_ext_ies_container = protocol_ext_container_empty_l; // GUMMEI ::= SEQUENCE @@ -677,7 +573,7 @@ struct add_guti_s { }; // AllocationAndRetentionPriority-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using alloc_and_retention_prio_ext_ies_o = s1ap_protocol_ext_empty_o; +using alloc_and_retention_prio_ext_ies_o = protocol_ext_empty_o; // Pre-emptionCapability ::= ENUMERATED struct pre_emption_cap_opts { @@ -714,10 +610,10 @@ struct alloc_and_retention_prio_s { }; // EUTRAN-CGI-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using eutran_cgi_ext_ies_o = s1ap_protocol_ext_empty_o; +using eutran_cgi_ext_ies_o = protocol_ext_empty_o; // TAI-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using tai_ext_ies_o = s1ap_protocol_ext_empty_o; +using tai_ext_ies_o = protocol_ext_empty_o; using eutran_cgi_ext_ies_container = protocol_ext_container_empty_l; @@ -754,16 +650,16 @@ struct tai_s { }; // CellBasedMDT-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using cell_based_mdt_ext_ies_o = s1ap_protocol_ext_empty_o; +using cell_based_mdt_ext_ies_o = protocol_ext_empty_o; // CellIdListforMDT ::= SEQUENCE (SIZE (1..32)) OF EUTRAN-CGI using cell_id_listfor_mdt_l = dyn_array; // TABasedMDT-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using ta_based_mdt_ext_ies_o = s1ap_protocol_ext_empty_o; +using ta_based_mdt_ext_ies_o = protocol_ext_empty_o; // TAIBasedMDT-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using tai_based_mdt_ext_ies_o = s1ap_protocol_ext_empty_o; +using tai_based_mdt_ext_ies_o = protocol_ext_empty_o; // TAIListforMDT ::= SEQUENCE (SIZE (1..8)) OF TAI using tai_listfor_mdt_l = dyn_array; @@ -882,22 +778,22 @@ struct area_scope_of_mdt_c { }; // CellBasedQMC-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using cell_based_qmc_ext_ies_o = s1ap_protocol_ext_empty_o; +using cell_based_qmc_ext_ies_o = protocol_ext_empty_o; // CellIdListforQMC ::= SEQUENCE (SIZE (1..32)) OF EUTRAN-CGI using cell_id_listfor_qmc_l = dyn_array; // PLMNAreaBasedQMC-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using plmn_area_based_qmc_ext_ies_o = s1ap_protocol_ext_empty_o; +using plmn_area_based_qmc_ext_ies_o = protocol_ext_empty_o; // PLMNListforQMC ::= SEQUENCE (SIZE (1..16)) OF OCTET STRING (SIZE (3)) using plmn_listfor_qmc_l = bounded_array, 16>; // TABasedQMC-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using ta_based_qmc_ext_ies_o = s1ap_protocol_ext_empty_o; +using ta_based_qmc_ext_ies_o = protocol_ext_empty_o; // TAIBasedQMC-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using tai_based_qmc_ext_ies_o = s1ap_protocol_ext_empty_o; +using tai_based_qmc_ext_ies_o = protocol_ext_empty_o; // TAIListforQMC ::= SEQUENCE (SIZE (1..8)) OF TAI using tai_listfor_qmc_l = dyn_array; @@ -1042,7 +938,7 @@ struct area_scope_of_qmc_c { }; // CellIdentifierAndCELevelForCECapableUEs-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using cell_id_and_ce_level_for_ce_capable_ues_ext_ies_o = s1ap_protocol_ext_empty_o; +using cell_id_and_ce_level_for_ce_capable_ues_ext_ies_o = protocol_ext_empty_o; using cell_id_and_ce_level_for_ce_capable_ues_ext_ies_container = protocol_ext_container_empty_l; @@ -1062,7 +958,7 @@ struct cell_id_and_ce_level_for_ce_capable_ues_s { }; // InformationForCECapableUEs-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using info_for_ce_capable_ues_ext_ies_o = s1ap_protocol_ext_empty_o; +using info_for_ce_capable_ues_ext_ies_o = protocol_ext_empty_o; using info_for_ce_capable_ues_ext_ies_container = protocol_ext_container_empty_l; @@ -1081,7 +977,7 @@ struct assist_data_for_ce_capable_ues_s { }; // RecommendedCellsForPagingItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using recommended_cells_for_paging_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using recommended_cells_for_paging_item_ext_ies_o = protocol_ext_empty_o; using recommended_cells_for_paging_item_ext_ies_container = protocol_ext_container_empty_l; @@ -1137,10 +1033,10 @@ struct recommended_cell_item_ies_o { using recommended_cell_list_l = bounded_array, 16>; // RecommendedCellsForPaging-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using recommended_cells_for_paging_ext_ies_o = s1ap_protocol_ext_empty_o; +using recommended_cells_for_paging_ext_ies_o = protocol_ext_empty_o; // AssistanceDataForRecommendedCells-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using assist_data_for_recommended_cells_ext_ies_o = s1ap_protocol_ext_empty_o; +using assist_data_for_recommended_cells_ext_ies_o = protocol_ext_empty_o; // NextPagingAreaScope ::= ENUMERATED struct next_paging_area_scope_opts { @@ -1151,7 +1047,7 @@ struct next_paging_area_scope_opts { typedef enumerated next_paging_area_scope_e; // PagingAttemptInformation-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using paging_attempt_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using paging_attempt_info_ext_ies_o = protocol_ext_empty_o; using recommended_cells_for_paging_ext_ies_container = protocol_ext_container_empty_l; @@ -1170,7 +1066,7 @@ struct recommended_cells_for_paging_s { }; // AssistanceDataForPaging-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using assist_data_for_paging_ext_ies_o = s1ap_protocol_ext_empty_o; +using assist_data_for_paging_ext_ies_o = protocol_ext_empty_o; using assist_data_for_recommended_cells_ext_ies_container = protocol_ext_container_empty_l; @@ -1232,10 +1128,10 @@ struct assist_data_for_paging_s { using bplmns_l = bounded_array, 6>; // COUNTValueExtended-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using count_value_extended_ext_ies_o = s1ap_protocol_ext_empty_o; +using count_value_extended_ext_ies_o = protocol_ext_empty_o; // COUNTvaluePDCP-SNlength18-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using coun_tvalue_pdcp_snlen18_ext_ies_o = s1ap_protocol_ext_empty_o; +using coun_tvalue_pdcp_snlen18_ext_ies_o = protocol_ext_empty_o; using count_value_extended_ext_ies_container = protocol_ext_container_empty_l; @@ -1255,7 +1151,7 @@ struct count_value_extended_s { }; // COUNTvalue-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using coun_tvalue_ext_ies_o = s1ap_protocol_ext_empty_o; +using coun_tvalue_ext_ies_o = protocol_ext_empty_o; using coun_tvalue_pdcp_snlen18_ext_ies_container = protocol_ext_container_empty_l; @@ -1445,7 +1341,7 @@ struct bluetooth_meas_cfg_opts { typedef enumerated bluetooth_meas_cfg_e; // BluetoothMeasurementConfiguration-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using bluetooth_meas_cfg_ext_ies_o = s1ap_protocol_ext_empty_o; +using bluetooth_meas_cfg_ext_ies_o = protocol_ext_empty_o; using bluetooth_meas_cfg_ext_ies_container = protocol_ext_container_empty_l; @@ -1476,10 +1372,10 @@ struct bluetooth_meas_cfg_s { }; // CancelledCellinEAI-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using cancelled_cellin_eai_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using cancelled_cellin_eai_item_ext_ies_o = protocol_ext_empty_o; // CancelledCellinTAI-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using cancelled_cellin_tai_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using cancelled_cellin_tai_item_ext_ies_o = protocol_ext_empty_o; using cancelled_cellin_eai_item_ext_ies_container = protocol_ext_container_empty_l; @@ -1522,13 +1418,13 @@ using cancelled_cellin_eai_l = dyn_array; using cancelled_cellin_tai_l = dyn_array; // CellID-Cancelled-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using cell_id_cancelled_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using cell_id_cancelled_item_ext_ies_o = protocol_ext_empty_o; // EmergencyAreaID-Cancelled-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using emergency_area_id_cancelled_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using emergency_area_id_cancelled_item_ext_ies_o = protocol_ext_empty_o; // TAI-Cancelled-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using tai_cancelled_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using tai_cancelled_item_ext_ies_o = protocol_ext_empty_o; using cell_id_cancelled_item_ext_ies_container = protocol_ext_container_empty_l; @@ -1652,10 +1548,10 @@ struct broadcast_cancelled_area_list_c { }; // CompletedCellinEAI-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using completed_cellin_eai_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using completed_cellin_eai_item_ext_ies_o = protocol_ext_empty_o; // CompletedCellinTAI-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using completed_cellin_tai_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using completed_cellin_tai_item_ext_ies_o = protocol_ext_empty_o; using completed_cellin_eai_item_ext_ies_container = protocol_ext_container_empty_l; @@ -1690,7 +1586,7 @@ struct completed_cellin_tai_item_s { }; // CellID-Broadcast-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using cell_id_broadcast_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using cell_id_broadcast_item_ext_ies_o = protocol_ext_empty_o; // CompletedCellinEAI ::= SEQUENCE (SIZE (1..65535)) OF CompletedCellinEAI-Item using completed_cellin_eai_l = dyn_array; @@ -1699,10 +1595,10 @@ using completed_cellin_eai_l = dyn_array; using completed_cellin_tai_l = dyn_array; // EmergencyAreaID-Broadcast-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using emergency_area_id_broadcast_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using emergency_area_id_broadcast_item_ext_ies_o = protocol_ext_empty_o; // TAI-Broadcast-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using tai_broadcast_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using tai_broadcast_item_ext_ies_o = protocol_ext_empty_o; using cell_id_broadcast_item_ext_ies_container = protocol_ext_container_empty_l; @@ -1825,7 +1721,7 @@ struct broadcast_completed_area_list_c { }; // CGI-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using cgi_ext_ies_o = s1ap_protocol_ext_empty_o; +using cgi_ext_ies_o = protocol_ext_empty_o; using cgi_ext_ies_container = protocol_ext_container_empty_l; @@ -1858,7 +1754,7 @@ struct cn_type_opts { typedef enumerated cn_type_e; // CNTypeRestrictions-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using cn_type_restricts_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using cn_type_restricts_item_ext_ies_o = protocol_ext_empty_o; using cn_type_restricts_item_ext_ies_container = protocol_ext_container_empty_l; @@ -1881,7 +1777,7 @@ struct cn_type_restricts_item_s { using cn_type_restricts_l = dyn_array; // CSG-IdList-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using csg_id_list_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using csg_id_list_item_ext_ies_o = protocol_ext_empty_o; using csg_id_list_item_ext_ies_container = protocol_ext_container_empty_l; @@ -1903,7 +1799,7 @@ struct csg_id_list_item_s { using csg_id_list_l = dyn_array; // CSGMembershipInfo-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using csg_membership_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using csg_membership_info_ext_ies_o = protocol_ext_empty_o; // CSGMembershipStatus ::= ENUMERATED struct csg_membership_status_opts { @@ -2228,7 +2124,7 @@ struct cause_c { }; // Cdma2000OneXSRVCCInfo-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using cdma2000_one_xsrvcc_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using cdma2000_one_xsrvcc_info_ext_ies_o = protocol_ext_empty_o; using cdma2000_one_xsrvcc_info_ext_ies_container = protocol_ext_container_empty_l; @@ -2501,31 +2397,18 @@ struct cell_traffic_trace_ies_o { static presence_e get_presence(const uint32_t& id); }; -template -struct protocol_ie_container_item_s { - uint32_t id = 0; - crit_e crit; - valueT_ value; - - // sequence methods - protocol_ie_container_item_s(uint32_t id_, crit_e crit_); - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; - struct cell_traffic_trace_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool privacy_ind_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > e_utran_trace_id; - ie_field_s eutran_cgi; - ie_field_s > trace_collection_entity_ip_address; - ie_field_s privacy_ind; + bool privacy_ind_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > e_utran_trace_id; + ie_field_s eutran_cgi; + ie_field_s > trace_collection_entity_ip_address; + ie_field_s privacy_ind; // sequence methods cell_traffic_trace_ies_container(); @@ -2535,16 +2418,7 @@ struct cell_traffic_trace_ies_container { }; // CellTrafficTrace ::= SEQUENCE -struct cell_traffic_trace_s { - bool ext = false; - cell_traffic_trace_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using cell_traffic_trace_s = elementary_procedure_option; // Cell-Size ::= ENUMERATED struct cell_size_opts { @@ -2555,7 +2429,7 @@ struct cell_size_opts { typedef enumerated cell_size_e; // CellType-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using cell_type_ext_ies_o = s1ap_protocol_ext_empty_o; +using cell_type_ext_ies_o = protocol_ext_empty_o; using cell_type_ext_ies_container = protocol_ext_container_empty_l; @@ -2629,7 +2503,7 @@ struct supported_tas_item_s { }; // ConnectedengNBItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using connectedeng_nb_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using connectedeng_nb_item_ext_ies_o = protocol_ext_empty_o; // SupportedTAs ::= SEQUENCE (SIZE (1..256)) OF SupportedTAs-Item using supported_tas_l = dyn_array; @@ -2707,10 +2581,10 @@ struct gbr_qos_info_ext_ies_o { }; // ScheduledCommunicationTime-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using sched_communication_time_ext_ies_o = s1ap_protocol_ext_empty_o; +using sched_communication_time_ext_ies_o = protocol_ext_empty_o; // DL-CP-SecurityInformation-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using dl_cp_security_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using dl_cp_security_info_ext_ies_o = protocol_ext_empty_o; // E-RABQoSParameters-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION struct erab_qos_params_ext_ies_o { @@ -2814,7 +2688,7 @@ struct sched_communication_time_s { }; // Subscription-Based-UE-DifferentiationInfo-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using subscription_based_ue_differentiation_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using subscription_based_ue_differentiation_info_ext_ies_o = protocol_ext_empty_o; // CE-ModeBRestricted ::= ENUMERATED struct ce_mode_brestricted_opts { @@ -3024,22 +2898,22 @@ struct conn_establishment_ind_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool ue_radio_cap_present = false; - bool enhanced_coverage_restricted_present = false; - bool dl_cp_security_info_present = false; - bool ce_mode_brestricted_present = false; - bool end_ind_present = false; - bool subscription_based_ue_differentiation_info_present = false; - bool ue_level_qos_params_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > ue_radio_cap; - ie_field_s enhanced_coverage_restricted; - ie_field_s dl_cp_security_info; - ie_field_s ce_mode_brestricted; - ie_field_s end_ind; - ie_field_s subscription_based_ue_differentiation_info; - ie_field_s ue_level_qos_params; + bool ue_radio_cap_present = false; + bool enhanced_coverage_restricted_present = false; + bool dl_cp_security_info_present = false; + bool ce_mode_brestricted_present = false; + bool end_ind_present = false; + bool subscription_based_ue_differentiation_info_present = false; + bool ue_level_qos_params_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > ue_radio_cap; + ie_field_s enhanced_coverage_restricted; + ie_field_s dl_cp_security_info; + ie_field_s ce_mode_brestricted; + ie_field_s end_ind; + ie_field_s subscription_based_ue_differentiation_info; + ie_field_s ue_level_qos_params; // sequence methods conn_establishment_ind_ies_container(); @@ -3049,16 +2923,7 @@ struct conn_establishment_ind_ies_container { }; // ConnectionEstablishmentIndication ::= SEQUENCE -struct conn_establishment_ind_s { - bool ext = false; - conn_establishment_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using conn_establishment_ind_s = elementary_procedure_option; // ENB-ID ::= CHOICE struct enb_id_c { @@ -3155,13 +3020,13 @@ struct gnb_id_c { }; // Global-GNB-ID-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using global_gnb_id_ext_ies_o = s1ap_protocol_ext_empty_o; +using global_gnb_id_ext_ies_o = protocol_ext_empty_o; // GlobalENB-ID-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using global_enb_id_ext_ies_o = s1ap_protocol_ext_empty_o; +using global_enb_id_ext_ies_o = protocol_ext_empty_o; // GNB-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using gnb_ext_ies_o = s1ap_protocol_ext_empty_o; +using gnb_ext_ies_o = protocol_ext_empty_o; using global_enb_id_ext_ies_container = protocol_ext_container_empty_l; @@ -3198,7 +3063,7 @@ struct global_gnb_id_s { }; // NG-eNB-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using ng_enb_ext_ies_o = s1ap_protocol_ext_empty_o; +using ng_enb_ext_ies_o = protocol_ext_empty_o; using gnb_ext_ies_container = protocol_ext_container_empty_l; @@ -3233,7 +3098,7 @@ struct ng_enb_s { }; // ContextatSource-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using contextat_source_ext_ies_o = s1ap_protocol_ext_empty_o; +using contextat_source_ext_ies_o = protocol_ext_empty_o; // Global-RAN-NODE-ID ::= CHOICE struct global_ran_node_id_c { @@ -3303,7 +3168,7 @@ struct contextat_source_s { }; // CriticalityDiagnostics-IE-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using crit_diagnostics_ie_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using crit_diagnostics_ie_item_ext_ies_o = protocol_ext_empty_o; // TypeOfError ::= ENUMERATED struct type_of_error_opts { @@ -3332,7 +3197,7 @@ struct crit_diagnostics_ie_item_s { }; // CriticalityDiagnostics-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using crit_diagnostics_ext_ies_o = s1ap_protocol_ext_empty_o; +using crit_diagnostics_ext_ies_o = protocol_ext_empty_o; // CriticalityDiagnostics-IE-List ::= SEQUENCE (SIZE (1..256)) OF CriticalityDiagnostics-IE-Item using crit_diagnostics_ie_list_l = dyn_array; @@ -3417,9 +3282,9 @@ struct deactiv_trace_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > e_utran_trace_id; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > e_utran_trace_id; // sequence methods deactiv_trace_ies_container(); @@ -3429,28 +3294,19 @@ struct deactiv_trace_ies_container { }; // DeactivateTrace ::= SEQUENCE -struct deactiv_trace_s { - bool ext = false; - deactiv_trace_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using deactiv_trace_s = elementary_procedure_option; // ForbiddenLACs ::= SEQUENCE (SIZE (1..4096)) OF OCTET STRING (SIZE (2)) using forbidden_lacs_l = dyn_array >; // ForbiddenLAs-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using forbidden_las_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using forbidden_las_item_ext_ies_o = protocol_ext_empty_o; // ForbiddenTACs ::= SEQUENCE (SIZE (1..4096)) OF OCTET STRING (SIZE (2)) using forbidden_tacs_l = dyn_array >; // ForbiddenTAs-Item-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using forbidden_tas_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using forbidden_tas_item_ext_ies_o = protocol_ext_empty_o; using forbidden_las_item_ext_ies_container = protocol_ext_container_empty_l; @@ -3587,7 +3443,7 @@ struct ho_restrict_list_ext_ies_o { }; // NRUESecurityCapabilities-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using nrue_security_cap_ext_ies_o = s1ap_protocol_ext_empty_o; +using nrue_security_cap_ext_ies_o = protocol_ext_empty_o; // DLNASPDUDeliveryAckRequest ::= ENUMERATED struct dlnaspdu_delivery_ack_request_opts { @@ -3781,35 +3637,35 @@ struct dl_nas_transport_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool ho_restrict_list_present = false; - bool subscriber_profile_idfor_rfp_present = false; - bool srvcc_operation_possible_present = false; - bool ue_radio_cap_present = false; - bool dlnaspdu_delivery_ack_request_present = false; - bool enhanced_coverage_restricted_present = false; - bool nrue_security_cap_present = false; - bool ce_mode_brestricted_present = false; - bool ue_cap_info_request_present = false; - bool end_ind_present = false; - bool pending_data_ind_present = false; - bool subscription_based_ue_differentiation_info_present = false; - bool add_rrm_prio_idx_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > nas_pdu; - ie_field_s ho_restrict_list; - ie_field_s > subscriber_profile_idfor_rfp; - ie_field_s srvcc_operation_possible; - ie_field_s > ue_radio_cap; - ie_field_s dlnaspdu_delivery_ack_request; - ie_field_s enhanced_coverage_restricted; - ie_field_s nrue_security_cap; - ie_field_s ce_mode_brestricted; - ie_field_s ue_cap_info_request; - ie_field_s end_ind; - ie_field_s pending_data_ind; - ie_field_s subscription_based_ue_differentiation_info; - ie_field_s > add_rrm_prio_idx; + bool ho_restrict_list_present = false; + bool subscriber_profile_idfor_rfp_present = false; + bool srvcc_operation_possible_present = false; + bool ue_radio_cap_present = false; + bool dlnaspdu_delivery_ack_request_present = false; + bool enhanced_coverage_restricted_present = false; + bool nrue_security_cap_present = false; + bool ce_mode_brestricted_present = false; + bool ue_cap_info_request_present = false; + bool end_ind_present = false; + bool pending_data_ind_present = false; + bool subscription_based_ue_differentiation_info_present = false; + bool add_rrm_prio_idx_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > nas_pdu; + ie_field_s ho_restrict_list; + ie_field_s > subscriber_profile_idfor_rfp; + ie_field_s srvcc_operation_possible; + ie_field_s > ue_radio_cap; + ie_field_s dlnaspdu_delivery_ack_request; + ie_field_s enhanced_coverage_restricted; + ie_field_s nrue_security_cap; + ie_field_s ce_mode_brestricted; + ie_field_s ue_cap_info_request; + ie_field_s end_ind; + ie_field_s pending_data_ind; + ie_field_s subscription_based_ue_differentiation_info; + ie_field_s > add_rrm_prio_idx; // sequence methods dl_nas_transport_ies_container(); @@ -3819,16 +3675,7 @@ struct dl_nas_transport_ies_container { }; // DownlinkNASTransport ::= SEQUENCE -struct dl_nas_transport_s { - bool ext = false; - dl_nas_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using dl_nas_transport_s = elementary_procedure_option; // DownlinkNonUEAssociatedLPPaTransport-IEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct dl_non_ueassociated_lp_pa_transport_ies_o { @@ -3890,19 +3737,11 @@ struct dl_non_ueassociated_lp_pa_transport_ies_container { }; // DownlinkNonUEAssociatedLPPaTransport ::= SEQUENCE -struct dl_non_ueassociated_lp_pa_transport_s { - bool ext = false; - dl_non_ueassociated_lp_pa_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using dl_non_ueassociated_lp_pa_transport_s = + elementary_procedure_option; // E-RABDataForwardingItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_data_forwarding_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_data_forwarding_item_ext_ies_o = protocol_ext_empty_o; using erab_data_forwarding_item_ext_ies_container = protocol_ext_container_empty_l; @@ -4050,10 +3889,10 @@ struct dl_s1cdma2000tunnelling_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool erab_subjectto_data_forwarding_list_present = false; - bool cdma2000_ho_status_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool erab_subjectto_data_forwarding_list_present = false; + bool cdma2000_ho_status_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s > erab_subjectto_data_forwarding_list; ie_field_s cdma2000_ho_status; ie_field_s cdma2000_rat_type; @@ -4067,16 +3906,7 @@ struct dl_s1cdma2000tunnelling_ies_container { }; // DownlinkS1cdma2000tunnelling ::= SEQUENCE -struct dl_s1cdma2000tunnelling_s { - bool ext = false; - dl_s1cdma2000tunnelling_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using dl_s1cdma2000tunnelling_s = elementary_procedure_option; // DownlinkUEAssociatedLPPaTransport-IEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct dl_ueassociated_lp_pa_transport_ies_o { @@ -4129,10 +3959,10 @@ struct dl_ueassociated_lp_pa_transport_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > routing_id; - ie_field_s > lp_pa_pdu; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > routing_id; + ie_field_s > lp_pa_pdu; // sequence methods dl_ueassociated_lp_pa_transport_ies_container(); @@ -4142,16 +3972,7 @@ struct dl_ueassociated_lp_pa_transport_ies_container { }; // DownlinkUEAssociatedLPPaTransport ::= SEQUENCE -struct dl_ueassociated_lp_pa_transport_s { - bool ext = false; - dl_ueassociated_lp_pa_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using dl_ueassociated_lp_pa_transport_s = elementary_procedure_option; // ProtocolIE-ContainerPair-item{S1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= ProtocolIE-ContainerPair template @@ -4160,11 +3981,10 @@ using protocol_ie_container_pair_item_l = protocol_ie_container_pair_l -using erab_ie_container_pair_list_l = - dyn_seq_of, 0, 65535, true>, 1, 256>; +using erab_ie_container_pair_list_l = dyn_seq_of, 1, 256>; // E-RABAdmittedItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_admitted_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_admitted_item_ext_ies_o = protocol_ext_empty_o; using erab_admitted_item_ext_ies_container = protocol_ext_container_empty_l; @@ -4225,7 +4045,7 @@ struct erab_admitted_item_ies_o { }; // E-RABFailedToResumeItemResumeReq-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_failed_to_resume_item_resume_req_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_failed_to_resume_item_resume_req_ext_ies_o = protocol_ext_empty_o; using erab_failed_to_resume_item_resume_req_ext_ies_container = protocol_ext_container_empty_l; @@ -4277,7 +4097,7 @@ struct erab_failed_to_resume_item_resume_req_ies_o { }; // E-RABFailedToResumeItemResumeRes-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_failed_to_resume_item_resume_res_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_failed_to_resume_item_resume_res_ext_ies_o = protocol_ext_empty_o; using erab_failed_to_resume_item_resume_res_ext_ies_container = protocol_ext_container_empty_l; @@ -4329,7 +4149,7 @@ struct erab_failed_to_resume_item_resume_res_ies_o { }; // E-RABFailedToSetupItemHOReqAckExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_failed_to_setup_item_ho_req_ack_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_failed_to_setup_item_ho_req_ack_ext_ies_o = protocol_ext_empty_o; using erab_failed_to_setup_item_ho_req_ack_ext_ies_container = protocol_ext_container_empty_l; @@ -4389,7 +4209,7 @@ struct dl_forwarding_opts { typedef enumerated dl_forwarding_e; // E-RABInformationListItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_info_list_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_info_list_item_ext_ies_o = protocol_ext_empty_o; using erab_info_list_item_ext_ies_container = protocol_ext_container_empty_l; @@ -4445,7 +4265,7 @@ struct erab_info_list_ies_o { using erab_info_list_l = dyn_array >; // E-RABItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_item_ext_ies_o = protocol_ext_empty_o; using erab_item_ext_ies_container = protocol_ext_container_empty_l; @@ -4500,7 +4320,7 @@ struct erab_item_ies_o { using erab_list_l = dyn_array >; // E-RABModifyItemBearerModConfExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_modify_item_bearer_mod_conf_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_modify_item_bearer_mod_conf_ext_ies_o = protocol_ext_empty_o; using erab_modify_item_bearer_mod_conf_ext_ies_container = protocol_ext_container_empty_l; @@ -4621,13 +4441,13 @@ struct erab_mod_confirm_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool erab_modify_list_bearer_mod_conf_present = false; - bool erab_failed_to_modify_list_bearer_mod_conf_present = false; - bool erab_to_be_released_list_bearer_mod_conf_present = false; - bool crit_diagnostics_present = false; - bool csg_membership_status_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool erab_modify_list_bearer_mod_conf_present = false; + bool erab_failed_to_modify_list_bearer_mod_conf_present = false; + bool erab_to_be_released_list_bearer_mod_conf_present = false; + bool crit_diagnostics_present = false; + bool csg_membership_status_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s, 1, 256, true> > erab_modify_list_bearer_mod_conf; ie_field_s, 1, 256, true> > @@ -4645,19 +4465,10 @@ struct erab_mod_confirm_ies_container { }; // E-RABModificationConfirm ::= SEQUENCE -struct erab_mod_confirm_s { - bool ext = false; - erab_mod_confirm_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using erab_mod_confirm_s = elementary_procedure_option; // E-RABUsageReportItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erabusage_report_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using erabusage_report_item_ext_ies_o = protocol_ext_empty_o; using erabusage_report_item_ext_ies_container = protocol_ext_container_empty_l; @@ -4711,13 +4522,13 @@ struct erabusage_report_item_ies_o { }; // NR-CGI-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using nr_cgi_ext_ies_o = s1ap_protocol_ext_empty_o; +using nr_cgi_ext_ies_o = protocol_ext_empty_o; // E-RABNotToBeModifiedItemBearerModInd-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_not_to_be_modified_item_bearer_mod_ind_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_not_to_be_modified_item_bearer_mod_ind_ext_ies_o = protocol_ext_empty_o; // E-RABToBeModifiedItemBearerModInd-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_to_be_modified_item_bearer_mod_ind_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_to_be_modified_item_bearer_mod_ind_ext_ies_o = protocol_ext_empty_o; // E-RABUsageReportList ::= SEQUENCE (SIZE (1..2)) OF ProtocolIE-SingleContainer{S1AP-PROTOCOL-IES : IEsSetParam} using erabusage_report_list_l = bounded_array, 2>; @@ -4740,10 +4551,10 @@ struct nr_cgi_s { }; // PSCellInformation-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using ps_cell_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using ps_cell_info_ext_ies_o = protocol_ext_empty_o; // SecondaryRATDataUsageReportItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using secondary_rat_data_usage_report_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using secondary_rat_data_usage_report_item_ext_ies_o = protocol_ext_empty_o; // SecondaryRATType ::= ENUMERATED struct secondary_rat_type_opts { @@ -4923,7 +4734,7 @@ struct secondary_rat_data_usage_report_item_ies_o { }; // Tunnel-Information-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using tunnel_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using tunnel_info_ext_ies_o = protocol_ext_empty_o; // UserLocationInformation-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION struct user_location_info_ext_ies_o { @@ -5073,13 +4884,13 @@ struct erab_mod_ind_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool erab_not_to_be_modified_list_bearer_mod_ind_present = false; - bool csg_membership_info_present = false; - bool tunnel_info_for_bbf_present = false; - bool secondary_rat_data_usage_report_list_present = false; - bool user_location_info_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool erab_not_to_be_modified_list_bearer_mod_ind_present = false; + bool csg_membership_info_present = false; + bool tunnel_info_for_bbf_present = false; + bool secondary_rat_data_usage_report_list_present = false; + bool user_location_info_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s > erab_to_be_modified_list_bearer_mod_ind; ie_field_s > @@ -5098,19 +4909,10 @@ struct erab_mod_ind_ies_container { }; // E-RABModificationIndication ::= SEQUENCE -struct erab_mod_ind_s { - bool ext = false; - erab_mod_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using erab_mod_ind_s = elementary_procedure_option; // E-RABModifyItemBearerModResExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_modify_item_bearer_mod_res_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_modify_item_bearer_mod_res_ext_ies_o = protocol_ext_empty_o; using erab_modify_item_bearer_mod_res_ext_ies_container = protocol_ext_container_empty_l; @@ -5409,11 +5211,11 @@ struct erab_modify_request_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool ueaggregate_maximum_bitrate_present = false; - bool secondary_rat_data_usage_request_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s ueaggregate_maximum_bitrate; + bool ueaggregate_maximum_bitrate_present = false; + bool secondary_rat_data_usage_request_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s ueaggregate_maximum_bitrate; ie_field_s, 1, 256, true> > erab_to_be_modified_list_bearer_mod_req; ie_field_s secondary_rat_data_usage_request; @@ -5426,16 +5228,7 @@ struct erab_modify_request_ies_container { }; // E-RABModifyRequest ::= SEQUENCE -struct erab_modify_request_s { - bool ext = false; - erab_modify_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using erab_modify_request_s = elementary_procedure_option; // E-RABModifyResponseIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct erab_modify_resp_ies_o { @@ -5504,12 +5297,12 @@ struct erab_modify_resp_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool erab_modify_list_bearer_mod_res_present = false; - bool erab_failed_to_modify_list_present = false; - bool crit_diagnostics_present = false; - bool secondary_rat_data_usage_report_list_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool erab_modify_list_bearer_mod_res_present = false; + bool erab_failed_to_modify_list_present = false; + bool crit_diagnostics_present = false; + bool secondary_rat_data_usage_report_list_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s, 1, 256, true> > erab_modify_list_bearer_mod_res; ie_field_s, 1, 256, true> > erab_failed_to_modify_list; @@ -5525,16 +5318,7 @@ struct erab_modify_resp_ies_container { }; // E-RABModifyResponse ::= SEQUENCE -struct erab_modify_resp_s { - bool ext = false; - erab_modify_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using erab_modify_resp_s = elementary_procedure_option; // E-RABReleaseCommandIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct erab_release_cmd_ies_o { @@ -5596,11 +5380,11 @@ struct erab_release_cmd_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool ueaggregate_maximum_bitrate_present = false; - bool nas_pdu_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s ueaggregate_maximum_bitrate; + bool ueaggregate_maximum_bitrate_present = false; + bool nas_pdu_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s ueaggregate_maximum_bitrate; ie_field_s, 1, 256, true> > erab_to_be_released_list; ie_field_s > nas_pdu; @@ -5612,16 +5396,7 @@ struct erab_release_cmd_ies_container { }; // E-RABReleaseCommand ::= SEQUENCE -struct erab_release_cmd_s { - bool ext = false; - erab_release_cmd_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using erab_release_cmd_s = elementary_procedure_option; // E-RABReleaseIndicationIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct erab_release_ind_ies_o { @@ -5683,10 +5458,10 @@ struct erab_release_ind_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool user_location_info_present = false; - bool secondary_rat_data_usage_report_list_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool user_location_info_present = false; + bool secondary_rat_data_usage_report_list_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s, 1, 256, true> > erab_released_list; ie_field_s user_location_info; ie_field_s, 1, 256, true> > @@ -5700,19 +5475,10 @@ struct erab_release_ind_ies_container { }; // E-RABReleaseIndication ::= SEQUENCE -struct erab_release_ind_s { - bool ext = false; - erab_release_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using erab_release_ind_s = elementary_procedure_option; // E-RABReleaseItemBearerRelCompExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_release_item_bearer_rel_comp_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_release_item_bearer_rel_comp_ext_ies_o = protocol_ext_empty_o; using erab_release_item_bearer_rel_comp_ext_ies_container = protocol_ext_container_empty_l; @@ -5838,13 +5604,13 @@ struct erab_release_resp_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool erab_release_list_bearer_rel_comp_present = false; - bool erab_failed_to_release_list_present = false; - bool crit_diagnostics_present = false; - bool user_location_info_present = false; - bool secondary_rat_data_usage_report_list_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool erab_release_list_bearer_rel_comp_present = false; + bool erab_failed_to_release_list_present = false; + bool crit_diagnostics_present = false; + bool user_location_info_present = false; + bool secondary_rat_data_usage_report_list_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s, 1, 256, true> > erab_release_list_bearer_rel_comp; ie_field_s, 1, 256, true> > erab_failed_to_release_list; @@ -5861,19 +5627,10 @@ struct erab_release_resp_ies_container { }; // E-RABReleaseResponse ::= SEQUENCE -struct erab_release_resp_s { - bool ext = false; - erab_release_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using erab_release_resp_s = elementary_procedure_option; // E-RABSetupItemBearerSUResExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_setup_item_bearer_su_res_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_setup_item_bearer_su_res_ext_ies_o = protocol_ext_empty_o; using erab_setup_item_bearer_su_res_ext_ies_container = protocol_ext_container_empty_l; @@ -5926,7 +5683,7 @@ struct erab_setup_item_bearer_su_res_ies_o { }; // E-RABSetupItemCtxtSUResExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_setup_item_ctxt_su_res_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_setup_item_ctxt_su_res_ext_ies_o = protocol_ext_empty_o; using erab_setup_item_ctxt_su_res_ext_ies_container = protocol_ext_container_empty_l; @@ -6167,10 +5924,10 @@ struct erab_setup_request_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool ueaggregate_maximum_bitrate_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s ueaggregate_maximum_bitrate; + bool ueaggregate_maximum_bitrate_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s ueaggregate_maximum_bitrate; ie_field_s, 1, 256, true> > erab_to_be_setup_list_bearer_su_req; @@ -6182,16 +5939,7 @@ struct erab_setup_request_ies_container { }; // E-RABSetupRequest ::= SEQUENCE -struct erab_setup_request_s { - bool ext = false; - erab_setup_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using erab_setup_request_s = elementary_procedure_option; // E-RABSetupResponseIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct erab_setup_resp_ies_o { @@ -6253,11 +6001,11 @@ struct erab_setup_resp_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool erab_setup_list_bearer_su_res_present = false; - bool erab_failed_to_setup_list_bearer_su_res_present = false; - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool erab_setup_list_bearer_su_res_present = false; + bool erab_failed_to_setup_list_bearer_su_res_present = false; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s, 1, 256, true> > erab_setup_list_bearer_su_res; ie_field_s, 1, 256, true> > @@ -6272,16 +6020,7 @@ struct erab_setup_resp_ies_container { }; // E-RABSetupResponse ::= SEQUENCE -struct erab_setup_resp_s { - bool ext = false; - erab_setup_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using erab_setup_resp_s = elementary_procedure_option; // E-RABToBeSetupItemCtxtSUReqExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION struct erab_to_be_setup_item_ctxt_su_req_ext_ies_o { @@ -6519,7 +6258,7 @@ using erab_to_be_setup_list_ctxt_su_req_l = dyn_array >; // E-RABToBeSwitchedDLItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_to_be_switched_dl_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_to_be_switched_dl_item_ext_ies_o = protocol_ext_empty_o; using erab_to_be_switched_dl_item_ext_ies_container = protocol_ext_container_empty_l; @@ -6572,7 +6311,7 @@ struct erab_to_be_switched_dl_item_ies_o { }; // E-RABToBeSwitchedULItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using erab_to_be_switched_ul_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using erab_to_be_switched_ul_item_ext_ies_o = protocol_ext_empty_o; using erab_to_be_switched_ul_item_ext_ies_container = protocol_ext_container_empty_l; @@ -6644,7 +6383,7 @@ struct ehrpd_multi_sector_load_report_resp_item_s { }; // ENBX2ExtTLA-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using enbx2_ext_tla_ext_ies_o = s1ap_protocol_ext_empty_o; +using enbx2_ext_tla_ext_ies_o = protocol_ext_empty_o; // ENBX2GTPTLAs ::= SEQUENCE (SIZE (1..16)) OF BIT STRING (SIZE (1..160,...)) using enbx2_gtptlas_l = bounded_array, 16>; @@ -6677,7 +6416,7 @@ struct muting_availability_ind_opts { typedef enumerated muting_availability_ind_e; // RLFReportInformation-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using rlf_report_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using rlf_report_info_ext_ies_o = protocol_ext_empty_o; // ENBIndirectX2TransportLayerAddresses ::= SEQUENCE (SIZE (1..2)) OF BIT STRING (SIZE (1..160,...)) using enb_indirect_x2_transport_layer_addresses_l = bounded_array, 2>; @@ -6686,10 +6425,10 @@ using enb_indirect_x2_transport_layer_addresses_l = bounded_array; // Global-en-gNB-ID-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using global_en_g_nb_id_ext_ies_o = s1ap_protocol_ext_empty_o; +using global_en_g_nb_id_ext_ies_o = protocol_ext_empty_o; // MutingPatternInformation-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using muting_pattern_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using muting_pattern_info_ext_ies_o = protocol_ext_empty_o; using rlf_report_info_ext_ies_container = protocol_ext_container_empty_l; @@ -6750,16 +6489,16 @@ struct time_synchronisation_info_ext_ies_o { }; // EN-DCSONeNBIdentification-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using en_dcso_nenb_identif_ext_ies_o = s1ap_protocol_ext_empty_o; +using en_dcso_nenb_identif_ext_ies_o = protocol_ext_empty_o; // EN-DCSONengNBIdentification-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using en_dcso_neng_nb_identif_ext_ies_o = s1ap_protocol_ext_empty_o; +using en_dcso_neng_nb_identif_ext_ies_o = protocol_ext_empty_o; // ENBX2TLAs ::= SEQUENCE (SIZE (1..2)) OF BIT STRING (SIZE (1..160,...)) using enbx2_tlas_l = bounded_array, 2>; // FiveGSTAI-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using five_gstai_ext_ies_o = s1ap_protocol_ext_empty_o; +using five_gstai_ext_ies_o = protocol_ext_empty_o; using global_en_g_nb_id_ext_ies_container = protocol_ext_container_empty_l; @@ -6924,10 +6663,10 @@ struct en_dcso_neng_nb_identif_s { }; // EN-DCTransferTypeReply-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using en_dc_transfer_type_reply_ext_ies_o = s1ap_protocol_ext_empty_o; +using en_dc_transfer_type_reply_ext_ies_o = protocol_ext_empty_o; // EN-DCTransferTypeRequest-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using en_dc_transfer_type_request_ext_ies_o = s1ap_protocol_ext_empty_o; +using en_dc_transfer_type_request_ext_ies_o = protocol_ext_empty_o; using five_gstai_ext_ies_container = protocol_ext_container_empty_l; @@ -7107,7 +6846,7 @@ struct son_info_request_opts { typedef enumerated son_info_request_e; // EN-DCSONConfigurationTransfer-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using en_dcson_cfg_transfer_ext_ies_o = s1ap_protocol_ext_empty_o; +using en_dcson_cfg_transfer_ext_ies_o = protocol_ext_empty_o; // EN-DCSONTransferType ::= CHOICE struct en_dcson_transfer_type_c { @@ -7240,7 +6979,7 @@ struct en_dcson_cfg_transfer_s { }; // ENB-StatusTransfer-TransparentContainer-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using enb_status_transfer_transparent_container_ext_ies_o = s1ap_protocol_ext_empty_o; +using enb_status_transfer_transparent_container_ext_ies_o = protocol_ext_empty_o; using enb_status_transfer_transparent_container_ext_ies_container = protocol_ext_container_empty_l; @@ -7259,10 +6998,10 @@ struct enb_status_transfer_transparent_container_s { }; // S-TMSI-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using s_tmsi_ext_ies_o = s1ap_protocol_ext_empty_o; +using s_tmsi_ext_ies_o = protocol_ext_empty_o; // UL-CP-SecurityInformation-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using ul_cp_security_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using ul_cp_security_info_ext_ies_o = protocol_ext_empty_o; using s_tmsi_ext_ies_container = protocol_ext_container_empty_l; @@ -7353,11 +7092,11 @@ struct enbcp_relocation_ind_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > enb_ue_s1ap_id; - ie_field_s s_tmsi; - ie_field_s eutran_cgi; - ie_field_s tai; - ie_field_s ul_cp_security_info; + ie_field_s enb_ue_s1ap_id; + ie_field_s s_tmsi; + ie_field_s eutran_cgi; + ie_field_s tai; + ie_field_s ul_cp_security_info; // sequence methods enbcp_relocation_ind_ies_container(); @@ -7367,19 +7106,10 @@ struct enbcp_relocation_ind_ies_container { }; // ENBCPRelocationIndication ::= SEQUENCE -struct enbcp_relocation_ind_s { - bool ext = false; - enbcp_relocation_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using enbcp_relocation_ind_s = elementary_procedure_option; // ListeningSubframePattern-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using listening_sf_pattern_ext_ies_o = s1ap_protocol_ext_empty_o; +using listening_sf_pattern_ext_ies_o = protocol_ext_empty_o; using listening_sf_pattern_ext_ies_container = protocol_ext_container_empty_l; @@ -7409,10 +7139,10 @@ struct listening_sf_pattern_s { }; // SynchronisationInformation-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using synchronisation_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using synchronisation_info_ext_ies_o = protocol_ext_empty_o; // SourceeNB-ID-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using sourceenb_id_ext_ies_o = s1ap_protocol_ext_empty_o; +using sourceenb_id_ext_ies_o = protocol_ext_empty_o; using synchronisation_info_ext_ies_container = protocol_ext_container_empty_l; @@ -7436,7 +7166,7 @@ struct synchronisation_info_s { }; // TargeteNB-ID-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using targetenb_id_ext_ies_o = s1ap_protocol_ext_empty_o; +using targetenb_id_ext_ies_o = protocol_ext_empty_o; // SONConfigurationTransfer-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION struct son_cfg_transfer_ext_ies_o { @@ -7607,16 +7337,7 @@ struct enb_cfg_transfer_ies_container { }; // ENBConfigurationTransfer ::= SEQUENCE -struct enb_cfg_transfer_s { - bool ext = false; - enb_cfg_transfer_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using enb_cfg_transfer_s = elementary_procedure_option; // NB-IoT-DefaultPagingDRX ::= ENUMERATED struct nb_io_t_default_paging_drx_opts { @@ -7727,16 +7448,7 @@ struct enb_cfg_upd_ies_container { }; // ENBConfigurationUpdate ::= SEQUENCE -struct enb_cfg_upd_s { - bool ext = false; - enb_cfg_upd_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using enb_cfg_upd_s = elementary_procedure_option; // ENBConfigurationUpdateAcknowledgeIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct enb_cfg_upd_ack_ies_o { @@ -7771,16 +7483,7 @@ struct enb_cfg_upd_ack_ies_o { }; // ENBConfigurationUpdateAcknowledge ::= SEQUENCE -struct enb_cfg_upd_ack_s { - bool ext = false; - protocol_ie_container_l protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using enb_cfg_upd_ack_s = elementary_procedure_option >; // TimeToWait ::= ENUMERATED struct time_to_wait_opts { @@ -7855,22 +7558,13 @@ struct enb_cfg_upd_fail_ies_container { }; // ENBConfigurationUpdateFailure ::= SEQUENCE -struct enb_cfg_upd_fail_s { - bool ext = false; - enb_cfg_upd_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using enb_cfg_upd_fail_s = elementary_procedure_option; // LAI-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using lai_ext_ies_o = s1ap_protocol_ext_empty_o; +using lai_ext_ies_o = protocol_ext_empty_o; // GERAN-Cell-ID-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using geran_cell_id_ext_ies_o = s1ap_protocol_ext_empty_o; +using geran_cell_id_ext_ies_o = protocol_ext_empty_o; using lai_ext_ies_container = protocol_ext_container_empty_l; @@ -7890,7 +7584,7 @@ struct lai_s { }; // TargetRNC-ID-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using target_rnc_id_ext_ies_o = s1ap_protocol_ext_empty_o; +using target_rnc_id_ext_ies_o = protocol_ext_empty_o; using geran_cell_id_ext_ies_container = protocol_ext_container_empty_l; @@ -7993,7 +7687,7 @@ struct rim_routing_address_c { }; // RIMTransfer-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using rim_transfer_ext_ies_o = s1ap_protocol_ext_empty_o; +using rim_transfer_ext_ies_o = protocol_ext_empty_o; using rim_transfer_ext_ies_container = protocol_ext_container_empty_l; @@ -8068,16 +7762,8 @@ struct enb_direct_info_transfer_ies_o { }; // ENBDirectInformationTransfer ::= SEQUENCE -struct enb_direct_info_transfer_s { - bool ext = false; - protocol_ie_container_l protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using enb_direct_info_transfer_s = + elementary_procedure_option >; // ENBStatusTransferIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct enb_status_transfer_ies_o { @@ -8128,9 +7814,9 @@ struct enb_status_transfer_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s enb_status_transfer_transparent_container; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s enb_status_transfer_transparent_container; // sequence methods enb_status_transfer_ies_container(); @@ -8140,16 +7826,7 @@ struct enb_status_transfer_ies_container { }; // ENBStatusTransfer ::= SEQUENCE -struct enb_status_transfer_s { - bool ext = false; - enb_status_transfer_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using enb_status_transfer_s = elementary_procedure_option; // EUTRANResponse ::= SEQUENCE struct eutran_resp_s { @@ -8223,16 +7900,16 @@ struct error_ind_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool mme_ue_s1ap_id_present = false; - bool enb_ue_s1ap_id_present = false; - bool cause_present = false; - bool crit_diagnostics_present = false; - bool s_tmsi_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s cause; - ie_field_s crit_diagnostics; - ie_field_s s_tmsi; + bool mme_ue_s1ap_id_present = false; + bool enb_ue_s1ap_id_present = false; + bool cause_present = false; + bool crit_diagnostics_present = false; + bool s_tmsi_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s cause; + ie_field_s crit_diagnostics; + ie_field_s s_tmsi; // sequence methods error_ind_ies_container(); @@ -8242,16 +7919,7 @@ struct error_ind_ies_container { }; // ErrorIndication ::= SEQUENCE -struct error_ind_s { - bool ext = false; - error_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using error_ind_s = elementary_procedure_option; // NumberOfMeasurementReportingLevels ::= ENUMERATED struct nof_meas_report_levels_opts { @@ -8298,7 +7966,7 @@ struct event_triggered_cell_load_report_resp_s { }; // ExpectedUEActivityBehaviour-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using expected_ue_activity_behaviour_ext_ies_o = s1ap_protocol_ext_empty_o; +using expected_ue_activity_behaviour_ext_ies_o = protocol_ext_empty_o; // SourceOfUEActivityBehaviourInformation ::= ENUMERATED struct source_of_ue_activity_behaviour_info_opts { @@ -8340,7 +8008,7 @@ struct expected_ho_interv_opts { typedef enumerated expected_ho_interv_e; // ExpectedUEBehaviour-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using expected_ue_behaviour_ext_ies_o = s1ap_protocol_ext_empty_o; +using expected_ue_behaviour_ext_ies_o = protocol_ext_empty_o; using expected_ue_behaviour_ext_ies_container = protocol_ext_container_empty_l; @@ -8485,9 +8153,9 @@ struct ho_cancel_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s cause; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s cause; // sequence methods ho_cancel_ies_container(); @@ -8497,16 +8165,7 @@ struct ho_cancel_ies_container { }; // HandoverCancel ::= SEQUENCE -struct ho_cancel_s { - bool ext = false; - ho_cancel_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_cancel_s = elementary_procedure_option; // HandoverCancelAcknowledgeIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct ho_cancel_ack_ies_o { @@ -8557,10 +8216,10 @@ struct ho_cancel_ack_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s crit_diagnostics; // sequence methods ho_cancel_ack_ies_container(); @@ -8570,16 +8229,7 @@ struct ho_cancel_ack_ies_container { }; // HandoverCancelAcknowledge ::= SEQUENCE -struct ho_cancel_ack_s { - bool ext = false; - ho_cancel_ack_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_cancel_ack_s = elementary_procedure_option; // HandoverType ::= ENUMERATED struct handov_type_opts { @@ -8676,15 +8326,15 @@ struct ho_cmd_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool nas_security_paramsfrom_e_utran_present = false; - bool erab_subjectto_data_forwarding_list_present = false; - bool erab_to_release_list_ho_cmd_present = false; - bool target_to_source_transparent_container_secondary_present = false; - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s handov_type; - ie_field_s > nas_security_paramsfrom_e_utran; + bool nas_security_paramsfrom_e_utran_present = false; + bool erab_subjectto_data_forwarding_list_present = false; + bool erab_to_release_list_ho_cmd_present = false; + bool target_to_source_transparent_container_secondary_present = false; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s handov_type; + ie_field_s > nas_security_paramsfrom_e_utran; ie_field_s > erab_subjectto_data_forwarding_list; ie_field_s, 1, 256, true> > erab_to_release_list_ho_cmd; ie_field_s > target_to_source_transparent_container; @@ -8699,16 +8349,7 @@ struct ho_cmd_ies_container { }; // HandoverCommand ::= SEQUENCE -struct ho_cmd_s { - bool ext = false; - ho_cmd_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_cmd_s = elementary_procedure_option; // HandoverFailureIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct ho_fail_ies_o { @@ -8761,10 +8402,10 @@ struct ho_fail_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s cause; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s cause; + ie_field_s crit_diagnostics; // sequence methods ho_fail_ies_container(); @@ -8774,16 +8415,7 @@ struct ho_fail_ies_container { }; // HandoverFailure ::= SEQUENCE -struct ho_fail_s { - bool ext = false; - ho_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_fail_s = elementary_procedure_option; // HandoverNotifyIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct ho_notify_ies_o { @@ -8851,16 +8483,16 @@ struct ho_notify_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool tunnel_info_for_bbf_present = false; - bool lhn_id_present = false; - bool ps_cell_info_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s eutran_cgi; - ie_field_s tai; - ie_field_s tunnel_info_for_bbf; - ie_field_s > lhn_id; - ie_field_s ps_cell_info; + bool tunnel_info_for_bbf_present = false; + bool lhn_id_present = false; + bool ps_cell_info_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s eutran_cgi; + ie_field_s tai; + ie_field_s tunnel_info_for_bbf; + ie_field_s > lhn_id; + ie_field_s ps_cell_info; // sequence methods ho_notify_ies_container(); @@ -8870,16 +8502,7 @@ struct ho_notify_ies_container { }; // HandoverNotify ::= SEQUENCE -struct ho_notify_s { - bool ext = false; - ho_notify_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_notify_s = elementary_procedure_option; // HandoverPreparationFailureIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct ho_prep_fail_ies_o { @@ -8932,11 +8555,11 @@ struct ho_prep_fail_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s cause; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s cause; + ie_field_s crit_diagnostics; // sequence methods ho_prep_fail_ies_container(); @@ -8946,19 +8569,10 @@ struct ho_prep_fail_ies_container { }; // HandoverPreparationFailure ::= SEQUENCE -struct ho_prep_fail_s { - bool ext = false; - ho_prep_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_prep_fail_s = elementary_procedure_option; // MBSFN-ResultToLogInfo-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using mbsfn_result_to_log_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using mbsfn_result_to_log_info_ext_ies_o = protocol_ext_empty_o; using mbsfn_result_to_log_info_ext_ies_container = protocol_ext_container_empty_l; @@ -8987,7 +8601,7 @@ struct links_to_log_opts { typedef enumerated links_to_log_e; // LoggedMBSFNMDT-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using logged_mbsfnmdt_ext_ies_o = s1ap_protocol_ext_empty_o; +using logged_mbsfnmdt_ext_ies_o = protocol_ext_empty_o; // LoggingDuration ::= ENUMERATED struct logging_dur_opts { @@ -9010,7 +8624,7 @@ struct logging_interv_opts { typedef enumerated logging_interv_e; // M3Configuration-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using m3_cfg_ext_ies_o = s1ap_protocol_ext_empty_o; +using m3_cfg_ext_ies_o = protocol_ext_empty_o; // M3period ::= ENUMERATED struct m3period_opts { @@ -9035,7 +8649,7 @@ struct m3period_opts { typedef enumerated m3period_e; // M4Configuration-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using m4_cfg_ext_ies_o = s1ap_protocol_ext_empty_o; +using m4_cfg_ext_ies_o = protocol_ext_empty_o; // M4period ::= ENUMERATED struct m4period_opts { @@ -9048,7 +8662,7 @@ struct m4period_opts { typedef enumerated m4period_e; // M5Configuration-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using m5_cfg_ext_ies_o = s1ap_protocol_ext_empty_o; +using m5_cfg_ext_ies_o = protocol_ext_empty_o; // M5period ::= ENUMERATED struct m5period_opts { @@ -9061,7 +8675,7 @@ struct m5period_opts { typedef enumerated m5period_e; // M6Configuration-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using m6_cfg_ext_ies_o = s1ap_protocol_ext_empty_o; +using m6_cfg_ext_ies_o = protocol_ext_empty_o; // M6delay-threshold ::= ENUMERATED struct m6delay_thres_opts { @@ -9084,7 +8698,7 @@ struct m6report_interv_opts { typedef enumerated m6report_interv_e; // M7Configuration-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using m7_cfg_ext_ies_o = s1ap_protocol_ext_empty_o; +using m7_cfg_ext_ies_o = protocol_ext_empty_o; // MBSFN-ResultToLog ::= SEQUENCE (SIZE (1..8)) OF MBSFN-ResultToLogInfo using mbsfn_result_to_log_l = dyn_array; @@ -9101,7 +8715,7 @@ typedef enumerated wlan_meas_cfg_e; using wlan_meas_cfg_name_list_l = bounded_array, 4>; // WLANMeasurementConfiguration-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using wlan_meas_cfg_ext_ies_o = s1ap_protocol_ext_empty_o; +using wlan_meas_cfg_ext_ies_o = protocol_ext_empty_o; using logged_mbsfnmdt_ext_ies_container = protocol_ext_container_empty_l; @@ -9123,10 +8737,10 @@ struct logged_mbsfnmdt_s { }; // M1PeriodicReporting-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using m1_periodic_report_ext_ies_o = s1ap_protocol_ext_empty_o; +using m1_periodic_report_ext_ies_o = protocol_ext_empty_o; // M1ThresholdEventA2-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using m1_thres_event_a2_ext_ies_o = s1ap_protocol_ext_empty_o; +using m1_thres_event_a2_ext_ies_o = protocol_ext_empty_o; using m3_cfg_ext_ies_container = protocol_ext_container_empty_l; @@ -9908,7 +9522,7 @@ struct request_type_ext_ies_o { }; // SecurityContext-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using security_context_ext_ies_o = s1ap_protocol_ext_empty_o; +using security_context_ext_ies_o = protocol_ext_empty_o; // TraceActivation-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION struct trace_activation_ext_ies_o { @@ -9970,13 +9584,13 @@ struct trace_depth_opts { typedef enumerated trace_depth_e; // UE-Sidelink-Aggregate-MaximumBitrates-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using ue_sidelink_aggregate_maximum_bitrates_ext_ies_o = s1ap_protocol_ext_empty_o; +using ue_sidelink_aggregate_maximum_bitrates_ext_ies_o = protocol_ext_empty_o; // UESecurityCapabilities-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using ue_security_cap_ext_ies_o = s1ap_protocol_ext_empty_o; +using ue_security_cap_ext_ies_o = protocol_ext_empty_o; // V2XServicesAuthorized-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using v2xservices_authorized_ext_ies_o = s1ap_protocol_ext_empty_o; +using v2xservices_authorized_ext_ies_o = protocol_ext_empty_o; // VehicleUE ::= ENUMERATED struct vehicle_ue_opts { @@ -10304,34 +9918,34 @@ struct ho_request_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool ho_restrict_list_present = false; - bool trace_activation_present = false; - bool request_type_present = false; - bool srvcc_operation_possible_present = false; - bool nas_security_paramsto_e_utran_present = false; - bool csg_id_present = false; - bool csg_membership_status_present = false; - bool gummei_id_present = false; - bool mme_ue_s1ap_id_minus2_present = false; - bool management_based_mdt_allowed_present = false; - bool management_based_mdtplmn_list_present = false; - bool masked_imeisv_present = false; - bool expected_ue_behaviour_present = false; - bool pro_se_authorized_present = false; - bool ueuser_plane_cio_tsupport_ind_present = false; - bool v2xservices_authorized_present = false; - bool ue_sidelink_aggregate_maximum_bitrate_present = false; - bool enhanced_coverage_restricted_present = false; - bool nrue_security_cap_present = false; - bool ce_mode_brestricted_present = false; - bool aerial_uesubscription_info_present = false; - bool pending_data_ind_present = false; - bool subscription_based_ue_differentiation_info_present = false; - bool add_rrm_prio_idx_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s handov_type; - ie_field_s cause; - ie_field_s ueaggregate_maximum_bitrate; + bool ho_restrict_list_present = false; + bool trace_activation_present = false; + bool request_type_present = false; + bool srvcc_operation_possible_present = false; + bool nas_security_paramsto_e_utran_present = false; + bool csg_id_present = false; + bool csg_membership_status_present = false; + bool gummei_id_present = false; + bool mme_ue_s1ap_id_minus2_present = false; + bool management_based_mdt_allowed_present = false; + bool management_based_mdtplmn_list_present = false; + bool masked_imeisv_present = false; + bool expected_ue_behaviour_present = false; + bool pro_se_authorized_present = false; + bool ueuser_plane_cio_tsupport_ind_present = false; + bool v2xservices_authorized_present = false; + bool ue_sidelink_aggregate_maximum_bitrate_present = false; + bool enhanced_coverage_restricted_present = false; + bool nrue_security_cap_present = false; + bool ce_mode_brestricted_present = false; + bool aerial_uesubscription_info_present = false; + bool pending_data_ind_present = false; + bool subscription_based_ue_differentiation_info_present = false; + bool add_rrm_prio_idx_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s handov_type; + ie_field_s cause; + ie_field_s ueaggregate_maximum_bitrate; ie_field_s > erab_to_be_setup_list_ho_req; ie_field_s > source_to_target_transparent_container; ie_field_s ue_security_cap; @@ -10369,16 +9983,7 @@ struct ho_request_ies_container { }; // HandoverRequest ::= SEQUENCE -struct ho_request_s { - bool ext = false; - ho_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_request_s = elementary_procedure_option; // CE-mode-B-SupportIndicator ::= ENUMERATED struct ce_mode_b_support_ind_opts { @@ -10471,8 +10076,8 @@ struct ho_request_ack_ies_container { bool crit_diagnostics_present = false; bool cell_access_mode_present = false; bool ce_mode_b_support_ind_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s > erab_admitted_list; ie_field_s > erab_failed_to_setup_list_ho_req_ack; ie_field_s > target_to_source_transparent_container; @@ -10489,19 +10094,10 @@ struct ho_request_ack_ies_container { }; // HandoverRequestAcknowledge ::= SEQUENCE -struct ho_request_ack_s { - bool ext = false; - ho_request_ack_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_request_ack_s = elementary_procedure_option; // TargetNgRanNode-ID-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using target_ng_ran_node_id_ext_ies_o = s1ap_protocol_ext_empty_o; +using target_ng_ran_node_id_ext_ies_o = protocol_ext_empty_o; using target_ng_ran_node_id_ext_ies_container = protocol_ext_container_empty_l; @@ -10703,28 +10299,28 @@ struct ho_required_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool direct_forwarding_path_availability_present = false; - bool srvccho_ind_present = false; - bool source_to_target_transparent_container_secondary_present = false; - bool ms_classmark2_present = false; - bool ms_classmark3_present = false; - bool csg_id_present = false; - bool cell_access_mode_present = false; - bool ps_service_not_available_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s handov_type; - ie_field_s cause; - ie_field_s target_id; - ie_field_s direct_forwarding_path_availability; - ie_field_s srvccho_ind; - ie_field_s > source_to_target_transparent_container; - ie_field_s > source_to_target_transparent_container_secondary; - ie_field_s > ms_classmark2; - ie_field_s > ms_classmark3; - ie_field_s > csg_id; - ie_field_s cell_access_mode; - ie_field_s ps_service_not_available; + bool direct_forwarding_path_availability_present = false; + bool srvccho_ind_present = false; + bool source_to_target_transparent_container_secondary_present = false; + bool ms_classmark2_present = false; + bool ms_classmark3_present = false; + bool csg_id_present = false; + bool cell_access_mode_present = false; + bool ps_service_not_available_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s handov_type; + ie_field_s cause; + ie_field_s target_id; + ie_field_s direct_forwarding_path_availability; + ie_field_s srvccho_ind; + ie_field_s > source_to_target_transparent_container; + ie_field_s > source_to_target_transparent_container_secondary; + ie_field_s > ms_classmark2; + ie_field_s > ms_classmark3; + ie_field_s > csg_id; + ie_field_s cell_access_mode; + ie_field_s ps_service_not_available; // sequence methods ho_required_ies_container(); @@ -10734,16 +10330,7 @@ struct ho_required_ies_container { }; // HandoverRequired ::= SEQUENCE -struct ho_required_s { - bool ext = false; - ho_required_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ho_required_s = elementary_procedure_option; // MMEPagingTarget ::= CHOICE struct mme_paging_target_c { @@ -10796,7 +10383,7 @@ struct mme_paging_target_c { }; // RecommendedENBItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using recommended_enb_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using recommended_enb_item_ext_ies_o = protocol_ext_empty_o; using recommended_enb_item_ext_ies_container = protocol_ext_container_empty_l; @@ -10850,10 +10437,10 @@ struct recommended_enb_item_ies_o { using recommended_enb_list_l = bounded_array, 16>; // RecommendedENBsForPaging-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using recommended_enbs_for_paging_ext_ies_o = s1ap_protocol_ext_empty_o; +using recommended_enbs_for_paging_ext_ies_o = protocol_ext_empty_o; // InformationOnRecommendedCellsAndENBsForPaging-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using info_on_recommended_cells_and_enbs_for_paging_ext_ies_o = s1ap_protocol_ext_empty_o; +using info_on_recommended_cells_and_enbs_for_paging_ext_ies_o = protocol_ext_empty_o; using recommended_enbs_for_paging_ext_ies_container = protocol_ext_container_empty_l; @@ -10939,11 +10526,11 @@ struct init_context_setup_fail_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s cause; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s cause; + ie_field_s crit_diagnostics; // sequence methods init_context_setup_fail_ies_container(); @@ -10953,16 +10540,7 @@ struct init_context_setup_fail_ies_container { }; // InitialContextSetupFailure ::= SEQUENCE -struct init_context_setup_fail_s { - bool ext = false; - init_context_setup_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using init_context_setup_fail_s = elementary_procedure_option; // AdditionalCSFallbackIndicator ::= ENUMERATED struct add_cs_fallback_ind_opts { @@ -11137,35 +10715,35 @@ struct init_context_setup_request_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool trace_activation_present = false; - bool ho_restrict_list_present = false; - bool ue_radio_cap_present = false; - bool subscriber_profile_idfor_rfp_present = false; - bool cs_fallback_ind_present = false; - bool srvcc_operation_possible_present = false; - bool csg_membership_status_present = false; - bool registered_lai_present = false; - bool gummei_id_present = false; - bool mme_ue_s1ap_id_minus2_present = false; - bool management_based_mdt_allowed_present = false; - bool management_based_mdtplmn_list_present = false; - bool add_cs_fallback_ind_present = false; - bool masked_imeisv_present = false; - bool expected_ue_behaviour_present = false; - bool pro_se_authorized_present = false; - bool ueuser_plane_cio_tsupport_ind_present = false; - bool v2xservices_authorized_present = false; - bool ue_sidelink_aggregate_maximum_bitrate_present = false; - bool enhanced_coverage_restricted_present = false; - bool nrue_security_cap_present = false; - bool ce_mode_brestricted_present = false; - bool aerial_uesubscription_info_present = false; - bool pending_data_ind_present = false; - bool subscription_based_ue_differentiation_info_present = false; - bool add_rrm_prio_idx_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s ueaggregate_maximum_bitrate; + bool trace_activation_present = false; + bool ho_restrict_list_present = false; + bool ue_radio_cap_present = false; + bool subscriber_profile_idfor_rfp_present = false; + bool cs_fallback_ind_present = false; + bool srvcc_operation_possible_present = false; + bool csg_membership_status_present = false; + bool registered_lai_present = false; + bool gummei_id_present = false; + bool mme_ue_s1ap_id_minus2_present = false; + bool management_based_mdt_allowed_present = false; + bool management_based_mdtplmn_list_present = false; + bool add_cs_fallback_ind_present = false; + bool masked_imeisv_present = false; + bool expected_ue_behaviour_present = false; + bool pro_se_authorized_present = false; + bool ueuser_plane_cio_tsupport_ind_present = false; + bool v2xservices_authorized_present = false; + bool ue_sidelink_aggregate_maximum_bitrate_present = false; + bool enhanced_coverage_restricted_present = false; + bool nrue_security_cap_present = false; + bool ce_mode_brestricted_present = false; + bool aerial_uesubscription_info_present = false; + bool pending_data_ind_present = false; + bool subscription_based_ue_differentiation_info_present = false; + bool add_rrm_prio_idx_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s ueaggregate_maximum_bitrate; ie_field_s, 1, 256, true> > erab_to_be_setup_list_ctxt_su_req; ie_field_s ue_security_cap; @@ -11205,16 +10783,7 @@ struct init_context_setup_request_ies_container { }; // InitialContextSetupRequest ::= SEQUENCE -struct init_context_setup_request_s { - bool ext = false; - init_context_setup_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using init_context_setup_request_s = elementary_procedure_option; // InitialContextSetupResponseIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct init_context_setup_resp_ies_o { @@ -11276,10 +10845,10 @@ struct init_context_setup_resp_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool erab_failed_to_setup_list_ctxt_su_res_present = false; - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool erab_failed_to_setup_list_ctxt_su_res_present = false; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s, 1, 256, true> > erab_setup_list_ctxt_su_res; ie_field_s, 1, 256, true> > @@ -11294,16 +10863,7 @@ struct init_context_setup_resp_ies_container { }; // InitialContextSetupResponse ::= SEQUENCE -struct init_context_setup_resp_s { - bool ext = false; - init_context_setup_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using init_context_setup_resp_s = elementary_procedure_option; // Coverage-Level ::= ENUMERATED struct coverage_level_opts { @@ -11479,45 +11039,45 @@ struct init_ue_msg_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool s_tmsi_present = false; - bool csg_id_present = false; - bool gummei_id_present = false; - bool cell_access_mode_present = false; - bool gw_transport_layer_address_present = false; - bool relay_node_ind_present = false; - bool gummei_type_present = false; - bool tunnel_info_for_bbf_present = false; - bool sipto_l_gw_transport_layer_address_present = false; - bool lhn_id_present = false; - bool mme_group_id_present = false; - bool ue_usage_type_present = false; - bool ce_mode_b_support_ind_present = false; - bool dcn_id_present = false; - bool coverage_level_present = false; - bool ue_application_layer_meas_cap_present = false; - bool edt_session_present = false; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > nas_pdu; - ie_field_s tai; - ie_field_s eutran_cgi; - ie_field_s rrc_establishment_cause; - ie_field_s s_tmsi; - ie_field_s > csg_id; - ie_field_s gummei_id; - ie_field_s cell_access_mode; - ie_field_s > gw_transport_layer_address; - ie_field_s relay_node_ind; - ie_field_s gummei_type; - ie_field_s tunnel_info_for_bbf; - ie_field_s > sipto_l_gw_transport_layer_address; - ie_field_s > lhn_id; - ie_field_s > mme_group_id; - ie_field_s > ue_usage_type; - ie_field_s ce_mode_b_support_ind; - ie_field_s > dcn_id; - ie_field_s coverage_level; - ie_field_s > ue_application_layer_meas_cap; - ie_field_s edt_session; + bool s_tmsi_present = false; + bool csg_id_present = false; + bool gummei_id_present = false; + bool cell_access_mode_present = false; + bool gw_transport_layer_address_present = false; + bool relay_node_ind_present = false; + bool gummei_type_present = false; + bool tunnel_info_for_bbf_present = false; + bool sipto_l_gw_transport_layer_address_present = false; + bool lhn_id_present = false; + bool mme_group_id_present = false; + bool ue_usage_type_present = false; + bool ce_mode_b_support_ind_present = false; + bool dcn_id_present = false; + bool coverage_level_present = false; + bool ue_application_layer_meas_cap_present = false; + bool edt_session_present = false; + ie_field_s enb_ue_s1ap_id; + ie_field_s > nas_pdu; + ie_field_s tai; + ie_field_s eutran_cgi; + ie_field_s rrc_establishment_cause; + ie_field_s s_tmsi; + ie_field_s > csg_id; + ie_field_s gummei_id; + ie_field_s cell_access_mode; + ie_field_s > gw_transport_layer_address; + ie_field_s relay_node_ind; + ie_field_s gummei_type; + ie_field_s tunnel_info_for_bbf; + ie_field_s > sipto_l_gw_transport_layer_address; + ie_field_s > lhn_id; + ie_field_s > mme_group_id; + ie_field_s > ue_usage_type; + ie_field_s ce_mode_b_support_ind; + ie_field_s > dcn_id; + ie_field_s coverage_level; + ie_field_s > ue_application_layer_meas_cap; + ie_field_s edt_session; // sequence methods init_ue_msg_ies_container(); @@ -11527,22 +11087,13 @@ struct init_ue_msg_ies_container { }; // InitialUEMessage ::= SEQUENCE -struct init_ue_msg_s { - bool ext = false; - init_ue_msg_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using init_ue_msg_s = elementary_procedure_option; // UE-associatedLogicalS1-ConnectionItemExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using ue_associated_lc_s1_conn_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using ue_associated_lc_s1_conn_item_ext_ies_o = protocol_ext_empty_o; // TAIItemExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using tai_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using tai_item_ext_ies_o = protocol_ext_empty_o; using ue_associated_lc_s1_conn_item_ext_ies_container = protocol_ext_container_empty_l; @@ -11564,7 +11115,7 @@ struct ue_associated_lc_s1_conn_item_s { }; // ServedDCNsItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using served_dcns_item_ext_ies_o = s1ap_protocol_ext_empty_o; +using served_dcns_item_ext_ies_o = protocol_ext_empty_o; // ServedGUMMEIsItem-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION struct served_gummeis_item_ext_ies_o { @@ -11624,7 +11175,7 @@ struct tai_item_s { }; // UE-S1AP-ID-pair-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using ue_s1ap_id_pair_ext_ies_o = s1ap_protocol_ext_empty_o; +using ue_s1ap_id_pair_ext_ies_o = protocol_ext_empty_o; // UE-associatedLogicalS1-ConnectionItemRes ::= OBJECT SET OF S1AP-PROTOCOL-IES struct ue_associated_lc_s1_conn_item_res_o { @@ -11687,7 +11238,7 @@ struct nb_io_t_paging_e_drx_cycle_opts { typedef enumerated nb_io_t_paging_e_drx_cycle_e; // NB-IoT-Paging-eDRXInformation-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using nb_io_t_paging_e_drx_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using nb_io_t_paging_e_drx_info_ext_ies_o = protocol_ext_empty_o; // NB-IoT-PagingTimeWindow ::= ENUMERATED struct nb_io_t_paging_time_win_opts { @@ -11745,7 +11296,7 @@ struct paging_e_drx_cycle_opts { typedef enumerated paging_e_drx_cycle_e; // Paging-eDRXInformation-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using paging_e_drx_info_ext_ies_o = s1ap_protocol_ext_empty_o; +using paging_e_drx_info_ext_ies_o = protocol_ext_empty_o; // PagingTimeWindow ::= ENUMERATED struct paging_time_win_opts { @@ -15235,16 +14786,7 @@ struct kill_request_ies_container { }; // KillRequest ::= SEQUENCE -struct kill_request_s { - bool ext = false; - kill_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using kill_request_s = elementary_procedure_option; struct kill_resp_ies_container { template @@ -15266,29 +14808,20 @@ struct kill_resp_ies_container { }; // KillResponse ::= SEQUENCE -struct kill_resp_s { - bool ext = false; - kill_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using kill_resp_s = elementary_procedure_option; struct location_report_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool ps_cell_info_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s eutran_cgi; - ie_field_s tai; - ie_field_s request_type; - ie_field_s ps_cell_info; + bool ps_cell_info_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s eutran_cgi; + ie_field_s tai; + ie_field_s request_type; + ie_field_s ps_cell_info; // sequence methods location_report_ies_container(); @@ -15298,25 +14831,16 @@ struct location_report_ies_container { }; // LocationReport ::= SEQUENCE -struct location_report_s { - bool ext = false; - location_report_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using location_report_s = elementary_procedure_option; struct location_report_ctrl_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s request_type; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s request_type; // sequence methods location_report_ctrl_ies_container(); @@ -15326,25 +14850,16 @@ struct location_report_ctrl_ies_container { }; // LocationReportingControl ::= SEQUENCE -struct location_report_ctrl_s { - bool ext = false; - location_report_ctrl_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using location_report_ctrl_s = elementary_procedure_option; struct location_report_fail_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s cause; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s cause; // sequence methods location_report_fail_ind_ies_container(); @@ -15354,24 +14869,15 @@ struct location_report_fail_ind_ies_container { }; // LocationReportingFailureIndication ::= SEQUENCE -struct location_report_fail_ind_s { - bool ext = false; - location_report_fail_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using location_report_fail_ind_s = elementary_procedure_option; struct mmecp_relocation_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; // sequence methods mmecp_relocation_ind_ies_container(); @@ -15381,16 +14887,7 @@ struct mmecp_relocation_ind_ies_container { }; // MMECPRelocationIndication ::= SEQUENCE -struct mmecp_relocation_ind_s { - bool ext = false; - mmecp_relocation_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using mmecp_relocation_ind_s = elementary_procedure_option; struct mme_cfg_transfer_ies_container { template @@ -15410,16 +14907,7 @@ struct mme_cfg_transfer_ies_container { }; // MMEConfigurationTransfer ::= SEQUENCE -struct mme_cfg_transfer_s { - bool ext = false; - mme_cfg_transfer_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using mme_cfg_transfer_s = elementary_procedure_option; struct mme_cfg_upd_ies_container { template @@ -15443,28 +14931,10 @@ struct mme_cfg_upd_ies_container { }; // MMEConfigurationUpdate ::= SEQUENCE -struct mme_cfg_upd_s { - bool ext = false; - mme_cfg_upd_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using mme_cfg_upd_s = elementary_procedure_option; // MMEConfigurationUpdateAcknowledge ::= SEQUENCE -struct mme_cfg_upd_ack_s { - bool ext = false; - protocol_ie_container_l protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using mme_cfg_upd_ack_s = elementary_procedure_option >; struct mme_cfg_upd_fail_ies_container { template @@ -15485,37 +14955,20 @@ struct mme_cfg_upd_fail_ies_container { }; // MMEConfigurationUpdateFailure ::= SEQUENCE -struct mme_cfg_upd_fail_s { - bool ext = false; - mme_cfg_upd_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using mme_cfg_upd_fail_s = elementary_procedure_option; // MMEDirectInformationTransfer ::= SEQUENCE -struct mme_direct_info_transfer_s { - bool ext = false; - protocol_ie_container_l protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using mme_direct_info_transfer_s = + elementary_procedure_option >; struct mme_status_transfer_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s enb_status_transfer_transparent_container; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s enb_status_transfer_transparent_container; // sequence methods mme_status_transfer_ies_container(); @@ -15525,24 +14978,15 @@ struct mme_status_transfer_ies_container { }; // MMEStatusTransfer ::= SEQUENCE -struct mme_status_transfer_s { - bool ext = false; - mme_status_transfer_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using mme_status_transfer_s = elementary_procedure_option; struct nas_delivery_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; // sequence methods nas_delivery_ind_ies_container(); @@ -15552,26 +14996,17 @@ struct nas_delivery_ind_ies_container { }; // NASDeliveryIndication ::= SEQUENCE -struct nas_delivery_ind_s { - bool ext = false; - nas_delivery_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using nas_delivery_ind_s = elementary_procedure_option; struct nas_non_delivery_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > nas_pdu; - ie_field_s cause; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > nas_pdu; + ie_field_s cause; // sequence methods nas_non_delivery_ind_ies_container(); @@ -15581,16 +15016,7 @@ struct nas_non_delivery_ind_ies_container { }; // NASNonDeliveryIndication ::= SEQUENCE -struct nas_non_delivery_ind_s { - bool ext = false; - nas_non_delivery_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using nas_non_delivery_ind_s = elementary_procedure_option; struct overload_start_ies_container { template @@ -15611,28 +15037,10 @@ struct overload_start_ies_container { }; // OverloadStart ::= SEQUENCE -struct overload_start_s { - bool ext = false; - overload_start_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using overload_start_s = elementary_procedure_option; // OverloadStop ::= SEQUENCE -struct overload_stop_s { - bool ext = false; - protocol_ie_container_l protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using overload_stop_s = elementary_procedure_option >; struct pws_fail_ind_ies_container { template @@ -15650,16 +15058,7 @@ struct pws_fail_ind_ies_container { }; // PWSFailureIndication ::= SEQUENCE -struct pws_fail_ind_s { - bool ext = false; - pws_fail_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pws_fail_ind_s = elementary_procedure_option; struct pws_restart_ind_ies_container { template @@ -15680,16 +15079,7 @@ struct pws_restart_ind_ies_container { }; // PWSRestartIndication ::= SEQUENCE -struct pws_restart_ind_s { - bool ext = false; - pws_restart_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using pws_restart_ind_s = elementary_procedure_option; struct paging_ies_container { template @@ -15731,16 +15121,7 @@ struct paging_ies_container { }; // Paging ::= SEQUENCE -struct paging_s { - bool ext = false; - paging_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using paging_s = elementary_procedure_option; struct path_switch_request_ies_container { template @@ -15756,7 +15137,7 @@ struct path_switch_request_ies_container { bool rrc_resume_cause_present = false; bool nrue_security_cap_present = false; bool ps_cell_info_present = false; - ie_field_s > enb_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s > erab_to_be_switched_dl_list; ie_field_s > source_mme_ue_s1ap_id; ie_field_s eutran_cgi; @@ -15780,43 +15161,34 @@ struct path_switch_request_ies_container { }; // PathSwitchRequest ::= SEQUENCE -struct path_switch_request_s { - bool ext = false; - path_switch_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using path_switch_request_s = elementary_procedure_option; struct path_switch_request_ack_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool ueaggregate_maximum_bitrate_present = false; - bool erab_to_be_switched_ul_list_present = false; - bool erab_to_be_released_list_present = false; - bool crit_diagnostics_present = false; - bool mme_ue_s1ap_id_minus2_present = false; - bool csg_membership_status_present = false; - bool pro_se_authorized_present = false; - bool ueuser_plane_cio_tsupport_ind_present = false; - bool v2xservices_authorized_present = false; - bool ue_sidelink_aggregate_maximum_bitrate_present = false; - bool enhanced_coverage_restricted_present = false; - bool nrue_security_cap_present = false; - bool ce_mode_brestricted_present = false; - bool aerial_uesubscription_info_present = false; - bool pending_data_ind_present = false; - bool subscription_based_ue_differentiation_info_present = false; - bool ho_restrict_list_present = false; - bool add_rrm_prio_idx_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s ueaggregate_maximum_bitrate; + bool ueaggregate_maximum_bitrate_present = false; + bool erab_to_be_switched_ul_list_present = false; + bool erab_to_be_released_list_present = false; + bool crit_diagnostics_present = false; + bool mme_ue_s1ap_id_minus2_present = false; + bool csg_membership_status_present = false; + bool pro_se_authorized_present = false; + bool ueuser_plane_cio_tsupport_ind_present = false; + bool v2xservices_authorized_present = false; + bool ue_sidelink_aggregate_maximum_bitrate_present = false; + bool enhanced_coverage_restricted_present = false; + bool nrue_security_cap_present = false; + bool ce_mode_brestricted_present = false; + bool aerial_uesubscription_info_present = false; + bool pending_data_ind_present = false; + bool subscription_based_ue_differentiation_info_present = false; + bool ho_restrict_list_present = false; + bool add_rrm_prio_idx_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s ueaggregate_maximum_bitrate; ie_field_s > erab_to_be_switched_ul_list; ie_field_s, 1, 256, true> > erab_to_be_released_list; ie_field_s security_context; @@ -15844,27 +15216,18 @@ struct path_switch_request_ack_ies_container { }; // PathSwitchRequestAcknowledge ::= SEQUENCE -struct path_switch_request_ack_s { - bool ext = false; - path_switch_request_ack_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using path_switch_request_ack_s = elementary_procedure_option; struct path_switch_request_fail_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s cause; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s cause; + ie_field_s crit_diagnostics; // sequence methods path_switch_request_fail_ies_container(); @@ -15874,16 +15237,7 @@ struct path_switch_request_fail_ies_container { }; // PathSwitchRequestFailure ::= SEQUENCE -struct path_switch_request_fail_s { - bool ext = false; - path_switch_request_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using path_switch_request_fail_s = elementary_procedure_option; template struct private_ie_container_item_s { @@ -15926,15 +15280,15 @@ struct reroute_nas_request_ies_container { using ie_field_s = protocol_ie_container_item_s; // member variables - bool mme_ue_s1ap_id_present = false; - bool add_guti_present = false; - bool ue_usage_type_present = false; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > s1_msg; - ie_field_s > mme_group_id; - ie_field_s add_guti; - ie_field_s > ue_usage_type; + bool mme_ue_s1ap_id_present = false; + bool add_guti_present = false; + bool ue_usage_type_present = false; + ie_field_s enb_ue_s1ap_id; + ie_field_s mme_ue_s1ap_id; + ie_field_s > s1_msg; + ie_field_s > mme_group_id; + ie_field_s add_guti; + ie_field_s > ue_usage_type; // sequence methods reroute_nas_request_ies_container(); @@ -15944,16 +15298,7 @@ struct reroute_nas_request_ies_container { }; // RerouteNASRequest ::= SEQUENCE -struct reroute_nas_request_s { - bool ext = false; - reroute_nas_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using reroute_nas_request_s = elementary_procedure_option; struct reset_ies_container { template @@ -15971,16 +15316,7 @@ struct reset_ies_container { }; // Reset ::= SEQUENCE -struct reset_s { - bool ext = false; - reset_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using reset_s = elementary_procedure_option; struct reset_ack_ies_container { template @@ -16001,28 +15337,10 @@ struct reset_ack_ies_container { }; // ResetAcknowledge ::= SEQUENCE -struct reset_ack_s { - bool ext = false; - reset_ack_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using reset_ack_s = elementary_procedure_option; // RetrieveUEInformation ::= SEQUENCE -struct retrieve_ue_info_s { - bool ext = false; - protocol_ie_container_l protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using retrieve_ue_info_s = elementary_procedure_option >; struct s1_setup_fail_ies_container { template @@ -16043,16 +15361,7 @@ struct s1_setup_fail_ies_container { }; // S1SetupFailure ::= SEQUENCE -struct s1_setup_fail_s { - bool ext = false; - s1_setup_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using s1_setup_fail_s = elementary_procedure_option; struct s1_setup_request_ies_container { template @@ -16081,16 +15390,7 @@ struct s1_setup_request_ies_container { }; // S1SetupRequest ::= SEQUENCE -struct s1_setup_request_s { - bool ext = false; - s1_setup_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using s1_setup_request_s = elementary_procedure_option; struct s1_setup_resp_ies_container { template @@ -16118,27 +15418,18 @@ struct s1_setup_resp_ies_container { }; // S1SetupResponse ::= SEQUENCE -struct s1_setup_resp_s { - bool ext = false; - s1_setup_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using s1_setup_resp_s = elementary_procedure_option; struct secondary_rat_data_usage_report_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool ho_flag_present = false; - bool user_location_info_present = false; - bool time_since_secondary_node_release_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool ho_flag_present = false; + bool user_location_info_present = false; + bool time_since_secondary_node_release_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s, 1, 256, true> > secondary_rat_data_usage_report_list; ie_field_s ho_flag; @@ -16153,26 +15444,17 @@ struct secondary_rat_data_usage_report_ies_container { }; // SecondaryRATDataUsageReport ::= SEQUENCE -struct secondary_rat_data_usage_report_s { - bool ext = false; - secondary_rat_data_usage_report_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using secondary_rat_data_usage_report_s = elementary_procedure_option; struct trace_fail_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > e_utran_trace_id; - ie_field_s cause; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > e_utran_trace_id; + ie_field_s cause; // sequence methods trace_fail_ind_ies_container(); @@ -16182,25 +15464,16 @@ struct trace_fail_ind_ies_container { }; // TraceFailureIndication ::= SEQUENCE -struct trace_fail_ind_s { - bool ext = false; - trace_fail_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using trace_fail_ind_s = elementary_procedure_option; struct trace_start_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s trace_activation; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s trace_activation; // sequence methods trace_start_ies_container(); @@ -16210,31 +15483,22 @@ struct trace_start_ies_container { }; // TraceStart ::= SEQUENCE -struct trace_start_s { - bool ext = false; - trace_start_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using trace_start_s = elementary_procedure_option; struct ue_cap_info_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool ue_radio_cap_for_paging_present = false; - bool ue_application_layer_meas_cap_present = false; - bool lte_m_ind_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > ue_radio_cap; - ie_field_s > ue_radio_cap_for_paging; - ie_field_s > ue_application_layer_meas_cap; - ie_field_s lte_m_ind; + bool ue_radio_cap_for_paging_present = false; + bool ue_application_layer_meas_cap_present = false; + bool lte_m_ind_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > ue_radio_cap; + ie_field_s > ue_radio_cap_for_paging; + ie_field_s > ue_application_layer_meas_cap; + ie_field_s lte_m_ind; // sequence methods ue_cap_info_ind_ies_container(); @@ -16244,28 +15508,19 @@ struct ue_cap_info_ind_ies_container { }; // UECapabilityInfoIndication ::= SEQUENCE -struct ue_cap_info_ind_s { - bool ext = false; - ue_cap_info_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_cap_info_ind_s = elementary_procedure_option; struct ue_context_mod_confirm_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool csg_membership_status_present = false; - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s csg_membership_status; - ie_field_s crit_diagnostics; + bool csg_membership_status_present = false; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s csg_membership_status; + ie_field_s crit_diagnostics; // sequence methods ue_context_mod_confirm_ies_container(); @@ -16275,27 +15530,18 @@ struct ue_context_mod_confirm_ies_container { }; // UEContextModificationConfirm ::= SEQUENCE -struct ue_context_mod_confirm_s { - bool ext = false; - ue_context_mod_confirm_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_mod_confirm_s = elementary_procedure_option; struct ue_context_mod_fail_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s cause; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s cause; + ie_field_s crit_diagnostics; // sequence methods ue_context_mod_fail_ies_container(); @@ -16305,26 +15551,17 @@ struct ue_context_mod_fail_ies_container { }; // UEContextModificationFailure ::= SEQUENCE -struct ue_context_mod_fail_s { - bool ext = false; - ue_context_mod_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_mod_fail_s = elementary_procedure_option; struct ue_context_mod_ind_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool csg_membership_info_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s csg_membership_info; + bool csg_membership_info_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s csg_membership_info; // sequence methods ue_context_mod_ind_ies_container(); @@ -16334,56 +15571,47 @@ struct ue_context_mod_ind_ies_container { }; // UEContextModificationIndication ::= SEQUENCE -struct ue_context_mod_ind_s { - bool ext = false; - ue_context_mod_ind_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_mod_ind_s = elementary_procedure_option; struct ue_context_mod_request_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool security_key_present = false; - bool subscriber_profile_idfor_rfp_present = false; - bool ueaggregate_maximum_bitrate_present = false; - bool cs_fallback_ind_present = false; - bool ue_security_cap_present = false; - bool csg_membership_status_present = false; - bool registered_lai_present = false; - bool add_cs_fallback_ind_present = false; - bool pro_se_authorized_present = false; - bool srvcc_operation_possible_present = false; - bool srvcc_operation_not_possible_present = false; - bool v2xservices_authorized_present = false; - bool ue_sidelink_aggregate_maximum_bitrate_present = false; - bool nrue_security_cap_present = false; - bool aerial_uesubscription_info_present = false; - bool add_rrm_prio_idx_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > security_key; - ie_field_s > subscriber_profile_idfor_rfp; - ie_field_s ueaggregate_maximum_bitrate; - ie_field_s cs_fallback_ind; - ie_field_s ue_security_cap; - ie_field_s csg_membership_status; - ie_field_s registered_lai; - ie_field_s add_cs_fallback_ind; - ie_field_s pro_se_authorized; - ie_field_s srvcc_operation_possible; - ie_field_s srvcc_operation_not_possible; - ie_field_s v2xservices_authorized; - ie_field_s ue_sidelink_aggregate_maximum_bitrate; - ie_field_s nrue_security_cap; - ie_field_s aerial_uesubscription_info; - ie_field_s > add_rrm_prio_idx; + bool security_key_present = false; + bool subscriber_profile_idfor_rfp_present = false; + bool ueaggregate_maximum_bitrate_present = false; + bool cs_fallback_ind_present = false; + bool ue_security_cap_present = false; + bool csg_membership_status_present = false; + bool registered_lai_present = false; + bool add_cs_fallback_ind_present = false; + bool pro_se_authorized_present = false; + bool srvcc_operation_possible_present = false; + bool srvcc_operation_not_possible_present = false; + bool v2xservices_authorized_present = false; + bool ue_sidelink_aggregate_maximum_bitrate_present = false; + bool nrue_security_cap_present = false; + bool aerial_uesubscription_info_present = false; + bool add_rrm_prio_idx_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > security_key; + ie_field_s > subscriber_profile_idfor_rfp; + ie_field_s ueaggregate_maximum_bitrate; + ie_field_s cs_fallback_ind; + ie_field_s ue_security_cap; + ie_field_s csg_membership_status; + ie_field_s registered_lai; + ie_field_s add_cs_fallback_ind; + ie_field_s pro_se_authorized; + ie_field_s srvcc_operation_possible; + ie_field_s srvcc_operation_not_possible; + ie_field_s v2xservices_authorized; + ie_field_s ue_sidelink_aggregate_maximum_bitrate; + ie_field_s nrue_security_cap; + ie_field_s aerial_uesubscription_info; + ie_field_s > add_rrm_prio_idx; // sequence methods ue_context_mod_request_ies_container(); @@ -16393,26 +15621,17 @@ struct ue_context_mod_request_ies_container { }; // UEContextModificationRequest ::= SEQUENCE -struct ue_context_mod_request_s { - bool ext = false; - ue_context_mod_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_mod_request_s = elementary_procedure_option; struct ue_context_mod_resp_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s crit_diagnostics; // sequence methods ue_context_mod_resp_ies_container(); @@ -16422,16 +15641,7 @@ struct ue_context_mod_resp_ies_container { }; // UEContextModificationResponse ::= SEQUENCE -struct ue_context_mod_resp_s { - bool ext = false; - ue_context_mod_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_mod_resp_s = elementary_procedure_option; struct ue_context_release_cmd_ies_container { template @@ -16449,32 +15659,23 @@ struct ue_context_release_cmd_ies_container { }; // UEContextReleaseCommand ::= SEQUENCE -struct ue_context_release_cmd_s { - bool ext = false; - ue_context_release_cmd_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_release_cmd_s = elementary_procedure_option; struct ue_context_release_complete_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - bool user_location_info_present = false; - bool info_on_recommended_cells_and_enbs_for_paging_present = false; - bool cell_id_and_ce_level_for_ce_capable_ues_present = false; - bool secondary_rat_data_usage_report_list_present = false; - bool time_since_secondary_node_release_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s crit_diagnostics; - ie_field_s user_location_info; + bool crit_diagnostics_present = false; + bool user_location_info_present = false; + bool info_on_recommended_cells_and_enbs_for_paging_present = false; + bool cell_id_and_ce_level_for_ce_capable_ues_present = false; + bool secondary_rat_data_usage_report_list_present = false; + bool time_since_secondary_node_release_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s crit_diagnostics; + ie_field_s user_location_info; ie_field_s info_on_recommended_cells_and_enbs_for_paging; ie_field_s cell_id_and_ce_level_for_ce_capable_ues; ie_field_s, 1, 256, true> > @@ -16489,28 +15690,19 @@ struct ue_context_release_complete_ies_container { }; // UEContextReleaseComplete ::= SEQUENCE -struct ue_context_release_complete_s { - bool ext = false; - ue_context_release_complete_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_release_complete_s = elementary_procedure_option; struct ue_context_release_request_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool gw_context_release_ind_present = false; - bool secondary_rat_data_usage_report_list_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s cause; - ie_field_s gw_context_release_ind; + bool gw_context_release_ind_present = false; + bool secondary_rat_data_usage_report_list_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s cause; + ie_field_s gw_context_release_ind; ie_field_s, 1, 256, true> > secondary_rat_data_usage_report_list; @@ -16522,27 +15714,18 @@ struct ue_context_release_request_ies_container { }; // UEContextReleaseRequest ::= SEQUENCE -struct ue_context_release_request_s { - bool ext = false; - ue_context_release_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_release_request_s = elementary_procedure_option; struct ue_context_resume_fail_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s cause; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s cause; + ie_field_s crit_diagnostics; // sequence methods ue_context_resume_fail_ies_container(); @@ -16552,26 +15735,17 @@ struct ue_context_resume_fail_ies_container { }; // UEContextResumeFailure ::= SEQUENCE -struct ue_context_resume_fail_s { - bool ext = false; - ue_context_resume_fail_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_resume_fail_s = elementary_procedure_option; struct ue_context_resume_request_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool erab_failed_to_resume_list_resume_req_present = false; - bool rrc_resume_cause_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool erab_failed_to_resume_list_resume_req_present = false; + bool rrc_resume_cause_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s > erab_failed_to_resume_list_resume_req; ie_field_s rrc_resume_cause; @@ -16584,28 +15758,19 @@ struct ue_context_resume_request_ies_container { }; // UEContextResumeRequest ::= SEQUENCE -struct ue_context_resume_request_s { - bool ext = false; - ue_context_resume_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_resume_request_s = elementary_procedure_option; struct ue_context_resume_resp_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool erab_failed_to_resume_list_resume_res_present = false; - bool crit_diagnostics_present = false; - bool security_context_present = false; - bool pending_data_ind_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool erab_failed_to_resume_list_resume_res_present = false; + bool crit_diagnostics_present = false; + bool security_context_present = false; + bool pending_data_ind_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s > erab_failed_to_resume_list_resume_res; ie_field_s crit_diagnostics; @@ -16620,29 +15785,20 @@ struct ue_context_resume_resp_ies_container { }; // UEContextResumeResponse ::= SEQUENCE -struct ue_context_resume_resp_s { - bool ext = false; - ue_context_resume_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_resume_resp_s = elementary_procedure_option; struct ue_context_suspend_request_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool info_on_recommended_cells_and_enbs_for_paging_present = false; - bool cell_id_and_ce_level_for_ce_capable_ues_present = false; - bool secondary_rat_data_usage_report_list_present = false; - bool user_location_info_present = false; - bool time_since_secondary_node_release_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; + bool info_on_recommended_cells_and_enbs_for_paging_present = false; + bool cell_id_and_ce_level_for_ce_capable_ues_present = false; + bool secondary_rat_data_usage_report_list_present = false; + bool user_location_info_present = false; + bool time_since_secondary_node_release_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; ie_field_s info_on_recommended_cells_and_enbs_for_paging; ie_field_s cell_id_and_ce_level_for_ce_capable_ues; ie_field_s, 1, 256, true> > @@ -16658,28 +15814,19 @@ struct ue_context_suspend_request_ies_container { }; // UEContextSuspendRequest ::= SEQUENCE -struct ue_context_suspend_request_s { - bool ext = false; - ue_context_suspend_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_suspend_request_s = elementary_procedure_option; struct ue_context_suspend_resp_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - bool security_context_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s crit_diagnostics; - ie_field_s security_context; + bool crit_diagnostics_present = false; + bool security_context_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s crit_diagnostics; + ie_field_s security_context; // sequence methods ue_context_suspend_resp_ies_container(); @@ -16689,16 +15836,7 @@ struct ue_context_suspend_resp_ies_container { }; // UEContextSuspendResponse ::= SEQUENCE -struct ue_context_suspend_resp_s { - bool ext = false; - ue_context_suspend_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_context_suspend_resp_s = elementary_procedure_option; struct ue_info_transfer_ies_container { template @@ -16723,26 +15861,17 @@ struct ue_info_transfer_ies_container { }; // UEInformationTransfer ::= SEQUENCE -struct ue_info_transfer_s { - bool ext = false; - ue_info_transfer_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_info_transfer_s = elementary_procedure_option; struct ue_radio_cap_match_request_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool ue_radio_cap_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > ue_radio_cap; + bool ue_radio_cap_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > ue_radio_cap; // sequence methods ue_radio_cap_match_request_ies_container(); @@ -16752,27 +15881,18 @@ struct ue_radio_cap_match_request_ies_container { }; // UERadioCapabilityMatchRequest ::= SEQUENCE -struct ue_radio_cap_match_request_s { - bool ext = false; - ue_radio_cap_match_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_radio_cap_match_request_s = elementary_procedure_option; struct ue_radio_cap_match_resp_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool crit_diagnostics_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s voice_support_match_ind; - ie_field_s crit_diagnostics; + bool crit_diagnostics_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s voice_support_match_ind; + ie_field_s crit_diagnostics; // sequence methods ue_radio_cap_match_resp_ies_container(); @@ -16782,35 +15902,26 @@ struct ue_radio_cap_match_resp_ies_container { }; // UERadioCapabilityMatchResponse ::= SEQUENCE -struct ue_radio_cap_match_resp_s { - bool ext = false; - ue_radio_cap_match_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ue_radio_cap_match_resp_s = elementary_procedure_option; struct ul_nas_transport_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool gw_transport_layer_address_present = false; - bool sipto_l_gw_transport_layer_address_present = false; - bool lhn_id_present = false; - bool ps_cell_info_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > nas_pdu; - ie_field_s eutran_cgi; - ie_field_s tai; - ie_field_s > gw_transport_layer_address; - ie_field_s > sipto_l_gw_transport_layer_address; - ie_field_s > lhn_id; - ie_field_s ps_cell_info; + bool gw_transport_layer_address_present = false; + bool sipto_l_gw_transport_layer_address_present = false; + bool lhn_id_present = false; + bool ps_cell_info_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > nas_pdu; + ie_field_s eutran_cgi; + ie_field_s tai; + ie_field_s > gw_transport_layer_address; + ie_field_s > sipto_l_gw_transport_layer_address; + ie_field_s > lhn_id; + ie_field_s ps_cell_info; // sequence methods ul_nas_transport_ies_container(); @@ -16820,16 +15931,7 @@ struct ul_nas_transport_ies_container { }; // UplinkNASTransport ::= SEQUENCE -struct ul_nas_transport_s { - bool ext = false; - ul_nas_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ul_nas_transport_s = elementary_procedure_option; struct ul_non_ueassociated_lp_pa_transport_ies_container { template @@ -16847,35 +15949,27 @@ struct ul_non_ueassociated_lp_pa_transport_ies_container { }; // UplinkNonUEAssociatedLPPaTransport ::= SEQUENCE -struct ul_non_ueassociated_lp_pa_transport_s { - bool ext = false; - ul_non_ueassociated_lp_pa_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ul_non_ueassociated_lp_pa_transport_s = + elementary_procedure_option; struct ul_s1cdma2000tunnelling_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - bool cdma2000_ho_required_ind_present = false; - bool cdma2000_one_xsrvcc_info_present = false; - bool cdma2000_one_xrand_present = false; - bool eutran_round_trip_delay_estimation_info_present = false; - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s cdma2000_rat_type; - ie_field_s > cdma2000_sector_id; - ie_field_s cdma2000_ho_required_ind; - ie_field_s cdma2000_one_xsrvcc_info; - ie_field_s > cdma2000_one_xrand; - ie_field_s > cdma2000_pdu; - ie_field_s > eutran_round_trip_delay_estimation_info; + bool cdma2000_ho_required_ind_present = false; + bool cdma2000_one_xsrvcc_info_present = false; + bool cdma2000_one_xrand_present = false; + bool eutran_round_trip_delay_estimation_info_present = false; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s cdma2000_rat_type; + ie_field_s > cdma2000_sector_id; + ie_field_s cdma2000_ho_required_ind; + ie_field_s cdma2000_one_xsrvcc_info; + ie_field_s > cdma2000_one_xrand; + ie_field_s > cdma2000_pdu; + ie_field_s > eutran_round_trip_delay_estimation_info; // sequence methods ul_s1cdma2000tunnelling_ies_container(); @@ -16885,26 +15979,17 @@ struct ul_s1cdma2000tunnelling_ies_container { }; // UplinkS1cdma2000tunnelling ::= SEQUENCE -struct ul_s1cdma2000tunnelling_s { - bool ext = false; - ul_s1cdma2000tunnelling_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ul_s1cdma2000tunnelling_s = elementary_procedure_option; struct ul_ueassociated_lp_pa_transport_ies_container { template using ie_field_s = protocol_ie_container_item_s; // member variables - ie_field_s > mme_ue_s1ap_id; - ie_field_s > enb_ue_s1ap_id; - ie_field_s > routing_id; - ie_field_s > lp_pa_pdu; + ie_field_s mme_ue_s1ap_id; + ie_field_s enb_ue_s1ap_id; + ie_field_s > routing_id; + ie_field_s > lp_pa_pdu; // sequence methods ul_ueassociated_lp_pa_transport_ies_container(); @@ -16914,16 +15999,7 @@ struct ul_ueassociated_lp_pa_transport_ies_container { }; // UplinkUEAssociatedLPPaTransport ::= SEQUENCE -struct ul_ueassociated_lp_pa_transport_s { - bool ext = false; - ul_ueassociated_lp_pa_transport_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using ul_ueassociated_lp_pa_transport_s = elementary_procedure_option; struct write_replace_warning_request_ies_container { template @@ -16959,16 +16035,7 @@ struct write_replace_warning_request_ies_container { }; // WriteReplaceWarningRequest ::= SEQUENCE -struct write_replace_warning_request_s { - bool ext = false; - write_replace_warning_request_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using write_replace_warning_request_s = elementary_procedure_option; struct write_replace_warning_resp_ies_container { template @@ -16990,16 +16057,7 @@ struct write_replace_warning_resp_ies_container { }; // WriteReplaceWarningResponse ::= SEQUENCE -struct write_replace_warning_resp_s { - bool ext = false; - write_replace_warning_resp_ies_container protocol_ies; - // ... - - // sequence methods - SRSASN_CODE pack(bit_ref& bref) const; - SRSASN_CODE unpack(cbit_ref& bref); - void to_json(json_writer& j) const; -}; +using write_replace_warning_resp_s = elementary_procedure_option; // S1AP-ELEMENTARY-PROCEDURES ::= OBJECT SET OF S1AP-ELEMENTARY-PROCEDURE struct s1ap_elem_procs_o { @@ -18216,7 +17274,7 @@ struct sourceenb_to_targetenb_transparent_container_s { }; // TargeteNB-ToSourceeNB-TransparentContainer-ExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION -using targetenb_to_sourceenb_transparent_container_ext_ies_o = s1ap_protocol_ext_empty_o; +using targetenb_to_sourceenb_transparent_container_ext_ies_o = protocol_ext_empty_o; using targetenb_to_sourceenb_transparent_container_ext_ies_container = protocol_ext_container_empty_l; @@ -18237,4 +17295,126 @@ struct targetenb_to_sourceenb_transparent_container_s { } // namespace s1ap } // namespace asn1 +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_single_container_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ie_field_s; +extern template struct asn1::protocol_ext_field_s; +extern template struct asn1::protocol_ext_field_s; + #endif // SRSASN1_S1AP_H diff --git a/lib/include/srsran/asn1/s1ap_utils.h b/lib/include/srsran/asn1/s1ap_utils.h index 9b76bebf0d..186daaf796 100644 --- a/lib/include/srsran/asn1/s1ap_utils.h +++ b/lib/include/srsran/asn1/s1ap_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -31,29 +31,36 @@ namespace asn1 { namespace s1ap { -struct init_context_setup_request_s; -struct ue_context_mod_request_s; -struct erab_setup_request_s; -struct erab_release_cmd_s; -struct erab_modify_request_s; +struct init_context_setup_request_ies_container; +using init_context_setup_request_s = elementary_procedure_option; +struct ue_context_mod_request_ies_container; +using ue_context_mod_request_s = elementary_procedure_option; +struct erab_setup_request_ies_container; +using erab_setup_request_s = elementary_procedure_option; +struct erab_release_cmd_ies_container; +using erab_release_cmd_s = elementary_procedure_option; +struct erab_modify_request_ies_container; +using erab_modify_request_s = elementary_procedure_option; struct ue_paging_id_c; -struct ho_request_s; +struct ho_request_ies_container; +using ho_request_s = elementary_procedure_option; struct sourceenb_to_targetenb_transparent_container_s; -struct init_context_setup_resp_s; -struct erab_setup_resp_s; +struct init_context_setup_resp_ies_container; +using init_context_setup_resp_s = elementary_procedure_option; +struct erab_setup_resp_ies_container; +using erab_setup_resp_s = elementary_procedure_option; struct rrc_establishment_cause_opts; struct cause_radio_network_opts; struct bearers_subject_to_status_transfer_item_ies_o; struct erab_level_qos_params_s; -struct ho_cmd_s; +struct ho_cmd_ies_container; +using ho_cmd_s = elementary_procedure_option; struct erab_admitted_item_s; struct erab_to_be_modified_item_bearer_mod_req_s; struct cause_c; struct erab_item_s; struct ue_aggregate_maximum_bitrate_s; -template -struct protocol_ie_single_container_s; using bearers_subject_to_status_transfer_list_l = dyn_array >; using rrc_establishment_cause_e = enumerated; diff --git a/lib/include/srsran/build_info.h.in b/lib/include/srsran/build_info.h.in index 3d6deebb56..9a7d182eea 100644 --- a/lib/include/srsran/build_info.h.in +++ b/lib/include/srsran/build_info.h.in @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/backtrace.h b/lib/include/srsran/common/backtrace.h index 309edce314..33a8ccbb87 100644 --- a/lib/include/srsran/common/backtrace.h +++ b/lib/include/srsran/common/backtrace.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/band_helper.h b/lib/include/srsran/common/band_helper.h index 617cfdb92e..27c9706c32 100644 --- a/lib/include/srsran/common/band_helper.h +++ b/lib/include/srsran/common/band_helper.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -89,7 +89,7 @@ class srsran_band_helper * @param scs SSB Subcarrier spacing * @return The SSB pattern case if band and subcarrier spacing match, SRSRAN_SSB_PATTERN_INVALID otherwise */ - srsran_ssb_patern_t get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs) const; + static srsran_ssb_pattern_t get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs); /** * @brief Select the lower SSB subcarrier spacing valid for this band @@ -135,14 +135,29 @@ class srsran_band_helper /** * @brief Compute the absolute frequency of the SSB for a DL ARFCN and a band. This selects an SSB center frequency + * following the band SS/PBCH frequency raster provided by TS38.104 table 5.4.3.1-1, which is the upper bound + * of the provided center frequency + * + * @param scs ssb subcarrier spacing. + * @param min_center_freq_hz center frequency above which the SSB absolute frequency must be. + * @return absolute frequency of the SSB in arfcn notation. + */ + uint32_t find_lower_bound_abs_freq_ssb(uint16_t band, srsran_subcarrier_spacing_t scs, uint32_t min_center_freq_hz); + + /** + * @brief Compute the absolute frequency of the SSB for a DL ARFCN and a band. This finds an SSB center frequency * following the band SS/PBCH frequency raster provided by TS38.104 table 5.4.3.1-1 as close as possible to PointA - * without letting any SS/PBCH subcarrier below PointA + * without letting any SS/PBCH subcarrier and CORESET#0 subcarrier (if RB offset is defined) below PointA * * @param scs ssb subcarrier spacing. * @param freq_point_a_arfcn frequency point a in arfcn notation. + * @param coreset0_offset_rb CORESET#0 RB offset. See TS 38.213, Table 13-1,2,3 * @return absolute frequency of the SSB in arfcn notation. */ - uint32_t get_abs_freq_ssb_arfcn(uint16_t band, srsran_subcarrier_spacing_t scs, uint32_t freq_point_a_arfcn); + uint32_t get_abs_freq_ssb_arfcn(uint16_t band, + srsran_subcarrier_spacing_t scs, + uint32_t freq_point_a_arfcn, + uint32_t coreset0_offset_rb = 0); /** * @brief Compute SSB center frequency for NR carrier @@ -396,7 +411,7 @@ class srsran_band_helper struct nr_band_ss_raster { uint16_t band; srsran_subcarrier_spacing_t scs; - srsran_ssb_patern_t pattern; + srsran_ssb_pattern_t pattern; uint32_t gscn_first; uint32_t gscn_step; uint32_t gscn_last; diff --git a/lib/include/srsran/common/bcd_helpers.h b/lib/include/srsran/common/bcd_helpers.h index 5212e1f1af..d8f58d6e8b 100644 --- a/lib/include/srsran/common/bcd_helpers.h +++ b/lib/include/srsran/common/bcd_helpers.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/bearer_manager.h b/lib/include/srsran/common/bearer_manager.h index 20931e4e92..3f8e16719f 100644 --- a/lib/include/srsran/common/bearer_manager.h +++ b/lib/include/srsran/common/bearer_manager.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -27,8 +27,8 @@ #include "srsran/common/rwlock_guard.h" #include "srsran/srslog/srslog.h" #include -#include #include +#include namespace srsran { @@ -45,6 +45,7 @@ class ue_bearer_manager_impl srsran::srsran_rat_t rat; uint32_t lcid; uint32_t eps_bearer_id; + uint32_t five_qi = 0; bool is_valid() const { return rat != srsran_rat_t::nulltype; } }; static const radio_bearer_t invalid_rb; @@ -59,9 +60,11 @@ class ue_bearer_manager_impl bool has_active_radio_bearer(uint32_t eps_bearer_id); - radio_bearer_t get_radio_bearer(uint32_t eps_bearer_id); + radio_bearer_t get_radio_bearer(uint32_t eps_bearer_id) const; + + radio_bearer_t get_eps_bearer_id_for_lcid(uint32_t lcid) const; - radio_bearer_t get_eps_bearer_id_for_lcid(uint32_t lcid); + bool set_five_qi(uint32_t eps_bearer_id, uint16_t five_qi); private: using eps_rb_map_t = std::map; @@ -148,6 +151,7 @@ class enb_bearer_manager using radio_bearer_t = srsran::detail::ue_bearer_manager_impl::radio_bearer_t; enb_bearer_manager(); + ~enb_bearer_manager(); /// Multi-user interface (see comments above) void add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid); @@ -155,7 +159,8 @@ class enb_bearer_manager void rem_user(uint16_t rnti); bool has_active_radio_bearer(uint16_t rnti, uint32_t eps_bearer_id); radio_bearer_t get_radio_bearer(uint16_t rnti, uint32_t eps_bearer_id); - radio_bearer_t get_lcid_bearer(uint16_t rnti, uint32_t lcid); + radio_bearer_t get_lcid_bearer(uint16_t rnti, uint32_t lcid) const; + bool set_five_qi(uint16_t rnti, uint32_t eps_bearer_id, uint16_t five_qi); private: srslog::basic_logger& logger; @@ -165,4 +170,4 @@ class enb_bearer_manager } // namespace srsenb -#endif // SRSRAN_BEARER_MANAGER_H \ No newline at end of file +#endif // SRSRAN_BEARER_MANAGER_H diff --git a/lib/include/srsran/common/block_queue.h b/lib/include/srsran/common/block_queue.h index 076b496a66..9e76e749ba 100644 --- a/lib/include/srsran/common/block_queue.h +++ b/lib/include/srsran/common/block_queue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -104,6 +104,8 @@ class block_queue return value; } + bool timedwait_pop(myobj* value, const struct timespec* abstime) { return pop_(value, true, abstime); } + bool empty() { // queue is empty? pthread_mutex_lock(&mutex); @@ -139,7 +141,7 @@ class block_queue } private: - bool pop_(myobj* value, bool block) + bool pop_(myobj* value, bool block, const struct timespec* abstime = nullptr) { if (!enable) { return false; @@ -151,7 +153,13 @@ class block_queue goto exit; } while (q.empty() && enable) { - pthread_cond_wait(&cv_empty, &mutex); + if (abstime == nullptr) { + pthread_cond_wait(&cv_empty, &mutex); + } else { + if (pthread_cond_timedwait(&cv_empty, &mutex, abstime)) { + goto exit; + } + } } if (!enable) { goto exit; diff --git a/lib/include/srsran/common/buffer_pool.h b/lib/include/srsran/common/buffer_pool.h index 56d1a6599a..f1e7113274 100644 --- a/lib/include/srsran/common/buffer_pool.h +++ b/lib/include/srsran/common/buffer_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -166,8 +166,10 @@ class buffer_pool uint32_t capacity; }; +/// Type of global byte buffer pool using byte_buffer_pool = concurrent_fixed_memory_pool; +/// Function used to generate unique byte buffers inline unique_byte_buffer_t make_byte_buffer() noexcept { return std::unique_ptr(new (std::nothrow) byte_buffer_t()); @@ -187,14 +189,49 @@ inline unique_byte_buffer_t make_byte_buffer(const char* debug_ctxt) noexcept return buffer; } +inline unique_byte_buffer_t make_byte_buffer(const uint8_t* payload, uint32_t len, const char* debug_ctxt) noexcept +{ + std::unique_ptr buffer(new (std::nothrow) byte_buffer_t()); + if (buffer == nullptr) { + srslog::fetch_basic_logger("POOL").error("Failed to allocate byte buffer in %s", debug_ctxt); + } else { + if (buffer->get_tailroom() >= len) { + memcpy(buffer->msg, payload, len); + buffer->N_bytes = len; + } else { + srslog::fetch_basic_logger("POOL").error( + "Failed to create byte buffer in %s. Payload too large (%d > %d)", debug_ctxt, len, buffer->get_tailroom()); + } + } + return buffer; +} + namespace detail { +template struct byte_buffer_pool_deleter { - void operator()(void* ptr) { byte_buffer_pool::get_instance()->deallocate_node(ptr); } + void operator()(T* ptr) const { byte_buffer_pool::get_instance()->deallocate_node(ptr); } }; } // namespace detail +/// Unique ptr to global byte buffer pool +template +using buffer_pool_ptr = std::unique_ptr >; + +/// Method to create unique_ptrs of type T allocated in global byte buffer pool +template +buffer_pool_ptr make_buffer_pool_obj(CtorArgs&&... args) noexcept +{ + static_assert(sizeof(T) <= byte_buffer_pool::BLOCK_SIZE, "pool_bounded_vector does not fit buffer pool block size"); + void* memblock = byte_buffer_pool::get_instance()->allocate_node(sizeof(T)); + if (memblock == nullptr) { + return buffer_pool_ptr(); + } + new (memblock) T(std::forward(args)...); + return buffer_pool_ptr(static_cast(memblock), detail::byte_buffer_pool_deleter()); +} + /** * Class to wrap objects of type T which get allocated/deallocated using the byte_buffer_pool * @tparam T type of the object being allocated @@ -222,21 +259,19 @@ struct byte_buffer_pool_ptr { template static byte_buffer_pool_ptr make(CtorArgs&&... args) { - void* memblock = byte_buffer_pool::get_instance()->allocate_node(sizeof(T)); - if (memblock == nullptr) { - return byte_buffer_pool_ptr(); - } - new (memblock) T(std::forward(args)...); byte_buffer_pool_ptr ret; - ret.ptr = std::unique_ptr(static_cast(memblock), - detail::byte_buffer_pool_deleter()); + ret.ptr = make_buffer_pool_obj(std::forward(args)...); return ret; }; private: - std::unique_ptr ptr; + buffer_pool_ptr ptr; }; +/// unique_ptr with virtual deleter, so it can be used by any pool +template +using any_pool_ptr = std::unique_ptr >; + } // namespace srsran #endif // SRSRAN_BUFFER_POOL_H diff --git a/lib/include/srsran/common/byte_buffer.h b/lib/include/srsran/common/byte_buffer.h index 6c26a3f7e3..f89708d505 100644 --- a/lib/include/srsran/common/byte_buffer.h +++ b/lib/include/srsran/common/byte_buffer.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -128,7 +128,7 @@ class byte_buffer_t // avoid self assignment if (&buf == this) return *this; - msg = &buffer[SRSRAN_BUFFER_HEADER_OFFSET]; + msg = &buffer[buf.msg - &(*buf.buffer)]; N_bytes = buf.N_bytes; md = buf.md; memcpy(msg, buf.msg, N_bytes); diff --git a/lib/include/srsran/common/common.h b/lib/include/srsran/common/common.h index c341b24c3a..aff76032ad 100644 --- a/lib/include/srsran/common/common.h +++ b/lib/include/srsran/common/common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -89,7 +89,7 @@ inline const char* enum_to_text(const char* const array[], uint32_t nof_types, u } template -ItemType enum_to_number(ItemType* array, uint32_t nof_types, uint32_t enum_val) +constexpr ItemType enum_to_number(ItemType* array, uint32_t nof_types, uint32_t enum_val) { return enum_val >= nof_types ? -1 : array[enum_val]; } diff --git a/lib/include/srsran/common/common_helper.h b/lib/include/srsran/common/common_helper.h index accd15a351..670a600985 100644 --- a/lib/include/srsran/common/common_helper.h +++ b/lib/include/srsran/common/common_helper.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/common_lte.h b/lib/include/srsran/common/common_lte.h index 8687f0d5a3..a68648f474 100644 --- a/lib/include/srsran/common/common_lte.h +++ b/lib/include/srsran/common/common_lte.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -60,9 +60,16 @@ const uint32_t MAX_LTE_SRB_ID = 2; enum class lte_drb { drb1 = 1, drb2, drb3, drb4, drb5, drb6, drb7, drb8, drb9, drb10, drb11, invalid }; const uint32_t MAX_LTE_DRB_ID = 11; const uint32_t MAX_LTE_LCID = 10; // logicalChannelIdentity 3..10 in TS 36.331 v15.3 +const uint32_t MAX_EPS_BEARER_ID = 15; // EPS Bearer ID range [5, 15] in 36 413 +const uint32_t MIN_EPS_BEARER_ID = 5; const uint32_t INVALID_LCID = 99; // random invalid LCID const uint32_t INVALID_EPS_BEARER_ID = 99; // random invalid eps bearer id +constexpr bool is_eps_bearer_id(uint32_t eps_bearer_id) +{ + return eps_bearer_id >= MIN_EPS_BEARER_ID and eps_bearer_id <= MAX_EPS_BEARER_ID; +} + constexpr bool is_lte_rb(uint32_t lcid) { return lcid <= MAX_LTE_LCID; @@ -97,6 +104,14 @@ inline const char* get_drb_name(lte_drb drb_id) return names[(uint32_t)(drb_id < lte_drb::invalid ? drb_id : lte_drb::invalid) - 1]; } +inline const char* get_rb_name(uint32_t lcid) +{ + if (is_lte_srb(lcid)) { + return get_srb_name(static_cast(lcid)); + } + return get_drb_name(static_cast(lcid - MAX_LTE_SRB_ID)); +} + } // namespace srsran #endif // SRSRAN_COMMON_LTE_H diff --git a/lib/include/srsran/common/common_nr.h b/lib/include/srsran/common/common_nr.h index 0b25229cab..9e2c0f56eb 100644 --- a/lib/include/srsran/common/common_nr.h +++ b/lib/include/srsran/common/common_nr.h @@ -1,6 +1,6 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -66,6 +66,15 @@ enum class nr_drb { const uint32_t MAX_NR_DRB_ID = 29; const uint32_t MAX_NR_NOF_BEARERS = MAX_NR_DRB_ID + MAX_NR_SRB_ID; // 32 +// PDU Session ID range [1, 15]. See TS 24.007, 11.2.3.1b. +const uint32_t MAX_NR_PDU_SESSION_ID = 15; +const uint32_t MIN_NR_PDU_SESSION_ID = 1; + +constexpr bool is_nr_pdu_session_id(uint32_t pdu_session_id) +{ + return pdu_session_id >= MIN_NR_PDU_SESSION_ID and pdu_session_id <= MAX_NR_PDU_SESSION_ID; +} + constexpr bool is_nr_lcid(uint32_t lcid) { return lcid < MAX_NR_NOF_BEARERS; @@ -103,6 +112,15 @@ inline const char* get_drb_name(nr_drb drb_id) "DRB25", "DRB26", "DRB27", "DRB28", "DRB29", "invalid DRB id"}; return names[(uint32_t)(drb_id < nr_drb::invalid ? drb_id : nr_drb::invalid) - 1]; } + +inline const char* get_nr_rb_name(uint32_t lcid) +{ + if (is_nr_srb(lcid)) { + return get_srb_name(static_cast(lcid)); + } + return get_drb_name(static_cast(lcid - MAX_NR_SRB_ID)); +} + } // namespace srsran #endif // SRSRAN_COMMON_NR_H \ No newline at end of file diff --git a/lib/include/srsran/common/config_file.h b/lib/include/srsran/common/config_file.h index 6f9c4da955..ddb371644e 100644 --- a/lib/include/srsran/common/config_file.h +++ b/lib/include/srsran/common/config_file.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/crash_handler.h b/lib/include/srsran/common/crash_handler.h index d57ffbf2f0..4e561f05d6 100644 --- a/lib/include/srsran/common/crash_handler.h +++ b/lib/include/srsran/common/crash_handler.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/enb_events.h b/lib/include/srsran/common/enb_events.h index 64e83fbaa5..c745075071 100644 --- a/lib/include/srsran/common/enb_events.h +++ b/lib/include/srsran/common/enb_events.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/epoll_helper.h b/lib/include/srsran/common/epoll_helper.h index 905dac9fa4..6d46613f12 100644 --- a/lib/include/srsran/common/epoll_helper.h +++ b/lib/include/srsran/common/epoll_helper.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/gen_mch_tables.h b/lib/include/srsran/common/gen_mch_tables.h index 972c41e2ba..e0d4f0f9ea 100644 --- a/lib/include/srsran/common/gen_mch_tables.h +++ b/lib/include/srsran/common/gen_mch_tables.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/int_helpers.h b/lib/include/srsran/common/int_helpers.h index c792e40b5f..77ea196928 100644 --- a/lib/include/srsran/common/int_helpers.h +++ b/lib/include/srsran/common/int_helpers.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/interfaces_common.h b/lib/include/srsran/common/interfaces_common.h index b7be668ad2..f2280210eb 100644 --- a/lib/include/srsran/common/interfaces_common.h +++ b/lib/include/srsran/common/interfaces_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -65,14 +65,9 @@ struct rf_args_t { std::array ch_rx_bands; std::array ch_tx_bands; -}; -struct vnf_args_t { - std::string type; - std::string bind_addr; - uint16_t bind_port; - std::string log_level; - int log_hex_limit; + FILE** rx_files; // Array of pre-opened FILE* for rx instead of a real device + FILE** tx_files; // Array of pre-opened FILE* for tx instead of a real device }; class srsran_gw_config_t @@ -89,8 +84,6 @@ class read_pdu_interface virtual uint32_t read_pdu(uint32_t lcid, uint8_t* payload, uint32_t requested_bytes) = 0; }; -class stack_interface_phy_nr -{}; } // namespace srsran diff --git a/lib/include/srsran/common/log_helper.h b/lib/include/srsran/common/log_helper.h index 910078600e..fcd88e2075 100644 --- a/lib/include/srsran/common/log_helper.h +++ b/lib/include/srsran/common/log_helper.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/mac_pcap.h b/lib/include/srsran/common/mac_pcap.h index 41371fc015..29eff6083f 100644 --- a/lib/include/srsran/common/mac_pcap.h +++ b/lib/include/srsran/common/mac_pcap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/mac_pcap_base.h b/lib/include/srsran/common/mac_pcap_base.h index b141009c35..b148eb6f18 100644 --- a/lib/include/srsran/common/mac_pcap_base.h +++ b/lib/include/srsran/common/mac_pcap_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -112,7 +112,8 @@ class mac_pcap_base : protected srsran::thread srslog::basic_logger& logger; std::atomic running = {false}; static_blocking_queue queue; - uint16_t ue_id = 0; + uint16_t ue_id = 0; + int emergency_handler_id = -1; private: void pack_and_queue(uint8_t* payload, diff --git a/lib/include/srsran/common/mac_pcap_net.h b/lib/include/srsran/common/mac_pcap_net.h index 36d150cbee..16dc9627ba 100644 --- a/lib/include/srsran/common/mac_pcap_net.h +++ b/lib/include/srsran/common/mac_pcap_net.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/metrics_hub.h b/lib/include/srsran/common/metrics_hub.h index 36919e5356..877cc7afac 100644 --- a/lib/include/srsran/common/metrics_hub.h +++ b/lib/include/srsran/common/metrics_hub.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/multiqueue.h b/lib/include/srsran/common/multiqueue.h index 26af347cbd..3430e14292 100644 --- a/lib/include/srsran/common/multiqueue.h +++ b/lib/include/srsran/common/multiqueue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/nas_pcap.h b/lib/include/srsran/common/nas_pcap.h index 3bec3e3efb..b078de7e04 100644 --- a/lib/include/srsran/common/nas_pcap.h +++ b/lib/include/srsran/common/nas_pcap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -31,22 +31,19 @@ namespace srsran { class nas_pcap { public: - nas_pcap() - { - enable_write = false; - ue_id = 0; - pcap_file = NULL; - } - void enable(); + nas_pcap(); + ~nas_pcap(); + void enable(); uint32_t open(std::string filename_, uint32_t ue_id = 0, srsran_rat_t rat_type = srsran_rat_t::lte); - void close(); - void write_nas(uint8_t* pdu, uint32_t pdu_len_bytes); + void close(); + void write_nas(uint8_t* pdu, uint32_t pdu_len_bytes); private: - bool enable_write; + bool enable_write = false; std::string filename; - FILE* pcap_file; - uint32_t ue_id; + FILE* pcap_file = nullptr; + uint32_t ue_id = 0; + int emergency_handler_id = -1; void pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes); }; diff --git a/lib/include/srsran/common/netsource_handler.h b/lib/include/srsran/common/netsource_handler.h index 2a8c7e2642..ce6019caac 100644 --- a/lib/include/srsran/common/netsource_handler.h +++ b/lib/include/srsran/common/netsource_handler.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/network_utils.h b/lib/include/srsran/common/network_utils.h index 27cb8a5dbd..2e4dbb3f2d 100644 --- a/lib/include/srsran/common/network_utils.h +++ b/lib/include/srsran/common/network_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -83,10 +83,14 @@ class unique_socket std::string get_ip() const { return net_utils::get_ip(addr); } net_utils::socket_type get_family() const { return net_utils::get_addr_family(sockfd); } + bool open_socket(net_utils::addr_family ip, net_utils::socket_type socket_type, net_utils::protocol_type protocol); bool bind_addr(const char* bind_addr_str, int port); bool connect_to(const char* dest_addr_str, int dest_port, sockaddr_in* dest_sockaddr = nullptr); bool start_listen(); - bool open_socket(net_utils::addr_family ip, net_utils::socket_type socket_type, net_utils::protocol_type protocol); + bool reuse_addr(); + bool sctp_subscribe_to_events(); + bool sctp_set_rto_opts(int rto_max); + bool sctp_set_init_msg_opts(int max_init_attempts, int max_init_timeo); int get_socket() const { return sockfd; }; protected: @@ -196,6 +200,12 @@ make_sctp_sdu_handler(srslog::basic_logger& logger, srsran::task_queue_handle& q socket_manager_itf::recv_callback_t make_sdu_handler(srslog::basic_logger& logger, srsran::task_queue_handle& queue, recvfrom_callback_t rx_callback); +inline socket_manager& get_rx_io_manager() +{ + static socket_manager io; + return io; +} + } // namespace srsran #endif // SRSRAN_RX_SOCKET_HANDLER_H diff --git a/lib/include/srsran/common/ngap_pcap.h b/lib/include/srsran/common/ngap_pcap.h new file mode 100644 index 0000000000..cbb00167fb --- /dev/null +++ b/lib/include/srsran/common/ngap_pcap.h @@ -0,0 +1,54 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_NGAP_PCAP_H +#define SRSRAN_NGAP_PCAP_H + +#include "srsran/common/pcap.h" +#include + +namespace srsran { + +class ngap_pcap +{ +public: + ngap_pcap(); + ~ngap_pcap(); + ngap_pcap(const ngap_pcap& other) = delete; + ngap_pcap& operator=(const ngap_pcap& other) = delete; + ngap_pcap(ngap_pcap&& other) = delete; + ngap_pcap& operator=(ngap_pcap&& other) = delete; + + void enable(); + void open(const char* filename_); + void close(); + void write_ngap(uint8_t* pdu, uint32_t pdu_len_bytes); + +private: + bool enable_write = false; + std::string filename; + FILE* pcap_file = nullptr; + int emergency_handler_id = -1; +}; + +} // namespace srsran + +#endif // SRSRAN_NGAP_PCAP_H diff --git a/lib/include/srsran/common/pcap.h b/lib/include/srsran/common/pcap.h index 9731ea5f66..831770eed8 100644 --- a/lib/include/srsran/common/pcap.h +++ b/lib/include/srsran/common/pcap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -33,6 +33,7 @@ #define UDP_DLT 149 // UDP needs to be selected as protocol #define S1AP_LTE_DLT 150 #define NAS_5G_DLT 151 +#define NGAP_5G_DLT 152 /* This structure gets written to the start of the file */ typedef struct pcap_hdr_s { @@ -189,6 +190,12 @@ typedef struct S1AP_Context_Info_s { unsigned char dummy; } S1AP_Context_Info_t; +/* Context information for every S1AP PDU that will be logged */ +typedef struct NGAP_Context_Info_s { + // No Context yet + unsigned char dummy; +} NGAP_Context_Info_t; + #ifdef __cplusplus extern "C" { #endif @@ -213,6 +220,9 @@ int LTE_PCAP_RLC_WritePDU(FILE* fd, RLC_Context_Info_t* context, const unsigned /* Write an individual S1AP PDU (PCAP packet header + s1ap-context + s1ap-pdu) */ int LTE_PCAP_S1AP_WritePDU(FILE* fd, S1AP_Context_Info_t* context, const unsigned char* PDU, unsigned int length); +/* Write an individual S1AP PDU (PCAP packet header + s1ap-context + s1ap-pdu) */ +int LTE_PCAP_NGAP_WritePDU(FILE* fd, NGAP_Context_Info_t* context, const unsigned char* PDU, unsigned int length); + /* Write an individual NR MAC PDU (PCAP packet header + UDP header + nr-mac-context + mac-pdu) */ int NR_PCAP_MAC_UDP_WritePDU(FILE* fd, mac_nr_context_info_t* context, const unsigned char* PDU, unsigned int length); int NR_PCAP_PACK_MAC_CONTEXT_TO_BUFFER(mac_nr_context_info_t* context, uint8_t* buffer, unsigned int length); diff --git a/lib/include/srsran/common/phy_cfg_nr.h b/lib/include/srsran/common/phy_cfg_nr.h index 2cd7bfd1db..0de054ceba 100644 --- a/lib/include/srsran/common/phy_cfg_nr.h +++ b/lib/include/srsran/common/phy_cfg_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -42,7 +42,7 @@ struct phy_cfg_nr_t { uint32_t periodicity_ms = 0; std::array position_in_burst = {}; srsran_subcarrier_spacing_t scs = srsran_subcarrier_spacing_30kHz; - srsran_ssb_patern_t pattern = SRSRAN_SSB_PATTERN_A; + srsran_ssb_pattern_t pattern = SRSRAN_SSB_PATTERN_A; }; srsran_duplex_config_nr_t duplex = {}; @@ -54,7 +54,8 @@ struct phy_cfg_nr_t { srsran_harq_ack_cfg_hl_t harq_ack = {}; srsran_csi_hl_cfg_t csi = {}; srsran_carrier_nr_t carrier = {}; - ssb_cfg_t ssb; + ssb_cfg_t ssb = {}; + uint32_t t_offset = 0; ///< n-TimingAdvanceOffset phy_cfg_nr_t() {} diff --git a/lib/include/srsran/common/phy_cfg_nr_default.h b/lib/include/srsran/common/phy_cfg_nr_default.h index 5d071b1395..91454dc35f 100644 --- a/lib/include/srsran/common/phy_cfg_nr_default.h +++ b/lib/include/srsran/common/phy_cfg_nr_default.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/rlc_pcap.h b/lib/include/srsran/common/rlc_pcap.h index d49643df81..c67b3c72c8 100644 --- a/lib/include/srsran/common/rlc_pcap.h +++ b/lib/include/srsran/common/rlc_pcap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/rwlock_guard.h b/lib/include/srsran/common/rwlock_guard.h index 36bed7c960..d1802d41f7 100644 --- a/lib/include/srsran/common/rwlock_guard.h +++ b/lib/include/srsran/common/rwlock_guard.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/s1ap_pcap.h b/lib/include/srsran/common/s1ap_pcap.h index 016db24553..fd869833e5 100644 --- a/lib/include/srsran/common/s1ap_pcap.h +++ b/lib/include/srsran/common/s1ap_pcap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -31,6 +31,7 @@ class s1ap_pcap { public: s1ap_pcap(); + ~s1ap_pcap(); s1ap_pcap(const s1ap_pcap& other) = delete; s1ap_pcap& operator=(const s1ap_pcap& other) = delete; s1ap_pcap(s1ap_pcap&& other) = delete; @@ -44,7 +45,8 @@ class s1ap_pcap private: bool enable_write = false; std::string filename; - FILE* pcap_file = nullptr; + FILE* pcap_file = nullptr; + int emergency_handler_id = -1; }; } // namespace srsran diff --git a/lib/include/srsran/common/s3g.h b/lib/include/srsran/common/s3g.h index c4d37a7774..bf049514f8 100644 --- a/lib/include/srsran/common/s3g.h +++ b/lib/include/srsran/common/s3g.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/security.h b/lib/include/srsran/common/security.h index 7b550e188c..81e2fabc03 100644 --- a/lib/include/srsran/common/security.h +++ b/lib/include/srsran/common/security.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -68,6 +68,28 @@ static const char integrity_algorithm_id_text[INTEGRITY_ALGORITHM_ID_N_ITEMS][20 "128-EIA2", "128-EIA3"}; +typedef enum { + CIPHERING_ALGORITHM_ID_NR_NEA0 = 0, + CIPHERING_ALGORITHM_ID_NR_128_NEA1, + CIPHERING_ALGORITHM_ID_NR_128_NEA2, + CIPHERING_ALGORITHM_ID_NR_128_NEA3, + CIPHERING_ALGORITHM_ID_NR_N_ITEMS, +} CIPHERING_ALGORITHM_ID_NR_ENUM; +static const char ciphering_algorithm_id_nr_text[CIPHERING_ALGORITHM_ID_N_ITEMS][20] = {"NEA0", + "128-NEA1", + "128-NEA2", + "128-NEA3"}; +typedef enum { + INTEGRITY_ALGORITHM_ID_NR_NIA0 = 0, + INTEGRITY_ALGORITHM_ID_NR_128_NIA1, + INTEGRITY_ALGORITHM_ID_NR_128_NIA2, + INTEGRITY_ALGORITHM_ID_NR_128_NIA3, + INTEGRITY_ALGORITHM_ID_NR_N_ITEMS, +} INTEGRITY_ALGORITHM_ID_NR_ENUM; +static const char integrity_algorithm_id_nr_text[INTEGRITY_ALGORITHM_ID_N_ITEMS][20] = {"NIA0", + "128-NIA1", + "128-NIA2", + "128-NIA3"}; typedef enum { SECURITY_DIRECTION_UPLINK = 0, SECURITY_DIRECTION_DOWNLINK = 1, @@ -84,6 +106,7 @@ struct k_enb_context_t { }; struct k_gnb_context_t { + as_key_t k_gnb; as_key_t sk_gnb; }; @@ -96,6 +119,15 @@ struct as_security_config_t { CIPHERING_ALGORITHM_ID_ENUM cipher_algo; }; +struct nr_as_security_config_t { + as_key_t k_nr_rrc_int; + as_key_t k_nr_rrc_enc; + as_key_t k_nr_up_int; + as_key_t k_nr_up_enc; + INTEGRITY_ALGORITHM_ID_NR_ENUM integ_algo; + CIPHERING_ALGORITHM_ID_NR_ENUM cipher_algo; +}; + template void log_error(const char* format, Args&&... args) { @@ -158,11 +190,22 @@ uint8_t security_generate_k_amf(const uint8_t* k_seaf, uint8_t security_generate_k_seaf(const uint8_t* k_ausf, const char* serving_network_name, uint8_t* k_seaf); +uint8_t security_generate_k_gnb(const as_key_t& k_amf, const uint32_t nas_count, as_key_t& k_gnb); + uint8_t security_generate_k_enb(const uint8_t* k_asme, const uint32_t nas_count, uint8_t* k_enb); +uint8_t security_generate_k_nb_star_common(uint8_t fc, + const uint8_t* k_enb, + const uint32_t pci_, + const uint32_t earfcn_, + uint8_t* k_enb_star); + uint8_t security_generate_k_enb_star(const uint8_t* k_enb, const uint32_t pci, const uint32_t earfcn, uint8_t* k_enb_star); +uint8_t +security_generate_k_gnb_star(const uint8_t* k_gnb, const uint32_t pci_, const uint32_t dl_arfcn_, uint8_t* k_gnb_star); + uint8_t security_generate_nh(const uint8_t* k_asme, const uint8_t* sync, uint8_t* nh); uint8_t security_generate_k_nas(const uint8_t* k_asme, diff --git a/lib/include/srsran/common/slot_point.h b/lib/include/srsran/common/slot_point.h index 35ebafe4aa..0253162e69 100644 --- a/lib/include/srsran/common/slot_point.h +++ b/lib/include/srsran/common/slot_point.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/ssl.h b/lib/include/srsran/common/ssl.h index cde203c57c..6940c0e402 100644 --- a/lib/include/srsran/common/ssl.h +++ b/lib/include/srsran/common/ssl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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/common/stack_procedure.h b/lib/include/srsran/common/stack_procedure.h index 362edb4599..8775cdcaa2 100644 --- a/lib/include/srsran/common/stack_procedure.h +++ b/lib/include/srsran/common/stack_procedure.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/standard_streams.h b/lib/include/srsran/common/standard_streams.h index afd8773c94..bad12fe26c 100644 --- a/lib/include/srsran/common/standard_streams.h +++ b/lib/include/srsran/common/standard_streams.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/string_helpers.h b/lib/include/srsran/common/string_helpers.h index ea6fe2aea0..12f6df9fc9 100644 --- a/lib/include/srsran/common/string_helpers.h +++ b/lib/include/srsran/common/string_helpers.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/task_scheduler.h b/lib/include/srsran/common/task_scheduler.h index 58494d885e..a5cde1826e 100644 --- a/lib/include/srsran/common/task_scheduler.h +++ b/lib/include/srsran/common/task_scheduler.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/test_common.h b/lib/include/srsran/common/test_common.h index d4f75027b1..f4c928462f 100644 --- a/lib/include/srsran/common/test_common.h +++ b/lib/include/srsran/common/test_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -146,6 +146,7 @@ inline void test_init(int argc, char** argv) srsran_debug_handle_crash(argc, argv); srslog::fetch_basic_logger("ALL").set_level(srslog::basic_levels::info); + srslog::fetch_basic_logger("TEST").set_level(srslog::basic_levels::info); // Start the log backend. srslog::init(); @@ -162,6 +163,39 @@ inline void copy_msg_to_buffer(unique_byte_buffer_t& pdu, const_byte_span msg) pdu->N_bytes = msg.size(); } +/** + * Delimits beginning/ending of a test with the following console output: + * ============= [Test ] =============== + * + * ======================================================= + */ +class test_delimit_logger +{ + const size_t delimiter_length = 128; + +public: + template + explicit test_delimit_logger(const char* test_name_fmt, Args&&... args) + { + test_name = fmt::format(test_name_fmt, std::forward(args)...); + std::string name_str = fmt::format("[ Test \"{}\" ]", test_name); + double nof_repeats = (delimiter_length - name_str.size()) / 2.0; + fmt::print("{0:=>{1}}{2}{0:=>{3}}\n", "", (int)floor(nof_repeats), name_str, (int)ceil(nof_repeats)); + } + test_delimit_logger(const test_delimit_logger&) = delete; + test_delimit_logger(test_delimit_logger&&) = delete; + test_delimit_logger& operator=(const test_delimit_logger&) = delete; + test_delimit_logger& operator=(test_delimit_logger&&) = delete; + ~test_delimit_logger() + { + srslog::flush(); + fmt::print("{:=>{}}\n", "", delimiter_length); + } + +private: + std::string test_name; +}; + } // namespace srsran #define CONDERROR(cond, fmt, ...) srsran_assert(not(cond), fmt, ##__VA_ARGS__) diff --git a/lib/include/srsran/common/test_pcap.h b/lib/include/srsran/common/test_pcap.h index 65f4ce5f66..e980d6d777 100644 --- a/lib/include/srsran/common/test_pcap.h +++ b/lib/include/srsran/common/test_pcap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/thread_pool.h b/lib/include/srsran/common/thread_pool.h index 65df9fc5ac..84459bf152 100644 --- a/lib/include/srsran/common/thread_pool.h +++ b/lib/include/srsran/common/thread_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/threads.h b/lib/include/srsran/common/threads.h index 28c9380543..54f4c0d1f2 100644 --- a/lib/include/srsran/common/threads.h +++ b/lib/include/srsran/common/threads.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/time_prof.h b/lib/include/srsran/common/time_prof.h index 404e3b5865..b9c14d4ec7 100644 --- a/lib/include/srsran/common/time_prof.h +++ b/lib/include/srsran/common/time_prof.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/timeout.h b/lib/include/srsran/common/timeout.h index b673b3ec33..6e95c18774 100644 --- a/lib/include/srsran/common/timeout.h +++ b/lib/include/srsran/common/timeout.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/timers.h b/lib/include/srsran/common/timers.h index 9a363aafeb..c30e949dfe 100644 --- a/lib/include/srsran/common/timers.h +++ b/lib/include/srsran/common/timers.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/trace.h b/lib/include/srsran/common/trace.h index 0e83762396..c02d47c7a2 100644 --- a/lib/include/srsran/common/trace.h +++ b/lib/include/srsran/common/trace.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/tsan_options.h b/lib/include/srsran/common/tsan_options.h index 4fa77498d9..0a99dbfc79 100644 --- a/lib/include/srsran/common/tsan_options.h +++ b/lib/include/srsran/common/tsan_options.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -60,6 +60,7 @@ const char* __tsan_default_suppressions() "deadlock:srsenb::mac::rlc_buffer_state\n" "deadlock:srsenb::mac::snr_info\n" "deadlock:srsenb::mac::ack_info\n" + "deadlock:srsenb::mac::cqi_info\n" "deadlock:srsenb::rlc::rb_is_um\n" "deadlock:srsenb::mac::sr_detected\n"; } diff --git a/lib/include/srsran/common/tti_point.h b/lib/include/srsran/common/tti_point.h index 91f73d52e7..76a9e71387 100644 --- a/lib/include/srsran/common/tti_point.h +++ b/lib/include/srsran/common/tti_point.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/tti_sempahore.h b/lib/include/srsran/common/tti_sempahore.h index 0901c4d6fc..0083893c94 100644 --- a/lib/include/srsran/common/tti_sempahore.h +++ b/lib/include/srsran/common/tti_sempahore.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -84,8 +84,10 @@ class tti_semaphore { std::unique_lock lock(mutex); - // Pop first element - fifo.pop_front(); + // If the FIFO is not empty pop first element + if (not fifo.empty()) { + fifo.pop_front(); + } // Notify release cvar.notify_all(); diff --git a/lib/include/srsran/common/tti_sync.h b/lib/include/srsran/common/tti_sync.h index f13c42b908..c030b9e5cd 100644 --- a/lib/include/srsran/common/tti_sync.h +++ b/lib/include/srsran/common/tti_sync.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/tti_sync_cv.h b/lib/include/srsran/common/tti_sync_cv.h index 1b2441c55d..9973e363c6 100644 --- a/lib/include/srsran/common/tti_sync_cv.h +++ b/lib/include/srsran/common/tti_sync_cv.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/common/zuc.h b/lib/include/srsran/common/zuc.h index 10be8102a1..2ae3ae87aa 100644 --- a/lib/include/srsran/common/zuc.h +++ b/lib/include/srsran/common/zuc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/config.h b/lib/include/srsran/config.h index ffa0650e71..531dae379f 100644 --- a/lib/include/srsran/config.h +++ b/lib/include/srsran/config.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -62,6 +62,7 @@ #define SRSRAN_ERROR_OUT_OF_BOUNDS -5 #define SRSRAN_ERROR_CANT_START -6 #define SRSRAN_ERROR_ALREADY_STARTED -7 +#define SRSRAN_ERROR_RX_EOF -8 // cf_t definition typedef _Complex float cf_t; diff --git a/srsue/src/set_net_admin_caps.cc b/lib/include/srsran/interfaces/e2_metrics_interface.h similarity index 52% rename from srsue/src/set_net_admin_caps.cc rename to lib/include/srsran/interfaces/e2_metrics_interface.h index c204011bb7..e7aa28c2f9 100644 --- a/srsue/src/set_net_admin_caps.cc +++ b/lib/include/srsran/interfaces/e2_metrics_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,29 +19,26 @@ * */ -#include -#include -#include -#include -#include -#include +#include "srsgnb/hdr/stack/ric/e2sm.h" +#include "srsran/common/common.h" +#include "srsran/common/interfaces_common.h" +#include "srsran/interfaces/enb_metrics_interface.h" +#include "srsran/srsran.h" -using namespace std; +#ifndef SRSRAN_E2_INTERFACES_H +#define SRSRAN_E2_INTERFACES_H -int main(int argc, char* argv[]) +namespace srsenb { + +class e2_interface_metrics { - if (argc != 2) { - std::cout << "Please call with the binary to provide net admin capabilities to as a parameter." << std::endl; - std::cout << "E.g. ./set_net_admin_caps myprogCalling " << std::endl; - return -1; - } +public: + virtual bool pull_metrics(enb_metrics_t* m) = 0; - std::string command("setcap 'cap_net_admin=eip' "); - command += argv[1]; + virtual bool register_e2sm(e2sm* sm) = 0; + virtual bool unregister_e2sm(e2sm* sm) = 0; +}; - std::cout << "Calling " << command << " with root rights." << std::endl; - setuid(0); - system(command.c_str()); +} // namespace srsenb - return 0; -} +#endif // SRSRAN_ENB_INTERFACES_H diff --git a/lib/include/srsran/interfaces/enb_command_interface.h b/lib/include/srsran/interfaces/enb_command_interface.h index 1e9e252f71..7c0b299012 100644 --- a/lib/include/srsran/interfaces/enb_command_interface.h +++ b/lib/include/srsran/interfaces/enb_command_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -28,6 +28,11 @@ namespace srsenb { class enb_command_interface { public: + /** + * Trigger downlink singnal measurements (currently PAPR) + */ + virtual void cmd_cell_measure() = 0; + /** * Sets the relative gain of a cell from it's index (following rr.conf) order. * @param cell_id Provides a cell identifier diff --git a/lib/include/srsran/interfaces/enb_gtpu_interfaces.h b/lib/include/srsran/interfaces/enb_gtpu_interfaces.h index 60b8071f2f..9b6719ce1b 100644 --- a/lib/include/srsran/interfaces/enb_gtpu_interfaces.h +++ b/lib/include/srsran/interfaces/enb_gtpu_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/interfaces/enb_interfaces.h b/lib/include/srsran/interfaces/enb_interfaces.h index 990e05affa..bfaa7bdfa2 100644 --- a/lib/include/srsran/interfaces/enb_interfaces.h +++ b/lib/include/srsran/interfaces/enb_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,8 +23,6 @@ #include "srsran/common/interfaces_common.h" #include "srsran/srsran.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" - #ifndef SRSRAN_ENB_INTERFACES_H #define SRSRAN_ENB_INTERFACES_H diff --git a/lib/include/srsran/interfaces/enb_mac_interfaces.h b/lib/include/srsran/interfaces/enb_mac_interfaces.h index 773f86a53f..c9a48ef4bc 100644 --- a/lib/include/srsran/interfaces/enb_mac_interfaces.h +++ b/lib/include/srsran/interfaces/enb_mac_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -28,7 +28,8 @@ namespace srsenb { struct mac_args_t { - uint32_t nof_prb; ///< Needed to dimension MAC softbuffers for all cells + uint32_t nof_prb; ///< Needed to dimension MAC softbuffers for all cells + uint32_t prach_bi; ///< Backoff Indicator to prevent UE from PRACHing too fast sched_interface::sched_args_t sched; int lcid_padding; uint32_t nof_prealloc_ues; ///< Number of UE resources to pre-allocate at eNB startup @@ -191,7 +192,7 @@ class mac_interface_phy_lte * @param rnti the UE identifier in the eNb * @param cc_idx the eNb Cell/Carrier identifier * @param nof_bytes the number of grants carrierd by the PUSCH message - * @param crc_res the CRC check, set to true if the message was decoded succesfully + * @param crc_res the CRC check, set to true if the message was decoded successfully * @return SRSRAN_SUCCESS if no error occurs, SRSRAN_ERROR* if an error occurs */ virtual int crc_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t nof_bytes, bool crc_res) = 0; @@ -203,7 +204,7 @@ class mac_interface_phy_lte * @param rnti the UE identifier in the eNb * @param enb_cc_idx the eNb Cell/Carrier identifier * @param nof_bytes the number of grants carrierd by the PUSCH message - * @param crc_res the CRC check, set to true if the message was decoded succesfully + * @param crc_res the CRC check, set to true if the message was decoded successfully * @param ul_nof_prbs Number of PRBs allocated to grant * @return SRSRAN_SUCCESS if no error occurs, SRSRAN_ERROR* if an error occurs */ diff --git a/lib/include/srsran/interfaces/enb_metrics_interface.h b/lib/include/srsran/interfaces/enb_metrics_interface.h index 7026b3de09..64532e7566 100644 --- a/lib/include/srsran/interfaces/enb_metrics_interface.h +++ b/lib/include/srsran/interfaces/enb_metrics_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/interfaces/enb_pdcp_interfaces.h b/lib/include/srsran/interfaces/enb_pdcp_interfaces.h index f465d77f49..26f1e4560e 100644 --- a/lib/include/srsran/interfaces/enb_pdcp_interfaces.h +++ b/lib/include/srsran/interfaces/enb_pdcp_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/interfaces/enb_phy_interfaces.h b/lib/include/srsran/interfaces/enb_phy_interfaces.h index 28c996133c..c511556dc0 100644 --- a/lib/include/srsran/interfaces/enb_phy_interfaces.h +++ b/lib/include/srsran/interfaces/enb_phy_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/interfaces/enb_rlc_interfaces.h b/lib/include/srsran/interfaces/enb_rlc_interfaces.h index eceedc62f5..1bf15a9c87 100644 --- a/lib/include/srsran/interfaces/enb_rlc_interfaces.h +++ b/lib/include/srsran/interfaces/enb_rlc_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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_rrc_interface_mac.h b/lib/include/srsran/interfaces/enb_rrc_interface_mac.h new file mode 100644 index 0000000000..323fa5c492 --- /dev/null +++ b/lib/include/srsran/interfaces/enb_rrc_interface_mac.h @@ -0,0 +1,48 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_ENB_RRC_INTERFACE_MAC_H +#define SRSRAN_ENB_RRC_INTERFACE_MAC_H + +#include "srsenb/hdr/stack/mac/sched_interface.h" + +namespace srsenb { + +/// RRC interface for MAC +class rrc_interface_mac +{ +public: + /* Radio Link failure */ + virtual int add_user(uint16_t rnti, const sched_interface::ue_cfg_t& init_ue_cfg) = 0; + virtual void upd_user(uint16_t new_rnti, uint16_t old_rnti) = 0; + virtual void set_activity_user(uint16_t rnti) = 0; + virtual void set_radiolink_dl_state(uint16_t rnti, bool crc_res) = 0; + virtual void set_radiolink_ul_state(uint16_t rnti, bool crc_res) = 0; + virtual bool is_paging_opportunity(uint32_t tti_tx_dl, uint32_t* payload_len) = 0; + virtual void read_pdu_pcch(uint32_t tti_tx_dl, uint8_t* payload, uint32_t payload_size) = 0; + + ///< Provide packed SIB to MAC (buffer is managed by RRC) + virtual uint8_t* read_pdu_bcch_dlsch(const uint8_t enb_cc_idx, const uint32_t sib_index) = 0; +}; + +} // namespace srsenb + +#endif // SRSRAN_ENB_RRC_INTERFACE_MAC_H diff --git a/lib/include/srsran/interfaces/enb_rrc_interface_pdcp.h b/lib/include/srsran/interfaces/enb_rrc_interface_pdcp.h new file mode 100644 index 0000000000..993186ee26 --- /dev/null +++ b/lib/include/srsran/interfaces/enb_rrc_interface_pdcp.h @@ -0,0 +1,39 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_ENB_RRC_INTERFACE_PDCP_H +#define SRSRAN_ENB_RRC_INTERFACE_PDCP_H + +#include "srsran/common/byte_buffer.h" + +namespace srsenb { + +/// RRC interface for PDCP +class rrc_interface_pdcp +{ +public: + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) = 0; + virtual void notify_pdcp_integrity_error(uint16_t rnti, uint32_t lcid) = 0; +}; + +} // namespace srsenb + +#endif // SRSRAN_ENB_RRC_INTERFACE_PDCP_H diff --git a/lib/include/srsran/interfaces/enb_rrc_interface_rlc.h b/lib/include/srsran/interfaces/enb_rrc_interface_rlc.h new file mode 100644 index 0000000000..9725718a27 --- /dev/null +++ b/lib/include/srsran/interfaces/enb_rrc_interface_rlc.h @@ -0,0 +1,40 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_ENB_RRC_INTERFACE_RLC_H +#define SRSRAN_ENB_RRC_INTERFACE_RLC_H + +#include "srsran/common/byte_buffer.h" + +namespace srsenb { + +/// RRC interface for RLC +class rrc_interface_rlc +{ +public: + virtual void max_retx_attempted(uint16_t rnti) = 0; + virtual void protocol_failure(uint16_t rnti) = 0; + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) = 0; +}; + +} // namespace srsenb + +#endif // SRSRAN_ENB_RRC_INTERFACE_RLC_H diff --git a/lib/include/srsran/interfaces/enb_rrc_interfaces.h b/lib/include/srsran/interfaces/enb_rrc_interface_s1ap.h similarity index 75% rename from lib/include/srsran/interfaces/enb_rrc_interfaces.h rename to lib/include/srsran/interfaces/enb_rrc_interface_s1ap.h index dc58cda307..b35f144d09 100644 --- a/lib/include/srsran/interfaces/enb_rrc_interfaces.h +++ b/lib/include/srsran/interfaces/enb_rrc_interface_s1ap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,7 +19,6 @@ * */ -#include "srsenb/hdr/stack/mac/sched_interface.h" #include "srsran/asn1/s1ap_utils.h" #include "srsran/interfaces/enb_rrc_interface_types.h" @@ -95,40 +94,6 @@ class rrc_interface_s1ap virtual void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) = 0; }; -/// RRC interface for RLC -class rrc_interface_rlc -{ -public: - virtual void max_retx_attempted(uint16_t rnti) = 0; - virtual void protocol_failure(uint16_t rnti) = 0; - virtual void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) = 0; -}; - -/// RRC interface for MAC -class rrc_interface_mac -{ -public: - /* Radio Link failure */ - virtual int add_user(uint16_t rnti, const sched_interface::ue_cfg_t& init_ue_cfg) = 0; - virtual void upd_user(uint16_t new_rnti, uint16_t old_rnti) = 0; - virtual void set_activity_user(uint16_t rnti) = 0; - virtual void set_radiolink_dl_state(uint16_t rnti, bool crc_res) = 0; - virtual void set_radiolink_ul_state(uint16_t rnti, bool crc_res) = 0; - virtual bool is_paging_opportunity(uint32_t tti_tx_dl, uint32_t* payload_len) = 0; - virtual void read_pdu_pcch(uint32_t tti_tx_dl, uint8_t* payload, uint32_t payload_size) = 0; - - ///< Provide packed SIB to MAC (buffer is managed by RRC) - virtual uint8_t* read_pdu_bcch_dlsch(const uint8_t enb_cc_idx, const uint32_t sib_index) = 0; -}; - -/// RRC interface for PDCP -class rrc_interface_pdcp -{ -public: - virtual void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) = 0; - virtual void notify_pdcp_integrity_error(uint16_t rnti, uint32_t lcid) = 0; -}; - } // namespace srsenb #endif // SRSRAN_ENB_RRC_INTERFACES_H diff --git a/lib/include/srsran/interfaces/enb_rrc_interface_types.h b/lib/include/srsran/interfaces/enb_rrc_interface_types.h index c926378fca..411e0a4971 100644 --- a/lib/include/srsran/interfaces/enb_rrc_interface_types.h +++ b/lib/include/srsran/interfaces/enb_rrc_interface_types.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -43,6 +43,7 @@ struct meas_cell_cfg_t { asn1::rrc::q_offset_range_e cell_individual_offset; uint32_t allowed_meas_bw; bool direct_forward_path_available; + int tac; }; // neigh measurement Cell info @@ -61,6 +62,7 @@ struct cell_cfg_t { uint32_t cell_id; uint16_t tac; uint32_t pci; + double tx_gain; uint16_t root_seq_idx; uint32_t dl_earfcn; double dl_freq_hz; @@ -73,6 +75,7 @@ struct cell_cfg_t { asn1::rrc::mob_ctrl_info_s::t304_e_ t304; std::vector scell_list; rrc_meas_cfg_t meas_cfg; + bool barred; }; typedef std::vector cell_list_t; diff --git a/lib/include/srsran/interfaces/enb_s1ap_interfaces.h b/lib/include/srsran/interfaces/enb_s1ap_interfaces.h index 7b9112dc9c..c6a074a718 100644 --- a/lib/include/srsran/interfaces/enb_s1ap_interfaces.h +++ b/lib/include/srsran/interfaces/enb_s1ap_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -41,6 +41,12 @@ struct s1ap_args_t { std::string enb_name; 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; + int32_t sctp_max_init_timeo; }; // S1AP interface for RRC @@ -88,6 +94,7 @@ class s1ap_interface_rrc */ virtual bool send_ho_required(uint16_t rnti, uint32_t target_eci, + uint16_t target_tac, srsran::plmn_id_t target_plmn, srsran::span fwd_erabs, srsran::unique_byte_buffer_t rrc_container, diff --git a/lib/include/srsran/interfaces/enb_time_interface.h b/lib/include/srsran/interfaces/enb_time_interface.h index 5a9acb7fa8..63ac3d666b 100644 --- a/lib/include/srsran/interfaces/enb_time_interface.h +++ b/lib/include/srsran/interfaces/enb_time_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/interfaces/enb_x2_interfaces.h b/lib/include/srsran/interfaces/enb_x2_interfaces.h index a5addce72f..81cb4a9cde 100644 --- a/lib/include/srsran/interfaces/enb_x2_interfaces.h +++ b/lib/include/srsran/interfaces/enb_x2_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -39,6 +39,7 @@ class rrc_nr_interface_rrc public: struct sgnb_addition_req_params_t { uint32_t eps_bearer_id; + uint32_t five_qi; // add configuration check // E-RAB Parameters, Tunnel address (IP address, TEID) // QCI, security, etc diff --git a/lib/include/srsran/interfaces/epc_interfaces.h b/lib/include/srsran/interfaces/epc_interfaces.h index fb8dfbf319..8cdc226c09 100644 --- a/lib/include/srsran/interfaces/epc_interfaces.h +++ b/lib/include/srsran/interfaces/epc_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/interfaces/gnb_interfaces.h b/lib/include/srsran/interfaces/gnb_interfaces.h index 6ef1b2d4b2..35c8ec816f 100644 --- a/lib/include/srsran/interfaces/gnb_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,15 +24,13 @@ #include "srsran/srsran.h" -#include "srsenb/hdr/stack/mac/sched_interface.h" #include "srsran/common/interfaces_common.h" #include "srsran/common/security.h" #include "srsran/interfaces/pdcp_interface_types.h" #include "srsran/interfaces/rlc_interface_types.h" -#include "srsran/interfaces/rrc_interface_types.h" // EUTRA interfaces that are used unmodified -#include "srsran/interfaces/enb_mac_interfaces.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" +#include "srsran/interfaces/enb_rrc_interface_pdcp.h" +#include "srsran/interfaces/enb_rrc_interface_rlc.h" namespace srsenb { @@ -132,6 +130,17 @@ class gtpu_interface_sdap_nr virtual void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) = 0; }; +/***************************** + * MAC internal INTERFACES + ****************************/ + +class mac_interface_pdu_demux_nr +{ +public: + // Called by PDU handler from Stack thread to store Msg3 content (According to O-RAN WG8 v3.0, Sec. 9.2.2.3.5 MAC) + virtual void store_msg3(uint16_t rnti, srsran::unique_byte_buffer_t pdu) = 0; +}; + /***************************** * RRC INTERFACES ****************************/ @@ -141,13 +150,13 @@ class rrc_interface_mac_nr { public: // Provides MIB packed message - virtual int read_pdu_bcch_bch(const uint32_t tti, srsran::unique_byte_buffer_t& buffer) = 0; - virtual int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) = 0; + virtual int read_pdu_bcch_bch(const uint32_t tti, srsran::byte_buffer_t& buffer) = 0; + virtual int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::byte_buffer_t& buffer) = 0; /// User management - virtual int add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg) = 0; - virtual int update_user(uint16_t new_rnti, uint16_t old_rnti) = 0; - virtual void set_activity_user(uint16_t rnti) = 0; + virtual int add_user(uint16_t rnti, uint32_t pcell_cc_idx) = 0; + virtual int update_user(uint16_t new_rnti, uint16_t old_rnti) = 0; + virtual void set_activity_user(uint16_t rnti) = 0; }; // NR interface is almost identical to EUTRA version @@ -288,15 +297,15 @@ class mac_interface_phy_nr uint32_t time_adv; }; - virtual int slot_indication(const srsran_slot_cfg_t& slot_cfg) = 0; - virtual int get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) = 0; - virtual int get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) = 0; - virtual int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) = 0; - virtual int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) = 0; - virtual void rach_detected(const rach_info_t& rach_info) = 0; + virtual int slot_indication(const srsran_slot_cfg_t& slot_cfg) = 0; + virtual dl_sched_t* get_dl_sched(const srsran_slot_cfg_t& slot_cfg) = 0; + virtual ul_sched_t* get_ul_sched(const srsran_slot_cfg_t& slot_cfg) = 0; + virtual int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) = 0; + virtual int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) = 0; + virtual void rach_detected(const rach_info_t& rach_info) = 0; }; -class stack_interface_phy_nr : public mac_interface_phy_nr, public srsran::stack_interface_phy_nr +class stack_interface_phy_nr : public mac_interface_phy_nr {}; } // namespace srsenb diff --git a/lib/include/srsran/interfaces/gnb_mac_interfaces.h b/lib/include/srsran/interfaces/gnb_mac_interfaces.h index 9076346c4e..eaaccd4bab 100644 --- a/lib/include/srsran/interfaces/gnb_mac_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_mac_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,7 +22,8 @@ #ifndef SRSRAN_GNB_MAC_INTERFACES_H #define SRSRAN_GNB_MAC_INTERFACES_H -#include "srsenb/hdr/stack/mac/nr/sched_nr_interface.h" +#include "srsgnb/hdr/stack/mac/sched_nr_interface.h" +#include "srsran/interfaces/enb_mac_interfaces.h" namespace srsenb { @@ -30,7 +31,7 @@ class mac_interface_rrc_nr { public: // Provides cell configuration including SIB periodicity, etc. - virtual int cell_cfg(const std::vector& nr_cells) = 0; + virtual int cell_cfg(const std::vector& nr_cells) = 0; /// Allocates a new user/RNTI at MAC. Returns RNTI on success or SRSRAN_INVALID_RNTI otherwise. virtual uint16_t reserve_rnti(uint32_t enb_cc_idx, const sched_nr_interface::ue_cfg_t& uecfg) = 0; diff --git a/lib/include/srsran/interfaces/gnb_ngap_interfaces.h b/lib/include/srsran/interfaces/gnb_ngap_interfaces.h index 20662f800e..1653ef13a8 100644 --- a/lib/include/srsran/interfaces/gnb_ngap_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_ngap_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -26,41 +26,49 @@ namespace srsenb { +const static int SRSRAN_NUM_SLICE = 3; +struct nssai_t { + bool active = false; + uint64_t sst; + uint64_t sd; +}; + struct ngap_args_t { - uint32_t gnb_id = 0; // 20-bit id (lsb bits) - uint8_t cell_id = 0; // 8-bit cell id - uint16_t tac = 0; // 16-bit tac - uint16_t mcc = 0; // BCD-coded with 0xF filler - uint16_t mnc = 0; // BCD-coded with 0xF filler - std::string amf_addr = ""; - std::string gtp_bind_addr = ""; - std::string gtp_advertise_addr = ""; - std::string ngc_bind_addr = ""; - std::string gnb_name = ""; + uint32_t gnb_id = 0; // 20-bit id (lsb bits) + uint8_t cell_id = 0; // 8-bit cell id + uint16_t tac = 0; // 16-bit tac + uint16_t mcc = 0; // BCD-coded with 0xF filler + uint16_t mnc = 0; // BCD-coded with 0xF filler + std::array nssai = {{{true, 1, 0}, {false, 2, 0}, {false, 3, 0}}}; + std::string amf_addr = ""; + std::string gtp_bind_addr = ""; + std::string gtp_advertise_addr = ""; + std::string ngc_bind_addr = ""; + std::string gnb_name = ""; }; // NGAP interface for RRC class ngap_interface_rrc_nr { public: - virtual void initial_ue(uint16_t rnti, - uint32_t gnb_cc_idx, - asn1::ngap_nr::rrcestablishment_cause_e cause, - srsran::unique_byte_buffer_t pdu) = 0; - virtual void initial_ue(uint16_t rnti, - uint32_t gnb_cc_idx, - asn1::ngap_nr::rrcestablishment_cause_e cause, - srsran::unique_byte_buffer_t pdu, - uint32_t m_tmsi) = 0; + virtual void initial_ue(uint16_t rnti, + uint32_t gnb_cc_idx, + asn1::ngap::rrcestablishment_cause_e cause, + srsran::const_byte_span pdu) = 0; + virtual void initial_ue(uint16_t rnti, + uint32_t gnb_cc_idx, + asn1::ngap::rrcestablishment_cause_e cause, + srsran::const_byte_span pdu, + uint32_t m_tmsi) = 0; - virtual void write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) = 0; - virtual bool user_exists(uint16_t rnti) = 0; - virtual void user_mod(uint16_t old_rnti, uint16_t new_rnti) = 0; - virtual bool user_release(uint16_t rnti, asn1::ngap_nr::cause_radio_network_e cause_radio) = 0; - virtual bool is_amf_connected() = 0; - virtual void ue_notify_rrc_reconf_complete(uint16_t rnti, bool outcome) = 0; + virtual void write_pdu(uint16_t rnti, srsran::const_byte_span pdu) = 0; + virtual bool user_exists(uint16_t rnti) = 0; + virtual void user_mod(uint16_t old_rnti, uint16_t new_rnti) = 0; + virtual void user_release_request(uint16_t rnti, asn1::ngap::cause_radio_network_e cause_radio) = 0; + virtual bool is_amf_connected() = 0; + virtual void ue_notify_rrc_reconf_complete(uint16_t rnti, bool outcome) = 0; }; } // namespace srsenb -#endif // SRSRAN_GNB_NGAP_INTERFACES_H \ No newline at end of file +#endif // SRSRAN_GNB_NGAP_INTERFACES_H diff --git a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h index b0262e3db4..a809d30709 100644 --- a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,6 @@ #ifndef SRSRAN_GNB_RRC_NR_INTERFACES_H #define SRSRAN_GNB_RRC_NR_INTERFACES_H -#include "srsenb/hdr/phy/phy_interfaces.h" #include "srsran/asn1/ngap.h" #include "srsran/common/byte_buffer.h" @@ -30,34 +29,22 @@ namespace srsenb { class rrc_interface_ngap_nr { public: - virtual int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) = 0; - virtual int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) = 0; - virtual int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) = 0; - virtual int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) = 0; - virtual int start_security_mode_procedure(uint16_t rnti) = 0; - virtual int - establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) = 0; - virtual int allocate_lcid(uint16_t rnti) = 0; - virtual int release_bearers(uint16_t rnti) = 0; - virtual void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) = 0; + virtual int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) = 0; + virtual int ue_set_bitrates(uint16_t rnti, const asn1::ngap::ue_aggregate_maximum_bit_rate_s& rates) = 0; + virtual int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap::ue_aggregate_maximum_bit_rate_s& rates) = 0; + virtual int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap::ue_security_cap_s& caps) = 0; + virtual int start_security_mode_procedure(uint16_t rnti, srsran::unique_byte_buffer_t nas_pdu) = 0; + virtual int establish_rrc_bearer(uint16_t rnti, + uint16_t pdu_session_id, + srsran::const_byte_span nas_pdu, + uint32_t lcid, + uint32_t five_qi) = 0; + virtual int allocate_lcid(uint16_t rnti) = 0; + virtual int release_bearers(uint16_t rnti) = 0; + virtual void release_user(uint16_t rnti) = 0; + virtual void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) = 0; }; -// Cell/Sector configuration for NR cells -struct rrc_cell_cfg_nr_t { - phy_cell_cfg_nr_t phy_cell; // already contains all PHY-related parameters (i.e. RF port, PCI, etc.) - uint32_t tac; // Tracking area code - uint32_t dl_arfcn; // DL freq already included in phy_cell - uint32_t ul_arfcn; // UL freq also in phy_cell - uint32_t dl_absolute_freq_point_a; // derived from DL ARFCN - uint32_t ul_absolute_freq_point_a; // derived from UL ARFCN - uint32_t ssb_absolute_freq_point; // derived from DL ARFCN - uint32_t band; - srsran_duplex_mode_t duplex_mode; - srsran_ssb_cfg_t ssb_cfg; -}; - -typedef std::vector rrc_cell_list_nr_t; - } // namespace srsenb -#endif // SRSRAN_GNB_RRC_NR_INTERFACES_H \ No newline at end of file +#endif // SRSRAN_GNB_RRC_NR_INTERFACES_H diff --git a/lib/include/srsran/interfaces/mac_interface_types.h b/lib/include/srsran/interfaces/mac_interface_types.h index a648ddaaf6..1e15f136ca 100644 --- a/lib/include/srsran/interfaces/mac_interface_types.h +++ b/lib/include/srsran/interfaces/mac_interface_types.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -133,7 +133,7 @@ struct rach_cfg_t { }; // 38.321 5.1.1 Not complete yet -struct rach_nr_cfg_t { +struct rach_cfg_nr_t { uint32_t prach_ConfigurationIndex; int PreambleReceivedTargetPower; uint32_t preambleTransMax; @@ -141,7 +141,7 @@ struct rach_nr_cfg_t { uint32_t ra_responseWindow; uint32_t ra_ContentionResolutionTimer; - rach_nr_cfg_t() { reset(); } + rach_cfg_nr_t() { reset(); } void reset() { prach_ConfigurationIndex = 0; @@ -224,6 +224,33 @@ struct mac_cfg_t { int time_alignment_timer = -1; }; +struct mac_cfg_nr_t { + // Default constructor with default values as in 36.331 9.2.2 + mac_cfg_nr_t() { set_defaults(); } + + void set_defaults() + { + rach_cfg.reset(); + sr_cfg.reset(); + set_mac_main_cfg_default(); + } + + void set_mac_main_cfg_default() + { + bsr_cfg.reset(); + phr_cfg.reset(); + harq_cfg.reset(); + time_alignment_timer = -1; + } + + bsr_cfg_t bsr_cfg; + phr_cfg_nr_t phr_cfg; + sr_cfg_t sr_cfg; + rach_cfg_nr_t rach_cfg; + ul_harq_cfg_t harq_cfg; + int time_alignment_timer = -1; +}; + } // namespace srsran #endif // SRSRAN_MAC_INTERFACE_TYPES_H diff --git a/lib/include/srsran/interfaces/pdcp_interface_types.h b/lib/include/srsran/interfaces/pdcp_interface_types.h index 7185135a06..fc38516603 100644 --- a/lib/include/srsran/interfaces/pdcp_interface_types.h +++ b/lib/include/srsran/interfaces/pdcp_interface_types.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -67,42 +67,43 @@ static const char* pdcp_pdu_type_text[PDCP_PDU_TYPE_N_ITEMS] = {"PDCP Report PDU // Taken from PDCP-Config (TS 38.331 version 15.2.1) enum class pdcp_t_reordering_t { - ms0 = 0, - ms1 = 1, - ms2 = 2, - ms4 = 4, - ms5 = 5, - ms8 = 8, - ms10 = 10, - ms15 = 15, - ms20 = 20, - ms30 = 30, - ms40 = 40, - ms50 = 50, - ms60 = 60, - ms80 = 80, - ms100 = 100, - ms120 = 120, - ms140 = 140, - ms160 = 160, - ms180 = 180, - ms200 = 200, - ms220 = 220, - ms240 = 240, - ms260 = 260, - ms280 = 280, - ms300 = 300, - ms500 = 500, - ms750 = 750, - ms1000 = 1000, - ms1250 = 1250, - ms1500 = 1500, - ms1750 = 1750, - ms2000 = 2000, - ms2250 = 2250, - ms2500 = 2500, - ms2750 = 2750, - ms3000 = 3000 + ms0 = 0, + ms1 = 1, + ms2 = 2, + ms4 = 4, + ms5 = 5, + ms8 = 8, + ms10 = 10, + ms15 = 15, + ms20 = 20, + ms30 = 30, + ms40 = 40, + ms50 = 50, + ms60 = 60, + ms80 = 80, + ms100 = 100, + ms120 = 120, + ms140 = 140, + ms160 = 160, + ms180 = 180, + ms200 = 200, + ms220 = 220, + ms240 = 240, + ms260 = 260, + ms280 = 280, + ms300 = 300, + ms500 = 500, + ms750 = 750, + ms1000 = 1000, + ms1250 = 1250, + ms1500 = 1500, + ms1750 = 1750, + ms2000 = 2000, + ms2250 = 2250, + ms2500 = 2500, + ms2750 = 2750, + ms3000 = 3000, + infinity = -1 }; // Taken from PDCP-Config (TS 38.331 version 15.2.1) @@ -122,7 +123,7 @@ enum class pdcp_discard_timer_t { ms500 = 500, ms750 = 750, ms1500 = 1500, - infinity = 0 + infinity = -1 }; class pdcp_config_t diff --git a/lib/include/srsran/interfaces/phy_common_interface.h b/lib/include/srsran/interfaces/phy_common_interface.h index 346a3a8a7a..faa2e437bb 100644 --- a/lib/include/srsran/interfaces/phy_common_interface.h +++ b/lib/include/srsran/interfaces/phy_common_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -28,7 +28,7 @@ namespace srsran { /** - * @brief Descibes a physical layer common interface + * @brief Describes a physical layer common interface */ class phy_common_interface { diff --git a/lib/include/srsran/interfaces/phy_interface_types.h b/lib/include/srsran/interfaces/phy_interface_types.h index 3c70b21f89..aba6e93ee3 100644 --- a/lib/include/srsran/interfaces/phy_interface_types.h +++ b/lib/include/srsran/interfaces/phy_interface_types.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/interfaces/radio_interfaces.h b/lib/include/srsran/interfaces/radio_interfaces.h index 3b492d805b..a36bcf90ad 100644 --- a/lib/include/srsran/interfaces/radio_interfaces.h +++ b/lib/include/srsran/interfaces/radio_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/interfaces/rlc_interface_types.h b/lib/include/srsran/interfaces/rlc_interface_types.h index 7f7368a52b..b39ab4872b 100644 --- a/lib/include/srsran/interfaces/rlc_interface_types.h +++ b/lib/include/srsran/interfaces/rlc_interface_types.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -73,11 +73,28 @@ inline std::string to_string(const rlc_am_nr_sn_size_t& sn_size) constexpr static const char* options[] = {"12 bits", "18 bits"}; return enum_to_text(options, (uint32_t)rlc_mode_t::nulltype, (uint32_t)sn_size); } -inline uint16_t to_number(const rlc_am_nr_sn_size_t& sn_size) +constexpr uint16_t to_number(const rlc_am_nr_sn_size_t& sn_size) { - constexpr static uint16_t options[] = {12, 18}; + constexpr uint16_t options[] = {12, 18}; return enum_to_number(options, (uint32_t)rlc_mode_t::nulltype, (uint32_t)sn_size); } +/** + * @brief Value range of the serial numbers + * @param sn_size Length of the serial number field in bits + * @return cardianlity + */ +constexpr uint32_t cardinality(const rlc_am_nr_sn_size_t& sn_size) +{ + return (1 << to_number(sn_size)); +} +/**************************************************************************** + * Tx constants + * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.2 + ***************************************************************************/ +constexpr uint32_t am_window_size(const rlc_am_nr_sn_size_t& sn_size) +{ + return cardinality(sn_size) / 2; +} struct rlc_am_config_t { /**************************************************************************** @@ -96,6 +113,26 @@ struct rlc_am_config_t { int32_t t_status_prohibit; // Timer used by rx to prohibit tx of status PDU (ms) }; +struct rlc_am_nr_config_t { + /**************************************************************************** + * Configurable parameters + * Ref: 3GPP TS 38.322 Section 7 + ***************************************************************************/ + + rlc_am_nr_sn_size_t tx_sn_field_length; // Number of bits used for tx (UL) sequence number + rlc_am_nr_sn_size_t rx_sn_field_length; // Number of bits used for rx (DL) sequence number + + // Timers Ref: 3GPP TS 38.322 Section 7.3 + int32_t t_poll_retx; // Poll retx timeout (ms) + int32_t t_reassembly; // Timer used by rx to detect PDU loss (ms) + int32_t t_status_prohibit; // Timer used by rx to prohibit tx of status PDU (ms) + + // Configurable Parameters. Ref: 3GPP TS 38.322 Section 7.4 + uint32_t max_retx_thresh; // Max number of retx + int32_t poll_pdu; // Insert poll bit after this many PDUs + int32_t poll_byte; // Insert poll bit after this much data (KB) +}; + struct rlc_um_config_t { /**************************************************************************** * Configurable parameters @@ -120,6 +157,7 @@ struct rlc_um_nr_config_t { rlc_um_nr_sn_size_t sn_field_length; // Number of bits used for sequence number int32_t t_reassembly_ms; // Timer used by rx to detect PDU loss (ms) + uint8_t bearer_id; // This is not in the 3GPP TS 38.322 }; #define RLC_TX_QUEUE_LEN (256) @@ -130,13 +168,14 @@ class rlc_config_t srsran_rat_t rat; rlc_mode_t rlc_mode; rlc_am_config_t am; + rlc_am_nr_config_t am_nr; rlc_um_config_t um; rlc_um_nr_config_t um_nr; uint32_t tx_queue_length; uint32_t mch_idx = 0; rlc_config_t() : - rat(srsran_rat_t::lte), rlc_mode(rlc_mode_t::tm), am(), um(), um_nr(), tx_queue_length(RLC_TX_QUEUE_LEN){}; + rat(srsran_rat_t::lte), rlc_mode(rlc_mode_t::tm), am(), am_nr(), um(), um_nr(), tx_queue_length(RLC_TX_QUEUE_LEN){}; // Factory for MCH static rlc_config_t mch_config() @@ -207,6 +246,27 @@ class rlc_config_t rlc_cnfg.am.t_poll_retx = 5; return rlc_cnfg; } + static rlc_config_t default_rlc_am_nr_config(uint32_t sn_size = 12) + { + rlc_config_t rlc_cnfg = {}; + rlc_cnfg.rat = srsran_rat_t::nr; + rlc_cnfg.rlc_mode = rlc_mode_t::am; + if (sn_size == 12) { + rlc_cnfg.am_nr.tx_sn_field_length = srsran::rlc_am_nr_sn_size_t::size12bits; + rlc_cnfg.am_nr.rx_sn_field_length = srsran::rlc_am_nr_sn_size_t::size12bits; + } else if (sn_size == 18) { + rlc_cnfg.am_nr.tx_sn_field_length = srsran::rlc_am_nr_sn_size_t::size18bits; + rlc_cnfg.am_nr.rx_sn_field_length = srsran::rlc_am_nr_sn_size_t::size18bits; + } else { + return {}; + } + rlc_cnfg.am_nr.t_status_prohibit = 8; + rlc_cnfg.am_nr.max_retx_thresh = 4; + rlc_cnfg.am_nr.t_reassembly = 35; + rlc_cnfg.am_nr.poll_pdu = 4; + rlc_cnfg.am_nr.t_poll_retx = 45; + return rlc_cnfg; + } static rlc_config_t default_rlc_um_nr_config(uint32_t sn_size = 6) { rlc_config_t cnfg = {}; diff --git a/lib/include/srsran/interfaces/rrc_interface_types.h b/lib/include/srsran/interfaces/rrc_interface_types.h index 64e27454eb..d0c0d73623 100644 --- a/lib/include/srsran/interfaces/rrc_interface_types.h +++ b/lib/include/srsran/interfaces/rrc_interface_types.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -411,7 +411,7 @@ inline uint16_t enum_to_number(const pmch_info_t::mch_sched_period_t& mch_period struct mcch_msg_t { uint32_t nof_common_sf_alloc = 0; - mbsfn_sf_cfg_t common_sf_alloc[8]; + mbsfn_sf_cfg_t common_sf_alloc[8] = {}; enum class common_sf_alloc_period_t { rf4, rf8, rf16, rf32, rf64, rf128, rf256, nulltype } common_sf_alloc_period; uint32_t nof_pmch_info; pmch_info_t pmch_info_list[15]; @@ -462,6 +462,8 @@ struct rrc_ue_capabilities_t { uint8_t category_ul = 0; bool support_dl_256qam = false; bool support_ul_64qam = false; + bool support_ca_bands = false; + bool support_ul_ca = false; }; } // namespace srsran diff --git a/lib/include/srsran/interfaces/ue_gw_interfaces.h b/lib/include/srsran/interfaces/ue_gw_interfaces.h index c93be15c2c..9af62c866e 100644 --- a/lib/include/srsran/interfaces/ue_gw_interfaces.h +++ b/lib/include/srsran/interfaces/ue_gw_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/interfaces/ue_interfaces.h b/lib/include/srsran/interfaces/ue_interfaces.h index a3774217a9..9093a71cc5 100644 --- a/lib/include/srsran/interfaces/ue_interfaces.h +++ b/lib/include/srsran/interfaces/ue_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/interfaces/ue_mac_interfaces.h b/lib/include/srsran/interfaces/ue_mac_interfaces.h index a3cc1a9224..8851492b66 100644 --- a/lib/include/srsran/interfaces/ue_mac_interfaces.h +++ b/lib/include/srsran/interfaces/ue_mac_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -45,6 +45,9 @@ class mac_interface_phy_lte uint32_t pid; uint16_t rnti; bool is_sps_release; + bool is_pdcch_order; + uint32_t preamble_idx; + uint32_t prach_mask_idx; uint32_t tti; } mac_grant_dl_t; @@ -100,10 +103,7 @@ class mac_interface_phy_lte virtual void bch_decoded_ok(uint32_t cc_idx, uint8_t* payload, uint32_t len) = 0; /* Indicate successful decoding of MCH TB through PMCH */ - virtual void mch_decoded(uint32_t len, bool crc) = 0; - - /* Obtain action for a new MCH subframe. */ - virtual void new_mch_dl(const srsran_pdsch_grant_t& phy_grant, tb_action_dl_t* action) = 0; + virtual void mch_decoded(uint32_t len, bool crc, uint8_t* payload) = 0; /* Communicate the number of mbsfn services available */ virtual void set_mbsfn_config(uint32_t nof_mbsfn_services) = 0; diff --git a/lib/include/srsran/interfaces/ue_nas_interfaces.h b/lib/include/srsran/interfaces/ue_nas_interfaces.h index dc16ea3d9d..3267159d00 100644 --- a/lib/include/srsran/interfaces/ue_nas_interfaces.h +++ b/lib/include/srsran/interfaces/ue_nas_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -38,7 +38,7 @@ class pdu_session_cfg_t { public: std::string apn_name; - apn_types apn_type; + apn_types apn_type = ipv4; std::string apn_user; std::string apn_pass; }; @@ -67,13 +67,15 @@ class nas_interface_rrc class nas_5g_interface_rrc_nr { public: - virtual int write_pdu(srsran::unique_byte_buffer_t pdu) = 0; + virtual int write_pdu(srsran::unique_byte_buffer_t pdu) = 0; + virtual int get_k_amf(srsran::as_key_t& k_amf) = 0; + virtual uint32_t get_ul_nas_count() = 0; }; class nas_5g_interface_procedures { public: - virtual int send_registration_request() = 0; + virtual int send_registration_request() = 0; virtual int send_pdu_session_establishment_request(uint32_t transaction_identity, uint16_t pdu_session_id, const pdu_session_cfg_t& pdu_session) = 0; diff --git a/lib/include/srsran/interfaces/ue_nr_interfaces.h b/lib/include/srsran/interfaces/ue_nr_interfaces.h index 8bbbf1dc5d..e28204a2de 100644 --- a/lib/include/srsran/interfaces/ue_nr_interfaces.h +++ b/lib/include/srsran/interfaces/ue_nr_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -36,8 +36,41 @@ class rrc_interface_phy_nr public: virtual void in_sync() = 0; virtual void out_of_sync() = 0; - virtual void run_tti(const uint32_t tti) = 0; virtual void set_phy_config_complete(bool status) = 0; + + /** + * @brief Describes a cell search result + */ + struct cell_search_result_t { + bool cell_found = false; + uint32_t ssb_arfcn = 0; ///< SSB center ARFCN + uint32_t pci = 0; ///< Physical Cell Identifier + srsran_pbch_msg_nr_t pbch_msg = {}; ///< Packed PBCH message for the upper layers + srsran_csi_trs_measurements_t measurements = {}; ///< Measurements from SSB block + }; + + /** + * @brief Informs RRC about cell search process completion + * @param result Cell search result completion + */ + virtual void cell_search_found_cell(const cell_search_result_t& result) = 0; + + /** + * @brief Describes a cell select result + */ + struct cell_select_result_t { + enum { + ERROR = 0, ///< The cell selection procedure failed due a to an invalid configuration + UNSUCCESSFUL, ///< The cell selection failed to find and synchronise the SSB + SUCCESSFUL, ///< The cell selection was successful, resulting in a camping state + } status; + }; + + /** + * @brief Informs RRC about cell select process completion + * @param result Cell select result completion + */ + virtual void cell_select_completed(const cell_select_result_t& result) = 0; }; class mac_interface_phy_nr @@ -93,8 +126,6 @@ class mac_interface_phy_nr tb_ul_t tb; // only single TB in UL } tb_action_ul_t; - virtual int sf_indication(const uint32_t tti) = 0; ///< TODO: rename to slot indication - // Query the MAC for the current RNTI to look for struct sched_rnti_t { uint16_t id; @@ -162,7 +193,7 @@ class mac_interface_rrc_nr virtual int set_config(const srsran::bsr_cfg_nr_t& bsr_cfg) = 0; virtual int set_config(const srsran::sr_cfg_nr_t& sr_cfg) = 0; virtual int set_config(const srsran::dl_harq_cfg_nr_t& dl_hrq_cfg) = 0; - virtual void set_config(const srsran::rach_nr_cfg_t& rach_cfg) = 0; + virtual void set_config(const srsran::rach_cfg_nr_t& rach_cfg_nr) = 0; virtual int add_tag_config(const srsran::tag_cfg_nr_t& tag_cfg) = 0; virtual int set_config(const srsran::phr_cfg_nr_t& phr_cfg) = 0; virtual int remove_tag_config(const uint32_t tag_id) = 0; @@ -175,25 +206,31 @@ class mac_interface_rrc_nr // RRC informs MAC about new UE identity for contention-free RA virtual bool set_crnti(const uint16_t crnti) = 0; + + // RRC informs MAC to start/stop search for BCCH messages + virtual void bcch_search(bool enabled) = 0; }; struct phy_args_nr_t { - uint32_t rf_channel_offset = 0; ///< Specifies the RF channel the NR carrier shall fill - uint32_t nof_carriers = 1; - uint32_t max_nof_prb = 106; - uint32_t nof_phy_threads = 3; - uint32_t worker_cpu_mask = 0; - srsran::phy_log_args_t log = {}; - srsran_ue_dl_nr_args_t dl = {}; - srsran_ue_ul_nr_args_t ul = {}; - std::set fixed_sr = {1}; - uint32_t fix_wideband_cqi = 15; // Set to a non-zero value for fixing the wide-band CQI report - bool store_pdsch_ko = false; - float trs_epre_ema_alpha = 0.1f; ///< EPRE measurement exponential average alpha - float trs_rsrp_ema_alpha = 0.1f; ///< RSRP measurement exponential average alpha - float trs_sinr_ema_alpha = 0.1f; ///< SINR measurement exponential average alpha - float trs_cfo_ema_alpha = 0.1f; ///< RSRP measurement exponential average alpha - bool enable_worker_cfo = true; ///< Enable/Disable open loop CFO correction at the workers + uint32_t rf_channel_offset = 0; ///< Specifies the RF channel the NR carrier shall fill + uint32_t nof_carriers = 1; + uint32_t max_nof_prb = 106; + double srate_hz = 23.04e6; + uint32_t nof_phy_threads = 3; + uint32_t worker_cpu_mask = 0; + int slot_recv_thread_prio = 0; /// Specifies the slot receive thread priority, RT by default + int workers_thread_prio = 2; /// Specifies the workers thread priority, RT by default + srsran::phy_log_args_t log = {}; + srsran_ue_dl_nr_args_t dl = {}; + srsran_ue_ul_nr_args_t ul = {}; + std::set fixed_sr = {1}; + uint32_t fix_wideband_cqi = 15; ///< Set to a non-zero value for fixing the wide-band CQI report + bool store_pdsch_ko = false; + float trs_epre_ema_alpha = 0.1f; ///< EPRE measurement exponential average alpha + float trs_rsrp_ema_alpha = 0.1f; ///< RSRP measurement exponential average alpha + float trs_sinr_ema_alpha = 0.1f; ///< SINR measurement exponential average alpha + float trs_cfo_ema_alpha = 0.1f; ///< RSRP measurement exponential average alpha + bool enable_worker_cfo = true; ///< Enable/Disable open loop CFO correction at the workers phy_args_nr_t() { @@ -218,20 +255,11 @@ struct phy_args_nr_t { class phy_interface_mac_nr { public: - typedef struct { - uint32_t tti; - uint32_t tb_len; - uint8_t* data; // always a pointer in our case - } tx_request_t; - // MAC informs PHY about UL grant included in RAR PDU - virtual int set_ul_grant(uint32_t rar_slot_idx, - std::array packed_ul_grant, - uint16_t rnti, - srsran_rnti_type_t rnti_type) = 0; - - // MAC instructs PHY to transmit MAC TB at the given TTI - virtual int tx_request(const tx_request_t& request) = 0; + virtual int set_rar_grant(uint32_t rar_slot_idx, + std::array packed_ul_grant, + uint16_t rnti, + srsran_rnti_type_t rnti_type) = 0; /// Instruct PHY to send PRACH in the next occasion. virtual void send_prach(const uint32_t prach_occasion, @@ -239,6 +267,12 @@ class phy_interface_mac_nr const float preamble_received_target_power, const float ta_base_sec = 0.0f) = 0; + /// Apply TA command after RAR + virtual void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) = 0; + + /// Apply TA command after MAC CE + virtual void set_timeadv(uint32_t tti, uint32_t ta_cmd) = 0; + /** * @brief Query PHY if there is a valid PUCCH SR resource configured for a given SR identifier * @param sr_id SR identifier @@ -256,13 +290,69 @@ class phy_interface_rrc_nr { public: virtual bool set_config(const srsran::phy_cfg_nr_t& cfg) = 0; + + /** + * @brief Describe the possible NR standalone physical layer possible states + */ + typedef enum { + PHY_NR_STATE_IDLE = 0, ///< There is no process going on + PHY_NR_STATE_CELL_SEARCH, ///< Cell search is currently in progress + PHY_NR_STATE_CELL_SELECT, ///< Cell selection is in progress or it is camped on a cell + PHY_NR_STATE_CAMPING + } phy_nr_state_t; + + /** + * @brief Retrieves the physical layer state + * @return + */ + virtual phy_nr_state_t get_state() = 0; + + /** + * @brief Stops the ongoing process and transitions to IDLE + */ + virtual void reset_nr() = 0; + + /** + * @brief Describes cell search arguments + */ + struct cell_search_args_t { + double center_freq_hz; + double ssb_freq_hz; + srsran_subcarrier_spacing_t ssb_scs; + srsran_ssb_pattern_t ssb_pattern; + srsran_duplex_mode_t duplex_mode; + }; + + /** + * @brief Start cell search + * @param args Cell Search arguments + * @return true if the physical layer started successfully the cell search process + */ + virtual bool start_cell_search(const cell_search_args_t& req) = 0; + + /** + * @brief Describes cell select arguments + */ + struct cell_select_args_t { + srsran_ssb_cfg_t ssb_cfg; + srsran_carrier_nr_t carrier; + }; + + /** + * @brief Start cell search + * @param args Cell Search arguments + * @return true if the physical layer started successfully the cell search process + */ + virtual bool start_cell_select(const cell_select_args_t& req) = 0; }; // Combined interface for PHY to access stack (MAC and RRC) -class stack_interface_phy_nr : public mac_interface_phy_nr, - public rrc_interface_phy_nr, - public srsran::stack_interface_phy_nr -{}; +class stack_interface_phy_nr : public mac_interface_phy_nr, public rrc_interface_phy_nr +{ +public: + /* Indicate new TTI */ + virtual void run_tti(const uint32_t tti, const uint32_t tti_jump) = 0; +}; // Combined interface for stack (MAC and RRC) to access PHY class phy_interface_stack_nr : public phy_interface_mac_nr, public phy_interface_rrc_nr diff --git a/lib/include/srsran/interfaces/ue_pdcp_interfaces.h b/lib/include/srsran/interfaces/ue_pdcp_interfaces.h index 36fb016e42..e508a7e01d 100644 --- a/lib/include/srsran/interfaces/ue_pdcp_interfaces.h +++ b/lib/include/srsran/interfaces/ue_pdcp_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -68,6 +68,13 @@ class pdcp_interface_stack virtual bool is_lcid_enabled(uint32_t lcid) = 0; }; +// SDAP interface +class pdcp_interface_sdap_nr +{ +public: + virtual void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) = 0; +}; + // STACK interface for GW (based on EPS-bearer IDs) class stack_interface_gw { diff --git a/lib/include/srsran/interfaces/ue_phy_interfaces.h b/lib/include/srsran/interfaces/ue_phy_interfaces.h index e84196515b..620ac442ae 100644 --- a/lib/include/srsran/interfaces/ue_phy_interfaces.h +++ b/lib/include/srsran/interfaces/ue_phy_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -35,6 +35,15 @@ namespace srsue { +struct cfr_args_t { + bool enable = false; + srsran_cfr_mode_t mode = SRSRAN_CFR_THR_MANUAL; + float manual_thres = 2.0f; + float strength = 1.0f; + float auto_target_papr = 7.0f; + float ema_alpha = 1.0f / (float)SRSRAN_CP_NORM_NSYMB; +}; + struct phy_args_t { std::string type = "lte"; srsran::phy_log_args_t log; @@ -45,6 +54,7 @@ struct phy_args_t { std::map ul_earfcn_map; // Map linking DL EARFCN and UL EARFCN int force_N_id_2 = -1; // Cell identity within the identity group (PSS) to filter. + int force_N_id_1 = -1; // Cell identity group (SSS) to filter. float dl_freq = -1.0f; float ul_freq = -1.0f; @@ -60,7 +70,7 @@ struct phy_args_t { uint32_t nof_lte_carriers = 1; uint32_t nof_nr_carriers = 0; - uint32_t nr_max_nof_prb = 106; + uint32_t nr_max_nof_prb = 52; uint32_t nof_rx_ant = 1; std::string equalizer_mode = "mmse"; int cqi_max = 15; @@ -105,7 +115,7 @@ struct phy_args_t { srsran::channel::args_t dl_channel_args; srsran::channel::args_t ul_channel_args; - srsran::vnf_args_t vnf_args; + cfr_args_t cfr_args; ///< Stores user-defined CFR configuration }; /* RAT agnostic Interface MAC -> PHY */ @@ -167,7 +177,7 @@ class phy_interface_rrc_lte virtual void meas_stop() = 0; /* Cell search and selection procedures */ - virtual bool cell_search() = 0; + virtual bool cell_search(int earfcn) = 0; virtual bool cell_select(phy_cell_t cell) = 0; virtual bool cell_is_camping() = 0; }; diff --git a/lib/include/srsran/interfaces/ue_rlc_interfaces.h b/lib/include/srsran/interfaces/ue_rlc_interfaces.h index 6c03c9d435..6aff37b2c8 100644 --- a/lib/include/srsran/interfaces/ue_rlc_interfaces.h +++ b/lib/include/srsran/interfaces/ue_rlc_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/interfaces/ue_rrc_interfaces.h b/lib/include/srsran/interfaces/ue_rrc_interfaces.h index 80ce3a8de2..6453fc3577 100644 --- a/lib/include/srsran/interfaces/ue_rrc_interfaces.h +++ b/lib/include/srsran/interfaces/ue_rrc_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -25,6 +25,7 @@ #include "phy_interface_types.h" #include "rrc_interface_types.h" #include "srsran/asn1/asn1_utils.h" +#include "srsran/asn1/rrc_nr.h" #include "srsran/common/byte_buffer.h" #include "srsran/common/tti_point.h" @@ -108,19 +109,13 @@ class rrc_interface_rlc class rrc_nr_interface_rrc { public: - virtual int get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps) = 0; - virtual int get_nr_capabilities(srsran::byte_buffer_t* nr_cap) = 0; - virtual void phy_set_cells_to_meas(uint32_t carrier_freq_r15) = 0; - virtual void phy_meas_stop() = 0; - virtual bool rrc_reconfiguration(bool endc_release_and_add_r15, - bool nr_secondary_cell_group_cfg_r15_present, - asn1::dyn_octstring nr_secondary_cell_group_cfg_r15, - bool sk_counter_r15_present, - uint32_t sk_counter_r15, - bool nr_radio_bearer_cfg1_r15_present, - asn1::dyn_octstring nr_radio_bearer_cfg1_r15) = 0; - virtual void rrc_release() = 0; - virtual bool is_config_pending() = 0; + virtual int get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps) = 0; + virtual int get_nr_capabilities(srsran::byte_buffer_t* nr_cap) = 0; + virtual void phy_set_cells_to_meas(uint32_t carrier_freq_r15) = 0; + virtual void phy_meas_stop() = 0; + virtual bool rrc_reconfiguration(bool endc_release_and_add_r15, const asn1::rrc_nr::rrc_recfg_s& rrc_nr_reconf) = 0; + virtual void rrc_release() = 0; + virtual bool is_config_pending() = 0; }; class rrc_nr_interface_nas_5g diff --git a/lib/include/srsran/interfaces/ue_sdap_interfaces.h b/lib/include/srsran/interfaces/ue_sdap_interfaces.h new file mode 100644 index 0000000000..55829092ec --- /dev/null +++ b/lib/include/srsran/interfaces/ue_sdap_interfaces.h @@ -0,0 +1,56 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +/****************************************************************************** + * File: ue_sdap_interfaces.h + * Description: Abstract base class interfaces for SDAP layer + *****************************************************************************/ + +#ifndef SRSRAN_UE_SDAP_INTERFACES_H +#define SRSRAN_UE_SDAP_INTERFACES_H + +/***************************** + * SDAP INTERFACES + ****************************/ +class sdap_interface_pdcp_nr +{ +public: + virtual void write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) = 0; +}; +class sdap_interface_gw_nr +{ +public: + virtual void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) = 0; +}; + +class sdap_interface_rrc +{ +public: + struct bearer_cfg_t { + bool is_data; + bool add_downlink_header; + bool add_uplink_header; + uint32_t qfi; + }; + virtual bool set_bearer_cfg(uint32_t lcid, const bearer_cfg_t& cfg) = 0; +}; + +#endif // SRSRAN_UE_SDAP_INTERFACES_H diff --git a/lib/include/srsran/interfaces/ue_usim_interfaces.h b/lib/include/srsran/interfaces/ue_usim_interfaces.h index 8c4e01a95a..aa748e8846 100644 --- a/lib/include/srsran/interfaces/ue_usim_interfaces.h +++ b/lib/include/srsran/interfaces/ue_usim_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -33,24 +33,24 @@ enum auth_result_t { AUTH_OK, AUTH_FAILED, AUTH_SYNCH_FAILURE }; class usim_interface_nas { public: - virtual std::string get_imsi_str() = 0; - virtual std::string get_imei_str() = 0; - virtual bool get_imsi_vec(uint8_t* imsi_, uint32_t n) = 0; - virtual bool get_imei_vec(uint8_t* imei_, uint32_t n) = 0; - virtual bool get_home_plmn_id(srsran::plmn_id_t* home_plmn_id) = 0; + virtual std::string get_imsi_str() = 0; + virtual std::string get_imei_str() = 0; + virtual bool get_imsi_vec(uint8_t* imsi_, uint32_t n) = 0; + virtual bool get_imei_vec(uint8_t* imei_, uint32_t n) = 0; + virtual bool get_home_plmn_id(srsran::plmn_id_t* home_plmn_id) = 0; // Get the home mcc as bytes array - virtual bool get_home_mcc_bytes(uint8_t* mcc_, uint32_t n) = 0; + virtual bool get_home_mcc_bytes(uint8_t* mcc_, uint32_t n) = 0; // Get the home mnc as byte array - virtual bool get_home_mnc_bytes(uint8_t* mnc_, uint32_t n) = 0; + virtual bool get_home_mnc_bytes(uint8_t* mnc_, uint32_t n) = 0; // Get the home msin in bytes array encoded as bcd - virtual bool get_home_msin_bcd(uint8_t* msin_, uint32_t n) = 0; + virtual bool get_home_msin_bcd(uint8_t* msin_, uint32_t n) = 0; virtual auth_result_t generate_authentication_response(uint8_t* rand, uint8_t* autn_enb, uint16_t mcc, uint16_t mnc, uint8_t* res, int* res_len, - uint8_t* k_asme) = 0; + uint8_t* k_asme) = 0; virtual auth_result_t generate_authentication_response_5g(uint8_t* rand, uint8_t* autn_enb, @@ -86,8 +86,10 @@ class usim_interface_rrc class usim_interface_rrc_nr { public: - virtual bool generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) = 0; - virtual bool update_nr_context(srsran::as_security_config_t* sec_cfg) = 0; + virtual void + generate_nr_as_keys(srsran::as_key_t& k_amf, uint32_t count_ul, srsran::as_security_config_t* sec_cfg) = 0; + virtual bool generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) = 0; + virtual bool update_nr_context(srsran::as_security_config_t* sec_cfg) = 0; }; } // namespace srsue diff --git a/lib/include/srsran/mac/bsr_nr.h b/lib/include/srsran/mac/bsr_nr.h index 1ab35dfb18..8d9f50e105 100644 --- a/lib/include/srsran/mac/bsr_nr.h +++ b/lib/include/srsran/mac/bsr_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/mac/mac_rar_pdu_nr.h b/lib/include/srsran/mac/mac_rar_pdu_nr.h index f1d9b3429d..d8c107613f 100644 --- a/lib/include/srsran/mac/mac_rar_pdu_nr.h +++ b/lib/include/srsran/mac/mac_rar_pdu_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/mac/mac_sch_pdu_nr.h b/lib/include/srsran/mac/mac_sch_pdu_nr.h index f9348ca7ae..0c3b37933b 100644 --- a/lib/include/srsran/mac/mac_sch_pdu_nr.h +++ b/lib/include/srsran/mac/mac_sch_pdu_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -38,7 +38,7 @@ class mac_sch_subpdu_nr { public: // 3GPP 38.321 v15.3.0 Combined Tables 6.2.1-1, 6.2.1-2 - typedef enum { + enum nr_lcid_sch_t { // Values for DL-SCH CCCH = 0b000000, DRX_CMD = 0b111100, @@ -58,7 +58,7 @@ class mac_sch_subpdu_nr // Common PADDING = 0b111111, - } nr_lcid_sch_t; + }; // SDUs up to 256 B can use the short 8-bit L field static const int32_t MAC_SUBHEADER_LEN_THRESHOLD = 256; @@ -66,17 +66,18 @@ class mac_sch_subpdu_nr mac_sch_subpdu_nr(mac_sch_pdu_nr* parent_) : parent(parent_), logger(&srslog::fetch_basic_logger("MAC-NR")){}; nr_lcid_sch_t get_type(); - bool is_sdu(); + bool is_sdu() const; bool is_valid_lcid(); bool is_var_len_ce(uint32_t lcid); - bool is_ul_ccch(); + bool is_ul_ccch() const; - int32_t read_subheader(const uint8_t* ptr); - uint32_t get_total_length(); - uint32_t get_sdu_length(); - uint32_t get_lcid(); - uint8_t* get_sdu(); - uint16_t get_c_rnti(); + int32_t read_subheader(const uint8_t* ptr); + uint32_t get_total_length() const; + uint32_t get_sdu_length() const; + uint32_t get_lcid() const; + uint8_t* get_sdu(); + const uint8_t* get_sdu() const; + uint16_t get_c_rnti() const; // both return the reported values as per TS 38.321, mapping to dB according to TS 38.133 Sec 10.1.17 not done here uint8_t get_phr(); @@ -87,13 +88,13 @@ class mac_sch_subpdu_nr uint8_t lcg_id; uint8_t buffer_size; }; - lcg_bsr_t get_sbsr(); + lcg_bsr_t get_sbsr() const; static const uint8_t max_num_lcg_lbsr = 8; struct lbsr_t { uint8_t bitmap; // the first octet of LBSR and Long Trunc BSR std::vector list; // one entry for each reported LCG }; - lbsr_t get_lbsr(); + lbsr_t get_lbsr() const; // TA struct ta_t { @@ -102,6 +103,12 @@ class mac_sch_subpdu_nr }; ta_t get_ta(); + // UE contention resolution identity CE + static const uint8_t ue_con_res_id_len = 6; + typedef std::array ue_con_res_id_t; + ue_con_res_id_t get_ue_con_res_id_ce(); + uint64_t get_ue_con_res_id_ce_packed(); + // setters void set_sdu(const uint32_t lcid_, const uint8_t* payload_, const uint32_t len_); void set_padding(const uint32_t len_); @@ -109,6 +116,7 @@ class mac_sch_subpdu_nr void set_se_phr(const uint8_t phr_, const uint8_t pcmax_); void set_sbsr(const lcg_bsr_t bsr_); void set_lbsr(const std::array bsr_); + void set_ue_con_res_id_ce(const ue_con_res_id_t id); uint32_t write_subpdu(const uint8_t* start_); @@ -132,9 +140,9 @@ class mac_sch_subpdu_nr /// internal buffer, useful for storing very short SDUs. class sdu_buffer { - static const uint8_t mac_ce_payload_len = 8 + 1; // Long BSR has max. 9 octets (see sizeof_ce() too) - std::array ce_write_buffer; // Buffer for CE payload - uint8_t* sdu = nullptr; + static const uint8_t mac_ce_payload_len = 8 + 1; // Long BSR has max. 9 octets (see sizeof_ce() too) + std::array ce_write_buffer = {}; // Buffer for CE payload + uint8_t* sdu = nullptr; public: sdu_buffer() = default; @@ -180,7 +188,8 @@ class mac_sch_subpdu_nr } /// Returns the SDU pointer. - uint8_t* ptr() { return sdu; } + const uint8_t* ptr() const { return sdu; } + uint8_t* ptr() { return sdu; } }; sdu_buffer sdu; @@ -195,8 +204,9 @@ class mac_sch_pdu_nr void pack(); int unpack(const uint8_t* payload, const uint32_t& len); - uint32_t get_num_subpdus(); - const mac_sch_subpdu_nr& get_subpdu(const uint32_t& index); + uint32_t get_num_subpdus() const { return subpdus.size(); } + const mac_sch_subpdu_nr& get_subpdu(const uint32_t& index) const; + mac_sch_subpdu_nr& get_subpdu(uint32_t index); bool is_ulsch(); int init_tx(byte_buffer_t* buffer_, uint32_t pdu_len_, bool is_ulsch_ = false); @@ -209,6 +219,7 @@ class mac_sch_pdu_nr uint32_t add_se_phr_ce(const uint8_t phr_, const uint8_t pcmax_); uint32_t add_sbsr_ce(const mac_sch_subpdu_nr::lcg_bsr_t bsr_); uint32_t add_lbsr_ce(const std::array bsr_); + uint32_t add_ue_con_res_id_ce(const mac_sch_subpdu_nr::ue_con_res_id_t id); uint32_t get_remaing_len(); diff --git a/lib/include/srsran/mac/pdu.h b/lib/include/srsran/mac/pdu.h index df82b95ac2..d91d9b64a6 100644 --- a/lib/include/srsran/mac/pdu.h +++ b/lib/include/srsran/mac/pdu.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/mac/pdu_queue.h b/lib/include/srsran/mac/pdu_queue.h index add1a39cdc..6792b92e3e 100644 --- a/lib/include/srsran/mac/pdu_queue.h +++ b/lib/include/srsran/mac/pdu_queue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/agc/agc.h b/lib/include/srsran/phy/agc/agc.h index c9a1252e38..00a8580702 100644 --- a/lib/include/srsran/phy/agc/agc.h +++ b/lib/include/srsran/phy/agc/agc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/cfr/cfr.h b/lib/include/srsran/phy/cfr/cfr.h new file mode 100644 index 0000000000..b18904af7f --- /dev/null +++ b/lib/include/srsran/phy/cfr/cfr.h @@ -0,0 +1,139 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_CFR_H +#define SRSRAN_CFR_H + +#include "srsran/config.h" +#include "srsran/phy/common/phy_common.h" +#include "srsran/phy/dft/dft.h" + +#define CFR_EMA_INIT_AVG_PWR 0.1 + +/** + * @brief CFR manual threshold or PAPR limiting with CMA or EMA power averaging + */ +typedef enum SRSRAN_API { + SRSRAN_CFR_THR_INVALID, + SRSRAN_CFR_THR_MANUAL, + SRSRAN_CFR_THR_AUTO_CMA, + SRSRAN_CFR_THR_AUTO_EMA, + SRSRAN_CFR_NOF_MODES +} srsran_cfr_mode_t; + +/** + * @brief CFR module configuration arguments + */ +typedef struct SRSRAN_API { + bool cfr_enable; + srsran_cfr_mode_t cfr_mode; + // always used (mandatory) + uint32_t symbol_bw; ///< OFDM symbol bandwidth, in FFT bins + uint32_t symbol_sz; ///< OFDM symbol size (in samples). This is the FFT size + float alpha; ///< Alpha parameter of the clipping algorithm + bool dc_sc; ///< Take into account the DC subcarrier for the filter BW + + // SRSRAN_CFR_THR_MANUAL mode parameters + float manual_thr; ///< Fixed threshold used in SRSRAN_CFR_THR_MANUAL mode + + // SRSRAN_CFR_THR_AUTO_CMA and SRSRAN_CFR_THR_AUTO_EMA mode parameters + bool measure_out_papr; ///< Enable / disable output PAPR measurement + float max_papr_db; ///< Input PAPR threshold used in SRSRAN_CFR_THR_AUTO_CMA and SRSRAN_CFR_THR_AUTO_EMA modes + float ema_alpha; ///< EMA alpha parameter for avg power calculation, used in SRSRAN_CFR_THR_AUTO_EMA mode +} srsran_cfr_cfg_t; + +typedef struct SRSRAN_API { + srsran_cfr_cfg_t cfg; + float max_papr_lin; + + srsran_dft_plan_t fft_plan; + srsran_dft_plan_t ifft_plan; + float* lpf_spectrum; ///< FFT filter spectrum + uint32_t lpf_bw; ///< Bandwidth of the LPF + + float* abs_buffer_in; ///< Store the input absolute value + float* abs_buffer_out; ///< Store the output absolute value + cf_t* peak_buffer; + + float pwr_avg_in; ///< store the avg. input power with MA or EMA averaging + float pwr_avg_out; ///< store the avg. output power with MA or EMA averaging + + // Power average buffers, used in SRSRAN_CFR_THR_AUTO_CMA mode + uint64_t cma_n; +} srsran_cfr_t; + +SRSRAN_API int srsran_cfr_init(srsran_cfr_t* q, srsran_cfr_cfg_t* cfg); + +/** + * @brief Applies the CFR algorithm to the time domain OFDM symbols + * + * @attention This function must be called once per symbol, and it will process q->symbol_sz samples + * + * @param[in] q The CFR object and configuration + * @param[in] in Input buffer containing the time domain OFDM symbol without CP + * @param[out] out Output buffer with the processed OFDM symbol + * @return SRSRAN_SUCCESS if the CFR object is initialised, otherwise SRSRAN_ERROR + */ +SRSRAN_API void srsran_cfr_process(srsran_cfr_t* q, cf_t* in, cf_t* out); + +SRSRAN_API void srsran_cfr_free(srsran_cfr_t* q); + +/** + * @brief Checks the validity of the CFR algorithm parameters. + * + * @attention Does not check symbol size and bandwidth + * + * @param[in] cfr_conf the CFR configuration + * @return true if the configuration is valid, false otherwise + */ +SRSRAN_API bool srsran_cfr_params_valid(srsran_cfr_cfg_t* cfr_conf); + +/** + * @brief Sets the manual threshold of the CFR (used in manual mode). + * + * @attention this is not thread-safe + * + * @param[in] q the CFR object + * @return SRSRAN_SUCCESS if successful, SRSRAN_ERROR or SRSRAN_ERROR_INVALID_INPUTS otherwise + */ +SRSRAN_API int srsran_cfr_set_threshold(srsran_cfr_t* q, float thres); + +/** + * @brief Sets the papr target of the CFR (used in auto modes). + * + * @attention this is not thread-safe + * + * @param[in] q the CFR object + * @return SRSRAN_SUCCESS if successful, SRSRAN_ERROR or SRSRAN_ERROR_INVALID_INPUTS otherwise + */ +SRSRAN_API int srsran_cfr_set_papr(srsran_cfr_t* q, float papr); + +/** + * @brief Converts a string representing a CFR mode from the config files into srsran_cfr_mode_t type + * + * @param[in] mode_str the cfr.mode string coming from the config file + * @return SRSRAN_CFR_THR_INVALID if mode_str is empty, + * SRSRAN_CFR_THR_INVALID if mode_str is not recognised, + * otherwise it returns the corresponding srsran_cfr_mode_t value. + */ +SRSRAN_API srsran_cfr_mode_t srsran_cfr_str2mode(const char* mode_str); + +#endif // SRSRAN_CFR_H diff --git a/lib/include/srsran/phy/ch_estimation/chest_common.h b/lib/include/srsran/phy/ch_estimation/chest_common.h index a054eb57a9..57421c4361 100644 --- a/lib/include/srsran/phy/ch_estimation/chest_common.h +++ b/lib/include/srsran/phy/ch_estimation/chest_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/chest_dl.h b/lib/include/srsran/phy/ch_estimation/chest_dl.h index cb18b2c08a..a246ade2c5 100644 --- a/lib/include/srsran/phy/ch_estimation/chest_dl.h +++ b/lib/include/srsran/phy/ch_estimation/chest_dl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/chest_dl_nbiot.h b/lib/include/srsran/phy/ch_estimation/chest_dl_nbiot.h index b819f2a97a..573b59870e 100644 --- a/lib/include/srsran/phy/ch_estimation/chest_dl_nbiot.h +++ b/lib/include/srsran/phy/ch_estimation/chest_dl_nbiot.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/chest_sl.h b/lib/include/srsran/phy/ch_estimation/chest_sl.h index 9dcbe98284..fb6f891e7e 100644 --- a/lib/include/srsran/phy/ch_estimation/chest_sl.h +++ b/lib/include/srsran/phy/ch_estimation/chest_sl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/chest_ul.h b/lib/include/srsran/phy/ch_estimation/chest_ul.h index cca034e17a..ddd1cb6b61 100644 --- a/lib/include/srsran/phy/ch_estimation/chest_ul.h +++ b/lib/include/srsran/phy/ch_estimation/chest_ul.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -49,7 +49,7 @@ typedef struct SRSRAN_API { cf_t* ce; uint32_t nof_re; float noise_estimate; - float noise_estimate_dbm; + float noise_estimate_dbFs; float rsrp; float rsrp_dBfs; float epre; diff --git a/lib/include/srsran/phy/ch_estimation/csi_rs.h b/lib/include/srsran/phy/ch_estimation/csi_rs.h index 285dca4b3b..a13d738c41 100644 --- a/lib/include/srsran/phy/ch_estimation/csi_rs.h +++ b/lib/include/srsran/phy/ch_estimation/csi_rs.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/csi_rs_cfg.h b/lib/include/srsran/phy/ch_estimation/csi_rs_cfg.h index 110a723f1d..e0ee4d8da4 100644 --- a/lib/include/srsran/phy/ch_estimation/csi_rs_cfg.h +++ b/lib/include/srsran/phy/ch_estimation/csi_rs_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/dmrs_pbch.h b/lib/include/srsran/phy/ch_estimation/dmrs_pbch.h index 135e1e8c13..4670775335 100644 --- a/lib/include/srsran/phy/ch_estimation/dmrs_pbch.h +++ b/lib/include/srsran/phy/ch_estimation/dmrs_pbch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/dmrs_pdcch.h b/lib/include/srsran/phy/ch_estimation/dmrs_pdcch.h index edb73b6ee1..b6ac1755ea 100644 --- a/lib/include/srsran/phy/ch_estimation/dmrs_pdcch.h +++ b/lib/include/srsran/phy/ch_estimation/dmrs_pdcch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/dmrs_pucch.h b/lib/include/srsran/phy/ch_estimation/dmrs_pucch.h index 188c6e2b4e..e562783cf4 100644 --- a/lib/include/srsran/phy/ch_estimation/dmrs_pucch.h +++ b/lib/include/srsran/phy/ch_estimation/dmrs_pucch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/dmrs_sch.h b/lib/include/srsran/phy/ch_estimation/dmrs_sch.h index 31f6c81ad9..695c3fee10 100644 --- a/lib/include/srsran/phy/ch_estimation/dmrs_sch.h +++ b/lib/include/srsran/phy/ch_estimation/dmrs_sch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/refsignal_dl.h b/lib/include/srsran/phy/ch_estimation/refsignal_dl.h index da1f133a16..59bf2032f1 100644 --- a/lib/include/srsran/phy/ch_estimation/refsignal_dl.h +++ b/lib/include/srsran/phy/ch_estimation/refsignal_dl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/refsignal_dl_nbiot.h b/lib/include/srsran/phy/ch_estimation/refsignal_dl_nbiot.h index ab77713bca..9d1ca80411 100644 --- a/lib/include/srsran/phy/ch_estimation/refsignal_dl_nbiot.h +++ b/lib/include/srsran/phy/ch_estimation/refsignal_dl_nbiot.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/refsignal_ul.h b/lib/include/srsran/phy/ch_estimation/refsignal_ul.h index 2d818335c1..16a107a25e 100644 --- a/lib/include/srsran/phy/ch_estimation/refsignal_ul.h +++ b/lib/include/srsran/phy/ch_estimation/refsignal_ul.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ch_estimation/wiener_dl.h b/lib/include/srsran/phy/ch_estimation/wiener_dl.h index 7fad9dfbf2..5bbd23ecba 100644 --- a/lib/include/srsran/phy/ch_estimation/wiener_dl.h +++ b/lib/include/srsran/phy/ch_estimation/wiener_dl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/channel/ch_awgn.h b/lib/include/srsran/phy/channel/ch_awgn.h index eff5e5e80f..33fa846a69 100644 --- a/lib/include/srsran/phy/channel/ch_awgn.h +++ b/lib/include/srsran/phy/channel/ch_awgn.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,13 +19,11 @@ * */ -/********************************************************************************************** - * File: ch_awgn.h - * - * Description: Additive white gaussian noise channel object +/** + * \file ch_awgn.h + * \brief Additive white Gaussian noise channel object * - * Reference: - *********************************************************************************************/ + */ #include "srsran/config.h" #include @@ -38,7 +36,7 @@ extern "C" { #endif /** - * The srsRAN channel AWGN implements an efficient Box-Muller Method accelerated with SIMD. + * \brief srsRAN channel AWGN implements an efficient Box-Muller Method accelerated with SIMD. */ typedef struct { float* table_cos; @@ -48,7 +46,7 @@ typedef struct { } srsran_channel_awgn_t; /** - * Initialization function of the channel AWGN object + * \brief function of the channel AWGN object * * @param q AWGN channel object * @param seed random generator seed @@ -56,7 +54,7 @@ typedef struct { SRSRAN_API int srsran_channel_awgn_init(srsran_channel_awgn_t* q, uint32_t seed); /** - * Sets the noise level N0 in decibels full scale (dBfs) + * \brief the noise level N0 in decibels full scale (dBfs) * * @param q AWGN channel object * @param n0_dBfs noise level @@ -64,7 +62,7 @@ SRSRAN_API int srsran_channel_awgn_init(srsran_channel_awgn_t* q, uint32_t seed) SRSRAN_API int srsran_channel_awgn_set_n0(srsran_channel_awgn_t* q, float n0_dBfs); /** - * Runs the complex AWGN channel + * \brief the complex AWGN channel * * @param q AWGN channel object * @param in complex input array @@ -74,7 +72,7 @@ SRSRAN_API int srsran_channel_awgn_set_n0(srsran_channel_awgn_t* q, float n0_dBf SRSRAN_API void srsran_channel_awgn_run_c(srsran_channel_awgn_t* q, const cf_t* in, cf_t* out, uint32_t length); /** - * Runs the real AWGN channel + * \brief the real AWGN channel * * @param q AWGN channel object * @param in real input array @@ -84,15 +82,31 @@ SRSRAN_API void srsran_channel_awgn_run_c(srsran_channel_awgn_t* q, const cf_t* SRSRAN_API void srsran_channel_awgn_run_f(srsran_channel_awgn_t* q, const float* in, float* out, uint32_t length); /** - * Free AWGN channel generator data + * \brief AWGN channel generator data * * @param q AWGN channel object */ SRSRAN_API void srsran_channel_awgn_free(srsran_channel_awgn_t* q); +/** + * \brief signal \p input with AWGN to obtain signal \p output (complex case). + * + * @param[in] input Input signal + * @param[out] output Output signal + * @param[in] variance Noise variance + * @param[in] len Number of samples + */ SRSRAN_API void srsran_ch_awgn_c(const cf_t* input, cf_t* output, float variance, uint32_t len); -SRSRAN_API void srsran_ch_awgn_f(const float* x, float* y, float variance, uint32_t len); +/** + * \brief Perturb signal \p input with AWGN to obtain signal \p output (real case). + * + * @param[in] input Input signal + * @param[out] output Output signal + * @param[in] variance Noise variance + * @param[in] len Number of samples + */ +SRSRAN_API void srsran_ch_awgn_f(const float* input, float* output, float variance, uint32_t len); SRSRAN_API float srsran_ch_awgn_get_variance(float ebno_db, float rate); diff --git a/lib/include/srsran/phy/channel/channel.h b/lib/include/srsran/phy/channel/channel.h index 75d61fcbb6..6fe3e24461 100644 --- a/lib/include/srsran/phy/channel/channel.h +++ b/lib/include/srsran/phy/channel/channel.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/channel/delay.h b/lib/include/srsran/phy/channel/delay.h index d58a88f775..fff87853ac 100644 --- a/lib/include/srsran/phy/channel/delay.h +++ b/lib/include/srsran/phy/channel/delay.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/channel/fading.h b/lib/include/srsran/phy/channel/fading.h index ccc2b63218..6334a15272 100644 --- a/lib/include/srsran/phy/channel/fading.h +++ b/lib/include/srsran/phy/channel/fading.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/channel/hst.h b/lib/include/srsran/phy/channel/hst.h index de88e5cea3..2e53bc2ca8 100644 --- a/lib/include/srsran/phy/channel/hst.h +++ b/lib/include/srsran/phy/channel/hst.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/channel/rlf.h b/lib/include/srsran/phy/channel/rlf.h index 782e3ee329..8dfbdf1520 100644 --- a/lib/include/srsran/phy/channel/rlf.h +++ b/lib/include/srsran/phy/channel/rlf.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/common/phy_common.h b/lib/include/srsran/phy/common/phy_common.h index cc6996f6a9..e839bea17b 100644 --- a/lib/include/srsran/phy/common/phy_common.h +++ b/lib/include/srsran/phy/common/phy_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -198,7 +198,7 @@ typedef enum { SRSRAN_SCS_15KHZ = 0, SRSRAN_SCS_7KHZ5, SRSRAN_SCS_1KHZ25 } srsr #define SRSRAN_FDD_NOF_HARQ (FDD_HARQ_DELAY_DL_MS + FDD_HARQ_DELAY_UL_MS) #define SRSRAN_MAX_HARQ_PROC 15 -#define SRSRAN_NOF_LTE_BANDS 58 +#define SRSRAN_NOF_LTE_BANDS 59 #define SRSRAN_DEFAULT_MAX_FRAMES_PBCH 500 #define SRSRAN_DEFAULT_MAX_FRAMES_PSS 10 @@ -540,7 +540,7 @@ SRSRAN_API char* srsran_nbiot_mode_string(srsran_nbiot_mode_t mode); * Returns a constant string pointer with the ACK/NACK feedback mode * * @param ack_nack_feedback_mode Mode - * @return Returns constant pointer with the text of the mode if succesful, `error` otherwise + * @return Returns constant pointer with the text of the mode if successful, `error` otherwise */ SRSRAN_API const char* srsran_ack_nack_feedback_mode_string(srsran_ack_nack_feedback_mode_t ack_nack_feedback_mode); @@ -548,7 +548,7 @@ SRSRAN_API const char* srsran_ack_nack_feedback_mode_string(srsran_ack_nack_feed * Returns a constant string pointer with the ACK/NACK feedback mode * * @param ack_nack_feedback_mode Mode - * @return Returns constant pointer with the text of the mode if succesful, `error` otherwise + * @return Returns constant pointer with the text of the mode if successful, `error` otherwise */ SRSRAN_API srsran_ack_nack_feedback_mode_t srsran_string_ack_nack_feedback_mode(const char* str); diff --git a/lib/include/srsran/phy/common/phy_common_nr.h b/lib/include/srsran/phy/common/phy_common_nr.h index 310aa72727..bb01b8b4d5 100644 --- a/lib/include/srsran/phy/common/phy_common_nr.h +++ b/lib/include/srsran/phy/common/phy_common_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -221,6 +221,8 @@ typedef enum SRSRAN_API { srsran_coreset_bundle_size_n6, } srsran_coreset_bundle_size_t; +uint32_t pdcch_nr_bundle_size(srsran_coreset_bundle_size_t x); + typedef enum SRSRAN_API { srsran_coreset_precoder_granularity_contiguous = 0, srsran_coreset_precoder_granularity_reg_bundle @@ -356,7 +358,7 @@ typedef enum SRSRAN_API { SRSRAN_SSB_PATTERN_D, // FR2, 120 kHz SCS SRSRAN_SSB_PATTERN_E, // FR2, 240 kHz SCS SRSRAN_SSB_PATTERN_INVALID, -} srsran_ssb_patern_t; +} srsran_ssb_pattern_t; typedef enum SRSRAN_API { SRSRAN_DUPLEX_MODE_FDD = 0, // Paired @@ -394,8 +396,9 @@ typedef struct SRSRAN_API { #define SRSRAN_DEFAULT_CARRIER_NR \ { \ - .pci = 500, .dl_center_frequency_hz = 3.5e9, .ul_center_frequency_hz = 3.5e9, .ssb_center_freq_hz = 3.5e9, \ - .offset_to_carrier = 0, .scs = srsran_subcarrier_spacing_15kHz, .nof_prb = 52, .start = 0, .max_mimo_layers = 1 \ + .pci = 500, .dl_center_frequency_hz = 117000 * 30e3, .ul_center_frequency_hz = 117000 * 30e3, \ + .ssb_center_freq_hz = 3.5e9, .offset_to_carrier = 0, .scs = srsran_subcarrier_spacing_15kHz, .nof_prb = 52, \ + .start = 0, .max_mimo_layers = 1 \ } /** @@ -713,19 +716,39 @@ SRSRAN_API int srsran_coreset_zero(uint32_t n_cell_id, uint32_t idx, srsran_coreset_t* coreset); +/** + * @brief Obtain offset in RBs between CoresetZero and SSB. See TS 38.213, Tables 13-{1,...,10} + * @param idx Index of 13-{1,...10} table + * @param ssb_scs SS/PBCH block subcarrier spacing + * @param pdcch_scs PDCCH subcarrier spacing + * @return offset in RBs, or -1 in case of invalid inputs + */ +SRSRAN_API int +srsran_coreset0_ssb_offset(uint32_t idx, srsran_subcarrier_spacing_t ssb_scs, srsran_subcarrier_spacing_t pdcch_scs); + +/** + * @brief Convert Coreset to string + * + * @param coreset The coreset structure as input + * @param str The string to write to + * @param str_len Maximum string length + * @return SRSRAN_API + */ +SRSRAN_API int srsran_coreset_to_str(srsran_coreset_t* coreset, char* str, uint32_t str_len); + /** * @brief Convert SSB pattern to string * @param pattern * @return a string describing the SSB pattern */ -SRSRAN_API const char* srsran_ssb_pattern_to_str(srsran_ssb_patern_t pattern); +SRSRAN_API const char* srsran_ssb_pattern_to_str(srsran_ssb_pattern_t pattern); /** * @brief Convert string to SSB pattern * @param str String to convert * @return The pattern, SRSRAN_SSB_PATTERN_INVALID if string is invalid */ -SRSRAN_API srsran_ssb_patern_t srsran_ssb_pattern_fom_str(const char* str); +SRSRAN_API srsran_ssb_pattern_t srsran_ssb_pattern_fom_str(const char* str); /** * @brief Compares if two NR carrier structures are equal diff --git a/lib/include/srsran/phy/common/phy_common_sl.h b/lib/include/srsran/phy/common/phy_common_sl.h index 3883b54e80..518352bf68 100644 --- a/lib/include/srsran/phy/common/phy_common_sl.h +++ b/lib/include/srsran/phy/common/phy_common_sl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/common/sequence.h b/lib/include/srsran/phy/common/sequence.h index c0158e81de..50ce69cd19 100644 --- a/lib/include/srsran/phy/common/sequence.h +++ b/lib/include/srsran/phy/common/sequence.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/common/sliv.h b/lib/include/srsran/phy/common/sliv.h index c4483c961a..1a0f127d11 100644 --- a/lib/include/srsran/phy/common/sliv.h +++ b/lib/include/srsran/phy/common/sliv.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/common/timestamp.h b/lib/include/srsran/phy/common/timestamp.h index 4c150fb124..7ce1c72d41 100644 --- a/lib/include/srsran/phy/common/timestamp.h +++ b/lib/include/srsran/phy/common/timestamp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/common/zc_sequence.h b/lib/include/srsran/phy/common/zc_sequence.h index 2d572ef54b..b0a12976b1 100644 --- a/lib/include/srsran/phy/common/zc_sequence.h +++ b/lib/include/srsran/phy/common/zc_sequence.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/dft/dft.h b/lib/include/srsran/phy/dft/dft.h index fe2d19be82..fe4bdf275a 100644 --- a/lib/include/srsran/phy/dft/dft.h +++ b/lib/include/srsran/phy/dft/dft.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/dft/dft_precoding.h b/lib/include/srsran/phy/dft/dft_precoding.h index 93dcc2c903..a7f0450896 100644 --- a/lib/include/srsran/phy/dft/dft_precoding.h +++ b/lib/include/srsran/phy/dft/dft_precoding.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/dft/ofdm.h b/lib/include/srsran/phy/dft/ofdm.h index 6ad33417de..3e8753ec50 100644 --- a/lib/include/srsran/phy/dft/ofdm.h +++ b/lib/include/srsran/phy/dft/ofdm.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -34,6 +34,7 @@ #include #include "srsran/config.h" +#include "srsran/phy/cfr/cfr.h" #include "srsran/phy/common/phy_common.h" #include "srsran/phy/dft/dft.h" @@ -48,19 +49,20 @@ typedef struct SRSRAN_API { // Compulsory parameters uint32_t nof_prb; ///< Number of Resource Block - cf_t* in_buffer; ///< Input bnuffer pointer + cf_t* in_buffer; ///< Input buffer pointer cf_t* out_buffer; ///< Output buffer pointer srsran_cp_t cp; ///< Cyclic prefix type // Optional parameters - srsran_sf_t sf_type; ///< Subframe type, normal or MBSFN - bool normalize; ///< Normalization flag, it divides the output by square root of the symbol size - float freq_shift_f; ///< Frequency shift, normalised by sampling rate (used in UL) - float rx_window_offset; ///< DFT Window offset in CP portion (0-1), RX only - uint32_t symbol_sz; ///< Symbol size, forces a given symbol size for the number of PRB - bool keep_dc; ///< If true, it does not remove the DC - double phase_compensation_hz; ///< Carrier frequency in Hz for phase compensation, set to 0 to disable + srsran_sf_t sf_type; ///< Subframe type, normal or MBSFN + bool normalize; ///< Normalization flag, it divides the output by square root of the symbol size + float freq_shift_f; ///< Frequency shift, normalised by sampling rate (used in UL) + float rx_window_offset; ///< DFT Window offset in CP portion (0-1), RX only + uint32_t symbol_sz; ///< Symbol size, forces a given symbol size for the number of PRB + bool keep_dc; ///< If true, it does not remove the DC + double phase_compensation_hz; ///< Carrier frequency in Hz for phase compensation, set to 0 to disable srsran_scs_t subcarrier_spacing; ///< Subcarrier spacing 15, 7.5 or 1.25 kHz + srsran_cfr_cfg_t cfr_tx_cfg; ///< Tx CFR configuration } srsran_ofdm_cfg_t; /** @@ -86,6 +88,7 @@ typedef struct SRSRAN_API { cf_t* shift_buffer; cf_t* window_offset_buffer; cf_t phase_compensation[SRSRAN_MAX_NSYMB * SRSRAN_NOF_SLOTS_PER_SF]; + srsran_cfr_t tx_cfr; ///< Tx CFR object } srsran_ofdm_t; /** @@ -152,4 +155,6 @@ SRSRAN_API int srsran_ofdm_set_phase_compensation(srsran_ofdm_t* q, double cente SRSRAN_API void srsran_ofdm_set_non_mbsfn_region(srsran_ofdm_t* q, uint8_t non_mbsfn_region); +SRSRAN_API int srsran_ofdm_set_cfr(srsran_ofdm_t* q, srsran_cfr_cfg_t* cfr); + #endif // SRSRAN_OFDM_H diff --git a/lib/include/srsran/phy/enb/enb_dl.h b/lib/include/srsran/phy/enb/enb_dl.h index 6e79e6e389..2c44868bd9 100644 --- a/lib/include/srsran/phy/enb/enb_dl.h +++ b/lib/include/srsran/phy/enb/enb_dl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -64,7 +64,9 @@ typedef struct SRSRAN_API { srsran_dl_sf_cfg_t dl_sf; - cf_t* sf_symbols[SRSRAN_MAX_PORTS]; + srsran_cfr_cfg_t cfr_config; + + cf_t* sf_symbols[SRSRAN_MAX_PORTS]; cf_t* out_buffer[SRSRAN_MAX_PORTS]; srsran_ofdm_t ifft[SRSRAN_MAX_PORTS]; srsran_ofdm_t ifft_mbsfn; @@ -102,6 +104,8 @@ SRSRAN_API void srsran_enb_dl_free(srsran_enb_dl_t* q); SRSRAN_API int srsran_enb_dl_set_cell(srsran_enb_dl_t* q, srsran_cell_t cell); +SRSRAN_API int srsran_enb_dl_set_cfr(srsran_enb_dl_t* q, const srsran_cfr_cfg_t* cfr); + SRSRAN_API bool srsran_enb_dl_location_is_common_ncce(srsran_enb_dl_t* q, const srsran_dci_location_t* loc); SRSRAN_API void srsran_enb_dl_put_base(srsran_enb_dl_t* q, srsran_dl_sf_cfg_t* dl_sf); diff --git a/lib/include/srsran/phy/enb/enb_ul.h b/lib/include/srsran/phy/enb/enb_ul.h index 1a1dbe793b..777c28c35b 100644 --- a/lib/include/srsran/phy/enb/enb_ul.h +++ b/lib/include/srsran/phy/enb/enb_ul.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/block/block.h b/lib/include/srsran/phy/fec/block/block.h index 8b88e1f54e..45cee40373 100644 --- a/lib/include/srsran/phy/fec/block/block.h +++ b/lib/include/srsran/phy/fec/block/block.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/cbsegm.h b/lib/include/srsran/phy/fec/cbsegm.h index be01ed5081..c6244c68e0 100644 --- a/lib/include/srsran/phy/fec/cbsegm.h +++ b/lib/include/srsran/phy/fec/cbsegm.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/convolutional/convcoder.h b/lib/include/srsran/phy/fec/convolutional/convcoder.h index 75ab8d04fb..89d93d5603 100644 --- a/lib/include/srsran/phy/fec/convolutional/convcoder.h +++ b/lib/include/srsran/phy/fec/convolutional/convcoder.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/convolutional/rm_conv.h b/lib/include/srsran/phy/fec/convolutional/rm_conv.h index fb504edc97..d4866484bf 100644 --- a/lib/include/srsran/phy/fec/convolutional/rm_conv.h +++ b/lib/include/srsran/phy/fec/convolutional/rm_conv.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/convolutional/viterbi.h b/lib/include/srsran/phy/fec/convolutional/viterbi.h index 043287fb6f..ec30121b1f 100644 --- a/lib/include/srsran/phy/fec/convolutional/viterbi.h +++ b/lib/include/srsran/phy/fec/convolutional/viterbi.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/crc.h b/lib/include/srsran/phy/fec/crc.h index 58c9b1a649..b9dd73825f 100644 --- a/lib/include/srsran/phy/fec/crc.h +++ b/lib/include/srsran/phy/fec/crc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/ldpc/base_graph.h b/lib/include/srsran/phy/fec/ldpc/base_graph.h index 478feec04e..bc9769b359 100644 --- a/lib/include/srsran/phy/fec/ldpc/base_graph.h +++ b/lib/include/srsran/phy/fec/ldpc/base_graph.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/ldpc/ldpc_common.h b/lib/include/srsran/phy/fec/ldpc/ldpc_common.h index c1b6d6ab74..20295d4b42 100644 --- a/lib/include/srsran/phy/fec/ldpc/ldpc_common.h +++ b/lib/include/srsran/phy/fec/ldpc/ldpc_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/ldpc/ldpc_decoder.h b/lib/include/srsran/phy/fec/ldpc/ldpc_decoder.h index c08ac2fc0d..9164efe83d 100644 --- a/lib/include/srsran/phy/fec/ldpc/ldpc_decoder.h +++ b/lib/include/srsran/phy/fec/ldpc/ldpc_decoder.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/ldpc/ldpc_encoder.h b/lib/include/srsran/phy/fec/ldpc/ldpc_encoder.h index 79022c6be7..90db63cb69 100644 --- a/lib/include/srsran/phy/fec/ldpc/ldpc_encoder.h +++ b/lib/include/srsran/phy/fec/ldpc/ldpc_encoder.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/ldpc/ldpc_rm.h b/lib/include/srsran/phy/fec/ldpc/ldpc_rm.h index a7e349cc84..b3b494c561 100644 --- a/lib/include/srsran/phy/fec/ldpc/ldpc_rm.h +++ b/lib/include/srsran/phy/fec/ldpc/ldpc_rm.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/polar/polar_chanalloc.h b/lib/include/srsran/phy/fec/polar/polar_chanalloc.h index db22c7b01c..d142e3580e 100644 --- a/lib/include/srsran/phy/fec/polar/polar_chanalloc.h +++ b/lib/include/srsran/phy/fec/polar/polar_chanalloc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/polar/polar_code.h b/lib/include/srsran/phy/fec/polar/polar_code.h index 65049f7096..47e22ac719 100644 --- a/lib/include/srsran/phy/fec/polar/polar_code.h +++ b/lib/include/srsran/phy/fec/polar/polar_code.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/polar/polar_decoder.h b/lib/include/srsran/phy/fec/polar/polar_decoder.h index 52f2e22b4f..87088f6657 100644 --- a/lib/include/srsran/phy/fec/polar/polar_decoder.h +++ b/lib/include/srsran/phy/fec/polar/polar_decoder.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/polar/polar_encoder.h b/lib/include/srsran/phy/fec/polar/polar_encoder.h index 205ce93da5..6d30e9a678 100644 --- a/lib/include/srsran/phy/fec/polar/polar_encoder.h +++ b/lib/include/srsran/phy/fec/polar/polar_encoder.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/polar/polar_interleaver.h b/lib/include/srsran/phy/fec/polar/polar_interleaver.h index 8cc1fd5dd0..f6159ec1a7 100644 --- a/lib/include/srsran/phy/fec/polar/polar_interleaver.h +++ b/lib/include/srsran/phy/fec/polar/polar_interleaver.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/polar/polar_rm.h b/lib/include/srsran/phy/fec/polar/polar_rm.h index 9d1afe2acb..694c3b017c 100644 --- a/lib/include/srsran/phy/fec/polar/polar_rm.h +++ b/lib/include/srsran/phy/fec/polar/polar_rm.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/polar/test/polar_sets.h b/lib/include/srsran/phy/fec/polar/test/polar_sets.h index ccdbc8c4ba..c387c550ee 100644 --- a/lib/include/srsran/phy/fec/polar/test/polar_sets.h +++ b/lib/include/srsran/phy/fec/polar/test/polar_sets.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/polar/test/subchannel_allocation.h b/lib/include/srsran/phy/fec/polar/test/subchannel_allocation.h index eaccab5b8d..69ebb3285c 100644 --- a/lib/include/srsran/phy/fec/polar/test/subchannel_allocation.h +++ b/lib/include/srsran/phy/fec/polar/test/subchannel_allocation.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/softbuffer.h b/lib/include/srsran/phy/fec/softbuffer.h index 3f5e66284b..08af4d4fe1 100644 --- a/lib/include/srsran/phy/fec/softbuffer.h +++ b/lib/include/srsran/phy/fec/softbuffer.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -62,7 +62,8 @@ SRSRAN_API int srsran_softbuffer_rx_init(srsran_softbuffer_rx_t* q, uint32_t nof * @param q The Rx soft-buffer pointer * @param max_cb The maximum number of code blocks to allocate * @param max_cb_size The code block size to allocate - * @return It returns SRSRAN_SUCCESS if it allocates the soft-buffer succesfully, otherwise it returns SRSRAN_ERROR code + * @return It returns SRSRAN_SUCCESS if it allocates the soft-buffer successfully, otherwise it returns SRSRAN_ERROR + * code */ SRSRAN_API int srsran_softbuffer_rx_init_guru(srsran_softbuffer_rx_t* q, uint32_t max_cb, uint32_t max_cb_size); @@ -90,7 +91,8 @@ SRSRAN_API int srsran_softbuffer_tx_init(srsran_softbuffer_tx_t* q, uint32_t nof * @param q The Tx soft-buffer pointer * @param max_cb The maximum number of code blocks to allocate * @param max_cb_size The code block size to allocate - * @return It returns SRSRAN_SUCCESS if it allocates the soft-buffer succesfully, otherwise it returns SRSRAN_ERROR code + * @return It returns SRSRAN_SUCCESS if it allocates the soft-buffer successfully, otherwise it returns SRSRAN_ERROR + * code */ SRSRAN_API int srsran_softbuffer_tx_init_guru(srsran_softbuffer_tx_t* q, uint32_t max_cb, uint32_t max_cb_size); diff --git a/lib/include/srsran/phy/fec/turbo/rm_turbo.h b/lib/include/srsran/phy/fec/turbo/rm_turbo.h index 5f7b55d2d2..51eac7f25a 100644 --- a/lib/include/srsran/phy/fec/turbo/rm_turbo.h +++ b/lib/include/srsran/phy/fec/turbo/rm_turbo.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/turbo/tc_interl.h b/lib/include/srsran/phy/fec/turbo/tc_interl.h index aa61ebf817..9d848ba3c4 100644 --- a/lib/include/srsran/phy/fec/turbo/tc_interl.h +++ b/lib/include/srsran/phy/fec/turbo/tc_interl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/turbo/turbocoder.h b/lib/include/srsran/phy/fec/turbo/turbocoder.h index b0047c4522..84b1556253 100644 --- a/lib/include/srsran/phy/fec/turbo/turbocoder.h +++ b/lib/include/srsran/phy/fec/turbo/turbocoder.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/turbo/turbodecoder.h b/lib/include/srsran/phy/fec/turbo/turbodecoder.h index f068edff1e..e958a3587d 100644 --- a/lib/include/srsran/phy/fec/turbo/turbodecoder.h +++ b/lib/include/srsran/phy/fec/turbo/turbodecoder.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/turbo/turbodecoder_gen.h b/lib/include/srsran/phy/fec/turbo/turbodecoder_gen.h index c837b32cf9..3c533ab8c3 100644 --- a/lib/include/srsran/phy/fec/turbo/turbodecoder_gen.h +++ b/lib/include/srsran/phy/fec/turbo/turbodecoder_gen.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/turbo/turbodecoder_impl.h b/lib/include/srsran/phy/fec/turbo/turbodecoder_impl.h index c3c757f913..9a98c52f67 100644 --- a/lib/include/srsran/phy/fec/turbo/turbodecoder_impl.h +++ b/lib/include/srsran/phy/fec/turbo/turbodecoder_impl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/turbo/turbodecoder_iter.h b/lib/include/srsran/phy/fec/turbo/turbodecoder_iter.h index b6deae8b06..c7e075b345 100644 --- a/lib/include/srsran/phy/fec/turbo/turbodecoder_iter.h +++ b/lib/include/srsran/phy/fec/turbo/turbodecoder_iter.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/turbo/turbodecoder_sse.h b/lib/include/srsran/phy/fec/turbo/turbodecoder_sse.h index 8018e94fe8..013951a7eb 100644 --- a/lib/include/srsran/phy/fec/turbo/turbodecoder_sse.h +++ b/lib/include/srsran/phy/fec/turbo/turbodecoder_sse.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/fec/turbo/turbodecoder_win.h b/lib/include/srsran/phy/fec/turbo/turbodecoder_win.h index eee2d787a1..c0172dbde0 100644 --- a/lib/include/srsran/phy/fec/turbo/turbodecoder_win.h +++ b/lib/include/srsran/phy/fec/turbo/turbodecoder_win.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/gnb/gnb_dl.h b/lib/include/srsran/phy/gnb/gnb_dl.h index fe6ea682ef..2b61873ebe 100644 --- a/lib/include/srsran/phy/gnb/gnb_dl.h +++ b/lib/include/srsran/phy/gnb/gnb_dl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/gnb/gnb_ul.h b/lib/include/srsran/phy/gnb/gnb_ul.h index ef54c25b06..d18368aa40 100644 --- a/lib/include/srsran/phy/gnb/gnb_ul.h +++ b/lib/include/srsran/phy/gnb/gnb_ul.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/io/binsource.h b/lib/include/srsran/phy/io/binsource.h index 1b5da7a6a8..d39d466a63 100644 --- a/lib/include/srsran/phy/io/binsource.h +++ b/lib/include/srsran/phy/io/binsource.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/io/filesink.h b/lib/include/srsran/phy/io/filesink.h index 026c8614a6..d9c76a8ed5 100644 --- a/lib/include/srsran/phy/io/filesink.h +++ b/lib/include/srsran/phy/io/filesink.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/io/filesource.h b/lib/include/srsran/phy/io/filesource.h index 71a2cf9532..82a0d5e2b1 100644 --- a/lib/include/srsran/phy/io/filesource.h +++ b/lib/include/srsran/phy/io/filesource.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/io/format.h b/lib/include/srsran/phy/io/format.h index cbd9b6d8d8..f3edf3e53e 100644 --- a/lib/include/srsran/phy/io/format.h +++ b/lib/include/srsran/phy/io/format.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/io/netsink.h b/lib/include/srsran/phy/io/netsink.h index d334c899cf..7977cec850 100644 --- a/lib/include/srsran/phy/io/netsink.h +++ b/lib/include/srsran/phy/io/netsink.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/io/netsource.h b/lib/include/srsran/phy/io/netsource.h index 9a1b9ea3a2..9d01bfd962 100644 --- a/lib/include/srsran/phy/io/netsource.h +++ b/lib/include/srsran/phy/io/netsource.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/mimo/layermap.h b/lib/include/srsran/phy/mimo/layermap.h index bab2c655ed..45e2f31368 100644 --- a/lib/include/srsran/phy/mimo/layermap.h +++ b/lib/include/srsran/phy/mimo/layermap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/mimo/precoding.h b/lib/include/srsran/phy/mimo/precoding.h index 5168407dea..11c4b443ce 100644 --- a/lib/include/srsran/phy/mimo/precoding.h +++ b/lib/include/srsran/phy/mimo/precoding.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/modem/demod_hard.h b/lib/include/srsran/phy/modem/demod_hard.h index c466f100d3..f6fb02567b 100644 --- a/lib/include/srsran/phy/modem/demod_hard.h +++ b/lib/include/srsran/phy/modem/demod_hard.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/modem/demod_soft.h b/lib/include/srsran/phy/modem/demod_soft.h index 052e94319f..307bbf2647 100644 --- a/lib/include/srsran/phy/modem/demod_soft.h +++ b/lib/include/srsran/phy/modem/demod_soft.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/modem/evm.h b/lib/include/srsran/phy/modem/evm.h index 2f464ee000..9580af82d2 100644 --- a/lib/include/srsran/phy/modem/evm.h +++ b/lib/include/srsran/phy/modem/evm.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/modem/mod.h b/lib/include/srsran/phy/modem/mod.h index 22aa05873f..4efaaabcca 100644 --- a/lib/include/srsran/phy/modem/mod.h +++ b/lib/include/srsran/phy/modem/mod.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/modem/modem_table.h b/lib/include/srsran/phy/modem/modem_table.h index c6f0e13e94..bd66677e9f 100644 --- a/lib/include/srsran/phy/modem/modem_table.h +++ b/lib/include/srsran/phy/modem/modem_table.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/cqi.h b/lib/include/srsran/phy/phch/cqi.h index fbd1efdff2..5f145b1510 100644 --- a/lib/include/srsran/phy/phch/cqi.h +++ b/lib/include/srsran/phy/phch/cqi.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/csi.h b/lib/include/srsran/phy/phch/csi.h index d5adae971d..cfc2345823 100644 --- a/lib/include/srsran/phy/phch/csi.h +++ b/lib/include/srsran/phy/phch/csi.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/csi_cfg.h b/lib/include/srsran/phy/phch/csi_cfg.h index e2465d3bfa..fde3908283 100644 --- a/lib/include/srsran/phy/phch/csi_cfg.h +++ b/lib/include/srsran/phy/phch/csi_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/dci.h b/lib/include/srsran/phy/phch/dci.h index 64f8e50ca0..97d0624c78 100644 --- a/lib/include/srsran/phy/phch/dci.h +++ b/lib/include/srsran/phy/phch/dci.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -79,7 +79,6 @@ typedef struct SRSRAN_API { } srsran_dci_tb_t; typedef struct SRSRAN_API { - uint16_t rnti; srsran_dci_format_t format; srsran_dci_location_t location; @@ -103,10 +102,10 @@ typedef struct SRSRAN_API { bool power_offset; uint8_t tpc_pucch; - // RA order - bool is_ra_order; - uint32_t ra_preamble; - uint32_t ra_mask_idx; + // PDCCH order + bool is_pdcch_order; + uint32_t preamble_idx; + uint32_t prach_mask_idx; // Release 10 uint32_t cif; @@ -130,7 +129,6 @@ typedef struct SRSRAN_API { /** Unpacked DCI Format0 message */ typedef struct SRSRAN_API { - uint16_t rnti; srsran_dci_format_t format; srsran_dci_location_t location; diff --git a/lib/include/srsran/phy/phch/dci_nbiot.h b/lib/include/srsran/phy/phch/dci_nbiot.h index 12798e8c75..3c3dfd7439 100644 --- a/lib/include/srsran/phy/phch/dci_nbiot.h +++ b/lib/include/srsran/phy/phch/dci_nbiot.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/dci_nr.h b/lib/include/srsran/phy/phch/dci_nr.h index 8a21723eec..b371bfea3a 100644 --- a/lib/include/srsran/phy/phch/dci_nr.h +++ b/lib/include/srsran/phy/phch/dci_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/harq_ack.h b/lib/include/srsran/phy/phch/harq_ack.h index 32f8fb73b6..eac4e10e7f 100644 --- a/lib/include/srsran/phy/phch/harq_ack.h +++ b/lib/include/srsran/phy/phch/harq_ack.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/harq_ack_cfg.h b/lib/include/srsran/phy/phch/harq_ack_cfg.h index abc41f7ece..83ca3e91f4 100644 --- a/lib/include/srsran/phy/phch/harq_ack_cfg.h +++ b/lib/include/srsran/phy/phch/harq_ack_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -42,6 +42,7 @@ typedef struct { uint32_t pid; ///< HARQ process identifier uint16_t rnti; uint32_t pucch_resource_id; + uint32_t n_cce; } srsran_harq_ack_resource_t; /** diff --git a/lib/include/srsran/phy/phch/mib_sl.h b/lib/include/srsran/phy/phch/mib_sl.h index 4f174c365c..7645096926 100644 --- a/lib/include/srsran/phy/phch/mib_sl.h +++ b/lib/include/srsran/phy/phch/mib_sl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/npbch.h b/lib/include/srsran/phy/phch/npbch.h index d517d3ddae..533af1ac76 100644 --- a/lib/include/srsran/phy/phch/npbch.h +++ b/lib/include/srsran/phy/phch/npbch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -58,7 +58,7 @@ typedef struct { * * Reference: 3GPP TS 36.211 version 13.2.0 Release 13 Sec. 10.2.4 */ -typedef struct SRS_API { +typedef struct SRSRAN_API { srsran_nbiot_cell_t cell; uint32_t frame_idx; diff --git a/lib/include/srsran/phy/phch/npdcch.h b/lib/include/srsran/phy/phch/npdcch.h index 0554f7d3e1..6d3d81557f 100644 --- a/lib/include/srsran/phy/phch/npdcch.h +++ b/lib/include/srsran/phy/phch/npdcch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/npdsch.h b/lib/include/srsran/phy/phch/npdsch.h index 7e9fdaad5b..10076f0aeb 100644 --- a/lib/include/srsran/phy/phch/npdsch.h +++ b/lib/include/srsran/phy/phch/npdsch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/npdsch_cfg.h b/lib/include/srsran/phy/phch/npdsch_cfg.h index f4d6f6d2bf..0c606a3a65 100644 --- a/lib/include/srsran/phy/phch/npdsch_cfg.h +++ b/lib/include/srsran/phy/phch/npdsch_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pbch.h b/lib/include/srsran/phy/phch/pbch.h index 7796581fc3..70134a9a5f 100644 --- a/lib/include/srsran/phy/phch/pbch.h +++ b/lib/include/srsran/phy/phch/pbch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pbch_msg_nr.h b/lib/include/srsran/phy/phch/pbch_msg_nr.h index fc82344e74..081b175135 100644 --- a/lib/include/srsran/phy/phch/pbch_msg_nr.h +++ b/lib/include/srsran/phy/phch/pbch_msg_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pbch_nr.h b/lib/include/srsran/phy/phch/pbch_nr.h index 0c5460c380..923d8f1c2b 100644 --- a/lib/include/srsran/phy/phch/pbch_nr.h +++ b/lib/include/srsran/phy/phch/pbch_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pcfich.h b/lib/include/srsran/phy/phch/pcfich.h index 57d77f442e..640ad2a150 100644 --- a/lib/include/srsran/phy/phch/pcfich.h +++ b/lib/include/srsran/phy/phch/pcfich.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pdcch.h b/lib/include/srsran/phy/phch/pdcch.h index b9682309dc..e201133597 100644 --- a/lib/include/srsran/phy/phch/pdcch.h +++ b/lib/include/srsran/phy/phch/pdcch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pdcch_cfg_nr.h b/lib/include/srsran/phy/phch/pdcch_cfg_nr.h index b4e80e9cd7..e82459b46f 100644 --- a/lib/include/srsran/phy/phch/pdcch_cfg_nr.h +++ b/lib/include/srsran/phy/phch/pdcch_cfg_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pdcch_nr.h b/lib/include/srsran/phy/phch/pdcch_nr.h index e595aad02e..ebf6fc8984 100644 --- a/lib/include/srsran/phy/phch/pdcch_nr.h +++ b/lib/include/srsran/phy/phch/pdcch_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pdsch.h b/lib/include/srsran/phy/phch/pdsch.h index 9f037e4bf9..6018c5bb62 100644 --- a/lib/include/srsran/phy/phch/pdsch.h +++ b/lib/include/srsran/phy/phch/pdsch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pdsch_cfg.h b/lib/include/srsran/phy/phch/pdsch_cfg.h index af7a6efe2d..7d54caff1a 100644 --- a/lib/include/srsran/phy/phch/pdsch_cfg.h +++ b/lib/include/srsran/phy/phch/pdsch_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pdsch_nr.h b/lib/include/srsran/phy/phch/pdsch_nr.h index 7e443a4baa..ba5fda674a 100644 --- a/lib/include/srsran/phy/phch/pdsch_nr.h +++ b/lib/include/srsran/phy/phch/pdsch_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/phch_cfg_nr.h b/lib/include/srsran/phy/phch/phch_cfg_nr.h index 5e1a407891..f8318e3854 100644 --- a/lib/include/srsran/phy/phch/phch_cfg_nr.h +++ b/lib/include/srsran/phy/phch/phch_cfg_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -86,6 +86,8 @@ typedef struct { srsran_dmrs_sch_typeA_pos_t typeA_pos; bool lte_CRS_to_match_around; + uint32_t reference_point_k_rb; + /// Parameters provided by FeatureSetDownlink-v1540 bool additional_DMRS_DL_Alt; diff --git a/lib/include/srsran/phy/phch/phich.h b/lib/include/srsran/phy/phch/phich.h index 46ca69ae39..ec307a391d 100644 --- a/lib/include/srsran/phy/phch/phich.h +++ b/lib/include/srsran/phy/phch/phich.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pmch.h b/lib/include/srsran/phy/phch/pmch.h index f367b25c61..4cb82082fe 100644 --- a/lib/include/srsran/phy/phch/pmch.h +++ b/lib/include/srsran/phy/phch/pmch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/prach.h b/lib/include/srsran/phy/phch/prach.h index a1a0927ccb..a7bce8df23 100644 --- a/lib/include/srsran/phy/phch/prach.h +++ b/lib/include/srsran/phy/phch/prach.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/psbch.h b/lib/include/srsran/phy/phch/psbch.h index 669da20a2d..d27d0b35dd 100644 --- a/lib/include/srsran/phy/phch/psbch.h +++ b/lib/include/srsran/phy/phch/psbch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pscch.h b/lib/include/srsran/phy/phch/pscch.h index c0945d90eb..651be3f221 100644 --- a/lib/include/srsran/phy/phch/pscch.h +++ b/lib/include/srsran/phy/phch/pscch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pssch.h b/lib/include/srsran/phy/phch/pssch.h index 2683c7cd44..85227671df 100644 --- a/lib/include/srsran/phy/phch/pssch.h +++ b/lib/include/srsran/phy/phch/pssch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pucch.h b/lib/include/srsran/phy/phch/pucch.h index 711ec0bc17..7de97109f0 100644 --- a/lib/include/srsran/phy/phch/pucch.h +++ b/lib/include/srsran/phy/phch/pucch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -84,6 +84,8 @@ typedef struct SRSRAN_API { srsran_uci_value_t uci_data; float dmrs_correlation; float snr_db; + float rssi_dbFs; + float ni_dbFs; float correlation; bool detected; diff --git a/lib/include/srsran/phy/phch/pucch_cfg.h b/lib/include/srsran/phy/phch/pucch_cfg.h index ac752c9dac..af42cc2582 100644 --- a/lib/include/srsran/phy/phch/pucch_cfg.h +++ b/lib/include/srsran/phy/phch/pucch_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pucch_cfg_nr.h b/lib/include/srsran/phy/phch/pucch_cfg_nr.h index 04cae47890..51a22cc213 100644 --- a/lib/include/srsran/phy/phch/pucch_cfg_nr.h +++ b/lib/include/srsran/phy/phch/pucch_cfg_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pucch_nr.h b/lib/include/srsran/phy/phch/pucch_nr.h index 6ff847b259..935cbae607 100644 --- a/lib/include/srsran/phy/phch/pucch_nr.h +++ b/lib/include/srsran/phy/phch/pucch_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pucch_proc.h b/lib/include/srsran/phy/phch/pucch_proc.h index fbecd8fd65..f24f6e1c5b 100644 --- a/lib/include/srsran/phy/phch/pucch_proc.h +++ b/lib/include/srsran/phy/phch/pucch_proc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -87,7 +87,7 @@ SRSRAN_API uint32_t srsran_pucch_proc_get_npucch(const srsran_cell_t* cell, * @param uci_cfg uplink control information configuration * @param j selected channel * @param b received bits - * @return Returns SRSRAN_SUCCESS if it can decode it succesfully, SRSRAN_ERROR code otherwise + * @return Returns SRSRAN_SUCCESS if it can decode it successfully, SRSRAN_ERROR code otherwise */ SRSRAN_API int srsran_pucch_cs_get_ack(const srsran_pucch_cfg_t* cfg, const srsran_uci_cfg_t* uci_cfg, diff --git a/lib/include/srsran/phy/phch/pusch.h b/lib/include/srsran/phy/phch/pusch.h index 8ebde349b3..ad6f49035d 100644 --- a/lib/include/srsran/phy/phch/pusch.h +++ b/lib/include/srsran/phy/phch/pusch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pusch_cfg.h b/lib/include/srsran/phy/phch/pusch_cfg.h index 11f4f19bb5..6daebd68e2 100644 --- a/lib/include/srsran/phy/phch/pusch_cfg.h +++ b/lib/include/srsran/phy/phch/pusch_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/pusch_nr.h b/lib/include/srsran/phy/phch/pusch_nr.h index 5c07c85c1f..da5c5f81fc 100644 --- a/lib/include/srsran/phy/phch/pusch_nr.h +++ b/lib/include/srsran/phy/phch/pusch_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/ra.h b/lib/include/srsran/phy/phch/ra.h index fd3165401f..35efb33500 100644 --- a/lib/include/srsran/phy/phch/ra.h +++ b/lib/include/srsran/phy/phch/ra.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/ra_dl.h b/lib/include/srsran/phy/phch/ra_dl.h index 89109551c9..64d69d7194 100644 --- a/lib/include/srsran/phy/phch/ra_dl.h +++ b/lib/include/srsran/phy/phch/ra_dl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/ra_dl_nr.h b/lib/include/srsran/phy/phch/ra_dl_nr.h index a460a7be88..0945f1ee58 100644 --- a/lib/include/srsran/phy/phch/ra_dl_nr.h +++ b/lib/include/srsran/phy/phch/ra_dl_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/ra_nbiot.h b/lib/include/srsran/phy/phch/ra_nbiot.h index 82786bfb9c..922fbf0bc1 100644 --- a/lib/include/srsran/phy/phch/ra_nbiot.h +++ b/lib/include/srsran/phy/phch/ra_nbiot.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/ra_nr.h b/lib/include/srsran/phy/phch/ra_nr.h index 8036562146..3f6eef2e5d 100644 --- a/lib/include/srsran/phy/phch/ra_nr.h +++ b/lib/include/srsran/phy/phch/ra_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -159,4 +159,57 @@ SRSRAN_API int srsran_ra_ul_set_grant_uci_nr(const srsran_carrier_nr_t* carri */ SRSRAN_API uint32_t srsran_ra_nr_type1_riv(uint32_t N_rb, uint32_t start_rb, uint32_t length_rb); +/** + * @brief Returns the MCS corresponding to CQI + * + * Mapping is performed as: return the MCS that has the closest spectral efficiency to that of the CQI + * + * @remark Implements mapping based on TS 38.214, MCS Tables 5.1.3.1-1, 5.1.3.1-2, 5.1.3.1-3 and CQI Tables 5.2.2.1-2, + * Table 5.2.2.1-3, 5.2.2.1-4 + * @param cqi CQI value + * @param cqi_table_idx CQI table index + * @param mcs_table MCS table parameter + * @param dci_format DCI format + * @param search_space_type Seach Space type + * @param rnti_type RNTI type + * @return The MCS index + */ +SRSRAN_API int srsran_ra_nr_cqi_to_mcs(uint8_t cqi, + srsran_csi_cqi_table_t cqi_table_idx, + srsran_mcs_table_t mcs_table, + srsran_dci_format_nr_t dci_format, + srsran_search_space_type_t search_space_type, + srsran_rnti_type_t rnti_type); + +/** + * @brief Returns the Spectral Efficiency corresponding to CQI + * + * Mapping is performed as: return the MCS that has the closest spectral efficiency to that of the CQI + * + * @remark Implements mapping based on TS 38.214, CQI Tables 5.2.2.1-2, Table 5.2.2.1-3, 5.2.2.1-4 + * @param cqi CQI value + * @param cqi_table_idx CQI table index + * @return The Spectral Efficiency + */ +SRSRAN_API double srsran_ra_nr_cqi_to_se(uint8_t cqi, srsran_csi_cqi_table_t cqi_table_idx); + +/** + * @brief Returns the MCS corresponding to Spectral Efficiency + * + * Mapping is performed as: return the greatest MCS with an SE lower than or equal to target SE + * + * @remark Implements mapping based on TS 38.214, MCS Tables 5.1.3.1-1, 5.1.3.1-2, 5.1.3.1-3 + * @param se_target Target Spectral efficiency to be mapped into MCS + * @param mcs_table MCS table parameter + * @param dci_format DCI format + * @param search_space_type Seach Space type + * @param rnti_type RNTI type + * @return The MCS index + */ +SRSRAN_API int srsran_ra_nr_se_to_mcs(double se_target, + srsran_mcs_table_t mcs_table, + srsran_dci_format_nr_t dci_format, + srsran_search_space_type_t search_space_type, + srsran_rnti_type_t rnti_type); + #endif // SRSRAN_RA_NR_H diff --git a/lib/include/srsran/phy/phch/ra_sl.h b/lib/include/srsran/phy/phch/ra_sl.h index ddb81fa250..9e8b2d0915 100644 --- a/lib/include/srsran/phy/phch/ra_sl.h +++ b/lib/include/srsran/phy/phch/ra_sl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/ra_ul.h b/lib/include/srsran/phy/phch/ra_ul.h index 3c9e78218e..7c2ac39a3b 100644 --- a/lib/include/srsran/phy/phch/ra_ul.h +++ b/lib/include/srsran/phy/phch/ra_ul.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/ra_ul_nr.h b/lib/include/srsran/phy/phch/ra_ul_nr.h index 6ddecd0d48..959d431386 100644 --- a/lib/include/srsran/phy/phch/ra_ul_nr.h +++ b/lib/include/srsran/phy/phch/ra_ul_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -128,11 +128,13 @@ SRSRAN_API int srsran_ra_ul_nr_freq(const srsran_carrier_nr_t* carrier, * @brief Selects a valid PUCCH resource for transmission * @param pucch_cfg PUCCH configuration from upper layers * @param uci_cfg Uplink Control information configuration (and PDCCH context) + * @param N_bwp_sz Uplink BWP size in nof_prb * @param[out] resource Selected resource for transmitting PUCCH * @return SRSRAN_SUCCESS if provided configuration is valid, SRSRAN_ERROR code otherwise */ SRSRAN_API int srsran_ra_ul_nr_pucch_resource(const srsran_pucch_nr_hl_cfg_t* pucch_cfg, const srsran_uci_cfg_nr_t* uci_cfg, + uint32_t N_bwp_sz, srsran_pucch_nr_resource_t* resource); /** diff --git a/lib/include/srsran/phy/phch/regs.h b/lib/include/srsran/phy/phch/regs.h index 3e56d7ac1e..915a9dbce6 100644 --- a/lib/include/srsran/phy/phch/regs.h +++ b/lib/include/srsran/phy/phch/regs.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/sch.h b/lib/include/srsran/phy/phch/sch.h index 3ecd799a33..63d542b4e3 100644 --- a/lib/include/srsran/phy/phch/sch.h +++ b/lib/include/srsran/phy/phch/sch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/sch_cfg_nr.h b/lib/include/srsran/phy/phch/sch_cfg_nr.h index 56c5824377..0e200c7dac 100644 --- a/lib/include/srsran/phy/phch/sch_cfg_nr.h +++ b/lib/include/srsran/phy/phch/sch_cfg_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/sch_nr.h b/lib/include/srsran/phy/phch/sch_nr.h index 60896d4dab..d9596b67f8 100644 --- a/lib/include/srsran/phy/phch/sch_nr.h +++ b/lib/include/srsran/phy/phch/sch_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/sci.h b/lib/include/srsran/phy/phch/sci.h index a08238d530..373942fbf7 100644 --- a/lib/include/srsran/phy/phch/sci.h +++ b/lib/include/srsran/phy/phch/sci.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/uci.h b/lib/include/srsran/phy/phch/uci.h index f9adcca2bc..10b1544e66 100644 --- a/lib/include/srsran/phy/phch/uci.h +++ b/lib/include/srsran/phy/phch/uci.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/uci_cfg.h b/lib/include/srsran/phy/phch/uci_cfg.h index c01a64adad..cb59a4596b 100644 --- a/lib/include/srsran/phy/phch/uci_cfg.h +++ b/lib/include/srsran/phy/phch/uci_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/uci_cfg_nr.h b/lib/include/srsran/phy/phch/uci_cfg_nr.h index a135f31f88..fe20ae236b 100644 --- a/lib/include/srsran/phy/phch/uci_cfg_nr.h +++ b/lib/include/srsran/phy/phch/uci_cfg_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/phch/uci_nr.h b/lib/include/srsran/phy/phch/uci_nr.h index a4fb05e407..1075f685cd 100644 --- a/lib/include/srsran/phy/phch/uci_nr.h +++ b/lib/include/srsran/phy/phch/uci_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/resampling/decim.h b/lib/include/srsran/phy/resampling/decim.h index e67a270349..e837b3805d 100644 --- a/lib/include/srsran/phy/resampling/decim.h +++ b/lib/include/srsran/phy/resampling/decim.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/resampling/interp.h b/lib/include/srsran/phy/resampling/interp.h index 2623a6485f..5951fc5bd7 100644 --- a/lib/include/srsran/phy/resampling/interp.h +++ b/lib/include/srsran/phy/resampling/interp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/resampling/resample_arb.h b/lib/include/srsran/phy/resampling/resample_arb.h index ef7f67b0fa..3300699e01 100644 --- a/lib/include/srsran/phy/resampling/resample_arb.h +++ b/lib/include/srsran/phy/resampling/resample_arb.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/resampling/resampler.h b/lib/include/srsran/phy/resampling/resampler.h index da28ff735e..7082f5ebcd 100644 --- a/lib/include/srsran/phy/resampling/resampler.h +++ b/lib/include/srsran/phy/resampling/resampler.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/rf/rf.h b/lib/include/srsran/phy/rf/rf.h index 64150574e8..78aa5c8785 100644 --- a/lib/include/srsran/phy/rf/rf.h +++ b/lib/include/srsran/phy/rf/rf.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "srsran/config.h" @@ -71,12 +72,91 @@ typedef struct { typedef void (*srsran_rf_error_handler_t)(void* arg, srsran_rf_error_t error); +/* RF frontend API */ +typedef struct { + const char* name; + const char* (*srsran_rf_devname)(void* h); + int (*srsran_rf_start_rx_stream)(void* h, bool now); + int (*srsran_rf_stop_rx_stream)(void* h); + void (*srsran_rf_flush_buffer)(void* h); + bool (*srsran_rf_has_rssi)(void* h); + float (*srsran_rf_get_rssi)(void* h); + void (*srsran_rf_suppress_stdout)(void* h); + void (*srsran_rf_register_error_handler)(void* h, srsran_rf_error_handler_t error_handler, void* arg); + int (*srsran_rf_open)(char* args, void** h); + int (*srsran_rf_open_multi)(char* args, void** h, uint32_t nof_channels); + int (*srsran_rf_close)(void* h); + double (*srsran_rf_set_rx_srate)(void* h, double freq); + int (*srsran_rf_set_rx_gain)(void* h, double gain); + int (*srsran_rf_set_rx_gain_ch)(void* h, uint32_t ch, double gain); + int (*srsran_rf_set_tx_gain)(void* h, double gain); + int (*srsran_rf_set_tx_gain_ch)(void* h, uint32_t ch, double gain); + double (*srsran_rf_get_rx_gain)(void* h); + double (*srsran_rf_get_tx_gain)(void* h); + srsran_rf_info_t* (*srsran_rf_get_info)(void* h); + double (*srsran_rf_set_rx_freq)(void* h, uint32_t ch, double freq); + double (*srsran_rf_set_tx_srate)(void* h, double freq); + double (*srsran_rf_set_tx_freq)(void* h, uint32_t ch, double freq); + void (*srsran_rf_get_time)(void* h, time_t* secs, double* frac_secs); + void (*srsran_rf_sync_pps)(void* h); + int (*srsran_rf_recv_with_time)(void* h, + void* data, + uint32_t nsamples, + bool blocking, + time_t* secs, + double* frac_secs); + int (*srsran_rf_recv_with_time_multi)(void* h, + void** data, + uint32_t nsamples, + bool blocking, + time_t* secs, + double* frac_secs); + int (*srsran_rf_send_timed)(void* h, + void* data, + int nsamples, + time_t secs, + double frac_secs, + bool has_time_spec, + bool blocking, + bool is_start_of_burst, + bool is_end_of_burst); + int (*srsran_rf_send_timed_multi)(void* h, + void** data, + int nsamples, + time_t secs, + double frac_secs, + bool has_time_spec, + bool blocking, + bool is_start_of_burst, + bool is_end_of_burst); +} rf_dev_t; + +typedef struct { + const char* plugin_name; + void* dl_handle; + rf_dev_t* rf_api; +} srsran_rf_plugin_t; + +SRSRAN_API int srsran_rf_load_plugins(); + SRSRAN_API int srsran_rf_open(srsran_rf_t* h, char* args); SRSRAN_API int srsran_rf_open_multi(srsran_rf_t* h, char* args, uint32_t nof_channels); SRSRAN_API int srsran_rf_open_devname(srsran_rf_t* h, const char* devname, char* args, uint32_t nof_channels); +/** + * @brief Opens a file-based RF abstraction + * @param[out] rf Device handle + * @param[in] rx_files List of pre-opened FILE* for each RX channel; NULL to disable + * @param[in] tx_files List of pre-opened FILE* for each TX channel; NULL to disable + * @param[in] nof_channels Number of channels per direction + * @param[in] base_srate Sample rate of RX and TX files + * @return SRSRAN_SUCCESS on success, otherwise error code + */ +SRSRAN_API int +srsran_rf_open_file(srsran_rf_t* rf, FILE** rx_files, FILE** tx_files, uint32_t nof_channels, uint32_t base_srate); + SRSRAN_API const char* srsran_rf_name(srsran_rf_t* h); SRSRAN_API int srsran_rf_start_gain_thread(srsran_rf_t* rf, bool tx_gain_same_rx); diff --git a/lib/include/srsran/phy/rf/rf_utils.h b/lib/include/srsran/phy/rf/rf_utils.h index 0e7fe0f758..b5e95752dc 100644 --- a/lib/include/srsran/phy/rf/rf_utils.h +++ b/lib/include/srsran/phy/rf/rf_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/scrambling/scrambling.h b/lib/include/srsran/phy/scrambling/scrambling.h index 140a4caef5..c5f96736cf 100644 --- a/lib/include/srsran/phy/scrambling/scrambling.h +++ b/lib/include/srsran/phy/scrambling/scrambling.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/cfo.h b/lib/include/srsran/phy/sync/cfo.h index b1874e791e..cfc3b68668 100644 --- a/lib/include/srsran/phy/sync/cfo.h +++ b/lib/include/srsran/phy/sync/cfo.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/cp.h b/lib/include/srsran/phy/sync/cp.h index 41cd61600a..39d2359be6 100644 --- a/lib/include/srsran/phy/sync/cp.h +++ b/lib/include/srsran/phy/sync/cp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/npss.h b/lib/include/srsran/phy/sync/npss.h index 8402ee2f1b..d932e6e0ea 100644 --- a/lib/include/srsran/phy/sync/npss.h +++ b/lib/include/srsran/phy/sync/npss.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/nsss.h b/lib/include/srsran/phy/sync/nsss.h index 1d31e7f856..63a994383d 100644 --- a/lib/include/srsran/phy/sync/nsss.h +++ b/lib/include/srsran/phy/sync/nsss.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/pss.h b/lib/include/srsran/phy/sync/pss.h index 2d665c9d69..49737d1cfa 100644 --- a/lib/include/srsran/phy/sync/pss.h +++ b/lib/include/srsran/phy/sync/pss.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/pss_nr.h b/lib/include/srsran/phy/sync/pss_nr.h index 81e96e1ebb..2fbfb3b967 100644 --- a/lib/include/srsran/phy/sync/pss_nr.h +++ b/lib/include/srsran/phy/sync/pss_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/psss.h b/lib/include/srsran/phy/sync/psss.h index c7b827b96e..2c495674fd 100644 --- a/lib/include/srsran/phy/sync/psss.h +++ b/lib/include/srsran/phy/sync/psss.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/refsignal_dl_sync.h b/lib/include/srsran/phy/sync/refsignal_dl_sync.h index dda32829db..2c6301d86c 100644 --- a/lib/include/srsran/phy/sync/refsignal_dl_sync.h +++ b/lib/include/srsran/phy/sync/refsignal_dl_sync.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/sfo.h b/lib/include/srsran/phy/sync/sfo.h index a5bb4729b4..9938962ea4 100644 --- a/lib/include/srsran/phy/sync/sfo.h +++ b/lib/include/srsran/phy/sync/sfo.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/ssb.h b/lib/include/srsran/phy/sync/ssb.h index d640ff8981..59ad75f534 100644 --- a/lib/include/srsran/phy/sync/ssb.h +++ b/lib/include/srsran/phy/sync/ssb.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -70,7 +70,7 @@ typedef struct SRSRAN_API { double center_freq_hz; ///< Base-band center frequency in Hz double ssb_freq_hz; ///< SSB center frequency srsran_subcarrier_spacing_t scs; ///< SSB configured Subcarrier spacing - srsran_ssb_patern_t pattern; ///< SSB pattern as defined in TS 38.313 section 4.1 Cell search + srsran_ssb_pattern_t pattern; ///< SSB pattern as defined in TS 38.313 section 4.1 Cell search srsran_duplex_mode_t duplex_mode; ///< Set to true if the spectrum is paired (FDD) uint32_t periodicity_ms; ///< SSB periodicity in ms float beta_pss; ///< PSS power allocation @@ -98,7 +98,7 @@ typedef struct SRSRAN_API { uint32_t corr_sz; ///< Correlation size uint32_t corr_window; ///< Correlation window length uint32_t ssb_sz; ///< SSB size in samples at the configured sampling rate - int32_t f_offset; ///< Current SSB integer frequency offset (multiple of SCS) + int32_t f_offset; ///< SSB integer frequency offset (multiple of SCS) between DC and the SSB center uint32_t cp_sz; ///< CP length for the given symbol size /// Other parameters @@ -125,9 +125,10 @@ typedef struct SRSRAN_API { * @note if pbch.crc is true, SSB transmission is found and decoded. Otherwise, no SSB transmission has been decoded */ typedef struct { - uint32_t N_id; ///< Most suitable physical cell identifier - uint32_t t_offset; ///< Time offset in the input samples - srsran_pbch_msg_nr_t pbch_msg; ///< Physical broadcast channel message of the most suitable SSB candidate + uint32_t N_id; ///< Most suitable physical cell identifier + uint32_t t_offset; ///< Time offset in the input samples + srsran_pbch_msg_nr_t pbch_msg; ///< Physical broadcast channel message of the most suitable SSB candidate + srsran_csi_trs_measurements_t measurements; ///< Measurements } srsran_ssb_search_res_t; /** @@ -151,22 +152,6 @@ SRSRAN_API void srsran_ssb_free(srsran_ssb_t* q); * @return SRSRAN_SUCCESS if the parameters are valid, SRSRAN_ERROR code otherwise */ SRSRAN_API int srsran_ssb_set_cfg(srsran_ssb_t* q, const srsran_ssb_cfg_t* cfg); -/** - * @brief Decodes PBCH in the given time domain signal - * @note It currently expects an input buffer of half radio frame - * @param q SSB object - * @param N_id Physical Cell Identifier - * @param n_hf Number of hald radio frame, 0 or 1 - * @param ssb_idx SSB candidate index - * @param in Input baseband buffer - * @return SRSRAN_SUCCESS if the parameters are valid, SRSRAN_ERROR code otherwise - */ -SRSRAN_API int srsran_ssb_decode_pbch(srsran_ssb_t* q, - uint32_t N_id, - uint32_t n_hf, - uint32_t ssb_idx, - const cf_t* in, - srsran_pbch_msg_nr_t* msg); /** * @brief Searches for an SSB transmission and decodes the PBCH message @@ -186,6 +171,21 @@ SRSRAN_API int srsran_ssb_search(srsran_ssb_t* q, const cf_t* in, uint32_t nof_s */ SRSRAN_API bool srsran_ssb_send(srsran_ssb_t* q, uint32_t sf_idx); +/** + * + * @param q SSB object + * @param N_id Physical Cell Identifier + * @param msg NR PBCH message to transmit + * @param re_grid Resource grid pointer + * @param grid_sz_rb Resource grid bandwidth in subcarriers + * @return SRSRAN_SUCCES if inputs and data are correct, otherwise SRSRAN_ERROR code + */ +SRSRAN_API int srsran_ssb_put_grid(srsran_ssb_t* q, + uint32_t N_id, + const srsran_pbch_msg_nr_t* msg, + cf_t* re_grid, + uint32_t grid_bw_sc); + /** * @brief Adds SSB to a given signal in time domain * @param q SSB object @@ -196,6 +196,41 @@ SRSRAN_API bool srsran_ssb_send(srsran_ssb_t* q, uint32_t sf_idx); SRSRAN_API int srsran_ssb_add(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* msg, const cf_t* in, cf_t* out); +/** + * @brief Decodes PBCH in the given time domain signal + * @note It currently expects an input buffer of half radio frame + * @param q SSB object + * @param N_id Physical Cell Identifier + * @param n_hf Number of hald radio frame, 0 or 1 + * @param ssb_idx SSB candidate index + * @param in Input baseband buffer + * @return SRSRAN_SUCCESS if the parameters are valid, SRSRAN_ERROR code otherwise + */ +SRSRAN_API int srsran_ssb_decode_pbch(srsran_ssb_t* q, + uint32_t N_id, + uint32_t n_hf, + uint32_t ssb_idx, + const cf_t* grid, + srsran_pbch_msg_nr_t* msg); + +/** + * @brief Decodes PBCH in the given resource grid + * @param q SSB object + * @param N_id Physical Cell Identifier + * @param n_hf Number of hald radio frame, 0 or 1 + * @param ssb_idx SSB candidate index + * @param grid Input resource grid buffer + * @param grid_sz_rb Resource grid bandwidth in subcarriers + * @return SRSRAN_SUCCESS if the parameters are valid, SRSRAN_ERROR code otherwise + */ +SRSRAN_API int srsran_ssb_decode_grid(srsran_ssb_t* q, + uint32_t N_id, + uint32_t n_hf, + uint32_t ssb_idx, + const cf_t* in, + uint32_t grid_sz_rb, + srsran_pbch_msg_nr_t* msg); + /** * @brief Perform cell search and measurement * @note This function assumes the SSB transmission is aligned with the input base-band signal @@ -277,4 +312,6 @@ SRSRAN_API uint32_t srsran_ssb_candidate_sf_idx(const srsran_ssb_t* q, uint32_t */ SRSRAN_API uint32_t srsran_ssb_candidate_sf_offset(const srsran_ssb_t* q, uint32_t ssb_idx); +SRSRAN_API uint32_t srsran_ssb_cfg_to_str(const srsran_ssb_cfg_t* cfg, char* str, uint32_t str_len); + #endif // SRSRAN_SSB_H diff --git a/lib/include/srsran/phy/sync/sss.h b/lib/include/srsran/phy/sync/sss.h index bbc485189a..1b610aced5 100644 --- a/lib/include/srsran/phy/sync/sss.h +++ b/lib/include/srsran/phy/sync/sss.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/sss_nr.h b/lib/include/srsran/phy/sync/sss_nr.h index 4d5a92ee7a..d53bdcc6f3 100644 --- a/lib/include/srsran/phy/sync/sss_nr.h +++ b/lib/include/srsran/phy/sync/sss_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/ssss.h b/lib/include/srsran/phy/sync/ssss.h index c1e306743f..83ccea1355 100644 --- a/lib/include/srsran/phy/sync/ssss.h +++ b/lib/include/srsran/phy/sync/ssss.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/sync.h b/lib/include/srsran/phy/sync/sync.h index 4c74c792bd..684137f600 100644 --- a/lib/include/srsran/phy/sync/sync.h +++ b/lib/include/srsran/phy/sync/sync.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/sync/sync_nbiot.h b/lib/include/srsran/phy/sync/sync_nbiot.h index e49719de29..3e0e160ab5 100644 --- a/lib/include/srsran/phy/sync/sync_nbiot.h +++ b/lib/include/srsran/phy/sync/sync_nbiot.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_cell_search.h b/lib/include/srsran/phy/ue/ue_cell_search.h index 4f9d764a71..23b0b10ae1 100644 --- a/lib/include/srsran/phy/ue/ue_cell_search.h +++ b/lib/include/srsran/phy/ue/ue_cell_search.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_cell_search_nbiot.h b/lib/include/srsran/phy/ue/ue_cell_search_nbiot.h index bfaac0daf3..4417902681 100644 --- a/lib/include/srsran/phy/ue/ue_cell_search_nbiot.h +++ b/lib/include/srsran/phy/ue/ue_cell_search_nbiot.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_dl.h b/lib/include/srsran/phy/ue/ue_dl.h index 20e41a2094..48f63d7666 100644 --- a/lib/include/srsran/phy/ue/ue_dl.h +++ b/lib/include/srsran/phy/ue/ue_dl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_dl_nbiot.h b/lib/include/srsran/phy/ue/ue_dl_nbiot.h index 3a561d8d29..93ceea83cd 100644 --- a/lib/include/srsran/phy/ue/ue_dl_nbiot.h +++ b/lib/include/srsran/phy/ue/ue_dl_nbiot.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_dl_nr.h b/lib/include/srsran/phy/ue/ue_dl_nr.h index a4dead0291..a735d4cdb9 100644 --- a/lib/include/srsran/phy/ue/ue_dl_nr.h +++ b/lib/include/srsran/phy/ue/ue_dl_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_mib.h b/lib/include/srsran/phy/ue/ue_mib.h index b8564c9008..a150d24345 100644 --- a/lib/include/srsran/phy/ue/ue_mib.h +++ b/lib/include/srsran/phy/ue/ue_mib.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_mib_nbiot.h b/lib/include/srsran/phy/ue/ue_mib_nbiot.h index 84b985089a..e6f4ecfd0d 100644 --- a/lib/include/srsran/phy/ue/ue_mib_nbiot.h +++ b/lib/include/srsran/phy/ue/ue_mib_nbiot.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_mib_sl.h b/lib/include/srsran/phy/ue/ue_mib_sl.h index 7fbf2fa7ba..9d4c9a03c1 100644 --- a/lib/include/srsran/phy/ue/ue_mib_sl.h +++ b/lib/include/srsran/phy/ue/ue_mib_sl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_phy.h b/lib/include/srsran/phy/ue/ue_phy.h index ba50a0e08d..505706f995 100644 --- a/lib/include/srsran/phy/ue/ue_phy.h +++ b/lib/include/srsran/phy/ue/ue_phy.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_sync.h b/lib/include/srsran/phy/ue/ue_sync.h index 83d5c623e1..9c208b3491 100644 --- a/lib/include/srsran/phy/ue/ue_sync.h +++ b/lib/include/srsran/phy/ue/ue_sync.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_sync_nbiot.h b/lib/include/srsran/phy/ue/ue_sync_nbiot.h index ee8cb0c2f4..6ca2923046 100644 --- a/lib/include/srsran/phy/ue/ue_sync_nbiot.h +++ b/lib/include/srsran/phy/ue/ue_sync_nbiot.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/ue/ue_sync_nr.h b/lib/include/srsran/phy/ue/ue_sync_nr.h index a6ab192ff0..5aac74dc7d 100644 --- a/lib/include/srsran/phy/ue/ue_sync_nr.h +++ b/lib/include/srsran/phy/ue/ue_sync_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -62,7 +62,7 @@ typedef struct SRSRAN_API { */ typedef struct SRSRAN_API { srsran_ssb_cfg_t ssb; ///< SSB configuration - uint32_t N_id; ///< Physicall cell identifier + uint32_t N_id; ///< Physical cell identifier } srsran_ue_sync_nr_cfg_t; /** diff --git a/lib/include/srsran/phy/ue/ue_ul.h b/lib/include/srsran/phy/ue/ue_ul.h index 03f883d6e6..52a6f61ddc 100644 --- a/lib/include/srsran/phy/ue/ue_ul.h +++ b/lib/include/srsran/phy/ue/ue_ul.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -108,6 +108,8 @@ typedef struct SRSRAN_API { srsran_ra_ul_pusch_hopping_t hopping; + srsran_cfr_cfg_t cfr_config; + cf_t* out_buffer; cf_t* refsignal; cf_t* srs_signal; @@ -121,6 +123,8 @@ SRSRAN_API void srsran_ue_ul_free(srsran_ue_ul_t* q); SRSRAN_API int srsran_ue_ul_set_cell(srsran_ue_ul_t* q, srsran_cell_t cell); +SRSRAN_API int srsran_ue_ul_set_cfr(srsran_ue_ul_t* q, const srsran_cfr_cfg_t* cfr); + SRSRAN_API int srsran_ue_ul_pregen_signals(srsran_ue_ul_t* q, srsran_ue_ul_cfg_t* cfg); SRSRAN_API int srsran_ue_ul_dci_to_pusch_grant(srsran_ue_ul_t* q, diff --git a/lib/include/srsran/phy/ue/ue_ul_nr.h b/lib/include/srsran/phy/ue/ue_ul_nr.h index 3a89aea74b..a543d1c5c3 100644 --- a/lib/include/srsran/phy/ue/ue_ul_nr.h +++ b/lib/include/srsran/phy/ue/ue_ul_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/bit.h b/lib/include/srsran/phy/utils/bit.h index f23ad5541a..0fed4c0d49 100644 --- a/lib/include/srsran/phy/utils/bit.h +++ b/lib/include/srsran/phy/utils/bit.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/cexptab.h b/lib/include/srsran/phy/utils/cexptab.h index 57e614e0f6..1e519800f1 100644 --- a/lib/include/srsran/phy/utils/cexptab.h +++ b/lib/include/srsran/phy/utils/cexptab.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/convolution.h b/lib/include/srsran/phy/utils/convolution.h index fb93ebee68..111893ad97 100644 --- a/lib/include/srsran/phy/utils/convolution.h +++ b/lib/include/srsran/phy/utils/convolution.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/debug.h b/lib/include/srsran/phy/utils/debug.h index 288fef7c89..e907b5b381 100644 --- a/lib/include/srsran/phy/utils/debug.h +++ b/lib/include/srsran/phy/utils/debug.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/filter.h b/lib/include/srsran/phy/utils/filter.h index 854390d8de..dde129b652 100644 --- a/lib/include/srsran/phy/utils/filter.h +++ b/lib/include/srsran/phy/utils/filter.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/mat.h b/lib/include/srsran/phy/utils/mat.h index 72e409f63e..4add50be3d 100644 --- a/lib/include/srsran/phy/utils/mat.h +++ b/lib/include/srsran/phy/utils/mat.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/phy_logger.h b/lib/include/srsran/phy/utils/phy_logger.h index cd2d8b702c..722d9374ba 100644 --- a/lib/include/srsran/phy/utils/phy_logger.h +++ b/lib/include/srsran/phy/utils/phy_logger.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/primes.h b/lib/include/srsran/phy/utils/primes.h index 81fca7aa3a..78827a9dca 100644 --- a/lib/include/srsran/phy/utils/primes.h +++ b/lib/include/srsran/phy/utils/primes.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/random.h b/lib/include/srsran/phy/utils/random.h index d8d8108bd3..b7b977686e 100644 --- a/lib/include/srsran/phy/utils/random.h +++ b/lib/include/srsran/phy/utils/random.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/re_pattern.h b/lib/include/srsran/phy/utils/re_pattern.h index 1fd410dcc8..74be926dea 100644 --- a/lib/include/srsran/phy/utils/re_pattern.h +++ b/lib/include/srsran/phy/utils/re_pattern.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/ringbuffer.h b/lib/include/srsran/phy/utils/ringbuffer.h index a822b47f1f..1b987294a1 100644 --- a/lib/include/srsran/phy/utils/ringbuffer.h +++ b/lib/include/srsran/phy/utils/ringbuffer.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/simd.h b/lib/include/srsran/phy/utils/simd.h index 538b59a8a3..80e450a0a6 100644 --- a/lib/include/srsran/phy/utils/simd.h +++ b/lib/include/srsran/phy/utils/simd.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/phy/utils/vector.h b/lib/include/srsran/phy/utils/vector.h index 4baab6f123..3545988a61 100644 --- a/lib/include/srsran/phy/utils/vector.h +++ b/lib/include/srsran/phy/utils/vector.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -70,6 +70,15 @@ extern "C" { // Proportional moving average #define SRSRAN_VEC_PMA(average1, n1, average2, n2) (((average1) * (n1) + (average2) * (n2)) / ((n1) + (n2))) +// Safe Proportional moving average +#ifdef __cplusplus +#define SRSRAN_VEC_SAFE_PMA(average1, n1, average2, n2) \ + (std::isnormal((n1) + (n2)) ? SRSRAN_VEC_PMA(average1, n1, average2, n2) : (0)) +#else +#define SRSRAN_VEC_SAFE_PMA(average1, n1, average2, n2) \ + (isnormal((n1) + (n2)) ? SRSRAN_VEC_PMA(average1, n1, average2, n2) : (0)) +#endif + // Exponential moving average #define SRSRAN_VEC_EMA(data, average, alpha) ((alpha) * (data) + (1 - alpha) * (average)) @@ -171,6 +180,9 @@ SRSRAN_API void srsran_vec_sub_ccc(const cf_t* x, const cf_t* y, cf_t* z, const SRSRAN_API void srsran_vec_sub_sss(const int16_t* x, const int16_t* y, int16_t* z, const uint32_t len); SRSRAN_API void srsran_vec_sub_bbb(const int8_t* x, const int8_t* y, int8_t* z, const uint32_t len); +/* sum a scalar to all elements of a vector */ +SRSRAN_API void srsran_vec_sc_sum_fff(const float* x, float h, float* z, uint32_t len); + /* scalar product */ SRSRAN_API void srsran_vec_sc_prod_cfc(const cf_t* x, const float h, cf_t* z, const uint32_t len); SRSRAN_API void srsran_vec_sc_prod_fcc(const float* x, const cf_t h, cf_t* z, const uint32_t len); @@ -230,6 +242,7 @@ SRSRAN_API void srsran_vec_conj_cc(const cf_t* x, cf_t* y, const uint32_t len); SRSRAN_API float srsran_vec_avg_power_cf(const cf_t* x, const uint32_t len); SRSRAN_API float srsran_vec_avg_power_sf(const int16_t* x, const uint32_t len); SRSRAN_API float srsran_vec_avg_power_bf(const int8_t* x, const uint32_t len); +SRSRAN_API float srsran_vec_avg_power_ff(const float* x, const uint32_t len); /* Correlation between complex vectors x and y */ SRSRAN_API float srsran_vec_corr_ccc(const cf_t* x, cf_t* y, const uint32_t len); @@ -358,6 +371,36 @@ SRSRAN_API void srsran_vec_apply_cfo(const cf_t* x, float cfo, cf_t* z, int len) SRSRAN_API float srsran_vec_estimate_frequency(const cf_t* x, int len); +/*! + * @brief Generates an amplitude envelope that, multiplied point-wise with a vector, results in clipping + * by a specified amplitude threshold. + * @param[in] x_abs Absolute value vector of the signal to be clipped + * @param[in] thres Clipping threshold + * @param[out] clip_env The generated clipping envelope + * @param[in] len Length of the vector. + */ +SRSRAN_API void +srsran_vec_gen_clip_env(const float* x_abs, const float thres, const float alpha, float* env, const int len); + +/*! + * @brief Calculates the PAPR of a complex vector + * @param[in] in Input vector + * @param[in] len Vector length. + */ +SRSRAN_API float srsran_vec_papr_c(const cf_t* in, const int len); + +/*! + * @brief Calculates the ACPR of a signal using its baseband spectrum + * @attention The spectrum passed by x_f needs to be in FFT form + * @param[in] x_f Spectrum of the signal + * @param[in] win_pos_len Channel frequency window for the positive side of the spectrum + * @param[in] win_neg_len Channel frequency window for the negative side of the spectrum + * @param[in] len Length of the x_f vector + * @returns The ACPR in linear form + */ +SRSRAN_API float +srsran_vec_acpr_c(const cf_t* x_f, const uint32_t win_pos_len, const uint32_t win_neg_len, const uint32_t len); + #ifdef __cplusplus } #endif diff --git a/lib/include/srsran/phy/utils/vector_simd.h b/lib/include/srsran/phy/utils/vector_simd.h index d59de219e4..3c15a7c6a1 100644 --- a/lib/include/srsran/phy/utils/vector_simd.h +++ b/lib/include/srsran/phy/utils/vector_simd.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -48,6 +48,8 @@ SRSRAN_API void srsran_vec_add_fff_simd(const float* x, const float* y, float* z SRSRAN_API void srsran_vec_sub_fff_simd(const float* x, const float* y, float* z, int len); +SRSRAN_API void srsran_vec_sc_sum_fff_simd(const float* x, float h, float* z, int len); + /* SIMD Vector Scalar Product */ SRSRAN_API void srsran_vec_sc_prod_cfc_simd(const cf_t* x, const float h, cf_t* y, const int len); diff --git a/lib/include/srsran/radio/channel_mapping.h b/lib/include/srsran/radio/channel_mapping.h index 3cfe2a28ff..3e1fe5f3ff 100644 --- a/lib/include/srsran/radio/channel_mapping.h +++ b/lib/include/srsran/radio/channel_mapping.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/radio/radio.h b/lib/include/srsran/radio/radio.h index da2991dff7..367ef35d83 100644 --- a/lib/include/srsran/radio/radio.h +++ b/lib/include/srsran/radio/radio.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -110,7 +110,7 @@ class radio : public radio_interface_phy, public srsran::radio_base std::array, SRSRAN_MAX_CHANNELS> rx_buffer; std::array interpolators = {}; std::array decimators = {}; - bool decimator_busy = false; ///< Indicates the decimator is changing the rate + std::atomic decimator_busy = {false}; ///< Indicates the decimator is changing the rate rf_timestamp_t end_of_burst_time = {}; std::atomic is_start_of_burst{false}; @@ -167,6 +167,19 @@ class radio : public radio_interface_phy, public srsran::radio_base */ bool open_dev(const uint32_t& device_idx, const std::string& device_name, const std::string& devive_args); + /** + * Helper method for opening a file-based RF device abstraction + * + * @param device_idx Device index + * @param rx_files Array of pre-opened FILE* for rx + * @param tx_files Array of pre-opened FILE* for tx + * @param nof_channels Number of elements in each array @p rx_files and @p tx_files + * @param base_srate Sampling rate in Hz + * @return it returns true if the device was opened successful, otherwise it returns false + */ + bool + open_dev(const uint32_t& device_idx, FILE** rx_files, FILE** tx_files, uint32_t nof_channels, uint32_t base_srate); + /** * Helper method for transmitting over a single RF device. This function maps automatically the logical transmit * buffers to the physical RF buffers for the given device. diff --git a/lib/include/srsran/radio/radio_base.h b/lib/include/srsran/radio/radio_base.h index 6b7c01ecc4..835e710a27 100644 --- a/lib/include/srsran/radio/radio_base.h +++ b/lib/include/srsran/radio/radio_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/radio/radio_dummy.h b/lib/include/srsran/radio/radio_dummy.h new file mode 100644 index 0000000000..768028c6f3 --- /dev/null +++ b/lib/include/srsran/radio/radio_dummy.h @@ -0,0 +1,306 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "channel_mapping.h" +#include "radio_metrics.h" +#include "rf_buffer.h" +#include "rf_timestamp.h" +#include "srsran/common/interfaces_common.h" +#include "srsran/interfaces/radio_interfaces.h" +#include "srsran/phy/resampling/resampler.h" +#include "srsran/phy/rf/rf.h" +#include "srsran/radio/radio_base.h" +#include "srsran/srslog/srslog.h" +#include "srsran/srsran.h" + +#include +#include +#include + +#ifndef SRSRAN_RADIO_DUMMY_H +#define SRSRAN_RADIO_DUMMY_H + +namespace srsran { + +/** + * Implementation of radio dummy for the PHY testing + * + * It uses ringbuffers from srsRAN library to emulate baseband transmission and reception. The current implementation + * does not support dynamic sampling rates, gains and frequencies. + */ +class radio_dummy : public srsran::radio_base, public srsran::radio_interface_phy +{ +private: + static const uint32_t TEMP_BUFFER_SZ = SRSRAN_SF_LEN_MAX * SRSRAN_NOF_SF_X_FRAME; + srslog::basic_logger& logger; + std::vector rx_ring_buffers; + std::vector tx_ring_buffers; + std::mutex tx_mutex; + std::atomic srate_hz = {0.0f}; + std::atomic rx_gain = {1.0f}; + std::atomic tx_gain = {1.0f}; + cf_t* temp_buffer = nullptr; + uint64_t rx_timestamp = 0; + uint64_t tx_timestamp = 0; + srsran_rf_info_t rf_info = {}; + std::atomic is_initialised = {false}; + std::atomic quit = {false}; + + void write_ring_buffers(std::vector& buffers, cf_t** buffer, uint32_t nsamples) + { + for (uint32_t i = 0; i < buffers.size(); i++) { + int ret = SRSRAN_SUCCESS; + do { + if (ret != SRSRAN_SUCCESS) { + logger.error("Ring buffer write failed (full). Trying again."); + } + ret = srsran_ringbuffer_write_timed(&buffers[i], buffer[i], (int)(sizeof(cf_t) * nsamples), 1000); + } while (ret == SRSRAN_ERROR_TIMEOUT and not quit); + } + } + + void read_ring_buffers(std::vector& buffers, cf_t** buffer, uint32_t nsamples) + { + for (uint32_t i = 0; i < buffers.size(); i++) { + int ret = SRSRAN_SUCCESS; + do { + if (ret != SRSRAN_SUCCESS) { + logger.error("Ring buffer read failed. Trying again."); + } + ret = srsran_ringbuffer_read_timed(&buffers[i], buffer[i], (int)(sizeof(cf_t) * nsamples), 1000); + } while (ret == SRSRAN_ERROR_TIMEOUT and not quit); + } + } + + void write_zeros_ring_buffers(std::vector& buffers, uint32_t nsamples) + { + uint32_t n = SRSRAN_MIN(nsamples, TEMP_BUFFER_SZ); + srsran_vec_cf_zero(temp_buffer, n); + + std::array zero_buffer_pointers = {}; + for (cf_t*& ptr : zero_buffer_pointers) { + ptr = temp_buffer; + } + + while (nsamples > 0) { + // Get new number of samples + n = SRSRAN_MIN(nsamples, TEMP_BUFFER_SZ); + + // Write zeros in the buffers + write_ring_buffers(buffers, zero_buffer_pointers.data(), n); + + nsamples -= n; + } + } + + void advance_tx_timestamp(uint64_t ts, bool round_sf = false) + { + std::lock_guard lock(tx_mutex); + + // Make sure new timestamp has not passed + if (ts < tx_timestamp) { + return; + } + + // Calculate transmission gap + uint32_t tx_gap = (uint32_t)(ts - tx_timestamp); + + // Round gap to subframe size + if (round_sf) { + uint64_t sf_sz = (uint64_t)(srate_hz / 1e3); + tx_gap = sf_sz * SRSRAN_CEIL(tx_gap, sf_sz); + } + + // Skip zeros if there is no gap + if (tx_gap == 0) { + return; + } + + // Write zeros in tx ring buffer + write_zeros_ring_buffers(tx_ring_buffers, tx_gap); + + // Update new transmit timestamp + tx_timestamp += tx_gap; + } + +public: + radio_dummy() : logger(srslog::fetch_basic_logger("RF", false)) {} + + ~radio_dummy() + { + for (auto& rb : rx_ring_buffers) { + srsran_ringbuffer_free(&rb); + } + for (auto& rb : tx_ring_buffers) { + srsran_ringbuffer_free(&rb); + } + if (temp_buffer) { + free(temp_buffer); + } + } + + std::string get_type() override { return "dummy"; } + int init(const rf_args_t& args_, phy_interface_radio* phy_) override + { + // Set logger level + logger.set_level(srslog::str_to_basic_level(args_.log_level)); + + // Get base sampling rate and assert the value is valid + srate_hz = args_.srate_hz; + if (not std::isnormal(srate_hz)) { + logger.error("A valid sampling rate is missing"); + return SRSRAN_ERROR; + } + + // Create receiver ring buffers + rx_ring_buffers.resize(args_.nof_carriers * (size_t)args_.nof_antennas); + for (auto& rb : rx_ring_buffers) { + if (srsran_ringbuffer_init(&rb, (int)sizeof(cf_t) * TEMP_BUFFER_SZ) != SRSRAN_SUCCESS) { + perror("init softbuffer"); + } + } + + // Create transmitter ring buffers + tx_ring_buffers.resize(args_.nof_carriers * (size_t)args_.nof_antennas); + for (auto& rb : tx_ring_buffers) { + if (srsran_ringbuffer_init(&rb, (int)sizeof(cf_t) * TEMP_BUFFER_SZ) != SRSRAN_SUCCESS) { + perror("init softbuffer"); + } + } + + // Create temporal buffer + temp_buffer = srsran_vec_cf_malloc(TEMP_BUFFER_SZ); + if (!temp_buffer) { + perror("malloc"); + } + + // Set RF Info (in dB) + rf_info.min_rx_gain = 0.0f; + rf_info.max_rx_gain = 90.0f; + rf_info.min_tx_gain = 0.0f; + rf_info.max_tx_gain = 90.0f; + + // Finally, the radio is initialised + is_initialised = true; + + return SRSRAN_SUCCESS; + } + void stop() override { quit = true; } + bool get_metrics(rf_metrics_t* metrics) override { return false; } + + void set_loglevel(std::string& str) { logger.set_level(srslog::str_to_basic_level(str)); } + + void write_rx(cf_t** buffer, uint32_t nsamples) { write_ring_buffers(rx_ring_buffers, buffer, nsamples); } + + void read_tx(cf_t** buffer, uint32_t nsamples) { read_ring_buffers(tx_ring_buffers, buffer, nsamples); } + + bool tx(srsran::rf_buffer_interface& buffer, const srsran::rf_timestamp_interface& tx_time) override + { + bool ret = true; + + // Convert timestamp to samples + uint64_t tx_time_n = srsran_timestamp_uint64(&tx_time.get(0), srate_hz); + + // Check if the transmission is in the past + { + std::lock_guard lock(tx_mutex); + if (tx_time_n < tx_timestamp) { + logger.error("Error transmission in the past for %d samples", (int)(tx_timestamp - tx_time_n)); + return false; + } + } + + // Advance TX to timestamp + advance_tx_timestamp(tx_time_n); + + // From now on, protect buffers + std::lock_guard lock(tx_mutex); + + // Write transmission buffers into the ring buffer + write_ring_buffers(tx_ring_buffers, buffer.to_cf_t(), buffer.get_nof_samples()); + + // Increment transmit timestamp + tx_timestamp += buffer.get_nof_samples(); + + return ret; + } + void release_freq(const uint32_t& carrier_idx) override{}; + void tx_end() override {} + bool rx_now(srsran::rf_buffer_interface& buffer, srsran::rf_timestamp_interface& rxd_time) override + { + // Advance Tx buffer + advance_tx_timestamp(rx_timestamp + buffer.get_nof_samples(), true); + + // Read samples + read_ring_buffers(rx_ring_buffers, buffer.to_cf_t(), buffer.get_nof_samples()); + + // Apply Rx gain + for (uint32_t i = 0; i < rx_ring_buffers.size(); i++) { + cf_t* ptr = buffer.get(i); + srsran_vec_sc_prod_cfc(ptr, rx_gain, ptr, buffer.get_nof_samples()); + } + + // Set Rx timestamp + srsran_timestamp_init_uint64(rxd_time.get_ptr(0), rx_timestamp, (double)srate_hz); + + // Advance timestamp + rx_timestamp += buffer.get_nof_samples(); + + return true; + } + void set_tx_freq(const uint32_t& channel_idx, const double& freq) override + { + logger.info("Set Tx freq to %+.0f MHz.", freq * 1.0e-6); + } + void set_rx_freq(const uint32_t& channel_idx, const double& freq) override + { + logger.info("Set Rx freq to %+.0f MHz.", freq * 1.0e-6); + } + void set_rx_gain_th(const float& gain) override + { + rx_gain = srsran_convert_dB_to_amplitude(gain); + logger.info("Set Rx gain-th to %+.1f dB (%.6f).", gain, rx_gain.load()); + } + void set_tx_gain(const float& gain) override + { + tx_gain = srsran_convert_dB_to_amplitude(gain); + logger.info("Set Tx gain to %+.1f dB (%.6f).", gain, tx_gain.load()); + } + void set_rx_gain(const float& gain) override + { + rx_gain = srsran_convert_dB_to_amplitude(gain); + logger.info("Set Rx gain to %+.1f dB (%.6f).", gain, rx_gain.load()); + } + void set_tx_srate(const double& srate) override { logger.info("Set Tx sampling rate to %+.3f MHz.", srate * 1.0e-6); } + void set_rx_srate(const double& srate) override { logger.info("Set Rx sampling rate to %+.3f MHz.", srate * 1.0e-6); } + void set_channel_rx_offset(uint32_t ch, int32_t offset_samples) override{}; + float get_rx_gain() override { return srsran_convert_amplitude_to_dB(rx_gain); } + double get_freq_offset() override { return 0; } + bool is_continuous_tx() override { return false; } + bool get_is_start_of_burst() override { return false; } + bool is_init() override { return is_initialised; } + void reset() override {} + srsran_rf_info_t* get_info() override { return &rf_info; } +}; + +} // namespace srsran + +#endif // SRSRAN_RADIO_DUMMY_H diff --git a/lib/include/srsran/radio/radio_metrics.h b/lib/include/srsran/radio/radio_metrics.h index 8be71fee77..4d46ff112e 100644 --- a/lib/include/srsran/radio/radio_metrics.h +++ b/lib/include/srsran/radio/radio_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/radio/radio_null.h b/lib/include/srsran/radio/radio_null.h index f832fecaa4..52cb9bfa8f 100644 --- a/lib/include/srsran/radio/radio_null.h +++ b/lib/include/srsran/radio/radio_null.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/radio/rf_buffer.h b/lib/include/srsran/radio/rf_buffer.h index 4ba95526f1..5616d527fb 100644 --- a/lib/include/srsran/radio/rf_buffer.h +++ b/lib/include/srsran/radio/rf_buffer.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/radio/rf_timestamp.h b/lib/include/srsran/radio/rf_timestamp.h index c4db90c17e..2348d73cab 100644 --- a/lib/include/srsran/radio/rf_timestamp.h +++ b/lib/include/srsran/radio/rf_timestamp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/rlc/bearer_mem_pool.h b/lib/include/srsran/rlc/bearer_mem_pool.h index 6b0a588dbc..e731d37494 100644 --- a/lib/include/srsran/rlc/bearer_mem_pool.h +++ b/lib/include/srsran/rlc/bearer_mem_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/rlc/rlc.h b/lib/include/srsran/rlc/rlc.h index f26d366c71..413249128a 100644 --- a/lib/include/srsran/rlc/rlc.h +++ b/lib/include/srsran/rlc/rlc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/rlc/rlc_am_base.h b/lib/include/srsran/rlc/rlc_am_base.h index 8997c295e1..e76b878c97 100644 --- a/lib/include/srsran/rlc/rlc_am_base.h +++ b/lib/include/srsran/rlc/rlc_am_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,6 +24,8 @@ #include "srsran/common/buffer_pool.h" #include "srsran/common/common.h" +#include "srsran/common/timers.h" +#include "srsran/interfaces/ue_rrc_interfaces.h" #include "srsran/rlc/rlc_common.h" #include "srsran/upper/byte_buffer_queue.h" #include @@ -31,20 +33,179 @@ #include #include -namespace srsran { +namespace srsue { + +class pdcp_interface_rlc; +class rrc_interface_rlc; + +} // namespace srsue -///< Add rlc_am_base here +namespace srsran { bool rlc_am_is_control_pdu(uint8_t* payload); bool rlc_am_is_control_pdu(byte_buffer_t* pdu); -} // namespace srsran +/******************************************************* + * RLC AM entity + * This entity is common between LTE and NR + * and only the TX/RX entities change between them + *******************************************************/ +class rlc_am : public rlc_common +{ +public: + class rlc_am_base_tx; + class rlc_am_base_rx; -namespace srsue { + friend class rlc_am_lte_tx; + friend class rlc_am_lte_rx; + friend class rlc_am_nr_tx; + friend class rlc_am_nr_rx; -class pdcp_interface_rlc; -class rrc_interface_rlc; + rlc_am(srsran_rat_t rat, + srslog::basic_logger& logger, + uint32_t lcid_, + srsue::pdcp_interface_rlc* pdcp_, + srsue::rrc_interface_rlc* rrc_, + srsran::timer_handler* timers_); -} // namespace srsue + bool configure(const rlc_config_t& cfg_) final; + + void reestablish() final; + + void stop() final; + + void empty_queue() final { tx_base->empty_queue(); } + + rlc_mode_t get_mode() final { return rlc_mode_t::am; } + + uint32_t get_lcid() final { return lcid; } + + /**************************************************************************** + * PDCP interface + ***************************************************************************/ + void write_sdu(unique_byte_buffer_t sdu) final; + + void discard_sdu(uint32_t discard_sn) final; + + bool sdu_queue_is_full() final; + + /**************************************************************************** + * MAC interface + ***************************************************************************/ + bool has_data() final; + uint32_t get_buffer_state() final; + void get_buffer_state(uint32_t& n_bytes_newtx, uint32_t& n_bytes_prio) final; + + uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) final; + + void write_pdu(uint8_t* payload, uint32_t nof_bytes) final; + + /**************************************************************************** + * Metrics + ***************************************************************************/ + rlc_bearer_metrics_t get_metrics() final; + void reset_metrics() final; + + /**************************************************************************** + * BSR Callback + ***************************************************************************/ + void set_bsr_callback(bsr_callback_t callback) final; + +protected: + // Common variables needed/provided by parent class + srsran::timer_handler* timers = nullptr; + uint32_t lcid = 0; + rlc_config_t cfg = {}; + + static const int poll_periodicity = 8; // After how many data PDUs a status PDU shall be requested + + std::mutex metrics_mutex; + rlc_bearer_metrics_t metrics = {}; + + srsue::rrc_interface_rlc* rrc = nullptr; + srsue::pdcp_interface_rlc* pdcp = nullptr; + + /******************************************************* + * RLC AM TX entity + * This class is used for common code between the + * LTE and NR TX entities + *******************************************************/ +public: + class rlc_am_base_tx + { + public: + explicit rlc_am_base_tx(srslog::basic_logger& logger_) : logger(logger_) {} + virtual ~rlc_am_base_tx() = default; + + virtual bool configure(const rlc_config_t& cfg_) = 0; + virtual void handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) = 0; + virtual uint32_t get_buffer_state() = 0; + virtual void get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue) = 0; + virtual void reestablish() = 0; + virtual void empty_queue() = 0; + virtual bool has_data() = 0; + virtual void stop() = 0; + + void set_bsr_callback(bsr_callback_t callback); + + int write_sdu(unique_byte_buffer_t sdu); + bool sdu_queue_is_full(); + virtual void discard_sdu(uint32_t pdcp_sn); + virtual uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) = 0; + + bool tx_enabled = false; + byte_buffer_pool* pool = nullptr; + srslog::basic_logger& logger; + std::string rb_name; + + bsr_callback_t bsr_callback; + + // Tx SDU buffers + byte_buffer_queue tx_sdu_queue; + + // Mutexes + std::mutex mutex; + }; + + /******************************************************* + * RLC AM RX entity + * This class is used for common code between the + * LTE and NR RX entities + *******************************************************/ + class rlc_am_base_rx + { + public: + explicit rlc_am_base_rx(rlc_am* parent_, srslog::basic_logger& logger_) : parent(parent_), logger(logger_) {} + virtual ~rlc_am_base_rx() = default; + + virtual bool configure(const rlc_config_t& cfg_) = 0; + virtual void handle_data_pdu(uint8_t* payload, uint32_t nof_bytes) = 0; + virtual void reestablish() = 0; + virtual void stop() = 0; + virtual uint32_t get_sdu_rx_latency_ms() = 0; + virtual uint32_t get_rx_buffered_bytes() = 0; + + void write_pdu(uint8_t* payload, uint32_t nof_bytes); + + srslog::basic_logger& logger; + byte_buffer_pool* pool = nullptr; + rlc_am* parent = nullptr; + std::string rb_name; + + protected: + std::atomic do_status = {false}; // light-weight access from Tx entity + }; + +protected: + std::unique_ptr tx_base = {}; + std::unique_ptr rx_base = {}; + +public: + // Getters for TX/RX entities. Useful for testing. + rlc_am_base_rx* get_rx() { return rx_base.get(); } + rlc_am_base_tx* get_tx() { return tx_base.get(); } +}; + +} // namespace srsran #endif // SRSRAN_RLC_AM_BASE_H diff --git a/lib/include/srsran/rlc/rlc_am_data_structs.h b/lib/include/srsran/rlc/rlc_am_data_structs.h new file mode 100644 index 0000000000..c53fe827ce --- /dev/null +++ b/lib/include/srsran/rlc/rlc_am_data_structs.h @@ -0,0 +1,547 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_RLC_AM_DATA_STRUCTS_H +#define SRSRAN_RLC_AM_DATA_STRUCTS_H + +#include "srsran/adt/circular_buffer.h" +#include "srsran/adt/circular_map.h" +#include "srsran/adt/intrusive_list.h" +#include "srsran/common/buffer_pool.h" +#include +#include +#include + +namespace srsran { + +template +class rlc_amd_tx_pdu; +template +class pdcp_pdu_info; + +/// Pool that manages the allocation of RLC AM PDU Segments to RLC PDUs and tracking of segments ACK state +template +struct rlc_am_pdu_segment_pool { + const static size_t MAX_POOL_SIZE = 16384; + + /// RLC AM PDU Segment, containing the PDCP SN and RLC SN it has been assigned to, and its current ACK state + using rlc_list_tag = default_intrusive_tag; + struct free_list_tag {}; + struct segment_resource : public intrusive_forward_list_element, + public intrusive_forward_list_element, + public intrusive_double_linked_list_element<> { + const static uint32_t invalid_rlc_sn = std::numeric_limits::max(); + const static uint32_t invalid_pdcp_sn = std::numeric_limits::max() - 1; // -1 for Status Report + + int id() const { return std::distance(parent_pool->segments.cbegin(), this); } + + void release_pdcp_sn() + { + pdcp_sn_ = invalid_pdcp_sn; + if (empty()) { + parent_pool->free_list.push_front(this); + } + } + + void release_rlc_sn() + { + rlc_sn_ = invalid_rlc_sn; + if (empty()) { + parent_pool->free_list.push_front(this); + } + } + + uint32_t rlc_sn() const { return rlc_sn_; } + uint32_t pdcp_sn() const { return pdcp_sn_; } + bool empty() const { return rlc_sn_ == invalid_rlc_sn and pdcp_sn_ == invalid_pdcp_sn; } + + private: + friend struct rlc_am_pdu_segment_pool; + uint32_t rlc_sn_ = invalid_rlc_sn; + uint32_t pdcp_sn_ = invalid_pdcp_sn; + rlc_am_pdu_segment_pool* parent_pool = nullptr; + }; + + rlc_am_pdu_segment_pool() + { + for (segment_resource& s : segments) { + s.parent_pool = this; + free_list.push_front(&s); + } + } + rlc_am_pdu_segment_pool(const rlc_am_pdu_segment_pool&) = delete; + rlc_am_pdu_segment_pool(rlc_am_pdu_segment_pool&&) = delete; + rlc_am_pdu_segment_pool& operator=(const rlc_am_pdu_segment_pool&) = delete; + rlc_am_pdu_segment_pool& operator=(rlc_am_pdu_segment_pool&&) = delete; + + bool has_segments() const { return not free_list.empty(); } + bool make_segment(rlc_amd_tx_pdu& rlc_list, pdcp_pdu_info& pdcp_list) + { + if (not has_segments()) { + return false; + } + segment_resource* segment = free_list.pop_front(); + segment->rlc_sn_ = rlc_list.rlc_sn; + segment->pdcp_sn_ = pdcp_list.sn; + rlc_list.add_segment(*segment); + pdcp_list.add_segment(*segment); + return true; + } + +private: + intrusive_forward_list::segment_resource, free_list_tag> free_list; + std::array::segment_resource, MAX_POOL_SIZE> segments; +}; + +/// Class that contains the parameters and state (e.g. segments) of a RLC PDU +template +class rlc_amd_tx_pdu +{ + using rlc_am_pdu_segment = typename rlc_am_pdu_segment_pool::segment_resource; + using list_type = intrusive_forward_list; + const static uint32_t invalid_rlc_sn = std::numeric_limits::max(); + + list_type list; + +public: + using iterator = typename list_type::iterator; + using const_iterator = typename list_type::const_iterator; + + const uint32_t rlc_sn = invalid_rlc_sn; + uint32_t retx_count = 0; + HeaderType header = {}; + unique_byte_buffer_t buf = nullptr; + + explicit rlc_amd_tx_pdu(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {} + rlc_amd_tx_pdu(const rlc_amd_tx_pdu&) = delete; + rlc_amd_tx_pdu(rlc_amd_tx_pdu&& other) noexcept = default; + rlc_amd_tx_pdu& operator=(const rlc_amd_tx_pdu& other) = delete; + rlc_amd_tx_pdu& operator=(rlc_amd_tx_pdu&& other) = delete; + ~rlc_amd_tx_pdu() + { + while (not list.empty()) { + // remove from list + rlc_am_pdu_segment* segment = list.pop_front(); + // deallocate if also removed from PDCP + segment->release_rlc_sn(); + } + } + + // Segment List Interface + void add_segment(rlc_am_pdu_segment& segment) { list.push_front(&segment); } + const_iterator begin() const { return list.begin(); } + const_iterator end() const { return list.end(); } + iterator begin() { return list.begin(); } + iterator end() { return list.end(); } +}; + +/// Class that contains the parameters and state (e.g. unACKed segments) of a PDCP PDU +template +class pdcp_pdu_info +{ + using rlc_am_pdu_segment = typename rlc_am_pdu_segment_pool::segment_resource; + using list_type = intrusive_double_linked_list; + + list_type list; // List of unACKed RLC PDUs that contain segments that belong to the PDCP PDU. + +public: + const static uint32_t status_report_sn = std::numeric_limits::max(); + const static uint32_t invalid_pdcp_sn = std::numeric_limits::max() - 1; + + using iterator = typename list_type::iterator; + using const_iterator = typename list_type::const_iterator; + + // Copy is forbidden to avoid multiple PDCP SN references to the same segment + pdcp_pdu_info() = default; + pdcp_pdu_info(pdcp_pdu_info&&) noexcept = default; + pdcp_pdu_info(const pdcp_pdu_info&) noexcept = delete; + pdcp_pdu_info& operator=(const pdcp_pdu_info&) noexcept = delete; + pdcp_pdu_info& operator=(pdcp_pdu_info&&) noexcept = default; + ~pdcp_pdu_info() { clear(); } + + uint32_t sn = invalid_pdcp_sn; + bool fully_txed = false; // Boolean indicating if the SDU is fully transmitted. + + bool fully_acked() const { return fully_txed and list.empty(); } + bool valid() const { return sn != invalid_pdcp_sn; } + + // Interface for list of unACKed RLC segments of the PDCP PDU + void add_segment(rlc_am_pdu_segment& segment) { list.push_front(&segment); } + void ack_segment(rlc_am_pdu_segment& segment) + { + // remove from list + list.pop(&segment); + // signal pool that the pdcp handle is released + segment.release_pdcp_sn(); + } + void clear() + { + sn = invalid_pdcp_sn; + fully_txed = false; + while (not list.empty()) { + ack_segment(list.front()); + } + } + + const_iterator begin() const { return list.begin(); } + const_iterator end() const { return list.end(); } +}; + +template +struct rlc_ringbuffer_base { + virtual ~rlc_ringbuffer_base() = default; + virtual T& add_pdu(size_t sn) = 0; + virtual void remove_pdu(size_t sn) = 0; + virtual T& operator[](size_t sn) = 0; + virtual size_t size() const = 0; + virtual bool empty() const = 0; + virtual bool full() const = 0; + virtual void clear() = 0; + virtual bool has_sn(uint32_t sn) const = 0; +}; + +template +struct rlc_ringbuffer_t : public rlc_ringbuffer_base { + ~rlc_ringbuffer_t() = default; + + T& add_pdu(size_t sn) override + { + srsran_expect(not has_sn(sn), "The same SN=%zd should not be added twice", sn); + window.overwrite(sn, T(sn)); + return window[sn]; + } + void remove_pdu(size_t sn) override + { + srsran_expect(has_sn(sn), "The removed SN=%zd is not in the window", sn); + window.erase(sn); + } + T& operator[](size_t sn) override { return window[sn]; } + size_t size() const override { return window.size(); } + bool full() const override { return window.full(); } + bool empty() const override { return window.empty(); } + void clear() override { window.clear(); } + + bool has_sn(uint32_t sn) const override { return window.contains(sn); } + + // Return the sum data bytes of all active PDUs (check PDU is non-null) + uint32_t get_buffered_bytes() + { + uint32_t buff_size = 0; + for (const auto& pdu : window) { + if (pdu.second.buf != nullptr) { + buff_size += pdu.second.buf->N_bytes; + } + } + return buff_size; + } + +private: + srsran::static_circular_map window; +}; + +template +struct buffered_pdcp_pdu_list { +public: + explicit buffered_pdcp_pdu_list() : buffered_pdus(buffered_pdcp_pdu_list::buffer_size) { clear(); } + + void clear() + { + count = 0; + for (pdcp_pdu_info& b : buffered_pdus) { + b.clear(); + } + } + + void add_pdcp_sdu(uint32_t sn) + { + srsran_expect(sn <= max_pdcp_sn or sn == status_report_sn, "Invalid PDCP SN=%d", sn); + srsran_assert(not has_pdcp_sn(sn), "Cannot re-add same PDCP SN twice"); + pdcp_pdu_info& pdu = get_pdu_(sn); + if (pdu.valid()) { + pdu.clear(); + count--; + } + pdu.sn = sn; + count++; + } + + void clear_pdcp_sdu(uint32_t sn) + { + pdcp_pdu_info& pdu = get_pdu_(sn); + if (not pdu.valid()) { + return; + } + pdu.clear(); + count--; + } + + pdcp_pdu_info& operator[](uint32_t sn) + { + srsran_expect(has_pdcp_sn(sn), "Invalid access to non-existent PDCP SN=%d", sn); + return get_pdu_(sn); + } + + bool has_pdcp_sn(uint32_t pdcp_sn) const + { + srsran_expect(pdcp_sn <= max_pdcp_sn or pdcp_sn == status_report_sn, "Invalid PDCP SN=%d", pdcp_sn); + return get_pdu_(pdcp_sn).sn == pdcp_sn; + } + uint32_t nof_sdus() const { return count; } + +private: + const static size_t max_pdcp_sn = 262143u; + const static size_t buffer_size = 4096u; + const static uint32_t status_report_sn = pdcp_pdu_info::status_report_sn; + + pdcp_pdu_info& get_pdu_(uint32_t sn) + { + return (sn == status_report_sn) ? status_report_pdu : buffered_pdus[static_cast(sn % buffer_size)]; + } + const pdcp_pdu_info& get_pdu_(uint32_t sn) const + { + return (sn == status_report_sn) ? status_report_pdu : buffered_pdus[static_cast(sn % buffer_size)]; + } + + // size equal to buffer_size + std::vector > buffered_pdus; + pdcp_pdu_info status_report_pdu; + uint32_t count = 0; +}; + +struct rlc_amd_retx_base_t { + const static uint32_t invalid_rlc_sn = std::numeric_limits::max(); + + uint32_t sn; ///< sequence number + bool is_segment; ///< flag whether this is a segment or not + uint32_t so_start; ///< offset to first byte of this segment + // so_end or segment_length are different for LTE and NR, hence are defined in subclasses + uint32_t current_so; ///< stores progressing SO during segmentation of this object + + rlc_amd_retx_base_t() : sn(invalid_rlc_sn), is_segment(false), so_start(0), current_so(0) {} + virtual ~rlc_amd_retx_base_t() = default; + + /** + * @brief overlaps implements a check whether the range of this retransmission object includes + * the given segment offset + * @param so the segment offset to check + * @return true if the segment offset is covered by the retransmission object. Otherwise false + */ + virtual bool overlaps(uint32_t so) const = 0; +}; + +struct rlc_amd_retx_lte_t : public rlc_amd_retx_base_t { + uint32_t so_end; ///< offset to first byte beyond the end of this segment + + rlc_amd_retx_lte_t() : rlc_amd_retx_base_t(), so_end(0) {} + bool overlaps(uint32_t segment_offset) const override + { + return (segment_offset >= so_start) && (segment_offset < so_end); + } +}; + +struct rlc_amd_retx_nr_t : public rlc_amd_retx_base_t { + uint32_t segment_length; ///< number of bytes contained in this segment + + rlc_amd_retx_nr_t() : rlc_amd_retx_base_t(), segment_length(0) {} + bool overlaps(uint32_t segment_offset) const override + { + return (segment_offset >= so_start) && (segment_offset < current_so + segment_length); + } +}; + +template +class pdu_retx_queue_base +{ +public: + virtual ~pdu_retx_queue_base() = default; + virtual T& push() = 0; + virtual void pop() = 0; + virtual T& front() = 0; + virtual void clear() = 0; + virtual size_t size() const = 0; + virtual bool empty() const = 0; + virtual bool full() const = 0; + + virtual T& operator[](size_t idx) = 0; + virtual const T& operator[](size_t idx) const = 0; + + virtual bool has_sn(uint32_t sn) const = 0; + virtual bool has_sn(uint32_t sn, uint32_t so) const = 0; +}; + +template +class pdu_retx_queue : public pdu_retx_queue_base +{ +public: + ~pdu_retx_queue() = default; + + T& push() override + { + assert(not full()); + T& p = buffer[wpos]; + wpos = (wpos + 1) % WINDOW_SIZE; + return p; + } + + void pop() override { rpos = (rpos + 1) % WINDOW_SIZE; } + + T& front() override + { + assert(not empty()); + return buffer[rpos]; + } + + T& operator[](size_t idx) override + { + srsran_assert(idx < size(), "Out-of-bounds access to element idx=%zd", idx); + return buffer[(rpos + idx) % WINDOW_SIZE]; + } + + const T& operator[](size_t idx) const override + { + srsran_assert(idx < size(), "Out-of-bounds access to element idx=%zd", idx); + return buffer[(rpos + idx) % WINDOW_SIZE]; + } + + void clear() override + { + wpos = 0; + rpos = 0; + } + + bool has_sn(uint32_t sn) const override + { + for (size_t i = rpos; i != wpos; i = (i + 1) % WINDOW_SIZE) { + if (buffer[i].sn == sn) { + return true; + } + } + return false; + } + + bool has_sn(uint32_t sn, uint32_t so) const override + { + for (size_t i = rpos; i != wpos; i = (i + 1) % WINDOW_SIZE) { + if (buffer[i].sn == sn) { + if (buffer[i].overlaps(so)) { + return true; + } + } + } + return false; + } + + size_t size() const override { return (wpos >= rpos) ? wpos - rpos : WINDOW_SIZE + wpos - rpos; } + bool empty() const override { return wpos == rpos; } + bool full() const override { return size() == WINDOW_SIZE - 1; } + +private: + std::array buffer; + size_t wpos = 0; + size_t rpos = 0; +}; + +template +class pdu_retx_queue_list +{ + std::list queue; + +public: + ~pdu_retx_queue_list() = default; + T& push() + { + queue.emplace_back(); + return queue.back(); + } + + void pop() + { + if (not queue.empty()) { + queue.pop_front(); + } + } + + T& front() + { + assert(not queue.empty()); + return queue.front(); + } + + const std::list& get_inner_queue() const { return queue; } + + void clear() { queue.clear(); } + size_t size() const { return queue.size(); } + bool empty() const { return queue.empty(); } + + bool has_sn(uint32_t sn) const + { + if (queue.empty()) { + return false; + } + for (auto elem : queue) { + if (elem.sn == sn) { + return true; + } + } + return false; + }; + + bool has_sn(uint32_t sn, uint32_t so) const + { + if (queue.empty()) { + return false; + } + for (auto elem : queue) { + if (elem.sn == sn) { + if (elem.overlaps(so)) { + return true; + } + } + } + return false; + }; + + /** + * @brief remove_sn removes SN from queue and returns after first match + * @param sn sequence number to be removed from queue + * @return true if one element was removed, false if no element to remove was found + */ + bool remove_sn(uint32_t sn) + { + if (queue.empty()) { + return false; + } + auto iter = queue.begin(); + while (iter != queue.end()) { + if (iter->sn == sn) { + iter = queue.erase(iter); + return true; + } else { + ++iter; + } + } + return false; + } +}; + +} // namespace srsran + +#endif // SRSRAN_RLC_AM_DATA_STRUCTS_H diff --git a/lib/include/srsran/rlc/rlc_am_lte.h b/lib/include/srsran/rlc/rlc_am_lte.h index 481802452b..4095313521 100644 --- a/lib/include/srsran/rlc/rlc_am_lte.h +++ b/lib/include/srsran/rlc/rlc_am_lte.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -25,13 +25,14 @@ #include "srsran/adt/accumulators.h" #include "srsran/adt/circular_array.h" #include "srsran/adt/circular_map.h" -#include "srsran/adt/intrusive_list.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/common.h" #include "srsran/common/task_scheduler.h" #include "srsran/common/timeout.h" #include "srsran/interfaces/pdcp_interface_types.h" #include "srsran/rlc/rlc_am_base.h" +#include "srsran/rlc/rlc_am_data_structs.h" +#include "srsran/rlc/rlc_am_lte_packing.h" #include "srsran/rlc/rlc_common.h" #include "srsran/support/srsran_assert.h" #include "srsran/upper/byte_buffer_queue.h" @@ -43,564 +44,199 @@ namespace srsran { #undef RLC_AM_BUFFER_DEBUG -class rlc_amd_tx_pdu; -class pdcp_pdu_info; - -/// Pool that manages the allocation of RLC AM PDU Segments to RLC PDUs and tracking of segments ACK state -struct rlc_am_pdu_segment_pool { - const static size_t MAX_POOL_SIZE = 16384; - using rlc_list_tag = default_intrusive_tag; - struct free_list_tag {}; - - /// RLC AM PDU Segment, containing the PDCP SN and RLC SN it has been assigned to, and its current ACK state - struct segment_resource : public intrusive_forward_list_element, - public intrusive_forward_list_element, - public intrusive_double_linked_list_element<> { - const static uint32_t invalid_rlc_sn = std::numeric_limits::max(); - const static uint32_t invalid_pdcp_sn = std::numeric_limits::max() - 1; // -1 for Status Report - - int id() const; - void release_pdcp_sn(); - void release_rlc_sn(); - uint32_t rlc_sn() const { return rlc_sn_; } - uint32_t pdcp_sn() const { return pdcp_sn_; } - bool empty() const { return rlc_sn_ == invalid_rlc_sn and pdcp_sn_ == invalid_pdcp_sn; } - - private: - friend struct rlc_am_pdu_segment_pool; - uint32_t rlc_sn_ = invalid_rlc_sn; - uint32_t pdcp_sn_ = invalid_pdcp_sn; - rlc_am_pdu_segment_pool* parent_pool = nullptr; - }; - - rlc_am_pdu_segment_pool(); - rlc_am_pdu_segment_pool(const rlc_am_pdu_segment_pool&) = delete; - rlc_am_pdu_segment_pool(rlc_am_pdu_segment_pool&&) = delete; - rlc_am_pdu_segment_pool& operator=(const rlc_am_pdu_segment_pool&) = delete; - rlc_am_pdu_segment_pool& operator=(rlc_am_pdu_segment_pool&&) = delete; - bool has_segments() const { return not free_list.empty(); } - bool make_segment(rlc_amd_tx_pdu& rlc_list, pdcp_pdu_info& pdcp_info); - -private: - intrusive_forward_list free_list; - std::array segments; -}; - -/// RLC AM PDU Segment, containing the PDCP SN and RLC SN it has been assigned to, and its current ACK state -using rlc_am_pdu_segment = rlc_am_pdu_segment_pool::segment_resource; - -struct rlc_amd_rx_pdu { - rlc_amd_pdu_header_t header; - unique_byte_buffer_t buf; - uint32_t rlc_sn; - - rlc_amd_rx_pdu() = default; - explicit rlc_amd_rx_pdu(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {} -}; - -struct rlc_amd_rx_pdu_segments_t { - std::list segments; -}; - -/// Class that contains the parameters and state (e.g. segments) of a RLC PDU -class rlc_amd_tx_pdu -{ - using list_type = intrusive_forward_list; - const static uint32_t invalid_rlc_sn = std::numeric_limits::max(); - - list_type list; - -public: - using iterator = typename list_type::iterator; - using const_iterator = typename list_type::const_iterator; - - const uint32_t rlc_sn = invalid_rlc_sn; - uint32_t retx_count = 0; - rlc_amd_pdu_header_t header; - unique_byte_buffer_t buf; - - explicit rlc_amd_tx_pdu(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {} - rlc_amd_tx_pdu(const rlc_amd_tx_pdu&) = delete; - rlc_amd_tx_pdu(rlc_amd_tx_pdu&& other) noexcept = default; - rlc_amd_tx_pdu& operator=(const rlc_amd_tx_pdu& other) = delete; - rlc_amd_tx_pdu& operator=(rlc_amd_tx_pdu&& other) = delete; - ~rlc_amd_tx_pdu(); - - // Segment List Interface - void add_segment(rlc_am_pdu_segment& segment) { list.push_front(&segment); } - const_iterator begin() const { return list.begin(); } - const_iterator end() const { return list.end(); } - iterator begin() { return list.begin(); } - iterator end() { return list.end(); } -}; - -struct rlc_amd_retx_t { - uint32_t sn; - bool is_segment; - uint32_t so_start; - uint32_t so_end; -}; - -struct rlc_sn_info_t { - uint32_t sn; - bool is_acked; -}; - -/// Class that contains the parameters and state (e.g. unACKed segments) of a PDCP PDU -class pdcp_pdu_info -{ - using list_type = intrusive_double_linked_list; - - list_type list; // List of unACKed RLC PDUs that contain segments that belong to the PDCP PDU. - -public: - const static uint32_t status_report_sn = std::numeric_limits::max(); - const static uint32_t invalid_pdcp_sn = std::numeric_limits::max() - 1; - - using iterator = typename list_type::iterator; - using const_iterator = typename list_type::const_iterator; - - // Copy is forbidden to avoid multiple PDCP SN references to the same segment - pdcp_pdu_info() = default; - pdcp_pdu_info(pdcp_pdu_info&&) noexcept = default; - pdcp_pdu_info(const pdcp_pdu_info&) noexcept = delete; - pdcp_pdu_info& operator=(const pdcp_pdu_info&) noexcept = delete; - pdcp_pdu_info& operator=(pdcp_pdu_info&&) noexcept = default; - ~pdcp_pdu_info() { clear(); } - - uint32_t sn = invalid_pdcp_sn; - bool fully_txed = false; // Boolean indicating if the SDU is fully transmitted. - - bool fully_acked() const { return fully_txed and list.empty(); } - bool valid() const { return sn != invalid_pdcp_sn; } - - // Interface for list of unACKed RLC segments of the PDCP PDU - void add_segment(rlc_am_pdu_segment& segment) { list.push_front(&segment); } - void ack_segment(rlc_am_pdu_segment& segment); - void clear() - { - sn = invalid_pdcp_sn; - fully_txed = false; - while (not list.empty()) { - ack_segment(list.front()); - } - } - const_iterator begin() const { return list.begin(); } - const_iterator end() const { return list.end(); } -}; - -template -struct rlc_ringbuffer_t { - T& add_pdu(size_t sn) - { - srsran_expect(not has_sn(sn), "The same SN=%zd should not be added twice", sn); - window.overwrite(sn, T(sn)); - return window[sn]; - } - void remove_pdu(size_t sn) - { - srsran_expect(has_sn(sn), "The removed SN=%zd is not in the window", sn); - window.erase(sn); - } - T& operator[](size_t sn) { return window[sn]; } - size_t size() const { return window.size(); } - bool empty() const { return window.empty(); } - void clear() { window.clear(); } - - bool has_sn(uint32_t sn) const { return window.contains(sn); } - - // Return the sum data bytes of all active PDUs (check PDU is non-null) - uint32_t get_buffered_bytes() - { - uint32_t buff_size = 0; - for (const auto& pdu : window) { - if (pdu.second.buf != nullptr) { - buff_size += pdu.second.buf->N_bytes; - } - } - return buff_size; - } - -private: - srsran::static_circular_map window; -}; - -struct buffered_pdcp_pdu_list { -public: - explicit buffered_pdcp_pdu_list(); - void clear(); - - void add_pdcp_sdu(uint32_t sn) - { - srsran_expect(sn <= max_pdcp_sn or sn == status_report_sn, "Invalid PDCP SN=%d", sn); - srsran_assert(not has_pdcp_sn(sn), "Cannot re-add same PDCP SN twice"); - pdcp_pdu_info& pdu = get_pdu_(sn); - if (pdu.valid()) { - pdu.clear(); - count--; - } - pdu.sn = sn; - count++; - } - void clear_pdcp_sdu(uint32_t sn) - { - pdcp_pdu_info& pdu = get_pdu_(sn); - if (not pdu.valid()) { - return; - } - pdu.clear(); - count--; - } - - pdcp_pdu_info& operator[](uint32_t sn) - { - srsran_expect(has_pdcp_sn(sn), "Invalid access to non-existent PDCP SN=%d", sn); - return get_pdu_(sn); - } - bool has_pdcp_sn(uint32_t pdcp_sn) const - { - srsran_expect(pdcp_sn <= max_pdcp_sn or pdcp_sn == status_report_sn, "Invalid PDCP SN=%d", pdcp_sn); - return get_pdu_(pdcp_sn).sn == pdcp_sn; - } - uint32_t nof_sdus() const { return count; } - -private: - const static size_t max_pdcp_sn = 262143u; - const static size_t buffer_size = 4096u; - const static uint32_t status_report_sn = pdcp_pdu_info::status_report_sn; - - pdcp_pdu_info& get_pdu_(uint32_t sn) - { - return (sn == status_report_sn) ? status_report_pdu : buffered_pdus[static_cast(sn % buffer_size)]; - } - const pdcp_pdu_info& get_pdu_(uint32_t sn) const - { - return (sn == status_report_sn) ? status_report_pdu : buffered_pdus[static_cast(sn % buffer_size)]; - } - - // size equal to buffer_size - std::vector buffered_pdus; - pdcp_pdu_info status_report_pdu; - uint32_t count = 0; -}; - -class pdu_retx_queue -{ -public: - rlc_amd_retx_t& push() - { - assert(not full()); - rlc_amd_retx_t& p = buffer[wpos]; - wpos = (wpos + 1) % RLC_AM_WINDOW_SIZE; - return p; - } - - void pop() { rpos = (rpos + 1) % RLC_AM_WINDOW_SIZE; } - - rlc_amd_retx_t& front() - { - assert(not empty()); - return buffer[rpos]; - } - - void clear() - { - wpos = 0; - rpos = 0; - } - - bool has_sn(uint32_t sn) const - { - for (size_t i = rpos; i != wpos; i = (i + 1) % RLC_AM_WINDOW_SIZE) { - if (buffer[i].sn == sn) { - return true; - } - } - return false; - } - - size_t size() const { return (wpos >= rpos) ? wpos - rpos : RLC_AM_WINDOW_SIZE + wpos - rpos; } - bool empty() const { return wpos == rpos; } - bool full() const { return size() == RLC_AM_WINDOW_SIZE - 1; } - -private: - std::array buffer; - size_t wpos = 0; - size_t rpos = 0; -}; - -class rlc_am_lte : public rlc_common +/****************************** + * + * RLC AM LTE entity + * + *****************************/ + +/****************************** + * RLC AM LTE TX entity + *****************************/ +class rlc_am_lte_tx; +class rlc_am_lte_rx; +class rlc_am_lte_tx : public rlc_am::rlc_am_base_tx, timer_callback { public: - rlc_am_lte(srslog::basic_logger& logger, - uint32_t lcid_, - srsue::pdcp_interface_rlc* pdcp_, - srsue::rrc_interface_rlc* rrc_, - srsran::timer_handler* timers_); + explicit rlc_am_lte_tx(rlc_am* parent_); + ~rlc_am_lte_tx() = default; + void set_rx(rlc_am_lte_rx* rx_) { rx = rx_; }; bool configure(const rlc_config_t& cfg_); + void empty_queue(); void reestablish(); void stop(); - void empty_queue(); - - rlc_mode_t get_mode(); - uint32_t get_bearer(); - - // PDCP interface - void write_sdu(unique_byte_buffer_t sdu); - void discard_sdu(uint32_t pdcp_sn); - bool sdu_queue_is_full(); + uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes); - // MAC interface bool has_data(); uint32_t get_buffer_state(); - void get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue); - uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes); - void write_pdu(uint8_t* payload, uint32_t nof_bytes); - - rlc_bearer_metrics_t get_metrics(); - void reset_metrics(); + void get_buffer_state(uint32_t& n_bytes_newtx, uint32_t& n_bytes_prio); - void set_bsr_callback(bsr_callback_t callback); + void empty_queue_nolock(); + void debug_state(); -private: - // Transmitter sub-class - class rlc_am_lte_tx : public timer_callback - { - public: - rlc_am_lte_tx(rlc_am_lte* parent_); - ~rlc_am_lte_tx(); + // Timeout callback interface + void timer_expired(uint32_t timeout_id) final; - bool configure(const rlc_config_t& cfg_); + // Interface for Rx subclass + void handle_control_pdu(uint8_t* payload, uint32_t nof_bytes); - void empty_queue(); - void reestablish(); - void stop(); +private: + void stop_nolock(); - int write_sdu(unique_byte_buffer_t sdu); - uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes); - void discard_sdu(uint32_t discard_sn); - bool sdu_queue_is_full(); + int build_status_pdu(uint8_t* payload, uint32_t nof_bytes); + int build_retx_pdu(uint8_t* payload, uint32_t nof_bytes); + int build_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_retx_lte_t retx); + int build_data_pdu(uint8_t* payload, uint32_t nof_bytes); + void update_notification_ack_info(uint32_t rlc_sn); - bool has_data(); - uint32_t get_buffer_state(); - void get_buffer_state(uint32_t& new_tx, uint32_t& prio_tx); + int required_buffer_size(const rlc_amd_retx_lte_t& retx); + void retransmit_pdu(uint32_t sn); - // Timeout callback interface - void timer_expired(uint32_t timeout_id); + // Helpers + bool window_full(); + bool poll_required(); + bool do_status(); + void check_sn_reached_max_retx(uint32_t sn); + void get_buffer_state_nolock(uint32_t& new_tx, uint32_t& prio_tx); - // Interface for Rx subclass - void handle_control_pdu(uint8_t* payload, uint32_t nof_bytes); + rlc_am* parent = nullptr; + rlc_am_lte_rx* rx = nullptr; + byte_buffer_pool* pool = nullptr; + rlc_am_pdu_segment_pool segment_pool; - void set_bsr_callback(bsr_callback_t callback); + /**************************************************************************** + * Configurable parameters + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ - private: - void stop_nolock(); + rlc_am_config_t cfg = {}; - int build_status_pdu(uint8_t* payload, uint32_t nof_bytes); - int build_retx_pdu(uint8_t* payload, uint32_t nof_bytes); - int build_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_retx_t retx); - int build_data_pdu(uint8_t* payload, uint32_t nof_bytes); - void update_notification_ack_info(uint32_t rlc_sn); + // TX SDU buffers + unique_byte_buffer_t tx_sdu; - void debug_state(); - void empty_queue_nolock(); + /**************************************************************************** + * State variables and counters + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ - int required_buffer_size(const rlc_amd_retx_t& retx); - void retransmit_pdu(uint32_t sn); + // Tx state variables + uint32_t vt_a = 0; // ACK state. SN of next PDU in sequence to be ACKed. Low edge of tx window. + uint32_t vt_ms = RLC_AM_WINDOW_SIZE; // Max send state. High edge of tx window. vt_a + window_size. + uint32_t vt_s = 0; // Send state. SN to be assigned for next PDU. + uint32_t poll_sn = 0; // Poll send state. SN of most recent PDU txed with poll bit set. - void get_buffer_state_nolock(uint32_t& new_tx, uint32_t& prio_tx); + // Tx counters + uint32_t pdu_without_poll = 0; + uint32_t byte_without_poll = 0; - // Helpers - bool poll_required(); - bool do_status(); - void check_sn_reached_max_retx(uint32_t sn); + rlc_status_pdu_t tx_status; - rlc_am_lte* parent = nullptr; - byte_buffer_pool* pool = nullptr; - srslog::basic_logger& logger; - rlc_am_pdu_segment_pool segment_pool; + /**************************************************************************** + * Timers + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ - /**************************************************************************** - * Configurable parameters - * Ref: 3GPP TS 36.322 v10.0.0 Section 7 - ***************************************************************************/ + srsran::timer_handler::unique_timer poll_retx_timer; + srsran::timer_handler::unique_timer status_prohibit_timer; - rlc_am_config_t cfg = {}; - - // TX SDU buffers - byte_buffer_queue tx_sdu_queue; - unique_byte_buffer_t tx_sdu; - - bool tx_enabled = false; - - /**************************************************************************** - * State variables and counters - * Ref: 3GPP TS 36.322 v10.0.0 Section 7 - ***************************************************************************/ + // SDU info for PDCP notifications + buffered_pdcp_pdu_list undelivered_sdu_info_queue; - // Tx state variables - uint32_t vt_a = 0; // ACK state. SN of next PDU in sequence to be ACKed. Low edge of tx window. - uint32_t vt_ms = RLC_AM_WINDOW_SIZE; // Max send state. High edge of tx window. vt_a + window_size. - uint32_t vt_s = 0; // Send state. SN to be assigned for next PDU. - uint32_t poll_sn = 0; // Poll send state. SN of most recent PDU txed with poll bit set. - - // Tx counters - uint32_t pdu_without_poll = 0; - uint32_t byte_without_poll = 0; - - rlc_status_pdu_t tx_status; + // Tx windows + rlc_ringbuffer_t, RLC_AM_WINDOW_SIZE> tx_window; + pdu_retx_queue retx_queue; + pdcp_sn_vector_t notify_info_vec; - /**************************************************************************** - * Timers - * Ref: 3GPP TS 36.322 v10.0.0 Section 7 - ***************************************************************************/ + // Mutexes + std::mutex mutex; - srsran::timer_handler::unique_timer poll_retx_timer; - srsran::timer_handler::unique_timer status_prohibit_timer; + // default to RLC SDU queue length + const uint32_t MAX_SDUS_PER_RLC_PDU = RLC_TX_QUEUE_LEN; +}; - // SDU info for PDCP notifications - buffered_pdcp_pdu_list undelivered_sdu_info_queue; - - // Callback function for buffer status report - bsr_callback_t bsr_callback; - - // Tx windows - rlc_ringbuffer_t tx_window; - pdu_retx_queue retx_queue; - pdcp_sn_vector_t notify_info_vec; +/****************************** + * RLC AM LTE RX entity + *****************************/ +class rlc_am_lte_rx : public rlc_am::rlc_am_base_rx, public timer_callback +{ +public: + explicit rlc_am_lte_rx(rlc_am* parent_); + ~rlc_am_lte_rx() = default; - // Mutexes - std::mutex mutex; + void set_tx(rlc_am_lte_tx* tx_) { tx = tx_; }; + bool configure(const rlc_config_t& cfg_) final; + void reestablish() final; + void stop() final; - // default to RLC SDU queue length - const uint32_t MAX_SDUS_PER_RLC_PDU = RLC_TX_QUEUE_LEN; - }; + uint32_t get_rx_buffered_bytes() final; // returns sum of PDUs in rx_window + uint32_t get_sdu_rx_latency_ms() final; - // Receiver sub-class - class rlc_am_lte_rx : public timer_callback - { - public: - rlc_am_lte_rx(rlc_am_lte* parent_); - ~rlc_am_lte_rx(); + // Timeout callback interface + void timer_expired(uint32_t timeout_id) final; - bool configure(rlc_am_config_t cfg_); - void reestablish(); - void stop(); + // Functions needed by Tx subclass to query rx state + int get_status_pdu_length(); + int get_status_pdu(rlc_status_pdu_t* status, uint32_t nof_bytes); + bool get_do_status(); - void write_pdu(uint8_t* payload, uint32_t nof_bytes); - - uint32_t get_rx_buffered_bytes(); // returns sum of PDUs in rx_window - uint32_t get_sdu_rx_latency_ms(); - - // Timeout callback interface - void timer_expired(uint32_t timeout_id); - - // Functions needed by Tx subclass to query rx state - int get_status_pdu_length(); - int get_status_pdu(rlc_status_pdu_t* status, const uint32_t nof_bytes); - bool get_do_status(); - - private: - void handle_data_pdu(uint8_t* payload, uint32_t nof_bytes, rlc_amd_pdu_header_t& header); - void handle_data_pdu_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_pdu_header_t& header); - void reassemble_rx_sdus(); - bool inside_rx_window(const int16_t sn); - void debug_state(); - void print_rx_segments(); - bool add_segment_and_check(rlc_amd_rx_pdu_segments_t* pdu, rlc_amd_rx_pdu* segment); - void reset_status(); - - rlc_am_lte* parent = nullptr; - byte_buffer_pool* pool = nullptr; - srslog::basic_logger& logger; - - /**************************************************************************** - * Configurable parameters - * Ref: 3GPP TS 36.322 v10.0.0 Section 7 - ***************************************************************************/ - rlc_am_config_t cfg = {}; - - // RX SDU buffers - unique_byte_buffer_t rx_sdu; - - /**************************************************************************** - * State variables and counters - * Ref: 3GPP TS 36.322 v10.0.0 Section 7 - ***************************************************************************/ - - // Rx state variables - uint32_t vr_r = 0; // Receive state. SN following last in-sequence received PDU. Low edge of rx window - uint32_t vr_mr = RLC_AM_WINDOW_SIZE; // Max acceptable receive state. High edge of rx window. vr_r + window size. - uint32_t vr_x = 0; // t_reordering state. SN following PDU which triggered t_reordering. - uint32_t vr_ms = 0; // Max status tx state. Highest possible value of SN for ACK_SN in status PDU. - uint32_t vr_h = 0; // Highest rx state. SN following PDU with highest SN among rxed PDUs. - - // Mutex to protect members - std::mutex mutex; - - // Rx windows - rlc_ringbuffer_t rx_window; - std::map rx_segments; - - bool poll_received = false; - std::atomic do_status = {false}; // light-weight access from Tx entity - - /**************************************************************************** - * Timers - * Ref: 3GPP TS 36.322 v10.0.0 Section 7 - ***************************************************************************/ - - srsran::timer_handler::unique_timer reordering_timer; - - srsran::rolling_average sdu_rx_latency_ms; - }; - - // Common variables needed/provided by parent class - srsue::rrc_interface_rlc* rrc = nullptr; - srslog::basic_logger& logger; - srsue::pdcp_interface_rlc* pdcp = nullptr; - srsran::timer_handler* timers = nullptr; - uint32_t lcid = 0; - rlc_config_t cfg = {}; - std::string rb_name; - - static const int poll_periodicity = 8; // After how many data PDUs a status PDU shall be requested - - // Rx and Tx objects - rlc_am_lte_tx tx; - rlc_am_lte_rx rx; - - std::mutex metrics_mutex; - rlc_bearer_metrics_t metrics = {}; +private: + void handle_data_pdu(uint8_t* payload, uint32_t nof_bytes) final; + void handle_data_pdu_full(uint8_t* payload, uint32_t nof_bytes, rlc_amd_pdu_header_t& header); + void handle_data_pdu_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_pdu_header_t& header); + void reassemble_rx_sdus(); + bool inside_rx_window(const int16_t sn); + void debug_state(); + void print_rx_segments(); + bool add_segment_and_check(rlc_amd_rx_pdu_segments_t* pdu, rlc_amd_rx_pdu* segment); + void reset_status(); + + rlc_am* parent = nullptr; + rlc_am_lte_tx* tx = nullptr; + byte_buffer_pool* pool = nullptr; + + /**************************************************************************** + * Configurable parameters + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ + rlc_am_config_t cfg = {}; + + // RX SDU buffers + unique_byte_buffer_t rx_sdu; + + /**************************************************************************** + * State variables and counters + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ + + // Rx state variables + uint32_t vr_r = 0; // Receive state. SN following last in-sequence received PDU. Low edge of rx window + uint32_t vr_mr = RLC_AM_WINDOW_SIZE; // Max acceptable receive state. High edge of rx window. vr_r + window size. + uint32_t vr_x = 0; // t_reordering state. SN following PDU which triggered t_reordering. + uint32_t vr_ms = 0; // Max status tx state. Highest possible value of SN for ACK_SN in status PDU. + uint32_t vr_h = 0; // Highest rx state. SN following PDU with highest SN among rxed PDUs. + + // Mutex to protect members + std::mutex mutex; + + // Rx windows + rlc_ringbuffer_t rx_window; + std::map rx_segments; + + bool poll_received = false; + std::atomic do_status = {false}; // light-weight access from Tx entity + + /**************************************************************************** + * Timers + * Ref: 3GPP TS 36.322 v10.0.0 Section 7 + ***************************************************************************/ + + srsran::timer_handler::unique_timer reordering_timer; + + srsran::rolling_average sdu_rx_latency_ms; }; -/**************************************************************************** - * Header pack/unpack helper functions - * Ref: 3GPP TS 36.322 v10.0.0 Section 6.2.1 - ***************************************************************************/ -void rlc_am_read_data_pdu_header(byte_buffer_t* pdu, rlc_amd_pdu_header_t* header); -void rlc_am_read_data_pdu_header(uint8_t** payload, uint32_t* nof_bytes, rlc_amd_pdu_header_t* header); -void rlc_am_write_data_pdu_header(rlc_amd_pdu_header_t* header, byte_buffer_t* pdu); -void rlc_am_write_data_pdu_header(rlc_amd_pdu_header_t* header, uint8_t** payload); -void rlc_am_read_status_pdu(byte_buffer_t* pdu, rlc_status_pdu_t* status); -void rlc_am_read_status_pdu(uint8_t* payload, uint32_t nof_bytes, rlc_status_pdu_t* status); -void rlc_am_write_status_pdu(rlc_status_pdu_t* status, byte_buffer_t* pdu); -int rlc_am_write_status_pdu(rlc_status_pdu_t* status, uint8_t* payload); - -uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t* header); -uint32_t rlc_am_packed_length(rlc_status_pdu_t* status); -uint32_t rlc_am_packed_length(rlc_amd_retx_t retx); -bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status, uint32_t rx_win_min = 0); -bool rlc_am_is_pdu_segment(uint8_t* payload); -std::string rlc_am_undelivered_sdu_info_to_string(const std::map& info_queue); -void log_rlc_amd_pdu_header_to_string(srslog::log_channel& log_ch, const rlc_amd_pdu_header_t& header); -bool rlc_am_start_aligned(const uint8_t fi); -bool rlc_am_end_aligned(const uint8_t fi); -bool rlc_am_is_unaligned(const uint8_t fi); -bool rlc_am_not_start_aligned(const uint8_t fi); - } // namespace srsran #endif // SRSRAN_RLC_AM_LTE_H diff --git a/lib/include/srsran/rlc/rlc_am_lte_packing.h b/lib/include/srsran/rlc/rlc_am_lte_packing.h new file mode 100644 index 0000000000..ee4ce6eca0 --- /dev/null +++ b/lib/include/srsran/rlc/rlc_am_lte_packing.h @@ -0,0 +1,137 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_RLC_AM_LTE_PACKING_H +#define SRSRAN_RLC_AM_LTE_PACKING_H + +#include "srsran/common/string_helpers.h" +#include "srsran/rlc/rlc_am_base.h" +#include "srsran/rlc/rlc_am_data_structs.h" // required for rlc_am_pdu_segment +#include + +namespace srsran { + +struct rlc_sn_info_t { + uint32_t sn; + bool is_acked; +}; + +struct rlc_amd_rx_pdu { + rlc_amd_pdu_header_t header; + unique_byte_buffer_t buf; + uint32_t rlc_sn = 0; + + rlc_amd_rx_pdu() = default; + explicit rlc_amd_rx_pdu(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {} +}; + +struct rlc_amd_rx_pdu_segments_t { + std::list segments; +}; + +/**************************************************************************** + * Header pack/unpack helper functions + * Ref: 3GPP TS 36.322 v10.0.0 Section 6.2.1 + ***************************************************************************/ +void rlc_am_read_data_pdu_header(byte_buffer_t* pdu, rlc_amd_pdu_header_t* header); +void rlc_am_read_data_pdu_header(uint8_t** payload, uint32_t* nof_bytes, rlc_amd_pdu_header_t* header); +void rlc_am_write_data_pdu_header(rlc_amd_pdu_header_t* header, byte_buffer_t* pdu); +void rlc_am_write_data_pdu_header(rlc_amd_pdu_header_t* header, uint8_t** payload); +void rlc_am_read_status_pdu(byte_buffer_t* pdu, rlc_status_pdu_t* status); +void rlc_am_read_status_pdu(uint8_t* payload, uint32_t nof_bytes, rlc_status_pdu_t* status); +void rlc_am_write_status_pdu(rlc_status_pdu_t* status, byte_buffer_t* pdu); +int rlc_am_write_status_pdu(rlc_status_pdu_t* status, uint8_t* payload); + +uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t* header); +uint32_t rlc_am_packed_length(rlc_status_pdu_t* status); +uint32_t rlc_am_packed_length(rlc_amd_retx_lte_t retx); +bool rlc_am_is_pdu_segment(uint8_t* payload); +bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status, uint32_t rx_win_min = 0); +bool rlc_am_start_aligned(const uint8_t fi); +bool rlc_am_end_aligned(const uint8_t fi); +bool rlc_am_is_unaligned(const uint8_t fi); +bool rlc_am_not_start_aligned(const uint8_t fi); +std::string +rlc_am_undelivered_sdu_info_to_string(const std::map >& info_queue); + +template +void log_rlc_amd_pdu_header_to_string(srslog::log_channel& log_ch, + const std::string& rb_name, + const char* fmt_str, + const rlc_amd_pdu_header_t& header, + Args&&... args) +{ + if (not log_ch.enabled()) { + return; + } + + fmt::memory_buffer buffer; + fmt::format_to(buffer, + "{}: [{}, RF={}, P={}, FI={}, SN={}, LSF={}, SO={}, N_li={}", + rb_name, + rlc_dc_field_text[header.dc], + (header.rf ? "1" : "0"), + (header.p ? "1" : "0"), + (header.fi ? "1" : "0"), + header.sn, + (header.lsf ? "1" : "0"), + header.so, + header.N_li); + if (header.N_li > 0) { + fmt::format_to(buffer, " ({}", header.li[0]); + for (uint32_t i = 1; i < header.N_li; ++i) { + fmt::format_to(buffer, ", {}", header.li[i]); + } + fmt::format_to(buffer, ")"); + } + fmt::format_to(buffer, "]"); + + log_ch(fmt_str, std::forward(args)..., to_c_str(buffer)); +} + +template +void log_rlc_am_status_pdu_to_string(srslog::log_channel& log_ch, + const std::string& rb_name, + const char* fmt_str, + rlc_status_pdu_t* status, + Args&&... args) +{ + if (not log_ch.enabled()) { + return; + } + fmt::memory_buffer buffer; + fmt::format_to(buffer, "{}: ACK_SN = {}, N_nack = {}", rb_name, status->ack_sn, status->N_nack); + if (status->N_nack > 0) { + fmt::format_to(buffer, ", NACK_SN = "); + for (uint32_t i = 0; i < status->N_nack; ++i) { + if (status->nacks[i].has_so) { + fmt::format_to( + buffer, "[{} {}:{}]", status->nacks[i].nack_sn, status->nacks[i].so_start, status->nacks[i].so_end); + } else { + fmt::format_to(buffer, "[{}]", status->nacks[i].nack_sn); + } + } + } + log_ch(fmt_str, std::forward(args)..., to_c_str(buffer)); +} +} // namespace srsran + +#endif // SRSRAN_RLC_AM_LTE_PACKING_H diff --git a/lib/include/srsran/rlc/rlc_am_nr.h b/lib/include/srsran/rlc/rlc_am_nr.h index 78fb0bf409..ccea5aa386 100644 --- a/lib/include/srsran/rlc/rlc_am_nr.h +++ b/lib/include/srsran/rlc/rlc_am_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,7 +24,11 @@ #include "srsran/common/buffer_pool.h" #include "srsran/common/common.h" +#include "srsran/common/timers.h" +#include "srsran/interfaces/pdcp_interface_types.h" #include "srsran/rlc/rlc_am_base.h" +#include "srsran/rlc/rlc_am_data_structs.h" +#include "srsran/rlc/rlc_am_nr_packing.h" #include "srsran/upper/byte_buffer_queue.h" #include #include @@ -33,42 +37,285 @@ namespace srsran { -typedef struct { - rlc_am_nr_pdu_header_t header; - unique_byte_buffer_t buf; -} rlc_amd_pdu_nr_t; +/****************************** + * + * RLC AM NR entity + * + *****************************/ +class rlc_am_nr_tx; +class rlc_am_nr_rx; + +/**************************************************************************** + * Tx state variables + * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.1 + ***************************************************************************/ +struct rlc_am_nr_tx_state_t { + /* + * TX_Next_Ack: This state variable holds the value of the SN of the next RLC SDU for which a positive + * acknowledgment is to be received in-sequence, and it serves as the lower edge of the transmitting window. It is + * initially set to 0, and is updated whenever the AM RLC entity receives a positive acknowledgment for an RLC SDU + * with SN = TX_Next_Ack. + */ + uint32_t tx_next_ack; + /* + * TX_Next: This state variable holds the value of the SN to be assigned for the next newly generated AMD PDU. It is + * initially set to 0, and is updated whenever the AM RLC entity constructs an AMD PDU with SN = TX_Next and + * contains an RLC SDU or the last segment of a RLC SDU. + */ + uint32_t tx_next; + /* + * POLL_SN: This state variable holds the value of the highest SN of the AMD PDU among the AMD PDUs submitted to + * lower layer when POLL_SN is set according to sub clause 5.3.3.2. It is initially set to 0. + */ + uint32_t poll_sn; + /* + * PDU_WITHOUT_POLL: This counter is initially set to 0. It counts the number of AMD PDUs sent since the most recent + * poll bit was transmitted. + */ + uint32_t pdu_without_poll; + /* + * BYTE_WITHOUT_POLL: This counter is initially set to 0. It counts the number of data bytes sent since the most + * recent poll bit was transmitted. + */ + uint32_t byte_without_poll; +}; + +struct rlc_amd_tx_pdu_nr { + const uint32_t rlc_sn = INVALID_RLC_SN; + uint32_t pdcp_sn = INVALID_RLC_SN; + rlc_am_nr_pdu_header_t header = {}; + unique_byte_buffer_t sdu_buf = nullptr; + uint32_t retx_count = RETX_COUNT_NOT_STARTED; + struct pdu_segment { + uint32_t so = 0; + uint32_t payload_len = 0; + }; + std::list segment_list; + explicit rlc_amd_tx_pdu_nr(uint32_t sn) : rlc_sn(sn) {} +}; + +class rlc_am_nr_tx : public rlc_am::rlc_am_base_tx +{ +public: + explicit rlc_am_nr_tx(rlc_am* parent_); + ~rlc_am_nr_tx() = default; + + void set_rx(rlc_am_nr_rx* rx_) { rx = rx_; } + bool configure(const rlc_config_t& cfg_) final; + uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) final; + void handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) final; + void handle_nack(const rlc_status_nack_t& nack, std::set& retx_sn_set); + + void reestablish() final; + void stop() final; + + int write_sdu(unique_byte_buffer_t sdu); + void empty_queue() final; + void empty_queue_no_lock(); + + // Data PDU helpers + uint32_t build_new_pdu(uint8_t* payload, uint32_t nof_bytes); + uint32_t build_new_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint8_t* payload, uint32_t nof_bytes); + uint32_t build_continuation_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint8_t* payload, uint32_t nof_bytes); + uint32_t build_retx_pdu(uint8_t* payload, uint32_t nof_bytes); + uint32_t build_retx_pdu_without_segmentation(rlc_amd_retx_nr_t retx, uint8_t* payload, uint32_t nof_bytes); + uint32_t build_retx_pdu_with_segmentation(rlc_amd_retx_nr_t& retx, uint8_t* payload, uint32_t nof_bytes); + bool is_retx_segmentation_required(const rlc_amd_retx_nr_t& retx, uint32_t nof_bytes); + uint32_t get_retx_expected_hdr_len(const rlc_amd_retx_nr_t& retx); + + // Buffer State + bool has_data() final; + uint32_t get_buffer_state() final; + void get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue) final; + + // Status PDU + bool do_status(); + uint32_t build_status_pdu(byte_buffer_t* payload, uint32_t nof_bytes); + + // Polling + uint8_t get_pdu_poll(uint32_t sn, bool is_retx, uint32_t sdu_bytes); + + // Timers + void timer_expired(uint32_t timeout_id); + + // Window helpers + bool inside_tx_window(uint32_t sn) const; + bool valid_ack_sn(uint32_t sn) const; + +private: + rlc_am* parent = nullptr; + rlc_am_nr_rx* rx = nullptr; + + uint32_t mod_nr = cardinality(rlc_am_nr_sn_size_t()); + inline uint32_t tx_mod_base_nr(uint32_t sn) const; + void check_sn_reached_max_retx(uint32_t sn); + + /**************************************************************************** + * Configurable parameters + * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.4 + ***************************************************************************/ + rlc_am_nr_config_t cfg = {}; -///< add class here + /**************************************************************************** + * Tx state variables + * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.1 + ***************************************************************************/ + struct rlc_am_nr_tx_state_t st = {}; + std::unique_ptr > tx_window; + + // Queues, buffers and container + pdu_retx_queue_list retx_queue; + uint32_t sdu_under_segmentation_sn = INVALID_RLC_SN; // SN of the SDU currently being segmented. + pdcp_sn_vector_t notify_info_vec; + + // Helper constants + uint32_t min_hdr_size = 2; // Pre-initialized for 12 bit SN, updated by configure() + uint32_t so_size = 2; + uint32_t max_hdr_size = 4; // Pre-initialized for 12 bit SN, updated by configure() + + /**************************************************************************** + * Tx constants + * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.2 + ***************************************************************************/ + inline uint32_t tx_window_size() const; + + /**************************************************************************** + * TX timers + * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.3 + ***************************************************************************/ + srsran::timer_handler::unique_timer poll_retransmit_timer; + +public: + // Getters/Setters + void set_tx_state(const rlc_am_nr_tx_state_t& st_) { st = st_; } // This should only be used for testing. + rlc_am_nr_tx_state_t get_tx_state() { return st; } // This should only be used for testing. + uint32_t get_tx_window_utilization() { return tx_window->size(); } // This should only be used for testing. + size_t get_retx_queue_size() const { return retx_queue.size(); } // This should only be used for testing. + + // Debug Helpers + void debug_state() const; + void info_state() const; + void debug_window() const; +}; /**************************************************************************** - * Header pack/unpack helper functions for NR - * Ref: 3GPP TS 38.322 v15.3.0 Section 6.2.2.3 + * State Variables + * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.1 ***************************************************************************/ -uint32_t rlc_am_nr_read_data_pdu_header(const byte_buffer_t* pdu, - const rlc_am_nr_sn_size_t sn_size, - rlc_am_nr_pdu_header_t* header); +struct rlc_am_nr_rx_state_t { + /* + * RX_Next: This state variable holds the value of the SN following the last in-sequence completely received RLC + * SDU, and it serves as the lower edge of the receiving window. It is initially set to 0, and is updated whenever + * the AM RLC entity receives an RLC SDU with SN = RX_Next. + */ + uint32_t rx_next = 0; + /* + * RX_Next_Status_Trigger: This state variable holds the value of the SN following the SN of the RLC SDU which + * triggered t-Reassembly. + */ + uint32_t rx_next_status_trigger = 0; + /* + * RX_Next_Highest: This state variable holds the highest possible value of the SN which can be indicated by + *"ACK_SN" when a STATUS PDU needs to be constructed. It is initially set to 0. + */ + uint32_t rx_highest_status = 0; + /* + * RX_Next_Highest: This state variable holds the value of the SN following the SN of the RLC SDU with the + * highest SN among received RLC SDUs. It is initially set to 0. + */ + uint32_t rx_next_highest = 0; +}; -uint32_t rlc_am_nr_read_data_pdu_header(const uint8_t* payload, - const uint32_t nof_bytes, - const rlc_am_nr_sn_size_t sn_size, - rlc_am_nr_pdu_header_t* header); +// Receiver sub-class +class rlc_am_nr_rx : public rlc_am::rlc_am_base_rx +{ +public: + explicit rlc_am_nr_rx(rlc_am* parent_); + ~rlc_am_nr_rx() = default; -uint32_t rlc_am_nr_write_data_pdu_header(const rlc_am_nr_pdu_header_t& header, byte_buffer_t* pdu); + void set_tx(rlc_am_nr_tx* tx_) { tx = tx_; } + bool configure(const rlc_config_t& cfg_) final; -uint32_t rlc_am_nr_packed_length(const rlc_am_nr_pdu_header_t& header); + void handle_data_pdu(uint8_t* payload, uint32_t nof_bytes) final; -uint32_t -rlc_am_nr_read_status_pdu(const byte_buffer_t* pdu, const rlc_am_nr_sn_size_t sn_size, rlc_am_nr_status_pdu_t* status); + void reestablish() final; + void stop() final; -uint32_t rlc_am_nr_read_status_pdu(const uint8_t* payload, - const uint32_t nof_bytes, - const rlc_am_nr_sn_size_t sn_size, - rlc_am_nr_status_pdu_t* status); + // Status PDU + bool get_do_status(); + uint32_t get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t len); + uint32_t get_status_pdu_length(); -int32_t rlc_am_nr_write_status_pdu(const rlc_am_nr_status_pdu_t& status_pdu, - const rlc_am_nr_sn_size_t sn_size, - byte_buffer_t* pdu); + // Data handling methods + int handle_full_data_sdu(const rlc_am_nr_pdu_header_t& header, const uint8_t* payload, uint32_t nof_bytes); + int handle_segment_data_sdu(const rlc_am_nr_pdu_header_t& header, const uint8_t* payload, uint32_t nof_bytes); + bool inside_rx_window(uint32_t sn) const; + bool valid_ack_sn(uint32_t sn) const; + void write_to_upper_layers(uint32_t lcid, unique_byte_buffer_t sdu); + void insert_received_segment(rlc_amd_rx_pdu_nr segment, rlc_amd_rx_sdu_nr_t::segment_list_t& segment_list) const; + /** + * @brief update_segment_inventory This function updates the flags has_gap and fully_received of an SDU + * according to the current inventory of received SDU segments + * @param rx_sdu The SDU to operate on + */ + void update_segment_inventory(rlc_amd_rx_sdu_nr_t& rx_sdu) const; -} // namespace srsran + // Metrics + uint32_t get_sdu_rx_latency_ms() final; + uint32_t get_rx_buffered_bytes() final; + + // Timers + void timer_expired(uint32_t timeout_id); + + // Helpers + void debug_state() const; + void debug_window() const; + +private: + rlc_am* parent = nullptr; + rlc_am_nr_tx* tx = nullptr; + byte_buffer_pool* pool = nullptr; + uint32_t mod_nr = cardinality(rlc_am_nr_sn_size_t()); + uint32_t rx_mod_base_nr(uint32_t sn) const; + + // RX Window + std::unique_ptr > rx_window; + + // Mutexes + std::mutex mutex; + + /**************************************************************************** + * Rx timers + * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.3 + ***************************************************************************/ + srsran::timer_handler::unique_timer status_prohibit_timer; + srsran::timer_handler::unique_timer reassembly_timer; + + /**************************************************************************** + * Configurable parameters + * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.4 + ***************************************************************************/ + rlc_am_nr_config_t cfg = {}; + + /**************************************************************************** + * Rx state variables + * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.1 + ***************************************************************************/ + struct rlc_am_nr_rx_state_t st = {}; + + /**************************************************************************** + * Rx constants + * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.2 + ***************************************************************************/ + inline uint32_t rx_window_size() const; + +public: + // Getters/Setters + void set_rx_state(const rlc_am_nr_rx_state_t& st_) { st = st_; } // This should only be used for testing. + rlc_am_nr_rx_state_t get_rx_state() { return st; } // This should only be used for testing. + uint32_t get_rx_window_size() { return rx_window->size(); } // This should only be used for testing. +}; + +} // namespace srsran #endif // SRSRAN_RLC_AM_NR_H diff --git a/lib/include/srsran/rlc/rlc_am_nr_packing.h b/lib/include/srsran/rlc/rlc_am_nr_packing.h new file mode 100644 index 0000000000..2922e2cce6 --- /dev/null +++ b/lib/include/srsran/rlc/rlc_am_nr_packing.h @@ -0,0 +1,239 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_RLC_AM_NR_PACKING_H +#define SRSRAN_RLC_AM_NR_PACKING_H + +#include "srsran/common/string_helpers.h" +#include "srsran/rlc/rlc_am_base.h" +#include + +namespace srsran { + +const uint32_t INVALID_RLC_SN = 0xFFFFFFFF; +const uint32_t RETX_COUNT_NOT_STARTED = 0xFFFFFFFF; + +///< AM NR PDU header +struct rlc_am_nr_pdu_header_t { + rlc_am_nr_pdu_header_t() = default; + rlc_am_nr_pdu_header_t(const rlc_am_nr_pdu_header_t& h) = default; + rlc_am_nr_pdu_header_t& operator=(const rlc_am_nr_pdu_header_t&) = default; + rlc_am_nr_pdu_header_t(rlc_am_nr_pdu_header_t&& h) = default; + ~rlc_am_nr_pdu_header_t() = default; + + rlc_am_nr_pdu_header_t& operator=(rlc_am_nr_pdu_header_t&& h) = default; + + rlc_dc_field_t dc = {}; ///< Data/Control (D/C) field + uint8_t p = {}; ///< Polling bit + rlc_nr_si_field_t si = {}; ///< Segmentation info + rlc_am_nr_sn_size_t sn_size = {}; ///< Sequence number size (12 or 18 bits) + uint32_t sn = {}; ///< Sequence number + uint16_t so = {}; ///< Sequence offset +}; + +struct rlc_amd_pdu_nr_t { + rlc_am_nr_pdu_header_t header; + unique_byte_buffer_t buf; +}; + +struct rlc_amd_rx_pdu_nr { + rlc_am_nr_pdu_header_t header = {}; + unique_byte_buffer_t buf = nullptr; + uint32_t rlc_sn = {}; + + rlc_amd_rx_pdu_nr() = default; + explicit rlc_amd_rx_pdu_nr(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {} +}; + +struct rlc_amd_rx_pdu_nr_cmp { + bool operator()(const rlc_amd_rx_pdu_nr& a, const rlc_amd_rx_pdu_nr& b) const { return a.header.so < b.header.so; } +}; + +struct rlc_amd_rx_sdu_nr_t { + uint32_t rlc_sn = 0; + bool fully_received = false; + bool has_gap = false; + unique_byte_buffer_t buf; + using segment_list_t = std::set; + segment_list_t segments; + + rlc_amd_rx_sdu_nr_t() = default; + explicit rlc_amd_rx_sdu_nr_t(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {} +}; + +struct rlc_amd_tx_sdu_nr_t { + uint32_t rlc_sn = INVALID_RLC_SN; + unique_byte_buffer_t buf; + + rlc_amd_tx_sdu_nr_t() = default; + explicit rlc_amd_tx_sdu_nr_t(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {} +}; + +constexpr uint32_t rlc_am_nr_status_pdu_sizeof_header_ack_sn = 3; ///< header fixed part and ACK SN +constexpr uint32_t rlc_am_nr_status_pdu_sizeof_nack_sn_ext_12bit_sn = 2; ///< NACK SN and extension fields (12 bit SN) +constexpr uint32_t rlc_am_nr_status_pdu_sizeof_nack_sn_ext_18bit_sn = 3; ///< NACK SN and extension fields (18 bit SN) +constexpr uint32_t rlc_am_nr_status_pdu_sizeof_nack_so = 4; ///< NACK segment offsets (start and end) +constexpr uint32_t rlc_am_nr_status_pdu_sizeof_nack_range = 1; ///< NACK range (nof consecutively lost SDUs) + +/// AM NR Status PDU header +class rlc_am_nr_status_pdu_t +{ +private: + /// Stored SN size required to compute the packed size + rlc_am_nr_sn_size_t sn_size = rlc_am_nr_sn_size_t::nulltype; + /// Stored modulus to determine continuous sequences across SN overflows + uint32_t mod_nr = cardinality(rlc_am_nr_sn_size_t::nulltype); + /// Internal NACK container; keep in sync with packed_size_ + std::vector nacks_ = {}; + /// Stores the current packed size; sync on each change of nacks_ + uint32_t packed_size_ = rlc_am_nr_status_pdu_sizeof_header_ack_sn; + + void refresh_packed_size(); + uint32_t nack_size(const rlc_status_nack_t& nack) const; + +public: + /// CPT header + rlc_am_nr_control_pdu_type_t cpt = rlc_am_nr_control_pdu_type_t::status_pdu; + /// SN of the next not received RLC Data PDU + uint32_t ack_sn = INVALID_RLC_SN; + /// Read-only reference to NACKs + const std::vector& nacks = nacks_; + /// Read-only reference to packed size + const uint32_t& packed_size = packed_size_; + + rlc_am_nr_status_pdu_t(rlc_am_nr_sn_size_t sn_size); + void reset(); + bool is_continuous_sequence(const rlc_status_nack_t& left, const rlc_status_nack_t& right) const; + void push_nack(const rlc_status_nack_t& nack); + const std::vector& get_nacks() const { return nacks_; } + uint32_t get_packed_size() const { return packed_size; } + bool trim(uint32_t max_packed_size); +}; + +/**************************************************************************** + * Header pack/unpack helper functions for NR + * Ref: 3GPP TS 38.322 v15.3.0 Section 6.2.2.3 + ***************************************************************************/ +uint32_t rlc_am_nr_read_data_pdu_header(const byte_buffer_t* pdu, + const rlc_am_nr_sn_size_t sn_size, + rlc_am_nr_pdu_header_t* header); + +uint32_t rlc_am_nr_read_data_pdu_header(const uint8_t* payload, + const uint32_t nof_bytes, + const rlc_am_nr_sn_size_t sn_size, + rlc_am_nr_pdu_header_t* header); + +uint32_t rlc_am_nr_write_data_pdu_header(const rlc_am_nr_pdu_header_t& header, uint8_t* payload); +uint32_t rlc_am_nr_write_data_pdu_header(const rlc_am_nr_pdu_header_t& header, byte_buffer_t* pdu); + +uint32_t rlc_am_nr_packed_length(const rlc_am_nr_pdu_header_t& header); + +/**************************************************************************** + * Status PDU pack/unpack helper functions for NR + * Ref: 3GPP TS 38.322 v16.2.0 Section 6.2.2.5 + ***************************************************************************/ +uint32_t +rlc_am_nr_read_status_pdu(const byte_buffer_t* pdu, const rlc_am_nr_sn_size_t sn_size, rlc_am_nr_status_pdu_t* status); + +uint32_t rlc_am_nr_read_status_pdu(const uint8_t* payload, + const uint32_t nof_bytes, + const rlc_am_nr_sn_size_t sn_size, + rlc_am_nr_status_pdu_t* status); +uint32_t +rlc_am_nr_read_status_pdu_12bit_sn(const uint8_t* payload, const uint32_t nof_bytes, rlc_am_nr_status_pdu_t* status); +uint32_t +rlc_am_nr_read_status_pdu_18bit_sn(const uint8_t* payload, const uint32_t nof_bytes, rlc_am_nr_status_pdu_t* status); + +int32_t rlc_am_nr_write_status_pdu(const rlc_am_nr_status_pdu_t& status_pdu, + const rlc_am_nr_sn_size_t sn_size, + byte_buffer_t* pdu); +int32_t rlc_am_nr_write_status_pdu_12bit_sn(const rlc_am_nr_status_pdu_t& status_pdu, byte_buffer_t* pdu); +int32_t rlc_am_nr_write_status_pdu_18bit_sn(const rlc_am_nr_status_pdu_t& status_pdu, byte_buffer_t* pdu); + +/** + * Logs Status PDU into provided log channel, using fmt_str as format string + */ +template +void log_rlc_am_nr_status_pdu_to_string(srslog::log_channel& log_ch, + const char* fmt_str, + rlc_am_nr_status_pdu_t* status, + const std::string& rb_name, + Args&&... args) +{ + if (not log_ch.enabled()) { + return; + } + fmt::memory_buffer buffer; + fmt::format_to(buffer, "ACK_SN = {}, N_nack = {}", status->ack_sn, status->nacks.size()); + if (status->nacks.size() > 0) { + fmt::format_to(buffer, ", NACK_SN = "); + for (uint32_t i = 0; i < status->nacks.size(); ++i) { + if (status->nacks[i].has_nack_range) { + if (status->nacks[i].has_so) { + fmt::format_to(buffer, + "[{} {}:{} r{}]", + status->nacks[i].nack_sn, + status->nacks[i].so_start, + status->nacks[i].so_end, + status->nacks[i].nack_range); + } else { + fmt::format_to(buffer, "[{} r{}]", status->nacks[i].nack_sn, status->nacks[i].nack_range); + } + } else { + if (status->nacks[i].has_so) { + fmt::format_to( + buffer, "[{} {}:{}]", status->nacks[i].nack_sn, status->nacks[i].so_start, status->nacks[i].so_end); + } else { + fmt::format_to(buffer, "[{}]", status->nacks[i].nack_sn); + } + } + } + } + log_ch(fmt_str, std::forward(args)..., to_c_str(buffer)); +} + +/* + * Log NR AMD PDUs + */ +inline void log_rlc_am_nr_pdu_header_to_string(srslog::log_channel& log_ch, + const rlc_am_nr_pdu_header_t& header, + const std::string& rb_name) +{ + if (not log_ch.enabled()) { + return; + } + fmt::memory_buffer buffer; + fmt::format_to(buffer, + "{}: [{}, P={}, SI={}, SN_SIZE={}, SN={}, SO={}", + rb_name, + rlc_dc_field_text[header.dc], + (header.p ? "1" : "0"), + to_string_short(header.si), + to_string(header.sn_size), + header.sn, + header.so); + fmt::format_to(buffer, "]"); + + log_ch("%s", to_c_str(buffer)); +} +} // namespace srsran + +#endif // SRSRAN_RLC_AM_NR_PACKING_H diff --git a/lib/include/srsran/rlc/rlc_common.h b/lib/include/srsran/rlc/rlc_common.h index ff9a342228..360d6e86d3 100644 --- a/lib/include/srsran/rlc/rlc_common.h +++ b/lib/include/srsran/rlc/rlc_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,10 +23,13 @@ #define SRSRAN_RLC_COMMON_H #include "srsran/adt/circular_buffer.h" +#include "srsran/adt/circular_map.h" +#include "srsran/adt/intrusive_list.h" #include "srsran/interfaces/rlc_interface_types.h" #include "srsran/rlc/bearer_mem_pool.h" #include "srsran/rlc/rlc_metrics.h" -#include +#include +#include namespace srsran { @@ -35,10 +38,24 @@ namespace srsran { * Ref: 3GPP TS 36.322 v10.0.0 ***************************************************************************/ +#define MOD 1024 #define RLC_AM_WINDOW_SIZE 512 #define RLC_MAX_SDU_SIZE ((1 << 11) - 1) // Length of LI field is 11bits #define RLC_AM_MIN_DATA_PDU_SIZE (3) // AMD PDU with 10 bit SN (length of LI field is 11 bits) (No LI) +#define RLC_AM_NR_TYP_NACKS 512 // Expected number of NACKs in status PDU before expanding space by alloc +#define RLC_AM_NR_MAX_NACKS 2048 // Maximum number of NACKs in status PDU + +#define RlcDebug(fmt, ...) logger.debug("%s: " fmt, rb_name, ##__VA_ARGS__) +#define RlcInfo(fmt, ...) logger.info("%s: " fmt, rb_name, ##__VA_ARGS__) +#define RlcWarning(fmt, ...) logger.warning("%s: " fmt, rb_name, ##__VA_ARGS__) +#define RlcError(fmt, ...) logger.error("%s: " fmt, rb_name, ##__VA_ARGS__) + +#define RlcHexDebug(msg, bytes, fmt, ...) logger.debug(msg, bytes, "%s: " fmt, rb_name, ##__VA_ARGS__) +#define RlcHexInfo(msg, bytes, fmt, ...) logger.info(msg, bytes, "%s: " fmt, rb_name, ##__VA_ARGS__) +#define RlcHexWarning(msg, bytes, fmt, ...) logger.warning(msg, bytes, "%s: " fmt, rb_name, ##__VA_ARGS__) +#define RlcHexError(msg, bytes, fmt, ...) logger.error(msg, bytes, "%s: " fmt, rb_name, ##__VA_ARGS__) + typedef enum { RLC_FI_FIELD_START_AND_END_ALIGNED = 0, RLC_FI_FIELD_NOT_END_ALIGNED, @@ -157,18 +174,33 @@ class rlc_amd_pdu_header_t // NACK helper (for LTE and NR) struct rlc_status_nack_t { - uint32_t nack_sn; - bool has_so; - uint16_t so_start; - uint16_t so_end; + const static uint16_t so_end_of_sdu = 0xFFFF; + + uint32_t nack_sn; // Sequence Number (SN) of first missing SDU + bool has_so; // NACKs continuous sequence of bytes [so_start..so_end] + uint16_t so_start; // First missing byte in SDU with SN=nack_sn + uint16_t so_end; // Last missing byte in SDU with SN=nack_sn or SN=nack_sn+nack_range-1 if has_nack_range. + bool has_nack_range; // NACKs continuous sequence of SDUs + uint8_t nack_range; // Number of SDUs being NACKed (including SN=nack_sn) rlc_status_nack_t() { - has_so = false; - nack_sn = 0; - so_start = 0; - so_end = 0; + has_so = false; + nack_sn = 0; + so_start = 0; + so_end = so_end_of_sdu; + has_nack_range = false; + nack_range = 0; + } + + bool equals(const rlc_status_nack_t& other) const + { + return nack_sn == other.nack_sn && has_so == other.has_so && so_start == other.so_start && so_end == other.so_end && + has_nack_range == other.has_nack_range && nack_range == other.nack_range; } + + bool operator==(const rlc_status_nack_t& other) const { return equals(other); } + bool operator!=(const rlc_status_nack_t& other) const { return not equals(other); } }; // STATUS PDU @@ -184,27 +216,6 @@ struct rlc_status_pdu_t { } }; -/** RLC AM NR structs */ - -///< AM NR PDU header -typedef struct { - rlc_dc_field_t dc; ///< Data/Control (D/C) field - uint8_t p; ///< Polling bit - rlc_nr_si_field_t si; ///< Segmentation info - rlc_am_nr_sn_size_t sn_size; ///< Sequence number size (12 or 18 bits) - uint32_t sn; ///< Sequence number - uint16_t so; ///< Sequence offset -} rlc_am_nr_pdu_header_t; - -///< AM NR Status PDU header (perhaps merge with LTE version) -typedef struct { - rlc_am_nr_control_pdu_type_t cpt; - uint32_t ack_sn; ///< SN of the next not received RLC Data PDU - uint16_t N_nack; ///< number of NACKs - uint8_t nack_range; ///< number of consecutively lost RLC SDUs starting from and including NACK_SN - rlc_status_nack_t nacks[RLC_AM_WINDOW_SIZE]; -} rlc_am_nr_status_pdu_t; - typedef std::function bsr_callback_t; /**************************************************************************** @@ -214,6 +225,7 @@ typedef std::function bsr_callback_t; class rlc_common { public: + explicit rlc_common(srslog::basic_logger& logger_) : logger(logger_) {} virtual ~rlc_common() = default; virtual bool configure(const rlc_config_t& cnfg) = 0; virtual void stop() = 0; @@ -267,8 +279,8 @@ class rlc_common } } - virtual rlc_mode_t get_mode() = 0; - virtual uint32_t get_bearer() = 0; + virtual rlc_mode_t get_mode() = 0; + virtual uint32_t get_lcid() = 0; virtual rlc_bearer_metrics_t get_metrics() = 0; virtual void reset_metrics() = 0; @@ -291,6 +303,10 @@ class rlc_common void* operator new(size_t sz) { return allocate_rlc_bearer(sz); } void operator delete(void* p) { return deallocate_rlc_bearer(p); } +protected: + std::string rb_name = {}; + srslog::basic_logger& logger; + private: bool suspended = false; diff --git a/lib/include/srsran/rlc/rlc_metrics.h b/lib/include/srsran/rlc/rlc_metrics.h index 6c0f23a23f..1604b662b8 100644 --- a/lib/include/srsran/rlc/rlc_metrics.h +++ b/lib/include/srsran/rlc/rlc_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/rlc/rlc_tm.h b/lib/include/srsran/rlc/rlc_tm.h index 333b8339de..8ea2410c65 100644 --- a/lib/include/srsran/rlc/rlc_tm.h +++ b/lib/include/srsran/rlc/rlc_tm.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -50,7 +50,7 @@ class rlc_tm final : public rlc_common void empty_queue() override; rlc_mode_t get_mode() override; - uint32_t get_bearer() override; + uint32_t get_lcid() override; rlc_bearer_metrics_t get_metrics() override; void reset_metrics() override; @@ -71,7 +71,6 @@ class rlc_tm final : public rlc_common private: byte_buffer_pool* pool = nullptr; - srslog::basic_logger& logger; uint32_t lcid = 0; srsue::pdcp_interface_rlc* pdcp = nullptr; srsue::rrc_interface_rlc* rrc = nullptr; diff --git a/lib/include/srsran/rlc/rlc_um_base.h b/lib/include/srsran/rlc/rlc_um_base.h index 63a3a19827..54d5ab6f51 100644 --- a/lib/include/srsran/rlc/rlc_um_base.h +++ b/lib/include/srsran/rlc/rlc_um_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -57,7 +57,7 @@ class rlc_um_base : public rlc_common bool is_mrb(); rlc_mode_t get_mode(); - uint32_t get_bearer(); + uint32_t get_lcid() final; // PDCP interface void write_sdu(unique_byte_buffer_t sdu); @@ -164,14 +164,12 @@ class rlc_um_base : public rlc_common }; // Common variables needed by parent class - srsue::rrc_interface_rlc* rrc = nullptr; - srsue::pdcp_interface_rlc* pdcp = nullptr; - srslog::basic_logger& logger; + srsue::rrc_interface_rlc* rrc = nullptr; + srsue::pdcp_interface_rlc* pdcp = nullptr; srsran::timer_handler* timers = nullptr; uint32_t lcid = 0; rlc_config_t cfg = {}; - std::string rb_name; - byte_buffer_pool* pool = nullptr; + byte_buffer_pool* pool = nullptr; std::string get_rb_name(srsue::rrc_interface_rlc* rrc, uint32_t lcid, bool is_mrb); // Rx and Tx objects diff --git a/lib/include/srsran/rlc/rlc_um_lte.h b/lib/include/srsran/rlc/rlc_um_lte.h index 7e121c6a59..b6348f10ba 100644 --- a/lib/include/srsran/rlc/rlc_um_lte.h +++ b/lib/include/srsran/rlc/rlc_um_lte.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -58,6 +58,7 @@ class rlc_um_lte : public rlc_um_base bool configure(const rlc_config_t& cfg, std::string rb_name); uint32_t build_data_pdu(unique_byte_buffer_t pdu, uint8_t* payload, uint32_t nof_bytes); + void discard_sdu(uint32_t discard_sn); uint32_t get_buffer_state(); bool sdu_queue_is_full(); diff --git a/lib/include/srsran/rlc/rlc_um_nr.h b/lib/include/srsran/rlc/rlc_um_nr.h index 9dd8d76863..056d4df253 100644 --- a/lib/include/srsran/rlc/rlc_um_nr.h +++ b/lib/include/srsran/rlc/rlc_um_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -50,6 +50,9 @@ class rlc_um_nr : public rlc_um_base ~rlc_um_nr(); bool configure(const rlc_config_t& cnfg); + // logging helpers + std::string get_rb_name() const; + private: // Transmitter sub-class for NR class rlc_um_nr_tx : public rlc_um_base_tx @@ -59,6 +62,7 @@ class rlc_um_nr : public rlc_um_base bool configure(const rlc_config_t& cfg, std::string rb_name); uint32_t build_data_pdu(unique_byte_buffer_t pdu, uint8_t* payload, uint32_t nof_bytes); + void discard_sdu(uint32_t discard_sn); uint32_t get_buffer_state(); private: @@ -108,8 +112,8 @@ class rlc_um_nr : public rlc_um_base uint32_t RX_Next_Highest = 0; // the SN following the SN of the UMD PDU with the highest SN among // received UMD PDUs. It serves as the higher edge of the reassembly window. - uint32_t UM_Window_Size; - uint32_t mod; // Rx counter modulus + uint32_t UM_Window_Size = 0; + uint32_t mod = 0; // Rx counter modulus // Rx window typedef struct { diff --git a/lib/include/srsran/rrc/rrc_common.h b/lib/include/srsran/rrc/rrc_common.h index d406636c58..f5d5c722f0 100644 --- a/lib/include/srsran/rrc/rrc_common.h +++ b/lib/include/srsran/rrc/rrc_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/bundled/fmt/core.h b/lib/include/srsran/srslog/bundled/fmt/core.h index d676f27e5b..04a85f2954 100644 --- a/lib/include/srsran/srslog/bundled/fmt/core.h +++ b/lib/include/srsran/srslog/bundled/fmt/core.h @@ -8,7 +8,8 @@ #ifndef FMT_CORE_H_ #define FMT_CORE_H_ -#include // std::FILE +#include +#include // std::FILE #include #include #include diff --git a/lib/include/srsran/srslog/context.h b/lib/include/srsran/srslog/context.h index d9ed6aa2ea..439899632d 100644 --- a/lib/include/srsran/srslog/context.h +++ b/lib/include/srsran/srslog/context.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/detail/log_backend.h b/lib/include/srsran/srslog/detail/log_backend.h index f7c9fb4dde..909e33607a 100644 --- a/lib/include/srsran/srslog/detail/log_backend.h +++ b/lib/include/srsran/srslog/detail/log_backend.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/detail/log_entry.h b/lib/include/srsran/srslog/detail/log_entry.h index f3a90a1d00..e462a06450 100644 --- a/lib/include/srsran/srslog/detail/log_entry.h +++ b/lib/include/srsran/srslog/detail/log_entry.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/detail/log_entry_metadata.h b/lib/include/srsran/srslog/detail/log_entry_metadata.h index a14262dd55..8c09bfb044 100644 --- a/lib/include/srsran/srslog/detail/log_entry_metadata.h +++ b/lib/include/srsran/srslog/detail/log_entry_metadata.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/detail/support/any.h b/lib/include/srsran/srslog/detail/support/any.h index db8ae95046..eb885130b4 100644 --- a/lib/include/srsran/srslog/detail/support/any.h +++ b/lib/include/srsran/srslog/detail/support/any.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/detail/support/backend_capacity.h b/lib/include/srsran/srslog/detail/support/backend_capacity.h index a0420850bf..f1875e0497 100644 --- a/lib/include/srsran/srslog/detail/support/backend_capacity.h +++ b/lib/include/srsran/srslog/detail/support/backend_capacity.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/detail/support/dyn_arg_store_pool.h b/lib/include/srsran/srslog/detail/support/dyn_arg_store_pool.h index d9b0fb406f..33cf09a632 100644 --- a/lib/include/srsran/srslog/detail/support/dyn_arg_store_pool.h +++ b/lib/include/srsran/srslog/detail/support/dyn_arg_store_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/detail/support/error_string.h b/lib/include/srsran/srslog/detail/support/error_string.h index 51b6142e44..a5072bfc30 100644 --- a/lib/include/srsran/srslog/detail/support/error_string.h +++ b/lib/include/srsran/srslog/detail/support/error_string.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/detail/support/memory_buffer.h b/lib/include/srsran/srslog/detail/support/memory_buffer.h index 6d28e098b1..6f8440f555 100644 --- a/lib/include/srsran/srslog/detail/support/memory_buffer.h +++ b/lib/include/srsran/srslog/detail/support/memory_buffer.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/detail/support/thread_utils.h b/lib/include/srsran/srslog/detail/support/thread_utils.h index 4120d18516..43c6268001 100644 --- a/lib/include/srsran/srslog/detail/support/thread_utils.h +++ b/lib/include/srsran/srslog/detail/support/thread_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/detail/support/tmp_utils.h b/lib/include/srsran/srslog/detail/support/tmp_utils.h index 24a9f2fd44..6f0a2ed7a9 100644 --- a/lib/include/srsran/srslog/detail/support/tmp_utils.h +++ b/lib/include/srsran/srslog/detail/support/tmp_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/detail/support/work_queue.h b/lib/include/srsran/srslog/detail/support/work_queue.h index 99d1ee3183..1ec0d6606e 100644 --- a/lib/include/srsran/srslog/detail/support/work_queue.h +++ b/lib/include/srsran/srslog/detail/support/work_queue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/event_trace.h b/lib/include/srsran/srslog/event_trace.h index c5525f5211..9e5acb416c 100644 --- a/lib/include/srsran/srslog/event_trace.h +++ b/lib/include/srsran/srslog/event_trace.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/formatter.h b/lib/include/srsran/srslog/formatter.h index a58e37f9cf..8315a263ff 100644 --- a/lib/include/srsran/srslog/formatter.h +++ b/lib/include/srsran/srslog/formatter.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/log_channel.h b/lib/include/srsran/srslog/log_channel.h index b01356ad1d..e3ae024c38 100644 --- a/lib/include/srsran/srslog/log_channel.h +++ b/lib/include/srsran/srslog/log_channel.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/logger.h b/lib/include/srsran/srslog/logger.h index cac34908fd..a267ee485b 100644 --- a/lib/include/srsran/srslog/logger.h +++ b/lib/include/srsran/srslog/logger.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/shared_types.h b/lib/include/srsran/srslog/shared_types.h index 2693d3f550..e9d595a264 100644 --- a/lib/include/srsran/srslog/shared_types.h +++ b/lib/include/srsran/srslog/shared_types.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/sink.h b/lib/include/srsran/srslog/sink.h index 342d8d001d..a79d18b820 100644 --- a/lib/include/srsran/srslog/sink.h +++ b/lib/include/srsran/srslog/sink.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/srslog.h b/lib/include/srsran/srslog/srslog.h index a65485791f..b166b13722 100644 --- a/lib/include/srsran/srslog/srslog.h +++ b/lib/include/srsran/srslog/srslog.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srslog/srslog_c.h b/lib/include/srsran/srslog/srslog_c.h index bb9989b5f4..0166e4cf45 100644 --- a/lib/include/srsran/srslog/srslog_c.h +++ b/lib/include/srsran/srslog/srslog_c.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/srsran.h b/lib/include/srsran/srsran.h index 912e44f115..04d636083d 100644 --- a/lib/include/srsran/srsran.h +++ b/lib/include/srsran/srsran.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -61,6 +61,7 @@ extern "C" { #include "srsran/phy/channel/ch_awgn.h" +#include "srsran/phy/cfr/cfr.h" #include "srsran/phy/dft/dft.h" #include "srsran/phy/dft/dft_precoding.h" #include "srsran/phy/dft/ofdm.h" @@ -122,6 +123,7 @@ extern "C" { #include "srsran/phy/ue/ue_dl_nr.h" #include "srsran/phy/ue/ue_mib.h" #include "srsran/phy/ue/ue_sync.h" +#include "srsran/phy/ue/ue_sync_nr.h" #include "srsran/phy/ue/ue_ul.h" #include "srsran/phy/ue/ue_ul_nr.h" diff --git a/lib/include/srsran/support/emergency_handlers.h b/lib/include/srsran/support/emergency_handlers.h index c2d64f4cef..b6b5d253d7 100644 --- a/lib/include/srsran/support/emergency_handlers.h +++ b/lib/include/srsran/support/emergency_handlers.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -26,7 +26,11 @@ using emergency_cleanup_callback = void (*)(void*); // Add a cleanup function to be called when a kill signal is about to be delivered to the process. The handler may // optionally pass a pointer to identify what instance of the handler is being called. -void add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* data); +// Returns the id of the handler as a positive value, otherwise returns -1 on error. +int add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* data); + +// Removes the emergency handler with the specified id. +void remove_emergency_cleanup_handler(int id); // Executes all registered emergency cleanup handlers. void execute_emergency_cleanup_handlers(); diff --git a/lib/include/srsran/support/signal_handler.h b/lib/include/srsran/support/signal_handler.h index 00649853eb..88b92d7bdf 100644 --- a/lib/include/srsran/support/signal_handler.h +++ b/lib/include/srsran/support/signal_handler.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/support/srsran_assert.h b/lib/include/srsran/support/srsran_assert.h index 3e27f1608d..2d8f40350c 100644 --- a/lib/include/srsran/support/srsran_assert.h +++ b/lib/include/srsran/support/srsran_assert.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -65,6 +65,15 @@ */ #define srsran_assert(condition, fmt, ...) srsran_assert_ifdef(ASSERTS_ENABLED, condition, fmt, ##__VA_ARGS__) +/** + * Specialization of "srsran_assert_ifdef" for the SANITY_CHECKS_ENABLED flag + */ +#ifndef NDEBUG +#define SANITY_CHECKS_ENABLED +#endif +#define srsran_sanity_check(condition, fmt, ...) \ + srsran_assert_ifdef(SANITY_CHECKS_ENABLED, condition, fmt, ##__VA_ARGS__) + #ifdef STOP_ON_WARNING #define srsran_expect(condition, fmt, ...) srsran_assert(condition, fmt, ##__VA_ARGS__) diff --git a/lib/include/srsran/support/srsran_test.h b/lib/include/srsran/support/srsran_test.h index d30f580ad1..ebc630e600 100644 --- a/lib/include/srsran/support/srsran_test.h +++ b/lib/include/srsran/support/srsran_test.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/system/sys_metrics.h b/lib/include/srsran/system/sys_metrics.h index f357c37fbb..e761317290 100644 --- a/lib/include/srsran/system/sys_metrics.h +++ b/lib/include/srsran/system/sys_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -38,7 +38,7 @@ struct sys_metrics_t { float process_cpu_usage = 0.f; float system_mem = 0.f; uint32_t cpu_count = 0; - std::array cpu_load; + std::array cpu_load = {}; }; } // namespace srsran diff --git a/lib/include/srsran/system/sys_metrics_processor.h b/lib/include/srsran/system/sys_metrics_processor.h index 507d050345..cb663b715b 100644 --- a/lib/include/srsran/system/sys_metrics_processor.h +++ b/lib/include/srsran/system/sys_metrics_processor.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/test/ue_test_interfaces.h b/lib/include/srsran/test/ue_test_interfaces.h index 63811ed268..06e66ff369 100644 --- a/lib/include/srsran/test/ue_test_interfaces.h +++ b/lib/include/srsran/test/ue_test_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -67,7 +67,7 @@ class rlc_dummy_interface : public rlc_interface_mac void write_pdu_bcch_bch(srsran::unique_byte_buffer_t payload) override {} void write_pdu_bcch_dlsch(uint8_t* payload, uint32_t nof_bytes) override {} void write_pdu_pcch(srsran::unique_byte_buffer_t payload) override {} - void write_pdu_mch(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) override {} + void write_pdu_mch(uint32_t mch_idx, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) override {} }; class phy_dummy_interface : public phy_interface_rrc_lte @@ -85,7 +85,7 @@ class phy_dummy_interface : public phy_interface_rrc_lte void meas_stop() override {} /* Cell search and selection procedures */ - bool cell_search() override { return true; } + bool cell_search(int earfcn) override { return true; } bool cell_select(phy_cell_t cell) override { return true; } bool cell_is_camping() override { return false; } }; diff --git a/lib/include/srsran/upper/byte_buffer_queue.h b/lib/include/srsran/upper/byte_buffer_queue.h index c23707322f..91ebaa5ff2 100644 --- a/lib/include/srsran/upper/byte_buffer_queue.h +++ b/lib/include/srsran/upper/byte_buffer_queue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/upper/gtpu.h b/lib/include/srsran/upper/gtpu.h index 2ec152b64e..2887729934 100644 --- a/lib/include/srsran/upper/gtpu.h +++ b/lib/include/srsran/upper/gtpu.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/upper/ipv6.h b/lib/include/srsran/upper/ipv6.h index 3fa39b5eb9..2a28a2d400 100644 --- a/lib/include/srsran/upper/ipv6.h +++ b/lib/include/srsran/upper/ipv6.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/upper/pdcp.h b/lib/include/srsran/upper/pdcp.h index a8cf097701..aa361bf030 100644 --- a/lib/include/srsran/upper/pdcp.h +++ b/lib/include/srsran/upper/pdcp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/upper/pdcp_entity_base.h b/lib/include/srsran/upper/pdcp_entity_base.h index 6c8f0428af..7ebf95f685 100644 --- a/lib/include/srsran/upper/pdcp_entity_base.h +++ b/lib/include/srsran/upper/pdcp_entity_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -85,7 +85,7 @@ class pdcp_entity_base } else { integrity_direction = direction; } - logger.debug("LCID=%d, integrity=%s", lcid, srsran_direction_text[integrity_direction]); + logger.debug("Enabled integrity. LCID=%d, integrity=%s", lcid, srsran_direction_text[integrity_direction]); } void enable_encryption(srsran_direction_t direction = DIRECTION_TXRX) @@ -98,7 +98,7 @@ class pdcp_entity_base } else { encryption_direction = direction; } - logger.debug("LCID=%d encryption=%s", lcid, srsran_direction_text[integrity_direction]); + logger.debug("Enabled encryption. LCID=%d, encryption=%s", lcid, srsran_direction_text[integrity_direction]); } void enable_security_timed(srsran_direction_t direction, uint32_t sn) diff --git a/lib/include/srsran/upper/pdcp_entity_lte.h b/lib/include/srsran/upper/pdcp_entity_lte.h index 4cb0a6d1d3..5bf8d43a23 100644 --- a/lib/include/srsran/upper/pdcp_entity_lte.h +++ b/lib/include/srsran/upper/pdcp_entity_lte.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -42,7 +42,7 @@ namespace srsran { class undelivered_sdus_queue { public: - explicit undelivered_sdus_queue(srsran::task_sched_handle task_sched); + explicit undelivered_sdus_queue(srsran::task_sched_handle task_sched, uint32_t sn_mod); bool empty() const { return count == 0; } bool is_full() const { return count >= capacity; } @@ -82,8 +82,9 @@ class undelivered_sdus_queue private: const static uint32_t capacity = 4096; const static uint32_t invalid_sn = -1; + uint32_t sn_mod = 0; - static uint32_t increment_sn(uint32_t sn) { return (sn + 1) % capacity; } + uint32_t increment_sn(uint32_t sn) { return (sn + 1) % sn_mod; } struct sdu_data { srsran::unique_byte_buffer_t sdu; diff --git a/lib/include/srsran/upper/pdcp_entity_nr.h b/lib/include/srsran/upper/pdcp_entity_nr.h index d8de91ce3d..88cec32966 100644 --- a/lib/include/srsran/upper/pdcp_entity_nr.h +++ b/lib/include/srsran/upper/pdcp_entity_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -35,7 +35,6 @@ #include namespace srsran { - /**************************************************************************** * NR PDCP Entity * PDCP entity for 5G NR @@ -49,7 +48,7 @@ class pdcp_entity_nr final : public pdcp_entity_base srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, uint32_t lcid); - ~pdcp_entity_nr() final; + ~pdcp_entity_nr() final = default; bool configure(const pdcp_config_t& cnfg_) final; void reset() final; void reestablish() final; @@ -62,12 +61,6 @@ class pdcp_entity_nr final : public pdcp_entity_base void notify_delivery(const pdcp_sn_vector_t& pdcp_sns) final; void notify_failure(const pdcp_sn_vector_t& pdcp_sns) final; - // State variable setters (should be used only for testing) - void set_tx_next(uint32_t tx_next_) { tx_next = tx_next_; } - void set_rx_next(uint32_t rx_next_) { rx_next = rx_next_; } - void set_rx_deliv(uint32_t rx_deliv_) { rx_deliv = rx_deliv_; } - void set_rx_reord(uint32_t rx_reord_) { rx_reord = rx_reord_; } - void get_bearer_state(pdcp_lte_state_t* state) override; void set_bearer_state(const pdcp_lte_state_t& state, bool set_fmc) override; @@ -79,6 +72,17 @@ class pdcp_entity_nr final : public pdcp_entity_base // State variable getters (useful for testing) uint32_t nof_discard_timers() { return discard_timers_map.size(); } + bool is_reordering_timer_running() { return reordering_timer.is_running(); } + + // State variable setters (should be used only for testing) + void set_tx_next(uint32_t tx_next_) { tx_next = tx_next_; } + void set_rx_next(uint32_t rx_next_) { rx_next = rx_next_; } + void set_rx_deliv(uint32_t rx_deliv_) { rx_deliv = rx_deliv_; } + void set_rx_reord(uint32_t rx_reord_) { rx_reord = rx_reord_; } + uint32_t get_tx_next() const { return tx_next; } + uint32_t get_rx_next() const { return rx_next; } + uint32_t get_rx_deliv() const { return rx_deliv; } + uint32_t get_rx_reord() const { return rx_reord; } private: srsue::rlc_interface_pdcp* rlc = nullptr; @@ -113,6 +117,11 @@ class pdcp_entity_nr final : public pdcp_entity_base // COUNT overflow protection bool tx_overflow = false; bool rx_overflow = false; + + enum class rlc_mode_t { + UM, + AM, + } rlc_mode; }; /* diff --git a/lib/include/srsran/upper/pdcp_metrics.h b/lib/include/srsran/upper/pdcp_metrics.h index af6a5ff0f9..eb2f44a605 100644 --- a/lib/include/srsran/upper/pdcp_metrics.h +++ b/lib/include/srsran/upper/pdcp_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/include/srsran/version.h.in b/lib/include/srsran/version.h.in index dca66c6ccf..ec0facf7fa 100644 --- a/lib/include/srsran/version.h.in +++ b/lib/include/srsran/version.h.in @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/CMakeLists.txt b/lib/src/CMakeLists.txt index aa9940faf7..e589650efa 100644 --- a/lib/src/CMakeLists.txt +++ b/lib/src/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/asn1/CMakeLists.txt b/lib/src/asn1/CMakeLists.txt index abdff4f03b..2c2e73f535 100644 --- a/lib/src/asn1/CMakeLists.txt +++ b/lib/src/asn1/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -28,7 +28,7 @@ add_library(srsran_asn1 STATIC # ASN1 utils add_library(asn1_utils STATIC asn1_utils.cc) target_link_libraries(asn1_utils srsran_common) -INSTALL(TARGETS asn1_utils DESTINATION ${LIBRARY_DIR}) +install(TARGETS asn1_utils DESTINATION ${LIBRARY_DIR} OPTIONAL) # RRC ASN1 lib add_library(rrc_asn1 STATIC @@ -54,29 +54,32 @@ add_library(rrc_asn1 STATIC # Compile RRC ASN1 optimized for size target_compile_options(rrc_asn1 PRIVATE "-Os") target_link_libraries(rrc_asn1 asn1_utils srsran_common) -INSTALL(TARGETS rrc_asn1 DESTINATION ${LIBRARY_DIR}) +install(TARGETS rrc_asn1 DESTINATION ${LIBRARY_DIR} OPTIONAL) # S1AP ASN1 lib add_library(s1ap_asn1 STATIC s1ap.cc s1ap_utils.cc) target_compile_options(s1ap_asn1 PRIVATE "-Os") target_link_libraries(s1ap_asn1 asn1_utils srsran_common) -INSTALL(TARGETS s1ap_asn1 DESTINATION ${LIBRARY_DIR}) +install(TARGETS s1ap_asn1 DESTINATION ${LIBRARY_DIR} OPTIONAL) # RRC NR ASN1 add_library(rrc_nr_asn1 STATIC rrc_nr.cc rrc_nr_utils.cc) target_compile_options(rrc_nr_asn1 PRIVATE "-Os") target_link_libraries(rrc_nr_asn1 asn1_utils srsran_common) -INSTALL(TARGETS rrc_nr_asn1 DESTINATION ${LIBRARY_DIR}) +install(TARGETS rrc_nr_asn1 DESTINATION ${LIBRARY_DIR} OPTIONAL) # NGAP ASN1 add_library(ngap_nr_asn1 STATIC ngap.cc) target_compile_options(ngap_nr_asn1 PRIVATE "-Os") target_link_libraries(ngap_nr_asn1 asn1_utils srsran_common) -INSTALL(TARGETS ngap_nr_asn1 DESTINATION ${LIBRARY_DIR}) +install(TARGETS ngap_nr_asn1 DESTINATION ${LIBRARY_DIR} OPTIONAL) # NAS 5G add_library(nas_5g_msg STATIC nas_5g_msg.cc nas_5g_ies.cc nas_5g_utils.cc) target_compile_options(nas_5g_msg PRIVATE "-Os") target_link_libraries(nas_5g_msg asn1_utils srsran_common) -INSTALL(TARGETS nas_5g_msg DESTINATION ${LIBRARY_DIR}) - - +install(TARGETS nas_5g_msg DESTINATION ${LIBRARY_DIR} OPTIONAL) +## ORAN E2 RIC +add_library(ric_e2 STATIC e2sm_kpm_v2.cpp e2ap.cpp e2sm.cpp) +target_compile_options(ric_e2 PRIVATE "-Os") +target_link_libraries(ric_e2 asn1_utils srsran_common) +install(TARGETS ric_e2 DESTINATION ${LIBRARY_DIR} OPTIONAL) diff --git a/lib/src/asn1/asn1_utils.cc b/lib/src/asn1/asn1_utils.cc index aab6887405..c02d16a8c8 100644 --- a/lib/src/asn1/asn1_utils.cc +++ b/lib/src/asn1/asn1_utils.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -153,7 +153,7 @@ SRSASN_CODE bit_ref::pack(uint64_t val, uint32_t n_bits) uint64_t mask; while (n_bits > 0) { if (ptr >= max_ptr) { - log_error("Buffer size limit was achieved"); + log_error("pack: Buffer size limit was achieved"); return SRSASN_ERROR_ENCODE_FAIL; } mask = ((1ul << n_bits) - 1ul); @@ -185,7 +185,7 @@ SRSASN_CODE unpack_bits(T& val, Ptr& ptr, uint8_t& offset, const uint8_t* max_pt val = 0; while (n_bits > 0) { if (ptr >= max_ptr) { - log_error("Buffer size limit was achieved"); + log_error("unpack_bits: Buffer size limit was achieved"); return SRSASN_ERROR_DECODE_FAIL; } if ((uint32_t)(8 - offset) > n_bits) { @@ -195,7 +195,7 @@ SRSASN_CODE unpack_bits(T& val, Ptr& ptr, uint8_t& offset, const uint8_t* max_pt n_bits = 0; } else { auto mask = static_cast((1u << (8u - offset)) - 1u); - val += ((uint32_t)((*ptr) & mask)) << (n_bits - 8 + offset); + val += static_cast((*ptr) & mask) << (n_bits - 8 + offset); n_bits -= 8 - offset; offset = 0; ptr++; @@ -249,7 +249,7 @@ SRSASN_CODE bit_ref_impl::unpack_bytes(uint8_t* buf, uint32_t n_bytes) if (offset == 0) { // Aligned case if (ptr + n_bytes > max_ptr) { - log_error("Buffer size limit was achieved"); + log_error("unpack_bytes (aligned): Buffer size limit was achieved"); return SRSASN_ERROR_DECODE_FAIL; } memcpy(buf, ptr, n_bytes); @@ -257,7 +257,7 @@ SRSASN_CODE bit_ref_impl::unpack_bytes(uint8_t* buf, uint32_t n_bytes) } else { // Unaligned case if (ptr + n_bytes >= max_ptr) { - log_error("Buffer size limit was achieved"); + log_error("unpack_bytes (unaligned): Buffer size limit was achieved"); return SRSASN_ERROR_DECODE_FAIL; } for (uint32_t i = 0; i < n_bytes; ++i) { @@ -273,7 +273,7 @@ SRSASN_CODE bit_ref_impl::align_bytes() if (offset == 0) return SRSASN_SUCCESS; if (ptr >= max_ptr) { - log_error("Buffer size limit was achieved"); + log_error("align_bytes: Buffer size limit was achieved"); return SRSASN_ERROR_DECODE_FAIL; } offset = 0; @@ -289,7 +289,7 @@ SRSASN_CODE bit_ref_impl::advance_bits(uint32_t n_bits) uint32_t bytes_offset = floorf((offset + n_bits) / 8.0f); if (ptr + bytes_required > max_ptr) { - log_error("Buffer size limit was achieved"); + log_error("advance_bytes: Buffer size limit was achieved"); return SRSASN_ERROR_DECODE_FAIL; } ptr += bytes_offset; @@ -315,7 +315,7 @@ SRSASN_CODE bit_ref::pack_bytes(const uint8_t* buf, uint32_t n_bytes) return SRSASN_SUCCESS; } if (ptr + n_bytes >= max_ptr) { - log_error("Buffer size limit was achieved"); + log_error("pack_bytes: Buffer size limit was achieved"); return SRSASN_ERROR_ENCODE_FAIL; } if (offset == 0) { @@ -335,7 +335,7 @@ SRSASN_CODE bit_ref::align_bytes_zero() if (offset == 0) return SRSASN_SUCCESS; if (ptr >= max_ptr) { - log_error("Buffer size limit was achieved"); + log_error("align_bytes_zero: Buffer size limit was achieved"); return SRSASN_ERROR_ENCODE_FAIL; } auto mask = static_cast(256u - (1u << (8u - offset))); @@ -1285,9 +1285,7 @@ pack(bit_ref& bref, const std::string& s, size_t lb, size_t ub, size_t alb, size size_t b = asn_string_utils::get_nof_bits_per_char(lb, ub, aligned); bool octet_aligned = asn_string_utils::is_octet_aligned(b, alb, aub, aligned); bool length_encoded = asn_string_utils::is_length_encoded(alb, aub, aligned); - if (octet_aligned) { - bref.align_bytes_zero(); - } + if (ext) { HANDLE_CODE(bref.pack(0, 1)); } @@ -1309,9 +1307,7 @@ SRSASN_CODE unpack(std::string& s, cbit_ref& bref, size_t lb, size_t ub, size_t bool octet_aligned = asn_string_utils::is_octet_aligned(b, alb, aub, aligned); bool length_encoded = asn_string_utils::is_length_encoded(alb, aub, aligned); size_t max_nof_bits = b * aub; - if (octet_aligned) { - bref.align_bytes(); - } + if (ext) { bool is_ext; HANDLE_CODE(bref.unpack(is_ext, 1)); @@ -1421,10 +1417,15 @@ SRSASN_CODE ext_groups_unpacker_guard::unpack(cbit_ref& bref) Open Field *********************/ -varlength_field_pack_guard::varlength_field_pack_guard(bit_ref& bref, bool align_) +varlength_field_pack_guard::varlength_field_pack_guard(bit_ref& bref, bool align_) : + buffer_ptr(srsran::make_buffer_pool_obj()) { + if (buffer_ptr == nullptr) { + // failed to allocate from global byte buffer pool. Fallback to malloc + buffer_ptr = std::unique_ptr(new byte_array_t()); + } brefstart = bref; - bref = bit_ref(&buffer[0], sizeof(buffer)); + bref = bit_ref(buffer_ptr->data(), buffer_ptr->size()); bref_tracker = &bref; align = align_; } @@ -1432,16 +1433,15 @@ varlength_field_pack_guard::varlength_field_pack_guard(bit_ref& bref, bool align varlength_field_pack_guard::~varlength_field_pack_guard() { // fill the spare bits - const bit_ref bref0 = bit_ref(&buffer[0], sizeof(buffer)); - uint32_t leftover = 7 - ((bref_tracker->distance(bref0) - (uint32_t)1) % (uint32_t)8); + uint32_t leftover = 7 - ((bref_tracker->distance() - (uint32_t)1) % (uint32_t)8); bref_tracker->pack(0, leftover); // check how many bytes were written in total - uint32_t nof_bytes = bref_tracker->distance(bref0) / (uint32_t)8; - if (nof_bytes > sizeof(buffer)) { + uint32_t nof_bytes = bref_tracker->distance() / (uint32_t)8; + if (nof_bytes > buffer_ptr->size()) { log_error("The packed variable sized field is too long for the reserved buffer (%zd > %zd)", (size_t)nof_bytes, - sizeof(buffer)); + buffer_ptr->size()); } // go back in time to pack length @@ -1449,7 +1449,7 @@ varlength_field_pack_guard::~varlength_field_pack_guard() // pack encoded bytes for (uint32_t i = 0; i < nof_bytes; ++i) { - brefstart.pack(buffer[i], 8); + brefstart.pack((*buffer_ptr)[i], 8); } *bref_tracker = brefstart; } @@ -1561,4 +1561,49 @@ std::string json_writer::to_string() const return std::string(buffer.data(), buffer.size()); } +/************************ + General Layer Types +************************/ + +uint32_t detail::base_empty_obj_set::idx_to_id(uint32_t idx) +{ + asn1::log_error("object set is empty\n"); + return 0; +} +bool detail::base_empty_obj_set::is_id_valid(const uint32_t& id) +{ + asn1::log_error("object set is empty\n"); + return false; +} +crit_e detail::base_empty_obj_set::get_crit(const uint32_t& id) +{ + return {}; +} +presence_e detail::base_empty_obj_set::get_presence(const uint32_t& id) +{ + return {}; +} + +void detail::empty_obj_set_item_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.end_obj(); +} +SRSASN_CODE detail::empty_obj_set_item_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + return SRSASN_SUCCESS; +} +SRSASN_CODE detail::empty_obj_set_item_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + return SRSASN_SUCCESS; +} + +const char* detail::empty_obj_set_item_c::types_opts::to_string() const +{ + log_error("The enum value=0 of type protocol_ies_empty_o::value_c::types is not valid."); + return ""; +} + } // namespace asn1 diff --git a/lib/src/asn1/e2ap.cpp b/lib/src/asn1/e2ap.cpp new file mode 100644 index 0000000000..83d8a368a2 --- /dev/null +++ b/lib/src/asn1/e2ap.cpp @@ -0,0 +1,16057 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/asn1/e2ap.h" +#include + +using namespace asn1; +using namespace asn1::e2ap; + +/******************************************************************************* + * Struct Methods + ******************************************************************************/ + +// CauseE2node ::= ENUMERATED +const char* cause_e2node_opts::to_string() const +{ + static const char* options[] = {"e2node-component-unknown"}; + return convert_enum_idx(options, 1, value, "cause_e2node_e"); +} +uint8_t cause_e2node_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "cause_e2node_e"); +} + +// CauseMisc ::= ENUMERATED +const char* cause_misc_opts::to_string() const +{ + static const char* options[] = {"control-processing-overload", "hardware-failure", "om-intervention", "unspecified"}; + return convert_enum_idx(options, 4, value, "cause_misc_e"); +} + +// CauseProtocol ::= ENUMERATED +const char* cause_protocol_opts::to_string() const +{ + static const char* options[] = {"transfer-syntax-error", + "abstract-syntax-error-reject", + "abstract-syntax-error-ignore-and-notify", + "message-not-compatible-with-receiver-state", + "semantic-error", + "abstract-syntax-error-falsely-constructed-message", + "unspecified"}; + return convert_enum_idx(options, 7, value, "cause_protocol_e"); +} + +// CauseRICrequest ::= ENUMERATED +const char* cause_ri_crequest_opts::to_string() const +{ + static const char* options[] = {"ran-function-id-invalid", + "action-not-supported", + "excessive-actions", + "duplicate-action", + "duplicate-event-trigger", + "function-resource-limit", + "request-id-unknown", + "inconsistent-action-subsequent-action-sequence", + "control-message-invalid", + "ric-call-process-id-invalid", + "control-timer-expired", + "control-failed-to-execute", + "system-not-ready", + "unspecified"}; + return convert_enum_idx(options, 14, value, "cause_ri_crequest_e"); +} + +// CauseRICservice ::= ENUMERATED +const char* cause_ricservice_opts::to_string() const +{ + static const char* options[] = {"ran-function-not-supported", "excessive-functions", "ric-resource-limit"}; + return convert_enum_idx(options, 3, value, "cause_ricservice_e"); +} + +// CauseTransport ::= ENUMERATED +const char* cause_transport_opts::to_string() const +{ + static const char* options[] = {"unspecified", "transport-resource-unavailable"}; + return convert_enum_idx(options, 2, value, "cause_transport_e"); +} + +// Cause ::= CHOICE +void cause_c::destroy_() {} +void cause_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +cause_c::cause_c(const cause_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ric_request: + c.init(other.c.get()); + break; + case types::ric_service: + c.init(other.c.get()); + break; + case types::e2_node: + c.init(other.c.get()); + break; + case types::transport: + c.init(other.c.get()); + break; + case types::protocol: + c.init(other.c.get()); + break; + case types::misc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cause_c"); + } +} +cause_c& cause_c::operator=(const cause_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ric_request: + c.set(other.c.get()); + break; + case types::ric_service: + c.set(other.c.get()); + break; + case types::e2_node: + c.set(other.c.get()); + break; + case types::transport: + c.set(other.c.get()); + break; + case types::protocol: + c.set(other.c.get()); + break; + case types::misc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cause_c"); + } + + return *this; +} +cause_ri_crequest_e& cause_c::set_ric_request() +{ + set(types::ric_request); + return c.get(); +} +cause_ricservice_e& cause_c::set_ric_service() +{ + set(types::ric_service); + return c.get(); +} +cause_e2node_e& cause_c::set_e2_node() +{ + set(types::e2_node); + return c.get(); +} +cause_transport_e& cause_c::set_transport() +{ + set(types::transport); + return c.get(); +} +cause_protocol_e& cause_c::set_protocol() +{ + set(types::protocol); + return c.get(); +} +cause_misc_e& cause_c::set_misc() +{ + set(types::misc); + return c.get(); +} +void cause_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ric_request: + j.write_str("ricRequest", c.get().to_string()); + break; + case types::ric_service: + j.write_str("ricService", c.get().to_string()); + break; + case types::e2_node: + j.write_str("e2Node", "e2node-component-unknown"); + break; + case types::transport: + j.write_str("transport", c.get().to_string()); + break; + case types::protocol: + j.write_str("protocol", c.get().to_string()); + break; + case types::misc: + j.write_str("misc", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "cause_c"); + } + j.end_obj(); +} +SRSASN_CODE cause_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ric_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ric_service: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2_node: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::transport: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::protocol: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::misc: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "cause_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE cause_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ric_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ric_service: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2_node: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::transport: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::protocol: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::misc: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "cause_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* cause_c::types_opts::to_string() const +{ + static const char* options[] = {"ricRequest", "ricService", "e2Node", "transport", "protocol", "misc"}; + return convert_enum_idx(options, 6, value, "cause_c::types"); +} +uint8_t cause_c::types_opts::to_number() const +{ + if (value == e2_node) { + return 2; + } + invalid_enum_number(value, "cause_c::types"); + return 0; +} + +// TypeOfError ::= ENUMERATED +const char* type_of_error_opts::to_string() const +{ + static const char* options[] = {"not-understood", "missing"}; + return convert_enum_idx(options, 2, value, "type_of_error_e"); +} + +// CriticalityDiagnostics-IE-Item ::= SEQUENCE +SRSASN_CODE crit_diagnostics_ie_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(iecrit.pack(bref)); + HANDLE_CODE(pack_integer(bref, ie_id, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(type_of_error.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE crit_diagnostics_ie_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(iecrit.unpack(bref)); + HANDLE_CODE(unpack_integer(ie_id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(type_of_error.unpack(bref)); + + return SRSASN_SUCCESS; +} +void crit_diagnostics_ie_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("iECriticality", iecrit.to_string()); + j.write_int("iE-ID", ie_id); + j.write_str("typeOfError", type_of_error.to_string()); + j.end_obj(); +} + +// RICrequestID ::= SEQUENCE +SRSASN_CODE ri_crequest_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ric_requestor_id, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(pack_integer(bref, ric_instance_id, (uint32_t)0u, (uint32_t)65535u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_crequest_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ric_requestor_id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(unpack_integer(ric_instance_id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + + return SRSASN_SUCCESS; +} +void ri_crequest_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ricRequestorID", ric_requestor_id); + j.write_int("ricInstanceID", ric_instance_id); + j.end_obj(); +} + +// TriggeringMessage ::= ENUMERATED +const char* trigger_msg_opts::to_string() const +{ + static const char* options[] = {"initiating-message", "successful-outcome", "unsuccessfull-outcome"}; + return convert_enum_idx(options, 3, value, "trigger_msg_e"); +} + +// CriticalityDiagnostics ::= SEQUENCE +SRSASN_CODE crit_diagnostics_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(proc_code_present, 1)); + HANDLE_CODE(bref.pack(trigger_msg_present, 1)); + HANDLE_CODE(bref.pack(proc_crit_present, 1)); + HANDLE_CODE(bref.pack(ric_requestor_id_present, 1)); + HANDLE_CODE(bref.pack(ies_crit_diagnostics.size() > 0, 1)); + + if (proc_code_present) { + HANDLE_CODE(pack_integer(bref, proc_code, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (trigger_msg_present) { + HANDLE_CODE(trigger_msg.pack(bref)); + } + if (proc_crit_present) { + HANDLE_CODE(proc_crit.pack(bref)); + } + if (ric_requestor_id_present) { + HANDLE_CODE(ric_requestor_id.pack(bref)); + } + if (ies_crit_diagnostics.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, ies_crit_diagnostics, 1, 256, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE crit_diagnostics_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(proc_code_present, 1)); + HANDLE_CODE(bref.unpack(trigger_msg_present, 1)); + HANDLE_CODE(bref.unpack(proc_crit_present, 1)); + HANDLE_CODE(bref.unpack(ric_requestor_id_present, 1)); + bool ies_crit_diagnostics_present; + HANDLE_CODE(bref.unpack(ies_crit_diagnostics_present, 1)); + + if (proc_code_present) { + HANDLE_CODE(unpack_integer(proc_code, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (trigger_msg_present) { + HANDLE_CODE(trigger_msg.unpack(bref)); + } + if (proc_crit_present) { + HANDLE_CODE(proc_crit.unpack(bref)); + } + if (ric_requestor_id_present) { + HANDLE_CODE(ric_requestor_id.unpack(bref)); + } + if (ies_crit_diagnostics_present) { + HANDLE_CODE(unpack_dyn_seq_of(ies_crit_diagnostics, bref, 1, 256, true)); + } + + return SRSASN_SUCCESS; +} +void crit_diagnostics_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (proc_code_present) { + j.write_int("procedureCode", proc_code); + } + if (trigger_msg_present) { + j.write_str("triggeringMessage", trigger_msg.to_string()); + } + if (proc_crit_present) { + j.write_str("procedureCriticality", proc_crit.to_string()); + } + if (ric_requestor_id_present) { + j.write_fieldname("ricRequestorID"); + ric_requestor_id.to_json(j); + } + if (ies_crit_diagnostics.size() > 0) { + j.start_array("iEsCriticalityDiagnostics"); + for (const auto& e1 : ies_crit_diagnostics) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// ENB-ID-Choice ::= CHOICE +void enb_id_choice_c::destroy_() +{ + switch (type_) { + case types::enb_id_macro: + c.destroy >(); + break; + case types::enb_id_shortmacro: + c.destroy >(); + break; + case types::enb_id_longmacro: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_choice_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::enb_id_macro: + c.init >(); + break; + case types::enb_id_shortmacro: + c.init >(); + break; + case types::enb_id_longmacro: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } +} +enb_id_choice_c::enb_id_choice_c(const enb_id_choice_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::enb_id_macro: + c.init(other.c.get >()); + break; + case types::enb_id_shortmacro: + c.init(other.c.get >()); + break; + case types::enb_id_longmacro: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } +} +enb_id_choice_c& enb_id_choice_c::operator=(const enb_id_choice_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::enb_id_macro: + c.set(other.c.get >()); + break; + case types::enb_id_shortmacro: + c.set(other.c.get >()); + break; + case types::enb_id_longmacro: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_choice_c::set_enb_id_macro() +{ + set(types::enb_id_macro); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_choice_c::set_enb_id_shortmacro() +{ + set(types::enb_id_shortmacro); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_choice_c::set_enb_id_longmacro() +{ + set(types::enb_id_longmacro); + return c.get >(); +} +void enb_id_choice_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::enb_id_macro: + j.write_str("enb-ID-macro", c.get >().to_string()); + break; + case types::enb_id_shortmacro: + j.write_str("enb-ID-shortmacro", c.get >().to_string()); + break; + case types::enb_id_longmacro: + j.write_str("enb-ID-longmacro", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_choice_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::enb_id_macro: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::enb_id_shortmacro: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::enb_id_longmacro: + HANDLE_CODE((c.get >().pack(bref))); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_choice_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::enb_id_macro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::enb_id_shortmacro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::enb_id_longmacro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_choice_c::types_opts::to_string() const +{ + static const char* options[] = {"enb-ID-macro", "enb-ID-shortmacro", "enb-ID-longmacro"}; + return convert_enum_idx(options, 3, value, "enb_id_choice_c::types"); +} + +// GNB-ID-Choice ::= CHOICE +void gnb_id_choice_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gnb-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE gnb_id_choice_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE gnb_id_choice_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "gnb_id_choice_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* gnb_id_choice_c::types_opts::to_string() const +{ + static const char* options[] = {"gnb-ID"}; + return convert_enum_idx(options, 1, value, "gnb_id_choice_c::types"); +} + +// ENB-ID ::= CHOICE +void enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_enb_id: + c.destroy >(); + break; + case types::home_enb_id: + c.destroy >(); + break; + case types::short_macro_enb_id: + c.destroy >(); + break; + case types::long_macro_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_enb_id: + c.init >(); + break; + case types::home_enb_id: + c.init >(); + break; + case types::short_macro_enb_id: + c.init >(); + break; + case types::long_macro_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c::enb_id_c(const enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_enb_id: + c.init(other.c.get >()); + break; + case types::home_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c& enb_id_c::operator=(const enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_enb_id: + c.set(other.c.get >()); + break; + case types::home_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_c::set_macro_enb_id() +{ + set(types::macro_enb_id); + return c.get >(); +} +fixed_bitstring<28, false, true>& enb_id_c::set_home_enb_id() +{ + set(types::home_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_c::set_short_macro_enb_id() +{ + set(types::short_macro_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_c::set_long_macro_enb_id() +{ + set(types::long_macro_enb_id); + return c.get >(); +} +void enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_enb_id: + j.write_str("macro-eNB-ID", c.get >().to_string()); + break; + case types::home_enb_id: + j.write_str("home-eNB-ID", c.get >().to_string()); + break; + case types::short_macro_enb_id: + j.write_str("short-Macro-eNB-ID", c.get >().to_string()); + break; + case types::long_macro_enb_id: + j.write_str("long-Macro-eNB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macro-eNB-ID", "home-eNB-ID", "short-Macro-eNB-ID", "long-Macro-eNB-ID"}; + return convert_enum_idx(options, 4, value, "enb_id_c::types"); +} + +// ENGNB-ID ::= CHOICE +void engnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE engnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE engnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "engnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* engnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB-ID"}; + return convert_enum_idx(options, 1, value, "engnb_id_c::types"); +} + +// GlobalgNB-ID ::= SEQUENCE +SRSASN_CODE globalg_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalg_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalg_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("plmn-id", plmn_id.to_string()); + j.write_fieldname("gnb-id"); + gnb_id.to_json(j); + j.end_obj(); +} + +// GlobalngeNB-ID ::= SEQUENCE +SRSASN_CODE globalngenb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalngenb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalngenb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("plmn-id", plmn_id.to_string()); + j.write_fieldname("enb-id"); + enb_id.to_json(j); + j.end_obj(); +} + +// GlobalENB-ID ::= SEQUENCE +SRSASN_CODE global_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("eNB-ID"); + enb_id.to_json(j); + j.end_obj(); +} + +// GlobalNG-RANNode-ID ::= CHOICE +void global_ng_ran_node_id_c::destroy_() +{ + switch (type_) { + case types::gnb: + c.destroy(); + break; + case types::ng_enb: + c.destroy(); + break; + default: + break; + } +} +void global_ng_ran_node_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb: + c.init(); + break; + case types::ng_enb: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + } +} +global_ng_ran_node_id_c::global_ng_ran_node_id_c(const global_ng_ran_node_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb: + c.init(other.c.get()); + break; + case types::ng_enb: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + } +} +global_ng_ran_node_id_c& global_ng_ran_node_id_c::operator=(const global_ng_ran_node_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb: + c.set(other.c.get()); + break; + case types::ng_enb: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + } + + return *this; +} +globalg_nb_id_s& global_ng_ran_node_id_c::set_gnb() +{ + set(types::gnb); + return c.get(); +} +globalngenb_id_s& global_ng_ran_node_id_c::set_ng_enb() +{ + set(types::ng_enb); + return c.get(); +} +void global_ng_ran_node_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb: + j.write_fieldname("gNB"); + c.get().to_json(j); + break; + case types::ng_enb: + j.write_fieldname("ng-eNB"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_ng_ran_node_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ng_ran_node_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ng_ran_node_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_ng_ran_node_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB", "ng-eNB"}; + return convert_enum_idx(options, 2, value, "global_ng_ran_node_id_c::types"); +} + +// GlobalenGNB-ID ::= SEQUENCE +SRSASN_CODE globalen_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalen_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalen_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("gNB-ID"); + gnb_id.to_json(j); + j.end_obj(); +} + +// RICsubsequentActionType ::= ENUMERATED +const char* ricsubsequent_action_type_opts::to_string() const +{ + static const char* options[] = {"continue", "wait"}; + return convert_enum_idx(options, 2, value, "ricsubsequent_action_type_e"); +} + +// RICtimeToWait ::= ENUMERATED +const char* ri_ctime_to_wait_opts::to_string() const +{ + static const char* options[] = {"w1ms", + "w2ms", + "w5ms", + "w10ms", + "w20ms", + "w30ms", + "w40ms", + "w50ms", + "w100ms", + "w200ms", + "w500ms", + "w1s", + "w2s", + "w5s", + "w10s", + "w20s", + "w60s"}; + return convert_enum_idx(options, 17, value, "ri_ctime_to_wait_e"); +} + +// E2nodeComponentInterfaceE1 ::= SEQUENCE +SRSASN_CODE e2node_component_interface_e1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_e1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_cp_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_e1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-ID", gnb_cu_cp_id); + j.end_obj(); +} + +// E2nodeComponentInterfaceF1 ::= SEQUENCE +SRSASN_CODE e2node_component_interface_f1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_f1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_f1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-DU-ID", gnb_du_id); + j.end_obj(); +} + +// E2nodeComponentInterfaceNG ::= SEQUENCE +SRSASN_CODE e2node_component_interface_ng_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(amf_name.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_ng_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(amf_name.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_ng_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("amf-name", amf_name.to_string()); + j.end_obj(); +} + +// E2nodeComponentInterfaceS1 ::= SEQUENCE +SRSASN_CODE e2node_component_interface_s1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(mme_name.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_s1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(mme_name.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_s1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("mme-name", mme_name.to_string()); + j.end_obj(); +} + +// E2nodeComponentInterfaceW1 ::= SEQUENCE +SRSASN_CODE e2node_component_interface_w1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ng_enb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_w1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ng_enb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_w1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ng-eNB-DU-ID", ng_enb_du_id); + j.end_obj(); +} + +// E2nodeComponentInterfaceX2 ::= SEQUENCE +SRSASN_CODE e2node_component_interface_x2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(global_enb_id_present, 1)); + HANDLE_CODE(bref.pack(global_en_g_nb_id_present, 1)); + + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.pack(bref)); + } + if (global_en_g_nb_id_present) { + HANDLE_CODE(global_en_g_nb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_x2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(global_enb_id_present, 1)); + HANDLE_CODE(bref.unpack(global_en_g_nb_id_present, 1)); + + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.unpack(bref)); + } + if (global_en_g_nb_id_present) { + HANDLE_CODE(global_en_g_nb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void e2node_component_interface_x2_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (global_enb_id_present) { + j.write_fieldname("global-eNB-ID"); + global_enb_id.to_json(j); + } + if (global_en_g_nb_id_present) { + j.write_fieldname("global-en-gNB-ID"); + global_en_g_nb_id.to_json(j); + } + j.end_obj(); +} + +// E2nodeComponentInterfaceXn ::= SEQUENCE +SRSASN_CODE e2node_component_interface_xn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_node_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_interface_xn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_node_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_interface_xn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-Node-ID"); + global_ng_ran_node_id.to_json(j); + j.end_obj(); +} + +// RICactionType ::= ENUMERATED +const char* ri_caction_type_opts::to_string() const +{ + static const char* options[] = {"report", "insert", "policy"}; + return convert_enum_idx(options, 3, value, "ri_caction_type_e"); +} + +// RICsubsequentAction ::= SEQUENCE +SRSASN_CODE ricsubsequent_action_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ric_subsequent_action_type.pack(bref)); + HANDLE_CODE(ric_time_to_wait.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubsequent_action_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ric_subsequent_action_type.unpack(bref)); + HANDLE_CODE(ric_time_to_wait.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ricsubsequent_action_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ricSubsequentActionType", ric_subsequent_action_type.to_string()); + j.write_str("ricTimeToWait", ric_time_to_wait.to_string()); + j.end_obj(); +} + +// E2nodeComponentConfiguration ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_request_part.pack(bref)); + HANDLE_CODE(e2node_component_resp_part.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_request_part.unpack(bref)); + HANDLE_CODE(e2node_component_resp_part.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentRequestPart", e2node_component_request_part.to_string()); + j.write_str("e2nodeComponentResponsePart", e2node_component_resp_part.to_string()); + j.end_obj(); +} + +// E2nodeComponentConfigurationAck ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_ack_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(fail_cause_present, 1)); + + HANDLE_CODE(upd_outcome.pack(bref)); + if (fail_cause_present) { + HANDLE_CODE(fail_cause.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_ack_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(fail_cause_present, 1)); + + HANDLE_CODE(upd_outcome.unpack(bref)); + if (fail_cause_present) { + HANDLE_CODE(fail_cause.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_ack_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("updateOutcome", upd_outcome.to_string()); + if (fail_cause_present) { + j.write_fieldname("failureCause"); + fail_cause.to_json(j); + } + j.end_obj(); +} + +const char* e2node_component_cfg_ack_s::upd_outcome_opts::to_string() const +{ + static const char* options[] = {"success", "failure"}; + return convert_enum_idx(options, 2, value, "e2node_component_cfg_ack_s::upd_outcome_e_"); +} + +// E2nodeComponentID ::= CHOICE +void e2node_component_id_c::destroy_() +{ + switch (type_) { + case types::e2node_component_interface_type_ng: + c.destroy(); + break; + case types::e2node_component_interface_type_xn: + c.destroy(); + break; + case types::e2node_component_interface_type_e1: + c.destroy(); + break; + case types::e2node_component_interface_type_f1: + c.destroy(); + break; + case types::e2node_component_interface_type_w1: + c.destroy(); + break; + case types::e2node_component_interface_type_s1: + c.destroy(); + break; + case types::e2node_component_interface_type_x2: + c.destroy(); + break; + default: + break; + } +} +void e2node_component_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::e2node_component_interface_type_ng: + c.init(); + break; + case types::e2node_component_interface_type_xn: + c.init(); + break; + case types::e2node_component_interface_type_e1: + c.init(); + break; + case types::e2node_component_interface_type_f1: + c.init(); + break; + case types::e2node_component_interface_type_w1: + c.init(); + break; + case types::e2node_component_interface_type_s1: + c.init(); + break; + case types::e2node_component_interface_type_x2: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + } +} +e2node_component_id_c::e2node_component_id_c(const e2node_component_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::e2node_component_interface_type_ng: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_xn: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_e1: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_f1: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_w1: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_s1: + c.init(other.c.get()); + break; + case types::e2node_component_interface_type_x2: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + } +} +e2node_component_id_c& e2node_component_id_c::operator=(const e2node_component_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::e2node_component_interface_type_ng: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_xn: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_e1: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_f1: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_w1: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_s1: + c.set(other.c.get()); + break; + case types::e2node_component_interface_type_x2: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + } + + return *this; +} +e2node_component_interface_ng_s& e2node_component_id_c::set_e2node_component_interface_type_ng() +{ + set(types::e2node_component_interface_type_ng); + return c.get(); +} +e2node_component_interface_xn_s& e2node_component_id_c::set_e2node_component_interface_type_xn() +{ + set(types::e2node_component_interface_type_xn); + return c.get(); +} +e2node_component_interface_e1_s& e2node_component_id_c::set_e2node_component_interface_type_e1() +{ + set(types::e2node_component_interface_type_e1); + return c.get(); +} +e2node_component_interface_f1_s& e2node_component_id_c::set_e2node_component_interface_type_f1() +{ + set(types::e2node_component_interface_type_f1); + return c.get(); +} +e2node_component_interface_w1_s& e2node_component_id_c::set_e2node_component_interface_type_w1() +{ + set(types::e2node_component_interface_type_w1); + return c.get(); +} +e2node_component_interface_s1_s& e2node_component_id_c::set_e2node_component_interface_type_s1() +{ + set(types::e2node_component_interface_type_s1); + return c.get(); +} +e2node_component_interface_x2_s& e2node_component_id_c::set_e2node_component_interface_type_x2() +{ + set(types::e2node_component_interface_type_x2); + return c.get(); +} +void e2node_component_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::e2node_component_interface_type_ng: + j.write_fieldname("e2nodeComponentInterfaceTypeNG"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_xn: + j.write_fieldname("e2nodeComponentInterfaceTypeXn"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_e1: + j.write_fieldname("e2nodeComponentInterfaceTypeE1"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_f1: + j.write_fieldname("e2nodeComponentInterfaceTypeF1"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_w1: + j.write_fieldname("e2nodeComponentInterfaceTypeW1"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_s1: + j.write_fieldname("e2nodeComponentInterfaceTypeS1"); + c.get().to_json(j); + break; + case types::e2node_component_interface_type_x2: + j.write_fieldname("e2nodeComponentInterfaceTypeX2"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + } + j.end_obj(); +} +SRSASN_CODE e2node_component_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::e2node_component_interface_type_ng: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_xn: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_e1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_f1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_w1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_s1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_interface_type_x2: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::e2node_component_interface_type_ng: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_xn: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_e1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_f1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_w1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_s1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_interface_type_x2: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2node_component_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2node_component_id_c::types_opts::to_string() const +{ + static const char* options[] = {"e2nodeComponentInterfaceTypeNG", + "e2nodeComponentInterfaceTypeXn", + "e2nodeComponentInterfaceTypeE1", + "e2nodeComponentInterfaceTypeF1", + "e2nodeComponentInterfaceTypeW1", + "e2nodeComponentInterfaceTypeS1", + "e2nodeComponentInterfaceTypeX2"}; + return convert_enum_idx(options, 7, value, "e2node_component_id_c::types"); +} + +// E2nodeComponentInterfaceType ::= ENUMERATED +const char* e2node_component_interface_type_opts::to_string() const +{ + static const char* options[] = {"ng", "xn", "e1", "f1", "w1", "s1", "x2"}; + return convert_enum_idx(options, 7, value, "e2node_component_interface_type_e"); +} + +// RICaction-ToBeSetup-Item ::= SEQUENCE +SRSASN_CODE ri_caction_to_be_setup_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ric_action_definition.size() > 0, 1)); + HANDLE_CODE(bref.pack(ric_subsequent_action_present, 1)); + + HANDLE_CODE(pack_integer(bref, ric_action_id, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(ric_action_type.pack(bref)); + if (ric_action_definition.size() > 0) { + HANDLE_CODE(ric_action_definition.pack(bref)); + } + if (ric_subsequent_action_present) { + HANDLE_CODE(ric_subsequent_action.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_to_be_setup_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool ric_action_definition_present; + HANDLE_CODE(bref.unpack(ric_action_definition_present, 1)); + HANDLE_CODE(bref.unpack(ric_subsequent_action_present, 1)); + + HANDLE_CODE(unpack_integer(ric_action_id, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(ric_action_type.unpack(bref)); + if (ric_action_definition_present) { + HANDLE_CODE(ric_action_definition.unpack(bref)); + } + if (ric_subsequent_action_present) { + HANDLE_CODE(ric_subsequent_action.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ri_caction_to_be_setup_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ricActionID", ric_action_id); + j.write_str("ricActionType", ric_action_type.to_string()); + if (ric_action_definition.size() > 0) { + j.write_str("ricActionDefinition", ric_action_definition.to_string()); + } + if (ric_subsequent_action_present) { + j.write_fieldname("ricSubsequentAction"); + ric_subsequent_action.to_json(j); + } + j.end_obj(); +} + +// TNLinformation ::= SEQUENCE +SRSASN_CODE tn_linfo_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(tnl_port_present, 1)); + + HANDLE_CODE(tnl_address.pack(bref)); + if (tnl_port_present) { + HANDLE_CODE(tnl_port.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE tn_linfo_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(tnl_port_present, 1)); + + HANDLE_CODE(tnl_address.unpack(bref)); + if (tnl_port_present) { + HANDLE_CODE(tnl_port.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void tn_linfo_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("tnlAddress", tnl_address.to_string()); + if (tnl_port_present) { + j.write_str("tnlPort", tnl_port.to_string()); + } + j.end_obj(); +} + +// TNLusage ::= ENUMERATED +const char* tn_lusage_opts::to_string() const +{ + static const char* options[] = {"ric-service", "support-function", "both"}; + return convert_enum_idx(options, 3, value, "tn_lusage_e"); +} + +// E2connectionSetupFailed-Item ::= SEQUENCE +SRSASN_CODE e2conn_setup_failed_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(tnl_info.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_setup_failed_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(tnl_info.unpack(bref)); + HANDLE_CODE(cause.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2conn_setup_failed_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("tnlInformation"); + tnl_info.to_json(j); + j.write_fieldname("cause"); + cause.to_json(j); + j.end_obj(); +} + +// E2connectionUpdate-Item ::= SEQUENCE +SRSASN_CODE e2conn_upd_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(tnl_info.pack(bref)); + HANDLE_CODE(tnl_usage.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(tnl_info.unpack(bref)); + HANDLE_CODE(tnl_usage.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2conn_upd_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("tnlInformation"); + tnl_info.to_json(j); + j.write_str("tnlUsage", tnl_usage.to_string()); + j.end_obj(); +} + +// E2connectionUpdateRemove-Item ::= SEQUENCE +SRSASN_CODE e2conn_upd_rem_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(tnl_info.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_rem_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(tnl_info.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2conn_upd_rem_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("tnlInformation"); + tnl_info.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigAddition-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_addition_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + HANDLE_CODE(e2node_component_cfg.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_addition_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + HANDLE_CODE(e2node_component_cfg.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_addition_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.write_fieldname("e2nodeComponentConfiguration"); + e2node_component_cfg.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigAdditionAck-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_addition_ack_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_addition_ack_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_addition_ack_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.write_fieldname("e2nodeComponentConfigurationAck"); + e2node_component_cfg_ack.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigRemoval-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_removal_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_removal_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_removal_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigRemovalAck-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_removal_ack_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_removal_ack_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_removal_ack_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.write_fieldname("e2nodeComponentConfigurationAck"); + e2node_component_cfg_ack.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigUpdate-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_upd_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + HANDLE_CODE(e2node_component_cfg.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_upd_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + HANDLE_CODE(e2node_component_cfg.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_upd_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.write_fieldname("e2nodeComponentConfiguration"); + e2node_component_cfg.to_json(j); + j.end_obj(); +} + +// E2nodeComponentConfigUpdateAck-Item ::= SEQUENCE +SRSASN_CODE e2node_component_cfg_upd_ack_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.pack(bref)); + HANDLE_CODE(e2node_component_id.pack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_upd_ack_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(e2node_component_interface_type.unpack(bref)); + HANDLE_CODE(e2node_component_id.unpack(bref)); + HANDLE_CODE(e2node_component_cfg_ack.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_component_cfg_upd_ack_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("e2nodeComponentInterfaceType", e2node_component_interface_type.to_string()); + j.write_fieldname("e2nodeComponentID"); + e2node_component_id.to_json(j); + j.write_fieldname("e2nodeComponentConfigurationAck"); + e2node_component_cfg_ack.to_json(j); + j.end_obj(); +} + +// E2nodeTNLassociationRemoval-Item ::= SEQUENCE +SRSASN_CODE e2node_tn_lassoc_removal_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(tnl_info.pack(bref)); + HANDLE_CODE(tnl_info_ric.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_tn_lassoc_removal_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(tnl_info.unpack(bref)); + HANDLE_CODE(tnl_info_ric.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2node_tn_lassoc_removal_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("tnlInformation"); + tnl_info.to_json(j); + j.write_fieldname("tnlInformationRIC"); + tnl_info_ric.to_json(j); + j.end_obj(); +} + +// RANfunction-Item ::= SEQUENCE +SRSASN_CODE ra_nfunction_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ran_function_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(ran_function_definition.pack(bref)); + HANDLE_CODE(pack_integer(bref, ran_function_revision, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(ran_function_oid.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ran_function_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(ran_function_definition.unpack(bref)); + HANDLE_CODE(unpack_integer(ran_function_revision, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(ran_function_oid.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ra_nfunction_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ranFunctionID", ran_function_id); + j.write_str("ranFunctionDefinition", ran_function_definition.to_string()); + j.write_int("ranFunctionRevision", ran_function_revision); + j.write_str("ranFunctionOID", ran_function_oid.to_string()); + j.end_obj(); +} + +// RANfunctionID-Item ::= SEQUENCE +SRSASN_CODE ra_nfunction_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ran_function_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(pack_integer(bref, ran_function_revision, (uint16_t)0u, (uint16_t)4095u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ran_function_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(unpack_integer(ran_function_revision, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + + return SRSASN_SUCCESS; +} +void ra_nfunction_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ranFunctionID", ran_function_id); + j.write_int("ranFunctionRevision", ran_function_revision); + j.end_obj(); +} + +// RANfunctionIDcause-Item ::= SEQUENCE +SRSASN_CODE ra_nfunction_idcause_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ran_function_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(cause.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_idcause_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ran_function_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(cause.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ra_nfunction_idcause_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ranFunctionID", ran_function_id); + j.write_fieldname("cause"); + cause.to_json(j); + j.end_obj(); +} + +// RICaction-Admitted-Item ::= SEQUENCE +SRSASN_CODE ri_caction_admitted_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ric_action_id, (uint16_t)0u, (uint16_t)255u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_admitted_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ric_action_id, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + + return SRSASN_SUCCESS; +} +void ri_caction_admitted_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ricActionID", ric_action_id); + j.end_obj(); +} + +// RICaction-NotAdmitted-Item ::= SEQUENCE +SRSASN_CODE ri_caction_not_admitted_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ric_action_id, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(cause.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_not_admitted_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ric_action_id, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(cause.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ri_caction_not_admitted_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ricActionID", ric_action_id); + j.write_fieldname("cause"); + cause.to_json(j); + j.end_obj(); +} + +// RICaction-ToBeSetup-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_caction_to_be_setup_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {19}; + return map_enum_number(options, 1, idx, "id"); +} +bool ri_caction_to_be_setup_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 19 == id; +} +crit_e ri_caction_to_be_setup_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 19) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ri_caction_to_be_setup_item_ies_o::value_c ri_caction_to_be_setup_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 19) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_caction_to_be_setup_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 19) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ri_caction_to_be_setup_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RICaction-ToBeSetup-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ri_caction_to_be_setup_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_to_be_setup_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ri_caction_to_be_setup_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICaction-ToBeSetup-Item"}; + return convert_enum_idx(options, 1, value, "ri_caction_to_be_setup_item_ies_o::value_c::types"); +} + +// RICsubscription-withCause-Item ::= SEQUENCE +SRSASN_CODE ricsubscription_with_cause_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ric_request_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, ran_function_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(cause.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_with_cause_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ric_request_id.unpack(bref)); + HANDLE_CODE(unpack_integer(ran_function_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + HANDLE_CODE(cause.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ricsubscription_with_cause_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ricRequestID"); + ric_request_id.to_json(j); + j.write_int("ranFunctionID", ran_function_id); + j.write_fieldname("cause"); + cause.to_json(j); + j.end_obj(); +} + +// E2connectionSetupFailed-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_setup_failed_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {41}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2conn_setup_failed_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 41 == id; +} +crit_e e2conn_setup_failed_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 41) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2conn_setup_failed_item_ies_o::value_c e2conn_setup_failed_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 41) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_setup_failed_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 41) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_setup_failed_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2connectionSetupFailed-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2conn_setup_failed_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_setup_failed_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2conn_setup_failed_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2connectionSetupFailed-Item"}; + return convert_enum_idx(options, 1, value, "e2conn_setup_failed_item_ies_o::value_c::types"); +} +uint8_t e2conn_setup_failed_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2conn_setup_failed_item_ies_o::value_c::types"); +} + +// E2connectionUpdate-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_upd_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {43}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2conn_upd_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 43 == id; +} +crit_e e2conn_upd_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 43) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2conn_upd_item_ies_o::value_c e2conn_upd_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 43) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_upd_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 43) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_upd_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2connectionUpdate-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2conn_upd_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2conn_upd_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2connectionUpdate-Item"}; + return convert_enum_idx(options, 1, value, "e2conn_upd_item_ies_o::value_c::types"); +} +uint8_t e2conn_upd_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2conn_upd_item_ies_o::value_c::types"); +} + +// E2connectionUpdateRemove-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_upd_rem_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {47}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2conn_upd_rem_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 47 == id; +} +crit_e e2conn_upd_rem_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 47) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2conn_upd_rem_item_ies_o::value_c e2conn_upd_rem_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 47) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_upd_rem_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 47) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_upd_rem_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2connectionUpdateRemove-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2conn_upd_rem_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_rem_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2conn_upd_rem_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2connectionUpdateRemove-Item"}; + return convert_enum_idx(options, 1, value, "e2conn_upd_rem_item_ies_o::value_c::types"); +} +uint8_t e2conn_upd_rem_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2conn_upd_rem_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigAddition-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_addition_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {51}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_addition_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 51 == id; +} +crit_e e2node_component_cfg_addition_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 51) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_addition_item_ies_o::value_c +e2node_component_cfg_addition_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 51) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_addition_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 51) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_addition_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigAddition-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_addition_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_addition_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_addition_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigAddition-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_addition_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_addition_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_addition_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigAdditionAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_addition_ack_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {53}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_addition_ack_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 53 == id; +} +crit_e e2node_component_cfg_addition_ack_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 53) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_addition_ack_item_ies_o::value_c +e2node_component_cfg_addition_ack_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 53) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_addition_ack_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 53) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_addition_ack_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigAdditionAck-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_addition_ack_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_addition_ack_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_addition_ack_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigAdditionAck-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_addition_ack_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_addition_ack_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_addition_ack_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigRemoval-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_removal_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {55}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_removal_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 55 == id; +} +crit_e e2node_component_cfg_removal_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 55) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_removal_item_ies_o::value_c e2node_component_cfg_removal_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 55) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_removal_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 55) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_removal_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigRemoval-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_removal_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_removal_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_removal_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigRemoval-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_removal_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_removal_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_removal_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigRemovalAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_removal_ack_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {57}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_removal_ack_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 57 == id; +} +crit_e e2node_component_cfg_removal_ack_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 57) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_removal_ack_item_ies_o::value_c +e2node_component_cfg_removal_ack_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 57) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_removal_ack_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 57) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_removal_ack_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigRemovalAck-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_removal_ack_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_removal_ack_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_removal_ack_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigRemovalAck-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_removal_ack_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_removal_ack_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_removal_ack_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigUpdate-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_upd_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {34}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_upd_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 34 == id; +} +crit_e e2node_component_cfg_upd_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 34) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_upd_item_ies_o::value_c e2node_component_cfg_upd_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 34) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_upd_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 34) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_upd_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigUpdate-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_upd_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_upd_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_upd_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigUpdate-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_upd_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_upd_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_upd_item_ies_o::value_c::types"); +} + +// E2nodeComponentConfigUpdateAck-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_component_cfg_upd_ack_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {36}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_component_cfg_upd_ack_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 36 == id; +} +crit_e e2node_component_cfg_upd_ack_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 36) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_component_cfg_upd_ack_item_ies_o::value_c e2node_component_cfg_upd_ack_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 36) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_component_cfg_upd_ack_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 36) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_component_cfg_upd_ack_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeComponentConfigUpdateAck-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_component_cfg_upd_ack_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_component_cfg_upd_ack_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_component_cfg_upd_ack_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeComponentConfigUpdateAck-Item"}; + return convert_enum_idx(options, 1, value, "e2node_component_cfg_upd_ack_item_ies_o::value_c::types"); +} +uint8_t e2node_component_cfg_upd_ack_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_component_cfg_upd_ack_item_ies_o::value_c::types"); +} + +// E2nodeTNLassociationRemoval-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_tn_lassoc_removal_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {59}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2node_tn_lassoc_removal_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 59 == id; +} +crit_e e2node_tn_lassoc_removal_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 59) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2node_tn_lassoc_removal_item_ies_o::value_c e2node_tn_lassoc_removal_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 59) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_tn_lassoc_removal_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 59) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2node_tn_lassoc_removal_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("E2nodeTNLassociationRemoval-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2node_tn_lassoc_removal_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_tn_lassoc_removal_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2node_tn_lassoc_removal_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"E2nodeTNLassociationRemoval-Item"}; + return convert_enum_idx(options, 1, value, "e2node_tn_lassoc_removal_item_ies_o::value_c::types"); +} +uint8_t e2node_tn_lassoc_removal_item_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {2}; + return map_enum_number(options, 1, value, "e2node_tn_lassoc_removal_item_ies_o::value_c::types"); +} + +// GlobalE2node-eNB-ID ::= SEQUENCE +SRSASN_CODE global_e2node_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_e2node_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_e2node_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-eNB-ID"); + global_enb_id.to_json(j); + j.end_obj(); +} + +// GlobalE2node-en-gNB-ID ::= SEQUENCE +SRSASN_CODE global_e2node_en_g_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(en_g_nb_cu_up_id_present, 1)); + HANDLE_CODE(bref.pack(en_g_nb_du_id_present, 1)); + + HANDLE_CODE(global_en_g_nb_id.pack(bref)); + if (en_g_nb_cu_up_id_present) { + HANDLE_CODE(pack_integer(bref, en_g_nb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (en_g_nb_du_id_present) { + HANDLE_CODE(pack_integer(bref, en_g_nb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_e2node_en_g_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(en_g_nb_cu_up_id_present, 1)); + HANDLE_CODE(bref.unpack(en_g_nb_du_id_present, 1)); + + HANDLE_CODE(global_en_g_nb_id.unpack(bref)); + if (en_g_nb_cu_up_id_present) { + HANDLE_CODE(unpack_integer(en_g_nb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (en_g_nb_du_id_present) { + HANDLE_CODE(unpack_integer(en_g_nb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +void global_e2node_en_g_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-en-gNB-ID"); + global_en_g_nb_id.to_json(j); + if (en_g_nb_cu_up_id_present) { + j.write_int("en-gNB-CU-UP-ID", en_g_nb_cu_up_id); + } + if (en_g_nb_du_id_present) { + j.write_int("en-gNB-DU-ID", en_g_nb_du_id); + } + j.end_obj(); +} + +// GlobalE2node-gNB-ID ::= SEQUENCE +SRSASN_CODE global_e2node_g_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(global_en_g_nb_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_up_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_du_id_present, 1)); + + HANDLE_CODE(global_g_nb_id.pack(bref)); + if (global_en_g_nb_id_present) { + HANDLE_CODE(global_en_g_nb_id.pack(bref)); + } + if (gnb_cu_up_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (gnb_du_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_e2node_g_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(global_en_g_nb_id_present, 1)); + HANDLE_CODE(bref.unpack(gnb_cu_up_id_present, 1)); + HANDLE_CODE(bref.unpack(gnb_du_id_present, 1)); + + HANDLE_CODE(global_g_nb_id.unpack(bref)); + if (global_en_g_nb_id_present) { + HANDLE_CODE(global_en_g_nb_id.unpack(bref)); + } + if (gnb_cu_up_id_present) { + HANDLE_CODE(unpack_integer(gnb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (gnb_du_id_present) { + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +void global_e2node_g_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-gNB-ID"); + global_g_nb_id.to_json(j); + if (global_en_g_nb_id_present) { + j.write_fieldname("global-en-gNB-ID"); + global_en_g_nb_id.to_json(j); + } + if (gnb_cu_up_id_present) { + j.write_int("gNB-CU-UP-ID", gnb_cu_up_id); + } + if (gnb_du_id_present) { + j.write_int("gNB-DU-ID", gnb_du_id); + } + j.end_obj(); +} + +// GlobalE2node-ng-eNB-ID ::= SEQUENCE +SRSASN_CODE global_e2node_ng_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(global_enb_id_present, 1)); + HANDLE_CODE(bref.pack(ng_enb_du_id_present, 1)); + + HANDLE_CODE(global_ng_enb_id.pack(bref)); + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.pack(bref)); + } + if (ng_enb_du_id_present) { + HANDLE_CODE(pack_integer(bref, ng_enb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_e2node_ng_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(global_enb_id_present, 1)); + HANDLE_CODE(bref.unpack(ng_enb_du_id_present, 1)); + + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.unpack(bref)); + } + if (ng_enb_du_id_present) { + HANDLE_CODE(unpack_integer(ng_enb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +void global_e2node_ng_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-ng-eNB-ID"); + global_ng_enb_id.to_json(j); + if (global_enb_id_present) { + j.write_fieldname("global-eNB-ID"); + global_enb_id.to_json(j); + } + if (ng_enb_du_id_present) { + j.write_int("ngENB-DU-ID", ng_enb_du_id); + } + j.end_obj(); +} + +// RANfunction-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ra_nfunction_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {8}; + return map_enum_number(options, 1, idx, "id"); +} +bool ra_nfunction_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 8 == id; +} +crit_e ra_nfunction_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 8) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ra_nfunction_item_ies_o::value_c ra_nfunction_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 8) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ra_nfunction_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 8) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ra_nfunction_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RANfunction-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ra_nfunction_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ra_nfunction_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RANfunction-Item"}; + return convert_enum_idx(options, 1, value, "ra_nfunction_item_ies_o::value_c::types"); +} + +// RANfunctionID-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ra_nfunction_id_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {6}; + return map_enum_number(options, 1, idx, "id"); +} +bool ra_nfunction_id_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 6 == id; +} +crit_e ra_nfunction_id_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 6) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ra_nfunction_id_item_ies_o::value_c ra_nfunction_id_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 6) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ra_nfunction_id_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 6) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ra_nfunction_id_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RANfunctionID-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ra_nfunction_id_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_id_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ra_nfunction_id_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RANfunctionID-Item"}; + return convert_enum_idx(options, 1, value, "ra_nfunction_id_item_ies_o::value_c::types"); +} + +// RANfunctionIDcause-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ra_nfunction_idcause_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {7}; + return map_enum_number(options, 1, idx, "id"); +} +bool ra_nfunction_idcause_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 7 == id; +} +crit_e ra_nfunction_idcause_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 7) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ra_nfunction_idcause_item_ies_o::value_c ra_nfunction_idcause_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 7) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ra_nfunction_idcause_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 7) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ra_nfunction_idcause_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RANfunctionIDcause-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ra_nfunction_idcause_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_idcause_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ra_nfunction_idcause_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RANfunctionIDcause-Item"}; + return convert_enum_idx(options, 1, value, "ra_nfunction_idcause_item_ies_o::value_c::types"); +} + +// RICaction-Admitted-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_caction_admitted_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {14}; + return map_enum_number(options, 1, idx, "id"); +} +bool ri_caction_admitted_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 14 == id; +} +crit_e ri_caction_admitted_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 14) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ri_caction_admitted_item_ies_o::value_c ri_caction_admitted_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 14) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_caction_admitted_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 14) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ri_caction_admitted_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RICaction-Admitted-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ri_caction_admitted_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_admitted_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ri_caction_admitted_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICaction-Admitted-Item"}; + return convert_enum_idx(options, 1, value, "ri_caction_admitted_item_ies_o::value_c::types"); +} + +// RICaction-NotAdmitted-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_caction_not_admitted_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {16}; + return map_enum_number(options, 1, idx, "id"); +} +bool ri_caction_not_admitted_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 16 == id; +} +crit_e ri_caction_not_admitted_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 16) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ri_caction_not_admitted_item_ies_o::value_c ri_caction_not_admitted_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 16) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_caction_not_admitted_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 16) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ri_caction_not_admitted_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RICaction-NotAdmitted-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ri_caction_not_admitted_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_caction_not_admitted_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ri_caction_not_admitted_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICaction-NotAdmitted-Item"}; + return convert_enum_idx(options, 1, value, "ri_caction_not_admitted_item_ies_o::value_c::types"); +} + +template struct asn1::protocol_ie_single_container_s; + +// RICsubscription-withCause-ItemIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_with_cause_item_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {61}; + return map_enum_number(options, 1, idx, "id"); +} +bool ricsubscription_with_cause_item_ies_o::is_id_valid(const uint32_t& id) +{ + return 61 == id; +} +crit_e ricsubscription_with_cause_item_ies_o::get_crit(const uint32_t& id) +{ + if (id == 61) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ricsubscription_with_cause_item_ies_o::value_c ricsubscription_with_cause_item_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 61) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_with_cause_item_ies_o::get_presence(const uint32_t& id) +{ + if (id == 61) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_with_cause_item_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("RICsubscription-withCause-Item"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE ricsubscription_with_cause_item_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_with_cause_item_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* ricsubscription_with_cause_item_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICsubscription-withCause-Item"}; + return convert_enum_idx(options, 1, value, "ricsubscription_with_cause_item_ies_o::value_c::types"); +} + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +// GlobalE2node-ID ::= CHOICE +void global_e2node_id_c::destroy_() +{ + switch (type_) { + case types::gnb: + c.destroy(); + break; + case types::en_g_nb: + c.destroy(); + break; + case types::ng_enb: + c.destroy(); + break; + case types::enb: + c.destroy(); + break; + default: + break; + } +} +void global_e2node_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb: + c.init(); + break; + case types::en_g_nb: + c.init(); + break; + case types::ng_enb: + c.init(); + break; + case types::enb: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + } +} +global_e2node_id_c::global_e2node_id_c(const global_e2node_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb: + c.init(other.c.get()); + break; + case types::en_g_nb: + c.init(other.c.get()); + break; + case types::ng_enb: + c.init(other.c.get()); + break; + case types::enb: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + } +} +global_e2node_id_c& global_e2node_id_c::operator=(const global_e2node_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb: + c.set(other.c.get()); + break; + case types::en_g_nb: + c.set(other.c.get()); + break; + case types::ng_enb: + c.set(other.c.get()); + break; + case types::enb: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + } + + return *this; +} +global_e2node_g_nb_id_s& global_e2node_id_c::set_gnb() +{ + set(types::gnb); + return c.get(); +} +global_e2node_en_g_nb_id_s& global_e2node_id_c::set_en_g_nb() +{ + set(types::en_g_nb); + return c.get(); +} +global_e2node_ng_enb_id_s& global_e2node_id_c::set_ng_enb() +{ + set(types::ng_enb); + return c.get(); +} +global_e2node_enb_id_s& global_e2node_id_c::set_enb() +{ + set(types::enb); + return c.get(); +} +void global_e2node_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb: + j.write_fieldname("gNB"); + c.get().to_json(j); + break; + case types::en_g_nb: + j.write_fieldname("en-gNB"); + c.get().to_json(j); + break; + case types::ng_enb: + j.write_fieldname("ng-eNB"); + c.get().to_json(j); + break; + case types::enb: + j.write_fieldname("eNB"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_e2node_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::en_g_nb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::enb: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_e2node_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::en_g_nb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::enb: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_e2node_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_e2node_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB", "en-gNB", "ng-eNB", "eNB"}; + return convert_enum_idx(options, 4, value, "global_e2node_id_c::types"); +} + +// GlobalRIC-ID ::= SEQUENCE +SRSASN_CODE global_ric_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(ric_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ric_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(ric_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_ric_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_str("ric-ID", ric_id.to_string()); + j.end_obj(); +} + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +template struct asn1::protocol_ie_single_container_s; + +// RICcontrolAckRequest ::= ENUMERATED +const char* ri_cctrl_ack_request_opts::to_string() const +{ + static const char* options[] = {"noAck", "ack"}; + return convert_enum_idx(options, 2, value, "ri_cctrl_ack_request_e"); +} + +// RICindicationType ::= ENUMERATED +const char* ri_cind_type_opts::to_string() const +{ + static const char* options[] = {"report", "insert"}; + return convert_enum_idx(options, 2, value, "ri_cind_type_e"); +} + +template struct asn1::protocol_ie_single_container_s; + +// RICsubscriptionDetails ::= SEQUENCE +SRSASN_CODE ricsubscription_details_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ric_event_trigger_definition.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, ric_action_to_be_setup_list, 1, 16, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_details_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ric_event_trigger_definition.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(ric_action_to_be_setup_list, bref, 1, 16, true)); + + return SRSASN_SUCCESS; +} +void ricsubscription_details_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ricEventTriggerDefinition", ric_event_trigger_definition.to_string()); + j.start_array("ricAction-ToBeSetup-List"); + for (const auto& e1 : ric_action_to_be_setup_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// TimeToWait ::= ENUMERATED +const char* time_to_wait_opts::to_string() const +{ + static const char* options[] = {"v1s", "v2s", "v5s", "v10s", "v20s", "v60s"}; + return convert_enum_idx(options, 6, value, "time_to_wait_e"); +} +uint8_t time_to_wait_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 5, 10, 20, 60}; + return map_enum_number(options, 6, value, "time_to_wait_e"); +} + +// E2RemovalFailureIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2_removal_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1, 2}; + return map_enum_number(options, 3, idx, "id"); +} +bool e2_removal_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2_removal_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2_removal_fail_ies_o::value_c e2_removal_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2_removal_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2_removal_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void e2_removal_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + } +} +e2_removal_fail_ies_o::value_c::value_c(const e2_removal_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + } +} +e2_removal_fail_ies_o::value_c& e2_removal_fail_ies_o::value_c::operator=(const e2_removal_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2_removal_fail_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& e2_removal_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& e2_removal_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& e2_removal_fail_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& e2_removal_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& e2_removal_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void e2_removal_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_removal_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_removal_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_removal_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_removal_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "Cause", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 3, value, "e2_removal_fail_ies_o::value_c::types"); +} +uint8_t e2_removal_fail_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2_removal_fail_ies_o::value_c::types"); +} + +// E2RemovalRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2_removal_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49}; + return map_enum_number(options, 1, idx, "id"); +} +bool e2_removal_request_ies_o::is_id_valid(const uint32_t& id) +{ + return 49 == id; +} +crit_e e2_removal_request_ies_o::get_crit(const uint32_t& id) +{ + if (id == 49) { + return crit_e::reject; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +e2_removal_request_ies_o::value_c e2_removal_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 49) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2_removal_request_ies_o::get_presence(const uint32_t& id) +{ + if (id == 49) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void e2_removal_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("INTEGER (0..255,...)", c); + j.end_obj(); +} +SRSASN_CODE e2_removal_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(pack_integer(bref, c, (uint16_t)0u, (uint16_t)255u, true, true)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_removal_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(unpack_integer(c, bref, (uint16_t)0u, (uint16_t)255u, true, true)); + return SRSASN_SUCCESS; +} + +const char* e2_removal_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)"}; + return convert_enum_idx(options, 1, value, "e2_removal_request_ies_o::value_c::types"); +} +uint8_t e2_removal_request_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2_removal_request_ies_o::value_c::types"); +} + +// E2RemovalResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2_removal_resp_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 2}; + return map_enum_number(options, 2, idx, "id"); +} +bool e2_removal_resp_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2_removal_resp_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2_removal_resp_ies_o::value_c e2_removal_resp_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2_removal_resp_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2_removal_resp_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void e2_removal_resp_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + } +} +e2_removal_resp_ies_o::value_c::value_c(const e2_removal_resp_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + } +} +e2_removal_resp_ies_o::value_c& e2_removal_resp_ies_o::value_c::operator=(const e2_removal_resp_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2_removal_resp_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& e2_removal_resp_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& e2_removal_resp_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& e2_removal_resp_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void e2_removal_resp_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_removal_resp_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_removal_resp_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_removal_resp_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_removal_resp_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 2, value, "e2_removal_resp_ies_o::value_c::types"); +} +uint8_t e2_removal_resp_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2_removal_resp_ies_o::value_c::types"); +} + +// E2connectionUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_upd_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 44, 46, 45}; + return map_enum_number(options, 4, idx, "id"); +} +bool e2conn_upd_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 44, 46, 45}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2conn_upd_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 44: + return crit_e::reject; + case 46: + return crit_e::reject; + case 45: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2conn_upd_ies_o::value_c e2conn_upd_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 44: + ret.set(value_c::types::e2conn_upd_add); + break; + case 46: + ret.set(value_c::types::e2conn_upd_rem); + break; + case 45: + ret.set(value_c::types::e2conn_upd_modify); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_upd_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 44: + return presence_e::optional; + case 46: + return presence_e::optional; + case 45: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_upd_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::e2conn_upd_add: + c.destroy(); + break; + case types::e2conn_upd_rem: + c.destroy(); + break; + case types::e2conn_upd_modify: + c.destroy(); + break; + default: + break; + } +} +void e2conn_upd_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::e2conn_upd_add: + c.init(); + break; + case types::e2conn_upd_rem: + c.init(); + break; + case types::e2conn_upd_modify: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + } +} +e2conn_upd_ies_o::value_c::value_c(const e2conn_upd_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::e2conn_upd_add: + c.init(other.c.get()); + break; + case types::e2conn_upd_rem: + c.init(other.c.get()); + break; + case types::e2conn_upd_modify: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + } +} +e2conn_upd_ies_o::value_c& e2conn_upd_ies_o::value_c::operator=(const e2conn_upd_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::e2conn_upd_add: + c.set(other.c.get()); + break; + case types::e2conn_upd_rem: + c.set(other.c.get()); + break; + case types::e2conn_upd_modify: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2conn_upd_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +e2conn_upd_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_add() +{ + assert_choice_type(types::e2conn_upd_add, type_, "Value"); + return c.get(); +} +e2conn_upd_rem_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_rem() +{ + assert_choice_type(types::e2conn_upd_rem, type_, "Value"); + return c.get(); +} +e2conn_upd_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_modify() +{ + assert_choice_type(types::e2conn_upd_modify, type_, "Value"); + return c.get(); +} +const uint16_t& e2conn_upd_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const e2conn_upd_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_add() const +{ + assert_choice_type(types::e2conn_upd_add, type_, "Value"); + return c.get(); +} +const e2conn_upd_rem_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_rem() const +{ + assert_choice_type(types::e2conn_upd_rem, type_, "Value"); + return c.get(); +} +const e2conn_upd_list_l& e2conn_upd_ies_o::value_c::e2conn_upd_modify() const +{ + assert_choice_type(types::e2conn_upd_modify, type_, "Value"); + return c.get(); +} +void e2conn_upd_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::e2conn_upd_add: + j.start_array("E2connectionUpdate-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2conn_upd_rem: + j.start_array("E2connectionUpdateRemove-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2conn_upd_modify: + j.start_array("E2connectionUpdate-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2conn_upd_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2conn_upd_add: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + case types::e2conn_upd_rem: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + case types::e2conn_upd_modify: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2conn_upd_add: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + case types::e2conn_upd_rem: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + case types::e2conn_upd_modify: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2conn_upd_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "INTEGER (0..255,...)", "E2connectionUpdate-List", "E2connectionUpdateRemove-List", "E2connectionUpdate-List"}; + return convert_enum_idx(options, 4, value, "e2conn_upd_ies_o::value_c::types"); +} + +// E2connectionUpdateAck-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_upd_ack_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 39, 40}; + return map_enum_number(options, 3, idx, "id"); +} +bool e2conn_upd_ack_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 39, 40}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2conn_upd_ack_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 39: + return crit_e::reject; + case 40: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2conn_upd_ack_ies_o::value_c e2conn_upd_ack_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 39: + ret.set(value_c::types::e2conn_setup); + break; + case 40: + ret.set(value_c::types::e2conn_setup_failed); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_upd_ack_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 39: + return presence_e::optional; + case 40: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_upd_ack_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::e2conn_setup: + c.destroy(); + break; + case types::e2conn_setup_failed: + c.destroy(); + break; + default: + break; + } +} +void e2conn_upd_ack_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::e2conn_setup: + c.init(); + break; + case types::e2conn_setup_failed: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + } +} +e2conn_upd_ack_ies_o::value_c::value_c(const e2conn_upd_ack_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::e2conn_setup: + c.init(other.c.get()); + break; + case types::e2conn_setup_failed: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + } +} +e2conn_upd_ack_ies_o::value_c& e2conn_upd_ack_ies_o::value_c::operator=(const e2conn_upd_ack_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::e2conn_setup: + c.set(other.c.get()); + break; + case types::e2conn_setup_failed: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2conn_upd_ack_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +e2conn_upd_list_l& e2conn_upd_ack_ies_o::value_c::e2conn_setup() +{ + assert_choice_type(types::e2conn_setup, type_, "Value"); + return c.get(); +} +e2conn_setup_failed_list_l& e2conn_upd_ack_ies_o::value_c::e2conn_setup_failed() +{ + assert_choice_type(types::e2conn_setup_failed, type_, "Value"); + return c.get(); +} +const uint16_t& e2conn_upd_ack_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const e2conn_upd_list_l& e2conn_upd_ack_ies_o::value_c::e2conn_setup() const +{ + assert_choice_type(types::e2conn_setup, type_, "Value"); + return c.get(); +} +const e2conn_setup_failed_list_l& e2conn_upd_ack_ies_o::value_c::e2conn_setup_failed() const +{ + assert_choice_type(types::e2conn_setup_failed, type_, "Value"); + return c.get(); +} +void e2conn_upd_ack_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::e2conn_setup: + j.start_array("E2connectionUpdate-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2conn_setup_failed: + j.start_array("E2connectionSetupFailed-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2conn_upd_ack_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2conn_setup: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + case types::e2conn_setup_failed: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_ack_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2conn_setup: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + case types::e2conn_setup_failed: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2conn_upd_ack_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "E2connectionUpdate-List", "E2connectionSetupFailed-List"}; + return convert_enum_idx(options, 3, value, "e2conn_upd_ack_ies_o::value_c::types"); +} + +// E2connectionUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2conn_upd_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + return map_enum_number(options, 4, idx, "id"); +} +bool e2conn_upd_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2conn_upd_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::reject; + case 31: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2conn_upd_fail_ies_o::value_c e2conn_upd_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 31: + ret.set(value_c::types::time_to_wait); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2conn_upd_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::optional; + case 31: + return presence_e::optional; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2conn_upd_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void e2conn_upd_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::time_to_wait: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + } +} +e2conn_upd_fail_ies_o::value_c::value_c(const e2conn_upd_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::time_to_wait: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + } +} +e2conn_upd_fail_ies_o::value_c& e2conn_upd_fail_ies_o::value_c::operator=(const e2conn_upd_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::time_to_wait: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2conn_upd_fail_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& e2conn_upd_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +time_to_wait_e& e2conn_upd_fail_ies_o::value_c::time_to_wait() +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& e2conn_upd_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& e2conn_upd_fail_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& e2conn_upd_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const time_to_wait_e& e2conn_upd_fail_ies_o::value_c::time_to_wait() const +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& e2conn_upd_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void e2conn_upd_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::time_to_wait: + j.write_str("TimeToWait", c.get().to_string()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2conn_upd_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2conn_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2conn_upd_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "Cause", "TimeToWait", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 4, value, "e2conn_upd_fail_ies_o::value_c::types"); +} +uint8_t e2conn_upd_fail_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2conn_upd_fail_ies_o::value_c::types"); +} + +// E2nodeConfigurationUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_cfg_upd_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 3, 50, 33, 54, 58}; + return map_enum_number(options, 6, idx, "id"); +} +bool e2node_cfg_upd_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 3, 50, 33, 54, 58}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2node_cfg_upd_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 3: + return crit_e::reject; + case 50: + return crit_e::reject; + case 33: + return crit_e::reject; + case 54: + return crit_e::reject; + case 58: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2node_cfg_upd_ies_o::value_c e2node_cfg_upd_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 3: + ret.set(value_c::types::global_e2node_id); + break; + case 50: + ret.set(value_c::types::e2node_component_cfg_addition); + break; + case 33: + ret.set(value_c::types::e2node_component_cfg_upd); + break; + case 54: + ret.set(value_c::types::e2node_component_cfg_removal); + break; + case 58: + ret.set(value_c::types::e2node_tn_lassoc_removal); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_cfg_upd_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 3: + return presence_e::optional; + case 50: + return presence_e::optional; + case 33: + return presence_e::optional; + case 54: + return presence_e::optional; + case 58: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2node_cfg_upd_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::global_e2node_id: + c.destroy(); + break; + case types::e2node_component_cfg_addition: + c.destroy(); + break; + case types::e2node_component_cfg_upd: + c.destroy(); + break; + case types::e2node_component_cfg_removal: + c.destroy(); + break; + case types::e2node_tn_lassoc_removal: + c.destroy(); + break; + default: + break; + } +} +void e2node_cfg_upd_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::global_e2node_id: + c.init(); + break; + case types::e2node_component_cfg_addition: + c.init(); + break; + case types::e2node_component_cfg_upd: + c.init(); + break; + case types::e2node_component_cfg_removal: + c.init(); + break; + case types::e2node_tn_lassoc_removal: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + } +} +e2node_cfg_upd_ies_o::value_c::value_c(const e2node_cfg_upd_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::global_e2node_id: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_addition: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_upd: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_removal: + c.init(other.c.get()); + break; + case types::e2node_tn_lassoc_removal: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + } +} +e2node_cfg_upd_ies_o::value_c& e2node_cfg_upd_ies_o::value_c::operator=(const e2node_cfg_upd_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::global_e2node_id: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_addition: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_upd: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_removal: + c.set(other.c.get()); + break; + case types::e2node_tn_lassoc_removal: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2node_cfg_upd_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +global_e2node_id_c& e2node_cfg_upd_ies_o::value_c::global_e2node_id() +{ + assert_choice_type(types::global_e2node_id, type_, "Value"); + return c.get(); +} +e2node_component_cfg_addition_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_addition() +{ + assert_choice_type(types::e2node_component_cfg_addition, type_, "Value"); + return c.get(); +} +e2node_component_cfg_upd_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_upd() +{ + assert_choice_type(types::e2node_component_cfg_upd, type_, "Value"); + return c.get(); +} +e2node_component_cfg_removal_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_removal() +{ + assert_choice_type(types::e2node_component_cfg_removal, type_, "Value"); + return c.get(); +} +e2node_tn_lassoc_removal_list_l& e2node_cfg_upd_ies_o::value_c::e2node_tn_lassoc_removal() +{ + assert_choice_type(types::e2node_tn_lassoc_removal, type_, "Value"); + return c.get(); +} +const uint16_t& e2node_cfg_upd_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const global_e2node_id_c& e2node_cfg_upd_ies_o::value_c::global_e2node_id() const +{ + assert_choice_type(types::global_e2node_id, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_addition_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_addition() const +{ + assert_choice_type(types::e2node_component_cfg_addition, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_upd_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_upd() const +{ + assert_choice_type(types::e2node_component_cfg_upd, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_removal_list_l& e2node_cfg_upd_ies_o::value_c::e2node_component_cfg_removal() const +{ + assert_choice_type(types::e2node_component_cfg_removal, type_, "Value"); + return c.get(); +} +const e2node_tn_lassoc_removal_list_l& e2node_cfg_upd_ies_o::value_c::e2node_tn_lassoc_removal() const +{ + assert_choice_type(types::e2node_tn_lassoc_removal, type_, "Value"); + return c.get(); +} +void e2node_cfg_upd_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::global_e2node_id: + j.write_fieldname("GlobalE2node-ID"); + c.get().to_json(j); + break; + case types::e2node_component_cfg_addition: + j.start_array("E2nodeComponentConfigAddition-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_upd: + j.start_array("E2nodeComponentConfigUpdate-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_removal: + j.start_array("E2nodeComponentConfigRemoval-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_tn_lassoc_removal: + j.start_array("E2nodeTNLassociationRemoval-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2node_cfg_upd_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_e2node_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_component_cfg_addition: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + case types::e2node_component_cfg_upd: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + case types::e2node_component_cfg_removal: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + case types::e2node_tn_lassoc_removal: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_e2node_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_component_cfg_addition: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + case types::e2node_component_cfg_upd: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + case types::e2node_component_cfg_removal: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + case types::e2node_tn_lassoc_removal: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 32, true)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2node_cfg_upd_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", + "GlobalE2node-ID", + "E2nodeComponentConfigAddition-List", + "E2nodeComponentConfigUpdate-List", + "E2nodeComponentConfigRemoval-List", + "E2nodeTNLassociationRemoval-List"}; + return convert_enum_idx(options, 6, value, "e2node_cfg_upd_ies_o::value_c::types"); +} + +// E2nodeConfigurationUpdateAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_cfg_upd_ack_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 52, 35, 56}; + return map_enum_number(options, 4, idx, "id"); +} +bool e2node_cfg_upd_ack_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 52, 35, 56}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2node_cfg_upd_ack_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 52: + return crit_e::reject; + case 35: + return crit_e::reject; + case 56: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2node_cfg_upd_ack_ies_o::value_c e2node_cfg_upd_ack_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 52: + ret.set(value_c::types::e2node_component_cfg_addition_ack); + break; + case 35: + ret.set(value_c::types::e2node_component_cfg_upd_ack); + break; + case 56: + ret.set(value_c::types::e2node_component_cfg_removal_ack); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_cfg_upd_ack_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 52: + return presence_e::optional; + case 35: + return presence_e::optional; + case 56: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2node_cfg_upd_ack_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::e2node_component_cfg_addition_ack: + c.destroy(); + break; + case types::e2node_component_cfg_upd_ack: + c.destroy(); + break; + case types::e2node_component_cfg_removal_ack: + c.destroy(); + break; + default: + break; + } +} +void e2node_cfg_upd_ack_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::e2node_component_cfg_addition_ack: + c.init(); + break; + case types::e2node_component_cfg_upd_ack: + c.init(); + break; + case types::e2node_component_cfg_removal_ack: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + } +} +e2node_cfg_upd_ack_ies_o::value_c::value_c(const e2node_cfg_upd_ack_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_addition_ack: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_upd_ack: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_removal_ack: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + } +} +e2node_cfg_upd_ack_ies_o::value_c& +e2node_cfg_upd_ack_ies_o::value_c::operator=(const e2node_cfg_upd_ack_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_addition_ack: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_upd_ack: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_removal_ack: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2node_cfg_upd_ack_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +e2node_component_cfg_addition_ack_list_l& e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_addition_ack() +{ + assert_choice_type(types::e2node_component_cfg_addition_ack, type_, "Value"); + return c.get(); +} +e2node_component_cfg_upd_ack_list_l& e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_upd_ack() +{ + assert_choice_type(types::e2node_component_cfg_upd_ack, type_, "Value"); + return c.get(); +} +e2node_component_cfg_removal_ack_list_l& e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_removal_ack() +{ + assert_choice_type(types::e2node_component_cfg_removal_ack, type_, "Value"); + return c.get(); +} +const uint16_t& e2node_cfg_upd_ack_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_addition_ack_list_l& +e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_addition_ack() const +{ + assert_choice_type(types::e2node_component_cfg_addition_ack, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_upd_ack_list_l& e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_upd_ack() const +{ + assert_choice_type(types::e2node_component_cfg_upd_ack, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_removal_ack_list_l& +e2node_cfg_upd_ack_ies_o::value_c::e2node_component_cfg_removal_ack() const +{ + assert_choice_type(types::e2node_component_cfg_removal_ack, type_, "Value"); + return c.get(); +} +void e2node_cfg_upd_ack_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::e2node_component_cfg_addition_ack: + j.start_array("E2nodeComponentConfigAdditionAck-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_upd_ack: + j.start_array("E2nodeComponentConfigUpdateAck-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_removal_ack: + j.start_array("E2nodeComponentConfigRemovalAck-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2node_cfg_upd_ack_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2node_component_cfg_addition_ack: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + case types::e2node_component_cfg_upd_ack: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + case types::e2node_component_cfg_removal_ack: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_ack_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::e2node_component_cfg_addition_ack: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + case types::e2node_component_cfg_upd_ack: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + case types::e2node_component_cfg_removal_ack: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2node_cfg_upd_ack_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", + "E2nodeComponentConfigAdditionAck-List", + "E2nodeComponentConfigUpdateAck-List", + "E2nodeComponentConfigRemovalAck-List"}; + return convert_enum_idx(options, 4, value, "e2node_cfg_upd_ack_ies_o::value_c::types"); +} + +// E2nodeConfigurationUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2node_cfg_upd_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + return map_enum_number(options, 4, idx, "id"); +} +bool e2node_cfg_upd_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2node_cfg_upd_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 31: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2node_cfg_upd_fail_ies_o::value_c e2node_cfg_upd_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 31: + ret.set(value_c::types::time_to_wait); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2node_cfg_upd_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 31: + return presence_e::optional; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2node_cfg_upd_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void e2node_cfg_upd_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::time_to_wait: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + } +} +e2node_cfg_upd_fail_ies_o::value_c::value_c(const e2node_cfg_upd_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::time_to_wait: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + } +} +e2node_cfg_upd_fail_ies_o::value_c& +e2node_cfg_upd_fail_ies_o::value_c::operator=(const e2node_cfg_upd_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::time_to_wait: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2node_cfg_upd_fail_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& e2node_cfg_upd_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +time_to_wait_e& e2node_cfg_upd_fail_ies_o::value_c::time_to_wait() +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& e2node_cfg_upd_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& e2node_cfg_upd_fail_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& e2node_cfg_upd_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const time_to_wait_e& e2node_cfg_upd_fail_ies_o::value_c::time_to_wait() const +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& e2node_cfg_upd_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void e2node_cfg_upd_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::time_to_wait: + j.write_str("TimeToWait", c.get().to_string()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2node_cfg_upd_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2node_cfg_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2node_cfg_upd_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "Cause", "TimeToWait", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 4, value, "e2node_cfg_upd_fail_ies_o::value_c::types"); +} +uint8_t e2node_cfg_upd_fail_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2node_cfg_upd_fail_ies_o::value_c::types"); +} + +// E2setupFailureIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2setup_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1, 31, 2, 48}; + return map_enum_number(options, 5, idx, "id"); +} +bool e2setup_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1, 31, 2, 48}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2setup_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 31: + return crit_e::ignore; + case 2: + return crit_e::ignore; + case 48: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2setup_fail_ies_o::value_c e2setup_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 31: + ret.set(value_c::types::time_to_wait); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + case 48: + ret.set(value_c::types::tn_linfo); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2setup_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 31: + return presence_e::optional; + case 2: + return presence_e::optional; + case 48: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2setup_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + case types::tn_linfo: + c.destroy(); + break; + default: + break; + } +} +void e2setup_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::time_to_wait: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::tn_linfo: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + } +} +e2setup_fail_ies_o::value_c::value_c(const e2setup_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::time_to_wait: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::tn_linfo: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + } +} +e2setup_fail_ies_o::value_c& e2setup_fail_ies_o::value_c::operator=(const e2setup_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::time_to_wait: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::tn_linfo: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2setup_fail_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& e2setup_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +time_to_wait_e& e2setup_fail_ies_o::value_c::time_to_wait() +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& e2setup_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +tn_linfo_s& e2setup_fail_ies_o::value_c::tn_linfo() +{ + assert_choice_type(types::tn_linfo, type_, "Value"); + return c.get(); +} +const uint16_t& e2setup_fail_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& e2setup_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const time_to_wait_e& e2setup_fail_ies_o::value_c::time_to_wait() const +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& e2setup_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const tn_linfo_s& e2setup_fail_ies_o::value_c::tn_linfo() const +{ + assert_choice_type(types::tn_linfo, type_, "Value"); + return c.get(); +} +void e2setup_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::time_to_wait: + j.write_str("TimeToWait", c.get().to_string()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + case types::tn_linfo: + j.write_fieldname("TNLinformation"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2setup_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::tn_linfo: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::tn_linfo: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2setup_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2setup_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "INTEGER (0..255,...)", "Cause", "TimeToWait", "CriticalityDiagnostics", "TNLinformation"}; + return convert_enum_idx(options, 5, value, "e2setup_fail_ies_o::value_c::types"); +} +uint8_t e2setup_fail_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "e2setup_fail_ies_o::value_c::types"); +} + +// E2setupRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2setup_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 3, 10, 50}; + return map_enum_number(options, 4, idx, "id"); +} +bool e2setup_request_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 3, 10, 50}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2setup_request_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 3: + return crit_e::reject; + case 10: + return crit_e::reject; + case 50: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2setup_request_ies_o::value_c e2setup_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 3: + ret.set(value_c::types::global_e2node_id); + break; + case 10: + ret.set(value_c::types::ra_nfunctions_added); + break; + case 50: + ret.set(value_c::types::e2node_component_cfg_addition); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2setup_request_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 3: + return presence_e::mandatory; + case 10: + return presence_e::mandatory; + case 50: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2setup_request_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::global_e2node_id: + c.destroy(); + break; + case types::ra_nfunctions_added: + c.destroy(); + break; + case types::e2node_component_cfg_addition: + c.destroy(); + break; + default: + break; + } +} +void e2setup_request_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::global_e2node_id: + c.init(); + break; + case types::ra_nfunctions_added: + c.init(); + break; + case types::e2node_component_cfg_addition: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + } +} +e2setup_request_ies_o::value_c::value_c(const e2setup_request_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::global_e2node_id: + c.init(other.c.get()); + break; + case types::ra_nfunctions_added: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_addition: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + } +} +e2setup_request_ies_o::value_c& e2setup_request_ies_o::value_c::operator=(const e2setup_request_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::global_e2node_id: + c.set(other.c.get()); + break; + case types::ra_nfunctions_added: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_addition: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2setup_request_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +global_e2node_id_c& e2setup_request_ies_o::value_c::global_e2node_id() +{ + assert_choice_type(types::global_e2node_id, type_, "Value"); + return c.get(); +} +ra_nfunctions_list_l& e2setup_request_ies_o::value_c::ra_nfunctions_added() +{ + assert_choice_type(types::ra_nfunctions_added, type_, "Value"); + return c.get(); +} +e2node_component_cfg_addition_list_l& e2setup_request_ies_o::value_c::e2node_component_cfg_addition() +{ + assert_choice_type(types::e2node_component_cfg_addition, type_, "Value"); + return c.get(); +} +const uint16_t& e2setup_request_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const global_e2node_id_c& e2setup_request_ies_o::value_c::global_e2node_id() const +{ + assert_choice_type(types::global_e2node_id, type_, "Value"); + return c.get(); +} +const ra_nfunctions_list_l& e2setup_request_ies_o::value_c::ra_nfunctions_added() const +{ + assert_choice_type(types::ra_nfunctions_added, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_addition_list_l& e2setup_request_ies_o::value_c::e2node_component_cfg_addition() const +{ + assert_choice_type(types::e2node_component_cfg_addition, type_, "Value"); + return c.get(); +} +void e2setup_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::global_e2node_id: + j.write_fieldname("GlobalE2node-ID"); + c.get().to_json(j); + break; + case types::ra_nfunctions_added: + j.start_array("RANfunctions-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_addition: + j.start_array("E2nodeComponentConfigAddition-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2setup_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_e2node_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunctions_added: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::e2node_component_cfg_addition: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_e2node_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunctions_added: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::e2node_component_cfg_addition: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2setup_request_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2setup_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "INTEGER (0..255,...)", "GlobalE2node-ID", "RANfunctions-List", "E2nodeComponentConfigAddition-List"}; + return convert_enum_idx(options, 4, value, "e2setup_request_ies_o::value_c::types"); +} + +// E2setupResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t e2setup_resp_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 4, 9, 13, 52}; + return map_enum_number(options, 5, idx, "id"); +} +bool e2setup_resp_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 4, 9, 13, 52}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e e2setup_resp_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 4: + return crit_e::reject; + case 9: + return crit_e::reject; + case 13: + return crit_e::reject; + case 52: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +e2setup_resp_ies_o::value_c e2setup_resp_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 4: + ret.set(value_c::types::global_ric_id); + break; + case 9: + ret.set(value_c::types::ra_nfunctions_accepted); + break; + case 13: + ret.set(value_c::types::ra_nfunctions_rejected); + break; + case 52: + ret.set(value_c::types::e2node_component_cfg_addition_ack); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e e2setup_resp_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 4: + return presence_e::mandatory; + case 9: + return presence_e::optional; + case 13: + return presence_e::optional; + case 52: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void e2setup_resp_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::global_ric_id: + c.destroy(); + break; + case types::ra_nfunctions_accepted: + c.destroy(); + break; + case types::ra_nfunctions_rejected: + c.destroy(); + break; + case types::e2node_component_cfg_addition_ack: + c.destroy(); + break; + default: + break; + } +} +void e2setup_resp_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::global_ric_id: + c.init(); + break; + case types::ra_nfunctions_accepted: + c.init(); + break; + case types::ra_nfunctions_rejected: + c.init(); + break; + case types::e2node_component_cfg_addition_ack: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + } +} +e2setup_resp_ies_o::value_c::value_c(const e2setup_resp_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::global_ric_id: + c.init(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.init(other.c.get()); + break; + case types::ra_nfunctions_rejected: + c.init(other.c.get()); + break; + case types::e2node_component_cfg_addition_ack: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + } +} +e2setup_resp_ies_o::value_c& e2setup_resp_ies_o::value_c::operator=(const e2setup_resp_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::global_ric_id: + c.set(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.set(other.c.get()); + break; + case types::ra_nfunctions_rejected: + c.set(other.c.get()); + break; + case types::e2node_component_cfg_addition_ack: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + } + + return *this; +} +uint16_t& e2setup_resp_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +global_ric_id_s& e2setup_resp_ies_o::value_c::global_ric_id() +{ + assert_choice_type(types::global_ric_id, type_, "Value"); + return c.get(); +} +ra_nfunctions_id_list_l& e2setup_resp_ies_o::value_c::ra_nfunctions_accepted() +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +ra_nfunctions_idcause_list_l& e2setup_resp_ies_o::value_c::ra_nfunctions_rejected() +{ + assert_choice_type(types::ra_nfunctions_rejected, type_, "Value"); + return c.get(); +} +e2node_component_cfg_addition_ack_list_l& e2setup_resp_ies_o::value_c::e2node_component_cfg_addition_ack() +{ + assert_choice_type(types::e2node_component_cfg_addition_ack, type_, "Value"); + return c.get(); +} +const uint16_t& e2setup_resp_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const global_ric_id_s& e2setup_resp_ies_o::value_c::global_ric_id() const +{ + assert_choice_type(types::global_ric_id, type_, "Value"); + return c.get(); +} +const ra_nfunctions_id_list_l& e2setup_resp_ies_o::value_c::ra_nfunctions_accepted() const +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +const ra_nfunctions_idcause_list_l& e2setup_resp_ies_o::value_c::ra_nfunctions_rejected() const +{ + assert_choice_type(types::ra_nfunctions_rejected, type_, "Value"); + return c.get(); +} +const e2node_component_cfg_addition_ack_list_l& e2setup_resp_ies_o::value_c::e2node_component_cfg_addition_ack() const +{ + assert_choice_type(types::e2node_component_cfg_addition_ack, type_, "Value"); + return c.get(); +} +void e2setup_resp_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::global_ric_id: + j.write_fieldname("GlobalRIC-ID"); + c.get().to_json(j); + break; + case types::ra_nfunctions_accepted: + j.start_array("RANfunctionsID-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::ra_nfunctions_rejected: + j.start_array("RANfunctionsIDcause-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::e2node_component_cfg_addition_ack: + j.start_array("E2nodeComponentConfigAdditionAck-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE e2setup_resp_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_ric_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::ra_nfunctions_rejected: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::e2node_component_cfg_addition_ack: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_resp_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::global_ric_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::ra_nfunctions_rejected: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::e2node_component_cfg_addition_ack: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 1024, true)); + break; + default: + log_invalid_choice_id(type_, "e2setup_resp_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2setup_resp_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", + "GlobalRIC-ID", + "RANfunctionsID-List", + "RANfunctionsIDcause-List", + "E2nodeComponentConfigAdditionAck-List"}; + return convert_enum_idx(options, 5, value, "e2setup_resp_ies_o::value_c::types"); +} +uint8_t e2setup_resp_ies_o::value_c::types_opts::to_number() const +{ + switch (value) { + case transaction_id: + return 0; + case e2node_component_cfg_addition_ack: + return 2; + default: + invalid_enum_number(value, "e2setup_resp_ies_o::value_c::types"); + } + return 0; +} + +// ErrorIndication-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t error_ind_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 29, 5, 1, 2}; + return map_enum_number(options, 5, idx, "id"); +} +bool error_ind_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 29, 5, 1, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e error_ind_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +error_ind_ies_o::value_c error_ind_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e error_ind_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::optional; + case 29: + return presence_e::optional; + case 5: + return presence_e::optional; + case 1: + return presence_e::optional; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void error_ind_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void error_ind_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::cause: + c.init(); + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + } +} +error_ind_ies_o::value_c::value_c(const error_ind_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + } +} +error_ind_ies_o::value_c& error_ind_ies_o::value_c::operator=(const error_ind_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + } + + return *this; +} +uint16_t& error_ind_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +ri_crequest_id_s& error_ind_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& error_ind_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +cause_c& error_ind_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& error_ind_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& error_ind_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& error_ind_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& error_ind_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const cause_c& error_ind_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& error_ind_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void error_ind_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE error_ind_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE error_ind_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "error_ind_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* error_ind_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "INTEGER (0..255,...)", "RICrequestID", "INTEGER (0..4095)", "Cause", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 5, value, "error_ind_ies_o::value_c::types"); +} + +// RICcontrolAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_cctrl_ack_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 20, 32}; + return map_enum_number(options, 4, idx, "id"); +} +bool ri_cctrl_ack_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 20, 32}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ri_cctrl_ack_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 20: + return crit_e::reject; + case 32: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ri_cctrl_ack_ies_o::value_c ri_cctrl_ack_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 20: + ret.set(value_c::types::ri_ccall_process_id); + break; + case 32: + ret.set(value_c::types::ri_cctrl_outcome); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_cctrl_ack_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 20: + return presence_e::optional; + case 32: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ri_cctrl_ack_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ri_ccall_process_id: + c.destroy >(); + break; + case types::ri_cctrl_outcome: + c.destroy >(); + break; + default: + break; + } +} +void ri_cctrl_ack_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ri_ccall_process_id: + c.init >(); + break; + case types::ri_cctrl_outcome: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + } +} +ri_cctrl_ack_ies_o::value_c::value_c(const ri_cctrl_ack_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ri_ccall_process_id: + c.init(other.c.get >()); + break; + case types::ri_cctrl_outcome: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + } +} +ri_cctrl_ack_ies_o::value_c& ri_cctrl_ack_ies_o::value_c::operator=(const ri_cctrl_ack_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ri_ccall_process_id: + c.set(other.c.get >()); + break; + case types::ri_cctrl_outcome: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ri_cctrl_ack_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ri_cctrl_ack_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +unbounded_octstring& ri_cctrl_ack_ies_o::value_c::ri_ccall_process_id() +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +unbounded_octstring& ri_cctrl_ack_ies_o::value_c::ri_cctrl_outcome() +{ + assert_choice_type(types::ri_cctrl_outcome, type_, "Value"); + return c.get >(); +} +const ri_crequest_id_s& ri_cctrl_ack_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ri_cctrl_ack_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const unbounded_octstring& ri_cctrl_ack_ies_o::value_c::ri_ccall_process_id() const +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +const unbounded_octstring& ri_cctrl_ack_ies_o::value_c::ri_cctrl_outcome() const +{ + assert_choice_type(types::ri_cctrl_outcome, type_, "Value"); + return c.get >(); +} +void ri_cctrl_ack_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ri_ccall_process_id: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_cctrl_outcome: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ri_cctrl_ack_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_cctrl_outcome: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_ack_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_cctrl_outcome: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_ack_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ri_cctrl_ack_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)", "OCTET STRING", "OCTET STRING"}; + return convert_enum_idx(options, 4, value, "ri_cctrl_ack_ies_o::value_c::types"); +} +uint8_t ri_cctrl_ack_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ri_cctrl_ack_ies_o::value_c::types"); + return 0; +} + +// RICcontrolFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_cctrl_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 20, 1, 32}; + return map_enum_number(options, 5, idx, "id"); +} +bool ri_cctrl_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 20, 1, 32}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ri_cctrl_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 20: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 32: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ri_cctrl_fail_ies_o::value_c ri_cctrl_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 20: + ret.set(value_c::types::ri_ccall_process_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 32: + ret.set(value_c::types::ri_cctrl_outcome); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_cctrl_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 20: + return presence_e::optional; + case 1: + return presence_e::mandatory; + case 32: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ri_cctrl_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ri_ccall_process_id: + c.destroy >(); + break; + case types::cause: + c.destroy(); + break; + case types::ri_cctrl_outcome: + c.destroy >(); + break; + default: + break; + } +} +void ri_cctrl_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ri_ccall_process_id: + c.init >(); + break; + case types::cause: + c.init(); + break; + case types::ri_cctrl_outcome: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + } +} +ri_cctrl_fail_ies_o::value_c::value_c(const ri_cctrl_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ri_ccall_process_id: + c.init(other.c.get >()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::ri_cctrl_outcome: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + } +} +ri_cctrl_fail_ies_o::value_c& ri_cctrl_fail_ies_o::value_c::operator=(const ri_cctrl_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ri_ccall_process_id: + c.set(other.c.get >()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::ri_cctrl_outcome: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ri_cctrl_fail_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ri_cctrl_fail_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +unbounded_octstring& ri_cctrl_fail_ies_o::value_c::ri_ccall_process_id() +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +cause_c& ri_cctrl_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +unbounded_octstring& ri_cctrl_fail_ies_o::value_c::ri_cctrl_outcome() +{ + assert_choice_type(types::ri_cctrl_outcome, type_, "Value"); + return c.get >(); +} +const ri_crequest_id_s& ri_cctrl_fail_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ri_cctrl_fail_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const unbounded_octstring& ri_cctrl_fail_ies_o::value_c::ri_ccall_process_id() const +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +const cause_c& ri_cctrl_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const unbounded_octstring& ri_cctrl_fail_ies_o::value_c::ri_cctrl_outcome() const +{ + assert_choice_type(types::ri_cctrl_outcome, type_, "Value"); + return c.get >(); +} +void ri_cctrl_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ri_ccall_process_id: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::ri_cctrl_outcome: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ri_cctrl_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cctrl_outcome: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cctrl_outcome: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ri_cctrl_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)", "OCTET STRING", "Cause", "OCTET STRING"}; + return convert_enum_idx(options, 5, value, "ri_cctrl_fail_ies_o::value_c::types"); +} +uint8_t ri_cctrl_fail_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ri_cctrl_fail_ies_o::value_c::types"); + return 0; +} + +// RICcontrolRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_cctrl_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 20, 22, 23, 21}; + return map_enum_number(options, 6, idx, "id"); +} +bool ri_cctrl_request_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 20, 22, 23, 21}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ri_cctrl_request_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 20: + return crit_e::reject; + case 22: + return crit_e::reject; + case 23: + return crit_e::reject; + case 21: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ri_cctrl_request_ies_o::value_c ri_cctrl_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 20: + ret.set(value_c::types::ri_ccall_process_id); + break; + case 22: + ret.set(value_c::types::ri_cctrl_hdr); + break; + case 23: + ret.set(value_c::types::ri_cctrl_msg); + break; + case 21: + ret.set(value_c::types::ri_cctrl_ack_request); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_cctrl_request_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 20: + return presence_e::optional; + case 22: + return presence_e::mandatory; + case 23: + return presence_e::mandatory; + case 21: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ri_cctrl_request_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ri_ccall_process_id: + c.destroy >(); + break; + case types::ri_cctrl_hdr: + c.destroy >(); + break; + case types::ri_cctrl_msg: + c.destroy >(); + break; + default: + break; + } +} +void ri_cctrl_request_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ri_ccall_process_id: + c.init >(); + break; + case types::ri_cctrl_hdr: + c.init >(); + break; + case types::ri_cctrl_msg: + c.init >(); + break; + case types::ri_cctrl_ack_request: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + } +} +ri_cctrl_request_ies_o::value_c::value_c(const ri_cctrl_request_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ri_ccall_process_id: + c.init(other.c.get >()); + break; + case types::ri_cctrl_hdr: + c.init(other.c.get >()); + break; + case types::ri_cctrl_msg: + c.init(other.c.get >()); + break; + case types::ri_cctrl_ack_request: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + } +} +ri_cctrl_request_ies_o::value_c& +ri_cctrl_request_ies_o::value_c::operator=(const ri_cctrl_request_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ri_ccall_process_id: + c.set(other.c.get >()); + break; + case types::ri_cctrl_hdr: + c.set(other.c.get >()); + break; + case types::ri_cctrl_msg: + c.set(other.c.get >()); + break; + case types::ri_cctrl_ack_request: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ri_cctrl_request_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ri_cctrl_request_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_ccall_process_id() +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_cctrl_hdr() +{ + assert_choice_type(types::ri_cctrl_hdr, type_, "Value"); + return c.get >(); +} +unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_cctrl_msg() +{ + assert_choice_type(types::ri_cctrl_msg, type_, "Value"); + return c.get >(); +} +ri_cctrl_ack_request_e& ri_cctrl_request_ies_o::value_c::ri_cctrl_ack_request() +{ + assert_choice_type(types::ri_cctrl_ack_request, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ri_cctrl_request_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ri_cctrl_request_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_ccall_process_id() const +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +const unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_cctrl_hdr() const +{ + assert_choice_type(types::ri_cctrl_hdr, type_, "Value"); + return c.get >(); +} +const unbounded_octstring& ri_cctrl_request_ies_o::value_c::ri_cctrl_msg() const +{ + assert_choice_type(types::ri_cctrl_msg, type_, "Value"); + return c.get >(); +} +const ri_cctrl_ack_request_e& ri_cctrl_request_ies_o::value_c::ri_cctrl_ack_request() const +{ + assert_choice_type(types::ri_cctrl_ack_request, type_, "Value"); + return c.get(); +} +void ri_cctrl_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ri_ccall_process_id: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_cctrl_hdr: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_cctrl_msg: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_cctrl_ack_request: + j.write_str("RICcontrolAckRequest", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ri_cctrl_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_cctrl_hdr: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_cctrl_msg: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_cctrl_ack_request: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_cctrl_hdr: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_cctrl_msg: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_cctrl_ack_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cctrl_request_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ri_cctrl_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "RICrequestID", "INTEGER (0..4095)", "OCTET STRING", "OCTET STRING", "OCTET STRING", "RICcontrolAckRequest"}; + return convert_enum_idx(options, 6, value, "ri_cctrl_request_ies_o::value_c::types"); +} +uint8_t ri_cctrl_request_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ri_cctrl_request_ies_o::value_c::types"); + return 0; +} + +// RICindication-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ri_cind_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 15, 27, 28, 25, 26, 20}; + return map_enum_number(options, 8, idx, "id"); +} +bool ri_cind_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 15, 27, 28, 25, 26, 20}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ri_cind_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 15: + return crit_e::reject; + case 27: + return crit_e::reject; + case 28: + return crit_e::reject; + case 25: + return crit_e::reject; + case 26: + return crit_e::reject; + case 20: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ri_cind_ies_o::value_c ri_cind_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 15: + ret.set(value_c::types::ri_caction_id); + break; + case 27: + ret.set(value_c::types::ri_cind_sn); + break; + case 28: + ret.set(value_c::types::ri_cind_type); + break; + case 25: + ret.set(value_c::types::ri_cind_hdr); + break; + case 26: + ret.set(value_c::types::ri_cind_msg); + break; + case 20: + ret.set(value_c::types::ri_ccall_process_id); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ri_cind_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 15: + return presence_e::mandatory; + case 27: + return presence_e::optional; + case 28: + return presence_e::mandatory; + case 25: + return presence_e::mandatory; + case 26: + return presence_e::mandatory; + case 20: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ri_cind_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ri_cind_hdr: + c.destroy >(); + break; + case types::ri_cind_msg: + c.destroy >(); + break; + case types::ri_ccall_process_id: + c.destroy >(); + break; + default: + break; + } +} +void ri_cind_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ri_caction_id: + break; + case types::ri_cind_sn: + break; + case types::ri_cind_type: + break; + case types::ri_cind_hdr: + c.init >(); + break; + case types::ri_cind_msg: + c.init >(); + break; + case types::ri_ccall_process_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + } +} +ri_cind_ies_o::value_c::value_c(const ri_cind_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ri_caction_id: + c.init(other.c.get()); + break; + case types::ri_cind_sn: + c.init(other.c.get()); + break; + case types::ri_cind_type: + c.init(other.c.get()); + break; + case types::ri_cind_hdr: + c.init(other.c.get >()); + break; + case types::ri_cind_msg: + c.init(other.c.get >()); + break; + case types::ri_ccall_process_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + } +} +ri_cind_ies_o::value_c& ri_cind_ies_o::value_c::operator=(const ri_cind_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ri_caction_id: + c.set(other.c.get()); + break; + case types::ri_cind_sn: + c.set(other.c.get()); + break; + case types::ri_cind_type: + c.set(other.c.get()); + break; + case types::ri_cind_hdr: + c.set(other.c.get >()); + break; + case types::ri_cind_msg: + c.set(other.c.get >()); + break; + case types::ri_ccall_process_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ri_cind_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ri_cind_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +uint16_t& ri_cind_ies_o::value_c::ri_caction_id() +{ + assert_choice_type(types::ri_caction_id, type_, "Value"); + return c.get(); +} +uint32_t& ri_cind_ies_o::value_c::ri_cind_sn() +{ + assert_choice_type(types::ri_cind_sn, type_, "Value"); + return c.get(); +} +ri_cind_type_e& ri_cind_ies_o::value_c::ri_cind_type() +{ + assert_choice_type(types::ri_cind_type, type_, "Value"); + return c.get(); +} +unbounded_octstring& ri_cind_ies_o::value_c::ri_cind_hdr() +{ + assert_choice_type(types::ri_cind_hdr, type_, "Value"); + return c.get >(); +} +unbounded_octstring& ri_cind_ies_o::value_c::ri_cind_msg() +{ + assert_choice_type(types::ri_cind_msg, type_, "Value"); + return c.get >(); +} +unbounded_octstring& ri_cind_ies_o::value_c::ri_ccall_process_id() +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +const ri_crequest_id_s& ri_cind_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ri_cind_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const uint16_t& ri_cind_ies_o::value_c::ri_caction_id() const +{ + assert_choice_type(types::ri_caction_id, type_, "Value"); + return c.get(); +} +const uint32_t& ri_cind_ies_o::value_c::ri_cind_sn() const +{ + assert_choice_type(types::ri_cind_sn, type_, "Value"); + return c.get(); +} +const ri_cind_type_e& ri_cind_ies_o::value_c::ri_cind_type() const +{ + assert_choice_type(types::ri_cind_type, type_, "Value"); + return c.get(); +} +const unbounded_octstring& ri_cind_ies_o::value_c::ri_cind_hdr() const +{ + assert_choice_type(types::ri_cind_hdr, type_, "Value"); + return c.get >(); +} +const unbounded_octstring& ri_cind_ies_o::value_c::ri_cind_msg() const +{ + assert_choice_type(types::ri_cind_msg, type_, "Value"); + return c.get >(); +} +const unbounded_octstring& ri_cind_ies_o::value_c::ri_ccall_process_id() const +{ + assert_choice_type(types::ri_ccall_process_id, type_, "Value"); + return c.get >(); +} +void ri_cind_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ri_caction_id: + j.write_int("INTEGER (0..255)", c.get()); + break; + case types::ri_cind_sn: + j.write_int("INTEGER (0..65535)", c.get()); + break; + case types::ri_cind_type: + j.write_str("RICindicationType", c.get().to_string()); + break; + case types::ri_cind_hdr: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_cind_msg: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + case types::ri_ccall_process_id: + j.write_str("OCTET STRING", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ri_cind_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_caction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + case types::ri_cind_sn: + HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + case types::ri_cind_type: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cind_hdr: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_cind_msg: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cind_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_caction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + case types::ri_cind_sn: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + case types::ri_cind_type: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cind_hdr: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_cind_msg: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::ri_ccall_process_id: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ri_cind_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ri_cind_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", + "INTEGER (0..4095)", + "INTEGER (0..255)", + "INTEGER (0..65535)", + "RICindicationType", + "OCTET STRING", + "OCTET STRING", + "OCTET STRING"}; + return convert_enum_idx(options, 8, value, "ri_cind_ies_o::value_c::types"); +} + +// RICserviceQuery-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricservice_query_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 9}; + return map_enum_number(options, 2, idx, "id"); +} +bool ricservice_query_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 9}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricservice_query_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 9: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricservice_query_ies_o::value_c ricservice_query_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 9: + ret.set(value_c::types::ra_nfunctions_accepted); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricservice_query_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 9: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricservice_query_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ra_nfunctions_accepted: + c.destroy(); + break; + default: + break; + } +} +void ricservice_query_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::ra_nfunctions_accepted: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + } +} +ricservice_query_ies_o::value_c::value_c(const ricservice_query_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + } +} +ricservice_query_ies_o::value_c& +ricservice_query_ies_o::value_c::operator=(const ricservice_query_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + } + + return *this; +} +uint16_t& ricservice_query_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +ra_nfunctions_id_list_l& ricservice_query_ies_o::value_c::ra_nfunctions_accepted() +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +const uint16_t& ricservice_query_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const ra_nfunctions_id_list_l& ricservice_query_ies_o::value_c::ra_nfunctions_accepted() const +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +void ricservice_query_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::ra_nfunctions_accepted: + j.start_array("RANfunctionsID-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricservice_query_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_query_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_query_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricservice_query_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "RANfunctionsID-List"}; + return convert_enum_idx(options, 2, value, "ricservice_query_ies_o::value_c::types"); +} +uint8_t ricservice_query_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "ricservice_query_ies_o::value_c::types"); +} + +// RICserviceUpdate-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricservice_upd_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 10, 12, 11}; + return map_enum_number(options, 4, idx, "id"); +} +bool ricservice_upd_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 10, 12, 11}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricservice_upd_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 10: + return crit_e::reject; + case 12: + return crit_e::reject; + case 11: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricservice_upd_ies_o::value_c ricservice_upd_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 10: + ret.set(value_c::types::ra_nfunctions_added); + break; + case 12: + ret.set(value_c::types::ra_nfunctions_modified); + break; + case 11: + ret.set(value_c::types::ra_nfunctions_deleted); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricservice_upd_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 10: + return presence_e::optional; + case 12: + return presence_e::optional; + case 11: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricservice_upd_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ra_nfunctions_added: + c.destroy(); + break; + case types::ra_nfunctions_modified: + c.destroy(); + break; + case types::ra_nfunctions_deleted: + c.destroy(); + break; + default: + break; + } +} +void ricservice_upd_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::ra_nfunctions_added: + c.init(); + break; + case types::ra_nfunctions_modified: + c.init(); + break; + case types::ra_nfunctions_deleted: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + } +} +ricservice_upd_ies_o::value_c::value_c(const ricservice_upd_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::ra_nfunctions_added: + c.init(other.c.get()); + break; + case types::ra_nfunctions_modified: + c.init(other.c.get()); + break; + case types::ra_nfunctions_deleted: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + } +} +ricservice_upd_ies_o::value_c& ricservice_upd_ies_o::value_c::operator=(const ricservice_upd_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::ra_nfunctions_added: + c.set(other.c.get()); + break; + case types::ra_nfunctions_modified: + c.set(other.c.get()); + break; + case types::ra_nfunctions_deleted: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + } + + return *this; +} +uint16_t& ricservice_upd_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +ra_nfunctions_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_added() +{ + assert_choice_type(types::ra_nfunctions_added, type_, "Value"); + return c.get(); +} +ra_nfunctions_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_modified() +{ + assert_choice_type(types::ra_nfunctions_modified, type_, "Value"); + return c.get(); +} +ra_nfunctions_id_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_deleted() +{ + assert_choice_type(types::ra_nfunctions_deleted, type_, "Value"); + return c.get(); +} +const uint16_t& ricservice_upd_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const ra_nfunctions_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_added() const +{ + assert_choice_type(types::ra_nfunctions_added, type_, "Value"); + return c.get(); +} +const ra_nfunctions_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_modified() const +{ + assert_choice_type(types::ra_nfunctions_modified, type_, "Value"); + return c.get(); +} +const ra_nfunctions_id_list_l& ricservice_upd_ies_o::value_c::ra_nfunctions_deleted() const +{ + assert_choice_type(types::ra_nfunctions_deleted, type_, "Value"); + return c.get(); +} +void ricservice_upd_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::ra_nfunctions_added: + j.start_array("RANfunctions-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::ra_nfunctions_modified: + j.start_array("RANfunctions-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::ra_nfunctions_deleted: + j.start_array("RANfunctionsID-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricservice_upd_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_added: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::ra_nfunctions_modified: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::ra_nfunctions_deleted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_added: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::ra_nfunctions_modified: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::ra_nfunctions_deleted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricservice_upd_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "INTEGER (0..255,...)", "RANfunctions-List", "RANfunctions-List", "RANfunctionsID-List"}; + return convert_enum_idx(options, 4, value, "ricservice_upd_ies_o::value_c::types"); +} +uint8_t ricservice_upd_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "ricservice_upd_ies_o::value_c::types"); +} + +// RICserviceUpdateAcknowledge-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricservice_upd_ack_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 9, 13}; + return map_enum_number(options, 3, idx, "id"); +} +bool ricservice_upd_ack_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 9, 13}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricservice_upd_ack_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 9: + return crit_e::reject; + case 13: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricservice_upd_ack_ies_o::value_c ricservice_upd_ack_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 9: + ret.set(value_c::types::ra_nfunctions_accepted); + break; + case 13: + ret.set(value_c::types::ra_nfunctions_rejected); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricservice_upd_ack_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 9: + return presence_e::optional; + case 13: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricservice_upd_ack_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ra_nfunctions_accepted: + c.destroy(); + break; + case types::ra_nfunctions_rejected: + c.destroy(); + break; + default: + break; + } +} +void ricservice_upd_ack_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::ra_nfunctions_accepted: + c.init(); + break; + case types::ra_nfunctions_rejected: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + } +} +ricservice_upd_ack_ies_o::value_c::value_c(const ricservice_upd_ack_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.init(other.c.get()); + break; + case types::ra_nfunctions_rejected: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + } +} +ricservice_upd_ack_ies_o::value_c& +ricservice_upd_ack_ies_o::value_c::operator=(const ricservice_upd_ack_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::ra_nfunctions_accepted: + c.set(other.c.get()); + break; + case types::ra_nfunctions_rejected: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + } + + return *this; +} +uint16_t& ricservice_upd_ack_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +ra_nfunctions_id_list_l& ricservice_upd_ack_ies_o::value_c::ra_nfunctions_accepted() +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +ra_nfunctions_idcause_list_l& ricservice_upd_ack_ies_o::value_c::ra_nfunctions_rejected() +{ + assert_choice_type(types::ra_nfunctions_rejected, type_, "Value"); + return c.get(); +} +const uint16_t& ricservice_upd_ack_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const ra_nfunctions_id_list_l& ricservice_upd_ack_ies_o::value_c::ra_nfunctions_accepted() const +{ + assert_choice_type(types::ra_nfunctions_accepted, type_, "Value"); + return c.get(); +} +const ra_nfunctions_idcause_list_l& ricservice_upd_ack_ies_o::value_c::ra_nfunctions_rejected() const +{ + assert_choice_type(types::ra_nfunctions_rejected, type_, "Value"); + return c.get(); +} +void ricservice_upd_ack_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::ra_nfunctions_accepted: + j.start_array("RANfunctionsID-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::ra_nfunctions_rejected: + j.start_array("RANfunctionsIDcause-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricservice_upd_ack_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + case types::ra_nfunctions_rejected: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_ack_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::ra_nfunctions_accepted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + case types::ra_nfunctions_rejected: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 256, true)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_ack_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricservice_upd_ack_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "RANfunctionsID-List", "RANfunctionsIDcause-List"}; + return convert_enum_idx(options, 3, value, "ricservice_upd_ack_ies_o::value_c::types"); +} +uint8_t ricservice_upd_ack_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "ricservice_upd_ack_ies_o::value_c::types"); +} + +// RICserviceUpdateFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricservice_upd_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + return map_enum_number(options, 4, idx, "id"); +} +bool ricservice_upd_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1, 31, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricservice_upd_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::reject; + case 31: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricservice_upd_fail_ies_o::value_c ricservice_upd_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 31: + ret.set(value_c::types::time_to_wait); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricservice_upd_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 31: + return presence_e::optional; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricservice_upd_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void ricservice_upd_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::time_to_wait: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + } +} +ricservice_upd_fail_ies_o::value_c::value_c(const ricservice_upd_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::time_to_wait: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + } +} +ricservice_upd_fail_ies_o::value_c& +ricservice_upd_fail_ies_o::value_c::operator=(const ricservice_upd_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::time_to_wait: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + } + + return *this; +} +uint16_t& ricservice_upd_fail_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& ricservice_upd_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +time_to_wait_e& ricservice_upd_fail_ies_o::value_c::time_to_wait() +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& ricservice_upd_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& ricservice_upd_fail_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& ricservice_upd_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const time_to_wait_e& ricservice_upd_fail_ies_o::value_c::time_to_wait() const +{ + assert_choice_type(types::time_to_wait, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& ricservice_upd_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void ricservice_upd_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::time_to_wait: + j.write_str("TimeToWait", c.get().to_string()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricservice_upd_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::time_to_wait: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricservice_upd_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricservice_upd_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "Cause", "TimeToWait", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 4, value, "ricservice_upd_fail_ies_o::value_c::types"); +} +uint8_t ricservice_upd_fail_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "ricservice_upd_fail_ies_o::value_c::types"); +} + +// RICsubscriptionDeleteFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_delete_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 1, 2}; + return map_enum_number(options, 4, idx, "id"); +} +bool ricsubscription_delete_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 1, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_delete_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 1: + return crit_e::ignore; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_delete_fail_ies_o::value_c ricsubscription_delete_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_delete_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_delete_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_delete_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::cause: + c.init(); + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + } +} +ricsubscription_delete_fail_ies_o::value_c::value_c(const ricsubscription_delete_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + } +} +ricsubscription_delete_fail_ies_o::value_c& +ricsubscription_delete_fail_ies_o::value_c::operator=(const ricsubscription_delete_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_delete_fail_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_delete_fail_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +cause_c& ricsubscription_delete_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& ricsubscription_delete_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_delete_fail_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_delete_fail_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const cause_c& ricsubscription_delete_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& ricsubscription_delete_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void ricsubscription_delete_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_delete_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_delete_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)", "Cause", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 4, value, "ricsubscription_delete_fail_ies_o::value_c::types"); +} +uint8_t ricsubscription_delete_fail_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_delete_fail_ies_o::value_c::types"); + return 0; +} + +// RICsubscriptionDeleteRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_delete_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5}; + return map_enum_number(options, 2, idx, "id"); +} +bool ricsubscription_delete_request_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_delete_request_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_delete_request_ies_o::value_c ricsubscription_delete_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_delete_request_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_delete_request_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_delete_request_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + } +} +ricsubscription_delete_request_ies_o::value_c::value_c(const ricsubscription_delete_request_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + } +} +ricsubscription_delete_request_ies_o::value_c& +ricsubscription_delete_request_ies_o::value_c::operator=(const ricsubscription_delete_request_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_delete_request_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_delete_request_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_delete_request_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_delete_request_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +void ricsubscription_delete_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_delete_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_request_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_delete_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)"}; + return convert_enum_idx(options, 2, value, "ricsubscription_delete_request_ies_o::value_c::types"); +} +uint8_t ricsubscription_delete_request_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_delete_request_ies_o::value_c::types"); + return 0; +} + +// RICsubscriptionDeleteRequired-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_delete_required_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {60}; + return map_enum_number(options, 1, idx, "id"); +} +bool ricsubscription_delete_required_ies_o::is_id_valid(const uint32_t& id) +{ + return 60 == id; +} +crit_e ricsubscription_delete_required_ies_o::get_crit(const uint32_t& id) +{ + if (id == 60) { + return crit_e::ignore; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} +ricsubscription_delete_required_ies_o::value_c ricsubscription_delete_required_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + if (id != 60) { + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_delete_required_ies_o::get_presence(const uint32_t& id) +{ + if (id == 60) { + return presence_e::mandatory; + } + asn1::log_error("The id=%d is not recognized", id); + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_delete_required_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("RICsubscription-List-withCause"); + for (const auto& e1 : c) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} +SRSASN_CODE ricsubscription_delete_required_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(pack_dyn_seq_of(bref, c, 1, 1024, true)); + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_required_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(unpack_dyn_seq_of(c, bref, 1, 1024, true)); + return SRSASN_SUCCESS; +} + +const char* ricsubscription_delete_required_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICsubscription-List-withCause"}; + return convert_enum_idx(options, 1, value, "ricsubscription_delete_required_ies_o::value_c::types"); +} + +// RICsubscriptionDeleteResponse-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_delete_resp_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5}; + return map_enum_number(options, 2, idx, "id"); +} +bool ricsubscription_delete_resp_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_delete_resp_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_delete_resp_ies_o::value_c ricsubscription_delete_resp_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_delete_resp_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_delete_resp_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_delete_resp_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + } +} +ricsubscription_delete_resp_ies_o::value_c::value_c(const ricsubscription_delete_resp_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + } +} +ricsubscription_delete_resp_ies_o::value_c& +ricsubscription_delete_resp_ies_o::value_c::operator=(const ricsubscription_delete_resp_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_delete_resp_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_delete_resp_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_delete_resp_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_delete_resp_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +void ricsubscription_delete_resp_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_delete_resp_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_resp_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_delete_resp_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_delete_resp_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)"}; + return convert_enum_idx(options, 2, value, "ricsubscription_delete_resp_ies_o::value_c::types"); +} +uint8_t ricsubscription_delete_resp_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_delete_resp_ies_o::value_c::types"); + return 0; +} + +// RICsubscriptionFailure-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_fail_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 1, 2}; + return map_enum_number(options, 4, idx, "id"); +} +bool ricsubscription_fail_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 1, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_fail_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 1: + return crit_e::reject; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_fail_ies_o::value_c ricsubscription_fail_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_fail_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_fail_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::cause: + c.destroy(); + break; + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_fail_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::cause: + c.init(); + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + } +} +ricsubscription_fail_ies_o::value_c::value_c(const ricsubscription_fail_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + } +} +ricsubscription_fail_ies_o::value_c& +ricsubscription_fail_ies_o::value_c::operator=(const ricsubscription_fail_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_fail_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_fail_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +cause_c& ricsubscription_fail_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& ricsubscription_fail_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_fail_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_fail_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const cause_c& ricsubscription_fail_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& ricsubscription_fail_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void ricsubscription_fail_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_fail_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_fail_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_fail_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_fail_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)", "Cause", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 4, value, "ricsubscription_fail_ies_o::value_c::types"); +} +uint8_t ricsubscription_fail_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_fail_ies_o::value_c::types"); + return 0; +} + +// RICsubscriptionRequest-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 30}; + return map_enum_number(options, 3, idx, "id"); +} +bool ricsubscription_request_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 30}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_request_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 30: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_request_ies_o::value_c ricsubscription_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 30: + ret.set(value_c::types::ricsubscription_details); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_request_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 30: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_request_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ricsubscription_details: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_request_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ricsubscription_details: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + } +} +ricsubscription_request_ies_o::value_c::value_c(const ricsubscription_request_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ricsubscription_details: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + } +} +ricsubscription_request_ies_o::value_c& +ricsubscription_request_ies_o::value_c::operator=(const ricsubscription_request_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ricsubscription_details: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_request_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_request_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +ricsubscription_details_s& ricsubscription_request_ies_o::value_c::ricsubscription_details() +{ + assert_choice_type(types::ricsubscription_details, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_request_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_request_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const ricsubscription_details_s& ricsubscription_request_ies_o::value_c::ricsubscription_details() const +{ + assert_choice_type(types::ricsubscription_details, type_, "Value"); + return c.get(); +} +void ricsubscription_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ricsubscription_details: + j.write_fieldname("RICsubscriptionDetails"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ricsubscription_details: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ricsubscription_details: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_request_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"RICrequestID", "INTEGER (0..4095)", "RICsubscriptionDetails"}; + return convert_enum_idx(options, 3, value, "ricsubscription_request_ies_o::value_c::types"); +} +uint8_t ricsubscription_request_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_request_ies_o::value_c::types"); + return 0; +} + +// RICsubscriptionResponse-IEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t ricsubscription_resp_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {29, 5, 17, 18}; + return map_enum_number(options, 4, idx, "id"); +} +bool ricsubscription_resp_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {29, 5, 17, 18}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e ricsubscription_resp_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 29: + return crit_e::reject; + case 5: + return crit_e::reject; + case 17: + return crit_e::reject; + case 18: + return crit_e::reject; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +ricsubscription_resp_ies_o::value_c ricsubscription_resp_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 29: + ret.set(value_c::types::ri_crequest_id); + break; + case 5: + ret.set(value_c::types::ra_nfunction_id); + break; + case 17: + ret.set(value_c::types::ri_cactions_admitted); + break; + case 18: + ret.set(value_c::types::ri_cactions_not_admitted); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e ricsubscription_resp_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 29: + return presence_e::mandatory; + case 5: + return presence_e::mandatory; + case 17: + return presence_e::mandatory; + case 18: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void ricsubscription_resp_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::ri_crequest_id: + c.destroy(); + break; + case types::ri_cactions_admitted: + c.destroy(); + break; + case types::ri_cactions_not_admitted: + c.destroy(); + break; + default: + break; + } +} +void ricsubscription_resp_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ri_crequest_id: + c.init(); + break; + case types::ra_nfunction_id: + break; + case types::ri_cactions_admitted: + c.init(); + break; + case types::ri_cactions_not_admitted: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + } +} +ricsubscription_resp_ies_o::value_c::value_c(const ricsubscription_resp_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ri_crequest_id: + c.init(other.c.get()); + break; + case types::ra_nfunction_id: + c.init(other.c.get()); + break; + case types::ri_cactions_admitted: + c.init(other.c.get()); + break; + case types::ri_cactions_not_admitted: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + } +} +ricsubscription_resp_ies_o::value_c& +ricsubscription_resp_ies_o::value_c::operator=(const ricsubscription_resp_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ri_crequest_id: + c.set(other.c.get()); + break; + case types::ra_nfunction_id: + c.set(other.c.get()); + break; + case types::ri_cactions_admitted: + c.set(other.c.get()); + break; + case types::ri_cactions_not_admitted: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + } + + return *this; +} +ri_crequest_id_s& ricsubscription_resp_ies_o::value_c::ri_crequest_id() +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +uint16_t& ricsubscription_resp_ies_o::value_c::ra_nfunction_id() +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +ri_caction_admitted_list_l& ricsubscription_resp_ies_o::value_c::ri_cactions_admitted() +{ + assert_choice_type(types::ri_cactions_admitted, type_, "Value"); + return c.get(); +} +ri_caction_not_admitted_list_l& ricsubscription_resp_ies_o::value_c::ri_cactions_not_admitted() +{ + assert_choice_type(types::ri_cactions_not_admitted, type_, "Value"); + return c.get(); +} +const ri_crequest_id_s& ricsubscription_resp_ies_o::value_c::ri_crequest_id() const +{ + assert_choice_type(types::ri_crequest_id, type_, "Value"); + return c.get(); +} +const uint16_t& ricsubscription_resp_ies_o::value_c::ra_nfunction_id() const +{ + assert_choice_type(types::ra_nfunction_id, type_, "Value"); + return c.get(); +} +const ri_caction_admitted_list_l& ricsubscription_resp_ies_o::value_c::ri_cactions_admitted() const +{ + assert_choice_type(types::ri_cactions_admitted, type_, "Value"); + return c.get(); +} +const ri_caction_not_admitted_list_l& ricsubscription_resp_ies_o::value_c::ri_cactions_not_admitted() const +{ + assert_choice_type(types::ri_cactions_not_admitted, type_, "Value"); + return c.get(); +} +void ricsubscription_resp_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ri_crequest_id: + j.write_fieldname("RICrequestID"); + c.get().to_json(j); + break; + case types::ra_nfunction_id: + j.write_int("INTEGER (0..4095)", c.get()); + break; + case types::ri_cactions_admitted: + j.start_array("RICaction-Admitted-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + case types::ri_cactions_not_admitted: + j.start_array("RICaction-NotAdmitted-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE ricsubscription_resp_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_cactions_admitted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 16, true)); + break; + case types::ri_cactions_not_admitted: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 0, 16, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_resp_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ri_crequest_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ra_nfunction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + break; + case types::ri_cactions_admitted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 16, true)); + break; + case types::ri_cactions_not_admitted: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 0, 16, true)); + break; + default: + log_invalid_choice_id(type_, "ricsubscription_resp_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ricsubscription_resp_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = { + "RICrequestID", "INTEGER (0..4095)", "RICaction-Admitted-List", "RICaction-NotAdmitted-List"}; + return convert_enum_idx(options, 4, value, "ricsubscription_resp_ies_o::value_c::types"); +} +uint8_t ricsubscription_resp_ies_o::value_c::types_opts::to_number() const +{ + if (value == ra_nfunction_id) { + return 0; + } + invalid_enum_number(value, "ricsubscription_resp_ies_o::value_c::types"); + return 0; +} + +// ResetRequestIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t reset_request_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 1}; + return map_enum_number(options, 2, idx, "id"); +} +bool reset_request_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 1}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e reset_request_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 1: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +reset_request_ies_o::value_c reset_request_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 1: + ret.set(value_c::types::cause); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e reset_request_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 1: + return presence_e::mandatory; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void reset_request_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::cause: + c.destroy(); + break; + default: + break; + } +} +void reset_request_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::cause: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + } +} +reset_request_ies_o::value_c::value_c(const reset_request_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::cause: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + } +} +reset_request_ies_o::value_c& reset_request_ies_o::value_c::operator=(const reset_request_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::cause: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + } + + return *this; +} +uint16_t& reset_request_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +cause_c& reset_request_ies_o::value_c::cause() +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +const uint16_t& reset_request_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const cause_c& reset_request_ies_o::value_c::cause() const +{ + assert_choice_type(types::cause, type_, "Value"); + return c.get(); +} +void reset_request_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::cause: + j.write_fieldname("Cause"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE reset_request_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE reset_request_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::cause: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "reset_request_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* reset_request_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "Cause"}; + return convert_enum_idx(options, 2, value, "reset_request_ies_o::value_c::types"); +} +uint8_t reset_request_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "reset_request_ies_o::value_c::types"); +} + +// ResetResponseIEs ::= OBJECT SET OF E2AP-PROTOCOL-IES +uint32_t reset_resp_ies_o::idx_to_id(uint32_t idx) +{ + static const uint32_t options[] = {49, 2}; + return map_enum_number(options, 2, idx, "id"); +} +bool reset_resp_ies_o::is_id_valid(const uint32_t& id) +{ + static const uint32_t options[] = {49, 2}; + for (const auto& o : options) { + if (o == id) { + return true; + } + } + return false; +} +crit_e reset_resp_ies_o::get_crit(const uint32_t& id) +{ + switch (id) { + case 49: + return crit_e::reject; + case 2: + return crit_e::ignore; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} +reset_resp_ies_o::value_c reset_resp_ies_o::get_value(const uint32_t& id) +{ + value_c ret{}; + switch (id) { + case 49: + ret.set(value_c::types::transaction_id); + break; + case 2: + ret.set(value_c::types::crit_diagnostics); + break; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return ret; +} +presence_e reset_resp_ies_o::get_presence(const uint32_t& id) +{ + switch (id) { + case 49: + return presence_e::mandatory; + case 2: + return presence_e::optional; + default: + asn1::log_error("The id=%d is not recognized", id); + } + return {}; +} + +// Value ::= OPEN TYPE +void reset_resp_ies_o::value_c::destroy_() +{ + switch (type_) { + case types::crit_diagnostics: + c.destroy(); + break; + default: + break; + } +} +void reset_resp_ies_o::value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::transaction_id: + break; + case types::crit_diagnostics: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + } +} +reset_resp_ies_o::value_c::value_c(const reset_resp_ies_o::value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::transaction_id: + c.init(other.c.get()); + break; + case types::crit_diagnostics: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + } +} +reset_resp_ies_o::value_c& reset_resp_ies_o::value_c::operator=(const reset_resp_ies_o::value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::transaction_id: + c.set(other.c.get()); + break; + case types::crit_diagnostics: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + } + + return *this; +} +uint16_t& reset_resp_ies_o::value_c::transaction_id() +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +crit_diagnostics_s& reset_resp_ies_o::value_c::crit_diagnostics() +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +const uint16_t& reset_resp_ies_o::value_c::transaction_id() const +{ + assert_choice_type(types::transaction_id, type_, "Value"); + return c.get(); +} +const crit_diagnostics_s& reset_resp_ies_o::value_c::crit_diagnostics() const +{ + assert_choice_type(types::crit_diagnostics, type_, "Value"); + return c.get(); +} +void reset_resp_ies_o::value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::transaction_id: + j.write_int("INTEGER (0..255,...)", c.get()); + break; + case types::crit_diagnostics: + j.write_fieldname("CriticalityDiagnostics"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + } + j.end_obj(); +} +SRSASN_CODE reset_resp_ies_o::value_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE reset_resp_ies_o::value_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::transaction_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::crit_diagnostics: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "reset_resp_ies_o::value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* reset_resp_ies_o::value_c::types_opts::to_string() const +{ + static const char* options[] = {"INTEGER (0..255,...)", "CriticalityDiagnostics"}; + return convert_enum_idx(options, 2, value, "reset_resp_ies_o::value_c::types"); +} +uint8_t reset_resp_ies_o::value_c::types_opts::to_number() const +{ + static const uint8_t options[] = {0}; + return map_enum_number(options, 1, value, "reset_resp_ies_o::value_c::types"); +} + +template struct asn1::protocol_ie_field_s; + +e2_removal_fail_ies_container::e2_removal_fail_ies_container() : + transaction_id(49, crit_e::reject), cause(1, crit_e::ignore), crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE e2_removal_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_removal_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2_removal_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2_removal_resp_ies_container::e2_removal_resp_ies_container() : + transaction_id(49, crit_e::reject), crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE e2_removal_resp_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_removal_resp_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2_removal_resp_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2conn_upd_ies_container::e2conn_upd_ies_container() : + transaction_id(49, crit_e::reject), + e2conn_upd_add(44, crit_e::reject), + e2conn_upd_rem(46, crit_e::reject), + e2conn_upd_modify(45, crit_e::reject) +{ +} +SRSASN_CODE e2conn_upd_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += e2conn_upd_add_present ? 1 : 0; + nof_ies += e2conn_upd_rem_present ? 1 : 0; + nof_ies += e2conn_upd_modify_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (e2conn_upd_add_present) { + HANDLE_CODE(e2conn_upd_add.pack(bref)); + } + if (e2conn_upd_rem_present) { + HANDLE_CODE(e2conn_upd_rem.pack(bref)); + } + if (e2conn_upd_modify_present) { + HANDLE_CODE(e2conn_upd_modify.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 44: { + e2conn_upd_add_present = true; + e2conn_upd_add.id = id; + HANDLE_CODE(e2conn_upd_add.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2conn_upd_add.value.unpack(bref)); + break; + } + case 46: { + e2conn_upd_rem_present = true; + e2conn_upd_rem.id = id; + HANDLE_CODE(e2conn_upd_rem.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2conn_upd_rem.value.unpack(bref)); + break; + } + case 45: { + e2conn_upd_modify_present = true; + e2conn_upd_modify.id = id; + HANDLE_CODE(e2conn_upd_modify.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2conn_upd_modify.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2conn_upd_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (e2conn_upd_add_present) { + j.write_fieldname(""); + e2conn_upd_add.to_json(j); + } + if (e2conn_upd_rem_present) { + j.write_fieldname(""); + e2conn_upd_rem.to_json(j); + } + if (e2conn_upd_modify_present) { + j.write_fieldname(""); + e2conn_upd_modify.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2conn_upd_ack_ies_container::e2conn_upd_ack_ies_container() : + transaction_id(49, crit_e::reject), e2conn_setup(39, crit_e::reject), e2conn_setup_failed(40, crit_e::reject) +{ +} +SRSASN_CODE e2conn_upd_ack_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += e2conn_setup_present ? 1 : 0; + nof_ies += e2conn_setup_failed_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (e2conn_setup_present) { + HANDLE_CODE(e2conn_setup.pack(bref)); + } + if (e2conn_setup_failed_present) { + HANDLE_CODE(e2conn_setup_failed.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_ack_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 39: { + e2conn_setup_present = true; + e2conn_setup.id = id; + HANDLE_CODE(e2conn_setup.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2conn_setup.value.unpack(bref)); + break; + } + case 40: { + e2conn_setup_failed_present = true; + e2conn_setup_failed.id = id; + HANDLE_CODE(e2conn_setup_failed.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2conn_setup_failed.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2conn_upd_ack_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (e2conn_setup_present) { + j.write_fieldname(""); + e2conn_setup.to_json(j); + } + if (e2conn_setup_failed_present) { + j.write_fieldname(""); + e2conn_setup_failed.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2conn_upd_fail_ies_container::e2conn_upd_fail_ies_container() : + transaction_id(49, crit_e::reject), + cause(1, crit_e::reject), + time_to_wait(31, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE e2conn_upd_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += cause_present ? 1 : 0; + nof_ies += time_to_wait_present ? 1 : 0; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (cause_present) { + HANDLE_CODE(cause.pack(bref)); + } + if (time_to_wait_present) { + HANDLE_CODE(time_to_wait.pack(bref)); + } + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2conn_upd_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + cause_present = true; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 31: { + time_to_wait_present = true; + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2conn_upd_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (cause_present) { + j.write_fieldname(""); + cause.to_json(j); + } + if (time_to_wait_present) { + j.write_fieldname(""); + time_to_wait.to_json(j); + } + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2node_cfg_upd_ies_container::e2node_cfg_upd_ies_container() : + transaction_id(49, crit_e::reject), + global_e2node_id(3, crit_e::reject), + e2node_component_cfg_addition(50, crit_e::reject), + e2node_component_cfg_upd(33, crit_e::reject), + e2node_component_cfg_removal(54, crit_e::reject), + e2node_tn_lassoc_removal(58, crit_e::reject) +{ +} +SRSASN_CODE e2node_cfg_upd_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += global_e2node_id_present ? 1 : 0; + nof_ies += e2node_component_cfg_addition_present ? 1 : 0; + nof_ies += e2node_component_cfg_upd_present ? 1 : 0; + nof_ies += e2node_component_cfg_removal_present ? 1 : 0; + nof_ies += e2node_tn_lassoc_removal_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (global_e2node_id_present) { + HANDLE_CODE(global_e2node_id.pack(bref)); + } + if (e2node_component_cfg_addition_present) { + HANDLE_CODE(e2node_component_cfg_addition.pack(bref)); + } + if (e2node_component_cfg_upd_present) { + HANDLE_CODE(e2node_component_cfg_upd.pack(bref)); + } + if (e2node_component_cfg_removal_present) { + HANDLE_CODE(e2node_component_cfg_removal.pack(bref)); + } + if (e2node_tn_lassoc_removal_present) { + HANDLE_CODE(e2node_tn_lassoc_removal.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 3: { + global_e2node_id_present = true; + global_e2node_id.id = id; + HANDLE_CODE(global_e2node_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_e2node_id.value.unpack(bref)); + break; + } + case 50: { + e2node_component_cfg_addition_present = true; + e2node_component_cfg_addition.id = id; + HANDLE_CODE(e2node_component_cfg_addition.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_addition.value.unpack(bref)); + break; + } + case 33: { + e2node_component_cfg_upd_present = true; + e2node_component_cfg_upd.id = id; + HANDLE_CODE(e2node_component_cfg_upd.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_upd.value.unpack(bref)); + break; + } + case 54: { + e2node_component_cfg_removal_present = true; + e2node_component_cfg_removal.id = id; + HANDLE_CODE(e2node_component_cfg_removal.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_removal.value.unpack(bref)); + break; + } + case 58: { + e2node_tn_lassoc_removal_present = true; + e2node_tn_lassoc_removal.id = id; + HANDLE_CODE(e2node_tn_lassoc_removal.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_tn_lassoc_removal.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2node_cfg_upd_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (global_e2node_id_present) { + j.write_fieldname(""); + global_e2node_id.to_json(j); + } + if (e2node_component_cfg_addition_present) { + j.write_fieldname(""); + e2node_component_cfg_addition.to_json(j); + } + if (e2node_component_cfg_upd_present) { + j.write_fieldname(""); + e2node_component_cfg_upd.to_json(j); + } + if (e2node_component_cfg_removal_present) { + j.write_fieldname(""); + e2node_component_cfg_removal.to_json(j); + } + if (e2node_tn_lassoc_removal_present) { + j.write_fieldname(""); + e2node_tn_lassoc_removal.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2node_cfg_upd_ack_ies_container::e2node_cfg_upd_ack_ies_container() : + transaction_id(49, crit_e::reject), + e2node_component_cfg_addition_ack(52, crit_e::reject), + e2node_component_cfg_upd_ack(35, crit_e::reject), + e2node_component_cfg_removal_ack(56, crit_e::reject) +{ +} +SRSASN_CODE e2node_cfg_upd_ack_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += e2node_component_cfg_addition_ack_present ? 1 : 0; + nof_ies += e2node_component_cfg_upd_ack_present ? 1 : 0; + nof_ies += e2node_component_cfg_removal_ack_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (e2node_component_cfg_addition_ack_present) { + HANDLE_CODE(e2node_component_cfg_addition_ack.pack(bref)); + } + if (e2node_component_cfg_upd_ack_present) { + HANDLE_CODE(e2node_component_cfg_upd_ack.pack(bref)); + } + if (e2node_component_cfg_removal_ack_present) { + HANDLE_CODE(e2node_component_cfg_removal_ack.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_ack_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 52: { + e2node_component_cfg_addition_ack_present = true; + e2node_component_cfg_addition_ack.id = id; + HANDLE_CODE(e2node_component_cfg_addition_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_addition_ack.value.unpack(bref)); + break; + } + case 35: { + e2node_component_cfg_upd_ack_present = true; + e2node_component_cfg_upd_ack.id = id; + HANDLE_CODE(e2node_component_cfg_upd_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_upd_ack.value.unpack(bref)); + break; + } + case 56: { + e2node_component_cfg_removal_ack_present = true; + e2node_component_cfg_removal_ack.id = id; + HANDLE_CODE(e2node_component_cfg_removal_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_removal_ack.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2node_cfg_upd_ack_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (e2node_component_cfg_addition_ack_present) { + j.write_fieldname(""); + e2node_component_cfg_addition_ack.to_json(j); + } + if (e2node_component_cfg_upd_ack_present) { + j.write_fieldname(""); + e2node_component_cfg_upd_ack.to_json(j); + } + if (e2node_component_cfg_removal_ack_present) { + j.write_fieldname(""); + e2node_component_cfg_removal_ack.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2node_cfg_upd_fail_ies_container::e2node_cfg_upd_fail_ies_container() : + transaction_id(49, crit_e::reject), + cause(1, crit_e::ignore), + time_to_wait(31, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE e2node_cfg_upd_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + nof_ies += time_to_wait_present ? 1 : 0; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (time_to_wait_present) { + HANDLE_CODE(time_to_wait.pack(bref)); + } + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2node_cfg_upd_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 31: { + time_to_wait_present = true; + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2node_cfg_upd_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (time_to_wait_present) { + j.write_fieldname(""); + time_to_wait.to_json(j); + } + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2setup_fail_ies_container::e2setup_fail_ies_container() : + transaction_id(49, crit_e::reject), + cause(1, crit_e::ignore), + time_to_wait(31, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore), + tn_linfo(48, crit_e::ignore) +{ +} +SRSASN_CODE e2setup_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + nof_ies += time_to_wait_present ? 1 : 0; + nof_ies += crit_diagnostics_present ? 1 : 0; + nof_ies += tn_linfo_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (time_to_wait_present) { + HANDLE_CODE(time_to_wait.pack(bref)); + } + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + if (tn_linfo_present) { + HANDLE_CODE(tn_linfo.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 31: { + time_to_wait_present = true; + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + case 48: { + tn_linfo_present = true; + tn_linfo.id = id; + HANDLE_CODE(tn_linfo.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tn_linfo.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2setup_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (time_to_wait_present) { + j.write_fieldname(""); + time_to_wait.to_json(j); + } + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + if (tn_linfo_present) { + j.write_fieldname(""); + tn_linfo.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2setup_request_ies_container::e2setup_request_ies_container() : + transaction_id(49, crit_e::reject), + global_e2node_id(3, crit_e::reject), + ra_nfunctions_added(10, crit_e::reject), + e2node_component_cfg_addition(50, crit_e::reject) +{ +} +SRSASN_CODE e2setup_request_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 4; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(global_e2node_id.pack(bref)); + HANDLE_CODE(ra_nfunctions_added.pack(bref)); + HANDLE_CODE(e2node_component_cfg_addition.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_request_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 4; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 3: { + nof_mandatory_ies--; + global_e2node_id.id = id; + HANDLE_CODE(global_e2node_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_e2node_id.value.unpack(bref)); + break; + } + case 10: { + nof_mandatory_ies--; + ra_nfunctions_added.id = id; + HANDLE_CODE(ra_nfunctions_added.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_added.value.unpack(bref)); + break; + } + case 50: { + nof_mandatory_ies--; + e2node_component_cfg_addition.id = id; + HANDLE_CODE(e2node_component_cfg_addition.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_addition.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2setup_request_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + global_e2node_id.to_json(j); + j.write_fieldname(""); + ra_nfunctions_added.to_json(j); + j.write_fieldname(""); + e2node_component_cfg_addition.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +e2setup_resp_ies_container::e2setup_resp_ies_container() : + transaction_id(49, crit_e::reject), + global_ric_id(4, crit_e::reject), + ra_nfunctions_accepted(9, crit_e::reject), + ra_nfunctions_rejected(13, crit_e::reject), + e2node_component_cfg_addition_ack(52, crit_e::reject) +{ +} +SRSASN_CODE e2setup_resp_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + nof_ies += ra_nfunctions_accepted_present ? 1 : 0; + nof_ies += ra_nfunctions_rejected_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(global_ric_id.pack(bref)); + if (ra_nfunctions_accepted_present) { + HANDLE_CODE(ra_nfunctions_accepted.pack(bref)); + } + if (ra_nfunctions_rejected_present) { + HANDLE_CODE(ra_nfunctions_rejected.pack(bref)); + } + HANDLE_CODE(e2node_component_cfg_addition_ack.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2setup_resp_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 4: { + nof_mandatory_ies--; + global_ric_id.id = id; + HANDLE_CODE(global_ric_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_ric_id.value.unpack(bref)); + break; + } + case 9: { + ra_nfunctions_accepted_present = true; + ra_nfunctions_accepted.id = id; + HANDLE_CODE(ra_nfunctions_accepted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_accepted.value.unpack(bref)); + break; + } + case 13: { + ra_nfunctions_rejected_present = true; + ra_nfunctions_rejected.id = id; + HANDLE_CODE(ra_nfunctions_rejected.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_rejected.value.unpack(bref)); + break; + } + case 52: { + nof_mandatory_ies--; + e2node_component_cfg_addition_ack.id = id; + HANDLE_CODE(e2node_component_cfg_addition_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e2node_component_cfg_addition_ack.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void e2setup_resp_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + global_ric_id.to_json(j); + if (ra_nfunctions_accepted_present) { + j.write_fieldname(""); + ra_nfunctions_accepted.to_json(j); + } + if (ra_nfunctions_rejected_present) { + j.write_fieldname(""); + ra_nfunctions_rejected.to_json(j); + } + j.write_fieldname(""); + e2node_component_cfg_addition_ack.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +error_ind_ies_container::error_ind_ies_container() : + transaction_id(49, crit_e::reject), + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + cause(1, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE error_ind_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 0; + nof_ies += transaction_id_present ? 1 : 0; + nof_ies += ri_crequest_id_present ? 1 : 0; + nof_ies += ra_nfunction_id_present ? 1 : 0; + nof_ies += cause_present ? 1 : 0; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + if (transaction_id_present) { + HANDLE_CODE(transaction_id.pack(bref)); + } + if (ri_crequest_id_present) { + HANDLE_CODE(ri_crequest_id.pack(bref)); + } + if (ra_nfunction_id_present) { + HANDLE_CODE(ra_nfunction_id.pack(bref)); + } + if (cause_present) { + HANDLE_CODE(cause.pack(bref)); + } + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE error_ind_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + transaction_id_present = true; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 29: { + ri_crequest_id_present = true; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + ra_nfunction_id_present = true; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 1: { + cause_present = true; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + + return SRSASN_SUCCESS; +} +void error_ind_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + if (transaction_id_present) { + j.write_fieldname(""); + transaction_id.to_json(j); + } + if (ri_crequest_id_present) { + j.write_fieldname(""); + ri_crequest_id.to_json(j); + } + if (ra_nfunction_id_present) { + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + } + if (cause_present) { + j.write_fieldname(""); + cause.to_json(j); + } + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ri_cctrl_ack_ies_container::ri_cctrl_ack_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + ri_ccall_process_id(20, crit_e::reject), + ri_cctrl_outcome(32, crit_e::reject) +{ +} +SRSASN_CODE ri_cctrl_ack_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + nof_ies += ri_ccall_process_id_present ? 1 : 0; + nof_ies += ri_cctrl_outcome_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + if (ri_ccall_process_id_present) { + HANDLE_CODE(ri_ccall_process_id.pack(bref)); + } + if (ri_cctrl_outcome_present) { + HANDLE_CODE(ri_cctrl_outcome.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_ack_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 20: { + ri_ccall_process_id_present = true; + ri_ccall_process_id.id = id; + HANDLE_CODE(ri_ccall_process_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_ccall_process_id.value.unpack(bref)); + break; + } + case 32: { + ri_cctrl_outcome_present = true; + ri_cctrl_outcome.id = id; + HANDLE_CODE(ri_cctrl_outcome.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cctrl_outcome.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ri_cctrl_ack_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + if (ri_ccall_process_id_present) { + j.write_fieldname(""); + ri_ccall_process_id.to_json(j); + } + if (ri_cctrl_outcome_present) { + j.write_fieldname(""); + ri_cctrl_outcome.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ri_cctrl_fail_ies_container::ri_cctrl_fail_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + ri_ccall_process_id(20, crit_e::reject), + cause(1, crit_e::ignore), + ri_cctrl_outcome(32, crit_e::reject) +{ +} +SRSASN_CODE ri_cctrl_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + nof_ies += ri_ccall_process_id_present ? 1 : 0; + nof_ies += ri_cctrl_outcome_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + if (ri_ccall_process_id_present) { + HANDLE_CODE(ri_ccall_process_id.pack(bref)); + } + HANDLE_CODE(cause.pack(bref)); + if (ri_cctrl_outcome_present) { + HANDLE_CODE(ri_cctrl_outcome.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 20: { + ri_ccall_process_id_present = true; + ri_ccall_process_id.id = id; + HANDLE_CODE(ri_ccall_process_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_ccall_process_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 32: { + ri_cctrl_outcome_present = true; + ri_cctrl_outcome.id = id; + HANDLE_CODE(ri_cctrl_outcome.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cctrl_outcome.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ri_cctrl_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + if (ri_ccall_process_id_present) { + j.write_fieldname(""); + ri_ccall_process_id.to_json(j); + } + j.write_fieldname(""); + cause.to_json(j); + if (ri_cctrl_outcome_present) { + j.write_fieldname(""); + ri_cctrl_outcome.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ri_cctrl_request_ies_container::ri_cctrl_request_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + ri_ccall_process_id(20, crit_e::reject), + ri_cctrl_hdr(22, crit_e::reject), + ri_cctrl_msg(23, crit_e::reject), + ri_cctrl_ack_request(21, crit_e::reject) +{ +} +SRSASN_CODE ri_cctrl_request_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 4; + nof_ies += ri_ccall_process_id_present ? 1 : 0; + nof_ies += ri_cctrl_ack_request_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + if (ri_ccall_process_id_present) { + HANDLE_CODE(ri_ccall_process_id.pack(bref)); + } + HANDLE_CODE(ri_cctrl_hdr.pack(bref)); + HANDLE_CODE(ri_cctrl_msg.pack(bref)); + if (ri_cctrl_ack_request_present) { + HANDLE_CODE(ri_cctrl_ack_request.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cctrl_request_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 4; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 20: { + ri_ccall_process_id_present = true; + ri_ccall_process_id.id = id; + HANDLE_CODE(ri_ccall_process_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_ccall_process_id.value.unpack(bref)); + break; + } + case 22: { + nof_mandatory_ies--; + ri_cctrl_hdr.id = id; + HANDLE_CODE(ri_cctrl_hdr.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cctrl_hdr.value.unpack(bref)); + break; + } + case 23: { + nof_mandatory_ies--; + ri_cctrl_msg.id = id; + HANDLE_CODE(ri_cctrl_msg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cctrl_msg.value.unpack(bref)); + break; + } + case 21: { + ri_cctrl_ack_request_present = true; + ri_cctrl_ack_request.id = id; + HANDLE_CODE(ri_cctrl_ack_request.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cctrl_ack_request.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ri_cctrl_request_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + if (ri_ccall_process_id_present) { + j.write_fieldname(""); + ri_ccall_process_id.to_json(j); + } + j.write_fieldname(""); + ri_cctrl_hdr.to_json(j); + j.write_fieldname(""); + ri_cctrl_msg.to_json(j); + if (ri_cctrl_ack_request_present) { + j.write_fieldname(""); + ri_cctrl_ack_request.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ri_cind_ies_container::ri_cind_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + ri_caction_id(15, crit_e::reject), + ri_cind_sn(27, crit_e::reject), + ri_cind_type(28, crit_e::reject), + ri_cind_hdr(25, crit_e::reject), + ri_cind_msg(26, crit_e::reject), + ri_ccall_process_id(20, crit_e::reject) +{ +} +SRSASN_CODE ri_cind_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 6; + nof_ies += ri_cind_sn_present ? 1 : 0; + nof_ies += ri_ccall_process_id_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + HANDLE_CODE(ri_caction_id.pack(bref)); + if (ri_cind_sn_present) { + HANDLE_CODE(ri_cind_sn.pack(bref)); + } + HANDLE_CODE(ri_cind_type.pack(bref)); + HANDLE_CODE(ri_cind_hdr.pack(bref)); + HANDLE_CODE(ri_cind_msg.pack(bref)); + if (ri_ccall_process_id_present) { + HANDLE_CODE(ri_ccall_process_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ri_cind_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 6; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 15: { + nof_mandatory_ies--; + ri_caction_id.id = id; + HANDLE_CODE(ri_caction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_caction_id.value.unpack(bref)); + break; + } + case 27: { + ri_cind_sn_present = true; + ri_cind_sn.id = id; + HANDLE_CODE(ri_cind_sn.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cind_sn.value.unpack(bref)); + break; + } + case 28: { + nof_mandatory_ies--; + ri_cind_type.id = id; + HANDLE_CODE(ri_cind_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cind_type.value.unpack(bref)); + break; + } + case 25: { + nof_mandatory_ies--; + ri_cind_hdr.id = id; + HANDLE_CODE(ri_cind_hdr.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cind_hdr.value.unpack(bref)); + break; + } + case 26: { + nof_mandatory_ies--; + ri_cind_msg.id = id; + HANDLE_CODE(ri_cind_msg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cind_msg.value.unpack(bref)); + break; + } + case 20: { + ri_ccall_process_id_present = true; + ri_ccall_process_id.id = id; + HANDLE_CODE(ri_ccall_process_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_ccall_process_id.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ri_cind_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.write_fieldname(""); + ri_caction_id.to_json(j); + if (ri_cind_sn_present) { + j.write_fieldname(""); + ri_cind_sn.to_json(j); + } + j.write_fieldname(""); + ri_cind_type.to_json(j); + j.write_fieldname(""); + ri_cind_hdr.to_json(j); + j.write_fieldname(""); + ri_cind_msg.to_json(j); + if (ri_ccall_process_id_present) { + j.write_fieldname(""); + ri_ccall_process_id.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricservice_query_ies_container::ricservice_query_ies_container() : + transaction_id(49, crit_e::reject), ra_nfunctions_accepted(9, crit_e::reject) +{ +} +SRSASN_CODE ricservice_query_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += ra_nfunctions_accepted_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (ra_nfunctions_accepted_present) { + HANDLE_CODE(ra_nfunctions_accepted.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_query_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 9: { + ra_nfunctions_accepted_present = true; + ra_nfunctions_accepted.id = id; + HANDLE_CODE(ra_nfunctions_accepted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_accepted.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricservice_query_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (ra_nfunctions_accepted_present) { + j.write_fieldname(""); + ra_nfunctions_accepted.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricservice_upd_ies_container::ricservice_upd_ies_container() : + transaction_id(49, crit_e::reject), + ra_nfunctions_added(10, crit_e::reject), + ra_nfunctions_modified(12, crit_e::reject), + ra_nfunctions_deleted(11, crit_e::reject) +{ +} +SRSASN_CODE ricservice_upd_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += ra_nfunctions_added_present ? 1 : 0; + nof_ies += ra_nfunctions_modified_present ? 1 : 0; + nof_ies += ra_nfunctions_deleted_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (ra_nfunctions_added_present) { + HANDLE_CODE(ra_nfunctions_added.pack(bref)); + } + if (ra_nfunctions_modified_present) { + HANDLE_CODE(ra_nfunctions_modified.pack(bref)); + } + if (ra_nfunctions_deleted_present) { + HANDLE_CODE(ra_nfunctions_deleted.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 10: { + ra_nfunctions_added_present = true; + ra_nfunctions_added.id = id; + HANDLE_CODE(ra_nfunctions_added.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_added.value.unpack(bref)); + break; + } + case 12: { + ra_nfunctions_modified_present = true; + ra_nfunctions_modified.id = id; + HANDLE_CODE(ra_nfunctions_modified.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_modified.value.unpack(bref)); + break; + } + case 11: { + ra_nfunctions_deleted_present = true; + ra_nfunctions_deleted.id = id; + HANDLE_CODE(ra_nfunctions_deleted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_deleted.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricservice_upd_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (ra_nfunctions_added_present) { + j.write_fieldname(""); + ra_nfunctions_added.to_json(j); + } + if (ra_nfunctions_modified_present) { + j.write_fieldname(""); + ra_nfunctions_modified.to_json(j); + } + if (ra_nfunctions_deleted_present) { + j.write_fieldname(""); + ra_nfunctions_deleted.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricservice_upd_ack_ies_container::ricservice_upd_ack_ies_container() : + transaction_id(49, crit_e::reject), + ra_nfunctions_accepted(9, crit_e::reject), + ra_nfunctions_rejected(13, crit_e::reject) +{ +} +SRSASN_CODE ricservice_upd_ack_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += ra_nfunctions_accepted_present ? 1 : 0; + nof_ies += ra_nfunctions_rejected_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (ra_nfunctions_accepted_present) { + HANDLE_CODE(ra_nfunctions_accepted.pack(bref)); + } + if (ra_nfunctions_rejected_present) { + HANDLE_CODE(ra_nfunctions_rejected.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_ack_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 9: { + ra_nfunctions_accepted_present = true; + ra_nfunctions_accepted.id = id; + HANDLE_CODE(ra_nfunctions_accepted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_accepted.value.unpack(bref)); + break; + } + case 13: { + ra_nfunctions_rejected_present = true; + ra_nfunctions_rejected.id = id; + HANDLE_CODE(ra_nfunctions_rejected.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunctions_rejected.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricservice_upd_ack_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (ra_nfunctions_accepted_present) { + j.write_fieldname(""); + ra_nfunctions_accepted.to_json(j); + } + if (ra_nfunctions_rejected_present) { + j.write_fieldname(""); + ra_nfunctions_rejected.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricservice_upd_fail_ies_container::ricservice_upd_fail_ies_container() : + transaction_id(49, crit_e::reject), + cause(1, crit_e::reject), + time_to_wait(31, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE ricservice_upd_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + nof_ies += time_to_wait_present ? 1 : 0; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (time_to_wait_present) { + HANDLE_CODE(time_to_wait.pack(bref)); + } + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricservice_upd_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 31: { + time_to_wait_present = true; + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricservice_upd_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (time_to_wait_present) { + j.write_fieldname(""); + time_to_wait.to_json(j); + } + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_delete_fail_ies_container::ricsubscription_delete_fail_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + cause(1, crit_e::ignore), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE ricsubscription_delete_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_delete_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_delete_request_ies_container::ricsubscription_delete_request_ies_container() : + ri_crequest_id(29, crit_e::reject), ra_nfunction_id(5, crit_e::reject) +{ +} +SRSASN_CODE ricsubscription_delete_request_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_request_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_delete_request_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_delete_resp_ies_container::ricsubscription_delete_resp_ies_container() : + ri_crequest_id(29, crit_e::reject), ra_nfunction_id(5, crit_e::reject) +{ +} +SRSASN_CODE ricsubscription_delete_resp_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_delete_resp_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_delete_resp_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_fail_ies_container::ricsubscription_fail_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + cause(1, crit_e::reject), + crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE ricsubscription_fail_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_fail_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_fail_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_request_ies_container::ricsubscription_request_ies_container() : + ri_crequest_id(29, crit_e::reject), ra_nfunction_id(5, crit_e::reject), ricsubscription_details(30, crit_e::reject) +{ +} +SRSASN_CODE ricsubscription_request_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + HANDLE_CODE(ricsubscription_details.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_request_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 30: { + nof_mandatory_ies--; + ricsubscription_details.id = id; + HANDLE_CODE(ricsubscription_details.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ricsubscription_details.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_request_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.write_fieldname(""); + ricsubscription_details.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +ricsubscription_resp_ies_container::ricsubscription_resp_ies_container() : + ri_crequest_id(29, crit_e::reject), + ra_nfunction_id(5, crit_e::reject), + ri_cactions_admitted(17, crit_e::reject), + ri_cactions_not_admitted(18, crit_e::reject) +{ +} +SRSASN_CODE ricsubscription_resp_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 3; + nof_ies += ri_cactions_not_admitted_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(ri_crequest_id.pack(bref)); + HANDLE_CODE(ra_nfunction_id.pack(bref)); + HANDLE_CODE(ri_cactions_admitted.pack(bref)); + if (ri_cactions_not_admitted_present) { + HANDLE_CODE(ri_cactions_not_admitted.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ricsubscription_resp_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 3; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 29: { + nof_mandatory_ies--; + ri_crequest_id.id = id; + HANDLE_CODE(ri_crequest_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_crequest_id.value.unpack(bref)); + break; + } + case 5: { + nof_mandatory_ies--; + ra_nfunction_id.id = id; + HANDLE_CODE(ra_nfunction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ra_nfunction_id.value.unpack(bref)); + break; + } + case 17: { + nof_mandatory_ies--; + ri_cactions_admitted.id = id; + HANDLE_CODE(ri_cactions_admitted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cactions_admitted.value.unpack(bref)); + break; + } + case 18: { + ri_cactions_not_admitted_present = true; + ri_cactions_not_admitted.id = id; + HANDLE_CODE(ri_cactions_not_admitted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ri_cactions_not_admitted.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void ricsubscription_resp_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + ri_crequest_id.to_json(j); + j.write_fieldname(""); + ra_nfunction_id.to_json(j); + j.write_fieldname(""); + ri_cactions_admitted.to_json(j); + if (ri_cactions_not_admitted_present) { + j.write_fieldname(""); + ri_cactions_not_admitted.to_json(j); + } + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +reset_request_ies_container::reset_request_ies_container() : + transaction_id(49, crit_e::reject), cause(1, crit_e::ignore) +{ +} +SRSASN_CODE reset_request_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 2; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + HANDLE_CODE(cause.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE reset_request_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 2; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 1: { + nof_mandatory_ies--; + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void reset_request_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + j.write_fieldname(""); + cause.to_json(j); + j.end_obj(); +} + +template struct asn1::protocol_ie_field_s; + +reset_resp_ies_container::reset_resp_ies_container() : + transaction_id(49, crit_e::reject), crit_diagnostics(2, crit_e::ignore) +{ +} +SRSASN_CODE reset_resp_ies_container::pack(bit_ref& bref) const +{ + uint32_t nof_ies = 1; + nof_ies += crit_diagnostics_present ? 1 : 0; + pack_length(bref, nof_ies, 0u, 65535u, true); + + HANDLE_CODE(transaction_id.pack(bref)); + if (crit_diagnostics_present) { + HANDLE_CODE(crit_diagnostics.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE reset_resp_ies_container::unpack(cbit_ref& bref) +{ + uint32_t nof_ies = 0; + unpack_length(nof_ies, bref, 0u, 65535u, true); + + uint32_t nof_mandatory_ies = 1; + + for (; nof_ies > 0; --nof_ies) { + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 49: { + nof_mandatory_ies--; + transaction_id.id = id; + HANDLE_CODE(transaction_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(transaction_id.value.unpack(bref)); + break; + } + case 2: { + crit_diagnostics_present = true; + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); + break; + } + default: + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); + return SRSASN_ERROR_DECODE_FAIL; + } + } + if (nof_mandatory_ies > 0) { + asn1::log_error("Mandatory fields are missing\n"); + + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +void reset_resp_ies_container::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname(""); + transaction_id.to_json(j); + if (crit_diagnostics_present) { + j.write_fieldname(""); + crit_diagnostics.to_json(j); + } + j.end_obj(); +} + +// E2AP-ELEMENTARY-PROCEDURES ::= OBJECT SET OF E2AP-ELEMENTARY-PROCEDURE +uint16_t e2_ap_elem_procs_o::idx_to_proc_code(uint32_t idx) +{ + static const uint16_t options[] = {8, 9, 7, 4, 1, 10, 11, 3, 13, 5, 6, 2, 12}; + return map_enum_number(options, 13, idx, "proc_code"); +} +bool e2_ap_elem_procs_o::is_proc_code_valid(const uint16_t& proc_code) +{ + static const uint16_t options[] = {8, 9, 7, 4, 1, 10, 11, 3, 13, 5, 6, 2, 12}; + for (const auto& o : options) { + if (o == proc_code) { + return true; + } + } + return false; +} +e2_ap_elem_procs_o::init_msg_c e2_ap_elem_procs_o::get_init_msg(const uint16_t& proc_code) +{ + init_msg_c ret{}; + switch (proc_code) { + case 8: + ret.set(init_msg_c::types::ricsubscription_request); + break; + case 9: + ret.set(init_msg_c::types::ricsubscription_delete_request); + break; + case 7: + ret.set(init_msg_c::types::ricservice_upd); + break; + case 4: + ret.set(init_msg_c::types::ri_cctrl_request); + break; + case 1: + ret.set(init_msg_c::types::e2setup_request); + break; + case 10: + ret.set(init_msg_c::types::e2node_cfg_upd); + break; + case 11: + ret.set(init_msg_c::types::e2conn_upd); + break; + case 3: + ret.set(init_msg_c::types::reset_request); + break; + case 13: + ret.set(init_msg_c::types::e2_removal_request); + break; + case 5: + ret.set(init_msg_c::types::ri_cind); + break; + case 6: + ret.set(init_msg_c::types::ricservice_query); + break; + case 2: + ret.set(init_msg_c::types::error_ind); + break; + case 12: + ret.set(init_msg_c::types::ricsubscription_delete_required); + break; + default: + asn1::log_error("The proc_code=%d is not recognized", proc_code); + } + return ret; +} +e2_ap_elem_procs_o::successful_outcome_c e2_ap_elem_procs_o::get_successful_outcome(const uint16_t& proc_code) +{ + successful_outcome_c ret{}; + switch (proc_code) { + case 8: + ret.set(successful_outcome_c::types::ricsubscription_resp); + break; + case 9: + ret.set(successful_outcome_c::types::ricsubscription_delete_resp); + break; + case 7: + ret.set(successful_outcome_c::types::ricservice_upd_ack); + break; + case 4: + ret.set(successful_outcome_c::types::ri_cctrl_ack); + break; + case 1: + ret.set(successful_outcome_c::types::e2setup_resp); + break; + case 10: + ret.set(successful_outcome_c::types::e2node_cfg_upd_ack); + break; + case 11: + ret.set(successful_outcome_c::types::e2conn_upd_ack); + break; + case 3: + ret.set(successful_outcome_c::types::reset_resp); + break; + case 13: + ret.set(successful_outcome_c::types::e2_removal_resp); + break; + default: + asn1::log_error("The proc_code=%d is not recognized", proc_code); + } + return ret; +} +e2_ap_elem_procs_o::unsuccessful_outcome_c e2_ap_elem_procs_o::get_unsuccessful_outcome(const uint16_t& proc_code) +{ + unsuccessful_outcome_c ret{}; + switch (proc_code) { + case 8: + ret.set(unsuccessful_outcome_c::types::ricsubscription_fail); + break; + case 9: + ret.set(unsuccessful_outcome_c::types::ricsubscription_delete_fail); + break; + case 7: + ret.set(unsuccessful_outcome_c::types::ricservice_upd_fail); + break; + case 4: + ret.set(unsuccessful_outcome_c::types::ri_cctrl_fail); + break; + case 1: + ret.set(unsuccessful_outcome_c::types::e2setup_fail); + break; + case 10: + ret.set(unsuccessful_outcome_c::types::e2node_cfg_upd_fail); + break; + case 11: + ret.set(unsuccessful_outcome_c::types::e2conn_upd_fail); + break; + case 13: + ret.set(unsuccessful_outcome_c::types::e2_removal_fail); + break; + default: + asn1::log_error("The proc_code=%d is not recognized", proc_code); + } + return ret; +} +crit_e e2_ap_elem_procs_o::get_crit(const uint16_t& proc_code) +{ + switch (proc_code) { + case 8: + return crit_e::reject; + case 9: + return crit_e::reject; + case 7: + return crit_e::reject; + case 4: + return crit_e::reject; + case 1: + return crit_e::reject; + case 10: + return crit_e::reject; + case 11: + return crit_e::reject; + case 3: + return crit_e::reject; + case 13: + return crit_e::reject; + case 5: + return crit_e::ignore; + case 6: + return crit_e::ignore; + case 2: + return crit_e::ignore; + case 12: + return crit_e::ignore; + default: + asn1::log_error("The proc_code=%d is not recognized", proc_code); + } + return {}; +} + +// InitiatingMessage ::= OPEN TYPE +void e2_ap_elem_procs_o::init_msg_c::destroy_() +{ + switch (type_) { + case types::ricsubscription_request: + c.destroy(); + break; + case types::ricsubscription_delete_request: + c.destroy(); + break; + case types::ricservice_upd: + c.destroy(); + break; + case types::ri_cctrl_request: + c.destroy(); + break; + case types::e2setup_request: + c.destroy(); + break; + case types::e2node_cfg_upd: + c.destroy(); + break; + case types::e2conn_upd: + c.destroy(); + break; + case types::reset_request: + c.destroy(); + break; + case types::e2_removal_request: + c.destroy(); + break; + case types::ri_cind: + c.destroy(); + break; + case types::ricservice_query: + c.destroy(); + break; + case types::error_ind: + c.destroy(); + break; + case types::ricsubscription_delete_required: + c.destroy(); + break; + default: + break; + } +} +void e2_ap_elem_procs_o::init_msg_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ricsubscription_request: + c.init(); + break; + case types::ricsubscription_delete_request: + c.init(); + break; + case types::ricservice_upd: + c.init(); + break; + case types::ri_cctrl_request: + c.init(); + break; + case types::e2setup_request: + c.init(); + break; + case types::e2node_cfg_upd: + c.init(); + break; + case types::e2conn_upd: + c.init(); + break; + case types::reset_request: + c.init(); + break; + case types::e2_removal_request: + c.init(); + break; + case types::ri_cind: + c.init(); + break; + case types::ricservice_query: + c.init(); + break; + case types::error_ind: + c.init(); + break; + case types::ricsubscription_delete_required: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + } +} +e2_ap_elem_procs_o::init_msg_c::init_msg_c(const e2_ap_elem_procs_o::init_msg_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ricsubscription_request: + c.init(other.c.get()); + break; + case types::ricsubscription_delete_request: + c.init(other.c.get()); + break; + case types::ricservice_upd: + c.init(other.c.get()); + break; + case types::ri_cctrl_request: + c.init(other.c.get()); + break; + case types::e2setup_request: + c.init(other.c.get()); + break; + case types::e2node_cfg_upd: + c.init(other.c.get()); + break; + case types::e2conn_upd: + c.init(other.c.get()); + break; + case types::reset_request: + c.init(other.c.get()); + break; + case types::e2_removal_request: + c.init(other.c.get()); + break; + case types::ri_cind: + c.init(other.c.get()); + break; + case types::ricservice_query: + c.init(other.c.get()); + break; + case types::error_ind: + c.init(other.c.get()); + break; + case types::ricsubscription_delete_required: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + } +} +e2_ap_elem_procs_o::init_msg_c& e2_ap_elem_procs_o::init_msg_c::operator=(const e2_ap_elem_procs_o::init_msg_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ricsubscription_request: + c.set(other.c.get()); + break; + case types::ricsubscription_delete_request: + c.set(other.c.get()); + break; + case types::ricservice_upd: + c.set(other.c.get()); + break; + case types::ri_cctrl_request: + c.set(other.c.get()); + break; + case types::e2setup_request: + c.set(other.c.get()); + break; + case types::e2node_cfg_upd: + c.set(other.c.get()); + break; + case types::e2conn_upd: + c.set(other.c.get()); + break; + case types::reset_request: + c.set(other.c.get()); + break; + case types::e2_removal_request: + c.set(other.c.get()); + break; + case types::ri_cind: + c.set(other.c.get()); + break; + case types::ricservice_query: + c.set(other.c.get()); + break; + case types::error_ind: + c.set(other.c.get()); + break; + case types::ricsubscription_delete_required: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + } + + return *this; +} +ricsubscription_request_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_request() +{ + assert_choice_type(types::ricsubscription_request, type_, "InitiatingMessage"); + return c.get(); +} +ricsubscription_delete_request_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_delete_request() +{ + assert_choice_type(types::ricsubscription_delete_request, type_, "InitiatingMessage"); + return c.get(); +} +ricservice_upd_s& e2_ap_elem_procs_o::init_msg_c::ricservice_upd() +{ + assert_choice_type(types::ricservice_upd, type_, "InitiatingMessage"); + return c.get(); +} +ri_cctrl_request_s& e2_ap_elem_procs_o::init_msg_c::ri_cctrl_request() +{ + assert_choice_type(types::ri_cctrl_request, type_, "InitiatingMessage"); + return c.get(); +} +e2setup_request_s& e2_ap_elem_procs_o::init_msg_c::e2setup_request() +{ + assert_choice_type(types::e2setup_request, type_, "InitiatingMessage"); + return c.get(); +} +e2node_cfg_upd_s& e2_ap_elem_procs_o::init_msg_c::e2node_cfg_upd() +{ + assert_choice_type(types::e2node_cfg_upd, type_, "InitiatingMessage"); + return c.get(); +} +e2conn_upd_s& e2_ap_elem_procs_o::init_msg_c::e2conn_upd() +{ + assert_choice_type(types::e2conn_upd, type_, "InitiatingMessage"); + return c.get(); +} +reset_request_s& e2_ap_elem_procs_o::init_msg_c::reset_request() +{ + assert_choice_type(types::reset_request, type_, "InitiatingMessage"); + return c.get(); +} +e2_removal_request_s& e2_ap_elem_procs_o::init_msg_c::e2_removal_request() +{ + assert_choice_type(types::e2_removal_request, type_, "InitiatingMessage"); + return c.get(); +} +ri_cind_s& e2_ap_elem_procs_o::init_msg_c::ri_cind() +{ + assert_choice_type(types::ri_cind, type_, "InitiatingMessage"); + return c.get(); +} +ricservice_query_s& e2_ap_elem_procs_o::init_msg_c::ricservice_query() +{ + assert_choice_type(types::ricservice_query, type_, "InitiatingMessage"); + return c.get(); +} +error_ind_s& e2_ap_elem_procs_o::init_msg_c::error_ind() +{ + assert_choice_type(types::error_ind, type_, "InitiatingMessage"); + return c.get(); +} +ricsubscription_delete_required_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_delete_required() +{ + assert_choice_type(types::ricsubscription_delete_required, type_, "InitiatingMessage"); + return c.get(); +} +const ricsubscription_request_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_request() const +{ + assert_choice_type(types::ricsubscription_request, type_, "InitiatingMessage"); + return c.get(); +} +const ricsubscription_delete_request_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_delete_request() const +{ + assert_choice_type(types::ricsubscription_delete_request, type_, "InitiatingMessage"); + return c.get(); +} +const ricservice_upd_s& e2_ap_elem_procs_o::init_msg_c::ricservice_upd() const +{ + assert_choice_type(types::ricservice_upd, type_, "InitiatingMessage"); + return c.get(); +} +const ri_cctrl_request_s& e2_ap_elem_procs_o::init_msg_c::ri_cctrl_request() const +{ + assert_choice_type(types::ri_cctrl_request, type_, "InitiatingMessage"); + return c.get(); +} +const e2setup_request_s& e2_ap_elem_procs_o::init_msg_c::e2setup_request() const +{ + assert_choice_type(types::e2setup_request, type_, "InitiatingMessage"); + return c.get(); +} +const e2node_cfg_upd_s& e2_ap_elem_procs_o::init_msg_c::e2node_cfg_upd() const +{ + assert_choice_type(types::e2node_cfg_upd, type_, "InitiatingMessage"); + return c.get(); +} +const e2conn_upd_s& e2_ap_elem_procs_o::init_msg_c::e2conn_upd() const +{ + assert_choice_type(types::e2conn_upd, type_, "InitiatingMessage"); + return c.get(); +} +const reset_request_s& e2_ap_elem_procs_o::init_msg_c::reset_request() const +{ + assert_choice_type(types::reset_request, type_, "InitiatingMessage"); + return c.get(); +} +const e2_removal_request_s& e2_ap_elem_procs_o::init_msg_c::e2_removal_request() const +{ + assert_choice_type(types::e2_removal_request, type_, "InitiatingMessage"); + return c.get(); +} +const ri_cind_s& e2_ap_elem_procs_o::init_msg_c::ri_cind() const +{ + assert_choice_type(types::ri_cind, type_, "InitiatingMessage"); + return c.get(); +} +const ricservice_query_s& e2_ap_elem_procs_o::init_msg_c::ricservice_query() const +{ + assert_choice_type(types::ricservice_query, type_, "InitiatingMessage"); + return c.get(); +} +const error_ind_s& e2_ap_elem_procs_o::init_msg_c::error_ind() const +{ + assert_choice_type(types::error_ind, type_, "InitiatingMessage"); + return c.get(); +} +const ricsubscription_delete_required_s& e2_ap_elem_procs_o::init_msg_c::ricsubscription_delete_required() const +{ + assert_choice_type(types::ricsubscription_delete_required, type_, "InitiatingMessage"); + return c.get(); +} +void e2_ap_elem_procs_o::init_msg_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ricsubscription_request: + j.write_fieldname("RICsubscriptionRequest"); + c.get().to_json(j); + break; + case types::ricsubscription_delete_request: + j.write_fieldname("RICsubscriptionDeleteRequest"); + c.get().to_json(j); + break; + case types::ricservice_upd: + j.write_fieldname("RICserviceUpdate"); + c.get().to_json(j); + break; + case types::ri_cctrl_request: + j.write_fieldname("RICcontrolRequest"); + c.get().to_json(j); + break; + case types::e2setup_request: + j.write_fieldname("E2setupRequest"); + c.get().to_json(j); + break; + case types::e2node_cfg_upd: + j.write_fieldname("E2nodeConfigurationUpdate"); + c.get().to_json(j); + break; + case types::e2conn_upd: + j.write_fieldname("E2connectionUpdate"); + c.get().to_json(j); + break; + case types::reset_request: + j.write_fieldname("ResetRequest"); + c.get().to_json(j); + break; + case types::e2_removal_request: + j.write_fieldname("E2RemovalRequest"); + c.get().to_json(j); + break; + case types::ri_cind: + j.write_fieldname("RICindication"); + c.get().to_json(j); + break; + case types::ricservice_query: + j.write_fieldname("RICserviceQuery"); + c.get().to_json(j); + break; + case types::error_ind: + j.write_fieldname("ErrorIndication"); + c.get().to_json(j); + break; + case types::ricsubscription_delete_required: + j.write_fieldname("RICsubscriptionDeleteRequired"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_ap_elem_procs_o::init_msg_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricsubscription_delete_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricservice_upd: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cctrl_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2setup_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_cfg_upd: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2conn_upd: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::reset_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2_removal_request: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cind: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricservice_query: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::error_ind: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricsubscription_delete_required: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_ap_elem_procs_o::init_msg_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricsubscription_delete_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricservice_upd: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cctrl_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2setup_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_cfg_upd: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2conn_upd: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::reset_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2_removal_request: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cind: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricservice_query: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::error_ind: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricsubscription_delete_required: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::init_msg_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_ap_elem_procs_o::init_msg_c::types_opts::to_string() const +{ + static const char* options[] = {"RICsubscriptionRequest", + "RICsubscriptionDeleteRequest", + "RICserviceUpdate", + "RICcontrolRequest", + "E2setupRequest", + "E2nodeConfigurationUpdate", + "E2connectionUpdate", + "ResetRequest", + "E2RemovalRequest", + "RICindication", + "RICserviceQuery", + "ErrorIndication", + "RICsubscriptionDeleteRequired"}; + return convert_enum_idx(options, 13, value, "e2_ap_elem_procs_o::init_msg_c::types"); +} + +// SuccessfulOutcome ::= OPEN TYPE +void e2_ap_elem_procs_o::successful_outcome_c::destroy_() +{ + switch (type_) { + case types::ricsubscription_resp: + c.destroy(); + break; + case types::ricsubscription_delete_resp: + c.destroy(); + break; + case types::ricservice_upd_ack: + c.destroy(); + break; + case types::ri_cctrl_ack: + c.destroy(); + break; + case types::e2setup_resp: + c.destroy(); + break; + case types::e2node_cfg_upd_ack: + c.destroy(); + break; + case types::e2conn_upd_ack: + c.destroy(); + break; + case types::reset_resp: + c.destroy(); + break; + case types::e2_removal_resp: + c.destroy(); + break; + default: + break; + } +} +void e2_ap_elem_procs_o::successful_outcome_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ricsubscription_resp: + c.init(); + break; + case types::ricsubscription_delete_resp: + c.init(); + break; + case types::ricservice_upd_ack: + c.init(); + break; + case types::ri_cctrl_ack: + c.init(); + break; + case types::e2setup_resp: + c.init(); + break; + case types::e2node_cfg_upd_ack: + c.init(); + break; + case types::e2conn_upd_ack: + c.init(); + break; + case types::reset_resp: + c.init(); + break; + case types::e2_removal_resp: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + } +} +e2_ap_elem_procs_o::successful_outcome_c::successful_outcome_c(const e2_ap_elem_procs_o::successful_outcome_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ricsubscription_resp: + c.init(other.c.get()); + break; + case types::ricsubscription_delete_resp: + c.init(other.c.get()); + break; + case types::ricservice_upd_ack: + c.init(other.c.get()); + break; + case types::ri_cctrl_ack: + c.init(other.c.get()); + break; + case types::e2setup_resp: + c.init(other.c.get()); + break; + case types::e2node_cfg_upd_ack: + c.init(other.c.get()); + break; + case types::e2conn_upd_ack: + c.init(other.c.get()); + break; + case types::reset_resp: + c.init(other.c.get()); + break; + case types::e2_removal_resp: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + } +} +e2_ap_elem_procs_o::successful_outcome_c& +e2_ap_elem_procs_o::successful_outcome_c::operator=(const e2_ap_elem_procs_o::successful_outcome_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ricsubscription_resp: + c.set(other.c.get()); + break; + case types::ricsubscription_delete_resp: + c.set(other.c.get()); + break; + case types::ricservice_upd_ack: + c.set(other.c.get()); + break; + case types::ri_cctrl_ack: + c.set(other.c.get()); + break; + case types::e2setup_resp: + c.set(other.c.get()); + break; + case types::e2node_cfg_upd_ack: + c.set(other.c.get()); + break; + case types::e2conn_upd_ack: + c.set(other.c.get()); + break; + case types::reset_resp: + c.set(other.c.get()); + break; + case types::e2_removal_resp: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + } + + return *this; +} +ricsubscription_resp_s& e2_ap_elem_procs_o::successful_outcome_c::ricsubscription_resp() +{ + assert_choice_type(types::ricsubscription_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +ricsubscription_delete_resp_s& e2_ap_elem_procs_o::successful_outcome_c::ricsubscription_delete_resp() +{ + assert_choice_type(types::ricsubscription_delete_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +ricservice_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::ricservice_upd_ack() +{ + assert_choice_type(types::ricservice_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +ri_cctrl_ack_s& e2_ap_elem_procs_o::successful_outcome_c::ri_cctrl_ack() +{ + assert_choice_type(types::ri_cctrl_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +e2setup_resp_s& e2_ap_elem_procs_o::successful_outcome_c::e2setup_resp() +{ + assert_choice_type(types::e2setup_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +e2node_cfg_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::e2node_cfg_upd_ack() +{ + assert_choice_type(types::e2node_cfg_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +e2conn_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::e2conn_upd_ack() +{ + assert_choice_type(types::e2conn_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +reset_resp_s& e2_ap_elem_procs_o::successful_outcome_c::reset_resp() +{ + assert_choice_type(types::reset_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +e2_removal_resp_s& e2_ap_elem_procs_o::successful_outcome_c::e2_removal_resp() +{ + assert_choice_type(types::e2_removal_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +const ricsubscription_resp_s& e2_ap_elem_procs_o::successful_outcome_c::ricsubscription_resp() const +{ + assert_choice_type(types::ricsubscription_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +const ricsubscription_delete_resp_s& e2_ap_elem_procs_o::successful_outcome_c::ricsubscription_delete_resp() const +{ + assert_choice_type(types::ricsubscription_delete_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +const ricservice_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::ricservice_upd_ack() const +{ + assert_choice_type(types::ricservice_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +const ri_cctrl_ack_s& e2_ap_elem_procs_o::successful_outcome_c::ri_cctrl_ack() const +{ + assert_choice_type(types::ri_cctrl_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +const e2setup_resp_s& e2_ap_elem_procs_o::successful_outcome_c::e2setup_resp() const +{ + assert_choice_type(types::e2setup_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +const e2node_cfg_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::e2node_cfg_upd_ack() const +{ + assert_choice_type(types::e2node_cfg_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +const e2conn_upd_ack_s& e2_ap_elem_procs_o::successful_outcome_c::e2conn_upd_ack() const +{ + assert_choice_type(types::e2conn_upd_ack, type_, "SuccessfulOutcome"); + return c.get(); +} +const reset_resp_s& e2_ap_elem_procs_o::successful_outcome_c::reset_resp() const +{ + assert_choice_type(types::reset_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +const e2_removal_resp_s& e2_ap_elem_procs_o::successful_outcome_c::e2_removal_resp() const +{ + assert_choice_type(types::e2_removal_resp, type_, "SuccessfulOutcome"); + return c.get(); +} +void e2_ap_elem_procs_o::successful_outcome_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ricsubscription_resp: + j.write_fieldname("RICsubscriptionResponse"); + c.get().to_json(j); + break; + case types::ricsubscription_delete_resp: + j.write_fieldname("RICsubscriptionDeleteResponse"); + c.get().to_json(j); + break; + case types::ricservice_upd_ack: + j.write_fieldname("RICserviceUpdateAcknowledge"); + c.get().to_json(j); + break; + case types::ri_cctrl_ack: + j.write_fieldname("RICcontrolAcknowledge"); + c.get().to_json(j); + break; + case types::e2setup_resp: + j.write_fieldname("E2setupResponse"); + c.get().to_json(j); + break; + case types::e2node_cfg_upd_ack: + j.write_fieldname("E2nodeConfigurationUpdateAcknowledge"); + c.get().to_json(j); + break; + case types::e2conn_upd_ack: + j.write_fieldname("E2connectionUpdateAcknowledge"); + c.get().to_json(j); + break; + case types::reset_resp: + j.write_fieldname("ResetResponse"); + c.get().to_json(j); + break; + case types::e2_removal_resp: + j.write_fieldname("E2RemovalResponse"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_ap_elem_procs_o::successful_outcome_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_resp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricsubscription_delete_resp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricservice_upd_ack: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cctrl_ack: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2setup_resp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_cfg_upd_ack: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2conn_upd_ack: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::reset_resp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2_removal_resp: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_ap_elem_procs_o::successful_outcome_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_resp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricsubscription_delete_resp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricservice_upd_ack: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cctrl_ack: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2setup_resp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_cfg_upd_ack: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2conn_upd_ack: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::reset_resp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2_removal_resp: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::successful_outcome_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_ap_elem_procs_o::successful_outcome_c::types_opts::to_string() const +{ + static const char* options[] = {"RICsubscriptionResponse", + "RICsubscriptionDeleteResponse", + "RICserviceUpdateAcknowledge", + "RICcontrolAcknowledge", + "E2setupResponse", + "E2nodeConfigurationUpdateAcknowledge", + "E2connectionUpdateAcknowledge", + "ResetResponse", + "E2RemovalResponse"}; + return convert_enum_idx(options, 9, value, "e2_ap_elem_procs_o::successful_outcome_c::types"); +} + +// UnsuccessfulOutcome ::= OPEN TYPE +void e2_ap_elem_procs_o::unsuccessful_outcome_c::destroy_() +{ + switch (type_) { + case types::ricsubscription_fail: + c.destroy(); + break; + case types::ricsubscription_delete_fail: + c.destroy(); + break; + case types::ricservice_upd_fail: + c.destroy(); + break; + case types::ri_cctrl_fail: + c.destroy(); + break; + case types::e2setup_fail: + c.destroy(); + break; + case types::e2node_cfg_upd_fail: + c.destroy(); + break; + case types::e2conn_upd_fail: + c.destroy(); + break; + case types::e2_removal_fail: + c.destroy(); + break; + default: + break; + } +} +void e2_ap_elem_procs_o::unsuccessful_outcome_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ricsubscription_fail: + c.init(); + break; + case types::ricsubscription_delete_fail: + c.init(); + break; + case types::ricservice_upd_fail: + c.init(); + break; + case types::ri_cctrl_fail: + c.init(); + break; + case types::e2setup_fail: + c.init(); + break; + case types::e2node_cfg_upd_fail: + c.init(); + break; + case types::e2conn_upd_fail: + c.init(); + break; + case types::e2_removal_fail: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + } +} +e2_ap_elem_procs_o::unsuccessful_outcome_c::unsuccessful_outcome_c( + const e2_ap_elem_procs_o::unsuccessful_outcome_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ricsubscription_fail: + c.init(other.c.get()); + break; + case types::ricsubscription_delete_fail: + c.init(other.c.get()); + break; + case types::ricservice_upd_fail: + c.init(other.c.get()); + break; + case types::ri_cctrl_fail: + c.init(other.c.get()); + break; + case types::e2setup_fail: + c.init(other.c.get()); + break; + case types::e2node_cfg_upd_fail: + c.init(other.c.get()); + break; + case types::e2conn_upd_fail: + c.init(other.c.get()); + break; + case types::e2_removal_fail: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + } +} +e2_ap_elem_procs_o::unsuccessful_outcome_c& +e2_ap_elem_procs_o::unsuccessful_outcome_c::operator=(const e2_ap_elem_procs_o::unsuccessful_outcome_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ricsubscription_fail: + c.set(other.c.get()); + break; + case types::ricsubscription_delete_fail: + c.set(other.c.get()); + break; + case types::ricservice_upd_fail: + c.set(other.c.get()); + break; + case types::ri_cctrl_fail: + c.set(other.c.get()); + break; + case types::e2setup_fail: + c.set(other.c.get()); + break; + case types::e2node_cfg_upd_fail: + c.set(other.c.get()); + break; + case types::e2conn_upd_fail: + c.set(other.c.get()); + break; + case types::e2_removal_fail: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + } + + return *this; +} +ricsubscription_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricsubscription_fail() +{ + assert_choice_type(types::ricsubscription_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +ricsubscription_delete_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricsubscription_delete_fail() +{ + assert_choice_type(types::ricsubscription_delete_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +ricservice_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricservice_upd_fail() +{ + assert_choice_type(types::ricservice_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +ri_cctrl_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ri_cctrl_fail() +{ + assert_choice_type(types::ri_cctrl_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +e2setup_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2setup_fail() +{ + assert_choice_type(types::e2setup_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +e2node_cfg_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2node_cfg_upd_fail() +{ + assert_choice_type(types::e2node_cfg_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +e2conn_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2conn_upd_fail() +{ + assert_choice_type(types::e2conn_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +e2_removal_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2_removal_fail() +{ + assert_choice_type(types::e2_removal_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const ricsubscription_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricsubscription_fail() const +{ + assert_choice_type(types::ricsubscription_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const ricsubscription_delete_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricsubscription_delete_fail() const +{ + assert_choice_type(types::ricsubscription_delete_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const ricservice_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ricservice_upd_fail() const +{ + assert_choice_type(types::ricservice_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const ri_cctrl_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::ri_cctrl_fail() const +{ + assert_choice_type(types::ri_cctrl_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const e2setup_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2setup_fail() const +{ + assert_choice_type(types::e2setup_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const e2node_cfg_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2node_cfg_upd_fail() const +{ + assert_choice_type(types::e2node_cfg_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const e2conn_upd_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2conn_upd_fail() const +{ + assert_choice_type(types::e2conn_upd_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +const e2_removal_fail_s& e2_ap_elem_procs_o::unsuccessful_outcome_c::e2_removal_fail() const +{ + assert_choice_type(types::e2_removal_fail, type_, "UnsuccessfulOutcome"); + return c.get(); +} +void e2_ap_elem_procs_o::unsuccessful_outcome_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ricsubscription_fail: + j.write_fieldname("RICsubscriptionFailure"); + c.get().to_json(j); + break; + case types::ricsubscription_delete_fail: + j.write_fieldname("RICsubscriptionDeleteFailure"); + c.get().to_json(j); + break; + case types::ricservice_upd_fail: + j.write_fieldname("RICserviceUpdateFailure"); + c.get().to_json(j); + break; + case types::ri_cctrl_fail: + j.write_fieldname("RICcontrolFailure"); + c.get().to_json(j); + break; + case types::e2setup_fail: + j.write_fieldname("E2setupFailure"); + c.get().to_json(j); + break; + case types::e2node_cfg_upd_fail: + j.write_fieldname("E2nodeConfigurationUpdateFailure"); + c.get().to_json(j); + break; + case types::e2conn_upd_fail: + j.write_fieldname("E2connectionUpdateFailure"); + c.get().to_json(j); + break; + case types::e2_removal_fail: + j.write_fieldname("E2RemovalFailure"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_ap_elem_procs_o::unsuccessful_outcome_c::pack(bit_ref& bref) const +{ + varlength_field_pack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricsubscription_delete_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ricservice_upd_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ri_cctrl_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2setup_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2node_cfg_upd_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2conn_upd_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e2_removal_fail: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_ap_elem_procs_o::unsuccessful_outcome_c::unpack(cbit_ref& bref) +{ + varlength_field_unpack_guard varlen_scope(bref, true); + switch (type_) { + case types::ricsubscription_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricsubscription_delete_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ricservice_upd_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ri_cctrl_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2setup_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2node_cfg_upd_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2conn_upd_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e2_removal_fail: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_elem_procs_o::unsuccessful_outcome_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::to_string() const +{ + static const char* options[] = {"RICsubscriptionFailure", + "RICsubscriptionDeleteFailure", + "RICserviceUpdateFailure", + "RICcontrolFailure", + "E2setupFailure", + "E2nodeConfigurationUpdateFailure", + "E2connectionUpdateFailure", + "E2RemovalFailure"}; + return convert_enum_idx(options, 8, value, "e2_ap_elem_procs_o::unsuccessful_outcome_c::types"); +} + +// InitiatingMessage ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +SRSASN_CODE init_msg_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, proc_code, (uint16_t)0u, (uint16_t)255u, false, true)); + warn_assert(crit != e2_ap_elem_procs_o::get_crit(proc_code), __func__, __LINE__); + HANDLE_CODE(crit.pack(bref)); + HANDLE_CODE(value.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE init_msg_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(proc_code, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(crit.unpack(bref)); + value = e2_ap_elem_procs_o::get_init_msg(proc_code); + HANDLE_CODE(value.unpack(bref)); + + return SRSASN_SUCCESS; +} +void init_msg_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("procedureCode", proc_code); + j.write_str("criticality", crit.to_string()); + j.write_fieldname("value"); + value.to_json(j); + j.end_obj(); +} +bool init_msg_s::load_info_obj(const uint16_t& proc_code_) +{ + if (not e2_ap_elem_procs_o::is_proc_code_valid(proc_code_)) { + return false; + } + proc_code = proc_code_; + crit = e2_ap_elem_procs_o::get_crit(proc_code); + value = e2_ap_elem_procs_o::get_init_msg(proc_code); + return value.type().value != e2_ap_elem_procs_o::init_msg_c::types_opts::nulltype; +} + +// SuccessfulOutcome ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +SRSASN_CODE successful_outcome_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, proc_code, (uint16_t)0u, (uint16_t)255u, false, true)); + warn_assert(crit != e2_ap_elem_procs_o::get_crit(proc_code), __func__, __LINE__); + HANDLE_CODE(crit.pack(bref)); + HANDLE_CODE(value.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE successful_outcome_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(proc_code, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(crit.unpack(bref)); + value = e2_ap_elem_procs_o::get_successful_outcome(proc_code); + HANDLE_CODE(value.unpack(bref)); + + return SRSASN_SUCCESS; +} +void successful_outcome_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("procedureCode", proc_code); + j.write_str("criticality", crit.to_string()); + j.write_fieldname("value"); + value.to_json(j); + j.end_obj(); +} +bool successful_outcome_s::load_info_obj(const uint16_t& proc_code_) +{ + if (not e2_ap_elem_procs_o::is_proc_code_valid(proc_code_)) { + return false; + } + proc_code = proc_code_; + crit = e2_ap_elem_procs_o::get_crit(proc_code); + value = e2_ap_elem_procs_o::get_successful_outcome(proc_code); + return value.type().value != e2_ap_elem_procs_o::successful_outcome_c::types_opts::nulltype; +} + +// UnsuccessfulOutcome ::= SEQUENCE{{E2AP-ELEMENTARY-PROCEDURE}} +SRSASN_CODE unsuccessful_outcome_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, proc_code, (uint16_t)0u, (uint16_t)255u, false, true)); + warn_assert(crit != e2_ap_elem_procs_o::get_crit(proc_code), __func__, __LINE__); + HANDLE_CODE(crit.pack(bref)); + HANDLE_CODE(value.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE unsuccessful_outcome_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(proc_code, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + HANDLE_CODE(crit.unpack(bref)); + value = e2_ap_elem_procs_o::get_unsuccessful_outcome(proc_code); + HANDLE_CODE(value.unpack(bref)); + + return SRSASN_SUCCESS; +} +void unsuccessful_outcome_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("procedureCode", proc_code); + j.write_str("criticality", crit.to_string()); + j.write_fieldname("value"); + value.to_json(j); + j.end_obj(); +} +bool unsuccessful_outcome_s::load_info_obj(const uint16_t& proc_code_) +{ + if (not e2_ap_elem_procs_o::is_proc_code_valid(proc_code_)) { + return false; + } + proc_code = proc_code_; + crit = e2_ap_elem_procs_o::get_crit(proc_code); + value = e2_ap_elem_procs_o::get_unsuccessful_outcome(proc_code); + return value.type().value != e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::nulltype; +} + +// E2AP-PDU ::= CHOICE +void e2_ap_pdu_c::destroy_() +{ + switch (type_) { + case types::init_msg: + c.destroy(); + break; + case types::successful_outcome: + c.destroy(); + break; + case types::unsuccessful_outcome: + c.destroy(); + break; + default: + break; + } +} +void e2_ap_pdu_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::init_msg: + c.init(); + break; + case types::successful_outcome: + c.init(); + break; + case types::unsuccessful_outcome: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + } +} +e2_ap_pdu_c::e2_ap_pdu_c(const e2_ap_pdu_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::init_msg: + c.init(other.c.get()); + break; + case types::successful_outcome: + c.init(other.c.get()); + break; + case types::unsuccessful_outcome: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + } +} +e2_ap_pdu_c& e2_ap_pdu_c::operator=(const e2_ap_pdu_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::init_msg: + c.set(other.c.get()); + break; + case types::successful_outcome: + c.set(other.c.get()); + break; + case types::unsuccessful_outcome: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + } + + return *this; +} +init_msg_s& e2_ap_pdu_c::set_init_msg() +{ + set(types::init_msg); + return c.get(); +} +successful_outcome_s& e2_ap_pdu_c::set_successful_outcome() +{ + set(types::successful_outcome); + return c.get(); +} +unsuccessful_outcome_s& e2_ap_pdu_c::set_unsuccessful_outcome() +{ + set(types::unsuccessful_outcome); + return c.get(); +} +void e2_ap_pdu_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::init_msg: + j.write_fieldname("initiatingMessage"); + c.get().to_json(j); + break; + case types::successful_outcome: + j.write_fieldname("successfulOutcome"); + c.get().to_json(j); + break; + case types::unsuccessful_outcome: + j.write_fieldname("unsuccessfulOutcome"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_ap_pdu_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::init_msg: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::successful_outcome: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::unsuccessful_outcome: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_ap_pdu_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::init_msg: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::successful_outcome: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::unsuccessful_outcome: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_ap_pdu_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_ap_pdu_c::types_opts::to_string() const +{ + static const char* options[] = {"initiatingMessage", "successfulOutcome", "unsuccessfulOutcome"}; + return convert_enum_idx(options, 3, value, "e2_ap_pdu_c::types"); +} + +// ProtocolIE-FieldPair{E2AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE{{E2AP-PROTOCOL-IES-PAIR}} +template +SRSASN_CODE protocol_ie_field_pair_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); + warn_assert(first_crit != ies_set_paramT_::get_first_crit(id), __func__, __LINE__); + HANDLE_CODE(first_crit.pack(bref)); + HANDLE_CODE(first_value.pack(bref)); + warn_assert(second_crit != ies_set_paramT_::get_second_crit(id), __func__, __LINE__); + HANDLE_CODE(second_crit.pack(bref)); + HANDLE_CODE(second_value.pack(bref)); + + return SRSASN_SUCCESS; +} +template +SRSASN_CODE protocol_ie_field_pair_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + HANDLE_CODE(first_crit.unpack(bref)); + first_value = ies_set_paramT_::get_first_value(id); + HANDLE_CODE(first_value.unpack(bref)); + HANDLE_CODE(second_crit.unpack(bref)); + second_value = ies_set_paramT_::get_second_value(id); + HANDLE_CODE(second_value.unpack(bref)); + + return SRSASN_SUCCESS; +} +template +void protocol_ie_field_pair_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("id", id); + j.write_str("firstCriticality", first_crit.to_string()); + j.write_str("secondCriticality", second_crit.to_string()); + j.end_obj(); +} +template +bool protocol_ie_field_pair_s::load_info_obj(const uint32_t& id_) +{ + if (not ies_set_paramT_::is_id_valid(id_)) { + return false; + } + id = id_; + first_crit = ies_set_paramT_::get_first_crit(id); + first_value = ies_set_paramT_::get_first_value(id); + second_crit = ies_set_paramT_::get_second_crit(id); + second_value = ies_set_paramT_::get_second_value(id); + return first_value.type().value != ies_set_paramT_::first_value_c::types_opts::nulltype and + second_value.type().value != ies_set_paramT_::second_value_c::types_opts::nulltype; +} diff --git a/lib/src/asn1/e2sm.cpp b/lib/src/asn1/e2sm.cpp new file mode 100644 index 0000000000..b3cafab1d4 --- /dev/null +++ b/lib/src/asn1/e2sm.cpp @@ -0,0 +1,3074 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/asn1/e2sm.h" +#include + +using namespace asn1; +using namespace asn1::e2sm; + +/******************************************************************************* + * Struct Methods + ******************************************************************************/ + +// EUTRA-CGI ::= SEQUENCE +SRSASN_CODE eutra_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(eutra_cell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE eutra_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(eutra_cell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void eutra_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("eUTRACellIdentity", eutra_cell_id.to_string()); + j.end_obj(); +} + +// NR-CGI ::= SEQUENCE +SRSASN_CODE nr_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(nrcell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(nrcell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void nr_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("nRCellIdentity", nrcell_id.to_string()); + j.end_obj(); +} + +// CGI ::= CHOICE +void cgi_c::destroy_() +{ + switch (type_) { + case types::nr_cgi: + c.destroy(); + break; + case types::eutra_cgi: + c.destroy(); + break; + default: + break; + } +} +void cgi_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr_cgi: + c.init(); + break; + case types::eutra_cgi: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c::cgi_c(const cgi_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr_cgi: + c.init(other.c.get()); + break; + case types::eutra_cgi: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c& cgi_c::operator=(const cgi_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr_cgi: + c.set(other.c.get()); + break; + case types::eutra_cgi: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + + return *this; +} +nr_cgi_s& cgi_c::set_nr_cgi() +{ + set(types::nr_cgi); + return c.get(); +} +eutra_cgi_s& cgi_c::set_eutra_cgi() +{ + set(types::eutra_cgi); + return c.get(); +} +void cgi_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr_cgi: + j.write_fieldname("nR-CGI"); + c.get().to_json(j); + break; + case types::eutra_cgi: + j.write_fieldname("eUTRA-CGI"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + j.end_obj(); +} +SRSASN_CODE cgi_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE cgi_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* cgi_c::types_opts::to_string() const +{ + static const char* options[] = {"nR-CGI", "eUTRA-CGI"}; + return convert_enum_idx(options, 2, value, "cgi_c::types"); +} + +// GUAMI ::= SEQUENCE +SRSASN_CODE guami_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(amf_region_id.pack(bref)); + HANDLE_CODE(amf_set_id.pack(bref)); + HANDLE_CODE(amf_pointer.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE guami_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(amf_region_id.unpack(bref)); + HANDLE_CODE(amf_set_id.unpack(bref)); + HANDLE_CODE(amf_pointer.unpack(bref)); + + return SRSASN_SUCCESS; +} +void guami_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("aMFRegionID", amf_region_id.to_string()); + j.write_str("aMFSetID", amf_set_id.to_string()); + j.write_str("aMFPointer", amf_pointer.to_string()); + j.end_obj(); +} + +// GUMMEI ::= SEQUENCE +SRSASN_CODE gummei_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(mme_group_id.pack(bref)); + HANDLE_CODE(mme_code.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE gummei_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(mme_group_id.unpack(bref)); + HANDLE_CODE(mme_code.unpack(bref)); + + return SRSASN_SUCCESS; +} +void gummei_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_str("mME-Group-ID", mme_group_id.to_string()); + j.write_str("mME-Code", mme_code.to_string()); + j.end_obj(); +} + +// CoreCPID ::= CHOICE +void core_cpid_c::destroy_() +{ + switch (type_) { + case types::five_gc: + c.destroy(); + break; + case types::epc: + c.destroy(); + break; + default: + break; + } +} +void core_cpid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::five_gc: + c.init(); + break; + case types::epc: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c::core_cpid_c(const core_cpid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c& core_cpid_c::operator=(const core_cpid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + + return *this; +} +guami_s& core_cpid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +gummei_s& core_cpid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void core_cpid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_fieldname("fiveGC"); + c.get().to_json(j); + break; + case types::epc: + j.write_fieldname("ePC"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + j.end_obj(); +} +SRSASN_CODE core_cpid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE core_cpid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* core_cpid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "core_cpid_c::types"); +} +uint8_t core_cpid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "core_cpid_c::types"); +} + +// ENB-ID ::= CHOICE +void enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_enb_id: + c.destroy >(); + break; + case types::home_enb_id: + c.destroy >(); + break; + case types::short_macro_enb_id: + c.destroy >(); + break; + case types::long_macro_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_enb_id: + c.init >(); + break; + case types::home_enb_id: + c.init >(); + break; + case types::short_macro_enb_id: + c.init >(); + break; + case types::long_macro_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c::enb_id_c(const enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_enb_id: + c.init(other.c.get >()); + break; + case types::home_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c& enb_id_c::operator=(const enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_enb_id: + c.set(other.c.get >()); + break; + case types::home_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_c::set_macro_enb_id() +{ + set(types::macro_enb_id); + return c.get >(); +} +fixed_bitstring<28, false, true>& enb_id_c::set_home_enb_id() +{ + set(types::home_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_c::set_short_macro_enb_id() +{ + set(types::short_macro_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_c::set_long_macro_enb_id() +{ + set(types::long_macro_enb_id); + return c.get >(); +} +void enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_enb_id: + j.write_str("macro-eNB-ID", c.get >().to_string()); + break; + case types::home_enb_id: + j.write_str("home-eNB-ID", c.get >().to_string()); + break; + case types::short_macro_enb_id: + j.write_str("short-Macro-eNB-ID", c.get >().to_string()); + break; + case types::long_macro_enb_id: + j.write_str("long-Macro-eNB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macro-eNB-ID", "home-eNB-ID", "short-Macro-eNB-ID", "long-Macro-eNB-ID"}; + return convert_enum_idx(options, 4, value, "enb_id_c::types"); +} + +// GlobalENB-ID ::= SEQUENCE +SRSASN_CODE global_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("eNB-ID"); + enb_id.to_json(j); + j.end_obj(); +} + +// GNB-ID ::= CHOICE +void gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB-ID"}; + return convert_enum_idx(options, 1, value, "gnb_id_c::types"); +} + +// GlobalGNB-ID ::= SEQUENCE +SRSASN_CODE global_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("gNB-ID"); + gnb_id.to_json(j); + j.end_obj(); +} + +// NgENB-ID ::= CHOICE +void ng_enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_ng_enb_id: + c.destroy >(); + break; + case types::short_macro_ng_enb_id: + c.destroy >(); + break; + case types::long_macro_ng_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void ng_enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_ng_enb_id: + c.init >(); + break; + case types::short_macro_ng_enb_id: + c.init >(); + break; + case types::long_macro_ng_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c::ng_enb_id_c(const ng_enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c& ng_enb_id_c::operator=(const ng_enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& ng_enb_id_c::set_macro_ng_enb_id() +{ + set(types::macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& ng_enb_id_c::set_short_macro_ng_enb_id() +{ + set(types::short_macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& ng_enb_id_c::set_long_macro_ng_enb_id() +{ + set(types::long_macro_ng_enb_id); + return c.get >(); +} +void ng_enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_ng_enb_id: + j.write_str("macroNgENB-ID", c.get >().to_string()); + break; + case types::short_macro_ng_enb_id: + j.write_str("shortMacroNgENB-ID", c.get >().to_string()); + break; + case types::long_macro_ng_enb_id: + j.write_str("longMacroNgENB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE ng_enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ng_enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ng_enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macroNgENB-ID", "shortMacroNgENB-ID", "longMacroNgENB-ID"}; + return convert_enum_idx(options, 3, value, "ng_enb_id_c::types"); +} + +// GlobalNgENB-ID ::= SEQUENCE +SRSASN_CODE global_ng_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(ng_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ng_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(ng_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_ng_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("ngENB-ID"); + ng_enb_id.to_json(j); + j.end_obj(); +} + +// GlobalRANNodeID ::= CHOICE +void global_ran_node_id_c::destroy_() +{ + switch (type_) { + case types::global_gnb_id: + c.destroy(); + break; + case types::global_ng_enb_id: + c.destroy(); + break; + default: + break; + } +} +void global_ran_node_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_gnb_id: + c.init(); + break; + case types::global_ng_enb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c::global_ran_node_id_c(const global_ran_node_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_gnb_id: + c.init(other.c.get()); + break; + case types::global_ng_enb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c& global_ran_node_id_c::operator=(const global_ran_node_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_gnb_id: + c.set(other.c.get()); + break; + case types::global_ng_enb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + + return *this; +} +global_gnb_id_s& global_ran_node_id_c::set_global_gnb_id() +{ + set(types::global_gnb_id); + return c.get(); +} +global_ng_enb_id_s& global_ran_node_id_c::set_global_ng_enb_id() +{ + set(types::global_ng_enb_id); + return c.get(); +} +void global_ran_node_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_gnb_id: + j.write_fieldname("globalGNB-ID"); + c.get().to_json(j); + break; + case types::global_ng_enb_id: + j.write_fieldname("globalNgENB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_ran_node_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ran_node_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_ran_node_id_c::types_opts::to_string() const +{ + static const char* options[] = {"globalGNB-ID", "globalNgENB-ID"}; + return convert_enum_idx(options, 2, value, "global_ran_node_id_c::types"); +} + +// EN-GNB-ID ::= CHOICE +void en_gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("en-gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE en_gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE en_gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "en_gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* en_gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"en-gNB-ID"}; + return convert_enum_idx(options, 1, value, "en_gnb_id_c::types"); +} + +// GlobalenGNB-ID ::= SEQUENCE +SRSASN_CODE globalen_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(en_g_nb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalen_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(en_g_nb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalen_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("en-gNB-ID"); + en_g_nb_id.to_json(j); + j.end_obj(); +} + +// GroupID ::= CHOICE +void group_id_c::destroy_() {} +void group_id_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +group_id_c::group_id_c(const group_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } +} +group_id_c& group_id_c::operator=(const group_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + + return *this; +} +uint16_t& group_id_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& group_id_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void group_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + j.end_obj(); +} +SRSASN_CODE group_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE group_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* group_id_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "group_id_c::types"); +} +uint8_t group_id_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "group_id_c::types"); +} + +// InterfaceID-E1 ::= SEQUENCE +SRSASN_CODE interface_id_e1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_e1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_e1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-CU-UP-ID", gnb_cu_up_id); + j.end_obj(); +} + +// InterfaceID-F1 ::= SEQUENCE +SRSASN_CODE interface_id_f1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_f1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_f1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-DU-ID", gnb_du_id); + j.end_obj(); +} + +// InterfaceID-NG ::= SEQUENCE +SRSASN_CODE interface_id_ng_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(guami.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_ng_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(guami.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_ng_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("guami"); + guami.to_json(j); + j.end_obj(); +} + +// InterfaceID-S1 ::= SEQUENCE +SRSASN_CODE interface_id_s1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(gummei.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_s1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(gummei.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_s1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + j.end_obj(); +} + +// InterfaceID-W1 ::= SEQUENCE +SRSASN_CODE interface_id_w1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_enb_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, ng_enb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_w1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + HANDLE_CODE(unpack_integer(ng_enb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_w1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-ng-eNB-ID"); + global_ng_enb_id.to_json(j); + j.write_int("ng-eNB-DU-ID", ng_enb_du_id); + j.end_obj(); +} + +// InterfaceID-X2 ::= SEQUENCE +SRSASN_CODE interface_id_x2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(node_type.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(node_type.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_x2_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("nodeType"); + node_type.to_json(j); + j.end_obj(); +} + +void interface_id_x2_s::node_type_c_::destroy_() +{ + switch (type_) { + case types::global_enb_id: + c.destroy(); + break; + case types::global_en_g_nb_id: + c.destroy(); + break; + default: + break; + } +} +void interface_id_x2_s::node_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_enb_id: + c.init(); + break; + case types::global_en_g_nb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_::node_type_c_(const interface_id_x2_s::node_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_enb_id: + c.init(other.c.get()); + break; + case types::global_en_g_nb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_& +interface_id_x2_s::node_type_c_::operator=(const interface_id_x2_s::node_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_enb_id: + c.set(other.c.get()); + break; + case types::global_en_g_nb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + + return *this; +} +global_enb_id_s& interface_id_x2_s::node_type_c_::set_global_enb_id() +{ + set(types::global_enb_id); + return c.get(); +} +globalen_gnb_id_s& interface_id_x2_s::node_type_c_::set_global_en_g_nb_id() +{ + set(types::global_en_g_nb_id); + return c.get(); +} +void interface_id_x2_s::node_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_enb_id: + j.write_fieldname("global-eNB-ID"); + c.get().to_json(j); + break; + case types::global_en_g_nb_id: + j.write_fieldname("global-en-gNB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_x2_s::node_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::node_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_x2_s::node_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"global-eNB-ID", "global-en-gNB-ID"}; + return convert_enum_idx(options, 2, value, "interface_id_x2_s::node_type_c_::types"); +} + +// InterfaceID-Xn ::= SEQUENCE +SRSASN_CODE interface_id_xn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_xn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_xn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.end_obj(); +} + +// InterfaceIdentifier ::= CHOICE +void interface_id_c::destroy_() +{ + switch (type_) { + case types::ng: + c.destroy(); + break; + case types::xn: + c.destroy(); + break; + case types::f1: + c.destroy(); + break; + case types::e1: + c.destroy(); + break; + case types::s1: + c.destroy(); + break; + case types::x2: + c.destroy(); + break; + case types::w1: + c.destroy(); + break; + default: + break; + } +} +void interface_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ng: + c.init(); + break; + case types::xn: + c.init(); + break; + case types::f1: + c.init(); + break; + case types::e1: + c.init(); + break; + case types::s1: + c.init(); + break; + case types::x2: + c.init(); + break; + case types::w1: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c::interface_id_c(const interface_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ng: + c.init(other.c.get()); + break; + case types::xn: + c.init(other.c.get()); + break; + case types::f1: + c.init(other.c.get()); + break; + case types::e1: + c.init(other.c.get()); + break; + case types::s1: + c.init(other.c.get()); + break; + case types::x2: + c.init(other.c.get()); + break; + case types::w1: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c& interface_id_c::operator=(const interface_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ng: + c.set(other.c.get()); + break; + case types::xn: + c.set(other.c.get()); + break; + case types::f1: + c.set(other.c.get()); + break; + case types::e1: + c.set(other.c.get()); + break; + case types::s1: + c.set(other.c.get()); + break; + case types::x2: + c.set(other.c.get()); + break; + case types::w1: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + + return *this; +} +interface_id_ng_s& interface_id_c::set_ng() +{ + set(types::ng); + return c.get(); +} +interface_id_xn_s& interface_id_c::set_xn() +{ + set(types::xn); + return c.get(); +} +interface_id_f1_s& interface_id_c::set_f1() +{ + set(types::f1); + return c.get(); +} +interface_id_e1_s& interface_id_c::set_e1() +{ + set(types::e1); + return c.get(); +} +interface_id_s1_s& interface_id_c::set_s1() +{ + set(types::s1); + return c.get(); +} +interface_id_x2_s& interface_id_c::set_x2() +{ + set(types::x2); + return c.get(); +} +interface_id_w1_s& interface_id_c::set_w1() +{ + set(types::w1); + return c.get(); +} +void interface_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ng: + j.write_fieldname("nG"); + c.get().to_json(j); + break; + case types::xn: + j.write_fieldname("xN"); + c.get().to_json(j); + break; + case types::f1: + j.write_fieldname("f1"); + c.get().to_json(j); + break; + case types::e1: + j.write_fieldname("e1"); + c.get().to_json(j); + break; + case types::s1: + j.write_fieldname("s1"); + c.get().to_json(j); + break; + case types::x2: + j.write_fieldname("x2"); + c.get().to_json(j); + break; + case types::w1: + j.write_fieldname("w1"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_c::types_opts::to_string() const +{ + static const char* options[] = {"nG", "xN", "f1", "e1", "s1", "x2", "w1"}; + return convert_enum_idx(options, 7, value, "interface_id_c::types"); +} + +// FreqBandNrItem ::= SEQUENCE +SRSASN_CODE freq_band_nr_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, freq_band_ind_nr, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE freq_band_nr_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(freq_band_ind_nr, bref, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +void freq_band_nr_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("freqBandIndicatorNr", freq_band_ind_nr); + j.end_obj(); +} + +// NR-ARFCN ::= SEQUENCE +SRSASN_CODE nr_arfcn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, nrarfcn, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list_nr, 1, 32, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_arfcn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(nrarfcn, bref, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(unpack_dyn_seq_of(freq_band_list_nr, bref, 1, 32, true)); + + return SRSASN_SUCCESS; +} +void nr_arfcn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("nRARFCN", nrarfcn); + j.start_array("freqBandListNr"); + for (const auto& e1 : freq_band_list_nr) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// QoSID ::= CHOICE +void qo_sid_c::destroy_() {} +void qo_sid_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +qo_sid_c::qo_sid_c(const qo_sid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } +} +qo_sid_c& qo_sid_c::operator=(const qo_sid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + + return *this; +} +uint16_t& qo_sid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& qo_sid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void qo_sid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + j.end_obj(); +} +SRSASN_CODE qo_sid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE qo_sid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* qo_sid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "qo_sid_c::types"); +} +uint8_t qo_sid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "qo_sid_c::types"); +} + +// RRCclass-LTE ::= ENUMERATED +const char* rr_cclass_lte_opts::to_string() const +{ + static const char* options[] = {"bCCH-BCH", + "bCCH-BCH-MBMS", + "bCCH-DL-SCH", + "bCCH-DL-SCH-BR", + "bCCH-DL-SCH-MBMS", + "mCCH", + "pCCH", + "dL-CCCH", + "dL-DCCH", + "uL-CCCH", + "uL-DCCH", + "sC-MCCH"}; + return convert_enum_idx(options, 12, value, "rr_cclass_lte_e"); +} + +// RRCclass-NR ::= ENUMERATED +const char* rr_cclass_nr_opts::to_string() const +{ + static const char* options[] = { + "bCCH-BCH", "bCCH-DL-SCH", "dL-CCCH", "dL-DCCH", "pCCH", "uL-CCCH", "uL-CCCH1", "uL-DCCH"}; + return convert_enum_idx(options, 8, value, "rr_cclass_nr_e"); +} +uint8_t rr_cclass_nr_opts::to_number() const +{ + if (value == ul_ccch1) { + return 1; + } + invalid_enum_number(value, "rr_cclass_nr_e"); + return 0; +} + +// RRC-MessageID ::= SEQUENCE +SRSASN_CODE rrc_msg_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(rrc_type.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, msg_id, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(rrc_type.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(msg_id, bref, false, true)); + + return SRSASN_SUCCESS; +} +void rrc_msg_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("rrcType"); + rrc_type.to_json(j); + j.write_int("messageID", msg_id); + j.end_obj(); +} + +void rrc_msg_id_s::rrc_type_c_::destroy_() {} +void rrc_msg_id_s::rrc_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +rrc_msg_id_s::rrc_type_c_::rrc_type_c_(const rrc_msg_id_s::rrc_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::lte: + c.init(other.c.get()); + break; + case types::nr: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } +} +rrc_msg_id_s::rrc_type_c_& rrc_msg_id_s::rrc_type_c_::operator=(const rrc_msg_id_s::rrc_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::lte: + c.set(other.c.get()); + break; + case types::nr: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + + return *this; +} +rr_cclass_lte_e& rrc_msg_id_s::rrc_type_c_::set_lte() +{ + set(types::lte); + return c.get(); +} +rr_cclass_nr_e& rrc_msg_id_s::rrc_type_c_::set_nr() +{ + set(types::nr); + return c.get(); +} +void rrc_msg_id_s::rrc_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::lte: + j.write_str("lTE", c.get().to_string()); + break; + case types::nr: + j.write_str("nR", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_msg_id_s::rrc_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"lTE", "nR"}; + return convert_enum_idx(options, 2, value, "rrc_msg_id_s::rrc_type_c_::types"); +} + +// S-NSSAI ::= SEQUENCE +SRSASN_CODE s_nssai_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(sd_present, 1)); + + HANDLE_CODE(sst.pack(bref)); + if (sd_present) { + HANDLE_CODE(sd.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE s_nssai_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(sd_present, 1)); + + HANDLE_CODE(sst.unpack(bref)); + if (sd_present) { + HANDLE_CODE(sd.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void s_nssai_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("sST", sst.to_string()); + if (sd_present) { + j.write_str("sD", sd.to_string()); + } + j.end_obj(); +} + +// ServingCell-ARFCN ::= CHOICE +void serving_cell_arfcn_c::destroy_() +{ + switch (type_) { + case types::nr: + c.destroy(); + break; + default: + break; + } +} +void serving_cell_arfcn_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr: + c.init(); + break; + case types::eutra: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c::serving_cell_arfcn_c(const serving_cell_arfcn_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c& serving_cell_arfcn_c::operator=(const serving_cell_arfcn_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + + return *this; +} +nr_arfcn_s& serving_cell_arfcn_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint32_t& serving_cell_arfcn_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_arfcn_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_fieldname("nR"); + c.get().to_json(j); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_arfcn_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_arfcn_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_arfcn_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_arfcn_c::types"); +} + +// ServingCell-PCI ::= CHOICE +void serving_cell_pci_c::destroy_() {} +void serving_cell_pci_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +serving_cell_pci_c::serving_cell_pci_c(const serving_cell_pci_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } +} +serving_cell_pci_c& serving_cell_pci_c::operator=(const serving_cell_pci_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + + return *this; +} +uint16_t& serving_cell_pci_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint16_t& serving_cell_pci_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_pci_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_int("nR", c.get()); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_pci_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_pci_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_pci_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_pci_c::types"); +} + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_e1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + j.end_obj(); +} + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_f1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + j.end_obj(); +} + +// UEID-EN-GNB ::= SEQUENCE +SRSASN_CODE ueid_en_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.pack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_en_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_en_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + if (gnb_cu_ue_f1_ap_id_present) { + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-ENB ::= SEQUENCE +SRSASN_CODE ueid_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(global_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, mme_ue_s1ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.pack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(global_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(mme_ue_s1ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.unpack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("mME-UE-S1AP-ID", mme_ue_s1ap_id); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + if (m_enb_ue_x2ap_id_present) { + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + } + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + if (global_enb_id_present) { + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB ::= SEQUENCE +SRSASN_CODE ueid_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_gnb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_ue_f1_ap_id_list, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool gnb_cu_ue_f1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_list_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_gnb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_ue_f1_ap_id_list, bref, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-UE-F1AP-ID-List"); + for (const auto& e1 : gnb_cu_ue_f1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_gnb_id_present) { + j.write_fieldname("globalGNB-ID"); + global_gnb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB-CU-UP ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_up_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_up_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_up_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-GNB-DU ::= SEQUENCE +SRSASN_CODE ueid_gnb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-NG-ENB ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (ng_enb_cu_ue_w1_ap_id_present) { + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_ng_enb_id_present) { + j.write_fieldname("globalNgENB-ID"); + global_ng_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-NG-ENB-DU ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + j.end_obj(); +} + +// UEID ::= CHOICE +void ueid_c::destroy_() +{ + switch (type_) { + case types::gnb_ueid: + c.destroy(); + break; + case types::gnb_du_ueid: + c.destroy(); + break; + case types::gnb_cu_up_ueid: + c.destroy(); + break; + case types::ng_enb_ueid: + c.destroy(); + break; + case types::ng_enb_du_ueid: + c.destroy(); + break; + case types::en_g_nb_ueid: + c.destroy(); + break; + case types::enb_ueid: + c.destroy(); + break; + default: + break; + } +} +void ueid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb_ueid: + c.init(); + break; + case types::gnb_du_ueid: + c.init(); + break; + case types::gnb_cu_up_ueid: + c.init(); + break; + case types::ng_enb_ueid: + c.init(); + break; + case types::ng_enb_du_ueid: + c.init(); + break; + case types::en_g_nb_ueid: + c.init(); + break; + case types::enb_ueid: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c::ueid_c(const ueid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb_ueid: + c.init(other.c.get()); + break; + case types::gnb_du_ueid: + c.init(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.init(other.c.get()); + break; + case types::en_g_nb_ueid: + c.init(other.c.get()); + break; + case types::enb_ueid: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c& ueid_c::operator=(const ueid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb_ueid: + c.set(other.c.get()); + break; + case types::gnb_du_ueid: + c.set(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.set(other.c.get()); + break; + case types::en_g_nb_ueid: + c.set(other.c.get()); + break; + case types::enb_ueid: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + + return *this; +} +ueid_gnb_s& ueid_c::set_gnb_ueid() +{ + set(types::gnb_ueid); + return c.get(); +} +ueid_gnb_du_s& ueid_c::set_gnb_du_ueid() +{ + set(types::gnb_du_ueid); + return c.get(); +} +ueid_gnb_cu_up_s& ueid_c::set_gnb_cu_up_ueid() +{ + set(types::gnb_cu_up_ueid); + return c.get(); +} +ueid_ng_enb_s& ueid_c::set_ng_enb_ueid() +{ + set(types::ng_enb_ueid); + return c.get(); +} +ueid_ng_enb_du_s& ueid_c::set_ng_enb_du_ueid() +{ + set(types::ng_enb_du_ueid); + return c.get(); +} +ueid_en_gnb_s& ueid_c::set_en_g_nb_ueid() +{ + set(types::en_g_nb_ueid); + return c.get(); +} +ueid_enb_s& ueid_c::set_enb_ueid() +{ + set(types::enb_ueid); + return c.get(); +} +void ueid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb_ueid: + j.write_fieldname("gNB-UEID"); + c.get().to_json(j); + break; + case types::gnb_du_ueid: + j.write_fieldname("gNB-DU-UEID"); + c.get().to_json(j); + break; + case types::gnb_cu_up_ueid: + j.write_fieldname("gNB-CU-UP-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_ueid: + j.write_fieldname("ng-eNB-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_du_ueid: + j.write_fieldname("ng-eNB-DU-UEID"); + c.get().to_json(j); + break; + case types::en_g_nb_ueid: + j.write_fieldname("en-gNB-UEID"); + c.get().to_json(j); + break; + case types::enb_ueid: + j.write_fieldname("eNB-UEID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + j.end_obj(); +} +SRSASN_CODE ueid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ueid_c::types_opts::to_string() const +{ + static const char* options[] = { + "gNB-UEID", "gNB-DU-UEID", "gNB-CU-UP-UEID", "ng-eNB-UEID", "ng-eNB-DU-UEID", "en-gNB-UEID", "eNB-UEID"}; + return convert_enum_idx(options, 7, value, "ueid_c::types"); +} diff --git a/lib/src/asn1/e2sm_kpm.cpp b/lib/src/asn1/e2sm_kpm.cpp new file mode 100644 index 0000000000..ba8eea9532 --- /dev/null +++ b/lib/src/asn1/e2sm_kpm.cpp @@ -0,0 +1,5189 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/asn1/e2sm_kpm.h" +#include + +using namespace asn1; +using namespace asn1::e2sm_kpm; + +/******************************************************************************* + * Struct Methods + ******************************************************************************/ + +// EUTRA-CGI ::= SEQUENCE +SRSASN_CODE eutra_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(eutra_cell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE eutra_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(eutra_cell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void eutra_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("eUTRACellIdentity", eutra_cell_id.to_string()); + j.end_obj(); +} + +// NR-CGI ::= SEQUENCE +SRSASN_CODE nr_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(nrcell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(nrcell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void nr_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("nRCellIdentity", nrcell_id.to_string()); + j.end_obj(); +} + +// CGI ::= CHOICE +void cgi_c::destroy_() +{ + switch (type_) { + case types::nr_cgi: + c.destroy(); + break; + case types::eutra_cgi: + c.destroy(); + break; + default: + break; + } +} +void cgi_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr_cgi: + c.init(); + break; + case types::eutra_cgi: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c::cgi_c(const cgi_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr_cgi: + c.init(other.c.get()); + break; + case types::eutra_cgi: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c& cgi_c::operator=(const cgi_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr_cgi: + c.set(other.c.get()); + break; + case types::eutra_cgi: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + + return *this; +} +nr_cgi_s& cgi_c::set_nr_cgi() +{ + set(types::nr_cgi); + return c.get(); +} +eutra_cgi_s& cgi_c::set_eutra_cgi() +{ + set(types::eutra_cgi); + return c.get(); +} +void cgi_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr_cgi: + j.write_fieldname("nR-CGI"); + c.get().to_json(j); + break; + case types::eutra_cgi: + j.write_fieldname("eUTRA-CGI"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + j.end_obj(); +} +SRSASN_CODE cgi_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE cgi_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* cgi_c::types_opts::to_string() const +{ + static const char* options[] = {"nR-CGI", "eUTRA-CGI"}; + return convert_enum_idx(options, 2, value, "cgi_c::types"); +} + +// FQIPERSlicesPerPlmnListItem ::= SEQUENCE +SRSASN_CODE fqiper_slices_per_plmn_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(pdcp_bytes_dl_present, 1)); + HANDLE_CODE(bref.pack(pdcp_bytes_ul_present, 1)); + + HANDLE_CODE(pack_integer(bref, five_qi, (uint16_t)0u, (uint16_t)255u, false, true)); + if (pdcp_bytes_dl_present) { + HANDLE_CODE(pack_integer(bref, pdcp_bytes_dl, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + if (pdcp_bytes_ul_present) { + HANDLE_CODE(pack_integer(bref, pdcp_bytes_ul, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE fqiper_slices_per_plmn_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(pdcp_bytes_dl_present, 1)); + HANDLE_CODE(bref.unpack(pdcp_bytes_ul_present, 1)); + + HANDLE_CODE(unpack_integer(five_qi, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + if (pdcp_bytes_dl_present) { + HANDLE_CODE(unpack_integer(pdcp_bytes_dl, bref, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + if (pdcp_bytes_ul_present) { + HANDLE_CODE(unpack_integer(pdcp_bytes_ul, bref, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + + return SRSASN_SUCCESS; +} +void fqiper_slices_per_plmn_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("fiveQI", five_qi); + if (pdcp_bytes_dl_present) { + j.write_int("pDCPBytesDL", pdcp_bytes_dl); + } + if (pdcp_bytes_ul_present) { + j.write_int("pDCPBytesUL", pdcp_bytes_ul); + } + j.end_obj(); +} + +// SNSSAI ::= SEQUENCE +SRSASN_CODE snssai_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(sd_present, 1)); + + HANDLE_CODE(sst.pack(bref)); + if (sd_present) { + HANDLE_CODE(sd.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE snssai_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(sd_present, 1)); + + HANDLE_CODE(sst.unpack(bref)); + if (sd_present) { + HANDLE_CODE(sd.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void snssai_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("sST", sst.to_string()); + if (sd_present) { + j.write_str("sD", sd.to_string()); + } + j.end_obj(); +} + +// PerQCIReportListItemFormat ::= SEQUENCE +SRSASN_CODE per_qci_report_list_item_format_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(pdcp_bytes_dl_present, 1)); + HANDLE_CODE(bref.pack(pdcp_bytes_ul_present, 1)); + + HANDLE_CODE(pack_integer(bref, qci, (uint16_t)0u, (uint16_t)255u, false, true)); + if (pdcp_bytes_dl_present) { + HANDLE_CODE(pack_integer(bref, pdcp_bytes_dl, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + if (pdcp_bytes_ul_present) { + HANDLE_CODE(pack_integer(bref, pdcp_bytes_ul, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE per_qci_report_list_item_format_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(pdcp_bytes_dl_present, 1)); + HANDLE_CODE(bref.unpack(pdcp_bytes_ul_present, 1)); + + HANDLE_CODE(unpack_integer(qci, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + if (pdcp_bytes_dl_present) { + HANDLE_CODE(unpack_integer(pdcp_bytes_dl, bref, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + if (pdcp_bytes_ul_present) { + HANDLE_CODE(unpack_integer(pdcp_bytes_ul, bref, (uint64_t)0u, (uint64_t)10000000000u, true, true)); + } + + return SRSASN_SUCCESS; +} +void per_qci_report_list_item_format_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("qci", qci); + if (pdcp_bytes_dl_present) { + j.write_int("pDCPBytesDL", pdcp_bytes_dl); + } + if (pdcp_bytes_ul_present) { + j.write_int("pDCPBytesUL", pdcp_bytes_ul); + } + j.end_obj(); +} + +// SliceToReportListItem ::= SEQUENCE +SRSASN_CODE slice_to_report_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(slice_id.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, fqiper_slices_per_plmn_list, 1, 64, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE slice_to_report_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(slice_id.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(fqiper_slices_per_plmn_list, bref, 1, 64, true)); + + return SRSASN_SUCCESS; +} +void slice_to_report_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("sliceID"); + slice_id.to_json(j); + j.start_array("fQIPERSlicesPerPlmnList"); + for (const auto& e1 : fqiper_slices_per_plmn_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// EPC-CUUP-PM-Format ::= SEQUENCE +SRSASN_CODE epc_cuup_pm_format_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, per_qci_report_list, 1, 256, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE epc_cuup_pm_format_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(per_qci_report_list, bref, 1, 256, true)); + + return SRSASN_SUCCESS; +} +void epc_cuup_pm_format_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("perQCIReportList"); + for (const auto& e1 : per_qci_report_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// FGC-CUUP-PM-Format ::= SEQUENCE +SRSASN_CODE fgc_cuup_pm_format_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, slice_to_report_list, 1, 1024, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE fgc_cuup_pm_format_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(slice_to_report_list, bref, 1, 1024, true)); + + return SRSASN_SUCCESS; +} +void fgc_cuup_pm_format_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("sliceToReportList"); + for (const auto& e1 : slice_to_report_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// PlmnID-List ::= SEQUENCE +SRSASN_CODE plmn_id_list_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(cu_up_pm_minus5_gc_present, 1)); + HANDLE_CODE(bref.pack(cu_up_pm_epc_present, 1)); + + HANDLE_CODE(plmn_id.pack(bref)); + if (cu_up_pm_minus5_gc_present) { + HANDLE_CODE(cu_up_pm_minus5_gc.pack(bref)); + } + if (cu_up_pm_epc_present) { + HANDLE_CODE(cu_up_pm_epc.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE plmn_id_list_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(cu_up_pm_minus5_gc_present, 1)); + HANDLE_CODE(bref.unpack(cu_up_pm_epc_present, 1)); + + HANDLE_CODE(plmn_id.unpack(bref)); + if (cu_up_pm_minus5_gc_present) { + HANDLE_CODE(cu_up_pm_minus5_gc.unpack(bref)); + } + if (cu_up_pm_epc_present) { + HANDLE_CODE(cu_up_pm_epc.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void plmn_id_list_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + if (cu_up_pm_minus5_gc_present) { + j.write_fieldname("cu-UP-PM-5GC"); + cu_up_pm_minus5_gc.to_json(j); + } + if (cu_up_pm_epc_present) { + j.write_fieldname("cu-UP-PM-EPC"); + cu_up_pm_epc.to_json(j); + } + j.end_obj(); +} + +// CUUPMeasurement-Container ::= SEQUENCE +SRSASN_CODE cuup_meas_container_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, plmn_list, 1, 12, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cuup_meas_container_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(plmn_list, bref, 1, 12, true)); + + return SRSASN_SUCCESS; +} +void cuup_meas_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("plmnList"); + for (const auto& e1 : plmn_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// FQIPERSlicesPerPlmnPerCellListItem ::= SEQUENCE +SRSASN_CODE fqiper_slices_per_plmn_per_cell_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(dl_prbusage_present, 1)); + HANDLE_CODE(bref.pack(ul_prbusage_present, 1)); + + HANDLE_CODE(pack_integer(bref, five_qi, (uint16_t)0u, (uint16_t)255u, false, true)); + if (dl_prbusage_present) { + HANDLE_CODE(pack_integer(bref, dl_prbusage, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_prbusage_present) { + HANDLE_CODE(pack_integer(bref, ul_prbusage, (uint8_t)0u, (uint8_t)100u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE fqiper_slices_per_plmn_per_cell_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(dl_prbusage_present, 1)); + HANDLE_CODE(bref.unpack(ul_prbusage_present, 1)); + + HANDLE_CODE(unpack_integer(five_qi, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + if (dl_prbusage_present) { + HANDLE_CODE(unpack_integer(dl_prbusage, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_prbusage_present) { + HANDLE_CODE(unpack_integer(ul_prbusage, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + + return SRSASN_SUCCESS; +} +void fqiper_slices_per_plmn_per_cell_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("fiveQI", five_qi); + if (dl_prbusage_present) { + j.write_int("dl-PRBUsage", dl_prbusage); + } + if (ul_prbusage_present) { + j.write_int("ul-PRBUsage", ul_prbusage); + } + j.end_obj(); +} + +// PerQCIReportListItem ::= SEQUENCE +SRSASN_CODE per_qci_report_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(dl_prbusage_present, 1)); + HANDLE_CODE(bref.pack(ul_prbusage_present, 1)); + + HANDLE_CODE(pack_integer(bref, qci, (uint16_t)0u, (uint16_t)255u, false, true)); + if (dl_prbusage_present) { + HANDLE_CODE(pack_integer(bref, dl_prbusage, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_prbusage_present) { + HANDLE_CODE(pack_integer(bref, ul_prbusage, (uint8_t)0u, (uint8_t)100u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE per_qci_report_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(dl_prbusage_present, 1)); + HANDLE_CODE(bref.unpack(ul_prbusage_present, 1)); + + HANDLE_CODE(unpack_integer(qci, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + if (dl_prbusage_present) { + HANDLE_CODE(unpack_integer(dl_prbusage, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_prbusage_present) { + HANDLE_CODE(unpack_integer(ul_prbusage, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + + return SRSASN_SUCCESS; +} +void per_qci_report_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("qci", qci); + if (dl_prbusage_present) { + j.write_int("dl-PRBUsage", dl_prbusage); + } + if (ul_prbusage_present) { + j.write_int("ul-PRBUsage", ul_prbusage); + } + j.end_obj(); +} + +// SlicePerPlmnPerCellListItem ::= SEQUENCE +SRSASN_CODE slice_per_plmn_per_cell_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(slice_id.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, fqiper_slices_per_plmn_per_cell_list, 1, 64, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE slice_per_plmn_per_cell_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(slice_id.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(fqiper_slices_per_plmn_per_cell_list, bref, 1, 64, true)); + + return SRSASN_SUCCESS; +} +void slice_per_plmn_per_cell_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("sliceID"); + slice_id.to_json(j); + j.start_array("fQIPERSlicesPerPlmnPerCellList"); + for (const auto& e1 : fqiper_slices_per_plmn_per_cell_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// EPC-DU-PM-Container ::= SEQUENCE +SRSASN_CODE epc_du_pm_container_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, per_qci_report_list, 1, 256, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE epc_du_pm_container_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(per_qci_report_list, bref, 1, 256, true)); + + return SRSASN_SUCCESS; +} +void epc_du_pm_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("perQCIReportList"); + for (const auto& e1 : per_qci_report_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// FGC-DU-PM-Container ::= SEQUENCE +SRSASN_CODE fgc_du_pm_container_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, slice_per_plmn_per_cell_list, 1, 1024, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE fgc_du_pm_container_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(slice_per_plmn_per_cell_list, bref, 1, 1024, true)); + + return SRSASN_SUCCESS; +} +void fgc_du_pm_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("slicePerPlmnPerCellList"); + for (const auto& e1 : slice_per_plmn_per_cell_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// NRCGI ::= SEQUENCE +SRSASN_CODE nrcgi_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(nrcell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nrcgi_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(nrcell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void nrcgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_str("nRCellIdentity", nrcell_id.to_string()); + j.end_obj(); +} + +// ServedPlmnPerCellListItem ::= SEQUENCE +SRSASN_CODE served_plmn_per_cell_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(du_pm_minus5_gc_present, 1)); + HANDLE_CODE(bref.pack(du_pm_epc_present, 1)); + + HANDLE_CODE(plmn_id.pack(bref)); + if (du_pm_minus5_gc_present) { + HANDLE_CODE(du_pm_minus5_gc.pack(bref)); + } + if (du_pm_epc_present) { + HANDLE_CODE(du_pm_epc.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE served_plmn_per_cell_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(du_pm_minus5_gc_present, 1)); + HANDLE_CODE(bref.unpack(du_pm_epc_present, 1)); + + HANDLE_CODE(plmn_id.unpack(bref)); + if (du_pm_minus5_gc_present) { + HANDLE_CODE(du_pm_minus5_gc.unpack(bref)); + } + if (du_pm_epc_present) { + HANDLE_CODE(du_pm_epc.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void served_plmn_per_cell_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + if (du_pm_minus5_gc_present) { + j.write_fieldname("du-PM-5GC"); + du_pm_minus5_gc.to_json(j); + } + if (du_pm_epc_present) { + j.write_fieldname("du-PM-EPC"); + du_pm_epc.to_json(j); + } + j.end_obj(); +} + +// CellResourceReportListItem ::= SEQUENCE +SRSASN_CODE cell_res_report_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(dl_totalof_available_prbs_present, 1)); + HANDLE_CODE(bref.pack(ul_totalof_available_prbs_present, 1)); + + HANDLE_CODE(nrcgi.pack(bref)); + if (dl_totalof_available_prbs_present) { + HANDLE_CODE(pack_integer(bref, dl_totalof_available_prbs, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_totalof_available_prbs_present) { + HANDLE_CODE(pack_integer(bref, ul_totalof_available_prbs, (uint8_t)0u, (uint8_t)100u, false, true)); + } + HANDLE_CODE(pack_dyn_seq_of(bref, served_plmn_per_cell_list, 1, 12, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cell_res_report_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(dl_totalof_available_prbs_present, 1)); + HANDLE_CODE(bref.unpack(ul_totalof_available_prbs_present, 1)); + + HANDLE_CODE(nrcgi.unpack(bref)); + if (dl_totalof_available_prbs_present) { + HANDLE_CODE(unpack_integer(dl_totalof_available_prbs, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + if (ul_totalof_available_prbs_present) { + HANDLE_CODE(unpack_integer(ul_totalof_available_prbs, bref, (uint8_t)0u, (uint8_t)100u, false, true)); + } + HANDLE_CODE(unpack_dyn_seq_of(served_plmn_per_cell_list, bref, 1, 12, true)); + + return SRSASN_SUCCESS; +} +void cell_res_report_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("nRCGI"); + nrcgi.to_json(j); + if (dl_totalof_available_prbs_present) { + j.write_int("dl-TotalofAvailablePRBs", dl_totalof_available_prbs); + } + if (ul_totalof_available_prbs_present) { + j.write_int("ul-TotalofAvailablePRBs", ul_totalof_available_prbs); + } + j.start_array("servedPlmnPerCellList"); + for (const auto& e1 : served_plmn_per_cell_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// GUAMI ::= SEQUENCE +SRSASN_CODE guami_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(amf_region_id.pack(bref)); + HANDLE_CODE(amf_set_id.pack(bref)); + HANDLE_CODE(amf_pointer.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE guami_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(amf_region_id.unpack(bref)); + HANDLE_CODE(amf_set_id.unpack(bref)); + HANDLE_CODE(amf_pointer.unpack(bref)); + + return SRSASN_SUCCESS; +} +void guami_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("aMFRegionID", amf_region_id.to_string()); + j.write_str("aMFSetID", amf_set_id.to_string()); + j.write_str("aMFPointer", amf_pointer.to_string()); + j.end_obj(); +} + +// GUMMEI ::= SEQUENCE +SRSASN_CODE gummei_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(mme_group_id.pack(bref)); + HANDLE_CODE(mme_code.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE gummei_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(mme_group_id.unpack(bref)); + HANDLE_CODE(mme_code.unpack(bref)); + + return SRSASN_SUCCESS; +} +void gummei_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_str("mME-Group-ID", mme_group_id.to_string()); + j.write_str("mME-Code", mme_code.to_string()); + j.end_obj(); +} + +// CoreCPID ::= CHOICE +void core_cpid_c::destroy_() +{ + switch (type_) { + case types::five_gc: + c.destroy(); + break; + case types::epc: + c.destroy(); + break; + default: + break; + } +} +void core_cpid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::five_gc: + c.init(); + break; + case types::epc: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c::core_cpid_c(const core_cpid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c& core_cpid_c::operator=(const core_cpid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + + return *this; +} +guami_s& core_cpid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +gummei_s& core_cpid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void core_cpid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_fieldname("fiveGC"); + c.get().to_json(j); + break; + case types::epc: + j.write_fieldname("ePC"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + j.end_obj(); +} +SRSASN_CODE core_cpid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE core_cpid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* core_cpid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "core_cpid_c::types"); +} +uint8_t core_cpid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "core_cpid_c::types"); +} + +// E2SM-KPM-e2_sm_kpm_action_definition_s ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_style_type, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_style_type, bref, false, true)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-Style-Type", ric_style_type); + j.end_obj(); +} + +// RT-Period-IE ::= ENUMERATED +const char* rt_period_ie_opts::to_string() const +{ + static const char* options[] = {"ms10", "ms20", "ms32", "ms40", "ms60", "ms64", "ms70", + "ms80", "ms128", "ms160", "ms256", "ms320", "ms512", "ms640", + "ms1024", "ms1280", "ms2048", "ms2560", "ms5120", "ms10240"}; + return convert_enum_idx(options, 20, value, "rt_period_ie_e"); +} +uint16_t rt_period_ie_opts::to_number() const +{ + static const uint16_t options[] = {10, 20, 32, 40, 60, 64, 70, 80, 128, 160, + 256, 320, 512, 640, 1024, 1280, 2048, 2560, 5120, 10240}; + return map_enum_number(options, 20, value, "rt_period_ie_e"); +} + +// Trigger-ConditionIE-Item ::= SEQUENCE +SRSASN_CODE trigger_condition_ie_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(report_period_ie.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE trigger_condition_ie_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(report_period_ie.unpack(bref)); + + return SRSASN_SUCCESS; +} +void trigger_condition_ie_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("report-Period-IE", report_period_ie.to_string()); + j.end_obj(); +} + +// E2SM-KPM-EventTriggerDefinition-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_event_trigger_definition_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(policy_test_list.size() > 0, 1)); + + if (policy_test_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, policy_test_list, 1, 15, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool policy_test_list_present; + HANDLE_CODE(bref.unpack(policy_test_list_present, 1)); + + if (policy_test_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(policy_test_list, bref, 1, 15, true)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_event_trigger_definition_format1_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (policy_test_list.size() > 0) { + j.start_array("policyTest-List"); + for (const auto& e1 : policy_test_list) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// E2SM-KPM-EventTriggerDefinition ::= CHOICE +void e2_sm_kpm_event_trigger_definition_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("eventDefinition-Format1"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "e2_sm_kpm_event_trigger_definition_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_event_trigger_definition_c::types_opts::to_string() const +{ + static const char* options[] = {"eventDefinition-Format1"}; + return convert_enum_idx(options, 1, value, "e2_sm_kpm_event_trigger_definition_c::types"); +} +uint8_t e2_sm_kpm_event_trigger_definition_c::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "e2_sm_kpm_event_trigger_definition_c::types"); +} + +// ENB-ID ::= CHOICE +void enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_enb_id: + c.destroy >(); + break; + case types::home_enb_id: + c.destroy >(); + break; + case types::short_macro_enb_id: + c.destroy >(); + break; + case types::long_macro_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_enb_id: + c.init >(); + break; + case types::home_enb_id: + c.init >(); + break; + case types::short_macro_enb_id: + c.init >(); + break; + case types::long_macro_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c::enb_id_c(const enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_enb_id: + c.init(other.c.get >()); + break; + case types::home_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c& enb_id_c::operator=(const enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_enb_id: + c.set(other.c.get >()); + break; + case types::home_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_c::set_macro_enb_id() +{ + set(types::macro_enb_id); + return c.get >(); +} +fixed_bitstring<28, false, true>& enb_id_c::set_home_enb_id() +{ + set(types::home_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_c::set_short_macro_enb_id() +{ + set(types::short_macro_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_c::set_long_macro_enb_id() +{ + set(types::long_macro_enb_id); + return c.get >(); +} +void enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_enb_id: + j.write_str("macro-eNB-ID", c.get >().to_string()); + break; + case types::home_enb_id: + j.write_str("home-eNB-ID", c.get >().to_string()); + break; + case types::short_macro_enb_id: + j.write_str("short-Macro-eNB-ID", c.get >().to_string()); + break; + case types::long_macro_enb_id: + j.write_str("long-Macro-eNB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macro-eNB-ID", "home-eNB-ID", "short-Macro-eNB-ID", "long-Macro-eNB-ID"}; + return convert_enum_idx(options, 4, value, "enb_id_c::types"); +} + +// ENB-ID-Choice ::= CHOICE +void enb_id_choice_c::destroy_() +{ + switch (type_) { + case types::enb_id_macro: + c.destroy >(); + break; + case types::enb_id_shortmacro: + c.destroy >(); + break; + case types::enb_id_longmacro: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_choice_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::enb_id_macro: + c.init >(); + break; + case types::enb_id_shortmacro: + c.init >(); + break; + case types::enb_id_longmacro: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } +} +enb_id_choice_c::enb_id_choice_c(const enb_id_choice_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::enb_id_macro: + c.init(other.c.get >()); + break; + case types::enb_id_shortmacro: + c.init(other.c.get >()); + break; + case types::enb_id_longmacro: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } +} +enb_id_choice_c& enb_id_choice_c::operator=(const enb_id_choice_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::enb_id_macro: + c.set(other.c.get >()); + break; + case types::enb_id_shortmacro: + c.set(other.c.get >()); + break; + case types::enb_id_longmacro: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_choice_c::set_enb_id_macro() +{ + set(types::enb_id_macro); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_choice_c::set_enb_id_shortmacro() +{ + set(types::enb_id_shortmacro); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_choice_c::set_enb_id_longmacro() +{ + set(types::enb_id_longmacro); + return c.get >(); +} +void enb_id_choice_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::enb_id_macro: + j.write_str("enb-ID-macro", c.get >().to_string()); + break; + case types::enb_id_shortmacro: + j.write_str("enb-ID-shortmacro", c.get >().to_string()); + break; + case types::enb_id_longmacro: + j.write_str("enb-ID-longmacro", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_choice_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::enb_id_macro: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::enb_id_shortmacro: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::enb_id_longmacro: + HANDLE_CODE((c.get >().pack(bref))); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_choice_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::enb_id_macro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::enb_id_shortmacro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::enb_id_longmacro: + HANDLE_CODE((c.get >().unpack(bref))); + break; + default: + log_invalid_choice_id(type_, "enb_id_choice_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_choice_c::types_opts::to_string() const +{ + static const char* options[] = {"enb-ID-macro", "enb-ID-shortmacro", "enb-ID-longmacro"}; + return convert_enum_idx(options, 3, value, "enb_id_choice_c::types"); +} + +// ENGNB-ID ::= CHOICE +void engnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE engnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE engnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "engnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* engnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB-ID"}; + return convert_enum_idx(options, 1, value, "engnb_id_c::types"); +} + +// GNB-ID-Choice ::= CHOICE +void gnb_id_choice_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gnb-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE gnb_id_choice_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE gnb_id_choice_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "gnb_id_choice_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* gnb_id_choice_c::types_opts::to_string() const +{ + static const char* options[] = {"gnb-ID"}; + return convert_enum_idx(options, 1, value, "gnb_id_choice_c::types"); +} + +// GlobalENB-ID ::= SEQUENCE +SRSASN_CODE global_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("eNB-ID"); + enb_id.to_json(j); + j.end_obj(); +} + +// GlobalenGNB-ID ::= SEQUENCE +SRSASN_CODE globalen_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalen_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalen_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("gNB-ID"); + gnb_id.to_json(j); + j.end_obj(); +} + +// GlobalgNB-ID ::= SEQUENCE +SRSASN_CODE globalg_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalg_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalg_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("plmn-id", plmn_id.to_string()); + j.write_fieldname("gnb-id"); + gnb_id.to_json(j); + j.end_obj(); +} + +// GlobalngeNB-ID ::= SEQUENCE +SRSASN_CODE globalngenb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalngenb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalngenb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("plmn-id", plmn_id.to_string()); + j.write_fieldname("enb-id"); + enb_id.to_json(j); + j.end_obj(); +} + +// GlobalKPMnode-eNB-ID ::= SEQUENCE +SRSASN_CODE global_kp_mnode_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_kp_mnode_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_kp_mnode_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-eNB-ID"); + global_enb_id.to_json(j); + j.end_obj(); +} + +// GlobalKPMnode-en-gNB-ID ::= SEQUENCE +SRSASN_CODE global_kp_mnode_en_g_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_g_nb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_kp_mnode_en_g_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_g_nb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_kp_mnode_en_g_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-gNB-ID"); + global_g_nb_id.to_json(j); + j.end_obj(); +} + +// GlobalKPMnode-gNB-ID ::= SEQUENCE +SRSASN_CODE global_kp_mnode_g_nb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(gnb_cu_up_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_du_id_present, 1)); + + HANDLE_CODE(global_g_nb_id.pack(bref)); + if (gnb_cu_up_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (gnb_du_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_kp_mnode_g_nb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(gnb_cu_up_id_present, 1)); + HANDLE_CODE(bref.unpack(gnb_du_id_present, 1)); + + HANDLE_CODE(global_g_nb_id.unpack(bref)); + if (gnb_cu_up_id_present) { + HANDLE_CODE(unpack_integer(gnb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + if (gnb_du_id_present) { + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + } + + return SRSASN_SUCCESS; +} +void global_kp_mnode_g_nb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-gNB-ID"); + global_g_nb_id.to_json(j); + if (gnb_cu_up_id_present) { + j.write_int("gNB-CU-UP-ID", gnb_cu_up_id); + } + if (gnb_du_id_present) { + j.write_int("gNB-DU-ID", gnb_du_id); + } + j.end_obj(); +} + +// GlobalKPMnode-ng-eNB-ID ::= SEQUENCE +SRSASN_CODE global_kp_mnode_ng_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_kp_mnode_ng_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_kp_mnode_ng_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-ng-eNB-ID"); + global_ng_enb_id.to_json(j); + j.end_obj(); +} + +// GlobalKPMnode-ID ::= CHOICE +void global_kp_mnode_id_c::destroy_() +{ + switch (type_) { + case types::gnb: + c.destroy(); + break; + case types::en_g_nb: + c.destroy(); + break; + case types::ng_enb: + c.destroy(); + break; + case types::enb: + c.destroy(); + break; + default: + break; + } +} +void global_kp_mnode_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb: + c.init(); + break; + case types::en_g_nb: + c.init(); + break; + case types::ng_enb: + c.init(); + break; + case types::enb: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + } +} +global_kp_mnode_id_c::global_kp_mnode_id_c(const global_kp_mnode_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb: + c.init(other.c.get()); + break; + case types::en_g_nb: + c.init(other.c.get()); + break; + case types::ng_enb: + c.init(other.c.get()); + break; + case types::enb: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + } +} +global_kp_mnode_id_c& global_kp_mnode_id_c::operator=(const global_kp_mnode_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb: + c.set(other.c.get()); + break; + case types::en_g_nb: + c.set(other.c.get()); + break; + case types::ng_enb: + c.set(other.c.get()); + break; + case types::enb: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + } + + return *this; +} +global_kp_mnode_g_nb_id_s& global_kp_mnode_id_c::set_gnb() +{ + set(types::gnb); + return c.get(); +} +global_kp_mnode_en_g_nb_id_s& global_kp_mnode_id_c::set_en_g_nb() +{ + set(types::en_g_nb); + return c.get(); +} +global_kp_mnode_ng_enb_id_s& global_kp_mnode_id_c::set_ng_enb() +{ + set(types::ng_enb); + return c.get(); +} +global_kp_mnode_enb_id_s& global_kp_mnode_id_c::set_enb() +{ + set(types::enb); + return c.get(); +} +void global_kp_mnode_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb: + j.write_fieldname("gNB"); + c.get().to_json(j); + break; + case types::en_g_nb: + j.write_fieldname("en-gNB"); + c.get().to_json(j); + break; + case types::ng_enb: + j.write_fieldname("ng-eNB"); + c.get().to_json(j); + break; + case types::enb: + j.write_fieldname("eNB"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_kp_mnode_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::en_g_nb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::enb: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_kp_mnode_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::en_g_nb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::enb: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_kp_mnode_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_kp_mnode_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB", "en-gNB", "ng-eNB", "eNB"}; + return convert_enum_idx(options, 4, value, "global_kp_mnode_id_c::types"); +} + +// E2SM-KPM-IndicationHeader-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_hdr_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(id_global_kp_mnode_id_present, 1)); + HANDLE_CODE(bref.pack(nrcgi_present, 1)); + HANDLE_CODE(bref.pack(plmn_id_present, 1)); + HANDLE_CODE(bref.pack(slice_id_present, 1)); + HANDLE_CODE(bref.pack(five_qi_present, 1)); + HANDLE_CODE(bref.pack(qci_present, 1)); + + if (id_global_kp_mnode_id_present) { + HANDLE_CODE(id_global_kp_mnode_id.pack(bref)); + } + if (nrcgi_present) { + HANDLE_CODE(nrcgi.pack(bref)); + } + if (plmn_id_present) { + HANDLE_CODE(plmn_id.pack(bref)); + } + if (slice_id_present) { + HANDLE_CODE(slice_id.pack(bref)); + } + if (five_qi_present) { + HANDLE_CODE(pack_integer(bref, five_qi, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qci_present) { + HANDLE_CODE(pack_integer(bref, qci, (uint16_t)0u, (uint16_t)255u, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_hdr_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(id_global_kp_mnode_id_present, 1)); + HANDLE_CODE(bref.unpack(nrcgi_present, 1)); + HANDLE_CODE(bref.unpack(plmn_id_present, 1)); + HANDLE_CODE(bref.unpack(slice_id_present, 1)); + HANDLE_CODE(bref.unpack(five_qi_present, 1)); + HANDLE_CODE(bref.unpack(qci_present, 1)); + + if (id_global_kp_mnode_id_present) { + HANDLE_CODE(id_global_kp_mnode_id.unpack(bref)); + } + if (nrcgi_present) { + HANDLE_CODE(nrcgi.unpack(bref)); + } + if (plmn_id_present) { + HANDLE_CODE(plmn_id.unpack(bref)); + } + if (slice_id_present) { + HANDLE_CODE(slice_id.unpack(bref)); + } + if (five_qi_present) { + HANDLE_CODE(unpack_integer(five_qi, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qci_present) { + HANDLE_CODE(unpack_integer(qci, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_hdr_format1_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (id_global_kp_mnode_id_present) { + j.write_fieldname("id-GlobalKPMnode-ID"); + id_global_kp_mnode_id.to_json(j); + } + if (nrcgi_present) { + j.write_fieldname("nRCGI"); + nrcgi.to_json(j); + } + if (plmn_id_present) { + j.write_str("pLMN-Identity", plmn_id.to_string()); + } + if (slice_id_present) { + j.write_fieldname("sliceID"); + slice_id.to_json(j); + } + if (five_qi_present) { + j.write_int("fiveQI", five_qi); + } + if (qci_present) { + j.write_int("qci", qci); + } + j.end_obj(); +} + +// E2SM-KPM-IndicationHeader ::= CHOICE +void e2_sm_kpm_ind_hdr_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("indicationHeader-Format1"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_ind_hdr_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_hdr_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "e2_sm_kpm_ind_hdr_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_ind_hdr_c::types_opts::to_string() const +{ + static const char* options[] = {"indicationHeader-Format1"}; + return convert_enum_idx(options, 1, value, "e2_sm_kpm_ind_hdr_c::types"); +} +uint8_t e2_sm_kpm_ind_hdr_c::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "e2_sm_kpm_ind_hdr_c::types"); +} + +// NI-Type ::= ENUMERATED +const char* ni_type_opts::to_string() const +{ + static const char* options[] = {"x2-u", "xn-u", "f1-u"}; + return convert_enum_idx(options, 3, value, "ni_type_e"); +} +uint8_t ni_type_opts::to_number() const +{ + switch (value) { + case x2_u: + return 2; + case f1_u: + return 1; + default: + invalid_enum_number(value, "ni_type_e"); + } + return 0; +} + +// PF-ContainerListItem ::= SEQUENCE +SRSASN_CODE pf_container_list_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(interface_type.pack(bref)); + HANDLE_CODE(o_cu_up_pm_container.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE pf_container_list_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(interface_type.unpack(bref)); + HANDLE_CODE(o_cu_up_pm_container.unpack(bref)); + + return SRSASN_SUCCESS; +} +void pf_container_list_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("interface-type", interface_type.to_string()); + j.write_fieldname("o-CU-UP-PM-Container"); + o_cu_up_pm_container.to_json(j); + j.end_obj(); +} + +// OCUCP-PF-Container ::= SEQUENCE +SRSASN_CODE ocucp_pf_container_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(gnb_cu_cp_name_present, 1)); + + if (gnb_cu_cp_name_present) { + HANDLE_CODE(gnb_cu_cp_name.pack(bref)); + } + HANDLE_CODE(bref.pack(cu_cp_res_status.nof_active_ues_present, 1)); + if (cu_cp_res_status.nof_active_ues_present) { + HANDLE_CODE(pack_integer(bref, cu_cp_res_status.nof_active_ues, (uint32_t)1u, (uint32_t)65536u, true, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ocucp_pf_container_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(gnb_cu_cp_name_present, 1)); + + if (gnb_cu_cp_name_present) { + HANDLE_CODE(gnb_cu_cp_name.unpack(bref)); + } + HANDLE_CODE(bref.unpack(cu_cp_res_status.nof_active_ues_present, 1)); + if (cu_cp_res_status.nof_active_ues_present) { + HANDLE_CODE(unpack_integer(cu_cp_res_status.nof_active_ues, bref, (uint32_t)1u, (uint32_t)65536u, true, true)); + } + + return SRSASN_SUCCESS; +} +void ocucp_pf_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (gnb_cu_cp_name_present) { + j.write_str("gNB-CU-CP-Name", gnb_cu_cp_name.to_string()); + } + j.write_fieldname("cu-CP-Resource-Status"); + j.start_obj(); + if (cu_cp_res_status.nof_active_ues_present) { + j.write_int("numberOfActive-UEs", cu_cp_res_status.nof_active_ues); + } + j.end_obj(); + j.end_obj(); +} + +// OCUUP-PF-Container ::= SEQUENCE +SRSASN_CODE ocuup_pf_container_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(gnb_cu_up_name_present, 1)); + + if (gnb_cu_up_name_present) { + HANDLE_CODE(gnb_cu_up_name.pack(bref)); + } + HANDLE_CODE(pack_dyn_seq_of(bref, pf_container_list, 1, 3, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ocuup_pf_container_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(gnb_cu_up_name_present, 1)); + + if (gnb_cu_up_name_present) { + HANDLE_CODE(gnb_cu_up_name.unpack(bref)); + } + HANDLE_CODE(unpack_dyn_seq_of(pf_container_list, bref, 1, 3, true)); + + return SRSASN_SUCCESS; +} +void ocuup_pf_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (gnb_cu_up_name_present) { + j.write_str("gNB-CU-UP-Name", gnb_cu_up_name.to_string()); + } + j.start_array("pf-ContainerList"); + for (const auto& e1 : pf_container_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// ODU-PF-Container ::= SEQUENCE +SRSASN_CODE odu_pf_container_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, cell_res_report_list, 1, 512, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE odu_pf_container_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(cell_res_report_list, bref, 1, 512, true)); + + return SRSASN_SUCCESS; +} +void odu_pf_container_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("cellResourceReportList"); + for (const auto& e1 : cell_res_report_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// PF-Container ::= CHOICE +void pf_container_c::destroy_() +{ + switch (type_) { + case types::odu: + c.destroy(); + break; + case types::ocu_cp: + c.destroy(); + break; + case types::ocu_up: + c.destroy(); + break; + default: + break; + } +} +void pf_container_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::odu: + c.init(); + break; + case types::ocu_cp: + c.init(); + break; + case types::ocu_up: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + } +} +pf_container_c::pf_container_c(const pf_container_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::odu: + c.init(other.c.get()); + break; + case types::ocu_cp: + c.init(other.c.get()); + break; + case types::ocu_up: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + } +} +pf_container_c& pf_container_c::operator=(const pf_container_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::odu: + c.set(other.c.get()); + break; + case types::ocu_cp: + c.set(other.c.get()); + break; + case types::ocu_up: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + } + + return *this; +} +odu_pf_container_s& pf_container_c::set_odu() +{ + set(types::odu); + return c.get(); +} +ocucp_pf_container_s& pf_container_c::set_ocu_cp() +{ + set(types::ocu_cp); + return c.get(); +} +ocuup_pf_container_s& pf_container_c::set_ocu_up() +{ + set(types::ocu_up); + return c.get(); +} +void pf_container_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::odu: + j.write_fieldname("oDU"); + c.get().to_json(j); + break; + case types::ocu_cp: + j.write_fieldname("oCU-CP"); + c.get().to_json(j); + break; + case types::ocu_up: + j.write_fieldname("oCU-UP"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + } + j.end_obj(); +} +SRSASN_CODE pf_container_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::odu: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ocu_cp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ocu_up: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE pf_container_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::odu: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ocu_cp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ocu_up: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "pf_container_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* pf_container_c::types_opts::to_string() const +{ + static const char* options[] = {"oDU", "oCU-CP", "oCU-UP"}; + return convert_enum_idx(options, 3, value, "pf_container_c::types"); +} + +// PM-Containers-List ::= SEQUENCE +SRSASN_CODE pm_containers_list_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(performance_container_present, 1)); + HANDLE_CODE(bref.pack(the_ran_container.size() > 0, 1)); + + if (performance_container_present) { + HANDLE_CODE(performance_container.pack(bref)); + } + if (the_ran_container.size() > 0) { + HANDLE_CODE(the_ran_container.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pm_containers_list_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(performance_container_present, 1)); + bool the_ran_container_present; + HANDLE_CODE(bref.unpack(the_ran_container_present, 1)); + + if (performance_container_present) { + HANDLE_CODE(performance_container.unpack(bref)); + } + if (the_ran_container_present) { + HANDLE_CODE(the_ran_container.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void pm_containers_list_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (performance_container_present) { + j.write_fieldname("performanceContainer"); + performance_container.to_json(j); + } + if (the_ran_container.size() > 0) { + j.write_str("theRANContainer", the_ran_container.to_string()); + } + j.end_obj(); +} + +// E2SM-KPM-IndicationMessage-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_msg_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, pm_containers, 1, 512, true)); + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(pm_containers, bref, 1, 512, true)); + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_msg_format1_s::to_json(json_writer& j) const +{ + j.start_array(); + j.start_obj(); + j.start_obj("E2SM-KPM-IndicationMessage-Format1"); + j.start_array("pm-Containers"); + for (const auto& e1 : pm_containers) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +// E2SM-KPM-IndicationMessage ::= CHOICE +void e2_sm_kpm_ind_msg_c::destroy_() +{ + switch (type_) { + case types::ind_msg_format1: + c.destroy(); + break; + default: + break; + } +} +void e2_sm_kpm_ind_msg_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ric_style_type: + break; + case types::ind_msg_format1: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + } +} +e2_sm_kpm_ind_msg_c::e2_sm_kpm_ind_msg_c(const e2_sm_kpm_ind_msg_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ric_style_type: + c.init(other.c.get()); + break; + case types::ind_msg_format1: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + } +} +e2_sm_kpm_ind_msg_c& e2_sm_kpm_ind_msg_c::operator=(const e2_sm_kpm_ind_msg_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ric_style_type: + c.set(other.c.get()); + break; + case types::ind_msg_format1: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + } + + return *this; +} +int64_t& e2_sm_kpm_ind_msg_c::set_ric_style_type() +{ + set(types::ric_style_type); + return c.get(); +} +e2_sm_kpm_ind_msg_format1_s& e2_sm_kpm_ind_msg_c::set_ind_msg_format1() +{ + set(types::ind_msg_format1); + return c.get(); +} +void e2_sm_kpm_ind_msg_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ric_style_type: + j.write_int("ric-Style-Type", c.get()); + break; + case types::ind_msg_format1: + j.write_fieldname("indicationMessage-Format1"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + } + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_ind_msg_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ric_style_type: + HANDLE_CODE(pack_unconstrained_integer(bref, c.get(), false, true)); + break; + case types::ind_msg_format1: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ric_style_type: + HANDLE_CODE(unpack_unconstrained_integer(c.get(), bref, false, true)); + break; + case types::ind_msg_format1: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_ind_msg_c::types_opts::to_string() const +{ + static const char* options[] = {"ric-Style-Type", "indicationMessage-Format1"}; + return convert_enum_idx(options, 2, value, "e2_sm_kpm_ind_msg_c::types"); +} +uint8_t e2_sm_kpm_ind_msg_c::types_opts::to_number() const +{ + if (value == ind_msg_format1) { + return 1; + } + invalid_enum_number(value, "e2_sm_kpm_ind_msg_c::types"); + return 0; +} + +// RANfunction-Name ::= SEQUENCE +SRSASN_CODE ra_nfunction_name_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_function_instance_present, 1)); + + HANDLE_CODE(ran_function_short_name.pack(bref)); + HANDLE_CODE(ran_function_e2_sm_oid.pack(bref)); + HANDLE_CODE(ran_function_description.pack(bref)); + if (ran_function_instance_present) { + HANDLE_CODE(pack_unconstrained_integer(bref, ran_function_instance, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_name_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_function_instance_present, 1)); + + HANDLE_CODE(ran_function_short_name.unpack(bref)); + HANDLE_CODE(ran_function_e2_sm_oid.unpack(bref)); + HANDLE_CODE(ran_function_description.unpack(bref)); + if (ran_function_instance_present) { + HANDLE_CODE(unpack_unconstrained_integer(ran_function_instance, bref, false, true)); + } + + return SRSASN_SUCCESS; +} +void ra_nfunction_name_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ranFunction-ShortName", ran_function_short_name.to_string()); + j.write_str("ranFunction-E2SM-OID", ran_function_e2_sm_oid.to_string()); + j.write_str("ranFunction-Description", ran_function_description.to_string()); + if (ran_function_instance_present) { + j.write_int("ranFunction-Instance", ran_function_instance); + } + j.end_obj(); +} + +// RIC-EventTriggerStyle-List ::= SEQUENCE +SRSASN_CODE ric_event_trigger_style_list_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_event_trigger_style_type, false, true)); + HANDLE_CODE(ric_event_trigger_style_name.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_event_trigger_format_type, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ric_event_trigger_style_list_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_event_trigger_style_type, bref, false, true)); + HANDLE_CODE(ric_event_trigger_style_name.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(ric_event_trigger_format_type, bref, false, true)); + + return SRSASN_SUCCESS; +} +void ric_event_trigger_style_list_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-EventTriggerStyle-Type", ric_event_trigger_style_type); + j.write_str("ric-EventTriggerStyle-Name", ric_event_trigger_style_name.to_string()); + j.write_int("ric-EventTriggerFormat-Type", ric_event_trigger_format_type); + j.end_obj(); +} + +// RIC-ReportStyle-List ::= SEQUENCE +SRSASN_CODE ric_report_style_list_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_report_style_type, false, true)); + HANDLE_CODE(ric_report_style_name.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_ind_hdr_format_type, false, true)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_ind_msg_format_type, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ric_report_style_list_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_report_style_type, bref, false, true)); + HANDLE_CODE(ric_report_style_name.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(ric_ind_hdr_format_type, bref, false, true)); + HANDLE_CODE(unpack_unconstrained_integer(ric_ind_msg_format_type, bref, false, true)); + + return SRSASN_SUCCESS; +} +void ric_report_style_list_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-ReportStyle-Type", ric_report_style_type); + j.write_str("ric-ReportStyle-Name", ric_report_style_name.to_string()); + j.write_int("ric-IndicationHeaderFormat-Type", ric_ind_hdr_format_type); + j.write_int("ric-IndicationMessageFormat-Type", ric_ind_msg_format_type); + j.end_obj(); +} + +// E2SM-KPM-RANfunction-Description ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ra_nfunction_description_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ran_function_name.pack(bref)); + bref.pack(e2_sm_kpm_ra_nfunction_item.ext, 1); + HANDLE_CODE(bref.pack(e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(e2_sm_kpm_ra_nfunction_item.ric_report_style_list.size() > 0, 1)); + if (e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list, 1, 63, true)); + } + if (e2_sm_kpm_ra_nfunction_item.ric_report_style_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, e2_sm_kpm_ra_nfunction_item.ric_report_style_list, 1, 63, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ra_nfunction_description_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ran_function_name.unpack(bref)); + bref.unpack(e2_sm_kpm_ra_nfunction_item.ext, 1); + bool ric_event_trigger_style_list_present; + HANDLE_CODE(bref.unpack(ric_event_trigger_style_list_present, 1)); + bool ric_report_style_list_present; + HANDLE_CODE(bref.unpack(ric_report_style_list_present, 1)); + if (ric_event_trigger_style_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list, bref, 1, 63, true)); + } + if (ric_report_style_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(e2_sm_kpm_ra_nfunction_item.ric_report_style_list, bref, 1, 63, true)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ra_nfunction_description_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ranFunction-Name"); + ran_function_name.to_json(j); + j.write_fieldname("e2SM-KPM-RANfunction-Item"); + j.start_obj(); + if (e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list.size() > 0) { + j.start_array("ric-EventTriggerStyle-List"); + for (const auto& e1 : e2_sm_kpm_ra_nfunction_item.ric_event_trigger_style_list) { + e1.to_json(j); + } + j.end_array(); + } + if (e2_sm_kpm_ra_nfunction_item.ric_report_style_list.size() > 0) { + j.start_array("ric-ReportStyle-List"); + for (const auto& e1 : e2_sm_kpm_ra_nfunction_item.ric_report_style_list) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); + j.end_obj(); +} + +// GNB-ID ::= CHOICE +void gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB-ID"}; + return convert_enum_idx(options, 1, value, "gnb_id_c::types"); +} + +// GlobalGNB-ID ::= SEQUENCE +SRSASN_CODE global_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("gNB-ID"); + gnb_id.to_json(j); + j.end_obj(); +} + +// NgENB-ID ::= CHOICE +void ng_enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_ng_enb_id: + c.destroy >(); + break; + case types::short_macro_ng_enb_id: + c.destroy >(); + break; + case types::long_macro_ng_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void ng_enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_ng_enb_id: + c.init >(); + break; + case types::short_macro_ng_enb_id: + c.init >(); + break; + case types::long_macro_ng_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c::ng_enb_id_c(const ng_enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c& ng_enb_id_c::operator=(const ng_enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& ng_enb_id_c::set_macro_ng_enb_id() +{ + set(types::macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& ng_enb_id_c::set_short_macro_ng_enb_id() +{ + set(types::short_macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& ng_enb_id_c::set_long_macro_ng_enb_id() +{ + set(types::long_macro_ng_enb_id); + return c.get >(); +} +void ng_enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_ng_enb_id: + j.write_str("macroNgENB-ID", c.get >().to_string()); + break; + case types::short_macro_ng_enb_id: + j.write_str("shortMacroNgENB-ID", c.get >().to_string()); + break; + case types::long_macro_ng_enb_id: + j.write_str("longMacroNgENB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE ng_enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ng_enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ng_enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macroNgENB-ID", "shortMacroNgENB-ID", "longMacroNgENB-ID"}; + return convert_enum_idx(options, 3, value, "ng_enb_id_c::types"); +} + +// GlobalNgENB-ID ::= SEQUENCE +SRSASN_CODE global_ng_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(ng_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ng_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(ng_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_ng_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("ngENB-ID"); + ng_enb_id.to_json(j); + j.end_obj(); +} + +// GlobalRANNodeID ::= CHOICE +void global_ran_node_id_c::destroy_() +{ + switch (type_) { + case types::global_gnb_id: + c.destroy(); + break; + case types::global_ng_enb_id: + c.destroy(); + break; + default: + break; + } +} +void global_ran_node_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_gnb_id: + c.init(); + break; + case types::global_ng_enb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c::global_ran_node_id_c(const global_ran_node_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_gnb_id: + c.init(other.c.get()); + break; + case types::global_ng_enb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c& global_ran_node_id_c::operator=(const global_ran_node_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_gnb_id: + c.set(other.c.get()); + break; + case types::global_ng_enb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + + return *this; +} +global_gnb_id_s& global_ran_node_id_c::set_global_gnb_id() +{ + set(types::global_gnb_id); + return c.get(); +} +global_ng_enb_id_s& global_ran_node_id_c::set_global_ng_enb_id() +{ + set(types::global_ng_enb_id); + return c.get(); +} +void global_ran_node_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_gnb_id: + j.write_fieldname("globalGNB-ID"); + c.get().to_json(j); + break; + case types::global_ng_enb_id: + j.write_fieldname("globalNgENB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_ran_node_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ran_node_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_ran_node_id_c::types_opts::to_string() const +{ + static const char* options[] = {"globalGNB-ID", "globalNgENB-ID"}; + return convert_enum_idx(options, 2, value, "global_ran_node_id_c::types"); +} + +// EN-GNB-ID ::= CHOICE +void en_gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("en-gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE en_gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE en_gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "en_gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* en_gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"en-gNB-ID"}; + return convert_enum_idx(options, 1, value, "en_gnb_id_c::types"); +} + +// GroupID ::= CHOICE +void group_id_c::destroy_() {} +void group_id_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +group_id_c::group_id_c(const group_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } +} +group_id_c& group_id_c::operator=(const group_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + + return *this; +} +uint16_t& group_id_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& group_id_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void group_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + j.end_obj(); +} +SRSASN_CODE group_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE group_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* group_id_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "group_id_c::types"); +} +uint8_t group_id_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "group_id_c::types"); +} + +// InterfaceID-E1 ::= SEQUENCE +SRSASN_CODE interface_id_e1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_e1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_e1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-CU-UP-ID", gnb_cu_up_id); + j.end_obj(); +} + +// InterfaceID-F1 ::= SEQUENCE +SRSASN_CODE interface_id_f1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_f1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_f1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-DU-ID", gnb_du_id); + j.end_obj(); +} + +// InterfaceID-NG ::= SEQUENCE +SRSASN_CODE interface_id_ng_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(guami.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_ng_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(guami.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_ng_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("guami"); + guami.to_json(j); + j.end_obj(); +} + +// InterfaceID-S1 ::= SEQUENCE +SRSASN_CODE interface_id_s1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(gummei.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_s1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(gummei.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_s1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + j.end_obj(); +} + +// InterfaceID-W1 ::= SEQUENCE +SRSASN_CODE interface_id_w1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_enb_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, ng_enb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_w1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + HANDLE_CODE(unpack_integer(ng_enb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_w1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-ng-eNB-ID"); + global_ng_enb_id.to_json(j); + j.write_int("ng-eNB-DU-ID", ng_enb_du_id); + j.end_obj(); +} + +// InterfaceID-X2 ::= SEQUENCE +SRSASN_CODE interface_id_x2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(node_type.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(node_type.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_x2_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("nodeType"); + node_type.to_json(j); + j.end_obj(); +} + +void interface_id_x2_s::node_type_c_::destroy_() +{ + switch (type_) { + case types::global_enb_id: + c.destroy(); + break; + case types::global_en_g_nb_id: + c.destroy(); + break; + default: + break; + } +} +void interface_id_x2_s::node_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_enb_id: + c.init(); + break; + case types::global_en_g_nb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_::node_type_c_(const interface_id_x2_s::node_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_enb_id: + c.init(other.c.get()); + break; + case types::global_en_g_nb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_& +interface_id_x2_s::node_type_c_::operator=(const interface_id_x2_s::node_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_enb_id: + c.set(other.c.get()); + break; + case types::global_en_g_nb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + + return *this; +} +global_enb_id_s& interface_id_x2_s::node_type_c_::set_global_enb_id() +{ + set(types::global_enb_id); + return c.get(); +} +globalen_gnb_id_s& interface_id_x2_s::node_type_c_::set_global_en_g_nb_id() +{ + set(types::global_en_g_nb_id); + return c.get(); +} +void interface_id_x2_s::node_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_enb_id: + j.write_fieldname("global-eNB-ID"); + c.get().to_json(j); + break; + case types::global_en_g_nb_id: + j.write_fieldname("global-en-gNB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_x2_s::node_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::node_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_x2_s::node_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"global-eNB-ID", "global-en-gNB-ID"}; + return convert_enum_idx(options, 2, value, "interface_id_x2_s::node_type_c_::types"); +} + +// InterfaceID-Xn ::= SEQUENCE +SRSASN_CODE interface_id_xn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_xn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_xn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.end_obj(); +} + +// InterfaceIdentifier ::= CHOICE +void interface_id_c::destroy_() +{ + switch (type_) { + case types::ng: + c.destroy(); + break; + case types::xn: + c.destroy(); + break; + case types::f1: + c.destroy(); + break; + case types::e1: + c.destroy(); + break; + case types::s1: + c.destroy(); + break; + case types::x2: + c.destroy(); + break; + case types::w1: + c.destroy(); + break; + default: + break; + } +} +void interface_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ng: + c.init(); + break; + case types::xn: + c.init(); + break; + case types::f1: + c.init(); + break; + case types::e1: + c.init(); + break; + case types::s1: + c.init(); + break; + case types::x2: + c.init(); + break; + case types::w1: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c::interface_id_c(const interface_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ng: + c.init(other.c.get()); + break; + case types::xn: + c.init(other.c.get()); + break; + case types::f1: + c.init(other.c.get()); + break; + case types::e1: + c.init(other.c.get()); + break; + case types::s1: + c.init(other.c.get()); + break; + case types::x2: + c.init(other.c.get()); + break; + case types::w1: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c& interface_id_c::operator=(const interface_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ng: + c.set(other.c.get()); + break; + case types::xn: + c.set(other.c.get()); + break; + case types::f1: + c.set(other.c.get()); + break; + case types::e1: + c.set(other.c.get()); + break; + case types::s1: + c.set(other.c.get()); + break; + case types::x2: + c.set(other.c.get()); + break; + case types::w1: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + + return *this; +} +interface_id_ng_s& interface_id_c::set_ng() +{ + set(types::ng); + return c.get(); +} +interface_id_xn_s& interface_id_c::set_xn() +{ + set(types::xn); + return c.get(); +} +interface_id_f1_s& interface_id_c::set_f1() +{ + set(types::f1); + return c.get(); +} +interface_id_e1_s& interface_id_c::set_e1() +{ + set(types::e1); + return c.get(); +} +interface_id_s1_s& interface_id_c::set_s1() +{ + set(types::s1); + return c.get(); +} +interface_id_x2_s& interface_id_c::set_x2() +{ + set(types::x2); + return c.get(); +} +interface_id_w1_s& interface_id_c::set_w1() +{ + set(types::w1); + return c.get(); +} +void interface_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ng: + j.write_fieldname("nG"); + c.get().to_json(j); + break; + case types::xn: + j.write_fieldname("xN"); + c.get().to_json(j); + break; + case types::f1: + j.write_fieldname("f1"); + c.get().to_json(j); + break; + case types::e1: + j.write_fieldname("e1"); + c.get().to_json(j); + break; + case types::s1: + j.write_fieldname("s1"); + c.get().to_json(j); + break; + case types::x2: + j.write_fieldname("x2"); + c.get().to_json(j); + break; + case types::w1: + j.write_fieldname("w1"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_c::types_opts::to_string() const +{ + static const char* options[] = {"nG", "xN", "f1", "e1", "s1", "x2", "w1"}; + return convert_enum_idx(options, 7, value, "interface_id_c::types"); +} + +// FreqBandNrItem ::= SEQUENCE +SRSASN_CODE freq_band_nr_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, freq_band_ind_nr, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE freq_band_nr_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(freq_band_ind_nr, bref, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +void freq_band_nr_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("freqBandIndicatorNr", freq_band_ind_nr); + j.end_obj(); +} + +// NR-ARFCN ::= SEQUENCE +SRSASN_CODE nr_arfcn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, nrarfcn, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list_nr, 1, 32, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_arfcn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(nrarfcn, bref, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(unpack_dyn_seq_of(freq_band_list_nr, bref, 1, 32, true)); + + return SRSASN_SUCCESS; +} +void nr_arfcn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("nRARFCN", nrarfcn); + j.start_array("freqBandListNr"); + for (const auto& e1 : freq_band_list_nr) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// QoSID ::= CHOICE +void qo_sid_c::destroy_() {} +void qo_sid_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +qo_sid_c::qo_sid_c(const qo_sid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } +} +qo_sid_c& qo_sid_c::operator=(const qo_sid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + + return *this; +} +uint16_t& qo_sid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& qo_sid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void qo_sid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + j.end_obj(); +} +SRSASN_CODE qo_sid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE qo_sid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* qo_sid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "qo_sid_c::types"); +} +uint8_t qo_sid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "qo_sid_c::types"); +} + +// RRCclass-LTE ::= ENUMERATED +const char* rr_cclass_lte_opts::to_string() const +{ + static const char* options[] = {"bCCH-BCH", + "bCCH-BCH-MBMS", + "bCCH-DL-SCH", + "bCCH-DL-SCH-BR", + "bCCH-DL-SCH-MBMS", + "mCCH", + "pCCH", + "dL-CCCH", + "dL-DCCH", + "uL-CCCH", + "uL-DCCH", + "sC-MCCH"}; + return convert_enum_idx(options, 12, value, "rr_cclass_lte_e"); +} + +// RRCclass-NR ::= ENUMERATED +const char* rr_cclass_nr_opts::to_string() const +{ + static const char* options[] = { + "bCCH-BCH", "bCCH-DL-SCH", "dL-CCCH", "dL-DCCH", "pCCH", "uL-CCCH", "uL-CCCH1", "uL-DCCH"}; + return convert_enum_idx(options, 8, value, "rr_cclass_nr_e"); +} +uint8_t rr_cclass_nr_opts::to_number() const +{ + if (value == ul_ccch1) { + return 1; + } + invalid_enum_number(value, "rr_cclass_nr_e"); + return 0; +} + +// RRC-MessageID ::= SEQUENCE +SRSASN_CODE rrc_msg_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(rrc_type.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, msg_id, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(rrc_type.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(msg_id, bref, false, true)); + + return SRSASN_SUCCESS; +} +void rrc_msg_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("rrcType"); + rrc_type.to_json(j); + j.write_int("messageID", msg_id); + j.end_obj(); +} + +void rrc_msg_id_s::rrc_type_c_::destroy_() {} +void rrc_msg_id_s::rrc_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +rrc_msg_id_s::rrc_type_c_::rrc_type_c_(const rrc_msg_id_s::rrc_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::lte: + c.init(other.c.get()); + break; + case types::nr: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } +} +rrc_msg_id_s::rrc_type_c_& rrc_msg_id_s::rrc_type_c_::operator=(const rrc_msg_id_s::rrc_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::lte: + c.set(other.c.get()); + break; + case types::nr: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + + return *this; +} +rr_cclass_lte_e& rrc_msg_id_s::rrc_type_c_::set_lte() +{ + set(types::lte); + return c.get(); +} +rr_cclass_nr_e& rrc_msg_id_s::rrc_type_c_::set_nr() +{ + set(types::nr); + return c.get(); +} +void rrc_msg_id_s::rrc_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::lte: + j.write_str("lTE", c.get().to_string()); + break; + case types::nr: + j.write_str("nR", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_msg_id_s::rrc_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"lTE", "nR"}; + return convert_enum_idx(options, 2, value, "rrc_msg_id_s::rrc_type_c_::types"); +} + +// S-NSSAI ::= SEQUENCE +SRSASN_CODE s_nssai_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(sd_present, 1)); + + HANDLE_CODE(sst.pack(bref)); + if (sd_present) { + HANDLE_CODE(sd.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE s_nssai_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(sd_present, 1)); + + HANDLE_CODE(sst.unpack(bref)); + if (sd_present) { + HANDLE_CODE(sd.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void s_nssai_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("sST", sst.to_string()); + if (sd_present) { + j.write_str("sD", sd.to_string()); + } + j.end_obj(); +} + +// ServingCell-ARFCN ::= CHOICE +void serving_cell_arfcn_c::destroy_() +{ + switch (type_) { + case types::nr: + c.destroy(); + break; + default: + break; + } +} +void serving_cell_arfcn_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr: + c.init(); + break; + case types::eutra: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c::serving_cell_arfcn_c(const serving_cell_arfcn_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c& serving_cell_arfcn_c::operator=(const serving_cell_arfcn_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + + return *this; +} +nr_arfcn_s& serving_cell_arfcn_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint32_t& serving_cell_arfcn_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_arfcn_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_fieldname("nR"); + c.get().to_json(j); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_arfcn_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_arfcn_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_arfcn_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_arfcn_c::types"); +} + +// ServingCell-PCI ::= CHOICE +void serving_cell_pci_c::destroy_() {} +void serving_cell_pci_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +serving_cell_pci_c::serving_cell_pci_c(const serving_cell_pci_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } +} +serving_cell_pci_c& serving_cell_pci_c::operator=(const serving_cell_pci_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + + return *this; +} +uint16_t& serving_cell_pci_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint16_t& serving_cell_pci_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_pci_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_int("nR", c.get()); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_pci_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_pci_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_pci_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_pci_c::types"); +} + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_e1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + j.end_obj(); +} + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_f1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + j.end_obj(); +} + +// UEID-EN-GNB ::= SEQUENCE +SRSASN_CODE ueid_en_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.pack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_en_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_en_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + if (gnb_cu_ue_f1_ap_id_present) { + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-ENB ::= SEQUENCE +SRSASN_CODE ueid_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(global_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, mme_ue_s1ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.pack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(global_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(mme_ue_s1ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.unpack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("mME-UE-S1AP-ID", mme_ue_s1ap_id); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + if (m_enb_ue_x2ap_id_present) { + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + } + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + if (global_enb_id_present) { + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB ::= SEQUENCE +SRSASN_CODE ueid_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_gnb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_ue_f1_ap_id_list, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool gnb_cu_ue_f1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_list_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_gnb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_ue_f1_ap_id_list, bref, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-UE-F1AP-ID-List"); + for (const auto& e1 : gnb_cu_ue_f1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_gnb_id_present) { + j.write_fieldname("globalGNB-ID"); + global_gnb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB-CU-UP ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_up_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_up_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_up_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-GNB-DU ::= SEQUENCE +SRSASN_CODE ueid_gnb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-NG-ENB ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (ng_enb_cu_ue_w1_ap_id_present) { + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_ng_enb_id_present) { + j.write_fieldname("globalNgENB-ID"); + global_ng_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-NG-ENB-DU ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + j.end_obj(); +} + +// UEID ::= CHOICE +void ueid_c::destroy_() +{ + switch (type_) { + case types::gnb_ueid: + c.destroy(); + break; + case types::gnb_du_ueid: + c.destroy(); + break; + case types::gnb_cu_up_ueid: + c.destroy(); + break; + case types::ng_enb_ueid: + c.destroy(); + break; + case types::ng_enb_du_ueid: + c.destroy(); + break; + case types::en_g_nb_ueid: + c.destroy(); + break; + case types::enb_ueid: + c.destroy(); + break; + default: + break; + } +} +void ueid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb_ueid: + c.init(); + break; + case types::gnb_du_ueid: + c.init(); + break; + case types::gnb_cu_up_ueid: + c.init(); + break; + case types::ng_enb_ueid: + c.init(); + break; + case types::ng_enb_du_ueid: + c.init(); + break; + case types::en_g_nb_ueid: + c.init(); + break; + case types::enb_ueid: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c::ueid_c(const ueid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb_ueid: + c.init(other.c.get()); + break; + case types::gnb_du_ueid: + c.init(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.init(other.c.get()); + break; + case types::en_g_nb_ueid: + c.init(other.c.get()); + break; + case types::enb_ueid: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c& ueid_c::operator=(const ueid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb_ueid: + c.set(other.c.get()); + break; + case types::gnb_du_ueid: + c.set(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.set(other.c.get()); + break; + case types::en_g_nb_ueid: + c.set(other.c.get()); + break; + case types::enb_ueid: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + + return *this; +} +ueid_gnb_s& ueid_c::set_gnb_ueid() +{ + set(types::gnb_ueid); + return c.get(); +} +ueid_gnb_du_s& ueid_c::set_gnb_du_ueid() +{ + set(types::gnb_du_ueid); + return c.get(); +} +ueid_gnb_cu_up_s& ueid_c::set_gnb_cu_up_ueid() +{ + set(types::gnb_cu_up_ueid); + return c.get(); +} +ueid_ng_enb_s& ueid_c::set_ng_enb_ueid() +{ + set(types::ng_enb_ueid); + return c.get(); +} +ueid_ng_enb_du_s& ueid_c::set_ng_enb_du_ueid() +{ + set(types::ng_enb_du_ueid); + return c.get(); +} +ueid_en_gnb_s& ueid_c::set_en_g_nb_ueid() +{ + set(types::en_g_nb_ueid); + return c.get(); +} +ueid_enb_s& ueid_c::set_enb_ueid() +{ + set(types::enb_ueid); + return c.get(); +} +void ueid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb_ueid: + j.write_fieldname("gNB-UEID"); + c.get().to_json(j); + break; + case types::gnb_du_ueid: + j.write_fieldname("gNB-DU-UEID"); + c.get().to_json(j); + break; + case types::gnb_cu_up_ueid: + j.write_fieldname("gNB-CU-UP-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_ueid: + j.write_fieldname("ng-eNB-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_du_ueid: + j.write_fieldname("ng-eNB-DU-UEID"); + c.get().to_json(j); + break; + case types::en_g_nb_ueid: + j.write_fieldname("en-gNB-UEID"); + c.get().to_json(j); + break; + case types::enb_ueid: + j.write_fieldname("eNB-UEID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + j.end_obj(); +} +SRSASN_CODE ueid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ueid_c::types_opts::to_string() const +{ + static const char* options[] = { + "gNB-UEID", "gNB-DU-UEID", "gNB-CU-UP-UEID", "ng-eNB-UEID", "ng-eNB-DU-UEID", "en-gNB-UEID", "eNB-UEID"}; + return convert_enum_idx(options, 7, value, "ueid_c::types"); +} diff --git a/lib/src/asn1/e2sm_kpm_v2.cpp b/lib/src/asn1/e2sm_kpm_v2.cpp new file mode 100644 index 0000000000..3527e90869 --- /dev/null +++ b/lib/src/asn1/e2sm_kpm_v2.cpp @@ -0,0 +1,6585 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/asn1/e2sm_kpm_v2.h" +#include + +using namespace asn1; +using namespace asn1::e2sm_kpm; + +/******************************************************************************* + * Struct Methods + ******************************************************************************/ + +// BinRangeValue ::= CHOICE +void bin_range_value_c::destroy_() +{ + switch (type_) { + case types::value_real: + c.destroy(); + break; + default: + break; + } +} +void bin_range_value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::value_int: + break; + case types::value_real: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + } +} +bin_range_value_c::bin_range_value_c(const bin_range_value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::value_int: + c.init(other.c.get()); + break; + case types::value_real: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + } +} +bin_range_value_c& bin_range_value_c::operator=(const bin_range_value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::value_int: + c.set(other.c.get()); + break; + case types::value_real: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + } + + return *this; +} +int64_t& bin_range_value_c::set_value_int() +{ + set(types::value_int); + return c.get(); +} +real_s& bin_range_value_c::set_value_real() +{ + set(types::value_real); + return c.get(); +} +void bin_range_value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::value_int: + j.write_int("valueInt", c.get()); + break; + case types::value_real: + j.write_fieldname("valueReal"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + } + j.end_obj(); +} +SRSASN_CODE bin_range_value_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::value_int: + HANDLE_CODE(pack_unconstrained_integer(bref, c.get(), false, true)); + break; + case types::value_real: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE bin_range_value_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::value_int: + HANDLE_CODE(unpack_unconstrained_integer(c.get(), bref, false, true)); + break; + case types::value_real: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "bin_range_value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* bin_range_value_c::types_opts::to_string() const +{ + static const char* options[] = {"valueInt", "valueReal"}; + return convert_enum_idx(options, 2, value, "bin_range_value_c::types"); +} + +// BinRangeItem ::= SEQUENCE +SRSASN_CODE bin_range_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, bin_idx, (uint32_t)1u, (uint32_t)65535u, true, true)); + HANDLE_CODE(start_value.pack(bref)); + HANDLE_CODE(end_value.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE bin_range_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(bin_idx, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + HANDLE_CODE(start_value.unpack(bref)); + HANDLE_CODE(end_value.unpack(bref)); + + return SRSASN_SUCCESS; +} +void bin_range_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("binIndex", bin_idx); + j.write_fieldname("startValue"); + start_value.to_json(j); + j.write_fieldname("endValue"); + end_value.to_json(j); + j.end_obj(); +} + +// BinRangeDefinition ::= SEQUENCE +SRSASN_CODE bin_range_definition_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(bin_range_list_y.size() > 0, 1)); + HANDLE_CODE(bref.pack(bin_range_list_z.size() > 0, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, bin_range_list_x, 1, 65535, true)); + if (bin_range_list_y.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, bin_range_list_y, 1, 65535, true)); + } + if (bin_range_list_z.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, bin_range_list_z, 1, 65535, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE bin_range_definition_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool bin_range_list_y_present; + HANDLE_CODE(bref.unpack(bin_range_list_y_present, 1)); + bool bin_range_list_z_present; + HANDLE_CODE(bref.unpack(bin_range_list_z_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(bin_range_list_x, bref, 1, 65535, true)); + if (bin_range_list_y_present) { + HANDLE_CODE(unpack_dyn_seq_of(bin_range_list_y, bref, 1, 65535, true)); + } + if (bin_range_list_z_present) { + HANDLE_CODE(unpack_dyn_seq_of(bin_range_list_z, bref, 1, 65535, true)); + } + + return SRSASN_SUCCESS; +} +void bin_range_definition_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("binRangeListX"); + for (const auto& e1 : bin_range_list_x) { + e1.to_json(j); + } + j.end_array(); + if (bin_range_list_y.size() > 0) { + j.start_array("binRangeListY"); + for (const auto& e1 : bin_range_list_y) { + e1.to_json(j); + } + j.end_array(); + } + if (bin_range_list_z.size() > 0) { + j.start_array("binRangeListZ"); + for (const auto& e1 : bin_range_list_z) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// EUTRA-CGI ::= SEQUENCE +SRSASN_CODE eutra_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(eutra_cell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE eutra_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(eutra_cell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void eutra_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("eUTRACellIdentity", eutra_cell_id.to_string()); + j.end_obj(); +} + +// NR-CGI ::= SEQUENCE +SRSASN_CODE nr_cgi_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(nrcell_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_cgi_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(nrcell_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void nr_cgi_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("nRCellIdentity", nrcell_id.to_string()); + j.end_obj(); +} + +// CGI ::= CHOICE +void cgi_c::destroy_() +{ + switch (type_) { + case types::nr_cgi: + c.destroy(); + break; + case types::eutra_cgi: + c.destroy(); + break; + default: + break; + } +} +void cgi_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr_cgi: + c.init(); + break; + case types::eutra_cgi: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c::cgi_c(const cgi_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr_cgi: + c.init(other.c.get()); + break; + case types::eutra_cgi: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } +} +cgi_c& cgi_c::operator=(const cgi_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr_cgi: + c.set(other.c.get()); + break; + case types::eutra_cgi: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + + return *this; +} +nr_cgi_s& cgi_c::set_nr_cgi() +{ + set(types::nr_cgi); + return c.get(); +} +eutra_cgi_s& cgi_c::set_eutra_cgi() +{ + set(types::eutra_cgi); + return c.get(); +} +void cgi_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr_cgi: + j.write_fieldname("nR-CGI"); + c.get().to_json(j); + break; + case types::eutra_cgi: + j.write_fieldname("eUTRA-CGI"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + } + j.end_obj(); +} +SRSASN_CODE cgi_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE cgi_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra_cgi: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "cgi_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* cgi_c::types_opts::to_string() const +{ + static const char* options[] = {"nR-CGI", "eUTRA-CGI"}; + return convert_enum_idx(options, 2, value, "cgi_c::types"); +} + +// GUAMI ::= SEQUENCE +SRSASN_CODE guami_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(amf_region_id.pack(bref)); + HANDLE_CODE(amf_set_id.pack(bref)); + HANDLE_CODE(amf_pointer.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE guami_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(amf_region_id.unpack(bref)); + HANDLE_CODE(amf_set_id.unpack(bref)); + HANDLE_CODE(amf_pointer.unpack(bref)); + + return SRSASN_SUCCESS; +} +void guami_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_str("aMFRegionID", amf_region_id.to_string()); + j.write_str("aMFSetID", amf_set_id.to_string()); + j.write_str("aMFPointer", amf_pointer.to_string()); + j.end_obj(); +} + +// GUMMEI ::= SEQUENCE +SRSASN_CODE gummei_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(mme_group_id.pack(bref)); + HANDLE_CODE(mme_code.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE gummei_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(mme_group_id.unpack(bref)); + HANDLE_CODE(mme_code.unpack(bref)); + + return SRSASN_SUCCESS; +} +void gummei_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_str("mME-Group-ID", mme_group_id.to_string()); + j.write_str("mME-Code", mme_code.to_string()); + j.end_obj(); +} + +// CoreCPID ::= CHOICE +void core_cpid_c::destroy_() +{ + switch (type_) { + case types::five_gc: + c.destroy(); + break; + case types::epc: + c.destroy(); + break; + default: + break; + } +} +void core_cpid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::five_gc: + c.init(); + break; + case types::epc: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c::core_cpid_c(const core_cpid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } +} +core_cpid_c& core_cpid_c::operator=(const core_cpid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + + return *this; +} +guami_s& core_cpid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +gummei_s& core_cpid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void core_cpid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_fieldname("fiveGC"); + c.get().to_json(j); + break; + case types::epc: + j.write_fieldname("ePC"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + } + j.end_obj(); +} +SRSASN_CODE core_cpid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE core_cpid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::epc: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "core_cpid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* core_cpid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "core_cpid_c::types"); +} +uint8_t core_cpid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "core_cpid_c::types"); +} + +// MeasurementType ::= CHOICE +void meas_type_c::destroy_() +{ + switch (type_) { + case types::meas_name: + c.destroy >(); + break; + default: + break; + } +} +void meas_type_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::meas_name: + c.init >(); + break; + case types::meas_id: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + } +} +meas_type_c::meas_type_c(const meas_type_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::meas_name: + c.init(other.c.get >()); + break; + case types::meas_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + } +} +meas_type_c& meas_type_c::operator=(const meas_type_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::meas_name: + c.set(other.c.get >()); + break; + case types::meas_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + } + + return *this; +} +printable_string<1, 150, true, true>& meas_type_c::set_meas_name() +{ + set(types::meas_name); + return c.get >(); +} +uint32_t& meas_type_c::set_meas_id() +{ + set(types::meas_id); + return c.get(); +} +void meas_type_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::meas_name: + j.write_str("measName", c.get >().to_string()); + break; + case types::meas_id: + j.write_int("measID", c.get()); + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + } + j.end_obj(); +} +SRSASN_CODE meas_type_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::meas_name: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::meas_id: + HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)1u, (uint32_t)65536u, true, true)); + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_type_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::meas_name: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::meas_id: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)1u, (uint32_t)65536u, true, true)); + break; + default: + log_invalid_choice_id(type_, "meas_type_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* meas_type_c::types_opts::to_string() const +{ + static const char* options[] = {"measName", "measID"}; + return convert_enum_idx(options, 2, value, "meas_type_c::types"); +} + +// DistMeasurementBinRangeItem ::= SEQUENCE +SRSASN_CODE dist_meas_bin_range_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(meas_type.pack(bref)); + HANDLE_CODE(bin_range_def.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE dist_meas_bin_range_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(meas_type.unpack(bref)); + HANDLE_CODE(bin_range_def.unpack(bref)); + + return SRSASN_SUCCESS; +} +void dist_meas_bin_range_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measType"); + meas_type.to_json(j); + j.write_fieldname("binRangeDef"); + bin_range_def.to_json(j); + j.end_obj(); +} + +// S-NSSAI ::= SEQUENCE +SRSASN_CODE s_nssai_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(sd_present, 1)); + + HANDLE_CODE(sst.pack(bref)); + if (sd_present) { + HANDLE_CODE(sd.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE s_nssai_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(sd_present, 1)); + + HANDLE_CODE(sst.unpack(bref)); + if (sd_present) { + HANDLE_CODE(sd.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void s_nssai_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("sST", sst.to_string()); + if (sd_present) { + j.write_str("sD", sd.to_string()); + } + j.end_obj(); +} + +// TestCond-Expression ::= ENUMERATED +const char* test_cond_expression_opts::to_string() const +{ + static const char* options[] = {"equal", "greaterthan", "lessthan", "contains", "present"}; + return convert_enum_idx(options, 5, value, "test_cond_expression_e"); +} + +// TestCond-Type ::= CHOICE +void test_cond_type_c::destroy_() {} +void test_cond_type_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +test_cond_type_c::test_cond_type_c(const test_cond_type_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gbr: + c.init(other.c.get()); + break; + case types::ambr: + c.init(other.c.get()); + break; + case types::is_stat: + c.init(other.c.get()); + break; + case types::is_cat_m: + c.init(other.c.get()); + break; + case types::rsrp: + c.init(other.c.get()); + break; + case types::rsrq: + c.init(other.c.get()); + break; + case types::ul_r_srp: + c.init(other.c.get()); + break; + case types::cqi: + c.init(other.c.get()); + break; + case types::five_qi: + c.init(other.c.get()); + break; + case types::qci: + c.init(other.c.get()); + break; + case types::snssai: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "test_cond_type_c"); + } +} +test_cond_type_c& test_cond_type_c::operator=(const test_cond_type_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gbr: + c.set(other.c.get()); + break; + case types::ambr: + c.set(other.c.get()); + break; + case types::is_stat: + c.set(other.c.get()); + break; + case types::is_cat_m: + c.set(other.c.get()); + break; + case types::rsrp: + c.set(other.c.get()); + break; + case types::rsrq: + c.set(other.c.get()); + break; + case types::ul_r_srp: + c.set(other.c.get()); + break; + case types::cqi: + c.set(other.c.get()); + break; + case types::five_qi: + c.set(other.c.get()); + break; + case types::qci: + c.set(other.c.get()); + break; + case types::snssai: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "test_cond_type_c"); + } + + return *this; +} +test_cond_type_c::gbr_e_& test_cond_type_c::set_gbr() +{ + set(types::gbr); + return c.get(); +} +test_cond_type_c::ambr_e_& test_cond_type_c::set_ambr() +{ + set(types::ambr); + return c.get(); +} +test_cond_type_c::is_stat_e_& test_cond_type_c::set_is_stat() +{ + set(types::is_stat); + return c.get(); +} +test_cond_type_c::is_cat_m_e_& test_cond_type_c::set_is_cat_m() +{ + set(types::is_cat_m); + return c.get(); +} +test_cond_type_c::rsrp_e_& test_cond_type_c::set_rsrp() +{ + set(types::rsrp); + return c.get(); +} +test_cond_type_c::rsrq_e_& test_cond_type_c::set_rsrq() +{ + set(types::rsrq); + return c.get(); +} +test_cond_type_c::ul_r_srp_e_& test_cond_type_c::set_ul_r_srp() +{ + set(types::ul_r_srp); + return c.get(); +} +test_cond_type_c::cqi_e_& test_cond_type_c::set_cqi() +{ + set(types::cqi); + return c.get(); +} +test_cond_type_c::five_qi_e_& test_cond_type_c::set_five_qi() +{ + set(types::five_qi); + return c.get(); +} +test_cond_type_c::qci_e_& test_cond_type_c::set_qci() +{ + set(types::qci); + return c.get(); +} +test_cond_type_c::snssai_e_& test_cond_type_c::set_snssai() +{ + set(types::snssai); + return c.get(); +} +void test_cond_type_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gbr: + j.write_str("gBR", "true"); + break; + case types::ambr: + j.write_str("aMBR", "true"); + break; + case types::is_stat: + j.write_str("isStat", "true"); + break; + case types::is_cat_m: + j.write_str("isCatM", "true"); + break; + case types::rsrp: + j.write_str("rSRP", "true"); + break; + case types::rsrq: + j.write_str("rSRQ", "true"); + break; + case types::ul_r_srp: + j.write_str("ul-rSRP", "true"); + break; + case types::cqi: + j.write_str("cQI", "true"); + break; + case types::five_qi: + j.write_str("fiveQI", "true"); + break; + case types::qci: + j.write_str("qCI", "true"); + break; + case types::snssai: + j.write_str("sNSSAI", "true"); + break; + default: + log_invalid_choice_id(type_, "test_cond_type_c"); + } + j.end_obj(); +} +SRSASN_CODE test_cond_type_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gbr: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ambr: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::is_stat: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::is_cat_m: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::rsrp: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::rsrq: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ul_r_srp: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::cqi: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::five_qi: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::qci: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::snssai: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + default: + log_invalid_choice_id(type_, "test_cond_type_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE test_cond_type_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gbr: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ambr: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::is_stat: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::is_cat_m: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::rsrp: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::rsrq: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ul_r_srp: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::cqi: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::five_qi: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::qci: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::snssai: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + default: + log_invalid_choice_id(type_, "test_cond_type_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* test_cond_type_c::gbr_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::gbr_e_"); +} + +const char* test_cond_type_c::ambr_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::ambr_e_"); +} + +const char* test_cond_type_c::is_stat_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::is_stat_e_"); +} + +const char* test_cond_type_c::is_cat_m_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::is_cat_m_e_"); +} + +const char* test_cond_type_c::rsrp_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::rsrp_e_"); +} + +const char* test_cond_type_c::rsrq_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::rsrq_e_"); +} + +const char* test_cond_type_c::ul_r_srp_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::ul_r_srp_e_"); +} + +const char* test_cond_type_c::cqi_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::cqi_e_"); +} + +const char* test_cond_type_c::five_qi_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::five_qi_e_"); +} + +const char* test_cond_type_c::qci_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::qci_e_"); +} + +const char* test_cond_type_c::snssai_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "test_cond_type_c::snssai_e_"); +} + +const char* test_cond_type_c::types_opts::to_string() const +{ + static const char* options[] = { + "gBR", "aMBR", "isStat", "isCatM", "rSRP", "rSRQ", "ul-rSRP", "cQI", "fiveQI", "qCI", "sNSSAI"}; + return convert_enum_idx(options, 11, value, "test_cond_type_c::types"); +} +uint8_t test_cond_type_c::types_opts::to_number() const +{ + if (value == five_qi) { + return 5; + } + invalid_enum_number(value, "test_cond_type_c::types"); + return 0; +} + +// TestCond-Value ::= CHOICE +void test_cond_value_c::destroy_() +{ + switch (type_) { + case types::value_bool: + c.destroy(); + break; + case types::value_bit_s: + c.destroy(); + break; + case types::value_oct_s: + c.destroy >(); + break; + case types::value_prt_s: + c.destroy >(); + break; + case types::value_real: + c.destroy(); + break; + default: + break; + } +} +void test_cond_value_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::value_int: + break; + case types::value_enum: + break; + case types::value_bool: + c.init(); + break; + case types::value_bit_s: + c.init(); + break; + case types::value_oct_s: + c.init >(); + break; + case types::value_prt_s: + c.init >(); + break; + case types::value_real: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + } +} +test_cond_value_c::test_cond_value_c(const test_cond_value_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::value_int: + c.init(other.c.get()); + break; + case types::value_enum: + c.init(other.c.get()); + break; + case types::value_bool: + c.init(other.c.get()); + break; + case types::value_bit_s: + c.init(other.c.get()); + break; + case types::value_oct_s: + c.init(other.c.get >()); + break; + case types::value_prt_s: + c.init(other.c.get >()); + break; + case types::value_real: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + } +} +test_cond_value_c& test_cond_value_c::operator=(const test_cond_value_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::value_int: + c.set(other.c.get()); + break; + case types::value_enum: + c.set(other.c.get()); + break; + case types::value_bool: + c.set(other.c.get()); + break; + case types::value_bit_s: + c.set(other.c.get()); + break; + case types::value_oct_s: + c.set(other.c.get >()); + break; + case types::value_prt_s: + c.set(other.c.get >()); + break; + case types::value_real: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + } + + return *this; +} +int64_t& test_cond_value_c::set_value_int() +{ + set(types::value_int); + return c.get(); +} +int64_t& test_cond_value_c::set_value_enum() +{ + set(types::value_enum); + return c.get(); +} +bool& test_cond_value_c::set_value_bool() +{ + set(types::value_bool); + return c.get(); +} +dyn_bitstring& test_cond_value_c::set_value_bit_s() +{ + set(types::value_bit_s); + return c.get(); +} +unbounded_octstring& test_cond_value_c::set_value_oct_s() +{ + set(types::value_oct_s); + return c.get >(); +} +printable_string<0, None, false, true>& test_cond_value_c::set_value_prt_s() +{ + set(types::value_prt_s); + return c.get >(); +} +real_s& test_cond_value_c::set_value_real() +{ + set(types::value_real); + return c.get(); +} +void test_cond_value_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::value_int: + j.write_int("valueInt", c.get()); + break; + case types::value_enum: + j.write_int("valueEnum", c.get()); + break; + case types::value_bool: + j.write_bool("valueBool", c.get()); + break; + case types::value_bit_s: + j.write_str("valueBitS", c.get().to_string()); + break; + case types::value_oct_s: + j.write_str("valueOctS", c.get >().to_string()); + break; + case types::value_prt_s: + j.write_str("valuePrtS", c.get >().to_string()); + break; + case types::value_real: + j.write_fieldname("valueReal"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + } + j.end_obj(); +} +SRSASN_CODE test_cond_value_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::value_int: + HANDLE_CODE(pack_unconstrained_integer(bref, c.get(), false, true)); + break; + case types::value_enum: + HANDLE_CODE(pack_unconstrained_integer(bref, c.get(), false, true)); + break; + case types::value_bool: + HANDLE_CODE(bref.pack(c.get(), 1)); + break; + case types::value_bit_s: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::value_oct_s: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::value_prt_s: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::value_real: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE test_cond_value_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::value_int: + HANDLE_CODE(unpack_unconstrained_integer(c.get(), bref, false, true)); + break; + case types::value_enum: + HANDLE_CODE(unpack_unconstrained_integer(c.get(), bref, false, true)); + break; + case types::value_bool: + HANDLE_CODE(bref.unpack(c.get(), 1)); + break; + case types::value_bit_s: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::value_oct_s: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::value_prt_s: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::value_real: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + default: + log_invalid_choice_id(type_, "test_cond_value_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* test_cond_value_c::types_opts::to_string() const +{ + static const char* options[] = { + "valueInt", "valueEnum", "valueBool", "valueBitS", "valueOctS", "valuePrtS", "valueReal"}; + return convert_enum_idx(options, 7, value, "test_cond_value_c::types"); +} + +// ENB-ID ::= CHOICE +void enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_enb_id: + c.destroy >(); + break; + case types::home_enb_id: + c.destroy >(); + break; + case types::short_macro_enb_id: + c.destroy >(); + break; + case types::long_macro_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_enb_id: + c.init >(); + break; + case types::home_enb_id: + c.init >(); + break; + case types::short_macro_enb_id: + c.init >(); + break; + case types::long_macro_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c::enb_id_c(const enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_enb_id: + c.init(other.c.get >()); + break; + case types::home_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } +} +enb_id_c& enb_id_c::operator=(const enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_enb_id: + c.set(other.c.get >()); + break; + case types::home_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& enb_id_c::set_macro_enb_id() +{ + set(types::macro_enb_id); + return c.get >(); +} +fixed_bitstring<28, false, true>& enb_id_c::set_home_enb_id() +{ + set(types::home_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& enb_id_c::set_short_macro_enb_id() +{ + set(types::short_macro_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& enb_id_c::set_long_macro_enb_id() +{ + set(types::long_macro_enb_id); + return c.get >(); +} +void enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_enb_id: + j.write_str("macro-eNB-ID", c.get >().to_string()); + break; + case types::home_enb_id: + j.write_str("home-eNB-ID", c.get >().to_string()); + break; + case types::short_macro_enb_id: + j.write_str("short-Macro-eNB-ID", c.get >().to_string()); + break; + case types::long_macro_enb_id: + j.write_str("long-Macro-eNB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().pack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::home_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + case types::long_macro_enb_id: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE((c.get >().unpack(bref))); + } break; + default: + log_invalid_choice_id(type_, "enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macro-eNB-ID", "home-eNB-ID", "short-Macro-eNB-ID", "long-Macro-eNB-ID"}; + return convert_enum_idx(options, 4, value, "enb_id_c::types"); +} + +// GNB-ID ::= CHOICE +void gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"gNB-ID"}; + return convert_enum_idx(options, 1, value, "gnb_id_c::types"); +} + +// MeasurementLabel ::= SEQUENCE +SRSASN_CODE meas_label_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(no_label_present, 1)); + HANDLE_CODE(bref.pack(plmn_id_present, 1)); + HANDLE_CODE(bref.pack(slice_id_present, 1)); + HANDLE_CODE(bref.pack(five_qi_present, 1)); + HANDLE_CODE(bref.pack(qfi_present, 1)); + HANDLE_CODE(bref.pack(qci_present, 1)); + HANDLE_CODE(bref.pack(qcimax_present, 1)); + HANDLE_CODE(bref.pack(qcimin_present, 1)); + HANDLE_CODE(bref.pack(arpmax_present, 1)); + HANDLE_CODE(bref.pack(arpmin_present, 1)); + HANDLE_CODE(bref.pack(bitrate_range_present, 1)); + HANDLE_CODE(bref.pack(layer_mu_mimo_present, 1)); + HANDLE_CODE(bref.pack(sum_present, 1)); + HANDLE_CODE(bref.pack(dist_bin_x_present, 1)); + HANDLE_CODE(bref.pack(dist_bin_y_present, 1)); + HANDLE_CODE(bref.pack(dist_bin_z_present, 1)); + HANDLE_CODE(bref.pack(pre_label_override_present, 1)); + HANDLE_CODE(bref.pack(start_end_ind_present, 1)); + HANDLE_CODE(bref.pack(min_present, 1)); + HANDLE_CODE(bref.pack(max_present, 1)); + HANDLE_CODE(bref.pack(avg_present, 1)); + + if (no_label_present) { + HANDLE_CODE(no_label.pack(bref)); + } + if (plmn_id_present) { + HANDLE_CODE(plmn_id.pack(bref)); + } + if (slice_id_present) { + HANDLE_CODE(slice_id.pack(bref)); + } + if (five_qi_present) { + HANDLE_CODE(pack_integer(bref, five_qi, (uint16_t)0u, (uint16_t)255u, true, true)); + } + if (qfi_present) { + HANDLE_CODE(pack_integer(bref, qfi, (uint8_t)0u, (uint8_t)63u, true, true)); + } + if (qci_present) { + HANDLE_CODE(pack_integer(bref, qci, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qcimax_present) { + HANDLE_CODE(pack_integer(bref, qcimax, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qcimin_present) { + HANDLE_CODE(pack_integer(bref, qcimin, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (arpmax_present) { + HANDLE_CODE(pack_integer(bref, arpmax, (uint8_t)1u, (uint8_t)15u, true, true)); + } + if (arpmin_present) { + HANDLE_CODE(pack_integer(bref, arpmin, (uint8_t)1u, (uint8_t)15u, true, true)); + } + if (bitrate_range_present) { + HANDLE_CODE(pack_integer(bref, bitrate_range, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (layer_mu_mimo_present) { + HANDLE_CODE(pack_integer(bref, layer_mu_mimo, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (sum_present) { + HANDLE_CODE(sum.pack(bref)); + } + if (dist_bin_x_present) { + HANDLE_CODE(pack_integer(bref, dist_bin_x, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (dist_bin_y_present) { + HANDLE_CODE(pack_integer(bref, dist_bin_y, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (dist_bin_z_present) { + HANDLE_CODE(pack_integer(bref, dist_bin_z, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (pre_label_override_present) { + HANDLE_CODE(pre_label_override.pack(bref)); + } + if (start_end_ind_present) { + HANDLE_CODE(start_end_ind.pack(bref)); + } + if (min_present) { + HANDLE_CODE(min.pack(bref)); + } + if (max_present) { + HANDLE_CODE(max.pack(bref)); + } + if (avg_present) { + HANDLE_CODE(avg.pack(bref)); + } + + if (ext) { + HANDLE_CODE(bref.pack(ssb_idx_present, 1)); + HANDLE_CODE(bref.pack(non_go_b_bfmode_idx_present, 1)); + HANDLE_CODE(bref.pack(mimo_mode_idx_present, 1)); + + if (ssb_idx_present) { + HANDLE_CODE(pack_integer(bref, ssb_idx, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (non_go_b_bfmode_idx_present) { + HANDLE_CODE(pack_integer(bref, non_go_b_bfmode_idx, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (mimo_mode_idx_present) { + HANDLE_CODE(pack_integer(bref, mimo_mode_idx, (uint8_t)1u, (uint8_t)2u, true, true)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_label_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(no_label_present, 1)); + HANDLE_CODE(bref.unpack(plmn_id_present, 1)); + HANDLE_CODE(bref.unpack(slice_id_present, 1)); + HANDLE_CODE(bref.unpack(five_qi_present, 1)); + HANDLE_CODE(bref.unpack(qfi_present, 1)); + HANDLE_CODE(bref.unpack(qci_present, 1)); + HANDLE_CODE(bref.unpack(qcimax_present, 1)); + HANDLE_CODE(bref.unpack(qcimin_present, 1)); + HANDLE_CODE(bref.unpack(arpmax_present, 1)); + HANDLE_CODE(bref.unpack(arpmin_present, 1)); + HANDLE_CODE(bref.unpack(bitrate_range_present, 1)); + HANDLE_CODE(bref.unpack(layer_mu_mimo_present, 1)); + HANDLE_CODE(bref.unpack(sum_present, 1)); + HANDLE_CODE(bref.unpack(dist_bin_x_present, 1)); + HANDLE_CODE(bref.unpack(dist_bin_y_present, 1)); + HANDLE_CODE(bref.unpack(dist_bin_z_present, 1)); + HANDLE_CODE(bref.unpack(pre_label_override_present, 1)); + HANDLE_CODE(bref.unpack(start_end_ind_present, 1)); + HANDLE_CODE(bref.unpack(min_present, 1)); + HANDLE_CODE(bref.unpack(max_present, 1)); + HANDLE_CODE(bref.unpack(avg_present, 1)); + + if (no_label_present) { + HANDLE_CODE(no_label.unpack(bref)); + } + if (plmn_id_present) { + HANDLE_CODE(plmn_id.unpack(bref)); + } + if (slice_id_present) { + HANDLE_CODE(slice_id.unpack(bref)); + } + if (five_qi_present) { + HANDLE_CODE(unpack_integer(five_qi, bref, (uint16_t)0u, (uint16_t)255u, true, true)); + } + if (qfi_present) { + HANDLE_CODE(unpack_integer(qfi, bref, (uint8_t)0u, (uint8_t)63u, true, true)); + } + if (qci_present) { + HANDLE_CODE(unpack_integer(qci, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qcimax_present) { + HANDLE_CODE(unpack_integer(qcimax, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (qcimin_present) { + HANDLE_CODE(unpack_integer(qcimin, bref, (uint16_t)0u, (uint16_t)255u, false, true)); + } + if (arpmax_present) { + HANDLE_CODE(unpack_integer(arpmax, bref, (uint8_t)1u, (uint8_t)15u, true, true)); + } + if (arpmin_present) { + HANDLE_CODE(unpack_integer(arpmin, bref, (uint8_t)1u, (uint8_t)15u, true, true)); + } + if (bitrate_range_present) { + HANDLE_CODE(unpack_integer(bitrate_range, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (layer_mu_mimo_present) { + HANDLE_CODE(unpack_integer(layer_mu_mimo, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (sum_present) { + HANDLE_CODE(sum.unpack(bref)); + } + if (dist_bin_x_present) { + HANDLE_CODE(unpack_integer(dist_bin_x, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (dist_bin_y_present) { + HANDLE_CODE(unpack_integer(dist_bin_y, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (dist_bin_z_present) { + HANDLE_CODE(unpack_integer(dist_bin_z, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (pre_label_override_present) { + HANDLE_CODE(pre_label_override.unpack(bref)); + } + if (start_end_ind_present) { + HANDLE_CODE(start_end_ind.unpack(bref)); + } + if (min_present) { + HANDLE_CODE(min.unpack(bref)); + } + if (max_present) { + HANDLE_CODE(max.unpack(bref)); + } + if (avg_present) { + HANDLE_CODE(avg.unpack(bref)); + } + + if (ext) { + HANDLE_CODE(bref.unpack(ssb_idx_present, 1)); + HANDLE_CODE(bref.unpack(non_go_b_bfmode_idx_present, 1)); + HANDLE_CODE(bref.unpack(mimo_mode_idx_present, 1)); + + if (ssb_idx_present) { + HANDLE_CODE(unpack_integer(ssb_idx, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (non_go_b_bfmode_idx_present) { + HANDLE_CODE(unpack_integer(non_go_b_bfmode_idx, bref, (uint32_t)1u, (uint32_t)65535u, true, true)); + } + if (mimo_mode_idx_present) { + HANDLE_CODE(unpack_integer(mimo_mode_idx, bref, (uint8_t)1u, (uint8_t)2u, true, true)); + } + } + return SRSASN_SUCCESS; +} +void meas_label_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (no_label_present) { + j.write_str("noLabel", "true"); + } + if (plmn_id_present) { + j.write_str("plmnID", plmn_id.to_string()); + } + if (slice_id_present) { + j.write_fieldname("sliceID"); + slice_id.to_json(j); + } + if (five_qi_present) { + j.write_int("fiveQI", five_qi); + } + if (qfi_present) { + j.write_int("qFI", qfi); + } + if (qci_present) { + j.write_int("qCI", qci); + } + if (qcimax_present) { + j.write_int("qCImax", qcimax); + } + if (qcimin_present) { + j.write_int("qCImin", qcimin); + } + if (arpmax_present) { + j.write_int("aRPmax", arpmax); + } + if (arpmin_present) { + j.write_int("aRPmin", arpmin); + } + if (bitrate_range_present) { + j.write_int("bitrateRange", bitrate_range); + } + if (layer_mu_mimo_present) { + j.write_int("layerMU-MIMO", layer_mu_mimo); + } + if (sum_present) { + j.write_str("sUM", "true"); + } + if (dist_bin_x_present) { + j.write_int("distBinX", dist_bin_x); + } + if (dist_bin_y_present) { + j.write_int("distBinY", dist_bin_y); + } + if (dist_bin_z_present) { + j.write_int("distBinZ", dist_bin_z); + } + if (pre_label_override_present) { + j.write_str("preLabelOverride", "true"); + } + if (start_end_ind_present) { + j.write_str("startEndInd", start_end_ind.to_string()); + } + if (min_present) { + j.write_str("min", "true"); + } + if (max_present) { + j.write_str("max", "true"); + } + if (avg_present) { + j.write_str("avg", "true"); + } + if (ext) { + if (ssb_idx_present) { + j.write_int("ssbIndex", ssb_idx); + } + if (non_go_b_bfmode_idx_present) { + j.write_int("nonGoB-BFmode-Index", non_go_b_bfmode_idx); + } + if (mimo_mode_idx_present) { + j.write_int("mIMO-mode-Index", mimo_mode_idx); + } + } + j.end_obj(); +} + +const char* meas_label_s::no_label_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::no_label_e_"); +} + +const char* meas_label_s::sum_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::sum_e_"); +} + +const char* meas_label_s::pre_label_override_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::pre_label_override_e_"); +} + +const char* meas_label_s::start_end_ind_opts::to_string() const +{ + static const char* options[] = {"start", "end"}; + return convert_enum_idx(options, 2, value, "meas_label_s::start_end_ind_e_"); +} + +const char* meas_label_s::min_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::min_e_"); +} + +const char* meas_label_s::max_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::max_e_"); +} + +const char* meas_label_s::avg_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_label_s::avg_e_"); +} + +// NgENB-ID ::= CHOICE +void ng_enb_id_c::destroy_() +{ + switch (type_) { + case types::macro_ng_enb_id: + c.destroy >(); + break; + case types::short_macro_ng_enb_id: + c.destroy >(); + break; + case types::long_macro_ng_enb_id: + c.destroy >(); + break; + default: + break; + } +} +void ng_enb_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::macro_ng_enb_id: + c.init >(); + break; + case types::short_macro_ng_enb_id: + c.init >(); + break; + case types::long_macro_ng_enb_id: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c::ng_enb_id_c(const ng_enb_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } +} +ng_enb_id_c& ng_enb_id_c::operator=(const ng_enb_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::short_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::long_macro_ng_enb_id: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + + return *this; +} +fixed_bitstring<20, false, true>& ng_enb_id_c::set_macro_ng_enb_id() +{ + set(types::macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<18, false, true>& ng_enb_id_c::set_short_macro_ng_enb_id() +{ + set(types::short_macro_ng_enb_id); + return c.get >(); +} +fixed_bitstring<21, false, true>& ng_enb_id_c::set_long_macro_ng_enb_id() +{ + set(types::long_macro_ng_enb_id); + return c.get >(); +} +void ng_enb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::macro_ng_enb_id: + j.write_str("macroNgENB-ID", c.get >().to_string()); + break; + case types::short_macro_ng_enb_id: + j.write_str("shortMacroNgENB-ID", c.get >().to_string()); + break; + case types::long_macro_ng_enb_id: + j.write_str("longMacroNgENB-ID", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + } + j.end_obj(); +} +SRSASN_CODE ng_enb_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().pack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ng_enb_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::short_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + case types::long_macro_ng_enb_id: + HANDLE_CODE((c.get >().unpack(bref))); + break; + default: + log_invalid_choice_id(type_, "ng_enb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ng_enb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"macroNgENB-ID", "shortMacroNgENB-ID", "longMacroNgENB-ID"}; + return convert_enum_idx(options, 3, value, "ng_enb_id_c::types"); +} + +// TestCondInfo ::= SEQUENCE +SRSASN_CODE test_cond_info_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(test_expr_present, 1)); + HANDLE_CODE(bref.pack(test_value_present, 1)); + + HANDLE_CODE(test_type.pack(bref)); + if (test_expr_present) { + HANDLE_CODE(test_expr.pack(bref)); + } + if (test_value_present) { + HANDLE_CODE(test_value.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE test_cond_info_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(test_expr_present, 1)); + HANDLE_CODE(bref.unpack(test_value_present, 1)); + + HANDLE_CODE(test_type.unpack(bref)); + if (test_expr_present) { + HANDLE_CODE(test_expr.unpack(bref)); + } + if (test_value_present) { + HANDLE_CODE(test_value.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void test_cond_info_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("testType"); + test_type.to_json(j); + if (test_expr_present) { + j.write_str("testExpr", test_expr.to_string()); + } + if (test_value_present) { + j.write_fieldname("testValue"); + test_value.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB-CU-CP-E1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_e1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_e1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + j.end_obj(); +} + +// UEID-GNB-CU-CP-F1AP-ID-Item ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_cp_f1_ap_id_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_cp_f1_ap_id_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + j.end_obj(); +} + +// GlobalENB-ID ::= SEQUENCE +SRSASN_CODE global_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("eNB-ID"); + enb_id.to_json(j); + j.end_obj(); +} + +// GlobalGNB-ID ::= SEQUENCE +SRSASN_CODE global_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(gnb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(gnb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("gNB-ID"); + gnb_id.to_json(j); + j.end_obj(); +} + +// GlobalNgENB-ID ::= SEQUENCE +SRSASN_CODE global_ng_enb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(ng_enb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ng_enb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(ng_enb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void global_ng_enb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMNIdentity", plmn_id.to_string()); + j.write_fieldname("ngENB-ID"); + ng_enb_id.to_json(j); + j.end_obj(); +} + +// LabelInfoItem ::= SEQUENCE +SRSASN_CODE label_info_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(meas_label.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE label_info_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(meas_label.unpack(bref)); + + return SRSASN_SUCCESS; +} +void label_info_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measLabel"); + meas_label.to_json(j); + j.end_obj(); +} + +// LogicalOR ::= ENUMERATED +const char* lc_or_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "lc_or_e"); +} + +// MatchingCondItem-Choice ::= CHOICE +void matching_cond_item_choice_c::destroy_() +{ + switch (type_) { + case types::meas_label: + c.destroy(); + break; + case types::test_cond_info: + c.destroy(); + break; + default: + break; + } +} +void matching_cond_item_choice_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::meas_label: + c.init(); + break; + case types::test_cond_info: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + } +} +matching_cond_item_choice_c::matching_cond_item_choice_c(const matching_cond_item_choice_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::meas_label: + c.init(other.c.get()); + break; + case types::test_cond_info: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + } +} +matching_cond_item_choice_c& matching_cond_item_choice_c::operator=(const matching_cond_item_choice_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::meas_label: + c.set(other.c.get()); + break; + case types::test_cond_info: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + } + + return *this; +} +meas_label_s& matching_cond_item_choice_c::set_meas_label() +{ + set(types::meas_label); + return c.get(); +} +test_cond_info_s& matching_cond_item_choice_c::set_test_cond_info() +{ + set(types::test_cond_info); + return c.get(); +} +void matching_cond_item_choice_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::meas_label: + j.write_fieldname("measLabel"); + c.get().to_json(j); + break; + case types::test_cond_info: + j.write_fieldname("testCondInfo"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + } + j.end_obj(); +} +SRSASN_CODE matching_cond_item_choice_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::meas_label: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::test_cond_info: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_cond_item_choice_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::meas_label: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::test_cond_info: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "matching_cond_item_choice_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* matching_cond_item_choice_c::types_opts::to_string() const +{ + static const char* options[] = {"measLabel", "testCondInfo"}; + return convert_enum_idx(options, 2, value, "matching_cond_item_choice_c::types"); +} + +// MatchingCondItem ::= SEQUENCE +SRSASN_CODE matching_cond_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(lc_or_present, 1)); + + HANDLE_CODE(matching_cond_choice.pack(bref)); + if (lc_or_present) { + HANDLE_CODE(lc_or.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_cond_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(lc_or_present, 1)); + + HANDLE_CODE(matching_cond_choice.unpack(bref)); + if (lc_or_present) { + HANDLE_CODE(lc_or.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void matching_cond_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("matchingCondChoice"); + matching_cond_choice.to_json(j); + if (lc_or_present) { + j.write_str("logicalOR", "true"); + } + j.end_obj(); +} + +// UEID-EN-GNB ::= SEQUENCE +SRSASN_CODE ueid_en_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.pack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_en_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + HANDLE_CODE(global_enb_id.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_present) { + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_en_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + if (gnb_cu_ue_f1_ap_id_present) { + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-ENB ::= SEQUENCE +SRSASN_CODE ueid_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.pack(global_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, mme_ue_s1ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.pack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(pack_integer(bref, m_enb_ue_x2ap_id_ext, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_enb_ue_x2ap_id_ext_present, 1)); + HANDLE_CODE(bref.unpack(global_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(mme_ue_s1ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + HANDLE_CODE(gummei.unpack(bref)); + if (m_enb_ue_x2ap_id_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id, bref, (uint16_t)0u, (uint16_t)4095u, false, true)); + } + if (m_enb_ue_x2ap_id_ext_present) { + HANDLE_CODE(unpack_integer(m_enb_ue_x2ap_id_ext, bref, (uint16_t)0u, (uint16_t)4095u, true, true)); + } + if (global_enb_id_present) { + HANDLE_CODE(global_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("mME-UE-S1AP-ID", mme_ue_s1ap_id); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + if (m_enb_ue_x2ap_id_present) { + j.write_int("m-eNB-UE-X2AP-ID", m_enb_ue_x2ap_id); + } + if (m_enb_ue_x2ap_id_ext_present) { + j.write_int("m-eNB-UE-X2AP-ID-Extension", m_enb_ue_x2ap_id_ext); + } + if (global_enb_id_present) { + j.write_fieldname("globalENB-ID"); + global_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB ::= SEQUENCE +SRSASN_CODE ueid_gnb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(gnb_cu_ue_f1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(gnb_cu_cp_ue_e1_ap_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_gnb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_ue_f1_ap_id_list, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, gnb_cu_cp_ue_e1_ap_id_list, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool gnb_cu_ue_f1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_ue_f1_ap_id_list_present, 1)); + bool gnb_cu_cp_ue_e1_ap_id_list_present; + HANDLE_CODE(bref.unpack(gnb_cu_cp_ue_e1_ap_id_list_present, 1)); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_gnb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (gnb_cu_ue_f1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_ue_f1_ap_id_list, bref, 1, 4, true)); + } + if (gnb_cu_cp_ue_e1_ap_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(gnb_cu_cp_ue_e1_ap_id_list, bref, 1, 65535, true)); + } + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_gnb_id_present) { + HANDLE_CODE(global_gnb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (gnb_cu_ue_f1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-UE-F1AP-ID-List"); + for (const auto& e1 : gnb_cu_ue_f1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (gnb_cu_cp_ue_e1_ap_id_list.size() > 0) { + j.start_array("gNB-CU-CP-UE-E1AP-ID-List"); + for (const auto& e1 : gnb_cu_cp_ue_e1_ap_id_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_gnb_id_present) { + j.write_fieldname("globalGNB-ID"); + global_gnb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-GNB-CU-UP ::= SEQUENCE +SRSASN_CODE ueid_gnb_cu_up_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_cp_ue_e1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_cu_up_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_cp_ue_e1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_cu_up_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-CP-UE-E1AP-ID", gnb_cu_cp_ue_e1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-GNB-DU ::= SEQUENCE +SRSASN_CODE ueid_gnb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_ueid_present, 1)); + + HANDLE_CODE(pack_integer(bref, gnb_cu_ue_f1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_gnb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_ueid_present, 1)); + + HANDLE_CODE(unpack_integer(gnb_cu_ue_f1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + if (ran_ueid_present) { + HANDLE_CODE(ran_ueid.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_gnb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("gNB-CU-UE-F1AP-ID", gnb_cu_ue_f1_ap_id); + if (ran_ueid_present) { + j.write_str("ran-UEID", ran_ueid.to_string()); + } + j.end_obj(); +} + +// UEID-NG-ENB ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.pack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.pack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(pack_integer(bref, amf_ue_ngap_id, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.pack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(pack_integer(bref, m_ng_ran_ue_xn_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ng_enb_cu_ue_w1_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(m_ng_ran_ue_xn_ap_id_present, 1)); + HANDLE_CODE(bref.unpack(global_ng_enb_id_present, 1)); + + HANDLE_CODE(unpack_integer(amf_ue_ngap_id, bref, (uint64_t)0u, (uint64_t)1099511627775u, false, true)); + HANDLE_CODE(guami.unpack(bref)); + if (ng_enb_cu_ue_w1_ap_id_present) { + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (m_ng_ran_ue_xn_ap_id_present) { + HANDLE_CODE(unpack_integer(m_ng_ran_ue_xn_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + } + if (global_ng_enb_id_present) { + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("amf-UE-NGAP-ID", amf_ue_ngap_id); + j.write_fieldname("guami"); + guami.to_json(j); + if (ng_enb_cu_ue_w1_ap_id_present) { + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + } + if (m_ng_ran_ue_xn_ap_id_present) { + j.write_int("m-NG-RAN-UE-XnAP-ID", m_ng_ran_ue_xn_ap_id); + } + if (global_ng_enb_id_present) { + j.write_fieldname("globalNgENB-ID"); + global_ng_enb_id.to_json(j); + } + j.end_obj(); +} + +// UEID-NG-ENB-DU ::= SEQUENCE +SRSASN_CODE ueid_ng_enb_du_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, ng_enb_cu_ue_w1_ap_id, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_ng_enb_du_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(ng_enb_cu_ue_w1_ap_id, bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void ueid_ng_enb_du_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ng-eNB-CU-UE-W1AP-ID", ng_enb_cu_ue_w1_ap_id); + j.end_obj(); +} + +// MeasurementInfoItem ::= SEQUENCE +SRSASN_CODE meas_info_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(meas_type.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, label_info_list, 1, 2147483647, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_info_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(meas_type.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(label_info_list, bref, 1, 2147483647, true)); + + return SRSASN_SUCCESS; +} +void meas_info_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measType"); + meas_type.to_json(j); + j.start_array("labelInfoList"); + for (const auto& e1 : label_info_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// UEID ::= CHOICE +void ueid_c::destroy_() +{ + switch (type_) { + case types::gnb_ueid: + c.destroy(); + break; + case types::gnb_du_ueid: + c.destroy(); + break; + case types::gnb_cu_up_ueid: + c.destroy(); + break; + case types::ng_enb_ueid: + c.destroy(); + break; + case types::ng_enb_du_ueid: + c.destroy(); + break; + case types::en_g_nb_ueid: + c.destroy(); + break; + case types::enb_ueid: + c.destroy(); + break; + default: + break; + } +} +void ueid_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::gnb_ueid: + c.init(); + break; + case types::gnb_du_ueid: + c.init(); + break; + case types::gnb_cu_up_ueid: + c.init(); + break; + case types::ng_enb_ueid: + c.init(); + break; + case types::ng_enb_du_ueid: + c.init(); + break; + case types::en_g_nb_ueid: + c.init(); + break; + case types::enb_ueid: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c::ueid_c(const ueid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::gnb_ueid: + c.init(other.c.get()); + break; + case types::gnb_du_ueid: + c.init(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_ueid: + c.init(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.init(other.c.get()); + break; + case types::en_g_nb_ueid: + c.init(other.c.get()); + break; + case types::enb_ueid: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } +} +ueid_c& ueid_c::operator=(const ueid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::gnb_ueid: + c.set(other.c.get()); + break; + case types::gnb_du_ueid: + c.set(other.c.get()); + break; + case types::gnb_cu_up_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_ueid: + c.set(other.c.get()); + break; + case types::ng_enb_du_ueid: + c.set(other.c.get()); + break; + case types::en_g_nb_ueid: + c.set(other.c.get()); + break; + case types::enb_ueid: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + + return *this; +} +ueid_gnb_s& ueid_c::set_gnb_ueid() +{ + set(types::gnb_ueid); + return c.get(); +} +ueid_gnb_du_s& ueid_c::set_gnb_du_ueid() +{ + set(types::gnb_du_ueid); + return c.get(); +} +ueid_gnb_cu_up_s& ueid_c::set_gnb_cu_up_ueid() +{ + set(types::gnb_cu_up_ueid); + return c.get(); +} +ueid_ng_enb_s& ueid_c::set_ng_enb_ueid() +{ + set(types::ng_enb_ueid); + return c.get(); +} +ueid_ng_enb_du_s& ueid_c::set_ng_enb_du_ueid() +{ + set(types::ng_enb_du_ueid); + return c.get(); +} +ueid_en_gnb_s& ueid_c::set_en_g_nb_ueid() +{ + set(types::en_g_nb_ueid); + return c.get(); +} +ueid_enb_s& ueid_c::set_enb_ueid() +{ + set(types::enb_ueid); + return c.get(); +} +void ueid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::gnb_ueid: + j.write_fieldname("gNB-UEID"); + c.get().to_json(j); + break; + case types::gnb_du_ueid: + j.write_fieldname("gNB-DU-UEID"); + c.get().to_json(j); + break; + case types::gnb_cu_up_ueid: + j.write_fieldname("gNB-CU-UP-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_ueid: + j.write_fieldname("ng-eNB-UEID"); + c.get().to_json(j); + break; + case types::ng_enb_du_ueid: + j.write_fieldname("ng-eNB-DU-UEID"); + c.get().to_json(j); + break; + case types::en_g_nb_ueid: + j.write_fieldname("en-gNB-UEID"); + c.get().to_json(j); + break; + case types::enb_ueid: + j.write_fieldname("eNB-UEID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + } + j.end_obj(); +} +SRSASN_CODE ueid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ueid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::gnb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::gnb_cu_up_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ng_enb_du_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::en_g_nb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::enb_ueid: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ueid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ueid_c::types_opts::to_string() const +{ + static const char* options[] = { + "gNB-UEID", "gNB-DU-UEID", "gNB-CU-UP-UEID", "ng-eNB-UEID", "ng-eNB-DU-UEID", "en-gNB-UEID", "eNB-UEID"}; + return convert_enum_idx(options, 7, value, "ueid_c::types"); +} + +// MatchingUEidPerSubItem ::= SEQUENCE +SRSASN_CODE matching_ueid_per_sub_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ue_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ueid_per_sub_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ue_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void matching_ueid_per_sub_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ueID"); + ue_id.to_json(j); + j.end_obj(); +} + +// MatchingUeCondPerSubItem ::= SEQUENCE +SRSASN_CODE matching_ue_cond_per_sub_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(test_cond_info.pack(bref)); + + if (ext) { + HANDLE_CODE(bref.pack(lc_or_present, 1)); + + if (lc_or_present) { + HANDLE_CODE(lc_or.pack(bref)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ue_cond_per_sub_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(test_cond_info.unpack(bref)); + + if (ext) { + HANDLE_CODE(bref.unpack(lc_or_present, 1)); + + if (lc_or_present) { + HANDLE_CODE(lc_or.unpack(bref)); + } + } + return SRSASN_SUCCESS; +} +void matching_ue_cond_per_sub_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("testCondInfo"); + test_cond_info.to_json(j); + if (ext) { + if (lc_or_present) { + j.write_str("logicalOR", "true"); + } + } + j.end_obj(); +} + +// MeasurementCondItem ::= SEQUENCE +SRSASN_CODE meas_cond_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(meas_type.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, matching_cond, 1, 32768, true)); + + if (ext) { + HANDLE_CODE(bref.pack(bin_range_def.is_present(), 1)); + + if (bin_range_def.is_present()) { + HANDLE_CODE(bin_range_def->pack(bref)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_cond_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(meas_type.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(matching_cond, bref, 1, 32768, true)); + + if (ext) { + bool bin_range_def_present; + HANDLE_CODE(bref.unpack(bin_range_def_present, 1)); + bin_range_def.set_present(bin_range_def_present); + + if (bin_range_def.is_present()) { + HANDLE_CODE(bin_range_def->unpack(bref)); + } + } + return SRSASN_SUCCESS; +} +void meas_cond_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measType"); + meas_type.to_json(j); + j.start_array("matchingCond"); + for (const auto& e1 : matching_cond) { + e1.to_json(j); + } + j.end_array(); + if (ext) { + if (bin_range_def.is_present()) { + j.write_fieldname("binRangeDef"); + bin_range_def->to_json(j); + } + } + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(cell_global_id_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, meas_info_list, 1, 65535, true)); + HANDLE_CODE(pack_integer(bref, granul_period, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + if (cell_global_id_present) { + HANDLE_CODE(cell_global_id.pack(bref)); + } + + if (ext) { + HANDLE_CODE(bref.pack(dist_meas_bin_range_info.is_present(), 1)); + + if (dist_meas_bin_range_info.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *dist_meas_bin_range_info, 1, 65535, true)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(cell_global_id_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(meas_info_list, bref, 1, 65535, true)); + HANDLE_CODE(unpack_integer(granul_period, bref, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + if (cell_global_id_present) { + HANDLE_CODE(cell_global_id.unpack(bref)); + } + + if (ext) { + bool dist_meas_bin_range_info_present; + HANDLE_CODE(bref.unpack(dist_meas_bin_range_info_present, 1)); + dist_meas_bin_range_info.set_present(dist_meas_bin_range_info_present); + + if (dist_meas_bin_range_info.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*dist_meas_bin_range_info, bref, 1, 65535, true)); + } + } + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_format1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("measInfoList"); + for (const auto& e1 : meas_info_list) { + e1.to_json(j); + } + j.end_array(); + j.write_int("granulPeriod", granul_period); + if (cell_global_id_present) { + j.write_fieldname("cellGlobalID"); + cell_global_id.to_json(j); + } + if (ext) { + if (dist_meas_bin_range_info.is_present()) { + j.start_array("distMeasBinRangeInfo"); + for (const auto& e1 : *dist_meas_bin_range_info) { + e1.to_json(j); + } + j.end_array(); + } + } + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition-Format2 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_format2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ue_id.pack(bref)); + HANDLE_CODE(subscript_info.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_format2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ue_id.unpack(bref)); + HANDLE_CODE(subscript_info.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_format2_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ueID"); + ue_id.to_json(j); + j.write_fieldname("subscriptInfo"); + subscript_info.to_json(j); + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition-Format3 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_format3_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(cell_global_id_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, meas_cond_list, 1, 65535, true)); + HANDLE_CODE(pack_integer(bref, granul_period, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + if (cell_global_id_present) { + HANDLE_CODE(cell_global_id.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_format3_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(cell_global_id_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(meas_cond_list, bref, 1, 65535, true)); + HANDLE_CODE(unpack_integer(granul_period, bref, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + if (cell_global_id_present) { + HANDLE_CODE(cell_global_id.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_format3_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("measCondList"); + for (const auto& e1 : meas_cond_list) { + e1.to_json(j); + } + j.end_array(); + j.write_int("granulPeriod", granul_period); + if (cell_global_id_present) { + j.write_fieldname("cellGlobalID"); + cell_global_id.to_json(j); + } + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition-Format4 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_format4_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, matching_ue_cond_list, 1, 32768, true)); + HANDLE_CODE(subscription_info.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_format4_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(matching_ue_cond_list, bref, 1, 32768, true)); + HANDLE_CODE(subscription_info.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_format4_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("matchingUeCondList"); + for (const auto& e1 : matching_ue_cond_list) { + e1.to_json(j); + } + j.end_array(); + j.write_fieldname("subscriptionInfo"); + subscription_info.to_json(j); + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition-Format5 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_format5_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, matching_ueid_list, 2, 65535, true)); + HANDLE_CODE(subscription_info.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_format5_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(matching_ueid_list, bref, 2, 65535, true)); + HANDLE_CODE(subscription_info.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_format5_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("matchingUEidList"); + for (const auto& e1 : matching_ueid_list) { + e1.to_json(j); + } + j.end_array(); + j.write_fieldname("subscriptionInfo"); + subscription_info.to_json(j); + j.end_obj(); +} + +// E2SM-KPM-ActionDefinition ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_action_definition_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_style_type, false, true)); + HANDLE_CODE(action_definition_formats.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_style_type, bref, false, true)); + HANDLE_CODE(action_definition_formats.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_action_definition_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-Style-Type", ric_style_type); + j.write_fieldname("actionDefinition-formats"); + action_definition_formats.to_json(j); + j.end_obj(); +} + +void e2_sm_kpm_action_definition_s::action_definition_formats_c_::destroy_() +{ + switch (type_) { + case types::action_definition_format1: + c.destroy(); + break; + case types::action_definition_format2: + c.destroy(); + break; + case types::action_definition_format3: + c.destroy(); + break; + case types::action_definition_format4: + c.destroy(); + break; + case types::action_definition_format5: + c.destroy(); + break; + default: + break; + } +} +void e2_sm_kpm_action_definition_s::action_definition_formats_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::action_definition_format1: + c.init(); + break; + case types::action_definition_format2: + c.init(); + break; + case types::action_definition_format3: + c.init(); + break; + case types::action_definition_format4: + c.init(); + break; + case types::action_definition_format5: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + } +} +e2_sm_kpm_action_definition_s::action_definition_formats_c_::action_definition_formats_c_( + const e2_sm_kpm_action_definition_s::action_definition_formats_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::action_definition_format1: + c.init(other.c.get()); + break; + case types::action_definition_format2: + c.init(other.c.get()); + break; + case types::action_definition_format3: + c.init(other.c.get()); + break; + case types::action_definition_format4: + c.init(other.c.get()); + break; + case types::action_definition_format5: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + } +} +e2_sm_kpm_action_definition_s::action_definition_formats_c_& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::operator=( + const e2_sm_kpm_action_definition_s::action_definition_formats_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::action_definition_format1: + c.set(other.c.get()); + break; + case types::action_definition_format2: + c.set(other.c.get()); + break; + case types::action_definition_format3: + c.set(other.c.get()); + break; + case types::action_definition_format4: + c.set(other.c.get()); + break; + case types::action_definition_format5: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + } + + return *this; +} +e2_sm_kpm_action_definition_format1_s& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::set_action_definition_format1() +{ + set(types::action_definition_format1); + return c.get(); +} +e2_sm_kpm_action_definition_format2_s& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::set_action_definition_format2() +{ + set(types::action_definition_format2); + return c.get(); +} +e2_sm_kpm_action_definition_format3_s& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::set_action_definition_format3() +{ + set(types::action_definition_format3); + return c.get(); +} +e2_sm_kpm_action_definition_format4_s& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::set_action_definition_format4() +{ + set(types::action_definition_format4); + return c.get(); +} +e2_sm_kpm_action_definition_format5_s& +e2_sm_kpm_action_definition_s::action_definition_formats_c_::set_action_definition_format5() +{ + set(types::action_definition_format5); + return c.get(); +} +void e2_sm_kpm_action_definition_s::action_definition_formats_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::action_definition_format1: + j.write_fieldname("actionDefinition-Format1"); + c.get().to_json(j); + break; + case types::action_definition_format2: + j.write_fieldname("actionDefinition-Format2"); + c.get().to_json(j); + break; + case types::action_definition_format3: + j.write_fieldname("actionDefinition-Format3"); + c.get().to_json(j); + break; + case types::action_definition_format4: + j.write_fieldname("actionDefinition-Format4"); + c.get().to_json(j); + break; + case types::action_definition_format5: + j.write_fieldname("actionDefinition-Format5"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + } + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_action_definition_s::action_definition_formats_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::action_definition_format1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::action_definition_format2: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::action_definition_format3: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::action_definition_format4: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::action_definition_format5: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_action_definition_s::action_definition_formats_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::action_definition_format1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::action_definition_format2: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::action_definition_format3: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::action_definition_format4: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::action_definition_format5: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_action_definition_s::action_definition_formats_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_action_definition_s::action_definition_formats_c_::types_opts::to_string() const +{ + static const char* options[] = {"actionDefinition-Format1", + "actionDefinition-Format2", + "actionDefinition-Format3", + "actionDefinition-Format4", + "actionDefinition-Format5"}; + return convert_enum_idx(options, 5, value, "e2_sm_kpm_action_definition_s::action_definition_formats_c_::types"); +} +uint8_t e2_sm_kpm_action_definition_s::action_definition_formats_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3, 4, 5}; + return map_enum_number(options, 5, value, "e2_sm_kpm_action_definition_s::action_definition_formats_c_::types"); +} + +// E2SM-KPM-EventTriggerDefinition-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_event_trigger_definition_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, report_period, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(report_period, bref, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_event_trigger_definition_format1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("reportingPeriod", report_period); + j.end_obj(); +} + +// E2SM-KPM-EventTriggerDefinition ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_event_trigger_definition_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(event_definition_formats.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(event_definition_formats.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_event_trigger_definition_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("eventDefinition-formats"); + event_definition_formats.to_json(j); + j.end_obj(); +} + +void e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("eventDefinition-Format1"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::types_opts::to_string() const +{ + static const char* options[] = {"eventDefinition-Format1"}; + return convert_enum_idx( + options, 1, value, "e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::types"); +} +uint8_t e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "e2_sm_kpm_event_trigger_definition_s::event_definition_formats_c_::types"); +} + +// E2SM-KPM-IndicationHeader-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_hdr_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(file_formatversion_present, 1)); + HANDLE_CODE(bref.pack(sender_name_present, 1)); + HANDLE_CODE(bref.pack(sender_type_present, 1)); + HANDLE_CODE(bref.pack(vendor_name_present, 1)); + + HANDLE_CODE(collet_start_time.pack(bref)); + if (file_formatversion_present) { + HANDLE_CODE(file_formatversion.pack(bref)); + } + if (sender_name_present) { + HANDLE_CODE(sender_name.pack(bref)); + } + if (sender_type_present) { + HANDLE_CODE(sender_type.pack(bref)); + } + if (vendor_name_present) { + HANDLE_CODE(vendor_name.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_hdr_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(file_formatversion_present, 1)); + HANDLE_CODE(bref.unpack(sender_name_present, 1)); + HANDLE_CODE(bref.unpack(sender_type_present, 1)); + HANDLE_CODE(bref.unpack(vendor_name_present, 1)); + + HANDLE_CODE(collet_start_time.unpack(bref)); + if (file_formatversion_present) { + HANDLE_CODE(file_formatversion.unpack(bref)); + } + if (sender_name_present) { + HANDLE_CODE(sender_name.unpack(bref)); + } + if (sender_type_present) { + HANDLE_CODE(sender_type.unpack(bref)); + } + if (vendor_name_present) { + HANDLE_CODE(vendor_name.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_hdr_format1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("colletStartTime", collet_start_time.to_string()); + if (file_formatversion_present) { + j.write_str("fileFormatversion", file_formatversion.to_string()); + } + if (sender_name_present) { + j.write_str("senderName", sender_name.to_string()); + } + if (sender_type_present) { + j.write_str("senderType", sender_type.to_string()); + } + if (vendor_name_present) { + j.write_str("vendorName", vendor_name.to_string()); + } + j.end_obj(); +} + +// E2SM-KPM-IndicationHeader ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_hdr_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ind_hdr_formats.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_hdr_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ind_hdr_formats.unpack(bref)); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_hdr_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("indicationHeader-formats"); + ind_hdr_formats.to_json(j); + j.end_obj(); +} + +void e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("indicationHeader-Format1"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::types_opts::to_string() const +{ + static const char* options[] = {"indicationHeader-Format1"}; + return convert_enum_idx(options, 1, value, "e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::types"); +} +uint8_t e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "e2_sm_kpm_ind_hdr_s::ind_hdr_formats_c_::types"); +} + +// MeasurementRecordItem ::= CHOICE +void meas_record_item_c::destroy_() +{ + switch (type_) { + case types::real: + c.destroy(); + break; + default: + break; + } +} +void meas_record_item_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::integer: + break; + case types::real: + c.init(); + break; + case types::no_value: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + } +} +meas_record_item_c::meas_record_item_c(const meas_record_item_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::integer: + c.init(other.c.get()); + break; + case types::real: + c.init(other.c.get()); + break; + case types::no_value: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + } +} +meas_record_item_c& meas_record_item_c::operator=(const meas_record_item_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::integer: + c.set(other.c.get()); + break; + case types::real: + c.set(other.c.get()); + break; + case types::no_value: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + } + + return *this; +} +uint64_t& meas_record_item_c::set_integer() +{ + set(types::integer); + return c.get(); +} +real_s& meas_record_item_c::set_real() +{ + set(types::real); + return c.get(); +} +void meas_record_item_c::set_no_value() +{ + set(types::no_value); +} +void meas_record_item_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::integer: + j.write_int("integer", c.get()); + break; + case types::real: + j.write_fieldname("real"); + c.get().to_json(j); + break; + case types::no_value: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + } + j.end_obj(); +} +SRSASN_CODE meas_record_item_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::integer: + HANDLE_CODE(pack_integer(bref, c.get(), (uint64_t)0u, (uint64_t)4294967295u, false, true)); + break; + case types::real: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::no_value: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_record_item_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::integer: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); + break; + case types::real: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::no_value: + break; + default: + log_invalid_choice_id(type_, "meas_record_item_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* meas_record_item_c::types_opts::to_string() const +{ + static const char* options[] = {"integer", "real", "noValue"}; + return convert_enum_idx(options, 3, value, "meas_record_item_c::types"); +} + +// MatchingUEidItem-PerGP ::= SEQUENCE +SRSASN_CODE matching_ueid_item_per_gp_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ue_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ueid_item_per_gp_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ue_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void matching_ueid_item_per_gp_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ueID"); + ue_id.to_json(j); + j.end_obj(); +} + +// MeasurementDataItem ::= SEQUENCE +SRSASN_CODE meas_data_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(incomplete_flag_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, meas_record, 1, 2147483647, true)); + if (incomplete_flag_present) { + HANDLE_CODE(incomplete_flag.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_data_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(incomplete_flag_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(meas_record, bref, 1, 2147483647, true)); + if (incomplete_flag_present) { + HANDLE_CODE(incomplete_flag.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void meas_data_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("measRecord"); + for (const auto& e1 : meas_record) { + e1.to_json(j); + } + j.end_array(); + if (incomplete_flag_present) { + j.write_str("incompleteFlag", "true"); + } + j.end_obj(); +} + +const char* meas_data_item_s::incomplete_flag_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "meas_data_item_s::incomplete_flag_e_"); +} + +// MatchingUEidItem ::= SEQUENCE +SRSASN_CODE matching_ueid_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ue_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ueid_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ue_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void matching_ueid_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ueID"); + ue_id.to_json(j); + j.end_obj(); +} + +// MatchingUEidPerGP-Item ::= SEQUENCE +SRSASN_CODE matching_ueid_per_gp_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(matched_per_gp.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ueid_per_gp_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(matched_per_gp.unpack(bref)); + + return SRSASN_SUCCESS; +} +void matching_ueid_per_gp_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("matchedPerGP"); + matched_per_gp.to_json(j); + j.end_obj(); +} + +void matching_ueid_per_gp_item_s::matched_per_gp_c_::destroy_() +{ + switch (type_) { + case types::one_or_more_uematched: + c.destroy(); + break; + default: + break; + } +} +void matching_ueid_per_gp_item_s::matched_per_gp_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::no_uematched: + break; + case types::one_or_more_uematched: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + } +} +matching_ueid_per_gp_item_s::matched_per_gp_c_::matched_per_gp_c_( + const matching_ueid_per_gp_item_s::matched_per_gp_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::no_uematched: + c.init(other.c.get()); + break; + case types::one_or_more_uematched: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + } +} +matching_ueid_per_gp_item_s::matched_per_gp_c_& +matching_ueid_per_gp_item_s::matched_per_gp_c_::operator=(const matching_ueid_per_gp_item_s::matched_per_gp_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::no_uematched: + c.set(other.c.get()); + break; + case types::one_or_more_uematched: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + } + + return *this; +} +matching_ueid_per_gp_item_s::matched_per_gp_c_::no_uematched_e_& +matching_ueid_per_gp_item_s::matched_per_gp_c_::set_no_uematched() +{ + set(types::no_uematched); + return c.get(); +} +matching_ueid_list_per_gp_l& matching_ueid_per_gp_item_s::matched_per_gp_c_::set_one_or_more_uematched() +{ + set(types::one_or_more_uematched); + return c.get(); +} +void matching_ueid_per_gp_item_s::matched_per_gp_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::no_uematched: + j.write_str("noUEmatched", "true"); + break; + case types::one_or_more_uematched: + j.start_array("oneOrMoreUEmatched"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + } + j.end_obj(); +} +SRSASN_CODE matching_ueid_per_gp_item_s::matched_per_gp_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::no_uematched: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::one_or_more_uematched: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 65535, true)); + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE matching_ueid_per_gp_item_s::matched_per_gp_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::no_uematched: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::one_or_more_uematched: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 65535, true)); + break; + default: + log_invalid_choice_id(type_, "matching_ueid_per_gp_item_s::matched_per_gp_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* matching_ueid_per_gp_item_s::matched_per_gp_c_::no_uematched_opts::to_string() const +{ + static const char* options[] = {"true"}; + return convert_enum_idx(options, 1, value, "matching_ueid_per_gp_item_s::matched_per_gp_c_::no_uematched_e_"); +} + +const char* matching_ueid_per_gp_item_s::matched_per_gp_c_::types_opts::to_string() const +{ + static const char* options[] = {"noUEmatched", "oneOrMoreUEmatched"}; + return convert_enum_idx(options, 2, value, "matching_ueid_per_gp_item_s::matched_per_gp_c_::types"); +} +uint8_t matching_ueid_per_gp_item_s::matched_per_gp_c_::types_opts::to_number() const +{ + if (value == one_or_more_uematched) { + return 1; + } + invalid_enum_number(value, "matching_ueid_per_gp_item_s::matched_per_gp_c_::types"); + return 0; +} + +// E2SM-KPM-IndicationMessage-Format1 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_msg_format1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(meas_info_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(granul_period_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, meas_data, 1, 65535, true)); + if (meas_info_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_info_list, 1, 65535, true)); + } + if (granul_period_present) { + HANDLE_CODE(pack_integer(bref, granul_period, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + } + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_format1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool meas_info_list_present; + HANDLE_CODE(bref.unpack(meas_info_list_present, 1)); + HANDLE_CODE(bref.unpack(granul_period_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(meas_data, bref, 1, 65535, true)); + if (meas_info_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_info_list, bref, 1, 65535, true)); + } + if (granul_period_present) { + HANDLE_CODE(unpack_integer(granul_period, bref, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + } + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_msg_format1_s::to_json(json_writer& j) const +{ + j.start_array(); + j.start_obj(); + j.start_obj("E2SM-KPM-IndicationMessage-Format1"); + j.start_array("measData"); + for (const auto& e1 : meas_data) { + e1.to_json(j); + } + j.end_array(); + if (meas_info_list.size() > 0) { + j.start_array("measInfoList"); + for (const auto& e1 : meas_info_list) { + e1.to_json(j); + } + j.end_array(); + } + if (granul_period_present) { + j.write_int("granulPeriod", granul_period); + } + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +// MeasurementCondUEidItem ::= SEQUENCE +SRSASN_CODE meas_cond_ueid_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(matching_ueid_list.size() > 0, 1)); + + HANDLE_CODE(meas_type.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, matching_cond, 1, 32768, true)); + if (matching_ueid_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, matching_ueid_list, 1, 65535, true)); + } + + if (ext) { + HANDLE_CODE(bref.pack(matching_ueid_per_gp.is_present(), 1)); + + if (matching_ueid_per_gp.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *matching_ueid_per_gp, 1, 65535, true)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_cond_ueid_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool matching_ueid_list_present; + HANDLE_CODE(bref.unpack(matching_ueid_list_present, 1)); + + HANDLE_CODE(meas_type.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(matching_cond, bref, 1, 32768, true)); + if (matching_ueid_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(matching_ueid_list, bref, 1, 65535, true)); + } + + if (ext) { + bool matching_ueid_per_gp_present; + HANDLE_CODE(bref.unpack(matching_ueid_per_gp_present, 1)); + matching_ueid_per_gp.set_present(matching_ueid_per_gp_present); + + if (matching_ueid_per_gp.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*matching_ueid_per_gp, bref, 1, 65535, true)); + } + } + return SRSASN_SUCCESS; +} +void meas_cond_ueid_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measType"); + meas_type.to_json(j); + j.start_array("matchingCond"); + for (const auto& e1 : matching_cond) { + e1.to_json(j); + } + j.end_array(); + if (matching_ueid_list.size() > 0) { + j.start_array("matchingUEidList"); + for (const auto& e1 : matching_ueid_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ext) { + if (matching_ueid_per_gp.is_present()) { + j.start_array("matchingUEidPerGP"); + for (const auto& e1 : *matching_ueid_per_gp) { + e1.to_json(j); + } + j.end_array(); + } + } + j.end_obj(); +} + +// UEMeasurementReportItem ::= SEQUENCE +SRSASN_CODE ue_meas_report_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ue_id.pack(bref)); + HANDLE_CODE(meas_report.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_meas_report_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ue_id.unpack(bref)); + HANDLE_CODE(meas_report.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ue_meas_report_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ueID"); + ue_id.to_json(j); + j.write_fieldname("measReport"); + meas_report.to_json(j); + j.end_obj(); +} + +// E2SM-KPM-IndicationMessage-Format2 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_msg_format2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(granul_period_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, meas_data, 1, 65535, true)); + HANDLE_CODE(pack_dyn_seq_of(bref, meas_cond_ueid_list, 1, 65535, true)); + if (granul_period_present) { + HANDLE_CODE(pack_integer(bref, granul_period, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + } + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_format2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(granul_period_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(meas_data, bref, 1, 65535, true)); + HANDLE_CODE(unpack_dyn_seq_of(meas_cond_ueid_list, bref, 1, 65535, true)); + if (granul_period_present) { + HANDLE_CODE(unpack_integer(granul_period, bref, (uint64_t)1u, (uint64_t)4294967295u, false, true)); + } + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_msg_format2_s::to_json(json_writer& j) const +{ + j.start_array(); + j.start_obj(); + j.start_obj("E2SM-KPM-IndicationMessage-Format2"); + j.start_array("measData"); + for (const auto& e1 : meas_data) { + e1.to_json(j); + } + j.end_array(); + j.start_array("measCondUEidList"); + for (const auto& e1 : meas_cond_ueid_list) { + e1.to_json(j); + } + j.end_array(); + if (granul_period_present) { + j.write_int("granulPeriod", granul_period); + } + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +// E2SM-KPM-IndicationMessage-Format3 ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_msg_format3_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, ue_meas_report_list, 1, 65535, true)); + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_format3_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(ue_meas_report_list, bref, 1, 65535, true)); + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_msg_format3_s::to_json(json_writer& j) const +{ + j.start_array(); + j.start_obj(); + j.start_obj("E2SM-KPM-IndicationMessage-Format3"); + j.start_array("ueMeasReportList"); + for (const auto& e1 : ue_meas_report_list) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +// E2SM-KPM-IndicationMessage ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ind_msg_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(ind_msg_formats.pack(bref)); + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(ind_msg_formats.unpack(bref)); + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ind_msg_s::to_json(json_writer& j) const +{ + j.start_array(); + j.start_obj(); + j.start_obj("E2SM-KPM-IndicationMessage"); + j.write_fieldname("indicationMessage-formats"); + ind_msg_formats.to_json(j); + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +void e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::destroy_() +{ + switch (type_) { + case types::ind_msg_format1: + c.destroy(); + break; + case types::ind_msg_format2: + c.destroy(); + break; + case types::ind_msg_format3: + c.destroy(); + break; + default: + break; + } +} +void e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ind_msg_format1: + c.init(); + break; + case types::ind_msg_format2: + c.init(); + break; + case types::ind_msg_format3: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + } +} +e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::ind_msg_formats_c_(const e2_sm_kpm_ind_msg_s::ind_msg_formats_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::ind_msg_format1: + c.init(other.c.get()); + break; + case types::ind_msg_format2: + c.init(other.c.get()); + break; + case types::ind_msg_format3: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + } +} +e2_sm_kpm_ind_msg_s::ind_msg_formats_c_& +e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::operator=(const e2_sm_kpm_ind_msg_s::ind_msg_formats_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ind_msg_format1: + c.set(other.c.get()); + break; + case types::ind_msg_format2: + c.set(other.c.get()); + break; + case types::ind_msg_format3: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + } + + return *this; +} +e2_sm_kpm_ind_msg_format1_s& e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::set_ind_msg_format1() +{ + set(types::ind_msg_format1); + return c.get(); +} +e2_sm_kpm_ind_msg_format2_s& e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::set_ind_msg_format2() +{ + set(types::ind_msg_format2); + return c.get(); +} +e2_sm_kpm_ind_msg_format3_s& e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::set_ind_msg_format3() +{ + set(types::ind_msg_format3); + return c.get(); +} +void e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ind_msg_format1: + j.write_fieldname("indicationMessage-Format1"); + c.get().to_json(j); + break; + case types::ind_msg_format2: + j.write_fieldname("indicationMessage-Format2"); + c.get().to_json(j); + break; + case types::ind_msg_format3: + j.write_fieldname("indicationMessage-Format3"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + } + j.end_obj(); +} +SRSASN_CODE e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ind_msg_format1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ind_msg_format2: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ind_msg_format3: { + varlength_field_pack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().pack(bref)); + } break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ind_msg_format1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ind_msg_format2: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ind_msg_format3: { + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(c.get().unpack(bref)); + } break; + default: + log_invalid_choice_id(type_, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::to_string() const +{ + static const char* options[] = { + "indicationMessage-Format1", "indicationMessage-Format2", "indicationMessage-Format3"}; + return convert_enum_idx(options, 3, value, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types"); +} +uint8_t e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3}; + return map_enum_number(options, 3, value, "e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types"); +} + +// MeasurementInfo-Action-Item ::= SEQUENCE +SRSASN_CODE meas_info_action_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(meas_id_present, 1)); + + HANDLE_CODE(meas_name.pack(bref)); + if (meas_id_present) { + HANDLE_CODE(pack_integer(bref, meas_id, (uint32_t)1u, (uint32_t)65536u, true, true)); + } + + if (ext) { + HANDLE_CODE(bref.pack(bin_range_def.is_present(), 1)); + + if (bin_range_def.is_present()) { + HANDLE_CODE(bin_range_def->pack(bref)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_info_action_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(meas_id_present, 1)); + + HANDLE_CODE(meas_name.unpack(bref)); + if (meas_id_present) { + HANDLE_CODE(unpack_integer(meas_id, bref, (uint32_t)1u, (uint32_t)65536u, true, true)); + } + + if (ext) { + bool bin_range_def_present; + HANDLE_CODE(bref.unpack(bin_range_def_present, 1)); + bin_range_def.set_present(bin_range_def_present); + + if (bin_range_def.is_present()) { + HANDLE_CODE(bin_range_def->unpack(bref)); + } + } + return SRSASN_SUCCESS; +} +void meas_info_action_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("measName", meas_name.to_string()); + if (meas_id_present) { + j.write_int("measID", meas_id); + } + if (ext) { + if (bin_range_def.is_present()) { + j.write_fieldname("binRangeDef"); + bin_range_def->to_json(j); + } + } + j.end_obj(); +} + +// RANfunction-Name ::= SEQUENCE +SRSASN_CODE ra_nfunction_name_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ran_function_instance_present, 1)); + + HANDLE_CODE(ran_function_short_name.pack(bref)); + HANDLE_CODE(ran_function_e2_sm_oid.pack(bref)); + HANDLE_CODE(ran_function_description.pack(bref)); + if (ran_function_instance_present) { + HANDLE_CODE(pack_unconstrained_integer(bref, ran_function_instance, false, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ra_nfunction_name_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ran_function_instance_present, 1)); + + HANDLE_CODE(ran_function_short_name.unpack(bref)); + HANDLE_CODE(ran_function_e2_sm_oid.unpack(bref)); + HANDLE_CODE(ran_function_description.unpack(bref)); + if (ran_function_instance_present) { + HANDLE_CODE(unpack_unconstrained_integer(ran_function_instance, bref, false, true)); + } + + return SRSASN_SUCCESS; +} +void ra_nfunction_name_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ranFunction-ShortName", ran_function_short_name.to_string()); + j.write_str("ranFunction-E2SM-OID", ran_function_e2_sm_oid.to_string()); + j.write_str("ranFunction-Description", ran_function_description.to_string()); + if (ran_function_instance_present) { + j.write_int("ranFunction-Instance", ran_function_instance); + } + j.end_obj(); +} + +// RIC-EventTriggerStyle-Item ::= SEQUENCE +SRSASN_CODE ric_event_trigger_style_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_event_trigger_style_type, false, true)); + HANDLE_CODE(ric_event_trigger_style_name.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_event_trigger_format_type, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ric_event_trigger_style_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_event_trigger_style_type, bref, false, true)); + HANDLE_CODE(ric_event_trigger_style_name.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(ric_event_trigger_format_type, bref, false, true)); + + return SRSASN_SUCCESS; +} +void ric_event_trigger_style_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-EventTriggerStyle-Type", ric_event_trigger_style_type); + j.write_str("ric-EventTriggerStyle-Name", ric_event_trigger_style_name.to_string()); + j.write_int("ric-EventTriggerFormat-Type", ric_event_trigger_format_type); + j.end_obj(); +} + +// RIC-ReportStyle-Item ::= SEQUENCE +SRSASN_CODE ric_report_style_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_report_style_type, false, true)); + HANDLE_CODE(ric_report_style_name.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_action_format_type, false, true)); + HANDLE_CODE(pack_dyn_seq_of(bref, meas_info_action_list, 1, 65535, true)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_ind_hdr_format_type, false, true)); + HANDLE_CODE(pack_unconstrained_integer(bref, ric_ind_msg_format_type, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ric_report_style_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_unconstrained_integer(ric_report_style_type, bref, false, true)); + HANDLE_CODE(ric_report_style_name.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(ric_action_format_type, bref, false, true)); + HANDLE_CODE(unpack_dyn_seq_of(meas_info_action_list, bref, 1, 65535, true)); + HANDLE_CODE(unpack_unconstrained_integer(ric_ind_hdr_format_type, bref, false, true)); + HANDLE_CODE(unpack_unconstrained_integer(ric_ind_msg_format_type, bref, false, true)); + + return SRSASN_SUCCESS; +} +void ric_report_style_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ric-ReportStyle-Type", ric_report_style_type); + j.write_str("ric-ReportStyle-Name", ric_report_style_name.to_string()); + j.write_int("ric-ActionFormat-Type", ric_action_format_type); + j.start_array("measInfo-Action-List"); + for (const auto& e1 : meas_info_action_list) { + e1.to_json(j); + } + j.end_array(); + j.write_int("ric-IndicationHeaderFormat-Type", ric_ind_hdr_format_type); + j.write_int("ric-IndicationMessageFormat-Type", ric_ind_msg_format_type); + j.end_obj(); +} + +// E2SM-KPM-RANfunction-Description ::= SEQUENCE +SRSASN_CODE e2_sm_kpm_ra_nfunction_description_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ric_event_trigger_style_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ric_report_style_list.size() > 0, 1)); + + HANDLE_CODE(ran_function_name.pack(bref)); + if (ric_event_trigger_style_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, ric_event_trigger_style_list, 1, 63, true)); + } + if (ric_report_style_list.size() > 0) { + HANDLE_CODE(pack_dyn_seq_of(bref, ric_report_style_list, 1, 63, true)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE e2_sm_kpm_ra_nfunction_description_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + bool ric_event_trigger_style_list_present; + HANDLE_CODE(bref.unpack(ric_event_trigger_style_list_present, 1)); + bool ric_report_style_list_present; + HANDLE_CODE(bref.unpack(ric_report_style_list_present, 1)); + + HANDLE_CODE(ran_function_name.unpack(bref)); + if (ric_event_trigger_style_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(ric_event_trigger_style_list, bref, 1, 63, true)); + } + if (ric_report_style_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(ric_report_style_list, bref, 1, 63, true)); + } + + return SRSASN_SUCCESS; +} +void e2_sm_kpm_ra_nfunction_description_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ranFunction-Name"); + ran_function_name.to_json(j); + if (ric_event_trigger_style_list.size() > 0) { + j.start_array("ric-EventTriggerStyle-List"); + for (const auto& e1 : ric_event_trigger_style_list) { + e1.to_json(j); + } + j.end_array(); + } + if (ric_report_style_list.size() > 0) { + j.start_array("ric-ReportStyle-List"); + for (const auto& e1 : ric_report_style_list) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// GlobalRANNodeID ::= CHOICE +void global_ran_node_id_c::destroy_() +{ + switch (type_) { + case types::global_gnb_id: + c.destroy(); + break; + case types::global_ng_enb_id: + c.destroy(); + break; + default: + break; + } +} +void global_ran_node_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_gnb_id: + c.init(); + break; + case types::global_ng_enb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c::global_ran_node_id_c(const global_ran_node_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_gnb_id: + c.init(other.c.get()); + break; + case types::global_ng_enb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } +} +global_ran_node_id_c& global_ran_node_id_c::operator=(const global_ran_node_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_gnb_id: + c.set(other.c.get()); + break; + case types::global_ng_enb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + + return *this; +} +global_gnb_id_s& global_ran_node_id_c::set_global_gnb_id() +{ + set(types::global_gnb_id); + return c.get(); +} +global_ng_enb_id_s& global_ran_node_id_c::set_global_ng_enb_id() +{ + set(types::global_ng_enb_id); + return c.get(); +} +void global_ran_node_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_gnb_id: + j.write_fieldname("globalGNB-ID"); + c.get().to_json(j); + break; + case types::global_ng_enb_id: + j.write_fieldname("globalNgENB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + } + j.end_obj(); +} +SRSASN_CODE global_ran_node_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE global_ran_node_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_gnb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_ng_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "global_ran_node_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* global_ran_node_id_c::types_opts::to_string() const +{ + static const char* options[] = {"globalGNB-ID", "globalNgENB-ID"}; + return convert_enum_idx(options, 2, value, "global_ran_node_id_c::types"); +} + +// EN-GNB-ID ::= CHOICE +void en_gnb_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("en-gNB-ID", c.to_string()); + j.end_obj(); +} +SRSASN_CODE en_gnb_id_c::pack(bit_ref& bref) const +{ + pack_enum(bref, type()); + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE en_gnb_id_c::unpack(cbit_ref& bref) +{ + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "en_gnb_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* en_gnb_id_c::types_opts::to_string() const +{ + static const char* options[] = {"en-gNB-ID"}; + return convert_enum_idx(options, 1, value, "en_gnb_id_c::types"); +} + +// GlobalenGNB-ID ::= SEQUENCE +SRSASN_CODE globalen_gnb_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(plmn_id.pack(bref)); + HANDLE_CODE(en_g_nb_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE globalen_gnb_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(plmn_id.unpack(bref)); + HANDLE_CODE(en_g_nb_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void globalen_gnb_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pLMN-Identity", plmn_id.to_string()); + j.write_fieldname("en-gNB-ID"); + en_g_nb_id.to_json(j); + j.end_obj(); +} + +// GroupID ::= CHOICE +void group_id_c::destroy_() {} +void group_id_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +group_id_c::group_id_c(const group_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } +} +group_id_c& group_id_c::operator=(const group_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + + return *this; +} +uint16_t& group_id_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& group_id_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void group_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + } + j.end_obj(); +} +SRSASN_CODE group_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE group_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "group_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* group_id_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "group_id_c::types"); +} +uint8_t group_id_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "group_id_c::types"); +} + +// InterfaceID-E1 ::= SEQUENCE +SRSASN_CODE interface_id_e1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_cu_up_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_e1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_cu_up_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_e1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-CU-UP-ID", gnb_cu_up_id); + j.end_obj(); +} + +// InterfaceID-F1 ::= SEQUENCE +SRSASN_CODE interface_id_f1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, gnb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_f1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + HANDLE_CODE(unpack_integer(gnb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_f1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.write_int("gNB-DU-ID", gnb_du_id); + j.end_obj(); +} + +// InterfaceID-NG ::= SEQUENCE +SRSASN_CODE interface_id_ng_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(guami.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_ng_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(guami.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_ng_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("guami"); + guami.to_json(j); + j.end_obj(); +} + +// InterfaceID-S1 ::= SEQUENCE +SRSASN_CODE interface_id_s1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(gummei.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_s1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(gummei.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_s1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("gUMMEI"); + gummei.to_json(j); + j.end_obj(); +} + +// InterfaceID-W1 ::= SEQUENCE +SRSASN_CODE interface_id_w1_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_enb_id.pack(bref)); + HANDLE_CODE(pack_integer(bref, ng_enb_du_id, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_w1_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_enb_id.unpack(bref)); + HANDLE_CODE(unpack_integer(ng_enb_du_id, bref, (uint64_t)0u, (uint64_t)68719476735u, false, true)); + + return SRSASN_SUCCESS; +} +void interface_id_w1_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-ng-eNB-ID"); + global_ng_enb_id.to_json(j); + j.write_int("ng-eNB-DU-ID", ng_enb_du_id); + j.end_obj(); +} + +// InterfaceID-X2 ::= SEQUENCE +SRSASN_CODE interface_id_x2_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(node_type.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(node_type.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_x2_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("nodeType"); + node_type.to_json(j); + j.end_obj(); +} + +void interface_id_x2_s::node_type_c_::destroy_() +{ + switch (type_) { + case types::global_enb_id: + c.destroy(); + break; + case types::global_en_g_nb_id: + c.destroy(); + break; + default: + break; + } +} +void interface_id_x2_s::node_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::global_enb_id: + c.init(); + break; + case types::global_en_g_nb_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_::node_type_c_(const interface_id_x2_s::node_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::global_enb_id: + c.init(other.c.get()); + break; + case types::global_en_g_nb_id: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } +} +interface_id_x2_s::node_type_c_& +interface_id_x2_s::node_type_c_::operator=(const interface_id_x2_s::node_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::global_enb_id: + c.set(other.c.get()); + break; + case types::global_en_g_nb_id: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + + return *this; +} +global_enb_id_s& interface_id_x2_s::node_type_c_::set_global_enb_id() +{ + set(types::global_enb_id); + return c.get(); +} +globalen_gnb_id_s& interface_id_x2_s::node_type_c_::set_global_en_g_nb_id() +{ + set(types::global_en_g_nb_id); + return c.get(); +} +void interface_id_x2_s::node_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::global_enb_id: + j.write_fieldname("global-eNB-ID"); + c.get().to_json(j); + break; + case types::global_en_g_nb_id: + j.write_fieldname("global-en-gNB-ID"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_x2_s::node_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_x2_s::node_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::global_enb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::global_en_g_nb_id: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_x2_s::node_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_x2_s::node_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"global-eNB-ID", "global-en-gNB-ID"}; + return convert_enum_idx(options, 2, value, "interface_id_x2_s::node_type_c_::types"); +} + +// InterfaceID-Xn ::= SEQUENCE +SRSASN_CODE interface_id_xn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(global_ng_ran_id.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_xn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(global_ng_ran_id.unpack(bref)); + + return SRSASN_SUCCESS; +} +void interface_id_xn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("global-NG-RAN-ID"); + global_ng_ran_id.to_json(j); + j.end_obj(); +} + +// InterfaceIdentifier ::= CHOICE +void interface_id_c::destroy_() +{ + switch (type_) { + case types::ng: + c.destroy(); + break; + case types::xn: + c.destroy(); + break; + case types::f1: + c.destroy(); + break; + case types::e1: + c.destroy(); + break; + case types::s1: + c.destroy(); + break; + case types::x2: + c.destroy(); + break; + case types::w1: + c.destroy(); + break; + default: + break; + } +} +void interface_id_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ng: + c.init(); + break; + case types::xn: + c.init(); + break; + case types::f1: + c.init(); + break; + case types::e1: + c.init(); + break; + case types::s1: + c.init(); + break; + case types::x2: + c.init(); + break; + case types::w1: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c::interface_id_c(const interface_id_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::ng: + c.init(other.c.get()); + break; + case types::xn: + c.init(other.c.get()); + break; + case types::f1: + c.init(other.c.get()); + break; + case types::e1: + c.init(other.c.get()); + break; + case types::s1: + c.init(other.c.get()); + break; + case types::x2: + c.init(other.c.get()); + break; + case types::w1: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } +} +interface_id_c& interface_id_c::operator=(const interface_id_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ng: + c.set(other.c.get()); + break; + case types::xn: + c.set(other.c.get()); + break; + case types::f1: + c.set(other.c.get()); + break; + case types::e1: + c.set(other.c.get()); + break; + case types::s1: + c.set(other.c.get()); + break; + case types::x2: + c.set(other.c.get()); + break; + case types::w1: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + + return *this; +} +interface_id_ng_s& interface_id_c::set_ng() +{ + set(types::ng); + return c.get(); +} +interface_id_xn_s& interface_id_c::set_xn() +{ + set(types::xn); + return c.get(); +} +interface_id_f1_s& interface_id_c::set_f1() +{ + set(types::f1); + return c.get(); +} +interface_id_e1_s& interface_id_c::set_e1() +{ + set(types::e1); + return c.get(); +} +interface_id_s1_s& interface_id_c::set_s1() +{ + set(types::s1); + return c.get(); +} +interface_id_x2_s& interface_id_c::set_x2() +{ + set(types::x2); + return c.get(); +} +interface_id_w1_s& interface_id_c::set_w1() +{ + set(types::w1); + return c.get(); +} +void interface_id_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ng: + j.write_fieldname("nG"); + c.get().to_json(j); + break; + case types::xn: + j.write_fieldname("xN"); + c.get().to_json(j); + break; + case types::f1: + j.write_fieldname("f1"); + c.get().to_json(j); + break; + case types::e1: + j.write_fieldname("e1"); + c.get().to_json(j); + break; + case types::s1: + j.write_fieldname("s1"); + c.get().to_json(j); + break; + case types::x2: + j.write_fieldname("x2"); + c.get().to_json(j); + break; + case types::w1: + j.write_fieldname("w1"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + } + j.end_obj(); +} +SRSASN_CODE interface_id_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE interface_id_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ng: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::xn: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::f1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::e1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::s1: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::x2: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::w1: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "interface_id_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* interface_id_c::types_opts::to_string() const +{ + static const char* options[] = {"nG", "xN", "f1", "e1", "s1", "x2", "w1"}; + return convert_enum_idx(options, 7, value, "interface_id_c::types"); +} + +// FreqBandNrItem ::= SEQUENCE +SRSASN_CODE freq_band_nr_item_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, freq_band_ind_nr, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE freq_band_nr_item_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(freq_band_ind_nr, bref, (uint16_t)1u, (uint16_t)1024u, true, true)); + + return SRSASN_SUCCESS; +} +void freq_band_nr_item_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("freqBandIndicatorNr", freq_band_ind_nr); + j.end_obj(); +} + +// NR-ARFCN ::= SEQUENCE +SRSASN_CODE nr_arfcn_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, nrarfcn, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list_nr, 1, 32, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nr_arfcn_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(nrarfcn, bref, (uint32_t)0u, (uint32_t)3279165u, false, true)); + HANDLE_CODE(unpack_dyn_seq_of(freq_band_list_nr, bref, 1, 32, true)); + + return SRSASN_SUCCESS; +} +void nr_arfcn_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("nRARFCN", nrarfcn); + j.start_array("freqBandListNr"); + for (const auto& e1 : freq_band_list_nr) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// QoSID ::= CHOICE +void qo_sid_c::destroy_() {} +void qo_sid_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +qo_sid_c::qo_sid_c(const qo_sid_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::five_gc: + c.init(other.c.get()); + break; + case types::epc: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } +} +qo_sid_c& qo_sid_c::operator=(const qo_sid_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::five_gc: + c.set(other.c.get()); + break; + case types::epc: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + + return *this; +} +uint16_t& qo_sid_c::set_five_gc() +{ + set(types::five_gc); + return c.get(); +} +uint16_t& qo_sid_c::set_epc() +{ + set(types::epc); + return c.get(); +} +void qo_sid_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::five_gc: + j.write_int("fiveGC", c.get()); + break; + case types::epc: + j.write_int("ePC", c.get()); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + } + j.end_obj(); +} +SRSASN_CODE qo_sid_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::five_gc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE qo_sid_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::five_gc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, true, true)); + break; + case types::epc: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u, false, true)); + break; + default: + log_invalid_choice_id(type_, "qo_sid_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* qo_sid_c::types_opts::to_string() const +{ + static const char* options[] = {"fiveGC", "ePC"}; + return convert_enum_idx(options, 2, value, "qo_sid_c::types"); +} +uint8_t qo_sid_c::types_opts::to_number() const +{ + static const uint8_t options[] = {5}; + return map_enum_number(options, 1, value, "qo_sid_c::types"); +} + +// RRCclass-LTE ::= ENUMERATED +const char* rr_cclass_lte_opts::to_string() const +{ + static const char* options[] = {"bCCH-BCH", + "bCCH-BCH-MBMS", + "bCCH-DL-SCH", + "bCCH-DL-SCH-BR", + "bCCH-DL-SCH-MBMS", + "mCCH", + "pCCH", + "dL-CCCH", + "dL-DCCH", + "uL-CCCH", + "uL-DCCH", + "sC-MCCH"}; + return convert_enum_idx(options, 12, value, "rr_cclass_lte_e"); +} + +// RRCclass-NR ::= ENUMERATED +const char* rr_cclass_nr_opts::to_string() const +{ + static const char* options[] = { + "bCCH-BCH", "bCCH-DL-SCH", "dL-CCCH", "dL-DCCH", "pCCH", "uL-CCCH", "uL-CCCH1", "uL-DCCH"}; + return convert_enum_idx(options, 8, value, "rr_cclass_nr_e"); +} +uint8_t rr_cclass_nr_opts::to_number() const +{ + if (value == ul_ccch1) { + return 1; + } + invalid_enum_number(value, "rr_cclass_nr_e"); + return 0; +} + +// RRC-MessageID ::= SEQUENCE +SRSASN_CODE rrc_msg_id_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(rrc_type.pack(bref)); + HANDLE_CODE(pack_unconstrained_integer(bref, msg_id, false, true)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(rrc_type.unpack(bref)); + HANDLE_CODE(unpack_unconstrained_integer(msg_id, bref, false, true)); + + return SRSASN_SUCCESS; +} +void rrc_msg_id_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("rrcType"); + rrc_type.to_json(j); + j.write_int("messageID", msg_id); + j.end_obj(); +} + +void rrc_msg_id_s::rrc_type_c_::destroy_() {} +void rrc_msg_id_s::rrc_type_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +rrc_msg_id_s::rrc_type_c_::rrc_type_c_(const rrc_msg_id_s::rrc_type_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::lte: + c.init(other.c.get()); + break; + case types::nr: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } +} +rrc_msg_id_s::rrc_type_c_& rrc_msg_id_s::rrc_type_c_::operator=(const rrc_msg_id_s::rrc_type_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::lte: + c.set(other.c.get()); + break; + case types::nr: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + + return *this; +} +rr_cclass_lte_e& rrc_msg_id_s::rrc_type_c_::set_lte() +{ + set(types::lte); + return c.get(); +} +rr_cclass_nr_e& rrc_msg_id_s::rrc_type_c_::set_nr() +{ + set(types::nr); + return c.get(); +} +void rrc_msg_id_s::rrc_type_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::lte: + j.write_str("lTE", c.get().to_string()); + break; + case types::nr: + j.write_str("nR", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_msg_id_s::rrc_type_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::lte: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_msg_id_s::rrc_type_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_msg_id_s::rrc_type_c_::types_opts::to_string() const +{ + static const char* options[] = {"lTE", "nR"}; + return convert_enum_idx(options, 2, value, "rrc_msg_id_s::rrc_type_c_::types"); +} + +// ServingCell-ARFCN ::= CHOICE +void serving_cell_arfcn_c::destroy_() +{ + switch (type_) { + case types::nr: + c.destroy(); + break; + default: + break; + } +} +void serving_cell_arfcn_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::nr: + c.init(); + break; + case types::eutra: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c::serving_cell_arfcn_c(const serving_cell_arfcn_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } +} +serving_cell_arfcn_c& serving_cell_arfcn_c::operator=(const serving_cell_arfcn_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + + return *this; +} +nr_arfcn_s& serving_cell_arfcn_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint32_t& serving_cell_arfcn_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_arfcn_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_fieldname("nR"); + c.get().to_json(j); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_arfcn_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_arfcn_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_arfcn_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_arfcn_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_arfcn_c::types"); +} + +// ServingCell-PCI ::= CHOICE +void serving_cell_pci_c::destroy_() {} +void serving_cell_pci_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +serving_cell_pci_c::serving_cell_pci_c(const serving_cell_pci_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr: + c.init(other.c.get()); + break; + case types::eutra: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } +} +serving_cell_pci_c& serving_cell_pci_c::operator=(const serving_cell_pci_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr: + c.set(other.c.get()); + break; + case types::eutra: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + + return *this; +} +uint16_t& serving_cell_pci_c::set_nr() +{ + set(types::nr); + return c.get(); +} +uint16_t& serving_cell_pci_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +void serving_cell_pci_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr: + j.write_int("nR", c.get()); + break; + case types::eutra: + j.write_int("eUTRA", c.get()); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + } + j.end_obj(); +} +SRSASN_CODE serving_cell_pci_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::nr: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_cell_pci_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1007u, false, true)); + break; + case types::eutra: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)503u, true, true)); + break; + default: + log_invalid_choice_id(type_, "serving_cell_pci_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_cell_pci_c::types_opts::to_string() const +{ + static const char* options[] = {"nR", "eUTRA"}; + return convert_enum_idx(options, 2, value, "serving_cell_pci_c::types"); +} diff --git a/lib/src/asn1/gtpc.cc b/lib/src/asn1/gtpc.cc index da184536ea..2ac0d0bd07 100644 --- a/lib/src/asn1/gtpc.cc +++ b/lib/src/asn1/gtpc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/asn1/liblte_mme.cc b/lib/src/asn1/liblte_mme.cc index 90bb3ee314..cfaab0f7df 100644 --- a/lib/src/asn1/liblte_mme.cc +++ b/lib/src/asn1/liblte_mme.cc @@ -319,6 +319,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_mobile_id_ie(uint8** ie_ptr, LIBLTE_MME_MOBI { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* id; + uint32* id32; uint32 length; uint32 i; bool odd = false; @@ -338,22 +339,35 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_mobile_id_ie(uint8** ie_ptr, LIBLTE_MME_MOBI } else if (LIBLTE_MME_MOBILE_ID_TYPE_IMEISV == mobile_id->type_of_id) { id = mobile_id->imeisv; odd = false; + } else if (LIBLTE_MME_MOBILE_ID_TYPE_TMSI == mobile_id->type_of_id) { + id32 = &mobile_id->tmsi; + odd = false; } else { // TODO: Not handling these IDs return (err); } - id[0] = **ie_ptr >> 4; - *ie_ptr += 1; - for (i = 0; i < 7; i++) { - id[i * 2 + 1] = (*ie_ptr)[i] & 0x0F; - id[i * 2 + 2] = (*ie_ptr)[i] >> 4; - } - if (odd) { - *ie_ptr += 7; + if (mobile_id->type_of_id != LIBLTE_MME_MOBILE_ID_TYPE_TMSI) { + id[0] = **ie_ptr >> 4; + *ie_ptr += 1; + for (i = 0; i < 7; i++) { + id[i * 2 + 1] = (*ie_ptr)[i] & 0x0F; + id[i * 2 + 2] = (*ie_ptr)[i] >> 4; + } + if (odd) { + *ie_ptr += 7; + } else { + id[i * 2 + 1] = (*ie_ptr)[i] & 0xF; + *ie_ptr += 8; + } } else { - id[i * 2 + 1] = (*ie_ptr)[i] & 0xF; - *ie_ptr += 8; + *ie_ptr += 1; + uint32 tmsi = 0; + for (i = 0; i < 4; i++) { + tmsi += ((*ie_ptr)[i] & 0xFF) << ((3 - i) * 8); + } + *id32 = tmsi; + *ie_ptr += 4; } err = LIBLTE_SUCCESS; @@ -598,6 +612,9 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_plmn_list_ie(uint8** ie_ptr, LIBLTE_MME_PLMN if (ie_ptr != NULL && plmn_list != NULL) { plmn_list->N_plmns = (*ie_ptr)[0] / 3; + if (plmn_list->N_plmns > LIBLTE_MME_PLMN_LIST_MAX_SIZE) { + return (err); + } for (i = 0; i < plmn_list->N_plmns; i++) { plmn_list->mcc[i] = ((*ie_ptr)[i * 3 + 0] & 0x0F) * 100; plmn_list->mcc[i] += (((*ie_ptr)[i * 3 + 0] >> 4) & 0x0F) * 10; @@ -1380,12 +1397,13 @@ liblte_mme_unpack_eps_network_feature_support_ie(uint8** ie_ptr, LIBLTE_MME_EPS_ LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; if (ie_ptr != NULL && eps_nfs != NULL) { + int ie_len = *ie_ptr[0]; eps_nfs->esrps = ((*ie_ptr)[1] >> 5) & 0x01; eps_nfs->cs_lcs = (LIBLTE_MME_CS_LCS_ENUM)(((*ie_ptr)[1] >> 3) & 0x03); eps_nfs->epc_lcs = ((*ie_ptr)[1] >> 2) & 0x01; eps_nfs->emc_bs = ((*ie_ptr)[1] >> 1) & 0x01; eps_nfs->ims_vops = (*ie_ptr)[1] & 0x01; - *ie_ptr += 2; + *ie_ptr += (ie_len + 1); err = LIBLTE_SUCCESS; } @@ -3004,9 +3022,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 = @@ -3194,7 +3216,7 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_generic_message_container_ie(uint8** ie_ptr, msg->N_bytes |= (*ie_ptr)[1]; if (msg->N_bytes > LIBLTE_MAX_MSG_SIZE_BYTES) { - return err; + return (err); } for (i = 0; i < msg->N_bytes; i++) { @@ -7585,7 +7607,11 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_downlink_generic_nas_transport_msg( liblte_mme_pack_generic_message_container_ie(&dl_generic_nas_transport->generic_msg_cont, &msg_ptr); // Additional Information - liblte_mme_pack_additional_information_ie(&dl_generic_nas_transport->add_info, &msg_ptr); + if (dl_generic_nas_transport->add_info_present) { + *msg_ptr = LIBLTE_MME_ADDITIONAL_INFORMATION_IEI; + msg_ptr++; + liblte_mme_pack_additional_information_ie(&dl_generic_nas_transport->add_info, &msg_ptr); + } // Fill in the number of bytes used msg->N_bytes = msg_ptr - msg->msg; @@ -7622,8 +7648,13 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_downlink_generic_nas_transport_msg( liblte_mme_unpack_generic_message_container_ie(&msg_ptr, &dl_generic_nas_transport->generic_msg_cont); // Additional Information - liblte_mme_unpack_additional_information_ie(&msg_ptr, &dl_generic_nas_transport->add_info); - + if (LIBLTE_MME_ADDITIONAL_INFORMATION_IEI == *msg_ptr) { + msg_ptr++; + liblte_mme_unpack_additional_information_ie(&msg_ptr, &dl_generic_nas_transport->add_info); + dl_generic_nas_transport->add_info_present = true; + } else { + dl_generic_nas_transport->add_info_present = false; + } err = LIBLTE_SUCCESS; } @@ -9018,12 +9049,27 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_deactivate_eps_bearer_context_accept_msg( *********************************************************************/ LIBLTE_ERROR_ENUM liblte_mme_pack_deactivate_eps_bearer_context_request_msg( LIBLTE_MME_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST_MSG_STRUCT* deact_eps_bearer_context_req, + uint8 sec_hdr_type, + uint32 count, LIBLTE_BYTE_MSG_STRUCT* msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; uint8* msg_ptr = msg->msg; if (deact_eps_bearer_context_req != NULL && msg != NULL) { + if (LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS != sec_hdr_type) { + // Protocol Discriminator and Security Header Type + *msg_ptr = (sec_hdr_type << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); + msg_ptr++; + + // MAC will be filled in later + msg_ptr += 4; + + // Sequence Number + *msg_ptr = count & 0xFF; + msg_ptr++; + } + // Protocol Discriminator and EPS Bearer ID *msg_ptr = (deact_eps_bearer_context_req->eps_bearer_id << 4) | (LIBLTE_MME_PD_EPS_SESSION_MANAGEMENT); msg_ptr++; diff --git a/lib/src/asn1/nas_5g_ies.cc b/lib/src/asn1/nas_5g_ies.cc index 01f41a7771..d1cb85518d 100644 --- a/lib/src/asn1/nas_5g_ies.cc +++ b/lib/src/asn1/nas_5g_ies.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -51,6 +51,34 @@ SRSASN_CODE registration_type_5gs_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* registration_type_5gs_t::registration_type_type_::to_string() const +{ + switch (value) { + case registration_type_type_::initial_registration: + return "Initial Registration"; + case registration_type_type_::mobility_registration_updating: + return "Mobility Registration Updating"; + case registration_type_type_::periodic_registration_updating: + return "Periodic Registration Updating"; + case registration_type_type_::emergency_registration: + return "Emergency Registration"; + case registration_type_type_::reserved: + return "Reserved"; + default: + return "Invalid Choice"; + } +} +const char* registration_type_5gs_t::follow_on_request_bit_type_::to_string() const +{ + switch (value) { + case follow_on_request_bit_type_::no_follow_on_request_pending: + return "no_follow_on_request_pending"; + case follow_on_request_bit_type_::follow_on_request_pending: + return "follow_on_request_pending"; + default: + return "Invalid Choice"; + } +} // IE: key set identifier // Reference: 9.11.3.32 SRSASN_CODE key_set_identifier_t::pack(asn1::bit_ref& bref) @@ -69,6 +97,26 @@ SRSASN_CODE key_set_identifier_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* key_set_identifier_t::security_context_flag_type_::to_string() const +{ + switch (value) { + case security_context_flag_type_::native_security_context: + return "native security context"; + case security_context_flag_type_::mapped_security_context: + return "mapped security context"; + default: + return "Invalid Choice"; + } +} +const char* key_set_identifier_t::nas_key_set_identifier_type_::to_string() const +{ + switch (value) { + case nas_key_set_identifier_type_::no_key_is_available_or_reserved: + return "no key is available or reserved"; + default: + return "Invalid Choice"; + } +} // IE: 5GS mobile identity // Reference: 9.11.3.4 SRSASN_CODE mobile_identity_5gs_t::pack(asn1::bit_ref& bref) @@ -189,7 +237,7 @@ SRSASN_CODE mobile_identity_5gs_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } -const char* mobile_identity_5gs_t::identity_types_::to_string() +const char* mobile_identity_5gs_t::identity_types_::to_string() const { switch (value) { case identity_types_::no_identity: @@ -1182,6 +1230,17 @@ SRSASN_CODE ue_usage_setting_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* ue_usage_setting_t::UE_usage_setting_type_::to_string() const +{ + switch (value) { + case UE_usage_setting_type_::voice_centric: + return "voice centric"; + case UE_usage_setting_type_::data_centric: + return "data centric"; + default: + return "Invalid Choice"; + } +} // IE: 5GS DRX parameters // Reference: 9.11.3.2A SRSASN_CODE drx_parameters_5gs_t::pack(asn1::bit_ref& bref) @@ -1222,6 +1281,23 @@ SRSASN_CODE drx_parameters_5gs_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* drx_parameters_5gs_t::drx_value_type_::to_string() const +{ + switch (value) { + case drx_value_type_::drx_value_not_specified: + return "DRX value not specified"; + case drx_value_type_::drx_cycle_parameter_t_32: + return "DRX cycle parameter T 32"; + case drx_value_type_::drx_cycle_parameter_t_64: + return "DRX cycle parameter T 64"; + case drx_value_type_::drx_cycle_parameter_t_128: + return "DRX cycle parameter T 128"; + case drx_value_type_::drx_cycle_parameter_t_256: + return "DRX cycle parameter T 256"; + default: + return "Invalid Choice"; + } +} // IE: EPS NAS message container // Reference: 9.11.3.24 SRSASN_CODE eps_nas_message_container_t::pack(asn1::bit_ref& bref) @@ -1309,6 +1385,31 @@ SRSASN_CODE payload_container_type_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* payload_container_type_t::Payload_container_type_type_::to_string() const +{ + switch (value) { + case Payload_container_type_type_::n1_sm_information: + return "N1 SM information"; + case Payload_container_type_type_::sms: + return "SMS"; + case Payload_container_type_type_::lte_positioning_protocol_lpp_message_container: + return "LTE Positioning Protocol LPP message container"; + case Payload_container_type_type_::sor_transparent_container: + return "SOR transparent container"; + case Payload_container_type_type_::ue_policy_container: + return "UE policy container"; + case Payload_container_type_type_::ue_parameters_update_transparent_container: + return "UE parameters update transparent container"; + case Payload_container_type_type_::location_services_message_container: + return "Location services message container"; + case Payload_container_type_type_::c_io_t_user_data_container: + return "CIoT user data container"; + case Payload_container_type_type_::multiple_payloads: + return "Multiple payloads"; + default: + return "Invalid Choice"; + } +} // IE: Payload container // Reference: 9.11.3.39 SRSASN_CODE payload_container_t::pack(asn1::bit_ref& bref) @@ -1404,6 +1505,58 @@ SRSASN_CODE update_type_5gs_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* update_type_5gs_t::SMS_requested_type_::to_string() const +{ + switch (value) { + case SMS_requested_type_::sms_over_nas_not_supported: + return "SMS over NAS not supported"; + case SMS_requested_type_::sms_over_nas_supported: + return "SMS over NAS supported"; + default: + return "Invalid Choice"; + } +} +const char* update_type_5gs_t::NG_RAN_RCU_type_::to_string() const +{ + switch (value) { + case NG_RAN_RCU_type_::ue_radio_capability_update_not_needed: + return "UE radio capability update not needed"; + case NG_RAN_RCU_type_::ue_radio_capability_update_needed: + return "UE radio capability update needed"; + default: + return "Invalid Choice"; + } +} +const char* update_type_5gs_t::PNB_5GS_CIoT_type_::to_string() const +{ + switch (value) { + case PNB_5GS_CIoT_type_::no_additional_information: + return "no additional information"; + case PNB_5GS_CIoT_type_::control_plane_c_io_t_5gs_optimization: + return "control plane CIoT 5GS optimization"; + case PNB_5GS_CIoT_type_::user_plane_c_io_t_5gs_optimization: + return "user plane CIoT 5GS optimization"; + case PNB_5GS_CIoT_type_::reserved: + return "reserved"; + default: + return "Invalid Choice"; + } +} +const char* update_type_5gs_t::PNB_EPS_CIoT_type_::to_string() const +{ + switch (value) { + case PNB_EPS_CIoT_type_::no_additional_information: + return "no additional information"; + case PNB_EPS_CIoT_type_::control_plane_c_io_t_eps_optimization: + return "control plane CIoT EPS optimization"; + case PNB_EPS_CIoT_type_::user_plane_c_io_t_eps_optimization: + return "user plane CIoT EPS optimization"; + case PNB_EPS_CIoT_type_::reserved: + return "reserved"; + default: + return "Invalid Choice"; + } +} // IE: Mobile station classmark 2 // Reference: 9.11.3.31C SRSASN_CODE mobile_station_classmark_2_t::pack(asn1::bit_ref& bref) @@ -1624,6 +1777,84 @@ SRSASN_CODE extended_drx_parameters_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* extended_drx_parameters_t::Paging_Time_Window_type_::to_string() const +{ + switch (value) { + case Paging_Time_Window_type_::seconds_0: + return "seconds_0"; + case Paging_Time_Window_type_::second_1: + return "second_1"; + case Paging_Time_Window_type_::seconds_2: + return "seconds_2"; + case Paging_Time_Window_type_::seconds_3: + return "seconds_3"; + case Paging_Time_Window_type_::seconds_4: + return "seconds_4"; + case Paging_Time_Window_type_::seconds_5: + return "seconds_5"; + case Paging_Time_Window_type_::seconds_6: + return "seconds_6"; + case Paging_Time_Window_type_::seconds_7: + return "seconds_7"; + case Paging_Time_Window_type_::seconds_8: + return "seconds_8"; + case Paging_Time_Window_type_::seconds_9: + return "seconds_9"; + case Paging_Time_Window_type_::seconds_10: + return "seconds_10"; + case Paging_Time_Window_type_::seconds_12: + return "seconds_12"; + case Paging_Time_Window_type_::seconds_14: + return "seconds_14"; + case Paging_Time_Window_type_::seconds_16: + return "seconds_16"; + case Paging_Time_Window_type_::seconds_18: + return "seconds_18"; + case Paging_Time_Window_type_::seconds_20: + return "seconds_20"; + default: + return "Invalid Choice"; + } +} +const char* extended_drx_parameters_t::eDRX_value_type_::to_string() const +{ + switch (value) { + case eDRX_value_type_::second_1_28: + return "second_1_28"; + case eDRX_value_type_::second_2_56: + return "second_2_56"; + case eDRX_value_type_::second_3_84: + return "second_3_84"; + case eDRX_value_type_::second_5_12: + return "second_5_12"; + case eDRX_value_type_::second_6_4: + return "second_6_4"; + case eDRX_value_type_::second_7_68: + return "second_7_68"; + case eDRX_value_type_::second_8_96: + return "second_8_96"; + case eDRX_value_type_::second_10_24: + return "second_10_24"; + case eDRX_value_type_::second_11_52: + return "second_11_52"; + case eDRX_value_type_::second_12_8: + return "second_12_8"; + case eDRX_value_type_::second_14_08: + return "second_14_08"; + case eDRX_value_type_::second_15_36: + return "second_15_36"; + case eDRX_value_type_::second_16_64: + return "second_16_64"; + case eDRX_value_type_::second_17_92: + return "second_17_92"; + case eDRX_value_type_::second_19_20: + return "second_19_20"; + case eDRX_value_type_::second_20_48: + return "second_20_48"; + default: + return "Invalid Choice"; + } +} // IE: GPRS timer 3 // Reference: 9.11.2.5 SRSASN_CODE gprs_timer_3_t::pack(asn1::bit_ref& bref) @@ -1661,6 +1892,29 @@ SRSASN_CODE gprs_timer_3_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* gprs_timer_3_t::Unit_type_::to_string() const +{ + switch (value) { + case Unit_type_::value_is_incremented_in_multiples_of_10_minutes: + return "value is incremented in multiples of 10 minutes"; + case Unit_type_::value_is_incremented_in_multiples_of_1_hour: + return "value is incremented in multiples of 1 hour"; + case Unit_type_::value_is_incremented_in_multiples_of_10_hours: + return "value is incremented in multiples of 10 hours"; + case Unit_type_::value_is_incremented_in_multiples_of_2_seconds: + return "value is incremented in multiples of 2 seconds"; + case Unit_type_::value_is_incremented_in_multiples_of_30_seconds: + return "value is incremented in multiples of 30 seconds"; + case Unit_type_::value_is_incremented_in_multiples_of_1_minute: + return "value is incremented in multiples of 1 minute"; + case Unit_type_::value_is_incremented_in_multiples_of_320_hours: + return "value is incremented in multiples of 320 hours"; + case Unit_type_::value_indicates_that_the_timer_is_deactivated: + return "value indicates that the timer is deactivated"; + default: + return "Invalid Choice"; + } +} // IE: UE radio capability ID // Reference: 9.11.3.68 SRSASN_CODE ue_radio_capability_id_t::pack(asn1::bit_ref& bref) @@ -1856,6 +2110,27 @@ SRSASN_CODE nb_n1_mode_drx_parameters_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* nb_n1_mode_drx_parameters_t::nb_n1_mode_drx_value_type_::to_string() const +{ + switch (value) { + case nb_n1_mode_drx_value_type_::drx_value_not_specified: + return "DRX value not specified"; + case nb_n1_mode_drx_value_type_::drx_cycle_parameter_t_32: + return "DRX cycle parameter T 32"; + case nb_n1_mode_drx_value_type_::drx_cycle_parameter_t_64: + return "DRX cycle parameter T 64"; + case nb_n1_mode_drx_value_type_::drx_cycle_parameter_t_128: + return "DRX cycle parameter T 128"; + case nb_n1_mode_drx_value_type_::drx_cycle_parameter_t_256: + return "DRX cycle parameter T 256"; + case nb_n1_mode_drx_value_type_::drx_cycle_parameter_t_512: + return "DRX cycle parameter T 512"; + case nb_n1_mode_drx_value_type_::drx_cycle_parameter_t_1024: + return "DRX cycle parameter T 1024"; + default: + return "Invalid Choice"; + } +} // IE: 5GS registration result // Reference: 9.11.3.6 SRSASN_CODE registration_result_5gs_t::pack(asn1::bit_ref& bref) @@ -1902,6 +2177,54 @@ SRSASN_CODE registration_result_5gs_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* registration_result_5gs_t::Emergency_registered_type_::to_string() const +{ + switch (value) { + case Emergency_registered_type_::not_registered_for_emergency_services: + return "Not registered for emergency services"; + case Emergency_registered_type_::registered_for_emergency_services: + return "Registered for emergency services"; + default: + return "Invalid Choice"; + } +} +const char* registration_result_5gs_t::NSSAA_to_be_performed_type_::to_string() const +{ + switch (value) { + case NSSAA_to_be_performed_type_::nssaa_is_not_to_be_performed: + return "NSSAA is not to be performed"; + case NSSAA_to_be_performed_type_::nssaa_is_to_be_performed: + return "NSSAA is to be performed"; + default: + return "Invalid Choice"; + } +} +const char* registration_result_5gs_t::SMS_allowed_type_::to_string() const +{ + switch (value) { + case SMS_allowed_type_::sms_over_nas_not_allowed: + return "SMS over NAS not allowed"; + case SMS_allowed_type_::sms_over_nas_allowed: + return "SMS over NAS allowed"; + default: + return "Invalid Choice"; + } +} +const char* registration_result_5gs_t::registration_result_type_::to_string() const +{ + switch (value) { + case registration_result_type_::access_3_gpp: + return "access 3GPP"; + case registration_result_type_::non_3_gpp_access: + return "Non-3GPP access"; + case registration_result_type_::access_3_gpp_and_non_3_gpp_access: + return "access 3GPP and non-3GPP access"; + case registration_result_type_::reserved: + return "reserved"; + default: + return "Invalid Choice"; + } +} // IE: PLMN list // Reference: 9.11.3.45 SRSASN_CODE plmn_list_t::pack(asn1::bit_ref& bref) @@ -1970,6 +2293,21 @@ SRSASN_CODE tracking_area_identity_list_5gs_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* tracking_area_identity_list_5gs_t::type_of_list_type_::to_string() const +{ + switch (value) { + case type_of_list_type_::list_of_ta_cs_belonging_to_one_plmn_or_snpn_with_non_consecutive_tac_values: + return "list of TACs belonging to one PLMN or SNPN, with non-consecutive TAC values"; + case type_of_list_type_::list_of_ta_cs_belonging_to_one_plmn_or_snpn_with_consecutive_tac_values: + return "list of TACs belonging to one PLMN or SNPN, with consecutive TAC values"; + case type_of_list_type_::list_of_ta_is_belonging_to_different_plm_ns: + return "list of TAIs belonging to different PLMNs"; + case type_of_list_type_::reserved: + return "Reserved"; + default: + return "Invalid Choice"; + } +} // IE: Rejected NSSAI // Reference: 9.11.3.46 SRSASN_CODE rejected_nssai_t::pack(asn1::bit_ref& bref) @@ -2432,6 +2770,21 @@ SRSASN_CODE nssai_inclusion_mode_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* nssai_inclusion_mode_t::NSSAI_inclusion_mode_type_::to_string() const +{ + switch (value) { + case NSSAI_inclusion_mode_type_::nssai_inclusion_mode_a: + return "NSSAI inclusion mode A"; + case NSSAI_inclusion_mode_type_::nssai_inclusion_mode_b: + return "NSSAI inclusion mode B"; + case NSSAI_inclusion_mode_type_::nssai_inclusion_mode_c: + return "NSSAI inclusion mode C"; + case NSSAI_inclusion_mode_type_::nssai_inclusion_mode_d: + return "NSSAI inclusion mode D"; + default: + return "Invalid Choice"; + } +} // IE: Operator-defined access category definitions // Reference: 9.11.3.38 SRSASN_CODE operator_defined_access_category_definitions_t::pack(asn1::bit_ref& bref) @@ -2500,6 +2853,17 @@ SRSASN_CODE ue_radio_capability_id_deletion_indication_t::unpack(asn1::cbit_ref& return SRSASN_SUCCESS; } +const char* ue_radio_capability_id_deletion_indication_t::Deletion_request_type_::to_string() const +{ + switch (value) { + case Deletion_request_type_::ue_radio_capability_id_deletion_not_requested: + return "UE radio capability ID deletion not requested"; + case Deletion_request_type_::network_assigned_ue_radio_capability_i_ds_deletion_requested: + return "Network-assigned UE radio capability IDs deletion requested"; + default: + return "Invalid Choice"; + } +} // IE: Ciphering key data // Reference: 9.11.3.18C SRSASN_CODE ciphering_key_data_t::pack(asn1::bit_ref& bref) @@ -2624,6 +2988,97 @@ SRSASN_CODE cause_5gmm_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* cause_5gmm_t::cause_5gmm_type_::to_string() const +{ + switch (value) { + case cause_5gmm_type_::illegal_ue: + return "Illegal UE"; + case cause_5gmm_type_::pei_not_accepted: + return "PEI not accepted"; + case cause_5gmm_type_::illegal_me: + return "Illegal ME"; + case cause_5gmm_type_::services_not_allowed_5gs: + return "Services not allowed 5GS"; + case cause_5gmm_type_::ue_identity_cannot_be_derived_by_the_network: + return "UE identity cannot be derived by the network"; + case cause_5gmm_type_::implicitly_de_registered: + return "Implicitly de-registered"; + case cause_5gmm_type_::plmn_not_allowed: + return "PLMN not allowed"; + case cause_5gmm_type_::tracking_area_not_allowed: + return "Tracking area not allowed"; + case cause_5gmm_type_::roaming_not_allowed_in_this_tracking_area: + return "Roaming not allowed in this tracking area"; + case cause_5gmm_type_::no_suitable_cells_in_tracking_area: + return "No suitable cells in tracking area"; + case cause_5gmm_type_::mac_failure: + return "MAC failure"; + case cause_5gmm_type_::synch_failure: + return "Synch failure"; + case cause_5gmm_type_::congestion: + return "Congestion"; + case cause_5gmm_type_::ue_security_capabilities_mismatch: + return "UE security capabilities mismatch"; + case cause_5gmm_type_::security_mode_rejected_unspecified: + return "Security mode rejected, unspecified"; + case cause_5gmm_type_::non_5g_authentication_unacceptable: + return "Non-5G authentication unacceptable"; + case cause_5gmm_type_::n1_mode_not_allowed: + return "N1 mode not allowed"; + case cause_5gmm_type_::restricted_service_area: + return "Restricted service area"; + case cause_5gmm_type_::redirection_to_epc_required: + return "Redirection to EPC required"; + case cause_5gmm_type_::ladn_not_available: + return "LADN not available"; + case cause_5gmm_type_::no_network_slices_available: + return "No network slices available"; + case cause_5gmm_type_::maximum_number_of_pdu_sessions_reached_: + return "Maximum number of PDU sessions reached"; + case cause_5gmm_type_::insufficient_resources_for_specific_slice_and_dnn: + return "Insufficient resources for specific slice and DNN"; + case cause_5gmm_type_::insufficient_resources_for_specific_slice: + return "Insufficient resources for specific slice"; + case cause_5gmm_type_::ng_ksi_already_in_use: + return "ngKSI already in use"; + case cause_5gmm_type_::non_3_gpp_access_to_5gcn_not_allowed: + return "Non-3GPP access to 5GCN not allowed"; + case cause_5gmm_type_::serving_network_not_authorized: + return "Serving network not authorized"; + case cause_5gmm_type_::temporarily_not_authorized_for_this_snpn: + return "Temporarily not authorized for this SNPN"; + case cause_5gmm_type_::permanently_not_authorized_for_this_snpn: + return "Permanently not authorized for this SNPN"; + case cause_5gmm_type_::not_authorized_for_this_cag_or_authorized_for_cag_cells_only: + return "Not authorized for this CAG or authorized for CAG cells only"; + case cause_5gmm_type_::wireline_access_area_not_allowed: + return "Wireline access area not allowed"; + case cause_5gmm_type_::payload_was_not_forwarded: + return "Payload was not forwarded"; + case cause_5gmm_type_::dnn_not_supported_or_not_subscribed_in_the_slice: + return "DNN not supported or not subscribed in the slice"; + case cause_5gmm_type_::insufficient_user_plane_resources_for_the_pdu_session: + return "Insufficient user-plane resources for the PDU session"; + case cause_5gmm_type_::semantically_incorrect_message: + return "Semantically incorrect message"; + case cause_5gmm_type_::invalid_mandatory_information: + return "Invalid mandatory information"; + case cause_5gmm_type_::message_type_non_existent_or_not_implemented: + return "Message type non-existent or not implemented"; + case cause_5gmm_type_::message_type_not_compatible_with_the_protocol_state: + return "Message type not compatible with the protocol state"; + case cause_5gmm_type_::information_element_non_existent_or_not_implemented: + return "Information element non-existent or not implemented"; + case cause_5gmm_type_::conditional_ie_error: + return "Conditional IE error"; + case cause_5gmm_type_::message_not_compatible_with_the_protocol_state: + return "Message not compatible with the protocol state"; + case cause_5gmm_type_::protocol_error_unspecified: + return "Protocol error, unspecified"; + default: + return "Invalid Choice"; + } +} // IE: De-registration type // Reference: 9.11.3.20 SRSASN_CODE de_registration_type_t::pack(asn1::bit_ref& bref) @@ -2644,6 +3099,41 @@ SRSASN_CODE de_registration_type_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* de_registration_type_t::switch_off_type_::to_string() const +{ + switch (value) { + case switch_off_type_::normal_de_registration: + return "Normal de-registration"; + case switch_off_type_::switch_off: + return "Switch Off"; + default: + return "Invalid Choice"; + } +} +const char* de_registration_type_t::re_registration_required_type_::to_string() const +{ + switch (value) { + case re_registration_required_type_::re_registration_not_required: + return "re-registration not required"; + case re_registration_required_type_::re_registration_required: + return "re-registration required"; + default: + return "Invalid Choice"; + } +} +const char* de_registration_type_t::access_type_type_::to_string() const +{ + switch (value) { + case access_type_type_::access_3_gpp: + return "access 3GPP"; + case access_type_type_::non_3_gpp_access: + return "Non-3GPP access"; + case access_type_type_::access_3_gpp_and_non_3_gpp_access: + return "access 3GPP and non-3GPP access"; + default: + return "Invalid Choice"; + } +} // IE: Spare half octet // Reference: 9.5 SRSASN_CODE spare_half_octet_t::pack(asn1::bit_ref& bref) @@ -2678,6 +3168,37 @@ SRSASN_CODE service_type_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* service_type_t::Service_type_value_type_::to_string() const +{ + switch (value) { + case Service_type_value_type_::signalling: + return "signalling"; + case Service_type_value_type_::data: + return "data"; + case Service_type_value_type_::mobile_terminated_services: + return "mobile terminated services"; + case Service_type_value_type_::emergency_services: + return "emergency services"; + case Service_type_value_type_::emergency_services_fallback: + return "emergency services fallback"; + case Service_type_value_type_::high_priority_access: + return "high priority access"; + case Service_type_value_type_::elevated_signalling: + return "elevated signalling"; + case Service_type_value_type_::unused_shall_be_interpreted_as_signalling: + return "unused shall be interpreted as signalling"; + case Service_type_value_type_::unused_shall_be_interpreted_as_signalling_1: + return "unused shall be interpreted as signalling_1"; + case Service_type_value_type_::unused_shall_be_interpreted_as_data: + return "unused shall be interpreted as data"; + case Service_type_value_type_::unused_shall_be_interpreted_as_data_1: + return "unused shall be interpreted as data_1"; + case Service_type_value_type_::unused_shall_be_interpreted_as_data_2: + return "unused shall be interpreted as data_2"; + default: + return "Invalid Choice"; + } +} // IE: Configuration update indication // Reference: 9.11.3.18 SRSASN_CODE configuration_update_indication_t::pack(asn1::bit_ref& bref) @@ -2698,6 +3219,21 @@ SRSASN_CODE configuration_update_indication_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* configuration_update_indication_t::control_plane_service_type_value_type_::to_string() const +{ + switch (value) { + case control_plane_service_type_value_type_::mobile_originating_request: + return "mobile originating request"; + case control_plane_service_type_value_type_::mobile_terminating_request: + return "mobile terminating request"; + case control_plane_service_type_value_type_::emergency_services: + return "emergency services"; + case control_plane_service_type_value_type_::emergency_services_fallback: + return "emergency services fallback"; + default: + return "Invalid Choice"; + } +} // IE: Network name // Reference: 9.11.3.35 SRSASN_CODE network_name_t::pack(asn1::bit_ref& bref) @@ -2730,11 +3266,6 @@ SRSASN_CODE network_name_t::unpack(asn1::cbit_ref& bref) // Reference: 9.11.3.52 SRSASN_CODE time_zone_t::pack(asn1::bit_ref& bref) { - HANDLE_CODE(bref.pack(year, 8)); - HANDLE_CODE(bref.pack(month, 8)); - HANDLE_CODE(bref.pack(day, 8)); - HANDLE_CODE(bref.pack(hour, 8)); - HANDLE_CODE(bref.pack(second, 8)); HANDLE_CODE(bref.pack(time_zone, 8)); return SRSASN_SUCCESS; } @@ -2743,11 +3274,6 @@ SRSASN_CODE time_zone_t::pack(asn1::bit_ref& bref) // Reference: 9.11.3.52 SRSASN_CODE time_zone_t::unpack(asn1::cbit_ref& bref) { - HANDLE_CODE(bref.unpack(year, 8)); - HANDLE_CODE(bref.unpack(month, 8)); - HANDLE_CODE(bref.unpack(day, 8)); - HANDLE_CODE(bref.unpack(hour, 8)); - HANDLE_CODE(bref.unpack(second, 8)); HANDLE_CODE(bref.unpack(time_zone, 8)); return SRSASN_SUCCESS; } @@ -2756,6 +3282,12 @@ SRSASN_CODE time_zone_t::unpack(asn1::cbit_ref& bref) // Reference: 9.11.3.53 SRSASN_CODE time_zone_and_time_t::pack(asn1::bit_ref& bref) { + HANDLE_CODE(bref.pack(year, 8)); + HANDLE_CODE(bref.pack(month, 8)); + HANDLE_CODE(bref.pack(day, 8)); + HANDLE_CODE(bref.pack(hour, 8)); + HANDLE_CODE(bref.pack(minute, 8)); + HANDLE_CODE(bref.pack(second, 8)); HANDLE_CODE(bref.pack(time_zone, 8)); return SRSASN_SUCCESS; } @@ -2764,6 +3296,12 @@ SRSASN_CODE time_zone_and_time_t::pack(asn1::bit_ref& bref) // Reference: 9.11.3.53 SRSASN_CODE time_zone_and_time_t::unpack(asn1::cbit_ref& bref) { + HANDLE_CODE(bref.unpack(year, 8)); + HANDLE_CODE(bref.unpack(month, 8)); + HANDLE_CODE(bref.unpack(day, 8)); + HANDLE_CODE(bref.unpack(hour, 8)); + HANDLE_CODE(bref.unpack(minute, 8)); + HANDLE_CODE(bref.unpack(second, 8)); HANDLE_CODE(bref.unpack(time_zone, 8)); return SRSASN_SUCCESS; } @@ -2804,6 +3342,21 @@ SRSASN_CODE daylight_saving_time_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* daylight_saving_time_t::value_type_::to_string() const +{ + switch (value) { + case value_type_::no_adjustment_for_daylight_saving_time: + return "No adjustment for Daylight Saving Time"; + case value_type_::hour_1_adjustment_for_daylight_saving_time: + return "hour 1 adjustment for Daylight Saving Time"; + case value_type_::hours_2_adjustment_for_daylight_saving_time: + return "hours 2 adjustment for Daylight Saving Time"; + case value_type_::reserved: + return "Reserved"; + default: + return "Invalid Choice"; + } +} // IE: SMS indication // Reference: 9.11.3.50A SRSASN_CODE sms_indication_t::pack(asn1::bit_ref& bref) @@ -2844,6 +3397,17 @@ SRSASN_CODE additional_configuration_indication_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* additional_configuration_indication_t::SCMR_type_::to_string() const +{ + switch (value) { + case SCMR_type_::no_additional_information: + return "no additional information"; + case SCMR_type_::release_of_n1_nas_signalling_connection_not_required: + return "release of N1 NAS signalling connection not required"; + default: + return "Invalid Choice"; + } +} // IE: ABBA // Reference: 9.11.3.10 SRSASN_CODE abba_t::pack(asn1::bit_ref& bref) @@ -3029,6 +3593,27 @@ SRSASN_CODE identity_type_5gs_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* identity_type_5gs_t::identity_types_::to_string() const +{ + switch (value) { + case identity_types_::suci: + return "SUCI"; + case identity_types_::guti_5g: + return "5G-GUTI"; + case identity_types_::imei: + return "IMEI"; + case identity_types_::s_tmsi_5g: + return "5G-S-TMSI"; + case identity_types_::imeisv: + return "IMEISV"; + case identity_types_::mac_address: + return "MAC address"; + case identity_types_::eui_64: + return "EUI-64"; + default: + return "Invalid Choice"; + } +} // IE: security algorithms // Reference: 9.11.3.34 SRSASN_CODE security_algorithms_t::pack(asn1::bit_ref& bref) @@ -3047,6 +3632,52 @@ SRSASN_CODE security_algorithms_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* security_algorithms_t::integrity_protection_algorithm_type_::to_string() const +{ + switch (value) { + case integrity_protection_algorithm_type_::ia0_5g: + return "IA0-5G"; + case integrity_protection_algorithm_type_::ia1_128_5g: + return "IA1-128-5G"; + case integrity_protection_algorithm_type_::ia2_128_5g: + return "IA2-128-5G"; + case integrity_protection_algorithm_type_::ia3_128_5g: + return "IA3-128-5G"; + case integrity_protection_algorithm_type_::ia4_5g: + return "IA4-5G"; + case integrity_protection_algorithm_type_::ia5_5g: + return "IA5-5G"; + case integrity_protection_algorithm_type_::ia6_5g: + return "IA6-5G"; + case integrity_protection_algorithm_type_::ia7_5g: + return "IA7-5G"; + default: + return "Invalid Choice"; + } +} +const char* security_algorithms_t::ciphering_algorithm_type_::to_string() const +{ + switch (value) { + case ciphering_algorithm_type_::ea0_5g: + return "EA0-5G"; + case ciphering_algorithm_type_::ea1_128_5g: + return "EA1-128-5G"; + case ciphering_algorithm_type_::ea2_128_5g: + return "EA2-128-5G"; + case ciphering_algorithm_type_::ea3_128_5g: + return "EA3-128-5G"; + case ciphering_algorithm_type_::ea4_5g: + return "EA4-5G"; + case ciphering_algorithm_type_::ea5_5g: + return "EA5-5G"; + case ciphering_algorithm_type_::ea6_5g: + return "EA6-5G"; + case ciphering_algorithm_type_::ea7_5g: + return "EA7-5G"; + default: + return "Invalid Choice"; + } +} // IE: IMEISV request // Reference: 9.11.3.28 SRSASN_CODE imeisv_request_t::pack(asn1::bit_ref& bref) @@ -3067,6 +3698,17 @@ SRSASN_CODE imeisv_request_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* imeisv_request_t::imeisv_request_type_::to_string() const +{ + switch (value) { + case imeisv_request_type_::imeisv_not_requested: + return "IMEISV not requested"; + case imeisv_request_type_::imeisv_requested: + return "IMEISV requested"; + default: + return "Invalid Choice"; + } +} // IE: EPS NAS security algorithms // Reference: 9.11.3.25 SRSASN_CODE eps_nas_security_algorithms_t::pack(asn1::bit_ref& bref) @@ -3094,6 +3736,52 @@ SRSASN_CODE eps_nas_security_algorithms_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* eps_nas_security_algorithms_t::integrity_protection_algorithm_type_::to_string() const +{ + switch (value) { + case integrity_protection_algorithm_type_::eia0: + return "EIA0"; + case integrity_protection_algorithm_type_::eia1_128: + return "EIA1-128"; + case integrity_protection_algorithm_type_::eia2_128: + return "EIA2-128"; + case integrity_protection_algorithm_type_::eia3_128: + return "EIA3-128"; + case integrity_protection_algorithm_type_::eia4: + return "EIA4"; + case integrity_protection_algorithm_type_::eia5: + return "EIA5"; + case integrity_protection_algorithm_type_::eia6: + return "EIA6"; + case integrity_protection_algorithm_type_::eia7: + return "EIA7"; + default: + return "Invalid Choice"; + } +} +const char* eps_nas_security_algorithms_t::ciphering_algorithm_type_::to_string() const +{ + switch (value) { + case ciphering_algorithm_type_::eea0: + return "EEA0"; + case ciphering_algorithm_type_::eea1_128: + return "EEA1-128"; + case ciphering_algorithm_type_::eea2_128: + return "EEA2-128"; + case ciphering_algorithm_type_::eea3_128: + return "EEA3-128"; + case ciphering_algorithm_type_::eea4: + return "EEA4"; + case ciphering_algorithm_type_::eea5: + return "EEA5"; + case ciphering_algorithm_type_::eea6: + return "EEA6"; + case ciphering_algorithm_type_::eea7: + return "EEA7"; + default: + return "Invalid Choice"; + } +} // IE: Additional 5G security information // Reference: 9.11.3.12 SRSASN_CODE additional_5g_security_information_t::pack(asn1::bit_ref& bref) @@ -3294,6 +3982,17 @@ SRSASN_CODE access_type_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* access_type_t::Access_type_value_type_::to_string() const +{ + switch (value) { + case Access_type_value_type_::access_3_gpp: + return "access_3GPP"; + case Access_type_value_type_::non_3_gpp_access: + return "Non_3GPP_access"; + default: + return "Invalid Choice"; + } +} // IE: PDU session identity 2 // Reference: 9.11.3.41 SRSASN_CODE pdu_session_identity_2_t::pack(asn1::bit_ref& bref) @@ -3330,6 +4029,27 @@ SRSASN_CODE request_type_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* request_type_t::Request_type_value_type_::to_string() const +{ + switch (value) { + case Request_type_value_type_::initial_request: + return "initial request"; + case Request_type_value_type_::existing_pdu_session: + return "existing PDU session"; + case Request_type_value_type_::initial_emergency_request: + return "initial emergency request"; + case Request_type_value_type_::existing_emergency_pdu_session: + return "existing emergency PDU session"; + case Request_type_value_type_::modification_request: + return "modification request"; + case Request_type_value_type_::ma_pdu_request: + return "MA PDU request"; + case Request_type_value_type_::reserved: + return "reserved"; + default: + return "Invalid Choice"; + } +} // IE: S-NSSAI // Reference: 9.11.2.8 SRSASN_CODE s_nssai_t::pack(asn1::bit_ref& bref) @@ -3401,6 +4121,23 @@ SRSASN_CODE s_nssai_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* s_nssai_t::SST_type_::to_string() const +{ + switch (value) { + case SST_type_::sst: + return "SST"; + case SST_type_::sst_and_mapped_hplmn_sst: + return "SST and mapped HPLMN SST"; + case SST_type_::sst_and_sd: + return "SST and SD"; + case SST_type_::sst_sd_and_mapped_hplmn_sst: + return "SST, SD and mapped HPLMN SST"; + case SST_type_::sst_sd_mapped_hplmn_sst_and_mapped_hplmn_sd: + return "SST, SD, mapped HPLMN SST and mapped HPLMN SD"; + default: + return "Invalid Choice"; + } +} // IE: DNN // Reference: 9.11.2.1B SRSASN_CODE dnn_t::pack(asn1::bit_ref& bref) @@ -3488,6 +4225,15 @@ SRSASN_CODE ma_pdu_session_information_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* ma_pdu_session_information_t::MA_PDU_session_information_value_type_::to_string() const +{ + switch (value) { + case MA_PDU_session_information_value_type_::ma_pdu_session_network_upgrade_is_allowed: + return "MA PDU session network upgrade is allowed"; + default: + return "Invalid Choice"; + } +} // IE: Release assistance indication // Reference: 9.11.3.46A SRSASN_CODE release_assistance_indication_t::pack(asn1::bit_ref& bref) @@ -3508,6 +4254,21 @@ SRSASN_CODE release_assistance_indication_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* release_assistance_indication_t::Downlink_data_expected_type_::to_string() const +{ + switch (value) { + case Downlink_data_expected_type_::no_information_regarding_ddx_is_conveyed: + return "No information regarding DDX is conveyed"; + case Downlink_data_expected_type_::no_further_uplink_and_no_further_downlink_data: + return "No further uplink and no further downlink data"; + case Downlink_data_expected_type_::only_a_single_downlink_data_transmission: + return "Only a single downlink data transmission"; + case Downlink_data_expected_type_::reserved: + return "reserved"; + default: + return "Invalid Choice"; + } +} // IE: Integrity protection maximum data rate // Reference: 9.11.4.7 SRSASN_CODE integrity_protection_maximum_data_rate_t::pack(asn1::bit_ref& bref) @@ -3526,6 +4287,32 @@ SRSASN_CODE integrity_protection_maximum_data_rate_t::unpack(asn1::cbit_ref& bre return SRSASN_SUCCESS; } +const char* integrity_protection_maximum_data_rate_t::max_data_rate_UPIP_uplink_type_::to_string() const +{ + switch (value) { + case max_data_rate_UPIP_uplink_type_::kbps_64: + return "kbps 64"; + case max_data_rate_UPIP_uplink_type_::null: + return "NULL"; + case max_data_rate_UPIP_uplink_type_::full_data_rate: + return "Full data rate"; + default: + return "Invalid Choice"; + } +} +const char* integrity_protection_maximum_data_rate_t::max_data_rate_UPIP_downlink_type_::to_string() const +{ + switch (value) { + case max_data_rate_UPIP_downlink_type_::kbps_64: + return "kbps 64"; + case max_data_rate_UPIP_downlink_type_::null: + return "NULL"; + case max_data_rate_UPIP_downlink_type_::full_data_rate: + return "Full data rate"; + default: + return "Invalid Choice"; + } +} // IE: PDU session type // Reference: 9.11.4.11 SRSASN_CODE pdu_session_type_t::pack(asn1::bit_ref& bref) @@ -3546,6 +4333,25 @@ SRSASN_CODE pdu_session_type_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* pdu_session_type_t::PDU_session_type_value_type_::to_string() const +{ + switch (value) { + case PDU_session_type_value_type_::ipv4: + return "ipv4"; + case PDU_session_type_value_type_::ipv6: + return "ipv6"; + case PDU_session_type_value_type_::ipv4v6: + return "ipv4v6"; + case PDU_session_type_value_type_::unstructured: + return "Unstructured"; + case PDU_session_type_value_type_::ethernet: + return "Ethernet"; + case PDU_session_type_value_type_::reserved: + return "reserved"; + default: + return "Invalid Choice"; + } +} // IE: SSC mode // Reference: 9.11.4.16 SRSASN_CODE ssc_mode_t::pack(asn1::bit_ref& bref) @@ -3566,6 +4372,27 @@ SRSASN_CODE ssc_mode_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* ssc_mode_t::SSC_mode_value_type_::to_string() const +{ + switch (value) { + case SSC_mode_value_type_::ssc_mode_1: + return "SSC mode 1"; + case SSC_mode_value_type_::ssc_mode_2: + return "SSC mode 2"; + case SSC_mode_value_type_::ssc_mode_3: + return "SSC mode 3"; + case SSC_mode_value_type_::unused_or_ssc_mode_1: + return "unused or SSC mode 1"; + case SSC_mode_value_type_::unused_or_ssc_mode_2: + return "unused or SSC mode 2"; + case SSC_mode_value_type_::unused_or_ssc_mode_3: + return "unused or SSC mode 3"; + case SSC_mode_value_type_::reserved: + return "reserved"; + default: + return "Invalid Choice"; + } +} // IE: 5GSM capability // Reference: 9.11.4.1 SRSASN_CODE capability_5gsm_t::pack(asn1::bit_ref& bref) @@ -3928,6 +4755,19 @@ SRSASN_CODE ethernet_header_compression_configuration_t::unpack(asn1::cbit_ref& return SRSASN_SUCCESS; } +const char* ethernet_header_compression_configuration_t::CID_Length_type_::to_string() const +{ + switch (value) { + case CID_Length_type_::ethernet_header_compression_not_used: + return "Ethernet header compression not used"; + case CID_Length_type_::bits_7: + return "bits_7"; + case CID_Length_type_::bits_15: + return "bits_15"; + default: + return "Invalid Choice"; + } +} // IE: PDU address // Reference: 9.11.4.10 SRSASN_CODE pdu_address_t::pack(asn1::bit_ref& bref) @@ -3944,9 +4784,9 @@ SRSASN_CODE pdu_address_t::pack(asn1::bit_ref& bref) if (pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv4) { HANDLE_CODE(bref.pack_bytes(ipv4.data(), 4)); } else if (pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv6) { - HANDLE_CODE(bref.pack_bytes(ipv6.data(), 16)); + HANDLE_CODE(bref.pack_bytes(ipv6.data(), 8)); } else if (pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv4v6) { - HANDLE_CODE(bref.pack_bytes(ipv6.data(), 16)); + HANDLE_CODE(bref.pack_bytes(ipv6.data(), 8)); HANDLE_CODE(bref.pack_bytes(ipv4.data(), 4)); } @@ -3985,20 +4825,20 @@ SRSASN_CODE pdu_address_t::unpack(asn1::cbit_ref& bref) HANDLE_CODE(bref.unpack_bytes(ipv4.data(), 4)); } else if (length == 9 && pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv6 && si6_lla == false) { - HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 16)); + HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 8)); } else if (length == 13 && pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv4v6 && si6_lla == false) { - HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 16)); + HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 8)); HANDLE_CODE(bref.unpack_bytes(ipv4.data(), 4)); } else if (length == 25 && pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv6 && si6_lla == true) { - HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 16)); - HANDLE_CODE(bref.unpack_bytes(smf_i_pv6_link_local_address.data(), 16)); + HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 8)); + HANDLE_CODE(bref.unpack_bytes(smf_i_pv6_link_local_address.data(), 8)); } else if (length == 29 && pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv4v6 && si6_lla == true) { - HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 16)); + HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 8)); HANDLE_CODE(bref.unpack_bytes(ipv4.data(), 4)); - HANDLE_CODE(bref.unpack_bytes(smf_i_pv6_link_local_address.data(), 16)); + HANDLE_CODE(bref.unpack_bytes(smf_i_pv6_link_local_address.data(), 8)); } else { asn1::log_error("Not expected combination of length and type field"); return SRSASN_ERROR_DECODE_FAIL; @@ -4006,6 +4846,19 @@ SRSASN_CODE pdu_address_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* pdu_address_t::PDU_session_type_value_type_::to_string() const +{ + switch (value) { + case PDU_session_type_value_type_::ipv4: + return "ipv4"; + case PDU_session_type_value_type_::ipv6: + return "ipv6"; + case PDU_session_type_value_type_::ipv4v6: + return "ipv4v6"; + default: + return "Invalid Choice"; + } +} // IE: QoS rules // Reference: 9.11.4.13 SRSASN_CODE qo_s_rules_t::pack(asn1::bit_ref& bref) @@ -4082,6 +4935,65 @@ SRSASN_CODE session_ambr_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* session_ambr_t::unit_session_AMBR_type_::to_string() const +{ + switch (value) { + case unit_session_AMBR_type_::not_used: + return "not used"; + case unit_session_AMBR_type_::inc_by_1_kbps: + return "inc by 1 Kbps"; + case unit_session_AMBR_type_::inc_by_4_kbps: + return "inc by 4 Kbps"; + case unit_session_AMBR_type_::inc_by_16_kbps: + return "inc by 16 Kbps"; + case unit_session_AMBR_type_::inc_by_64_kbps: + return "inc by 64 Kbps"; + case unit_session_AMBR_type_::inc_by_256_kbps: + return "inc by 256 kbps"; + case unit_session_AMBR_type_::inc_by_1_mbps: + return "inc by 1 Mbps"; + case unit_session_AMBR_type_::inc_by_4_mbps: + return "inc by 4 Mbps"; + case unit_session_AMBR_type_::inc_by_16_mbps: + return "inc by 16 Mbps"; + case unit_session_AMBR_type_::inc_by_64_mbps: + return "inc by 64 Mbps"; + case unit_session_AMBR_type_::inc_by_256_mbps: + return "inc by 256 Mbps"; + case unit_session_AMBR_type_::inc_by_1_gbps: + return "inc by 1 Gbps"; + case unit_session_AMBR_type_::inc_by_4_gbps: + return "inc by 4 Gbps"; + case unit_session_AMBR_type_::inc_by_16_gbps: + return "inc by 16 Gbps"; + case unit_session_AMBR_type_::inc_by_64_gbps: + return "inc by 64 Gbps"; + case unit_session_AMBR_type_::inc_by_256_gbps: + return "inc by 256 Gbps"; + case unit_session_AMBR_type_::inc_by_1_tbps: + return "inc by 1 Tbps"; + case unit_session_AMBR_type_::inc_by_4_tbps: + return "inc by 4 Tbps"; + case unit_session_AMBR_type_::inc_by_16_tbps: + return "inc by 16 Tbps"; + case unit_session_AMBR_type_::inc_by_64_tbps: + return "inc by 64 Tbps"; + case unit_session_AMBR_type_::inc_by_256_tbps: + return "inc by 256 Tbps"; + case unit_session_AMBR_type_::inc_by_1_pbps: + return "inc by 1 Pbps"; + case unit_session_AMBR_type_::inc_by_4_pbps: + return "inc by 4 Pbps"; + case unit_session_AMBR_type_::inc_by_16_pbps: + return "inc by 16 Pbps"; + case unit_session_AMBR_type_::inc_by_64_pbps: + return "inc by 64 Pbps"; + case unit_session_AMBR_type_::inc_by_256_pbps: + return "inc by 256 Pbps"; + default: + return "Invalid Choice"; + } +} // IE: 5GSM cause // Reference: 9.11.4.2 SRSASN_CODE cause_5gsm_t::pack(asn1::bit_ref& bref) @@ -4098,6 +5010,99 @@ SRSASN_CODE cause_5gsm_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* cause_5gsm_t::cause_value_type_::to_string() const +{ + switch (value) { + case cause_value_type_::operator_determined_barring: + return "Operator determined barring"; + case cause_value_type_::insufficient_resources: + return "Insufficient resources"; + case cause_value_type_::missing_or_unknown_dnn: + return "Missing or unknown DNN"; + case cause_value_type_::unknown_pdu_session_type: + return "Unknown PDU session type"; + case cause_value_type_::user_authentication_or_authorization_failed: + return "User authentication or authorization failed"; + case cause_value_type_::request_rejected_unspecified: + return "Request rejected, unspecified"; + case cause_value_type_::service_option_not_supported: + return "Service option not supported"; + case cause_value_type_::requested_service_option_not_subscribed: + return "Requested service option not subscribed"; + case cause_value_type_::pti_already_in_use: + return "PTI already in use"; + case cause_value_type_::regular_deactivation: + return "Regular deactivation"; + case cause_value_type_::network_failure: + return "Network failure"; + case cause_value_type_::reactivation_requested: + return "Reactivation requested"; + case cause_value_type_::semantic_error_in_the_tft_operation: + return "Semantic error in the TFT operation"; + case cause_value_type_::syntactical_error_in_the_tft_operation: + return "Syntactical error in the TFT operation"; + case cause_value_type_::invalid_pdu_session_identity: + return "Invalid PDU session identity"; + case cause_value_type_::semantic_errors_in_packet_filter: + return "Semantic errors in packet filter"; + case cause_value_type_::syntactical_error_in_packet_filter: + return "Syntactical error in packet filter"; + case cause_value_type_::out_of_ladn_service_area: + return "Out of LADN service area"; + case cause_value_type_::pti_mismatch: + return "PTI mismatch"; + case cause_value_type_::pdu_session_type_i_pv4_only_allowed: + return "PDU session type IPv4 only allowed"; + case cause_value_type_::pdu_session_type_i_pv6_only_allowed: + return "PDU session type IPv6 only allowed"; + case cause_value_type_::pdu_session_does_not_exist: + return "PDU session does not exist"; + case cause_value_type_::pdu_session_type_i_pv4v6_only_allowed: + return "PDU session type IPv4v6 only allowed"; + case cause_value_type_::pdu_session_type_unstructured_only_allowed: + return "PDU session type Unstructured only allowed"; + case cause_value_type_::unsupported_5_qi_value: + return "Unsupported 5QI value"; + case cause_value_type_::pdu_session_type_ethernet_only_allowed: + return "PDU session type Ethernet only allowed"; + case cause_value_type_::insufficient_resources_for_specific_slice_and_dnn: + return "Insufficient resources for specific slice and DNN"; + case cause_value_type_::not_supported_ssc_mode: + return "Not supported SSC mode"; + case cause_value_type_::insufficient_resources_for_specific_slice: + return "Insufficient resources for specific slice"; + case cause_value_type_::missing_or_unknown_dnn_in_a_slice: + return "Missing or unknown DNN in a slice"; + case cause_value_type_::invalid_pti_value: + return "Invalid PTI value"; + case cause_value_type_::maximum_data_rate_per_ue_for_user_plane_integrity_protection_is_too_low: + return "Maximum data rate per UE for user-plane integrity protection is too low"; + case cause_value_type_::semantic_error_in_the_qo_s_operation: + return "Semantic error in the QoS operation"; + case cause_value_type_::syntactical_error_in_the_qo_s_operation: + return "Syntactical error in the QoS operation"; + case cause_value_type_::invalid_mapped_eps_bearer_identity: + return "Invalid mapped EPS bearer identity"; + case cause_value_type_::semantically_incorrect_message: + return "Semantically incorrect message"; + case cause_value_type_::invalid_mandatory_information: + return "Invalid mandatory information"; + case cause_value_type_::message_type_non_existent_or_not_implemented: + return "Message type non-existent or not implemented"; + case cause_value_type_::message_type_not_compatible_with_the_protocol_state: + return "Message type not compatible with the protocol state"; + case cause_value_type_::information_element_non_existent_or_not_implemented: + return "Information element non-existent or not implemented"; + case cause_value_type_::conditional_ie_error: + return "Conditional IE error"; + case cause_value_type_::message_not_compatible_with_the_protocol_state: + return "Message not compatible with the protocol state"; + case cause_value_type_::protocol_error_unspecified: + return "Protocol error, unspecified"; + default: + return "Invalid Choice"; + } +} // IE: GPRS timer // Reference: 9.11.2.3 SRSASN_CODE gprs_timer_t::pack(asn1::bit_ref& bref) @@ -4116,6 +5121,21 @@ SRSASN_CODE gprs_timer_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* gprs_timer_t::Unit_type_::to_string() const +{ + switch (value) { + case Unit_type_::value_is_incremented_in_multiples_of_2_seconds: + return "value is incremented in multiples of 2 seconds"; + case Unit_type_::value_is_incremented_in_multiples_of_1_minute: + return "value is incremented in multiples of 1 minute"; + case Unit_type_::value_is_incremented_in_multiples_of_decihours: + return "value is incremented in multiples of decihours"; + case Unit_type_::value_indicates_that_the_timer_is_deactivated: + return "value indicates that the timer is deactivated"; + default: + return "Invalid Choice"; + } +} // IE: Always-on PDU session indication // Reference: 9.11.4.3 SRSASN_CODE always_on_pdu_session_indication_t::pack(asn1::bit_ref& bref) @@ -4263,6 +5283,17 @@ SRSASN_CODE network_feature_support_5gsm_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* network_feature_support_5gsm_t::EPT_S1_type_::to_string() const +{ + switch (value) { + case EPT_S1_type_::ethernet_pdn_type_in_s1_mode_not_supported: + return "Ethernet PDN type in S1 mode not supported"; + case EPT_S1_type_::ethernet_pdn_type_in_s1_mode_supported: + return "Ethernet PDN type in S1 mode supported"; + default: + return "Invalid Choice"; + } +} // IE: Serving PLMN rate control // Reference: 9.11.4.20 SRSASN_CODE serving_plmn_rate_control_t::pack(asn1::bit_ref& bref) @@ -4394,6 +5425,17 @@ SRSASN_CODE congestion_re_attempt_indicator_5gsm_t::unpack(asn1::cbit_ref& bref) return SRSASN_SUCCESS; } +const char* congestion_re_attempt_indicator_5gsm_t::abo_type_::to_string() const +{ + switch (value) { + case abo_type_::the_back_off_timer_is_applied_in_the_registered_plmn: + return "The back-off timer is applied in the registered PLMN"; + case abo_type_::the_back_off_timer_is_applied_in_all_plm_ns: + return "The back-off timer is applied in all PLMNs"; + default: + return "Invalid Choice"; + } +} // IE: Re-attempt indicator // Reference: 9.11.4.17 SRSASN_CODE re_attempt_indicator_t::pack(asn1::bit_ref& bref) diff --git a/lib/src/asn1/nas_5g_msg.cc b/lib/src/asn1/nas_5g_msg.cc index 67d5676de4..a2e0c23367 100644 --- a/lib/src/asn1/nas_5g_msg.cc +++ b/lib/src/asn1/nas_5g_msg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/asn1/nas_5g_utils.cc b/lib/src/asn1/nas_5g_utils.cc index 07fe1f2421..5cc51842cc 100644 --- a/lib/src/asn1/nas_5g_utils.cc +++ b/lib/src/asn1/nas_5g_utils.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/asn1/ngap.cc b/lib/src/asn1/ngap.cc index fe55a2580e..49c6d7203a 100644 --- a/lib/src/asn1/ngap.cc +++ b/lib/src/asn1/ngap.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,241 +23,12 @@ #include using namespace asn1; -using namespace asn1::ngap_nr; +using namespace asn1::ngap; /******************************************************************************* * Struct Methods ******************************************************************************/ -// Criticality ::= ENUMERATED -const char* crit_opts::to_string() const -{ - static const char* options[] = {"reject", "ignore", "notify"}; - return convert_enum_idx(options, 3, value, "crit_e"); -} - -// Presence ::= ENUMERATED -const char* presence_opts::to_string() const -{ - static const char* options[] = {"optional", "conditional", "mandatory"}; - return convert_enum_idx(options, 3, value, "presence_e"); -} - -// ProtocolIE-Field{NGAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{NGAP-PROTOCOL-IES}} -template -SRSASN_CODE protocol_ie_field_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); - warn_assert(crit != ies_set_paramT_::get_crit(id), __func__, __LINE__); - HANDLE_CODE(crit.pack(bref)); - HANDLE_CODE(value.pack(bref)); - - return SRSASN_SUCCESS; -} -template -SRSASN_CODE protocol_ie_field_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.unpack(bref)); - value = ies_set_paramT_::get_value(id); - HANDLE_CODE(value.unpack(bref)); - - return SRSASN_SUCCESS; -} -template -void protocol_ie_field_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("id", id); - j.write_str("criticality", crit.to_string()); - j.end_obj(); -} -template -bool protocol_ie_field_s::load_info_obj(const uint32_t& id_) -{ - if (not ies_set_paramT_::is_id_valid(id_)) { - return false; - } - id = id_; - crit = ies_set_paramT_::get_crit(id); - value = ies_set_paramT_::get_value(id); - return value.type().value != ies_set_paramT_::value_c::types_opts::nulltype; -} - -uint32_t ngap_protocol_ies_empty_o::idx_to_id(uint32_t idx) -{ - asn1::log_error("object set is empty\n"); - return 0; -} -bool ngap_protocol_ies_empty_o::is_id_valid(const uint32_t& id) -{ - asn1::log_error("object set is empty\n"); - return false; -} -crit_e ngap_protocol_ies_empty_o::get_crit(const uint32_t& id) -{ - return {}; -} -ngap_protocol_ies_empty_o::value_c ngap_protocol_ies_empty_o::get_value(const uint32_t& id) -{ - return {}; -} -presence_e ngap_protocol_ies_empty_o::get_presence(const uint32_t& id) -{ - return {}; -} - -// Value ::= OPEN TYPE -void ngap_protocol_ies_empty_o::value_c::to_json(json_writer& j) const -{ - j.start_obj(); - j.end_obj(); -} -SRSASN_CODE ngap_protocol_ies_empty_o::value_c::pack(bit_ref& bref) const -{ - varlength_field_pack_guard varlen_scope(bref, true); - return SRSASN_SUCCESS; -} -SRSASN_CODE ngap_protocol_ies_empty_o::value_c::unpack(cbit_ref& bref) -{ - varlength_field_unpack_guard varlen_scope(bref, true); - return SRSASN_SUCCESS; -} - -const char* ngap_protocol_ies_empty_o::value_c::types_opts::to_string() const -{ - static const char* options[] = {}; - return convert_enum_idx(options, 0, value, "ngap_protocol_ies_empty_o::value_c::types"); -} - -// ProtocolExtensionField{NGAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE{{NGAP-PROTOCOL-EXTENSION}} -template -SRSASN_CODE protocol_ext_field_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); - warn_assert(crit != ext_set_paramT_::get_crit(id), __func__, __LINE__); - HANDLE_CODE(crit.pack(bref)); - HANDLE_CODE(ext_value.pack(bref)); - - return SRSASN_SUCCESS; -} -template -SRSASN_CODE protocol_ext_field_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.unpack(bref)); - ext_value = ext_set_paramT_::get_ext(id); - HANDLE_CODE(ext_value.unpack(bref)); - - return SRSASN_SUCCESS; -} -template -void protocol_ext_field_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("id", id); - j.write_str("criticality", crit.to_string()); - j.end_obj(); -} -template -bool protocol_ext_field_s::load_info_obj(const uint32_t& id_) -{ - if (not ext_set_paramT_::is_id_valid(id_)) { - return false; - } - id = id_; - crit = ext_set_paramT_::get_crit(id); - ext_value = ext_set_paramT_::get_ext(id); - return ext_value.type().value != ext_set_paramT_::ext_c::types_opts::nulltype; -} - -// ProtocolIE-SingleContainer{NGAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{NGAP-PROTOCOL-IES}} -template -SRSASN_CODE protocol_ie_single_container_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); - warn_assert(crit != ies_set_paramT_::get_crit(id), __func__, __LINE__); - HANDLE_CODE(crit.pack(bref)); - HANDLE_CODE(value.pack(bref)); - - return SRSASN_SUCCESS; -} -template -SRSASN_CODE protocol_ie_single_container_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.unpack(bref)); - value = ies_set_paramT_::get_value(id); - HANDLE_CODE(value.unpack(bref)); - - return SRSASN_SUCCESS; -} -template -void protocol_ie_single_container_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("id", id); - j.write_str("criticality", crit.to_string()); - j.end_obj(); -} -template -bool protocol_ie_single_container_s::load_info_obj(const uint32_t& id_) -{ - if (not ies_set_paramT_::is_id_valid(id_)) { - return false; - } - id = id_; - crit = ies_set_paramT_::get_crit(id); - value = ies_set_paramT_::get_value(id); - return value.type().value != ies_set_paramT_::value_c::types_opts::nulltype; -} - -uint32_t ngap_protocol_ext_empty_o::idx_to_id(uint32_t idx) -{ - asn1::log_error("object set is empty\n"); - return 0; -} -bool ngap_protocol_ext_empty_o::is_id_valid(const uint32_t& id) -{ - asn1::log_error("object set is empty\n"); - return false; -} -crit_e ngap_protocol_ext_empty_o::get_crit(const uint32_t& id) -{ - return {}; -} -ngap_protocol_ext_empty_o::ext_c ngap_protocol_ext_empty_o::get_ext(const uint32_t& id) -{ - return {}; -} -presence_e ngap_protocol_ext_empty_o::get_presence(const uint32_t& id) -{ - return {}; -} - -// Extension ::= OPEN TYPE -void ngap_protocol_ext_empty_o::ext_c::to_json(json_writer& j) const -{ - j.start_obj(); - j.end_obj(); -} -SRSASN_CODE ngap_protocol_ext_empty_o::ext_c::pack(bit_ref& bref) const -{ - varlength_field_pack_guard varlen_scope(bref, true); - return SRSASN_SUCCESS; -} -SRSASN_CODE ngap_protocol_ext_empty_o::ext_c::unpack(cbit_ref& bref) -{ - varlength_field_unpack_guard varlen_scope(bref, true); - return SRSASN_SUCCESS; -} - -const char* ngap_protocol_ext_empty_o::ext_c::types_opts::to_string() const -{ - static const char* options[] = {}; - return convert_enum_idx(options, 0, value, "ngap_protocol_ext_empty_o::ext_c::types"); -} - // CPTransportLayerInformation ::= CHOICE void cp_transport_layer_info_c::destroy_() { @@ -393,63 +164,6 @@ const char* cp_transport_layer_info_c::types_opts::to_string() const return convert_enum_idx(options, 2, value, "cp_transport_layer_info_c::types"); } -template -protocol_ext_container_item_s::protocol_ext_container_item_s(uint32_t id_, crit_e crit_) : id(id_), crit(crit_) - -{} -template -SRSASN_CODE protocol_ext_container_item_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.pack(bref)); - { - varlength_field_pack_guard varlen_scope(bref, true); - HANDLE_CODE(ext.pack(bref)); - } - return SRSASN_SUCCESS; -} -template -SRSASN_CODE protocol_ext_container_item_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.unpack(bref)); - { - varlength_field_unpack_guard varlen_scope(bref, true); - HANDLE_CODE(ext.unpack(bref)); - } - return SRSASN_SUCCESS; -} -template -void protocol_ext_container_item_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("id", id); - j.write_str("criticality", crit.to_string()); - j.end_obj(); -} - -SRSASN_CODE protocol_ext_container_empty_l::pack(bit_ref& bref) const -{ - uint32_t nof_ies = 0; - pack_length(bref, nof_ies, 1u, 65535u, true); - - return SRSASN_SUCCESS; -} -SRSASN_CODE protocol_ext_container_empty_l::unpack(cbit_ref& bref) -{ - uint32_t nof_ies = 0; - unpack_length(nof_ies, bref, 1u, 65535u, true); - if (nof_ies > 0) { - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; -} -void protocol_ext_container_empty_l::to_json(json_writer& j) const -{ - j.start_obj(); - j.end_obj(); -} - // AMF-TNLAssociationSetupItem ::= SEQUENCE SRSASN_CODE amf_tnlassoc_setup_item_s::pack(bit_ref& bref) const { @@ -1279,42 +993,7 @@ uint8_t amf_cfg_upd_ies_o::value_c::types_opts::to_number() const return 0; } -template -protocol_ie_container_item_s::protocol_ie_container_item_s(uint32_t id_, crit_e crit_) : id(id_), crit(crit_) - -{} -template -SRSASN_CODE protocol_ie_container_item_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.pack(bref)); - { - varlength_field_pack_guard varlen_scope(bref, true); - HANDLE_CODE(value.pack(bref)); - } - return SRSASN_SUCCESS; -} -template -SRSASN_CODE protocol_ie_container_item_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.unpack(bref)); - { - varlength_field_unpack_guard varlen_scope(bref, true); - HANDLE_CODE(value.unpack(bref)); - } - return SRSASN_SUCCESS; -} -template -void protocol_ie_container_item_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("id", id); - j.write_str("criticality", crit.to_string()); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; amf_cfg_upd_ies_container::amf_cfg_upd_ies_container() : amf_name(1, crit_e::reject), @@ -1367,53 +1046,67 @@ SRSASN_CODE amf_cfg_upd_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 1: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 1: { amf_name_present = true; - amf_name.id = c.id; - amf_name.crit = c.crit; - amf_name.value = c.value.amf_name(); + amf_name.id = id; + HANDLE_CODE(amf_name.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_name.value.unpack(bref)); break; - case 96: + } + case 96: { served_guami_list_present = true; - served_guami_list.id = c.id; - served_guami_list.crit = c.crit; - served_guami_list.value = c.value.served_guami_list(); + served_guami_list.id = id; + HANDLE_CODE(served_guami_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(served_guami_list.value.unpack(bref)); break; - case 86: + } + case 86: { relative_amf_capacity_present = true; - relative_amf_capacity.id = c.id; - relative_amf_capacity.crit = c.crit; - relative_amf_capacity.value = c.value.relative_amf_capacity(); + relative_amf_capacity.id = id; + HANDLE_CODE(relative_amf_capacity.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(relative_amf_capacity.value.unpack(bref)); break; - case 80: + } + case 80: { plmn_support_list_present = true; - plmn_support_list.id = c.id; - plmn_support_list.crit = c.crit; - plmn_support_list.value = c.value.plmn_support_list(); + plmn_support_list.id = id; + HANDLE_CODE(plmn_support_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(plmn_support_list.value.unpack(bref)); break; - case 6: + } + case 6: { amf_tnlassoc_to_add_list_present = true; - amf_tnlassoc_to_add_list.id = c.id; - amf_tnlassoc_to_add_list.crit = c.crit; - amf_tnlassoc_to_add_list.value = c.value.amf_tnlassoc_to_add_list(); + amf_tnlassoc_to_add_list.id = id; + HANDLE_CODE(amf_tnlassoc_to_add_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_tnlassoc_to_add_list.value.unpack(bref)); break; - case 7: + } + case 7: { amf_tnlassoc_to_rem_list_present = true; - amf_tnlassoc_to_rem_list.id = c.id; - amf_tnlassoc_to_rem_list.crit = c.crit; - amf_tnlassoc_to_rem_list.value = c.value.amf_tnlassoc_to_rem_list(); + amf_tnlassoc_to_rem_list.id = id; + HANDLE_CODE(amf_tnlassoc_to_rem_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_tnlassoc_to_rem_list.value.unpack(bref)); break; - case 8: + } + case 8: { amf_tnlassoc_to_upd_list_present = true; - amf_tnlassoc_to_upd_list.id = c.id; - amf_tnlassoc_to_upd_list.crit = c.crit; - amf_tnlassoc_to_upd_list.value = c.value.amf_tnlassoc_to_upd_list(); + amf_tnlassoc_to_upd_list.id = id; + HANDLE_CODE(amf_tnlassoc_to_upd_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_tnlassoc_to_upd_list.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -1454,29 +1147,6 @@ void amf_cfg_upd_ies_container::to_json(json_writer& j) const j.end_obj(); } -// AMFConfigurationUpdate ::= SEQUENCE -SRSASN_CODE amf_cfg_upd_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE amf_cfg_upd_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void amf_cfg_upd_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // CauseMisc ::= ENUMERATED const char* cause_misc_opts::to_string() const { @@ -1897,7 +1567,7 @@ SRSASN_CODE crit_diagnostics_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(proc_code_present, 1)); HANDLE_CODE(bref.pack(trigger_msg_present, 1)); HANDLE_CODE(bref.pack(proc_crit_present, 1)); - HANDLE_CODE(bref.pack(ies_crit_diagnostics_present, 1)); + HANDLE_CODE(bref.pack(ies_crit_diagnostics.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); if (proc_code_present) { @@ -1909,7 +1579,7 @@ SRSASN_CODE crit_diagnostics_s::pack(bit_ref& bref) const if (proc_crit_present) { HANDLE_CODE(proc_crit.pack(bref)); } - if (ies_crit_diagnostics_present) { + if (ies_crit_diagnostics.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ies_crit_diagnostics, 1, 256, true)); } if (ie_exts_present) { @@ -1924,6 +1594,7 @@ SRSASN_CODE crit_diagnostics_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(proc_code_present, 1)); HANDLE_CODE(bref.unpack(trigger_msg_present, 1)); HANDLE_CODE(bref.unpack(proc_crit_present, 1)); + bool ies_crit_diagnostics_present; HANDLE_CODE(bref.unpack(ies_crit_diagnostics_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -1957,7 +1628,7 @@ void crit_diagnostics_s::to_json(json_writer& j) const if (proc_crit_present) { j.write_str("procedureCriticality", proc_crit.to_string()); } - if (ies_crit_diagnostics_present) { + if (ies_crit_diagnostics.size() > 0) { j.start_array("iEsCriticalityDiagnostics"); for (const auto& e1 : ies_crit_diagnostics) { e1.to_json(j); @@ -2216,7 +1887,7 @@ const char* amf_cfg_upd_ack_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "amf_cfg_upd_ack_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; amf_cfg_upd_ack_ies_container::amf_cfg_upd_ack_ies_container() : amf_tnlassoc_setup_list(5, crit_e::ignore), @@ -2249,29 +1920,35 @@ SRSASN_CODE amf_cfg_upd_ack_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 5: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 5: { amf_tnlassoc_setup_list_present = true; - amf_tnlassoc_setup_list.id = c.id; - amf_tnlassoc_setup_list.crit = c.crit; - amf_tnlassoc_setup_list.value = c.value.amf_tnlassoc_setup_list(); + amf_tnlassoc_setup_list.id = id; + HANDLE_CODE(amf_tnlassoc_setup_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_tnlassoc_setup_list.value.unpack(bref)); break; - case 4: + } + case 4: { amf_tnlassoc_failed_to_setup_list_present = true; - amf_tnlassoc_failed_to_setup_list.id = c.id; - amf_tnlassoc_failed_to_setup_list.crit = c.crit; - amf_tnlassoc_failed_to_setup_list.value = c.value.amf_tnlassoc_failed_to_setup_list(); + amf_tnlassoc_failed_to_setup_list.id = id; + HANDLE_CODE(amf_tnlassoc_failed_to_setup_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_tnlassoc_failed_to_setup_list.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -2296,29 +1973,6 @@ void amf_cfg_upd_ack_ies_container::to_json(json_writer& j) const j.end_obj(); } -// AMFConfigurationUpdateAcknowledge ::= SEQUENCE -SRSASN_CODE amf_cfg_upd_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE amf_cfg_upd_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void amf_cfg_upd_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // TimeToWait ::= ENUMERATED const char* time_to_wait_opts::to_string() const { @@ -2566,7 +2220,7 @@ const char* amf_cfg_upd_fail_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "amf_cfg_upd_fail_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; amf_cfg_upd_fail_ies_container::amf_cfg_upd_fail_ies_container() : cause(15, crit_e::ignore), time_to_wait(107, crit_e::ignore), crit_diagnostics(19, crit_e::ignore) @@ -2596,29 +2250,35 @@ SRSASN_CODE amf_cfg_upd_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 1; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 15: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 107: + } + case 107: { time_to_wait_present = true; - time_to_wait.id = c.id; - time_to_wait.crit = c.crit; - time_to_wait.value = c.value.time_to_wait(); + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -2645,29 +2305,6 @@ void amf_cfg_upd_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// AMFConfigurationUpdateFailure ::= SEQUENCE -SRSASN_CODE amf_cfg_upd_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE amf_cfg_upd_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void amf_cfg_upd_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // GNB-ID ::= CHOICE void gnb_id_c::destroy_() { @@ -3781,28 +3418,6 @@ const char* amf_status_ind_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 1, value, "amf_status_ind_ies_o::value_c::types"); } -// AMFStatusIndication ::= SEQUENCE -SRSASN_CODE amf_status_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(pack_dyn_seq_of(bref, protocol_ies, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE amf_status_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(unpack_dyn_seq_of(protocol_ies, bref, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -void amf_status_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - j.end_obj(); -} - // DataForwardingAccepted ::= ENUMERATED const char* data_forwarding_accepted_opts::to_string() const { @@ -4537,18 +4152,18 @@ void area_of_interest_tai_item_s::to_json(json_writer& j) const SRSASN_CODE area_of_interest_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(area_of_interest_tai_list_present, 1)); - HANDLE_CODE(bref.pack(area_of_interest_cell_list_present, 1)); - HANDLE_CODE(bref.pack(area_of_interest_ran_node_list_present, 1)); + HANDLE_CODE(bref.pack(area_of_interest_tai_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(area_of_interest_cell_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(area_of_interest_ran_node_list.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); - if (area_of_interest_tai_list_present) { + if (area_of_interest_tai_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, area_of_interest_tai_list, 1, 16, true)); } - if (area_of_interest_cell_list_present) { + if (area_of_interest_cell_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, area_of_interest_cell_list, 1, 256, true)); } - if (area_of_interest_ran_node_list_present) { + if (area_of_interest_ran_node_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, area_of_interest_ran_node_list, 1, 64, true)); } if (ie_exts_present) { @@ -4560,8 +4175,11 @@ SRSASN_CODE area_of_interest_s::pack(bit_ref& bref) const SRSASN_CODE area_of_interest_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool area_of_interest_tai_list_present; HANDLE_CODE(bref.unpack(area_of_interest_tai_list_present, 1)); + bool area_of_interest_cell_list_present; HANDLE_CODE(bref.unpack(area_of_interest_cell_list_present, 1)); + bool area_of_interest_ran_node_list_present; HANDLE_CODE(bref.unpack(area_of_interest_ran_node_list_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -4583,21 +4201,21 @@ SRSASN_CODE area_of_interest_s::unpack(cbit_ref& bref) void area_of_interest_s::to_json(json_writer& j) const { j.start_obj(); - if (area_of_interest_tai_list_present) { + if (area_of_interest_tai_list.size() > 0) { j.start_array("areaOfInterestTAIList"); for (const auto& e1 : area_of_interest_tai_list) { e1.to_json(j); } j.end_array(); } - if (area_of_interest_cell_list_present) { + if (area_of_interest_cell_list.size() > 0) { j.start_array("areaOfInterestCellList"); for (const auto& e1 : area_of_interest_cell_list) { e1.to_json(j); } j.end_array(); } - if (area_of_interest_ran_node_list_present) { + if (area_of_interest_ran_node_list.size() > 0) { j.start_array("areaOfInterestRANNodeList"); for (const auto& e1 : area_of_interest_ran_node_list) { e1.to_json(j); @@ -6945,7 +6563,7 @@ const char* cell_traffic_trace_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 5, value, "cell_traffic_trace_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; cell_traffic_trace_ies_container::cell_traffic_trace_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -6975,41 +6593,51 @@ SRSASN_CODE cell_traffic_trace_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 5; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 44: + } + case 44: { nof_mandatory_ies--; - ngran_trace_id.id = c.id; - ngran_trace_id.crit = c.crit; - ngran_trace_id.value = c.value.ngran_trace_id(); + ngran_trace_id.id = id; + HANDLE_CODE(ngran_trace_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ngran_trace_id.value.unpack(bref)); break; - case 43: + } + case 43: { nof_mandatory_ies--; - ngran_cgi.id = c.id; - ngran_cgi.crit = c.crit; - ngran_cgi.value = c.value.ngran_cgi(); + ngran_cgi.id = id; + HANDLE_CODE(ngran_cgi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ngran_cgi.value.unpack(bref)); break; - case 109: + } + case 109: { nof_mandatory_ies--; - trace_collection_entity_ip_address.id = c.id; - trace_collection_entity_ip_address.crit = c.crit; - trace_collection_entity_ip_address.value = c.value.trace_collection_entity_ip_address(); + trace_collection_entity_ip_address.id = id; + HANDLE_CODE(trace_collection_entity_ip_address.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(trace_collection_entity_ip_address.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -7036,29 +6664,6 @@ void cell_traffic_trace_ies_container::to_json(json_writer& j) const j.end_obj(); } -// CellTrafficTrace ::= SEQUENCE -SRSASN_CODE cell_traffic_trace_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE cell_traffic_trace_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void cell_traffic_trace_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // CellSize ::= ENUMERATED const char* cell_size_opts::to_string() const { @@ -7286,7 +6891,7 @@ SRSASN_CODE expected_ue_behaviour_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(expected_ue_activity_behaviour_present, 1)); HANDLE_CODE(bref.pack(expected_ho_interv_present, 1)); HANDLE_CODE(bref.pack(expected_ue_mob_present, 1)); - HANDLE_CODE(bref.pack(expected_ue_moving_trajectory_present, 1)); + HANDLE_CODE(bref.pack(expected_ue_moving_trajectory.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); if (expected_ue_activity_behaviour_present) { @@ -7298,7 +6903,7 @@ SRSASN_CODE expected_ue_behaviour_s::pack(bit_ref& bref) const if (expected_ue_mob_present) { HANDLE_CODE(expected_ue_mob.pack(bref)); } - if (expected_ue_moving_trajectory_present) { + if (expected_ue_moving_trajectory.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, expected_ue_moving_trajectory, 1, 16, true)); } if (ie_exts_present) { @@ -7313,6 +6918,7 @@ SRSASN_CODE expected_ue_behaviour_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(expected_ue_activity_behaviour_present, 1)); HANDLE_CODE(bref.unpack(expected_ho_interv_present, 1)); HANDLE_CODE(bref.unpack(expected_ue_mob_present, 1)); + bool expected_ue_moving_trajectory_present; HANDLE_CODE(bref.unpack(expected_ue_moving_trajectory_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -7347,7 +6953,7 @@ void expected_ue_behaviour_s::to_json(json_writer& j) const if (expected_ue_mob_present) { j.write_str("expectedUEMobility", expected_ue_mob.to_string()); } - if (expected_ue_moving_trajectory_present) { + if (expected_ue_moving_trajectory.size() > 0) { j.start_array("expectedUEMovingTrajectory"); for (const auto& e1 : expected_ue_moving_trajectory) { e1.to_json(j); @@ -8482,7 +8088,7 @@ const char* deactiv_trace_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "deactiv_trace_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; deactiv_trace_ies_container::deactiv_trace_ies_container() : amf_ue_ngap_id(10, crit_e::reject), ran_ue_ngap_id(85, crit_e::reject), ngran_trace_id(44, crit_e::ignore) @@ -8506,29 +8112,35 @@ SRSASN_CODE deactiv_trace_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 44: + } + case 44: { nof_mandatory_ies--; - ngran_trace_id.id = c.id; - ngran_trace_id.crit = c.crit; - ngran_trace_id.value = c.value.ngran_trace_id(); + ngran_trace_id.id = id; + HANDLE_CODE(ngran_trace_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ngran_trace_id.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -8551,29 +8163,6 @@ void deactiv_trace_ies_container::to_json(json_writer& j) const j.end_obj(); } -// DeactivateTrace ::= SEQUENCE -SRSASN_CODE deactiv_trace_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE deactiv_trace_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void deactiv_trace_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // ForbiddenAreaInformation-Item ::= SEQUENCE SRSASN_CODE forbidden_area_info_item_s::pack(bit_ref& bref) const { @@ -8660,15 +8249,15 @@ void rat_restricts_item_s::to_json(json_writer& j) const SRSASN_CODE service_area_info_item_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(allowed_tacs_present, 1)); - HANDLE_CODE(bref.pack(not_allowed_tacs_present, 1)); + HANDLE_CODE(bref.pack(allowed_tacs.size() > 0, 1)); + HANDLE_CODE(bref.pack(not_allowed_tacs.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); HANDLE_CODE(plmn_id.pack(bref)); - if (allowed_tacs_present) { + if (allowed_tacs.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, allowed_tacs, 1, 16, true)); } - if (not_allowed_tacs_present) { + if (not_allowed_tacs.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, not_allowed_tacs, 1, 16, true)); } if (ie_exts_present) { @@ -8680,7 +8269,9 @@ SRSASN_CODE service_area_info_item_s::pack(bit_ref& bref) const SRSASN_CODE service_area_info_item_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool allowed_tacs_present; HANDLE_CODE(bref.unpack(allowed_tacs_present, 1)); + bool not_allowed_tacs_present; HANDLE_CODE(bref.unpack(not_allowed_tacs_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -8701,14 +8292,14 @@ void service_area_info_item_s::to_json(json_writer& j) const { j.start_obj(); j.write_str("pLMNIdentity", plmn_id.to_string()); - if (allowed_tacs_present) { + if (allowed_tacs.size() > 0) { j.start_array("allowedTACs"); for (const auto& e1 : allowed_tacs) { j.write_str(e1.to_string()); } j.end_array(); } - if (not_allowed_tacs_present) { + if (not_allowed_tacs.size() > 0) { j.start_array("notAllowedTACs"); for (const auto& e1 : not_allowed_tacs) { j.write_str(e1.to_string()); @@ -8787,26 +8378,26 @@ const char* mob_restrict_list_ext_ies_o::ext_c::types_opts::to_string() const SRSASN_CODE mob_restrict_list_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(equivalent_plmns_present, 1)); - HANDLE_CODE(bref.pack(rat_restricts_present, 1)); - HANDLE_CODE(bref.pack(forbidden_area_info_present, 1)); - HANDLE_CODE(bref.pack(service_area_info_present, 1)); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(equivalent_plmns.size() > 0, 1)); + HANDLE_CODE(bref.pack(rat_restricts.size() > 0, 1)); + HANDLE_CODE(bref.pack(forbidden_area_info.size() > 0, 1)); + HANDLE_CODE(bref.pack(service_area_info.size() > 0, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); HANDLE_CODE(serving_plmn.pack(bref)); - if (equivalent_plmns_present) { + if (equivalent_plmns.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, equivalent_plmns, 1, 15, true)); } - if (rat_restricts_present) { + if (rat_restricts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, rat_restricts, 1, 16, true)); } - if (forbidden_area_info_present) { + if (forbidden_area_info.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, forbidden_area_info, 1, 16, true)); } - if (service_area_info_present) { + if (service_area_info.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, service_area_info, 1, 16, true)); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -8815,10 +8406,15 @@ SRSASN_CODE mob_restrict_list_s::pack(bit_ref& bref) const SRSASN_CODE mob_restrict_list_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool equivalent_plmns_present; HANDLE_CODE(bref.unpack(equivalent_plmns_present, 1)); + bool rat_restricts_present; HANDLE_CODE(bref.unpack(rat_restricts_present, 1)); + bool forbidden_area_info_present; HANDLE_CODE(bref.unpack(forbidden_area_info_present, 1)); + bool service_area_info_present; HANDLE_CODE(bref.unpack(service_area_info_present, 1)); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); HANDLE_CODE(serving_plmn.unpack(bref)); @@ -8844,35 +8440,35 @@ void mob_restrict_list_s::to_json(json_writer& j) const { j.start_obj(); j.write_str("servingPLMN", serving_plmn.to_string()); - if (equivalent_plmns_present) { + if (equivalent_plmns.size() > 0) { j.start_array("equivalentPLMNs"); for (const auto& e1 : equivalent_plmns) { j.write_str(e1.to_string()); } j.end_array(); } - if (rat_restricts_present) { + if (rat_restricts.size() > 0) { j.start_array("rATRestrictions"); for (const auto& e1 : rat_restricts) { e1.to_json(j); } j.end_array(); } - if (forbidden_area_info_present) { + if (forbidden_area_info.size() > 0) { j.start_array("forbiddenAreaInformation"); for (const auto& e1 : forbidden_area_info) { e1.to_json(j); } j.end_array(); } - if (service_area_info_present) { + if (service_area_info.size() > 0) { j.start_array("serviceAreaInformation"); for (const auto& e1 : service_area_info) { e1.to_json(j); } j.end_array(); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -9382,7 +8978,7 @@ const char* dl_nas_transport_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 9, value, "dl_nas_transport_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; dl_nas_transport_ies_container::dl_nas_transport_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -9438,65 +9034,83 @@ SRSASN_CODE dl_nas_transport_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 48: + } + case 48: { old_amf_present = true; - old_amf.id = c.id; - old_amf.crit = c.crit; - old_amf.value = c.value.old_amf(); + old_amf.id = id; + HANDLE_CODE(old_amf.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(old_amf.value.unpack(bref)); break; - case 83: + } + case 83: { ran_paging_prio_present = true; - ran_paging_prio.id = c.id; - ran_paging_prio.crit = c.crit; - ran_paging_prio.value = c.value.ran_paging_prio(); + ran_paging_prio.id = id; + HANDLE_CODE(ran_paging_prio.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_paging_prio.value.unpack(bref)); break; - case 38: + } + case 38: { nof_mandatory_ies--; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; - case 36: + } + case 36: { mob_restrict_list_present = true; - mob_restrict_list.id = c.id; - mob_restrict_list.crit = c.crit; - mob_restrict_list.value = c.value.mob_restrict_list(); + mob_restrict_list.id = id; + HANDLE_CODE(mob_restrict_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mob_restrict_list.value.unpack(bref)); break; - case 31: + } + case 31: { idx_to_rfsp_present = true; - idx_to_rfsp.id = c.id; - idx_to_rfsp.crit = c.crit; - idx_to_rfsp.value = c.value.idx_to_rfsp(); + idx_to_rfsp.id = id; + HANDLE_CODE(idx_to_rfsp.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(idx_to_rfsp.value.unpack(bref)); break; - case 110: + } + case 110: { ue_aggregate_maximum_bit_rate_present = true; - ue_aggregate_maximum_bit_rate.id = c.id; - ue_aggregate_maximum_bit_rate.crit = c.crit; - ue_aggregate_maximum_bit_rate.value = c.value.ue_aggregate_maximum_bit_rate(); + ue_aggregate_maximum_bit_rate.id = id; + HANDLE_CODE(ue_aggregate_maximum_bit_rate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_aggregate_maximum_bit_rate.value.unpack(bref)); break; - case 0: + } + case 0: { allowed_nssai_present = true; - allowed_nssai.id = c.id; - allowed_nssai.crit = c.crit; - allowed_nssai.value = c.value.allowed_nssai(); + allowed_nssai.id = id; + HANDLE_CODE(allowed_nssai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(allowed_nssai.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -9543,29 +9157,6 @@ void dl_nas_transport_ies_container::to_json(json_writer& j) const j.end_obj(); } -// DownlinkNASTransport ::= SEQUENCE -SRSASN_CODE dl_nas_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE dl_nas_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void dl_nas_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // DownlinkNonUEAssociatedNRPPaTransportIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES uint32_t dl_non_ueassociated_nrp_pa_transport_ies_o::idx_to_id(uint32_t idx) { @@ -9767,7 +9358,7 @@ const char* dl_non_ueassociated_nrp_pa_transport_ies_o::value_c::types_opts::to_ return convert_enum_idx(options, 2, value, "dl_non_ueassociated_nrp_pa_transport_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; dl_non_ueassociated_nrp_pa_transport_ies_container::dl_non_ueassociated_nrp_pa_transport_ies_container() : routing_id(89, crit_e::reject), nrp_pa_pdu(46, crit_e::reject) @@ -9790,23 +9381,27 @@ SRSASN_CODE dl_non_ueassociated_nrp_pa_transport_ies_container::unpack(cbit_ref& uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 89: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 89: { nof_mandatory_ies--; - routing_id.id = c.id; - routing_id.crit = c.crit; - routing_id.value = c.value.routing_id(); + routing_id.id = id; + HANDLE_CODE(routing_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(routing_id.value.unpack(bref)); break; - case 46: + } + case 46: { nof_mandatory_ies--; - nrp_pa_pdu.id = c.id; - nrp_pa_pdu.crit = c.crit; - nrp_pa_pdu.value = c.value.nrp_pa_pdu(); + nrp_pa_pdu.id = id; + HANDLE_CODE(nrp_pa_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrp_pa_pdu.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -9827,41 +9422,18 @@ void dl_non_ueassociated_nrp_pa_transport_ies_container::to_json(json_writer& j) j.end_obj(); } -// DownlinkNonUEAssociatedNRPPaTransport ::= SEQUENCE -SRSASN_CODE dl_non_ueassociated_nrp_pa_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE dl_non_ueassociated_nrp_pa_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void dl_non_ueassociated_nrp_pa_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // XnExtTLA-Item ::= SEQUENCE SRSASN_CODE xn_ext_tla_item_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(ipsec_tla_present, 1)); - HANDLE_CODE(bref.pack(gtp_tlas_present, 1)); + HANDLE_CODE(bref.pack(gtp_tlas.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); if (ipsec_tla_present) { HANDLE_CODE(ipsec_tla.pack(bref)); } - if (gtp_tlas_present) { + if (gtp_tlas.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, gtp_tlas, 1, 16, true)); } if (ie_exts_present) { @@ -9874,6 +9446,7 @@ SRSASN_CODE xn_ext_tla_item_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(ipsec_tla_present, 1)); + bool gtp_tlas_present; HANDLE_CODE(bref.unpack(gtp_tlas_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -9895,7 +9468,7 @@ void xn_ext_tla_item_s::to_json(json_writer& j) const if (ipsec_tla_present) { j.write_str("iPsecTLA", ipsec_tla.to_string()); } - if (gtp_tlas_present) { + if (gtp_tlas.size() > 0) { j.start_array("gTP-TLAs"); for (const auto& e1 : gtp_tlas) { j.write_str(e1.to_string()); @@ -9913,11 +9486,11 @@ void xn_ext_tla_item_s::to_json(json_writer& j) const SRSASN_CODE xn_tnl_cfg_info_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(xn_extended_transport_layer_addresses_present, 1)); + HANDLE_CODE(bref.pack(xn_extended_transport_layer_addresses.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); HANDLE_CODE(pack_dyn_seq_of(bref, xn_transport_layer_addresses, 1, 16, true)); - if (xn_extended_transport_layer_addresses_present) { + if (xn_extended_transport_layer_addresses.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, xn_extended_transport_layer_addresses, 1, 2, true)); } if (ie_exts_present) { @@ -9929,6 +9502,7 @@ SRSASN_CODE xn_tnl_cfg_info_s::pack(bit_ref& bref) const SRSASN_CODE xn_tnl_cfg_info_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool xn_extended_transport_layer_addresses_present; HANDLE_CODE(bref.unpack(xn_extended_transport_layer_addresses_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -9950,7 +9524,7 @@ void xn_tnl_cfg_info_s::to_json(json_writer& j) const j.write_str(e1.to_string()); } j.end_array(); - if (xn_extended_transport_layer_addresses_present) { + if (xn_extended_transport_layer_addresses.size() > 0) { j.start_array("xnExtendedTransportLayerAddresses"); for (const auto& e1 : xn_extended_transport_layer_addresses) { e1.to_json(j); @@ -10513,7 +10087,7 @@ const char* dl_ran_cfg_transfer_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 2, value, "dl_ran_cfg_transfer_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; dl_ran_cfg_transfer_ies_container::dl_ran_cfg_transfer_ies_container() : son_cfg_transfer_dl(98, crit_e::ignore), endc_son_cfg_transfer_dl(157, crit_e::ignore) @@ -10540,23 +10114,27 @@ SRSASN_CODE dl_ran_cfg_transfer_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 98: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 98: { son_cfg_transfer_dl_present = true; - son_cfg_transfer_dl.id = c.id; - son_cfg_transfer_dl.crit = c.crit; - son_cfg_transfer_dl.value = c.value.son_cfg_transfer_dl(); + son_cfg_transfer_dl.id = id; + HANDLE_CODE(son_cfg_transfer_dl.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(son_cfg_transfer_dl.value.unpack(bref)); break; - case 157: + } + case 157: { endc_son_cfg_transfer_dl_present = true; - endc_son_cfg_transfer_dl.id = c.id; - endc_son_cfg_transfer_dl.crit = c.crit; - endc_son_cfg_transfer_dl.value = c.value.endc_son_cfg_transfer_dl(); + endc_son_cfg_transfer_dl.id = id; + HANDLE_CODE(endc_son_cfg_transfer_dl.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(endc_son_cfg_transfer_dl.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -10577,29 +10155,6 @@ void dl_ran_cfg_transfer_ies_container::to_json(json_writer& j) const j.end_obj(); } -// DownlinkRANConfigurationTransfer ::= SEQUENCE -SRSASN_CODE dl_ran_cfg_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE dl_ran_cfg_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void dl_ran_cfg_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // RANStatusTransfer-TransparentContainer ::= SEQUENCE SRSASN_CODE ran_status_transfer_transparent_container_s::pack(bit_ref& bref) const { @@ -10873,7 +10428,7 @@ const char* dl_ran_status_transfer_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "dl_ran_status_transfer_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; dl_ran_status_transfer_ies_container::dl_ran_status_transfer_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -10899,29 +10454,35 @@ SRSASN_CODE dl_ran_status_transfer_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 84: + } + case 84: { nof_mandatory_ies--; - ran_status_transfer_transparent_container.id = c.id; - ran_status_transfer_transparent_container.crit = c.crit; - ran_status_transfer_transparent_container.value = c.value.ran_status_transfer_transparent_container(); + ran_status_transfer_transparent_container.id = id; + HANDLE_CODE(ran_status_transfer_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_status_transfer_transparent_container.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -10944,29 +10505,6 @@ void dl_ran_status_transfer_ies_container::to_json(json_writer& j) const j.end_obj(); } -// DownlinkRANStatusTransfer ::= SEQUENCE -SRSASN_CODE dl_ran_status_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE dl_ran_status_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void dl_ran_status_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // DownlinkUEAssociatedNRPPaTransportIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES uint32_t dl_ueassociated_nrp_pa_transport_ies_o::idx_to_id(uint32_t idx) { @@ -11235,7 +10773,7 @@ const char* dl_ueassociated_nrp_pa_transport_ies_o::value_c::types_opts::to_stri return convert_enum_idx(options, 4, value, "dl_ueassociated_nrp_pa_transport_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; dl_ueassociated_nrp_pa_transport_ies_container::dl_ueassociated_nrp_pa_transport_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -11263,35 +10801,43 @@ SRSASN_CODE dl_ueassociated_nrp_pa_transport_ies_container::unpack(cbit_ref& bre uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 89: + } + case 89: { nof_mandatory_ies--; - routing_id.id = c.id; - routing_id.crit = c.crit; - routing_id.value = c.value.routing_id(); + routing_id.id = id; + HANDLE_CODE(routing_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(routing_id.value.unpack(bref)); break; - case 46: + } + case 46: { nof_mandatory_ies--; - nrp_pa_pdu.id = c.id; - nrp_pa_pdu.crit = c.crit; - nrp_pa_pdu.value = c.value.nrp_pa_pdu(); + nrp_pa_pdu.id = id; + HANDLE_CODE(nrp_pa_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrp_pa_pdu.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -11316,29 +10862,6 @@ void dl_ueassociated_nrp_pa_transport_ies_container::to_json(json_writer& j) con j.end_obj(); } -// DownlinkUEAssociatedNRPPaTransport ::= SEQUENCE -SRSASN_CODE dl_ueassociated_nrp_pa_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE dl_ueassociated_nrp_pa_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void dl_ueassociated_nrp_pa_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // DelayCritical ::= ENUMERATED const char* delay_crit_opts::to_string() const { @@ -11900,7 +11423,7 @@ const char* error_ind_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 4, value, "error_ind_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; error_ind_ies_container::error_ind_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -11938,35 +11461,43 @@ SRSASN_CODE error_ind_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { amf_ue_ngap_id_present = true; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { ran_ue_ngap_id_present = true; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 15: + } + case 15: { cause_present = true; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -11995,29 +11526,6 @@ void error_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// ErrorIndication ::= SEQUENCE -SRSASN_CODE error_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE error_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void error_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // FiveG-S-TMSI ::= SEQUENCE SRSASN_CODE five_g_s_tmsi_s::pack(bit_ref& bref) const { @@ -12374,7 +11882,7 @@ const char* ho_cancel_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "ho_cancel_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_cancel_ies_container::ho_cancel_ies_container() : amf_ue_ngap_id(10, crit_e::reject), ran_ue_ngap_id(85, crit_e::reject), cause(15, crit_e::ignore) @@ -12398,29 +11906,35 @@ SRSASN_CODE ho_cancel_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -12443,29 +11957,6 @@ void ho_cancel_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverCancel ::= SEQUENCE -SRSASN_CODE ho_cancel_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_cancel_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_cancel_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // HandoverCancelAcknowledgeIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES uint32_t ho_cancel_ack_ies_o::idx_to_id(uint32_t idx) { @@ -12695,7 +12186,7 @@ const char* ho_cancel_ack_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "ho_cancel_ack_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_cancel_ack_ies_container::ho_cancel_ack_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), ran_ue_ngap_id(85, crit_e::ignore), crit_diagnostics(19, crit_e::ignore) @@ -12722,29 +12213,35 @@ SRSASN_CODE ho_cancel_ack_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -12769,29 +12266,6 @@ void ho_cancel_ack_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverCancelAcknowledge ::= SEQUENCE -SRSASN_CODE ho_cancel_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_cancel_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_cancel_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // PDUSessionResourceHandoverItem ::= SEQUENCE SRSASN_CODE pdu_session_res_ho_item_s::pack(bit_ref& bref) const { @@ -13307,7 +12781,7 @@ const char* ho_cmd_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 8, value, "ho_cmd_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_cmd_ies_container::ho_cmd_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -13352,59 +12826,75 @@ SRSASN_CODE ho_cmd_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 5; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 29: + } + case 29: { nof_mandatory_ies--; - handov_type.id = c.id; - handov_type.crit = c.crit; - handov_type.value = c.value.handov_type(); + handov_type.id = id; + HANDLE_CODE(handov_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(handov_type.value.unpack(bref)); break; - case 39: + } + case 39: { nas_security_params_from_ngran_present = true; - nas_security_params_from_ngran.id = c.id; - nas_security_params_from_ngran.crit = c.crit; - nas_security_params_from_ngran.value = c.value.nas_security_params_from_ngran(); + nas_security_params_from_ngran.id = id; + HANDLE_CODE(nas_security_params_from_ngran.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_security_params_from_ngran.value.unpack(bref)); break; - case 59: + } + case 59: { nof_mandatory_ies--; - pdu_session_res_ho_list.id = c.id; - pdu_session_res_ho_list.crit = c.crit; - pdu_session_res_ho_list.value = c.value.pdu_session_res_ho_list(); + pdu_session_res_ho_list.id = id; + HANDLE_CODE(pdu_session_res_ho_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_ho_list.value.unpack(bref)); break; - case 78: + } + case 78: { pdu_session_res_to_release_list_ho_cmd_present = true; - pdu_session_res_to_release_list_ho_cmd.id = c.id; - pdu_session_res_to_release_list_ho_cmd.crit = c.crit; - pdu_session_res_to_release_list_ho_cmd.value = c.value.pdu_session_res_to_release_list_ho_cmd(); + pdu_session_res_to_release_list_ho_cmd.id = id; + HANDLE_CODE(pdu_session_res_to_release_list_ho_cmd.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_to_release_list_ho_cmd.value.unpack(bref)); break; - case 106: + } + case 106: { nof_mandatory_ies--; - target_to_source_transparent_container.id = c.id; - target_to_source_transparent_container.crit = c.crit; - target_to_source_transparent_container.value = c.value.target_to_source_transparent_container(); + target_to_source_transparent_container.id = id; + HANDLE_CODE(target_to_source_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(target_to_source_transparent_container.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -13443,29 +12933,6 @@ void ho_cmd_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverCommand ::= SEQUENCE -SRSASN_CODE ho_cmd_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_cmd_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_cmd_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // QosFlowPerTNLInformation ::= SEQUENCE SRSASN_CODE qos_flow_per_tnl_info_s::pack(bit_ref& bref) const { @@ -13653,20 +13120,20 @@ SRSASN_CODE ho_cmd_transfer_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(dlforwarding_up_tnl_info_present, 1)); - HANDLE_CODE(bref.pack(qos_flow_to_be_forwarded_list_present, 1)); - HANDLE_CODE(bref.pack(data_forwarding_resp_drb_list_present, 1)); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(qos_flow_to_be_forwarded_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(data_forwarding_resp_drb_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); if (dlforwarding_up_tnl_info_present) { HANDLE_CODE(dlforwarding_up_tnl_info.pack(bref)); } - if (qos_flow_to_be_forwarded_list_present) { + if (qos_flow_to_be_forwarded_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_to_be_forwarded_list, 1, 64, true)); } - if (data_forwarding_resp_drb_list_present) { + if (data_forwarding_resp_drb_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, data_forwarding_resp_drb_list, 1, 32, true)); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -13676,8 +13143,11 @@ SRSASN_CODE ho_cmd_transfer_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(dlforwarding_up_tnl_info_present, 1)); + bool qos_flow_to_be_forwarded_list_present; HANDLE_CODE(bref.unpack(qos_flow_to_be_forwarded_list_present, 1)); + bool data_forwarding_resp_drb_list_present; HANDLE_CODE(bref.unpack(data_forwarding_resp_drb_list_present, 1)); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); if (dlforwarding_up_tnl_info_present) { @@ -13702,21 +13172,21 @@ void ho_cmd_transfer_s::to_json(json_writer& j) const j.write_fieldname("dLForwardingUP-TNLInformation"); dlforwarding_up_tnl_info.to_json(j); } - if (qos_flow_to_be_forwarded_list_present) { + if (qos_flow_to_be_forwarded_list.size() > 0) { j.start_array("qosFlowToBeForwardedList"); for (const auto& e1 : qos_flow_to_be_forwarded_list) { e1.to_json(j); } j.end_array(); } - if (data_forwarding_resp_drb_list_present) { + if (data_forwarding_resp_drb_list.size() > 0) { j.start_array("dataForwardingResponseDRBList"); for (const auto& e1 : data_forwarding_resp_drb_list) { e1.to_json(j); } j.end_array(); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -13961,7 +13431,7 @@ uint8_t ho_fail_ies_o::value_c::types_opts::to_number() const return map_enum_number(options, 1, value, "ho_fail_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_fail_ies_container::ho_fail_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), cause(15, crit_e::ignore), crit_diagnostics(19, crit_e::ignore) @@ -13988,29 +13458,35 @@ SRSASN_CODE ho_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -14035,29 +13511,6 @@ void ho_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverFailure ::= SEQUENCE -SRSASN_CODE ho_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // UserLocationInformationEUTRA ::= SEQUENCE SRSASN_CODE user_location_info_eutra_s::pack(bit_ref& bref) const { @@ -14629,7 +14082,7 @@ const char* ho_notify_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "ho_notify_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_notify_ies_container::ho_notify_ies_container() : amf_ue_ngap_id(10, crit_e::reject), ran_ue_ngap_id(85, crit_e::reject), user_location_info(121, crit_e::ignore) @@ -14653,29 +14106,35 @@ SRSASN_CODE ho_notify_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 121: + } + case 121: { nof_mandatory_ies--; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -14698,29 +14157,6 @@ void ho_notify_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverNotify ::= SEQUENCE -SRSASN_CODE ho_notify_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_notify_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_notify_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // HandoverPreparationFailureIEs ::= OBJECT SET OF NGAP-PROTOCOL-IES uint32_t ho_prep_fail_ies_o::idx_to_id(uint32_t idx) { @@ -14990,7 +14426,7 @@ const char* ho_prep_fail_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 4, value, "ho_prep_fail_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_prep_fail_ies_container::ho_prep_fail_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -15021,35 +14457,43 @@ SRSASN_CODE ho_prep_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -15076,29 +14520,6 @@ void ho_prep_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverPreparationFailure ::= SEQUENCE -SRSASN_CODE ho_prep_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_prep_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_prep_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // HandoverPreparationUnsuccessfulTransfer ::= SEQUENCE SRSASN_CODE ho_prep_unsuccessful_transfer_s::pack(bit_ref& bref) const { @@ -15214,13 +14635,13 @@ const char* trace_depth_opts::to_string() const SRSASN_CODE location_report_request_type_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(area_of_interest_list_present, 1)); + HANDLE_CODE(bref.pack(area_of_interest_list.size() > 0, 1)); HANDLE_CODE(bref.pack(location_report_ref_id_to_be_cancelled_present, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); HANDLE_CODE(event_type.pack(bref)); HANDLE_CODE(report_area.pack(bref)); - if (area_of_interest_list_present) { + if (area_of_interest_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, area_of_interest_list, 1, 64, true)); } if (location_report_ref_id_to_be_cancelled_present) { @@ -15235,6 +14656,7 @@ SRSASN_CODE location_report_request_type_s::pack(bit_ref& bref) const SRSASN_CODE location_report_request_type_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool area_of_interest_list_present; HANDLE_CODE(bref.unpack(area_of_interest_list_present, 1)); HANDLE_CODE(bref.unpack(location_report_ref_id_to_be_cancelled_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -15258,7 +14680,7 @@ void location_report_request_type_s::to_json(json_writer& j) const j.start_obj(); j.write_str("eventType", event_type.to_string()); j.write_str("reportArea", "cell"); - if (area_of_interest_list_present) { + if (area_of_interest_list.size() > 0) { j.start_array("areaOfInterestList"); for (const auto& e1 : area_of_interest_list) { e1.to_json(j); @@ -16298,7 +15720,7 @@ uint8_t ho_request_ies_o::value_c::types_opts::to_number() const return 0; } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_request_ies_container::ho_request_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -16383,125 +15805,163 @@ SRSASN_CODE ho_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 10; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 29: + } + case 29: { nof_mandatory_ies--; - handov_type.id = c.id; - handov_type.crit = c.crit; - handov_type.value = c.value.handov_type(); + handov_type.id = id; + HANDLE_CODE(handov_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(handov_type.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 110: + } + case 110: { nof_mandatory_ies--; - ue_aggregate_maximum_bit_rate.id = c.id; - ue_aggregate_maximum_bit_rate.crit = c.crit; - ue_aggregate_maximum_bit_rate.value = c.value.ue_aggregate_maximum_bit_rate(); + ue_aggregate_maximum_bit_rate.id = id; + HANDLE_CODE(ue_aggregate_maximum_bit_rate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_aggregate_maximum_bit_rate.value.unpack(bref)); break; - case 18: + } + case 18: { core_network_assist_info_present = true; - core_network_assist_info.id = c.id; - core_network_assist_info.crit = c.crit; - core_network_assist_info.value = c.value.core_network_assist_info(); + core_network_assist_info.id = id; + HANDLE_CODE(core_network_assist_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(core_network_assist_info.value.unpack(bref)); break; - case 119: + } + case 119: { nof_mandatory_ies--; - ue_security_cap.id = c.id; - ue_security_cap.crit = c.crit; - ue_security_cap.value = c.value.ue_security_cap(); + ue_security_cap.id = id; + HANDLE_CODE(ue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_security_cap.value.unpack(bref)); break; - case 93: + } + case 93: { nof_mandatory_ies--; - security_context.id = c.id; - security_context.crit = c.crit; - security_context.value = c.value.security_context(); + security_context.id = id; + HANDLE_CODE(security_context.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_context.value.unpack(bref)); break; - case 41: + } + case 41: { new_security_context_ind_present = true; - new_security_context_ind.id = c.id; - new_security_context_ind.crit = c.crit; - new_security_context_ind.value = c.value.new_security_context_ind(); + new_security_context_ind.id = id; + HANDLE_CODE(new_security_context_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(new_security_context_ind.value.unpack(bref)); break; - case 37: + } + case 37: { nasc_present = true; - nasc.id = c.id; - nasc.crit = c.crit; - nasc.value = c.value.nasc(); + nasc.id = id; + HANDLE_CODE(nasc.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nasc.value.unpack(bref)); break; - case 73: + } + case 73: { nof_mandatory_ies--; - pdu_session_res_setup_list_ho_req.id = c.id; - pdu_session_res_setup_list_ho_req.crit = c.crit; - pdu_session_res_setup_list_ho_req.value = c.value.pdu_session_res_setup_list_ho_req(); + pdu_session_res_setup_list_ho_req.id = id; + HANDLE_CODE(pdu_session_res_setup_list_ho_req.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_setup_list_ho_req.value.unpack(bref)); break; - case 0: + } + case 0: { nof_mandatory_ies--; - allowed_nssai.id = c.id; - allowed_nssai.crit = c.crit; - allowed_nssai.value = c.value.allowed_nssai(); + allowed_nssai.id = id; + HANDLE_CODE(allowed_nssai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(allowed_nssai.value.unpack(bref)); break; - case 108: + } + case 108: { trace_activation_present = true; - trace_activation.id = c.id; - trace_activation.crit = c.crit; - trace_activation.value = c.value.trace_activation(); + trace_activation.id = id; + HANDLE_CODE(trace_activation.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(trace_activation.value.unpack(bref)); break; - case 34: + } + case 34: { masked_imeisv_present = true; - masked_imeisv.id = c.id; - masked_imeisv.crit = c.crit; - masked_imeisv.value = c.value.masked_imeisv(); + masked_imeisv.id = id; + HANDLE_CODE(masked_imeisv.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(masked_imeisv.value.unpack(bref)); break; - case 101: + } + case 101: { nof_mandatory_ies--; - source_to_target_transparent_container.id = c.id; - source_to_target_transparent_container.crit = c.crit; - source_to_target_transparent_container.value = c.value.source_to_target_transparent_container(); + source_to_target_transparent_container.id = id; + HANDLE_CODE(source_to_target_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(source_to_target_transparent_container.value.unpack(bref)); break; - case 36: + } + case 36: { mob_restrict_list_present = true; - mob_restrict_list.id = c.id; - mob_restrict_list.crit = c.crit; - mob_restrict_list.value = c.value.mob_restrict_list(); + mob_restrict_list.id = id; + HANDLE_CODE(mob_restrict_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mob_restrict_list.value.unpack(bref)); break; - case 33: + } + case 33: { location_report_request_type_present = true; - location_report_request_type.id = c.id; - location_report_request_type.crit = c.crit; - location_report_request_type.value = c.value.location_report_request_type(); + location_report_request_type.id = id; + HANDLE_CODE(location_report_request_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(location_report_request_type.value.unpack(bref)); break; - case 91: + } + case 91: { rrc_inactive_transition_report_request_present = true; - rrc_inactive_transition_report_request.id = c.id; - rrc_inactive_transition_report_request.crit = c.crit; - rrc_inactive_transition_report_request.value = c.value.rrc_inactive_transition_report_request(); + rrc_inactive_transition_report_request.id = id; + HANDLE_CODE(rrc_inactive_transition_report_request.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(rrc_inactive_transition_report_request.value.unpack(bref)); break; - case 28: + } + case 28: { nof_mandatory_ies--; - guami.id = c.id; - guami.crit = c.crit; - guami.value = c.value.guami(); + guami.id = id; + HANDLE_CODE(guami.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(guami.value.unpack(bref)); break; - case 146: + } + case 146: { redirection_voice_fallback_present = true; - redirection_voice_fallback.id = c.id; - redirection_voice_fallback.crit = c.crit; - redirection_voice_fallback.value = c.value.redirection_voice_fallback(); + redirection_voice_fallback.id = id; + HANDLE_CODE(redirection_voice_fallback.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(redirection_voice_fallback.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -16574,29 +16034,6 @@ void ho_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverRequest ::= SEQUENCE -SRSASN_CODE ho_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // PDUSessionResourceAdmittedItem ::= SEQUENCE SRSASN_CODE pdu_session_res_admitted_item_s::pack(bit_ref& bref) const { @@ -17033,7 +16470,7 @@ const char* ho_request_ack_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 6, value, "ho_request_ack_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_request_ack_ies_container::ho_request_ack_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -17071,47 +16508,59 @@ SRSASN_CODE ho_request_ack_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 53: + } + case 53: { nof_mandatory_ies--; - pdu_session_res_admitted_list.id = c.id; - pdu_session_res_admitted_list.crit = c.crit; - pdu_session_res_admitted_list.value = c.value.pdu_session_res_admitted_list(); + pdu_session_res_admitted_list.id = id; + HANDLE_CODE(pdu_session_res_admitted_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_admitted_list.value.unpack(bref)); break; - case 56: + } + case 56: { pdu_session_res_failed_to_setup_list_ho_ack_present = true; - pdu_session_res_failed_to_setup_list_ho_ack.id = c.id; - pdu_session_res_failed_to_setup_list_ho_ack.crit = c.crit; - pdu_session_res_failed_to_setup_list_ho_ack.value = c.value.pdu_session_res_failed_to_setup_list_ho_ack(); + pdu_session_res_failed_to_setup_list_ho_ack.id = id; + HANDLE_CODE(pdu_session_res_failed_to_setup_list_ho_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_failed_to_setup_list_ho_ack.value.unpack(bref)); break; - case 106: + } + case 106: { nof_mandatory_ies--; - target_to_source_transparent_container.id = c.id; - target_to_source_transparent_container.crit = c.crit; - target_to_source_transparent_container.value = c.value.target_to_source_transparent_container(); + target_to_source_transparent_container.id = id; + HANDLE_CODE(target_to_source_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(target_to_source_transparent_container.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -17144,29 +16593,6 @@ void ho_request_ack_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverRequestAcknowledge ::= SEQUENCE -SRSASN_CODE ho_request_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_request_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_request_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // ConfidentialityProtectionResult ::= ENUMERATED const char* confidentiality_protection_result_opts::to_string() const { @@ -17331,9 +16757,9 @@ SRSASN_CODE ho_request_ack_transfer_s::pack(bit_ref& bref) const bref.pack(ext, 1); HANDLE_CODE(bref.pack(dlforwarding_up_tnl_info_present, 1)); HANDLE_CODE(bref.pack(security_result_present, 1)); - HANDLE_CODE(bref.pack(qos_flow_failed_to_setup_list_present, 1)); - HANDLE_CODE(bref.pack(data_forwarding_resp_drb_list_present, 1)); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(qos_flow_failed_to_setup_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(data_forwarding_resp_drb_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); HANDLE_CODE(dl_ngu_up_tnl_info.pack(bref)); if (dlforwarding_up_tnl_info_present) { @@ -17343,13 +16769,13 @@ SRSASN_CODE ho_request_ack_transfer_s::pack(bit_ref& bref) const HANDLE_CODE(security_result.pack(bref)); } HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_setup_resp_list, 1, 64, true)); - if (qos_flow_failed_to_setup_list_present) { + if (qos_flow_failed_to_setup_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_failed_to_setup_list, 1, 64, true)); } - if (data_forwarding_resp_drb_list_present) { + if (data_forwarding_resp_drb_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, data_forwarding_resp_drb_list, 1, 32, true)); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -17360,8 +16786,11 @@ SRSASN_CODE ho_request_ack_transfer_s::unpack(cbit_ref& bref) bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(dlforwarding_up_tnl_info_present, 1)); HANDLE_CODE(bref.unpack(security_result_present, 1)); + bool qos_flow_failed_to_setup_list_present; HANDLE_CODE(bref.unpack(qos_flow_failed_to_setup_list_present, 1)); + bool data_forwarding_resp_drb_list_present; HANDLE_CODE(bref.unpack(data_forwarding_resp_drb_list_present, 1)); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); HANDLE_CODE(dl_ngu_up_tnl_info.unpack(bref)); @@ -17402,21 +16831,21 @@ void ho_request_ack_transfer_s::to_json(json_writer& j) const e1.to_json(j); } j.end_array(); - if (qos_flow_failed_to_setup_list_present) { + if (qos_flow_failed_to_setup_list.size() > 0) { j.start_array("qosFlowFailedToSetupList"); for (const auto& e1 : qos_flow_failed_to_setup_list) { e1.to_json(j); } j.end_array(); } - if (data_forwarding_resp_drb_list_present) { + if (data_forwarding_resp_drb_list.size() > 0) { j.start_array("dataForwardingResponseDRBList"); for (const auto& e1 : data_forwarding_resp_drb_list) { e1.to_json(j); } j.end_array(); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -18095,7 +17524,7 @@ const char* ho_required_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 8, value, "ho_required_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_required_ies_container::ho_required_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -18134,59 +17563,75 @@ SRSASN_CODE ho_required_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 7; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 29: + } + case 29: { nof_mandatory_ies--; - handov_type.id = c.id; - handov_type.crit = c.crit; - handov_type.value = c.value.handov_type(); + handov_type.id = id; + HANDLE_CODE(handov_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(handov_type.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 105: + } + case 105: { nof_mandatory_ies--; - target_id.id = c.id; - target_id.crit = c.crit; - target_id.value = c.value.target_id(); + target_id.id = id; + HANDLE_CODE(target_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(target_id.value.unpack(bref)); break; - case 22: + } + case 22: { direct_forwarding_path_availability_present = true; - direct_forwarding_path_availability.id = c.id; - direct_forwarding_path_availability.crit = c.crit; - direct_forwarding_path_availability.value = c.value.direct_forwarding_path_availability(); + direct_forwarding_path_availability.id = id; + HANDLE_CODE(direct_forwarding_path_availability.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(direct_forwarding_path_availability.value.unpack(bref)); break; - case 61: + } + case 61: { nof_mandatory_ies--; - pdu_session_res_list_ho_rqd.id = c.id; - pdu_session_res_list_ho_rqd.crit = c.crit; - pdu_session_res_list_ho_rqd.value = c.value.pdu_session_res_list_ho_rqd(); + pdu_session_res_list_ho_rqd.id = id; + HANDLE_CODE(pdu_session_res_list_ho_rqd.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_list_ho_rqd.value.unpack(bref)); break; - case 101: + } + case 101: { nof_mandatory_ies--; - source_to_target_transparent_container.id = c.id; - source_to_target_transparent_container.crit = c.crit; - source_to_target_transparent_container.value = c.value.source_to_target_transparent_container(); + source_to_target_transparent_container.id = id; + HANDLE_CODE(source_to_target_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(source_to_target_transparent_container.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -18221,29 +17666,6 @@ void ho_required_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverRequired ::= SEQUENCE -SRSASN_CODE ho_required_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_required_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_required_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // HandoverRequiredTransfer ::= SEQUENCE SRSASN_CODE ho_required_transfer_s::pack(bit_ref& bref) const { @@ -18811,7 +18233,7 @@ const char* init_context_setup_fail_ies_o::value_c::types_opts::to_string() cons return convert_enum_idx(options, 5, value, "init_context_setup_fail_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; init_context_setup_fail_ies_container::init_context_setup_fail_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -18847,41 +18269,51 @@ SRSASN_CODE init_context_setup_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 132: + } + case 132: { pdu_session_res_failed_to_setup_list_cxt_fail_present = true; - pdu_session_res_failed_to_setup_list_cxt_fail.id = c.id; - pdu_session_res_failed_to_setup_list_cxt_fail.crit = c.crit; - pdu_session_res_failed_to_setup_list_cxt_fail.value = c.value.pdu_session_res_failed_to_setup_list_cxt_fail(); + pdu_session_res_failed_to_setup_list_cxt_fail.id = id; + HANDLE_CODE(pdu_session_res_failed_to_setup_list_cxt_fail.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_failed_to_setup_list_cxt_fail.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -18912,38 +18344,15 @@ void init_context_setup_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// InitialContextSetupFailure ::= SEQUENCE -SRSASN_CODE init_context_setup_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE init_context_setup_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void init_context_setup_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // PDUSessionResourceSetupItemCxtReq ::= SEQUENCE SRSASN_CODE pdu_session_res_setup_item_cxt_req_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(nas_pdu_present, 1)); + HANDLE_CODE(bref.pack(nas_pdu.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); HANDLE_CODE(pack_integer(bref, pdu_session_id, (uint16_t)0u, (uint16_t)255u, false, true)); - if (nas_pdu_present) { + if (nas_pdu.size() > 0) { HANDLE_CODE(nas_pdu.pack(bref)); } HANDLE_CODE(s_nssai.pack(bref)); @@ -18957,6 +18366,7 @@ SRSASN_CODE pdu_session_res_setup_item_cxt_req_s::pack(bit_ref& bref) const SRSASN_CODE pdu_session_res_setup_item_cxt_req_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool nas_pdu_present; HANDLE_CODE(bref.unpack(nas_pdu_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -18976,7 +18386,7 @@ void pdu_session_res_setup_item_cxt_req_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("pDUSessionID", pdu_session_id); - if (nas_pdu_present) { + if (nas_pdu.size() > 0) { j.write_str("nAS-PDU", nas_pdu.to_string()); } j.write_fieldname("s-NSSAI"); @@ -18993,14 +18403,14 @@ void pdu_session_res_setup_item_cxt_req_s::to_json(json_writer& j) const SRSASN_CODE ue_radio_cap_for_paging_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(ueradio_cap_for_paging_of_nr_present, 1)); - HANDLE_CODE(bref.pack(ueradio_cap_for_paging_of_eutra_present, 1)); + HANDLE_CODE(bref.pack(ueradio_cap_for_paging_of_nr.size() > 0, 1)); + HANDLE_CODE(bref.pack(ueradio_cap_for_paging_of_eutra.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); - if (ueradio_cap_for_paging_of_nr_present) { + if (ueradio_cap_for_paging_of_nr.size() > 0) { HANDLE_CODE(ueradio_cap_for_paging_of_nr.pack(bref)); } - if (ueradio_cap_for_paging_of_eutra_present) { + if (ueradio_cap_for_paging_of_eutra.size() > 0) { HANDLE_CODE(ueradio_cap_for_paging_of_eutra.pack(bref)); } if (ie_exts_present) { @@ -19012,7 +18422,9 @@ SRSASN_CODE ue_radio_cap_for_paging_s::pack(bit_ref& bref) const SRSASN_CODE ue_radio_cap_for_paging_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool ueradio_cap_for_paging_of_nr_present; HANDLE_CODE(bref.unpack(ueradio_cap_for_paging_of_nr_present, 1)); + bool ueradio_cap_for_paging_of_eutra_present; HANDLE_CODE(bref.unpack(ueradio_cap_for_paging_of_eutra_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -19031,10 +18443,10 @@ SRSASN_CODE ue_radio_cap_for_paging_s::unpack(cbit_ref& bref) void ue_radio_cap_for_paging_s::to_json(json_writer& j) const { j.start_obj(); - if (ueradio_cap_for_paging_of_nr_present) { + if (ueradio_cap_for_paging_of_nr.size() > 0) { j.write_str("uERadioCapabilityForPagingOfNR", ueradio_cap_for_paging_of_nr.to_string()); } - if (ueradio_cap_for_paging_of_eutra_present) { + if (ueradio_cap_for_paging_of_eutra.size() > 0) { j.write_str("uERadioCapabilityForPagingOfEUTRA", ueradio_cap_for_paging_of_eutra.to_string()); } if (ie_exts_present) { @@ -19947,7 +19359,7 @@ const char* init_context_setup_request_ies_o::value_c::types_opts::to_string() c return convert_enum_idx(options, 20, value, "init_context_setup_request_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; init_context_setup_request_ies_container::init_context_setup_request_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -20049,131 +19461,171 @@ SRSASN_CODE init_context_setup_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 6; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 48: + } + case 48: { old_amf_present = true; - old_amf.id = c.id; - old_amf.crit = c.crit; - old_amf.value = c.value.old_amf(); + old_amf.id = id; + HANDLE_CODE(old_amf.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(old_amf.value.unpack(bref)); break; - case 110: + } + case 110: { ue_aggregate_maximum_bit_rate_present = true; - ue_aggregate_maximum_bit_rate.id = c.id; - ue_aggregate_maximum_bit_rate.crit = c.crit; - ue_aggregate_maximum_bit_rate.value = c.value.ue_aggregate_maximum_bit_rate(); + ue_aggregate_maximum_bit_rate.id = id; + HANDLE_CODE(ue_aggregate_maximum_bit_rate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_aggregate_maximum_bit_rate.value.unpack(bref)); break; - case 18: + } + case 18: { core_network_assist_info_present = true; - core_network_assist_info.id = c.id; - core_network_assist_info.crit = c.crit; - core_network_assist_info.value = c.value.core_network_assist_info(); + core_network_assist_info.id = id; + HANDLE_CODE(core_network_assist_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(core_network_assist_info.value.unpack(bref)); break; - case 28: + } + case 28: { nof_mandatory_ies--; - guami.id = c.id; - guami.crit = c.crit; - guami.value = c.value.guami(); + guami.id = id; + HANDLE_CODE(guami.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(guami.value.unpack(bref)); break; - case 71: + } + case 71: { pdu_session_res_setup_list_cxt_req_present = true; - pdu_session_res_setup_list_cxt_req.id = c.id; - pdu_session_res_setup_list_cxt_req.crit = c.crit; - pdu_session_res_setup_list_cxt_req.value = c.value.pdu_session_res_setup_list_cxt_req(); + pdu_session_res_setup_list_cxt_req.id = id; + HANDLE_CODE(pdu_session_res_setup_list_cxt_req.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_setup_list_cxt_req.value.unpack(bref)); break; - case 0: + } + case 0: { nof_mandatory_ies--; - allowed_nssai.id = c.id; - allowed_nssai.crit = c.crit; - allowed_nssai.value = c.value.allowed_nssai(); + allowed_nssai.id = id; + HANDLE_CODE(allowed_nssai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(allowed_nssai.value.unpack(bref)); break; - case 119: + } + case 119: { nof_mandatory_ies--; - ue_security_cap.id = c.id; - ue_security_cap.crit = c.crit; - ue_security_cap.value = c.value.ue_security_cap(); + ue_security_cap.id = id; + HANDLE_CODE(ue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_security_cap.value.unpack(bref)); break; - case 94: + } + case 94: { nof_mandatory_ies--; - security_key.id = c.id; - security_key.crit = c.crit; - security_key.value = c.value.security_key(); + security_key.id = id; + HANDLE_CODE(security_key.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_key.value.unpack(bref)); break; - case 108: + } + case 108: { trace_activation_present = true; - trace_activation.id = c.id; - trace_activation.crit = c.crit; - trace_activation.value = c.value.trace_activation(); + trace_activation.id = id; + HANDLE_CODE(trace_activation.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(trace_activation.value.unpack(bref)); break; - case 36: + } + case 36: { mob_restrict_list_present = true; - mob_restrict_list.id = c.id; - mob_restrict_list.crit = c.crit; - mob_restrict_list.value = c.value.mob_restrict_list(); + mob_restrict_list.id = id; + HANDLE_CODE(mob_restrict_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mob_restrict_list.value.unpack(bref)); break; - case 117: + } + case 117: { ue_radio_cap_present = true; - ue_radio_cap.id = c.id; - ue_radio_cap.crit = c.crit; - ue_radio_cap.value = c.value.ue_radio_cap(); + ue_radio_cap.id = id; + HANDLE_CODE(ue_radio_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap.value.unpack(bref)); break; - case 31: + } + case 31: { idx_to_rfsp_present = true; - idx_to_rfsp.id = c.id; - idx_to_rfsp.crit = c.crit; - idx_to_rfsp.value = c.value.idx_to_rfsp(); + idx_to_rfsp.id = id; + HANDLE_CODE(idx_to_rfsp.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(idx_to_rfsp.value.unpack(bref)); break; - case 34: + } + case 34: { masked_imeisv_present = true; - masked_imeisv.id = c.id; - masked_imeisv.crit = c.crit; - masked_imeisv.value = c.value.masked_imeisv(); + masked_imeisv.id = id; + HANDLE_CODE(masked_imeisv.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(masked_imeisv.value.unpack(bref)); break; - case 38: + } + case 38: { nas_pdu_present = true; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; - case 24: + } + case 24: { emergency_fallback_ind_present = true; - emergency_fallback_ind.id = c.id; - emergency_fallback_ind.crit = c.crit; - emergency_fallback_ind.value = c.value.emergency_fallback_ind(); + emergency_fallback_ind.id = id; + HANDLE_CODE(emergency_fallback_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(emergency_fallback_ind.value.unpack(bref)); break; - case 91: + } + case 91: { rrc_inactive_transition_report_request_present = true; - rrc_inactive_transition_report_request.id = c.id; - rrc_inactive_transition_report_request.crit = c.crit; - rrc_inactive_transition_report_request.value = c.value.rrc_inactive_transition_report_request(); + rrc_inactive_transition_report_request.id = id; + HANDLE_CODE(rrc_inactive_transition_report_request.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(rrc_inactive_transition_report_request.value.unpack(bref)); break; - case 118: + } + case 118: { ue_radio_cap_for_paging_present = true; - ue_radio_cap_for_paging.id = c.id; - ue_radio_cap_for_paging.crit = c.crit; - ue_radio_cap_for_paging.value = c.value.ue_radio_cap_for_paging(); + ue_radio_cap_for_paging.id = id; + HANDLE_CODE(ue_radio_cap_for_paging.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap_for_paging.value.unpack(bref)); break; - case 146: + } + case 146: { redirection_voice_fallback_present = true; - redirection_voice_fallback.id = c.id; - redirection_voice_fallback.crit = c.crit; - redirection_voice_fallback.value = c.value.redirection_voice_fallback(); + redirection_voice_fallback.id = id; + HANDLE_CODE(redirection_voice_fallback.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(redirection_voice_fallback.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -20258,29 +19710,6 @@ void init_context_setup_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// InitialContextSetupRequest ::= SEQUENCE -SRSASN_CODE init_context_setup_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE init_context_setup_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void init_context_setup_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // PDUSessionResourceFailedToSetupItemCxtRes ::= SEQUENCE SRSASN_CODE pdu_session_res_failed_to_setup_item_cxt_res_s::pack(bit_ref& bref) const { @@ -20680,7 +20109,7 @@ const char* init_context_setup_resp_ies_o::value_c::types_opts::to_string() cons return convert_enum_idx(options, 5, value, "init_context_setup_resp_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; init_context_setup_resp_ies_container::init_context_setup_resp_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -20719,41 +20148,51 @@ SRSASN_CODE init_context_setup_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 72: + } + case 72: { pdu_session_res_setup_list_cxt_res_present = true; - pdu_session_res_setup_list_cxt_res.id = c.id; - pdu_session_res_setup_list_cxt_res.crit = c.crit; - pdu_session_res_setup_list_cxt_res.value = c.value.pdu_session_res_setup_list_cxt_res(); + pdu_session_res_setup_list_cxt_res.id = id; + HANDLE_CODE(pdu_session_res_setup_list_cxt_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_setup_list_cxt_res.value.unpack(bref)); break; - case 55: + } + case 55: { pdu_session_res_failed_to_setup_list_cxt_res_present = true; - pdu_session_res_failed_to_setup_list_cxt_res.id = c.id; - pdu_session_res_failed_to_setup_list_cxt_res.crit = c.crit; - pdu_session_res_failed_to_setup_list_cxt_res.value = c.value.pdu_session_res_failed_to_setup_list_cxt_res(); + pdu_session_res_failed_to_setup_list_cxt_res.id = id; + HANDLE_CODE(pdu_session_res_failed_to_setup_list_cxt_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_failed_to_setup_list_cxt_res.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -20786,29 +20225,6 @@ void init_context_setup_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// InitialContextSetupResponse ::= SEQUENCE -SRSASN_CODE init_context_setup_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE init_context_setup_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void init_context_setup_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // RRCEstablishmentCause ::= ENUMERATED const char* rrcestablishment_cause_opts::to_string() const { @@ -21265,7 +20681,7 @@ uint8_t init_ue_msg_ies_o::value_c::types_opts::to_number() const return map_enum_number(options, 1, value, "init_ue_msg_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; init_ue_msg_ies_container::init_ue_msg_ies_container() : ran_ue_ngap_id(85, crit_e::reject), @@ -21313,59 +20729,75 @@ SRSASN_CODE init_ue_msg_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 85: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 38: + } + case 38: { nof_mandatory_ies--; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; - case 121: + } + case 121: { nof_mandatory_ies--; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 90: + } + case 90: { nof_mandatory_ies--; - rrcestablishment_cause.id = c.id; - rrcestablishment_cause.crit = c.crit; - rrcestablishment_cause.value = c.value.rrcestablishment_cause(); + rrcestablishment_cause.id = id; + HANDLE_CODE(rrcestablishment_cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(rrcestablishment_cause.value.unpack(bref)); break; - case 26: + } + case 26: { five_g_s_tmsi_present = true; - five_g_s_tmsi.id = c.id; - five_g_s_tmsi.crit = c.crit; - five_g_s_tmsi.value = c.value.five_g_s_tmsi(); + five_g_s_tmsi.id = id; + HANDLE_CODE(five_g_s_tmsi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(five_g_s_tmsi.value.unpack(bref)); break; - case 3: + } + case 3: { amf_set_id_present = true; - amf_set_id.id = c.id; - amf_set_id.crit = c.crit; - amf_set_id.value = c.value.amf_set_id(); + amf_set_id.id = id; + HANDLE_CODE(amf_set_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_set_id.value.unpack(bref)); break; - case 112: + } + case 112: { ue_context_request_present = true; - ue_context_request.id = c.id; - ue_context_request.crit = c.crit; - ue_context_request.value = c.value.ue_context_request(); + ue_context_request.id = id; + HANDLE_CODE(ue_context_request.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_context_request.value.unpack(bref)); break; - case 0: + } + case 0: { allowed_nssai_present = true; - allowed_nssai.id = c.id; - allowed_nssai.crit = c.crit; - allowed_nssai.value = c.value.allowed_nssai(); + allowed_nssai.id = id; + HANDLE_CODE(allowed_nssai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(allowed_nssai.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -21406,37 +20838,6 @@ void init_ue_msg_ies_container::to_json(json_writer& j) const j.end_obj(); } -// InitialUEMessage ::= SEQUENCE -SRSASN_CODE init_ue_msg_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - bref.align_bytes_zero(); - - return SRSASN_SUCCESS; -} -SRSASN_CODE init_ue_msg_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - bref.align_bytes(); - - return SRSASN_SUCCESS; -} -void init_ue_msg_s::to_json(json_writer& j) const -{ - j.start_array(); - j.start_obj(); - j.start_obj("InitialUEMessage"); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); - j.end_obj(); - j.end_array(); -} - // OverloadAction ::= ENUMERATED const char* overload_action_opts::to_string() const { @@ -22093,10 +21494,10 @@ void pdu_session_res_failed_to_setup_item_su_res_s::to_json(json_writer& j) cons SRSASN_CODE pdu_session_res_item_cxt_rel_cpl_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, pdu_session_id, (uint16_t)0u, (uint16_t)255u, false, true)); - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -22105,6 +21506,7 @@ SRSASN_CODE pdu_session_res_item_cxt_rel_cpl_s::pack(bit_ref& bref) const SRSASN_CODE pdu_session_res_item_cxt_rel_cpl_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); HANDLE_CODE(unpack_integer(pdu_session_id, bref, (uint16_t)0u, (uint16_t)255u, false, true)); @@ -22118,7 +21520,7 @@ void pdu_session_res_item_cxt_rel_cpl_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("pDUSessionID", pdu_session_id); - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -22242,15 +21644,15 @@ void pdu_session_res_modify_item_mod_ind_s::to_json(json_writer& j) const SRSASN_CODE pdu_session_res_modify_item_mod_req_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(nas_pdu_present, 1)); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(nas_pdu.size() > 0, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, pdu_session_id, (uint16_t)0u, (uint16_t)255u, false, true)); - if (nas_pdu_present) { + if (nas_pdu.size() > 0) { HANDLE_CODE(nas_pdu.pack(bref)); } HANDLE_CODE(pdu_session_res_modify_request_transfer.pack(bref)); - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -22259,7 +21661,9 @@ SRSASN_CODE pdu_session_res_modify_item_mod_req_s::pack(bit_ref& bref) const SRSASN_CODE pdu_session_res_modify_item_mod_req_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool nas_pdu_present; HANDLE_CODE(bref.unpack(nas_pdu_present, 1)); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); HANDLE_CODE(unpack_integer(pdu_session_id, bref, (uint16_t)0u, (uint16_t)255u, false, true)); @@ -22277,11 +21681,11 @@ void pdu_session_res_modify_item_mod_req_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("pDUSessionID", pdu_session_id); - if (nas_pdu_present) { + if (nas_pdu.size() > 0) { j.write_str("nAS-PDU", nas_pdu.to_string()); } j.write_str("pDUSessionResourceModifyRequestTransfer", pdu_session_res_modify_request_transfer.to_string()); - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -22564,11 +21968,11 @@ void pdu_session_res_secondary_ratusage_item_s::to_json(json_writer& j) const SRSASN_CODE pdu_session_res_setup_item_su_req_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(pdu_session_nas_pdu_present, 1)); + HANDLE_CODE(bref.pack(pdu_session_nas_pdu.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); HANDLE_CODE(pack_integer(bref, pdu_session_id, (uint16_t)0u, (uint16_t)255u, false, true)); - if (pdu_session_nas_pdu_present) { + if (pdu_session_nas_pdu.size() > 0) { HANDLE_CODE(pdu_session_nas_pdu.pack(bref)); } HANDLE_CODE(s_nssai.pack(bref)); @@ -22582,6 +21986,7 @@ SRSASN_CODE pdu_session_res_setup_item_su_req_s::pack(bit_ref& bref) const SRSASN_CODE pdu_session_res_setup_item_su_req_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool pdu_session_nas_pdu_present; HANDLE_CODE(bref.unpack(pdu_session_nas_pdu_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -22601,7 +22006,7 @@ void pdu_session_res_setup_item_su_req_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("pDUSessionID", pdu_session_id); - if (pdu_session_nas_pdu_present) { + if (pdu_session_nas_pdu.size() > 0) { j.write_str("pDUSessionNAS-PDU", pdu_session_nas_pdu.to_string()); } j.write_fieldname("s-NSSAI"); @@ -38799,7 +38204,7 @@ const char* write_replace_warning_resp_ies_o::value_c::types_opts::to_string() c return convert_enum_idx(options, 4, value, "write_replace_warning_resp_ies_o::value_c::types"); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; location_report_ies_container::location_report_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -38837,47 +38242,59 @@ SRSASN_CODE location_report_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 121: + } + case 121: { nof_mandatory_ies--; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 116: + } + case 116: { ue_presence_in_area_of_interest_list_present = true; - ue_presence_in_area_of_interest_list.id = c.id; - ue_presence_in_area_of_interest_list.crit = c.crit; - ue_presence_in_area_of_interest_list.value = c.value.ue_presence_in_area_of_interest_list(); + ue_presence_in_area_of_interest_list.id = id; + HANDLE_CODE(ue_presence_in_area_of_interest_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_presence_in_area_of_interest_list.value.unpack(bref)); break; - case 33: + } + case 33: { nof_mandatory_ies--; - location_report_request_type.id = c.id; - location_report_request_type.crit = c.crit; - location_report_request_type.value = c.value.location_report_request_type(); + location_report_request_type.id = id; + HANDLE_CODE(location_report_request_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(location_report_request_type.value.unpack(bref)); break; - case 149: + } + case 149: { ps_cell_info_present = true; - ps_cell_info.id = c.id; - ps_cell_info.crit = c.crit; - ps_cell_info.value = c.value.ps_cell_info(); + ps_cell_info.id = id; + HANDLE_CODE(ps_cell_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ps_cell_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -38910,30 +38327,7 @@ void location_report_ies_container::to_json(json_writer& j) const j.end_obj(); } -// LocationReport ::= SEQUENCE -SRSASN_CODE location_report_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE location_report_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void location_report_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; location_report_ctrl_ies_container::location_report_ctrl_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -38959,29 +38353,35 @@ SRSASN_CODE location_report_ctrl_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 33: + } + case 33: { nof_mandatory_ies--; - location_report_request_type.id = c.id; - location_report_request_type.crit = c.crit; - location_report_request_type.value = c.value.location_report_request_type(); + location_report_request_type.id = id; + HANDLE_CODE(location_report_request_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(location_report_request_type.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -39004,30 +38404,7 @@ void location_report_ctrl_ies_container::to_json(json_writer& j) const j.end_obj(); } -// LocationReportingControl ::= SEQUENCE -SRSASN_CODE location_report_ctrl_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE location_report_ctrl_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void location_report_ctrl_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; location_report_fail_ind_ies_container::location_report_fail_ind_ies_container() : amf_ue_ngap_id(10, crit_e::reject), ran_ue_ngap_id(85, crit_e::reject), cause(15, crit_e::ignore) @@ -39051,29 +38428,35 @@ SRSASN_CODE location_report_fail_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -39096,30 +38479,7 @@ void location_report_fail_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// LocationReportingFailureIndication ::= SEQUENCE -SRSASN_CODE location_report_fail_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE location_report_fail_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void location_report_fail_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; nas_non_delivery_ind_ies_container::nas_non_delivery_ind_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -39147,35 +38507,43 @@ SRSASN_CODE nas_non_delivery_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 38: + } + case 38: { nof_mandatory_ies--; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -39200,30 +38568,7 @@ void nas_non_delivery_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// NASNonDeliveryIndication ::= SEQUENCE -SRSASN_CODE nas_non_delivery_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE nas_non_delivery_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void nas_non_delivery_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ng_reset_ies_container::ng_reset_ies_container() : cause(15, crit_e::ignore), reset_type(88, crit_e::reject) {} SRSASN_CODE ng_reset_ies_container::pack(bit_ref& bref) const @@ -39244,23 +38589,27 @@ SRSASN_CODE ng_reset_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 15: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 88: + } + case 88: { nof_mandatory_ies--; - reset_type.id = c.id; - reset_type.crit = c.crit; - reset_type.value = c.value.reset_type(); + reset_type.id = id; + HANDLE_CODE(reset_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(reset_type.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -39281,30 +38630,7 @@ void ng_reset_ies_container::to_json(json_writer& j) const j.end_obj(); } -// NGReset ::= SEQUENCE -SRSASN_CODE ng_reset_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ng_reset_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ng_reset_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ng_reset_ack_ies_container::ng_reset_ack_ies_container() : ue_associated_lc_ng_conn_list(111, crit_e::ignore), crit_diagnostics(19, crit_e::ignore) @@ -39331,23 +38657,27 @@ SRSASN_CODE ng_reset_ack_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 111: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 111: { ue_associated_lc_ng_conn_list_present = true; - ue_associated_lc_ng_conn_list.id = c.id; - ue_associated_lc_ng_conn_list.crit = c.crit; - ue_associated_lc_ng_conn_list.value = c.value.ue_associated_lc_ng_conn_list(); + ue_associated_lc_ng_conn_list.id = id; + HANDLE_CODE(ue_associated_lc_ng_conn_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_associated_lc_ng_conn_list.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -39368,30 +38698,7 @@ void ng_reset_ack_ies_container::to_json(json_writer& j) const j.end_obj(); } -// NGResetAcknowledge ::= SEQUENCE -SRSASN_CODE ng_reset_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ng_reset_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ng_reset_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ng_setup_fail_ies_container::ng_setup_fail_ies_container() : cause(15, crit_e::ignore), time_to_wait(107, crit_e::ignore), crit_diagnostics(19, crit_e::ignore) @@ -39421,29 +38728,35 @@ SRSASN_CODE ng_setup_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 1; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 15: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 107: + } + case 107: { time_to_wait_present = true; - time_to_wait.id = c.id; - time_to_wait.crit = c.crit; - time_to_wait.value = c.value.time_to_wait(); + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -39470,30 +38783,7 @@ void ng_setup_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// NGSetupFailure ::= SEQUENCE -SRSASN_CODE ng_setup_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ng_setup_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ng_setup_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ng_setup_request_ies_container::ng_setup_request_ies_container() : global_ran_node_id(27, crit_e::reject), @@ -39529,41 +38819,51 @@ SRSASN_CODE ng_setup_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 27: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 27: { nof_mandatory_ies--; - global_ran_node_id.id = c.id; - global_ran_node_id.crit = c.crit; - global_ran_node_id.value = c.value.global_ran_node_id(); + global_ran_node_id.id = id; + HANDLE_CODE(global_ran_node_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_ran_node_id.value.unpack(bref)); break; - case 82: + } + case 82: { ran_node_name_present = true; - ran_node_name.id = c.id; - ran_node_name.crit = c.crit; - ran_node_name.value = c.value.ran_node_name(); + ran_node_name.id = id; + HANDLE_CODE(ran_node_name.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_node_name.value.unpack(bref)); break; - case 102: + } + case 102: { nof_mandatory_ies--; - supported_ta_list.id = c.id; - supported_ta_list.crit = c.crit; - supported_ta_list.value = c.value.supported_ta_list(); + supported_ta_list.id = id; + HANDLE_CODE(supported_ta_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(supported_ta_list.value.unpack(bref)); break; - case 21: + } + case 21: { nof_mandatory_ies--; - default_paging_drx.id = c.id; - default_paging_drx.crit = c.crit; - default_paging_drx.value = c.value.default_paging_drx(); + default_paging_drx.id = id; + HANDLE_CODE(default_paging_drx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(default_paging_drx.value.unpack(bref)); break; - case 147: + } + case 147: { ue_retention_info_present = true; - ue_retention_info.id = c.id; - ue_retention_info.crit = c.crit; - ue_retention_info.value = c.value.ue_retention_info(); + ue_retention_info.id = id; + HANDLE_CODE(ue_retention_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_retention_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -39594,30 +38894,7 @@ void ng_setup_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// NGSetupRequest ::= SEQUENCE -SRSASN_CODE ng_setup_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ng_setup_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ng_setup_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ng_setup_resp_ies_container::ng_setup_resp_ies_container() : amf_name(1, crit_e::reject), @@ -39655,47 +38932,59 @@ SRSASN_CODE ng_setup_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 1: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 1: { nof_mandatory_ies--; - amf_name.id = c.id; - amf_name.crit = c.crit; - amf_name.value = c.value.amf_name(); + amf_name.id = id; + HANDLE_CODE(amf_name.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_name.value.unpack(bref)); break; - case 96: + } + case 96: { nof_mandatory_ies--; - served_guami_list.id = c.id; - served_guami_list.crit = c.crit; - served_guami_list.value = c.value.served_guami_list(); + served_guami_list.id = id; + HANDLE_CODE(served_guami_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(served_guami_list.value.unpack(bref)); break; - case 86: + } + case 86: { nof_mandatory_ies--; - relative_amf_capacity.id = c.id; - relative_amf_capacity.crit = c.crit; - relative_amf_capacity.value = c.value.relative_amf_capacity(); + relative_amf_capacity.id = id; + HANDLE_CODE(relative_amf_capacity.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(relative_amf_capacity.value.unpack(bref)); break; - case 80: + } + case 80: { nof_mandatory_ies--; - plmn_support_list.id = c.id; - plmn_support_list.crit = c.crit; - plmn_support_list.value = c.value.plmn_support_list(); + plmn_support_list.id = id; + HANDLE_CODE(plmn_support_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(plmn_support_list.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 147: + } + case 147: { ue_retention_info_present = true; - ue_retention_info.id = c.id; - ue_retention_info.crit = c.crit; - ue_retention_info.value = c.value.ue_retention_info(); + ue_retention_info.id = id; + HANDLE_CODE(ue_retention_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_retention_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -39728,30 +39017,7 @@ void ng_setup_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// NGSetupResponse ::= SEQUENCE -SRSASN_CODE ng_setup_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ng_setup_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ng_setup_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; overload_start_ies_container::overload_start_ies_container() : amf_overload_resp(2, crit_e::reject), @@ -39784,29 +39050,35 @@ SRSASN_CODE overload_start_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 2: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 2: { amf_overload_resp_present = true; - amf_overload_resp.id = c.id; - amf_overload_resp.crit = c.crit; - amf_overload_resp.value = c.value.amf_overload_resp(); + amf_overload_resp.id = id; + HANDLE_CODE(amf_overload_resp.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_overload_resp.value.unpack(bref)); break; - case 9: + } + case 9: { amf_traffic_load_reduction_ind_present = true; - amf_traffic_load_reduction_ind.id = c.id; - amf_traffic_load_reduction_ind.crit = c.crit; - amf_traffic_load_reduction_ind.value = c.value.amf_traffic_load_reduction_ind(); + amf_traffic_load_reduction_ind.id = id; + HANDLE_CODE(amf_traffic_load_reduction_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_traffic_load_reduction_ind.value.unpack(bref)); break; - case 49: + } + case 49: { overload_start_nssai_list_present = true; - overload_start_nssai_list.id = c.id; - overload_start_nssai_list.crit = c.crit; - overload_start_nssai_list.value = c.value.overload_start_nssai_list(); + overload_start_nssai_list.id = id; + HANDLE_CODE(overload_start_nssai_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(overload_start_nssai_list.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -39831,75 +39103,7 @@ void overload_start_ies_container::to_json(json_writer& j) const j.end_obj(); } -// OverloadStart ::= SEQUENCE -SRSASN_CODE overload_start_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE overload_start_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void overload_start_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -SRSASN_CODE protocol_ie_container_empty_l::pack(bit_ref& bref) const -{ - uint32_t nof_ies = 0; - pack_length(bref, nof_ies, 0u, 65535u, true); - - return SRSASN_SUCCESS; -} -SRSASN_CODE protocol_ie_container_empty_l::unpack(cbit_ref& bref) -{ - uint32_t nof_ies = 0; - unpack_length(nof_ies, bref, 0u, 65535u, true); - if (nof_ies > 0) { - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; -} -void protocol_ie_container_empty_l::to_json(json_writer& j) const -{ - j.start_obj(); - j.end_obj(); -} - -// OverloadStop ::= SEQUENCE -SRSASN_CODE overload_stop_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE overload_stop_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void overload_stop_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pdu_session_res_modify_confirm_ies_container::pdu_session_res_modify_confirm_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -39935,41 +39139,51 @@ SRSASN_CODE pdu_session_res_modify_confirm_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 62: + } + case 62: { nof_mandatory_ies--; - pdu_session_res_modify_list_mod_cfm.id = c.id; - pdu_session_res_modify_list_mod_cfm.crit = c.crit; - pdu_session_res_modify_list_mod_cfm.value = c.value.pdu_session_res_modify_list_mod_cfm(); + pdu_session_res_modify_list_mod_cfm.id = id; + HANDLE_CODE(pdu_session_res_modify_list_mod_cfm.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_modify_list_mod_cfm.value.unpack(bref)); break; - case 131: + } + case 131: { pdu_session_res_failed_to_modify_list_mod_cfm_present = true; - pdu_session_res_failed_to_modify_list_mod_cfm.id = c.id; - pdu_session_res_failed_to_modify_list_mod_cfm.crit = c.crit; - pdu_session_res_failed_to_modify_list_mod_cfm.value = c.value.pdu_session_res_failed_to_modify_list_mod_cfm(); + pdu_session_res_failed_to_modify_list_mod_cfm.id = id; + HANDLE_CODE(pdu_session_res_failed_to_modify_list_mod_cfm.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_failed_to_modify_list_mod_cfm.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -40000,30 +39214,7 @@ void pdu_session_res_modify_confirm_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PDUSessionResourceModifyConfirm ::= SEQUENCE -SRSASN_CODE pdu_session_res_modify_confirm_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pdu_session_res_modify_confirm_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pdu_session_res_modify_confirm_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pdu_session_res_modify_ind_ies_container::pdu_session_res_modify_ind_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -40049,29 +39240,35 @@ SRSASN_CODE pdu_session_res_modify_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 63: + } + case 63: { nof_mandatory_ies--; - pdu_session_res_modify_list_mod_ind.id = c.id; - pdu_session_res_modify_list_mod_ind.crit = c.crit; - pdu_session_res_modify_list_mod_ind.value = c.value.pdu_session_res_modify_list_mod_ind(); + pdu_session_res_modify_list_mod_ind.id = id; + HANDLE_CODE(pdu_session_res_modify_list_mod_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_modify_list_mod_ind.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -40094,30 +39291,7 @@ void pdu_session_res_modify_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PDUSessionResourceModifyIndication ::= SEQUENCE -SRSASN_CODE pdu_session_res_modify_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pdu_session_res_modify_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pdu_session_res_modify_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pdu_session_res_modify_request_ies_container::pdu_session_res_modify_request_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -40148,35 +39322,43 @@ SRSASN_CODE pdu_session_res_modify_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 83: + } + case 83: { ran_paging_prio_present = true; - ran_paging_prio.id = c.id; - ran_paging_prio.crit = c.crit; - ran_paging_prio.value = c.value.ran_paging_prio(); + ran_paging_prio.id = id; + HANDLE_CODE(ran_paging_prio.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_paging_prio.value.unpack(bref)); break; - case 64: + } + case 64: { nof_mandatory_ies--; - pdu_session_res_modify_list_mod_req.id = c.id; - pdu_session_res_modify_list_mod_req.crit = c.crit; - pdu_session_res_modify_list_mod_req.value = c.value.pdu_session_res_modify_list_mod_req(); + pdu_session_res_modify_list_mod_req.id = id; + HANDLE_CODE(pdu_session_res_modify_list_mod_req.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_modify_list_mod_req.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -40203,30 +39385,7 @@ void pdu_session_res_modify_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PDUSessionResourceModifyRequest ::= SEQUENCE -SRSASN_CODE pdu_session_res_modify_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pdu_session_res_modify_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pdu_session_res_modify_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pdu_session_res_modify_resp_ies_container::pdu_session_res_modify_resp_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -40270,47 +39429,59 @@ SRSASN_CODE pdu_session_res_modify_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 65: + } + case 65: { pdu_session_res_modify_list_mod_res_present = true; - pdu_session_res_modify_list_mod_res.id = c.id; - pdu_session_res_modify_list_mod_res.crit = c.crit; - pdu_session_res_modify_list_mod_res.value = c.value.pdu_session_res_modify_list_mod_res(); + pdu_session_res_modify_list_mod_res.id = id; + HANDLE_CODE(pdu_session_res_modify_list_mod_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_modify_list_mod_res.value.unpack(bref)); break; - case 54: + } + case 54: { pdu_session_res_failed_to_modify_list_mod_res_present = true; - pdu_session_res_failed_to_modify_list_mod_res.id = c.id; - pdu_session_res_failed_to_modify_list_mod_res.crit = c.crit; - pdu_session_res_failed_to_modify_list_mod_res.value = c.value.pdu_session_res_failed_to_modify_list_mod_res(); + pdu_session_res_failed_to_modify_list_mod_res.id = id; + HANDLE_CODE(pdu_session_res_failed_to_modify_list_mod_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_failed_to_modify_list_mod_res.value.unpack(bref)); break; - case 121: + } + case 121: { user_location_info_present = true; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -40347,30 +39518,7 @@ void pdu_session_res_modify_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PDUSessionResourceModifyResponse ::= SEQUENCE -SRSASN_CODE pdu_session_res_modify_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pdu_session_res_modify_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pdu_session_res_modify_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pdu_session_res_notify_ies_container::pdu_session_res_notify_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -40409,41 +39557,51 @@ SRSASN_CODE pdu_session_res_notify_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 66: + } + case 66: { pdu_session_res_notify_list_present = true; - pdu_session_res_notify_list.id = c.id; - pdu_session_res_notify_list.crit = c.crit; - pdu_session_res_notify_list.value = c.value.pdu_session_res_notify_list(); + pdu_session_res_notify_list.id = id; + HANDLE_CODE(pdu_session_res_notify_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_notify_list.value.unpack(bref)); break; - case 67: + } + case 67: { pdu_session_res_released_list_not_present = true; - pdu_session_res_released_list_not.id = c.id; - pdu_session_res_released_list_not.crit = c.crit; - pdu_session_res_released_list_not.value = c.value.pdu_session_res_released_list_not(); + pdu_session_res_released_list_not.id = id; + HANDLE_CODE(pdu_session_res_released_list_not.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_released_list_not.value.unpack(bref)); break; - case 121: + } + case 121: { user_location_info_present = true; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -40476,30 +39634,7 @@ void pdu_session_res_notify_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PDUSessionResourceNotify ::= SEQUENCE -SRSASN_CODE pdu_session_res_notify_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pdu_session_res_notify_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pdu_session_res_notify_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pdu_session_res_release_cmd_ies_container::pdu_session_res_release_cmd_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -40535,41 +39670,51 @@ SRSASN_CODE pdu_session_res_release_cmd_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 83: + } + case 83: { ran_paging_prio_present = true; - ran_paging_prio.id = c.id; - ran_paging_prio.crit = c.crit; - ran_paging_prio.value = c.value.ran_paging_prio(); + ran_paging_prio.id = id; + HANDLE_CODE(ran_paging_prio.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_paging_prio.value.unpack(bref)); break; - case 38: + } + case 38: { nas_pdu_present = true; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; - case 79: + } + case 79: { nof_mandatory_ies--; - pdu_session_res_to_release_list_rel_cmd.id = c.id; - pdu_session_res_to_release_list_rel_cmd.crit = c.crit; - pdu_session_res_to_release_list_rel_cmd.value = c.value.pdu_session_res_to_release_list_rel_cmd(); + pdu_session_res_to_release_list_rel_cmd.id = id; + HANDLE_CODE(pdu_session_res_to_release_list_rel_cmd.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_to_release_list_rel_cmd.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -40600,30 +39745,7 @@ void pdu_session_res_release_cmd_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PDUSessionResourceReleaseCommand ::= SEQUENCE -SRSASN_CODE pdu_session_res_release_cmd_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pdu_session_res_release_cmd_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pdu_session_res_release_cmd_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pdu_session_res_release_resp_ies_container::pdu_session_res_release_resp_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -40659,41 +39781,51 @@ SRSASN_CODE pdu_session_res_release_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 70: + } + case 70: { nof_mandatory_ies--; - pdu_session_res_released_list_rel_res.id = c.id; - pdu_session_res_released_list_rel_res.crit = c.crit; - pdu_session_res_released_list_rel_res.value = c.value.pdu_session_res_released_list_rel_res(); + pdu_session_res_released_list_rel_res.id = id; + HANDLE_CODE(pdu_session_res_released_list_rel_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_released_list_rel_res.value.unpack(bref)); break; - case 121: + } + case 121: { user_location_info_present = true; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -40724,30 +39856,7 @@ void pdu_session_res_release_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PDUSessionResourceReleaseResponse ::= SEQUENCE -SRSASN_CODE pdu_session_res_release_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pdu_session_res_release_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pdu_session_res_release_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pdu_session_res_setup_request_ies_container::pdu_session_res_setup_request_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -40788,47 +39897,59 @@ SRSASN_CODE pdu_session_res_setup_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 83: + } + case 83: { ran_paging_prio_present = true; - ran_paging_prio.id = c.id; - ran_paging_prio.crit = c.crit; - ran_paging_prio.value = c.value.ran_paging_prio(); + ran_paging_prio.id = id; + HANDLE_CODE(ran_paging_prio.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_paging_prio.value.unpack(bref)); break; - case 38: + } + case 38: { nas_pdu_present = true; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; - case 74: + } + case 74: { nof_mandatory_ies--; - pdu_session_res_setup_list_su_req.id = c.id; - pdu_session_res_setup_list_su_req.crit = c.crit; - pdu_session_res_setup_list_su_req.value = c.value.pdu_session_res_setup_list_su_req(); + pdu_session_res_setup_list_su_req.id = id; + HANDLE_CODE(pdu_session_res_setup_list_su_req.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_setup_list_su_req.value.unpack(bref)); break; - case 110: + } + case 110: { ue_aggregate_maximum_bit_rate_present = true; - ue_aggregate_maximum_bit_rate.id = c.id; - ue_aggregate_maximum_bit_rate.crit = c.crit; - ue_aggregate_maximum_bit_rate.value = c.value.ue_aggregate_maximum_bit_rate(); + ue_aggregate_maximum_bit_rate.id = id; + HANDLE_CODE(ue_aggregate_maximum_bit_rate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_aggregate_maximum_bit_rate.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -40863,30 +39984,7 @@ void pdu_session_res_setup_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PDUSessionResourceSetupRequest ::= SEQUENCE -SRSASN_CODE pdu_session_res_setup_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pdu_session_res_setup_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pdu_session_res_setup_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pdu_session_res_setup_resp_ies_container::pdu_session_res_setup_resp_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -40925,41 +40023,51 @@ SRSASN_CODE pdu_session_res_setup_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 75: + } + case 75: { pdu_session_res_setup_list_su_res_present = true; - pdu_session_res_setup_list_su_res.id = c.id; - pdu_session_res_setup_list_su_res.crit = c.crit; - pdu_session_res_setup_list_su_res.value = c.value.pdu_session_res_setup_list_su_res(); + pdu_session_res_setup_list_su_res.id = id; + HANDLE_CODE(pdu_session_res_setup_list_su_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_setup_list_su_res.value.unpack(bref)); break; - case 58: + } + case 58: { pdu_session_res_failed_to_setup_list_su_res_present = true; - pdu_session_res_failed_to_setup_list_su_res.id = c.id; - pdu_session_res_failed_to_setup_list_su_res.crit = c.crit; - pdu_session_res_failed_to_setup_list_su_res.value = c.value.pdu_session_res_failed_to_setup_list_su_res(); + pdu_session_res_failed_to_setup_list_su_res.id = id; + HANDLE_CODE(pdu_session_res_failed_to_setup_list_su_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_failed_to_setup_list_su_res.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -40992,30 +40100,7 @@ void pdu_session_res_setup_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PDUSessionResourceSetupResponse ::= SEQUENCE -SRSASN_CODE pdu_session_res_setup_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pdu_session_res_setup_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pdu_session_res_setup_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pws_cancel_request_ies_container::pws_cancel_request_ies_container() : msg_id(35, crit_e::reject), @@ -41049,35 +40134,43 @@ SRSASN_CODE pws_cancel_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 35: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 35: { nof_mandatory_ies--; - msg_id.id = c.id; - msg_id.crit = c.crit; - msg_id.value = c.value.msg_id(); + msg_id.id = id; + HANDLE_CODE(msg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(msg_id.value.unpack(bref)); break; - case 95: + } + case 95: { nof_mandatory_ies--; - serial_num.id = c.id; - serial_num.crit = c.crit; - serial_num.value = c.value.serial_num(); + serial_num.id = id; + HANDLE_CODE(serial_num.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(serial_num.value.unpack(bref)); break; - case 122: + } + case 122: { warning_area_list_present = true; - warning_area_list.id = c.id; - warning_area_list.crit = c.crit; - warning_area_list.value = c.value.warning_area_list(); + warning_area_list.id = id; + HANDLE_CODE(warning_area_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_area_list.value.unpack(bref)); break; - case 14: + } + case 14: { cancel_all_warning_msgs_present = true; - cancel_all_warning_msgs.id = c.id; - cancel_all_warning_msgs.crit = c.crit; - cancel_all_warning_msgs.value = c.value.cancel_all_warning_msgs(); + cancel_all_warning_msgs.id = id; + HANDLE_CODE(cancel_all_warning_msgs.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cancel_all_warning_msgs.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -41106,30 +40199,7 @@ void pws_cancel_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PWSCancelRequest ::= SEQUENCE -SRSASN_CODE pws_cancel_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pws_cancel_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pws_cancel_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pws_cancel_resp_ies_container::pws_cancel_resp_ies_container() : msg_id(35, crit_e::reject), @@ -41163,35 +40233,43 @@ SRSASN_CODE pws_cancel_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 35: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 35: { nof_mandatory_ies--; - msg_id.id = c.id; - msg_id.crit = c.crit; - msg_id.value = c.value.msg_id(); + msg_id.id = id; + HANDLE_CODE(msg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(msg_id.value.unpack(bref)); break; - case 95: + } + case 95: { nof_mandatory_ies--; - serial_num.id = c.id; - serial_num.crit = c.crit; - serial_num.value = c.value.serial_num(); + serial_num.id = id; + HANDLE_CODE(serial_num.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(serial_num.value.unpack(bref)); break; - case 12: + } + case 12: { broadcast_cancelled_area_list_present = true; - broadcast_cancelled_area_list.id = c.id; - broadcast_cancelled_area_list.crit = c.crit; - broadcast_cancelled_area_list.value = c.value.broadcast_cancelled_area_list(); + broadcast_cancelled_area_list.id = id; + HANDLE_CODE(broadcast_cancelled_area_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(broadcast_cancelled_area_list.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -41220,30 +40298,7 @@ void pws_cancel_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PWSCancelResponse ::= SEQUENCE -SRSASN_CODE pws_cancel_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pws_cancel_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pws_cancel_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pws_fail_ind_ies_container::pws_fail_ind_ies_container() : pws_failed_cell_id_list(81, crit_e::reject), global_ran_node_id(27, crit_e::reject) @@ -41266,23 +40321,27 @@ SRSASN_CODE pws_fail_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 81: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 81: { nof_mandatory_ies--; - pws_failed_cell_id_list.id = c.id; - pws_failed_cell_id_list.crit = c.crit; - pws_failed_cell_id_list.value = c.value.pws_failed_cell_id_list(); + pws_failed_cell_id_list.id = id; + HANDLE_CODE(pws_failed_cell_id_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pws_failed_cell_id_list.value.unpack(bref)); break; - case 27: + } + case 27: { nof_mandatory_ies--; - global_ran_node_id.id = c.id; - global_ran_node_id.crit = c.crit; - global_ran_node_id.value = c.value.global_ran_node_id(); + global_ran_node_id.id = id; + HANDLE_CODE(global_ran_node_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_ran_node_id.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -41303,30 +40362,7 @@ void pws_fail_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PWSFailureIndication ::= SEQUENCE -SRSASN_CODE pws_fail_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pws_fail_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pws_fail_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pws_restart_ind_ies_container::pws_restart_ind_ies_container() : cell_id_list_for_restart(16, crit_e::reject), @@ -41357,35 +40393,43 @@ SRSASN_CODE pws_restart_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 16: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 16: { nof_mandatory_ies--; - cell_id_list_for_restart.id = c.id; - cell_id_list_for_restart.crit = c.crit; - cell_id_list_for_restart.value = c.value.cell_id_list_for_restart(); + cell_id_list_for_restart.id = id; + HANDLE_CODE(cell_id_list_for_restart.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cell_id_list_for_restart.value.unpack(bref)); break; - case 27: + } + case 27: { nof_mandatory_ies--; - global_ran_node_id.id = c.id; - global_ran_node_id.crit = c.crit; - global_ran_node_id.value = c.value.global_ran_node_id(); + global_ran_node_id.id = id; + HANDLE_CODE(global_ran_node_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_ran_node_id.value.unpack(bref)); break; - case 104: + } + case 104: { nof_mandatory_ies--; - tai_list_for_restart.id = c.id; - tai_list_for_restart.crit = c.crit; - tai_list_for_restart.value = c.value.tai_list_for_restart(); + tai_list_for_restart.id = id; + HANDLE_CODE(tai_list_for_restart.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tai_list_for_restart.value.unpack(bref)); break; - case 23: + } + case 23: { emergency_area_id_list_for_restart_present = true; - emergency_area_id_list_for_restart.id = c.id; - emergency_area_id_list_for_restart.crit = c.crit; - emergency_area_id_list_for_restart.value = c.value.emergency_area_id_list_for_restart(); + emergency_area_id_list_for_restart.id = id; + HANDLE_CODE(emergency_area_id_list_for_restart.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(emergency_area_id_list_for_restart.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -41412,30 +40456,7 @@ void pws_restart_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PWSRestartIndication ::= SEQUENCE -SRSASN_CODE pws_restart_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pws_restart_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pws_restart_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; paging_ies_container::paging_ies_container() : ue_paging_id(115, crit_e::ignore), @@ -41484,53 +40505,67 @@ SRSASN_CODE paging_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 115: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 115: { nof_mandatory_ies--; - ue_paging_id.id = c.id; - ue_paging_id.crit = c.crit; - ue_paging_id.value = c.value.ue_paging_id(); + ue_paging_id.id = id; + HANDLE_CODE(ue_paging_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_paging_id.value.unpack(bref)); break; - case 50: + } + case 50: { paging_drx_present = true; - paging_drx.id = c.id; - paging_drx.crit = c.crit; - paging_drx.value = c.value.paging_drx(); + paging_drx.id = id; + HANDLE_CODE(paging_drx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(paging_drx.value.unpack(bref)); break; - case 103: + } + case 103: { nof_mandatory_ies--; - tai_list_for_paging.id = c.id; - tai_list_for_paging.crit = c.crit; - tai_list_for_paging.value = c.value.tai_list_for_paging(); + tai_list_for_paging.id = id; + HANDLE_CODE(tai_list_for_paging.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tai_list_for_paging.value.unpack(bref)); break; - case 52: + } + case 52: { paging_prio_present = true; - paging_prio.id = c.id; - paging_prio.crit = c.crit; - paging_prio.value = c.value.paging_prio(); + paging_prio.id = id; + HANDLE_CODE(paging_prio.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(paging_prio.value.unpack(bref)); break; - case 118: + } + case 118: { ue_radio_cap_for_paging_present = true; - ue_radio_cap_for_paging.id = c.id; - ue_radio_cap_for_paging.crit = c.crit; - ue_radio_cap_for_paging.value = c.value.ue_radio_cap_for_paging(); + ue_radio_cap_for_paging.id = id; + HANDLE_CODE(ue_radio_cap_for_paging.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap_for_paging.value.unpack(bref)); break; - case 51: + } + case 51: { paging_origin_present = true; - paging_origin.id = c.id; - paging_origin.crit = c.crit; - paging_origin.value = c.value.paging_origin(); + paging_origin.id = id; + HANDLE_CODE(paging_origin.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(paging_origin.value.unpack(bref)); break; - case 11: + } + case 11: { assist_data_for_paging_present = true; - assist_data_for_paging.id = c.id; - assist_data_for_paging.crit = c.crit; - assist_data_for_paging.value = c.value.assist_data_for_paging(); + assist_data_for_paging.id = id; + HANDLE_CODE(assist_data_for_paging.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(assist_data_for_paging.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -41571,30 +40606,7 @@ void paging_ies_container::to_json(json_writer& j) const j.end_obj(); } -// Paging ::= SEQUENCE -SRSASN_CODE paging_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE paging_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void paging_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; path_switch_request_ies_container::path_switch_request_ies_container() : ran_ue_ngap_id(85, crit_e::reject), @@ -41629,47 +40641,59 @@ SRSASN_CODE path_switch_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 5; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 85: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 100: + } + case 100: { nof_mandatory_ies--; - source_amf_ue_ngap_id.id = c.id; - source_amf_ue_ngap_id.crit = c.crit; - source_amf_ue_ngap_id.value = c.value.source_amf_ue_ngap_id(); + source_amf_ue_ngap_id.id = id; + HANDLE_CODE(source_amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(source_amf_ue_ngap_id.value.unpack(bref)); break; - case 121: + } + case 121: { nof_mandatory_ies--; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 119: + } + case 119: { nof_mandatory_ies--; - ue_security_cap.id = c.id; - ue_security_cap.crit = c.crit; - ue_security_cap.value = c.value.ue_security_cap(); + ue_security_cap.id = id; + HANDLE_CODE(ue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_security_cap.value.unpack(bref)); break; - case 76: + } + case 76: { nof_mandatory_ies--; - pdu_session_res_to_be_switched_dl_list.id = c.id; - pdu_session_res_to_be_switched_dl_list.crit = c.crit; - pdu_session_res_to_be_switched_dl_list.value = c.value.pdu_session_res_to_be_switched_dl_list(); + pdu_session_res_to_be_switched_dl_list.id = id; + HANDLE_CODE(pdu_session_res_to_be_switched_dl_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_to_be_switched_dl_list.value.unpack(bref)); break; - case 57: + } + case 57: { pdu_session_res_failed_to_setup_list_ps_req_present = true; - pdu_session_res_failed_to_setup_list_ps_req.id = c.id; - pdu_session_res_failed_to_setup_list_ps_req.crit = c.crit; - pdu_session_res_failed_to_setup_list_ps_req.value = c.value.pdu_session_res_failed_to_setup_list_ps_req(); + pdu_session_res_failed_to_setup_list_ps_req.id = id; + HANDLE_CODE(pdu_session_res_failed_to_setup_list_ps_req.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_failed_to_setup_list_ps_req.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -41700,30 +40724,7 @@ void path_switch_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PathSwitchRequest ::= SEQUENCE -SRSASN_CODE path_switch_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE path_switch_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void path_switch_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; path_switch_request_ack_ies_container::path_switch_request_ack_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -41788,83 +40789,107 @@ SRSASN_CODE path_switch_request_ack_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 5; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 119: + } + case 119: { ue_security_cap_present = true; - ue_security_cap.id = c.id; - ue_security_cap.crit = c.crit; - ue_security_cap.value = c.value.ue_security_cap(); + ue_security_cap.id = id; + HANDLE_CODE(ue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_security_cap.value.unpack(bref)); break; - case 93: + } + case 93: { nof_mandatory_ies--; - security_context.id = c.id; - security_context.crit = c.crit; - security_context.value = c.value.security_context(); + security_context.id = id; + HANDLE_CODE(security_context.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_context.value.unpack(bref)); break; - case 41: + } + case 41: { new_security_context_ind_present = true; - new_security_context_ind.id = c.id; - new_security_context_ind.crit = c.crit; - new_security_context_ind.value = c.value.new_security_context_ind(); + new_security_context_ind.id = id; + HANDLE_CODE(new_security_context_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(new_security_context_ind.value.unpack(bref)); break; - case 77: + } + case 77: { nof_mandatory_ies--; - pdu_session_res_switched_list.id = c.id; - pdu_session_res_switched_list.crit = c.crit; - pdu_session_res_switched_list.value = c.value.pdu_session_res_switched_list(); + pdu_session_res_switched_list.id = id; + HANDLE_CODE(pdu_session_res_switched_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_switched_list.value.unpack(bref)); break; - case 68: + } + case 68: { pdu_session_res_released_list_ps_ack_present = true; - pdu_session_res_released_list_ps_ack.id = c.id; - pdu_session_res_released_list_ps_ack.crit = c.crit; - pdu_session_res_released_list_ps_ack.value = c.value.pdu_session_res_released_list_ps_ack(); + pdu_session_res_released_list_ps_ack.id = id; + HANDLE_CODE(pdu_session_res_released_list_ps_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_released_list_ps_ack.value.unpack(bref)); break; - case 0: + } + case 0: { nof_mandatory_ies--; - allowed_nssai.id = c.id; - allowed_nssai.crit = c.crit; - allowed_nssai.value = c.value.allowed_nssai(); + allowed_nssai.id = id; + HANDLE_CODE(allowed_nssai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(allowed_nssai.value.unpack(bref)); break; - case 18: + } + case 18: { core_network_assist_info_present = true; - core_network_assist_info.id = c.id; - core_network_assist_info.crit = c.crit; - core_network_assist_info.value = c.value.core_network_assist_info(); + core_network_assist_info.id = id; + HANDLE_CODE(core_network_assist_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(core_network_assist_info.value.unpack(bref)); break; - case 91: + } + case 91: { rrc_inactive_transition_report_request_present = true; - rrc_inactive_transition_report_request.id = c.id; - rrc_inactive_transition_report_request.crit = c.crit; - rrc_inactive_transition_report_request.value = c.value.rrc_inactive_transition_report_request(); + rrc_inactive_transition_report_request.id = id; + HANDLE_CODE(rrc_inactive_transition_report_request.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(rrc_inactive_transition_report_request.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 146: + } + case 146: { redirection_voice_fallback_present = true; - redirection_voice_fallback.id = c.id; - redirection_voice_fallback.crit = c.crit; - redirection_voice_fallback.value = c.value.redirection_voice_fallback(); + redirection_voice_fallback.id = id; + HANDLE_CODE(redirection_voice_fallback.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(redirection_voice_fallback.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -41919,30 +40944,7 @@ void path_switch_request_ack_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PathSwitchRequestAcknowledge ::= SEQUENCE -SRSASN_CODE path_switch_request_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE path_switch_request_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void path_switch_request_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; path_switch_request_fail_ies_container::path_switch_request_fail_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -41973,35 +40975,43 @@ SRSASN_CODE path_switch_request_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 69: + } + case 69: { nof_mandatory_ies--; - pdu_session_res_released_list_ps_fail.id = c.id; - pdu_session_res_released_list_ps_fail.crit = c.crit; - pdu_session_res_released_list_ps_fail.value = c.value.pdu_session_res_released_list_ps_fail(); + pdu_session_res_released_list_ps_fail.id = id; + HANDLE_CODE(pdu_session_res_released_list_ps_fail.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_released_list_ps_fail.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -42028,29 +41038,6 @@ void path_switch_request_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PathSwitchRequestFailure ::= SEQUENCE -SRSASN_CODE path_switch_request_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE path_switch_request_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void path_switch_request_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - template private_ie_container_item_s::private_ie_container_item_s(private_ie_id_c id_, crit_e crit_) : id(id_), crit(crit_) @@ -42141,7 +41128,7 @@ void private_msg_s::to_json(json_writer& j) const j.end_array(); } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ran_cfg_upd_ies_container::ran_cfg_upd_ies_container() : ran_node_name(82, crit_e::ignore), @@ -42179,35 +41166,43 @@ SRSASN_CODE ran_cfg_upd_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 82: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 82: { ran_node_name_present = true; - ran_node_name.id = c.id; - ran_node_name.crit = c.crit; - ran_node_name.value = c.value.ran_node_name(); + ran_node_name.id = id; + HANDLE_CODE(ran_node_name.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_node_name.value.unpack(bref)); break; - case 102: + } + case 102: { supported_ta_list_present = true; - supported_ta_list.id = c.id; - supported_ta_list.crit = c.crit; - supported_ta_list.value = c.value.supported_ta_list(); + supported_ta_list.id = id; + HANDLE_CODE(supported_ta_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(supported_ta_list.value.unpack(bref)); break; - case 21: + } + case 21: { default_paging_drx_present = true; - default_paging_drx.id = c.id; - default_paging_drx.crit = c.crit; - default_paging_drx.value = c.value.default_paging_drx(); + default_paging_drx.id = id; + HANDLE_CODE(default_paging_drx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(default_paging_drx.value.unpack(bref)); break; - case 27: + } + case 27: { global_ran_node_id_present = true; - global_ran_node_id.id = c.id; - global_ran_node_id.crit = c.crit; - global_ran_node_id.value = c.value.global_ran_node_id(); + global_ran_node_id.id = id; + HANDLE_CODE(global_ran_node_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_ran_node_id.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -42236,52 +41231,7 @@ void ran_cfg_upd_ies_container::to_json(json_writer& j) const j.end_obj(); } -// RANConfigurationUpdate ::= SEQUENCE -SRSASN_CODE ran_cfg_upd_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ran_cfg_upd_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ran_cfg_upd_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -// RANConfigurationUpdateAcknowledge ::= SEQUENCE -SRSASN_CODE ran_cfg_upd_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(pack_dyn_seq_of(bref, protocol_ies, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ran_cfg_upd_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(unpack_dyn_seq_of(protocol_ies, bref, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -void ran_cfg_upd_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ran_cfg_upd_fail_ies_container::ran_cfg_upd_fail_ies_container() : cause(15, crit_e::ignore), time_to_wait(107, crit_e::ignore), crit_diagnostics(19, crit_e::ignore) @@ -42311,29 +41261,35 @@ SRSASN_CODE ran_cfg_upd_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 1; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 15: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 107: + } + case 107: { time_to_wait_present = true; - time_to_wait.id = c.id; - time_to_wait.crit = c.crit; - time_to_wait.value = c.value.time_to_wait(); + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -42360,30 +41316,7 @@ void ran_cfg_upd_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// RANConfigurationUpdateFailure ::= SEQUENCE -SRSASN_CODE ran_cfg_upd_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ran_cfg_upd_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ran_cfg_upd_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; rrc_inactive_transition_report_ies_container::rrc_inactive_transition_report_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -42411,35 +41344,43 @@ SRSASN_CODE rrc_inactive_transition_report_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 92: + } + case 92: { nof_mandatory_ies--; - rrc_state.id = c.id; - rrc_state.crit = c.crit; - rrc_state.value = c.value.rrc_state(); + rrc_state.id = id; + HANDLE_CODE(rrc_state.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(rrc_state.value.unpack(bref)); break; - case 121: + } + case 121: { nof_mandatory_ies--; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -42464,30 +41405,7 @@ void rrc_inactive_transition_report_ies_container::to_json(json_writer& j) const j.end_obj(); } -// RRCInactiveTransitionReport ::= SEQUENCE -SRSASN_CODE rrc_inactive_transition_report_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE rrc_inactive_transition_report_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void rrc_inactive_transition_report_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; reroute_nas_request_ies_container::reroute_nas_request_ies_container() : ran_ue_ngap_id(85, crit_e::reject), @@ -42523,41 +41441,51 @@ SRSASN_CODE reroute_nas_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 85: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 10: + } + case 10: { amf_ue_ngap_id_present = true; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 42: + } + case 42: { nof_mandatory_ies--; - ngap_msg.id = c.id; - ngap_msg.crit = c.crit; - ngap_msg.value = c.value.ngap_msg(); + ngap_msg.id = id; + HANDLE_CODE(ngap_msg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ngap_msg.value.unpack(bref)); break; - case 3: + } + case 3: { nof_mandatory_ies--; - amf_set_id.id = c.id; - amf_set_id.crit = c.crit; - amf_set_id.value = c.value.amf_set_id(); + amf_set_id.id = id; + HANDLE_CODE(amf_set_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_set_id.value.unpack(bref)); break; - case 0: + } + case 0: { allowed_nssai_present = true; - allowed_nssai.id = c.id; - allowed_nssai.crit = c.crit; - allowed_nssai.value = c.value.allowed_nssai(); + allowed_nssai.id = id; + HANDLE_CODE(allowed_nssai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(allowed_nssai.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -42588,30 +41516,7 @@ void reroute_nas_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// RerouteNASRequest ::= SEQUENCE -SRSASN_CODE reroute_nas_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE reroute_nas_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void reroute_nas_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; secondary_rat_data_usage_report_ies_container::secondary_rat_data_usage_report_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -42642,35 +41547,43 @@ SRSASN_CODE secondary_rat_data_usage_report_ies_container::unpack(cbit_ref& bref uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 142: + } + case 142: { nof_mandatory_ies--; - pdu_session_res_secondary_ratusage_list.id = c.id; - pdu_session_res_secondary_ratusage_list.crit = c.crit; - pdu_session_res_secondary_ratusage_list.value = c.value.pdu_session_res_secondary_ratusage_list(); + pdu_session_res_secondary_ratusage_list.id = id; + HANDLE_CODE(pdu_session_res_secondary_ratusage_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_secondary_ratusage_list.value.unpack(bref)); break; - case 143: + } + case 143: { ho_flag_present = true; - ho_flag.id = c.id; - ho_flag.crit = c.crit; - ho_flag.value = c.value.ho_flag(); + ho_flag.id = id; + HANDLE_CODE(ho_flag.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ho_flag.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -42697,30 +41610,7 @@ void secondary_rat_data_usage_report_ies_container::to_json(json_writer& j) cons j.end_obj(); } -// SecondaryRATDataUsageReport ::= SEQUENCE -SRSASN_CODE secondary_rat_data_usage_report_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE secondary_rat_data_usage_report_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void secondary_rat_data_usage_report_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; trace_fail_ind_ies_container::trace_fail_ind_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -42748,35 +41638,43 @@ SRSASN_CODE trace_fail_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 44: + } + case 44: { nof_mandatory_ies--; - ngran_trace_id.id = c.id; - ngran_trace_id.crit = c.crit; - ngran_trace_id.value = c.value.ngran_trace_id(); + ngran_trace_id.id = id; + HANDLE_CODE(ngran_trace_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ngran_trace_id.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -42801,30 +41699,7 @@ void trace_fail_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// TraceFailureIndication ::= SEQUENCE -SRSASN_CODE trace_fail_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE trace_fail_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void trace_fail_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; trace_start_ies_container::trace_start_ies_container() : amf_ue_ngap_id(10, crit_e::reject), ran_ue_ngap_id(85, crit_e::reject), trace_activation(108, crit_e::ignore) @@ -42848,29 +41723,35 @@ SRSASN_CODE trace_start_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 108: + } + case 108: { nof_mandatory_ies--; - trace_activation.id = c.id; - trace_activation.crit = c.crit; - trace_activation.value = c.value.trace_activation(); + trace_activation.id = id; + HANDLE_CODE(trace_activation.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(trace_activation.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -42893,30 +41774,7 @@ void trace_start_ies_container::to_json(json_writer& j) const j.end_obj(); } -// TraceStart ::= SEQUENCE -SRSASN_CODE trace_start_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE trace_start_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void trace_start_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_mod_fail_ies_container::ue_context_mod_fail_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -42947,35 +41805,43 @@ SRSASN_CODE ue_context_mod_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -43002,30 +41868,7 @@ void ue_context_mod_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextModificationFailure ::= SEQUENCE -SRSASN_CODE ue_context_mod_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_mod_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_mod_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_mod_request_ies_container::ue_context_mod_request_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -43094,77 +41937,99 @@ SRSASN_CODE ue_context_mod_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 83: + } + case 83: { ran_paging_prio_present = true; - ran_paging_prio.id = c.id; - ran_paging_prio.crit = c.crit; - ran_paging_prio.value = c.value.ran_paging_prio(); + ran_paging_prio.id = id; + HANDLE_CODE(ran_paging_prio.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_paging_prio.value.unpack(bref)); break; - case 94: + } + case 94: { security_key_present = true; - security_key.id = c.id; - security_key.crit = c.crit; - security_key.value = c.value.security_key(); + security_key.id = id; + HANDLE_CODE(security_key.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_key.value.unpack(bref)); break; - case 31: + } + case 31: { idx_to_rfsp_present = true; - idx_to_rfsp.id = c.id; - idx_to_rfsp.crit = c.crit; - idx_to_rfsp.value = c.value.idx_to_rfsp(); + idx_to_rfsp.id = id; + HANDLE_CODE(idx_to_rfsp.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(idx_to_rfsp.value.unpack(bref)); break; - case 110: + } + case 110: { ue_aggregate_maximum_bit_rate_present = true; - ue_aggregate_maximum_bit_rate.id = c.id; - ue_aggregate_maximum_bit_rate.crit = c.crit; - ue_aggregate_maximum_bit_rate.value = c.value.ue_aggregate_maximum_bit_rate(); + ue_aggregate_maximum_bit_rate.id = id; + HANDLE_CODE(ue_aggregate_maximum_bit_rate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_aggregate_maximum_bit_rate.value.unpack(bref)); break; - case 119: + } + case 119: { ue_security_cap_present = true; - ue_security_cap.id = c.id; - ue_security_cap.crit = c.crit; - ue_security_cap.value = c.value.ue_security_cap(); + ue_security_cap.id = id; + HANDLE_CODE(ue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_security_cap.value.unpack(bref)); break; - case 18: + } + case 18: { core_network_assist_info_present = true; - core_network_assist_info.id = c.id; - core_network_assist_info.crit = c.crit; - core_network_assist_info.value = c.value.core_network_assist_info(); + core_network_assist_info.id = id; + HANDLE_CODE(core_network_assist_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(core_network_assist_info.value.unpack(bref)); break; - case 24: + } + case 24: { emergency_fallback_ind_present = true; - emergency_fallback_ind.id = c.id; - emergency_fallback_ind.crit = c.crit; - emergency_fallback_ind.value = c.value.emergency_fallback_ind(); + emergency_fallback_ind.id = id; + HANDLE_CODE(emergency_fallback_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(emergency_fallback_ind.value.unpack(bref)); break; - case 40: + } + case 40: { new_amf_ue_ngap_id_present = true; - new_amf_ue_ngap_id.id = c.id; - new_amf_ue_ngap_id.crit = c.crit; - new_amf_ue_ngap_id.value = c.value.new_amf_ue_ngap_id(); + new_amf_ue_ngap_id.id = id; + HANDLE_CODE(new_amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(new_amf_ue_ngap_id.value.unpack(bref)); break; - case 91: + } + case 91: { rrc_inactive_transition_report_request_present = true; - rrc_inactive_transition_report_request.id = c.id; - rrc_inactive_transition_report_request.crit = c.crit; - rrc_inactive_transition_report_request.value = c.value.rrc_inactive_transition_report_request(); + rrc_inactive_transition_report_request.id = id; + HANDLE_CODE(rrc_inactive_transition_report_request.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(rrc_inactive_transition_report_request.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -43221,30 +42086,7 @@ void ue_context_mod_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextModificationRequest ::= SEQUENCE -SRSASN_CODE ue_context_mod_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_mod_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_mod_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_mod_resp_ies_container::ue_context_mod_resp_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -43283,41 +42125,51 @@ SRSASN_CODE ue_context_mod_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 92: + } + case 92: { rrc_state_present = true; - rrc_state.id = c.id; - rrc_state.crit = c.crit; - rrc_state.value = c.value.rrc_state(); + rrc_state.id = id; + HANDLE_CODE(rrc_state.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(rrc_state.value.unpack(bref)); break; - case 121: + } + case 121: { user_location_info_present = true; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -43350,30 +42202,7 @@ void ue_context_mod_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextModificationResponse ::= SEQUENCE -SRSASN_CODE ue_context_mod_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_mod_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_mod_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_release_cmd_ies_container::ue_context_release_cmd_ies_container() : ue_ngap_ids(114, crit_e::reject), cause(15, crit_e::ignore) @@ -43396,23 +42225,27 @@ SRSASN_CODE ue_context_release_cmd_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 114: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 114: { nof_mandatory_ies--; - ue_ngap_ids.id = c.id; - ue_ngap_ids.crit = c.crit; - ue_ngap_ids.value = c.value.ue_ngap_ids(); + ue_ngap_ids.id = id; + HANDLE_CODE(ue_ngap_ids.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_ngap_ids.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -43433,30 +42266,7 @@ void ue_context_release_cmd_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextReleaseCommand ::= SEQUENCE -SRSASN_CODE ue_context_release_cmd_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_release_cmd_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_release_cmd_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_release_complete_ies_container::ue_context_release_complete_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -43500,48 +42310,59 @@ SRSASN_CODE ue_context_release_complete_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 121: + } + case 121: { user_location_info_present = true; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 32: + } + case 32: { info_on_recommended_cells_and_ran_nodes_for_paging_present = true; - info_on_recommended_cells_and_ran_nodes_for_paging.id = c.id; - info_on_recommended_cells_and_ran_nodes_for_paging.crit = c.crit; - info_on_recommended_cells_and_ran_nodes_for_paging.value = - c.value.info_on_recommended_cells_and_ran_nodes_for_paging(); + info_on_recommended_cells_and_ran_nodes_for_paging.id = id; + HANDLE_CODE(info_on_recommended_cells_and_ran_nodes_for_paging.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(info_on_recommended_cells_and_ran_nodes_for_paging.value.unpack(bref)); break; - case 60: + } + case 60: { pdu_session_res_list_cxt_rel_cpl_present = true; - pdu_session_res_list_cxt_rel_cpl.id = c.id; - pdu_session_res_list_cxt_rel_cpl.crit = c.crit; - pdu_session_res_list_cxt_rel_cpl.value = c.value.pdu_session_res_list_cxt_rel_cpl(); + pdu_session_res_list_cxt_rel_cpl.id = id; + HANDLE_CODE(pdu_session_res_list_cxt_rel_cpl.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_list_cxt_rel_cpl.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -43578,30 +42399,7 @@ void ue_context_release_complete_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextReleaseComplete ::= SEQUENCE -SRSASN_CODE ue_context_release_complete_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_release_complete_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_release_complete_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_release_request_ies_container::ue_context_release_request_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -43632,35 +42430,43 @@ SRSASN_CODE ue_context_release_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 133: + } + case 133: { pdu_session_res_list_cxt_rel_req_present = true; - pdu_session_res_list_cxt_rel_req.id = c.id; - pdu_session_res_list_cxt_rel_req.crit = c.crit; - pdu_session_res_list_cxt_rel_req.value = c.value.pdu_session_res_list_cxt_rel_req(); + pdu_session_res_list_cxt_rel_req.id = id; + HANDLE_CODE(pdu_session_res_list_cxt_rel_req.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_res_list_cxt_rel_req.value.unpack(bref)); break; - case 15: + } + case 15: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -43687,30 +42493,7 @@ void ue_context_release_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextReleaseRequest ::= SEQUENCE -SRSASN_CODE ue_context_release_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_release_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_release_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_radio_cap_check_request_ies_container::ue_radio_cap_check_request_ies_container() : amf_ue_ngap_id(10, crit_e::reject), ran_ue_ngap_id(85, crit_e::reject), ue_radio_cap(117, crit_e::ignore) @@ -43737,29 +42520,35 @@ SRSASN_CODE ue_radio_cap_check_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 117: + } + case 117: { ue_radio_cap_present = true; - ue_radio_cap.id = c.id; - ue_radio_cap.crit = c.crit; - ue_radio_cap.value = c.value.ue_radio_cap(); + ue_radio_cap.id = id; + HANDLE_CODE(ue_radio_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -43784,30 +42573,7 @@ void ue_radio_cap_check_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UERadioCapabilityCheckRequest ::= SEQUENCE -SRSASN_CODE ue_radio_cap_check_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_radio_cap_check_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_radio_cap_check_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_radio_cap_check_resp_ies_container::ue_radio_cap_check_resp_ies_container() : amf_ue_ngap_id(10, crit_e::ignore), @@ -43838,35 +42604,43 @@ SRSASN_CODE ue_radio_cap_check_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 30: + } + case 30: { nof_mandatory_ies--; - ims_voice_support_ind.id = c.id; - ims_voice_support_ind.crit = c.crit; - ims_voice_support_ind.value = c.value.ims_voice_support_ind(); + ims_voice_support_ind.id = id; + HANDLE_CODE(ims_voice_support_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ims_voice_support_ind.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -43893,30 +42667,7 @@ void ue_radio_cap_check_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UERadioCapabilityCheckResponse ::= SEQUENCE -SRSASN_CODE ue_radio_cap_check_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_radio_cap_check_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_radio_cap_check_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_radio_cap_info_ind_ies_container::ue_radio_cap_info_ind_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -43947,35 +42698,43 @@ SRSASN_CODE ue_radio_cap_info_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 117: + } + case 117: { nof_mandatory_ies--; - ue_radio_cap.id = c.id; - ue_radio_cap.crit = c.crit; - ue_radio_cap.value = c.value.ue_radio_cap(); + ue_radio_cap.id = id; + HANDLE_CODE(ue_radio_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap.value.unpack(bref)); break; - case 118: + } + case 118: { ue_radio_cap_for_paging_present = true; - ue_radio_cap_for_paging.id = c.id; - ue_radio_cap_for_paging.crit = c.crit; - ue_radio_cap_for_paging.value = c.value.ue_radio_cap_for_paging(); + ue_radio_cap_for_paging.id = id; + HANDLE_CODE(ue_radio_cap_for_paging.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap_for_paging.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -44002,30 +42761,7 @@ void ue_radio_cap_info_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UERadioCapabilityInfoIndication ::= SEQUENCE -SRSASN_CODE ue_radio_cap_info_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_radio_cap_info_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_radio_cap_info_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; uetnla_binding_release_request_ies_container::uetnla_binding_release_request_ies_container() : amf_ue_ngap_id(10, crit_e::reject), ran_ue_ngap_id(85, crit_e::reject) @@ -44048,23 +42784,27 @@ SRSASN_CODE uetnla_binding_release_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -44085,30 +42825,7 @@ void uetnla_binding_release_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UETNLABindingReleaseRequest ::= SEQUENCE -SRSASN_CODE uetnla_binding_release_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE uetnla_binding_release_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void uetnla_binding_release_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ul_nas_transport_ies_container::ul_nas_transport_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -44136,35 +42853,43 @@ SRSASN_CODE ul_nas_transport_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 38: + } + case 38: { nof_mandatory_ies--; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; - case 121: + } + case 121: { nof_mandatory_ies--; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -44189,30 +42914,7 @@ void ul_nas_transport_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UplinkNASTransport ::= SEQUENCE -SRSASN_CODE ul_nas_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ul_nas_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ul_nas_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ul_non_ueassociated_nrp_pa_transport_ies_container::ul_non_ueassociated_nrp_pa_transport_ies_container() : routing_id(89, crit_e::reject), nrp_pa_pdu(46, crit_e::reject) @@ -44235,23 +42937,27 @@ SRSASN_CODE ul_non_ueassociated_nrp_pa_transport_ies_container::unpack(cbit_ref& uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 89: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 89: { nof_mandatory_ies--; - routing_id.id = c.id; - routing_id.crit = c.crit; - routing_id.value = c.value.routing_id(); + routing_id.id = id; + HANDLE_CODE(routing_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(routing_id.value.unpack(bref)); break; - case 46: + } + case 46: { nof_mandatory_ies--; - nrp_pa_pdu.id = c.id; - nrp_pa_pdu.crit = c.crit; - nrp_pa_pdu.value = c.value.nrp_pa_pdu(); + nrp_pa_pdu.id = id; + HANDLE_CODE(nrp_pa_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrp_pa_pdu.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -44272,30 +42978,7 @@ void ul_non_ueassociated_nrp_pa_transport_ies_container::to_json(json_writer& j) j.end_obj(); } -// UplinkNonUEAssociatedNRPPaTransport ::= SEQUENCE -SRSASN_CODE ul_non_ueassociated_nrp_pa_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ul_non_ueassociated_nrp_pa_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ul_non_ueassociated_nrp_pa_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ul_ran_cfg_transfer_ies_container::ul_ran_cfg_transfer_ies_container() : son_cfg_transfer_ul(99, crit_e::ignore), endc_son_cfg_transfer_ul(158, crit_e::ignore) @@ -44322,23 +43005,27 @@ SRSASN_CODE ul_ran_cfg_transfer_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 99: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 99: { son_cfg_transfer_ul_present = true; - son_cfg_transfer_ul.id = c.id; - son_cfg_transfer_ul.crit = c.crit; - son_cfg_transfer_ul.value = c.value.son_cfg_transfer_ul(); + son_cfg_transfer_ul.id = id; + HANDLE_CODE(son_cfg_transfer_ul.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(son_cfg_transfer_ul.value.unpack(bref)); break; - case 158: + } + case 158: { endc_son_cfg_transfer_ul_present = true; - endc_son_cfg_transfer_ul.id = c.id; - endc_son_cfg_transfer_ul.crit = c.crit; - endc_son_cfg_transfer_ul.value = c.value.endc_son_cfg_transfer_ul(); + endc_son_cfg_transfer_ul.id = id; + HANDLE_CODE(endc_son_cfg_transfer_ul.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(endc_son_cfg_transfer_ul.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -44359,30 +43046,7 @@ void ul_ran_cfg_transfer_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UplinkRANConfigurationTransfer ::= SEQUENCE -SRSASN_CODE ul_ran_cfg_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ul_ran_cfg_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ul_ran_cfg_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ul_ran_status_transfer_ies_container::ul_ran_status_transfer_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -44408,29 +43072,35 @@ SRSASN_CODE ul_ran_status_transfer_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 84: + } + case 84: { nof_mandatory_ies--; - ran_status_transfer_transparent_container.id = c.id; - ran_status_transfer_transparent_container.crit = c.crit; - ran_status_transfer_transparent_container.value = c.value.ran_status_transfer_transparent_container(); + ran_status_transfer_transparent_container.id = id; + HANDLE_CODE(ran_status_transfer_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_status_transfer_transparent_container.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -44453,30 +43123,7 @@ void ul_ran_status_transfer_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UplinkRANStatusTransfer ::= SEQUENCE -SRSASN_CODE ul_ran_status_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ul_ran_status_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ul_ran_status_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ul_ueassociated_nrp_pa_transport_ies_container::ul_ueassociated_nrp_pa_transport_ies_container() : amf_ue_ngap_id(10, crit_e::reject), @@ -44504,35 +43151,43 @@ SRSASN_CODE ul_ueassociated_nrp_pa_transport_ies_container::unpack(cbit_ref& bre uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 10: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 10: { nof_mandatory_ies--; - amf_ue_ngap_id.id = c.id; - amf_ue_ngap_id.crit = c.crit; - amf_ue_ngap_id.value = c.value.amf_ue_ngap_id(); + amf_ue_ngap_id.id = id; + HANDLE_CODE(amf_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(amf_ue_ngap_id.value.unpack(bref)); break; - case 85: + } + case 85: { nof_mandatory_ies--; - ran_ue_ngap_id.id = c.id; - ran_ue_ngap_id.crit = c.crit; - ran_ue_ngap_id.value = c.value.ran_ue_ngap_id(); + ran_ue_ngap_id.id = id; + HANDLE_CODE(ran_ue_ngap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ran_ue_ngap_id.value.unpack(bref)); break; - case 89: + } + case 89: { nof_mandatory_ies--; - routing_id.id = c.id; - routing_id.crit = c.crit; - routing_id.value = c.value.routing_id(); + routing_id.id = id; + HANDLE_CODE(routing_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(routing_id.value.unpack(bref)); break; - case 46: + } + case 46: { nof_mandatory_ies--; - nrp_pa_pdu.id = c.id; - nrp_pa_pdu.crit = c.crit; - nrp_pa_pdu.value = c.value.nrp_pa_pdu(); + nrp_pa_pdu.id = id; + HANDLE_CODE(nrp_pa_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrp_pa_pdu.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -44557,30 +43212,7 @@ void ul_ueassociated_nrp_pa_transport_ies_container::to_json(json_writer& j) con j.end_obj(); } -// UplinkUEAssociatedNRPPaTransport ::= SEQUENCE -SRSASN_CODE ul_ueassociated_nrp_pa_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ul_ueassociated_nrp_pa_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ul_ueassociated_nrp_pa_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; write_replace_warning_request_ies_container::write_replace_warning_request_ies_container() : msg_id(35, crit_e::reject), @@ -44643,77 +43275,99 @@ SRSASN_CODE write_replace_warning_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 35: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 35: { nof_mandatory_ies--; - msg_id.id = c.id; - msg_id.crit = c.crit; - msg_id.value = c.value.msg_id(); + msg_id.id = id; + HANDLE_CODE(msg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(msg_id.value.unpack(bref)); break; - case 95: + } + case 95: { nof_mandatory_ies--; - serial_num.id = c.id; - serial_num.crit = c.crit; - serial_num.value = c.value.serial_num(); + serial_num.id = id; + HANDLE_CODE(serial_num.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(serial_num.value.unpack(bref)); break; - case 122: + } + case 122: { warning_area_list_present = true; - warning_area_list.id = c.id; - warning_area_list.crit = c.crit; - warning_area_list.value = c.value.warning_area_list(); + warning_area_list.id = id; + HANDLE_CODE(warning_area_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_area_list.value.unpack(bref)); break; - case 87: + } + case 87: { nof_mandatory_ies--; - repeat_period.id = c.id; - repeat_period.crit = c.crit; - repeat_period.value = c.value.repeat_period(); + repeat_period.id = id; + HANDLE_CODE(repeat_period.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(repeat_period.value.unpack(bref)); break; - case 47: + } + case 47: { nof_mandatory_ies--; - nof_broadcasts_requested.id = c.id; - nof_broadcasts_requested.crit = c.crit; - nof_broadcasts_requested.value = c.value.nof_broadcasts_requested(); + nof_broadcasts_requested.id = id; + HANDLE_CODE(nof_broadcasts_requested.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nof_broadcasts_requested.value.unpack(bref)); break; - case 125: + } + case 125: { warning_type_present = true; - warning_type.id = c.id; - warning_type.crit = c.crit; - warning_type.value = c.value.warning_type(); + warning_type.id = id; + HANDLE_CODE(warning_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_type.value.unpack(bref)); break; - case 124: + } + case 124: { warning_security_info_present = true; - warning_security_info.id = c.id; - warning_security_info.crit = c.crit; - warning_security_info.value = c.value.warning_security_info(); + warning_security_info.id = id; + HANDLE_CODE(warning_security_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_security_info.value.unpack(bref)); break; - case 20: + } + case 20: { data_coding_scheme_present = true; - data_coding_scheme.id = c.id; - data_coding_scheme.crit = c.crit; - data_coding_scheme.value = c.value.data_coding_scheme(); + data_coding_scheme.id = id; + HANDLE_CODE(data_coding_scheme.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(data_coding_scheme.value.unpack(bref)); break; - case 123: + } + case 123: { warning_msg_contents_present = true; - warning_msg_contents.id = c.id; - warning_msg_contents.crit = c.crit; - warning_msg_contents.value = c.value.warning_msg_contents(); + warning_msg_contents.id = id; + HANDLE_CODE(warning_msg_contents.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_msg_contents.value.unpack(bref)); break; - case 17: + } + case 17: { concurrent_warning_msg_ind_present = true; - concurrent_warning_msg_ind.id = c.id; - concurrent_warning_msg_ind.crit = c.crit; - concurrent_warning_msg_ind.value = c.value.concurrent_warning_msg_ind(); + concurrent_warning_msg_ind.id = id; + HANDLE_CODE(concurrent_warning_msg_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(concurrent_warning_msg_ind.value.unpack(bref)); break; - case 141: + } + case 141: { warning_area_coordinates_present = true; - warning_area_coordinates.id = c.id; - warning_area_coordinates.crit = c.crit; - warning_area_coordinates.value = c.value.warning_area_coordinates(); + warning_area_coordinates.id = id; + HANDLE_CODE(warning_area_coordinates.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_area_coordinates.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -44766,30 +43420,7 @@ void write_replace_warning_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// WriteReplaceWarningRequest ::= SEQUENCE -SRSASN_CODE write_replace_warning_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE write_replace_warning_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void write_replace_warning_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; write_replace_warning_resp_ies_container::write_replace_warning_resp_ies_container() : msg_id(35, crit_e::reject), @@ -44823,35 +43454,43 @@ SRSASN_CODE write_replace_warning_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 35: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 35: { nof_mandatory_ies--; - msg_id.id = c.id; - msg_id.crit = c.crit; - msg_id.value = c.value.msg_id(); + msg_id.id = id; + HANDLE_CODE(msg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(msg_id.value.unpack(bref)); break; - case 95: + } + case 95: { nof_mandatory_ies--; - serial_num.id = c.id; - serial_num.crit = c.crit; - serial_num.value = c.value.serial_num(); + serial_num.id = id; + HANDLE_CODE(serial_num.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(serial_num.value.unpack(bref)); break; - case 13: + } + case 13: { broadcast_completed_area_list_present = true; - broadcast_completed_area_list.id = c.id; - broadcast_completed_area_list.crit = c.crit; - broadcast_completed_area_list.value = c.value.broadcast_completed_area_list(); + broadcast_completed_area_list.id = id; + HANDLE_CODE(broadcast_completed_area_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(broadcast_completed_area_list.value.unpack(bref)); break; - case 19: + } + case 19: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -44880,29 +43519,6 @@ void write_replace_warning_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// WriteReplaceWarningResponse ::= SEQUENCE -SRSASN_CODE write_replace_warning_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE write_replace_warning_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void write_replace_warning_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // NGAP-ELEMENTARY-PROCEDURES ::= OBJECT SET OF NGAP-ELEMENTARY-PROCEDURE uint16_t ngap_elem_procs_o::idx_to_proc_code(uint32_t idx) { @@ -48914,12 +47530,12 @@ void qos_flow_info_item_s::to_json(json_writer& j) const SRSASN_CODE pdu_session_res_info_item_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(drbs_to_qos_flows_map_list_present, 1)); + HANDLE_CODE(bref.pack(drbs_to_qos_flows_map_list.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); HANDLE_CODE(pack_integer(bref, pdu_session_id, (uint16_t)0u, (uint16_t)255u, false, true)); HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_info_list, 1, 64, true)); - if (drbs_to_qos_flows_map_list_present) { + if (drbs_to_qos_flows_map_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, drbs_to_qos_flows_map_list, 1, 32, true)); } if (ie_exts_present) { @@ -48931,6 +47547,7 @@ SRSASN_CODE pdu_session_res_info_item_s::pack(bit_ref& bref) const SRSASN_CODE pdu_session_res_info_item_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool drbs_to_qos_flows_map_list_present; HANDLE_CODE(bref.unpack(drbs_to_qos_flows_map_list_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -48954,7 +47571,7 @@ void pdu_session_res_info_item_s::to_json(json_writer& j) const e1.to_json(j); } j.end_array(); - if (drbs_to_qos_flows_map_list_present) { + if (drbs_to_qos_flows_map_list.size() > 0) { j.start_array("dRBsToQosFlowsMappingList"); for (const auto& e1 : drbs_to_qos_flows_map_list) { e1.to_json(j); @@ -49049,16 +47666,16 @@ void up_transport_layer_info_pair_item_s::to_json(json_writer& j) const SRSASN_CODE pdu_session_res_modify_confirm_transfer_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(add_ng_uuptnl_info_present, 1)); - HANDLE_CODE(bref.pack(qos_flow_failed_to_modify_list_present, 1)); + HANDLE_CODE(bref.pack(add_ng_uuptnl_info.size() > 0, 1)); + HANDLE_CODE(bref.pack(qos_flow_failed_to_modify_list.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_modify_confirm_list, 1, 64, true)); HANDLE_CODE(ulngu_up_tnl_info.pack(bref)); - if (add_ng_uuptnl_info_present) { + if (add_ng_uuptnl_info.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, add_ng_uuptnl_info, 1, 3, true)); } - if (qos_flow_failed_to_modify_list_present) { + if (qos_flow_failed_to_modify_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_failed_to_modify_list, 1, 64, true)); } if (ie_exts_present) { @@ -49070,7 +47687,9 @@ SRSASN_CODE pdu_session_res_modify_confirm_transfer_s::pack(bit_ref& bref) const SRSASN_CODE pdu_session_res_modify_confirm_transfer_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool add_ng_uuptnl_info_present; HANDLE_CODE(bref.unpack(add_ng_uuptnl_info_present, 1)); + bool qos_flow_failed_to_modify_list_present; HANDLE_CODE(bref.unpack(qos_flow_failed_to_modify_list_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -49098,14 +47717,14 @@ void pdu_session_res_modify_confirm_transfer_s::to_json(json_writer& j) const j.end_array(); j.write_fieldname("uLNGU-UP-TNLInformation"); ulngu_up_tnl_info.to_json(j); - if (add_ng_uuptnl_info_present) { + if (add_ng_uuptnl_info.size() > 0) { j.start_array("additionalNG-UUPTNLInformation"); for (const auto& e1 : add_ng_uuptnl_info) { e1.to_json(j); } j.end_array(); } - if (qos_flow_failed_to_modify_list_present) { + if (qos_flow_failed_to_modify_list.size() > 0) { j.start_array("qosFlowFailedToModifyList"); for (const auto& e1 : qos_flow_failed_to_modify_list) { e1.to_json(j); @@ -49270,13 +47889,13 @@ SRSASN_CODE secondary_ratusage_info_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(pdu_session_usage_report_present, 1)); - HANDLE_CODE(bref.pack(qos_flows_usage_report_list_present, 1)); + HANDLE_CODE(bref.pack(qos_flows_usage_report_list.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_ext_present, 1)); if (pdu_session_usage_report_present) { HANDLE_CODE(pdu_session_usage_report.pack(bref)); } - if (qos_flows_usage_report_list_present) { + if (qos_flows_usage_report_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, qos_flows_usage_report_list, 1, 64, true)); } if (ie_ext_present) { @@ -49289,6 +47908,7 @@ SRSASN_CODE secondary_ratusage_info_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(pdu_session_usage_report_present, 1)); + bool qos_flows_usage_report_list_present; HANDLE_CODE(bref.unpack(qos_flows_usage_report_list_present, 1)); HANDLE_CODE(bref.unpack(ie_ext_present, 1)); @@ -49311,7 +47931,7 @@ void secondary_ratusage_info_s::to_json(json_writer& j) const j.write_fieldname("pDUSessionUsageReport"); pdu_session_usage_report.to_json(j); } - if (qos_flows_usage_report_list_present) { + if (qos_flows_usage_report_list.size() > 0) { j.start_array("qosFlowsUsageReportList"); for (const auto& e1 : qos_flows_usage_report_list) { e1.to_json(j); @@ -49528,7 +48148,7 @@ const char* pdu_session_res_modify_ind_transfer_ext_ies_o::ext_c::types_opts::to return convert_enum_idx(options, 2, value, "pdu_session_res_modify_ind_transfer_ext_ies_o::ext_c::types"); } -template struct asn1::ngap_nr::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; pdu_session_res_modify_ind_transfer_ext_ies_container::pdu_session_res_modify_ind_transfer_ext_ies_container() : secondary_ratusage_info(144, crit_e::ignore), security_result(156, crit_e::ignore) @@ -49555,23 +48175,27 @@ SRSASN_CODE pdu_session_res_modify_ind_transfer_ext_ies_container::unpack(cbit_r unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 144: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 144: { secondary_ratusage_info_present = true; - secondary_ratusage_info.id = c.id; - secondary_ratusage_info.crit = c.crit; - secondary_ratusage_info.ext = c.ext_value.secondary_ratusage_info(); + secondary_ratusage_info.id = id; + HANDLE_CODE(secondary_ratusage_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(secondary_ratusage_info.ext.unpack(bref)); break; - case 156: + } + case 156: { security_result_present = true; - security_result.id = c.id; - security_result.crit = c.crit; - security_result.ext = c.ext_value.security_result(); + security_result.id = id; + HANDLE_CODE(security_result.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_result.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -49596,11 +48220,11 @@ void pdu_session_res_modify_ind_transfer_ext_ies_container::to_json(json_writer& SRSASN_CODE pdu_session_res_modify_ind_transfer_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(add_dl_qos_flow_per_tnl_info_present, 1)); + HANDLE_CODE(bref.pack(add_dl_qos_flow_per_tnl_info.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); HANDLE_CODE(dlqos_flow_per_tnl_info.pack(bref)); - if (add_dl_qos_flow_per_tnl_info_present) { + if (add_dl_qos_flow_per_tnl_info.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, add_dl_qos_flow_per_tnl_info, 1, 3, true)); } if (ie_exts_present) { @@ -49612,6 +48236,7 @@ SRSASN_CODE pdu_session_res_modify_ind_transfer_s::pack(bit_ref& bref) const SRSASN_CODE pdu_session_res_modify_ind_transfer_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool add_dl_qos_flow_per_tnl_info_present; HANDLE_CODE(bref.unpack(add_dl_qos_flow_per_tnl_info_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -49630,7 +48255,7 @@ void pdu_session_res_modify_ind_transfer_s::to_json(json_writer& j) const j.start_obj(); j.write_fieldname("dLQosFlowPerTNLInformation"); dlqos_flow_per_tnl_info.to_json(j); - if (add_dl_qos_flow_per_tnl_info_present) { + if (add_dl_qos_flow_per_tnl_info.size() > 0) { j.start_array("additionalDLQosFlowPerTNLInformation"); for (const auto& e1 : add_dl_qos_flow_per_tnl_info) { e1.to_json(j); @@ -50457,7 +49082,7 @@ uint8_t pdu_session_res_modify_request_transfer_ies_o::value_c::types_opts::to_n return 0; } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pdu_session_res_modify_request_transfer_ies_container::pdu_session_res_modify_request_transfer_ies_container() : pdu_session_aggregate_maximum_bit_rate(130, crit_e::reject), @@ -50505,47 +49130,59 @@ SRSASN_CODE pdu_session_res_modify_request_transfer_ies_container::unpack(cbit_r unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 130: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 130: { pdu_session_aggregate_maximum_bit_rate_present = true; - pdu_session_aggregate_maximum_bit_rate.id = c.id; - pdu_session_aggregate_maximum_bit_rate.crit = c.crit; - pdu_session_aggregate_maximum_bit_rate.value = c.value.pdu_session_aggregate_maximum_bit_rate(); + pdu_session_aggregate_maximum_bit_rate.id = id; + HANDLE_CODE(pdu_session_aggregate_maximum_bit_rate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_aggregate_maximum_bit_rate.value.unpack(bref)); break; - case 140: + } + case 140: { ul_ngu_up_tnl_modify_list_present = true; - ul_ngu_up_tnl_modify_list.id = c.id; - ul_ngu_up_tnl_modify_list.crit = c.crit; - ul_ngu_up_tnl_modify_list.value = c.value.ul_ngu_up_tnl_modify_list(); + ul_ngu_up_tnl_modify_list.id = id; + HANDLE_CODE(ul_ngu_up_tnl_modify_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ul_ngu_up_tnl_modify_list.value.unpack(bref)); break; - case 129: + } + case 129: { network_instance_present = true; - network_instance.id = c.id; - network_instance.crit = c.crit; - network_instance.value = c.value.network_instance(); + network_instance.id = id; + HANDLE_CODE(network_instance.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(network_instance.value.unpack(bref)); break; - case 135: + } + case 135: { qos_flow_add_or_modify_request_list_present = true; - qos_flow_add_or_modify_request_list.id = c.id; - qos_flow_add_or_modify_request_list.crit = c.crit; - qos_flow_add_or_modify_request_list.value = c.value.qos_flow_add_or_modify_request_list(); + qos_flow_add_or_modify_request_list.id = id; + HANDLE_CODE(qos_flow_add_or_modify_request_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(qos_flow_add_or_modify_request_list.value.unpack(bref)); break; - case 137: + } + case 137: { qos_flow_to_release_list_present = true; - qos_flow_to_release_list.id = c.id; - qos_flow_to_release_list.crit = c.crit; - qos_flow_to_release_list.value = c.value.qos_flow_to_release_list(); + qos_flow_to_release_list.id = id; + HANDLE_CODE(qos_flow_to_release_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(qos_flow_to_release_list.value.unpack(bref)); break; - case 126: + } + case 126: { add_ul_ngu_up_tnl_info_present = true; - add_ul_ngu_up_tnl_info.id = c.id; - add_ul_ngu_up_tnl_info.crit = c.crit; - add_ul_ngu_up_tnl_info.value = c.value.add_ul_ngu_up_tnl_info(); + add_ul_ngu_up_tnl_info.id = id; + HANDLE_CODE(add_ul_ngu_up_tnl_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(add_ul_ngu_up_tnl_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -50582,29 +49219,6 @@ void pdu_session_res_modify_request_transfer_ies_container::to_json(json_writer& j.end_obj(); } -// PDUSessionResourceModifyRequestTransfer ::= SEQUENCE -SRSASN_CODE pdu_session_res_modify_request_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pdu_session_res_modify_request_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pdu_session_res_modify_request_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // QosFlowAddOrModifyResponseItem ::= SEQUENCE SRSASN_CODE qos_flow_add_or_modify_resp_item_s::pack(bit_ref& bref) const { @@ -50713,10 +49327,10 @@ SRSASN_CODE pdu_session_res_modify_resp_transfer_s::pack(bit_ref& bref) const bref.pack(ext, 1); HANDLE_CODE(bref.pack(dl_ngu_up_tnl_info_present, 1)); HANDLE_CODE(bref.pack(ul_ngu_up_tnl_info_present, 1)); - HANDLE_CODE(bref.pack(qos_flow_add_or_modify_resp_list_present, 1)); - HANDLE_CODE(bref.pack(add_dl_qos_flow_per_tnl_info_present, 1)); - HANDLE_CODE(bref.pack(qos_flow_failed_to_add_or_modify_list_present, 1)); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(qos_flow_add_or_modify_resp_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(add_dl_qos_flow_per_tnl_info.size() > 0, 1)); + HANDLE_CODE(bref.pack(qos_flow_failed_to_add_or_modify_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); if (dl_ngu_up_tnl_info_present) { HANDLE_CODE(dl_ngu_up_tnl_info.pack(bref)); @@ -50724,16 +49338,16 @@ SRSASN_CODE pdu_session_res_modify_resp_transfer_s::pack(bit_ref& bref) const if (ul_ngu_up_tnl_info_present) { HANDLE_CODE(ul_ngu_up_tnl_info.pack(bref)); } - if (qos_flow_add_or_modify_resp_list_present) { + if (qos_flow_add_or_modify_resp_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_add_or_modify_resp_list, 1, 64, true)); } - if (add_dl_qos_flow_per_tnl_info_present) { + if (add_dl_qos_flow_per_tnl_info.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, add_dl_qos_flow_per_tnl_info, 1, 3, true)); } - if (qos_flow_failed_to_add_or_modify_list_present) { + if (qos_flow_failed_to_add_or_modify_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_failed_to_add_or_modify_list, 1, 64, true)); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -50744,9 +49358,13 @@ SRSASN_CODE pdu_session_res_modify_resp_transfer_s::unpack(cbit_ref& bref) bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(dl_ngu_up_tnl_info_present, 1)); HANDLE_CODE(bref.unpack(ul_ngu_up_tnl_info_present, 1)); + bool qos_flow_add_or_modify_resp_list_present; HANDLE_CODE(bref.unpack(qos_flow_add_or_modify_resp_list_present, 1)); + bool add_dl_qos_flow_per_tnl_info_present; HANDLE_CODE(bref.unpack(add_dl_qos_flow_per_tnl_info_present, 1)); + bool qos_flow_failed_to_add_or_modify_list_present; HANDLE_CODE(bref.unpack(qos_flow_failed_to_add_or_modify_list_present, 1)); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); if (dl_ngu_up_tnl_info_present) { @@ -50781,28 +49399,28 @@ void pdu_session_res_modify_resp_transfer_s::to_json(json_writer& j) const j.write_fieldname("uL-NGU-UP-TNLInformation"); ul_ngu_up_tnl_info.to_json(j); } - if (qos_flow_add_or_modify_resp_list_present) { + if (qos_flow_add_or_modify_resp_list.size() > 0) { j.start_array("qosFlowAddOrModifyResponseList"); for (const auto& e1 : qos_flow_add_or_modify_resp_list) { e1.to_json(j); } j.end_array(); } - if (add_dl_qos_flow_per_tnl_info_present) { + if (add_dl_qos_flow_per_tnl_info.size() > 0) { j.start_array("additionalDLQosFlowPerTNLInformation"); for (const auto& e1 : add_dl_qos_flow_per_tnl_info) { e1.to_json(j); } j.end_array(); } - if (qos_flow_failed_to_add_or_modify_list_present) { + if (qos_flow_failed_to_add_or_modify_list.size() > 0) { j.start_array("qosFlowFailedToAddOrModifyList"); for (const auto& e1 : qos_flow_failed_to_add_or_modify_list) { e1.to_json(j); } j.end_array(); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -50924,10 +49542,10 @@ const char* pdu_session_res_notify_released_transfer_ext_ies_o::ext_c::types_opt SRSASN_CODE pdu_session_res_notify_released_transfer_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); HANDLE_CODE(cause.pack(bref)); - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -50936,6 +49554,7 @@ SRSASN_CODE pdu_session_res_notify_released_transfer_s::pack(bit_ref& bref) cons SRSASN_CODE pdu_session_res_notify_released_transfer_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); HANDLE_CODE(cause.unpack(bref)); @@ -50950,7 +49569,7 @@ void pdu_session_res_notify_released_transfer_s::to_json(json_writer& j) const j.start_obj(); j.write_fieldname("cause"); cause.to_json(j); - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -51068,17 +49687,17 @@ const char* pdu_session_res_notify_transfer_ext_ies_o::ext_c::types_opts::to_str SRSASN_CODE pdu_session_res_notify_transfer_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(qos_flow_notify_list_present, 1)); - HANDLE_CODE(bref.pack(qos_flow_released_list_present, 1)); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(qos_flow_notify_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(qos_flow_released_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); - if (qos_flow_notify_list_present) { + if (qos_flow_notify_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_notify_list, 1, 64, true)); } - if (qos_flow_released_list_present) { + if (qos_flow_released_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_released_list, 1, 64, true)); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -51087,8 +49706,11 @@ SRSASN_CODE pdu_session_res_notify_transfer_s::pack(bit_ref& bref) const SRSASN_CODE pdu_session_res_notify_transfer_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool qos_flow_notify_list_present; HANDLE_CODE(bref.unpack(qos_flow_notify_list_present, 1)); + bool qos_flow_released_list_present; HANDLE_CODE(bref.unpack(qos_flow_released_list_present, 1)); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); if (qos_flow_notify_list_present) { @@ -51106,21 +49728,21 @@ SRSASN_CODE pdu_session_res_notify_transfer_s::unpack(cbit_ref& bref) void pdu_session_res_notify_transfer_s::to_json(json_writer& j) const { j.start_obj(); - if (qos_flow_notify_list_present) { + if (qos_flow_notify_list.size() > 0) { j.start_array("qosFlowNotifyList"); for (const auto& e1 : qos_flow_notify_list) { e1.to_json(j); } j.end_array(); } - if (qos_flow_released_list_present) { + if (qos_flow_released_list.size() > 0) { j.start_array("qosFlowReleasedList"); for (const auto& e1 : qos_flow_released_list) { e1.to_json(j); } j.end_array(); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -51230,9 +49852,9 @@ const char* pdu_session_res_release_resp_transfer_ext_ies_o::ext_c::types_opts:: SRSASN_CODE pdu_session_res_release_resp_transfer_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -51241,6 +49863,7 @@ SRSASN_CODE pdu_session_res_release_resp_transfer_s::pack(bit_ref& bref) const SRSASN_CODE pdu_session_res_release_resp_transfer_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); if (ie_exts_present) { @@ -51252,7 +49875,7 @@ SRSASN_CODE pdu_session_res_release_resp_transfer_s::unpack(cbit_ref& bref) void pdu_session_res_release_resp_transfer_s::to_json(json_writer& j) const { j.start_obj(); - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -51415,14 +50038,14 @@ SRSASN_CODE security_ind_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(maximum_integrity_protected_data_rate_ul_present, 1)); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); HANDLE_CODE(integrity_protection_ind.pack(bref)); HANDLE_CODE(confidentiality_protection_ind.pack(bref)); if (maximum_integrity_protected_data_rate_ul_present) { HANDLE_CODE(maximum_integrity_protected_data_rate_ul.pack(bref)); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -51432,6 +50055,7 @@ SRSASN_CODE security_ind_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(maximum_integrity_protected_data_rate_ul_present, 1)); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); HANDLE_CODE(integrity_protection_ind.unpack(bref)); @@ -51453,7 +50077,7 @@ void security_ind_s::to_json(json_writer& j) const if (maximum_integrity_protected_data_rate_ul_present) { j.write_str("maximumIntegrityProtectedDataRate-UL", maximum_integrity_protected_data_rate_ul.to_string()); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -51907,7 +50531,7 @@ uint8_t pdu_session_res_setup_request_transfer_ies_o::value_c::types_opts::to_nu return 0; } -template struct asn1::ngap_nr::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pdu_session_res_setup_request_transfer_ies_container::pdu_session_res_setup_request_transfer_ies_container() : pdu_session_aggregate_maximum_bit_rate(130, crit_e::reject), @@ -51958,59 +50582,75 @@ SRSASN_CODE pdu_session_res_setup_request_transfer_ies_container::unpack(cbit_re uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 130: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 130: { pdu_session_aggregate_maximum_bit_rate_present = true; - pdu_session_aggregate_maximum_bit_rate.id = c.id; - pdu_session_aggregate_maximum_bit_rate.crit = c.crit; - pdu_session_aggregate_maximum_bit_rate.value = c.value.pdu_session_aggregate_maximum_bit_rate(); + pdu_session_aggregate_maximum_bit_rate.id = id; + HANDLE_CODE(pdu_session_aggregate_maximum_bit_rate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_aggregate_maximum_bit_rate.value.unpack(bref)); break; - case 139: + } + case 139: { nof_mandatory_ies--; - ul_ngu_up_tnl_info.id = c.id; - ul_ngu_up_tnl_info.crit = c.crit; - ul_ngu_up_tnl_info.value = c.value.ul_ngu_up_tnl_info(); + ul_ngu_up_tnl_info.id = id; + HANDLE_CODE(ul_ngu_up_tnl_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ul_ngu_up_tnl_info.value.unpack(bref)); break; - case 126: + } + case 126: { add_ul_ngu_up_tnl_info_present = true; - add_ul_ngu_up_tnl_info.id = c.id; - add_ul_ngu_up_tnl_info.crit = c.crit; - add_ul_ngu_up_tnl_info.value = c.value.add_ul_ngu_up_tnl_info(); + add_ul_ngu_up_tnl_info.id = id; + HANDLE_CODE(add_ul_ngu_up_tnl_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(add_ul_ngu_up_tnl_info.value.unpack(bref)); break; - case 127: + } + case 127: { data_forwarding_not_possible_present = true; - data_forwarding_not_possible.id = c.id; - data_forwarding_not_possible.crit = c.crit; - data_forwarding_not_possible.value = c.value.data_forwarding_not_possible(); + data_forwarding_not_possible.id = id; + HANDLE_CODE(data_forwarding_not_possible.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(data_forwarding_not_possible.value.unpack(bref)); break; - case 134: + } + case 134: { nof_mandatory_ies--; - pdu_session_type.id = c.id; - pdu_session_type.crit = c.crit; - pdu_session_type.value = c.value.pdu_session_type(); + pdu_session_type.id = id; + HANDLE_CODE(pdu_session_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pdu_session_type.value.unpack(bref)); break; - case 138: + } + case 138: { security_ind_present = true; - security_ind.id = c.id; - security_ind.crit = c.crit; - security_ind.value = c.value.security_ind(); + security_ind.id = id; + HANDLE_CODE(security_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_ind.value.unpack(bref)); break; - case 129: + } + case 129: { network_instance_present = true; - network_instance.id = c.id; - network_instance.crit = c.crit; - network_instance.value = c.value.network_instance(); + network_instance.id = id; + HANDLE_CODE(network_instance.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(network_instance.value.unpack(bref)); break; - case 136: + } + case 136: { nof_mandatory_ies--; - qos_flow_setup_request_list.id = c.id; - qos_flow_setup_request_list.crit = c.crit; - qos_flow_setup_request_list.value = c.value.qos_flow_setup_request_list(); + qos_flow_setup_request_list.id = id; + HANDLE_CODE(qos_flow_setup_request_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(qos_flow_setup_request_list.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -52053,46 +50693,23 @@ void pdu_session_res_setup_request_transfer_ies_container::to_json(json_writer& j.end_obj(); } -// PDUSessionResourceSetupRequestTransfer ::= SEQUENCE -SRSASN_CODE pdu_session_res_setup_request_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pdu_session_res_setup_request_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pdu_session_res_setup_request_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // PDUSessionResourceSetupResponseTransfer ::= SEQUENCE SRSASN_CODE pdu_session_res_setup_resp_transfer_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(add_dl_qos_flow_per_tnl_info_present, 1)); + HANDLE_CODE(bref.pack(add_dl_qos_flow_per_tnl_info.size() > 0, 1)); HANDLE_CODE(bref.pack(security_result_present, 1)); - HANDLE_CODE(bref.pack(qos_flow_failed_to_setup_list_present, 1)); + HANDLE_CODE(bref.pack(qos_flow_failed_to_setup_list.size() > 0, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); HANDLE_CODE(dlqos_flow_per_tnl_info.pack(bref)); - if (add_dl_qos_flow_per_tnl_info_present) { + if (add_dl_qos_flow_per_tnl_info.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, add_dl_qos_flow_per_tnl_info, 1, 3, true)); } if (security_result_present) { HANDLE_CODE(security_result.pack(bref)); } - if (qos_flow_failed_to_setup_list_present) { + if (qos_flow_failed_to_setup_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_failed_to_setup_list, 1, 64, true)); } if (ie_exts_present) { @@ -52104,8 +50721,10 @@ SRSASN_CODE pdu_session_res_setup_resp_transfer_s::pack(bit_ref& bref) const SRSASN_CODE pdu_session_res_setup_resp_transfer_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool add_dl_qos_flow_per_tnl_info_present; HANDLE_CODE(bref.unpack(add_dl_qos_flow_per_tnl_info_present, 1)); HANDLE_CODE(bref.unpack(security_result_present, 1)); + bool qos_flow_failed_to_setup_list_present; HANDLE_CODE(bref.unpack(qos_flow_failed_to_setup_list_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -52130,7 +50749,7 @@ void pdu_session_res_setup_resp_transfer_s::to_json(json_writer& j) const j.start_obj(); j.write_fieldname("dLQosFlowPerTNLInformation"); dlqos_flow_per_tnl_info.to_json(j); - if (add_dl_qos_flow_per_tnl_info_present) { + if (add_dl_qos_flow_per_tnl_info.size() > 0) { j.start_array("additionalDLQosFlowPerTNLInformation"); for (const auto& e1 : add_dl_qos_flow_per_tnl_info) { e1.to_json(j); @@ -52141,7 +50760,7 @@ void pdu_session_res_setup_resp_transfer_s::to_json(json_writer& j) const j.write_fieldname("securityResult"); security_result.to_json(j); } - if (qos_flow_failed_to_setup_list_present) { + if (qos_flow_failed_to_setup_list.size() > 0) { j.start_array("qosFlowFailedToSetupList"); for (const auto& e1 : qos_flow_failed_to_setup_list) { e1.to_json(j); @@ -52276,7 +50895,7 @@ SRSASN_CODE path_switch_request_ack_transfer_s::pack(bit_ref& bref) const bref.pack(ext, 1); HANDLE_CODE(bref.pack(ul_ngu_up_tnl_info_present, 1)); HANDLE_CODE(bref.pack(security_ind_present, 1)); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); if (ul_ngu_up_tnl_info_present) { HANDLE_CODE(ul_ngu_up_tnl_info.pack(bref)); @@ -52284,7 +50903,7 @@ SRSASN_CODE path_switch_request_ack_transfer_s::pack(bit_ref& bref) const if (security_ind_present) { HANDLE_CODE(security_ind.pack(bref)); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -52295,6 +50914,7 @@ SRSASN_CODE path_switch_request_ack_transfer_s::unpack(cbit_ref& bref) bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(ul_ngu_up_tnl_info_present, 1)); HANDLE_CODE(bref.unpack(security_ind_present, 1)); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); if (ul_ngu_up_tnl_info_present) { @@ -52320,7 +50940,7 @@ void path_switch_request_ack_transfer_s::to_json(json_writer& j) const j.write_fieldname("securityIndication"); security_ind.to_json(j); } - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -52518,7 +51138,7 @@ SRSASN_CODE path_switch_request_transfer_s::pack(bit_ref& bref) const bref.pack(ext, 1); HANDLE_CODE(bref.pack(dl_ngu_tnl_info_reused_present, 1)); HANDLE_CODE(bref.pack(user_plane_security_info_present, 1)); - HANDLE_CODE(bref.pack(ie_exts_present, 1)); + HANDLE_CODE(bref.pack(ie_exts.size() > 0, 1)); HANDLE_CODE(dl_ngu_up_tnl_info.pack(bref)); if (dl_ngu_tnl_info_reused_present) { @@ -52528,7 +51148,7 @@ SRSASN_CODE path_switch_request_transfer_s::pack(bit_ref& bref) const HANDLE_CODE(user_plane_security_info.pack(bref)); } HANDLE_CODE(pack_dyn_seq_of(bref, qos_flow_accepted_list, 1, 64, true)); - if (ie_exts_present) { + if (ie_exts.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ie_exts, 1, 65535, true)); } @@ -52539,6 +51159,7 @@ SRSASN_CODE path_switch_request_transfer_s::unpack(cbit_ref& bref) bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(dl_ngu_tnl_info_reused_present, 1)); HANDLE_CODE(bref.unpack(user_plane_security_info_present, 1)); + bool ie_exts_present; HANDLE_CODE(bref.unpack(ie_exts_present, 1)); HANDLE_CODE(dl_ngu_up_tnl_info.unpack(bref)); @@ -52572,7 +51193,7 @@ void path_switch_request_transfer_s::to_json(json_writer& j) const e1.to_json(j); } j.end_array(); - if (ie_exts_present) { + if (ie_exts.size() > 0) { j.write_fieldname("iE-Extensions"); } j.end_obj(); @@ -52751,16 +51372,16 @@ void secondary_rat_data_usage_report_transfer_s::to_json(json_writer& j) const SRSASN_CODE source_ngran_node_to_target_ngran_node_transparent_container_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(pdu_session_res_info_list_present, 1)); - HANDLE_CODE(bref.pack(erab_info_list_present, 1)); + HANDLE_CODE(bref.pack(pdu_session_res_info_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(erab_info_list.size() > 0, 1)); HANDLE_CODE(bref.pack(idx_to_rfsp_present, 1)); HANDLE_CODE(bref.pack(ie_exts_present, 1)); HANDLE_CODE(rrc_container.pack(bref)); - if (pdu_session_res_info_list_present) { + if (pdu_session_res_info_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, pdu_session_res_info_list, 1, 256, true)); } - if (erab_info_list_present) { + if (erab_info_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, erab_info_list, 1, 256, true)); } HANDLE_CODE(target_cell_id.pack(bref)); @@ -52777,7 +51398,9 @@ SRSASN_CODE source_ngran_node_to_target_ngran_node_transparent_container_s::pack SRSASN_CODE source_ngran_node_to_target_ngran_node_transparent_container_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool pdu_session_res_info_list_present; HANDLE_CODE(bref.unpack(pdu_session_res_info_list_present, 1)); + bool erab_info_list_present; HANDLE_CODE(bref.unpack(erab_info_list_present, 1)); HANDLE_CODE(bref.unpack(idx_to_rfsp_present, 1)); HANDLE_CODE(bref.unpack(ie_exts_present, 1)); @@ -52804,14 +51427,14 @@ void source_ngran_node_to_target_ngran_node_transparent_container_s::to_json(jso { j.start_obj(); j.write_str("rRCContainer", rrc_container.to_string()); - if (pdu_session_res_info_list_present) { + if (pdu_session_res_info_list.size() > 0) { j.start_array("pDUSessionResourceInformationList"); for (const auto& e1 : pdu_session_res_info_list) { e1.to_json(j); } j.end_array(); } - if (erab_info_list_present) { + if (erab_info_list.size() > 0) { j.start_array("e-RABInformationList"); for (const auto& e1 : erab_info_list) { e1.to_json(j); diff --git a/lib/src/asn1/rrc.cc b/lib/src/asn1/rrc.cc index 150f5971f6..2edbea5528 100644 --- a/lib/src/asn1/rrc.cc +++ b/lib/src/asn1/rrc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,12 +29,19 @@ using namespace asn1::rrc; * Struct Methods ******************************************************************************/ +const char* mib_s::part_earfcn_minus17_c_::types_opts::to_string() const +{ + static const char* options[] = {"spare", "earfcn-LSB"}; + return convert_enum_idx(options, 2, value, "mib_s::part_earfcn_minus17_c_::types"); +} + // MasterInformationBlock-MBMS-r14 ::= SEQUENCE SRSASN_CODE mib_mbms_r14_s::pack(bit_ref& bref) const { HANDLE_CODE(dl_bw_mbms_r14.pack(bref)); HANDLE_CODE(sys_frame_num_r14.pack(bref)); HANDLE_CODE(pack_integer(bref, add_non_mbsfn_sfs_r14, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(pack_integer(bref, semi_static_cfi_mbms_r16, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; @@ -44,6 +51,7 @@ SRSASN_CODE mib_mbms_r14_s::unpack(cbit_ref& bref) HANDLE_CODE(dl_bw_mbms_r14.unpack(bref)); HANDLE_CODE(sys_frame_num_r14.unpack(bref)); HANDLE_CODE(unpack_integer(add_non_mbsfn_sfs_r14, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(unpack_integer(semi_static_cfi_mbms_r16, bref, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; @@ -54,6 +62,7 @@ void mib_mbms_r14_s::to_json(json_writer& j) const j.write_str("dl-Bandwidth-MBMS-r14", dl_bw_mbms_r14.to_string()); j.write_str("systemFrameNumber-r14", sys_frame_num_r14.to_string()); j.write_int("additionalNonMBSFNSubframes-r14", add_non_mbsfn_sfs_r14); + j.write_int("semiStaticCFI-MBMS-r16", semi_static_cfi_mbms_r16); j.write_str("spare", spare.to_string()); j.end_obj(); } @@ -170,6 +179,17 @@ sl_disc_res_pool_r12_s::tx_params_r12_s_::ue_sel_res_cfg_r12_s_::pool_sel_r12_c_ options, 2, value, "sl_disc_res_pool_r12_s::tx_params_r12_s_::ue_sel_res_cfg_r12_s_::pool_sel_r12_c_::types"); } +const char* mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::types_opts::to_string() const +{ + static const char* options[] = {"sf5-r15", "sf10-r15", "sf20-r15", "sf40-r15", "sf80-r15", "sf160-r15"}; + return convert_enum_idx(options, 6, value, "mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::types"); +} +uint8_t mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {5, 10, 20, 40, 80, 160}; + return map_enum_number(options, 6, value, "mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::types"); +} + const char* plmn_id_info2_r12_c::types_opts::to_string() const { static const char* options[] = {"plmn-Index-r12", "plmnIdentity-r12"}; @@ -183,6 +203,12 @@ const char* sl_disc_tx_res_inter_freq_r13_c::types_opts::to_string() const return convert_enum_idx(options, 4, value, "sl_disc_tx_res_inter_freq_r13_c::types"); } +const char* ssb_to_measure_r15_c::types_opts::to_string() const +{ + static const char* options[] = {"shortBitmap-r15", "mediumBitmap-r15", "longBitmap-r15"}; + return convert_enum_idx(options, 3, value, "ssb_to_measure_r15_c::types"); +} + const char* sib_type1_v1320_ies_s::freq_hop_params_dl_r13_s_::interv_dl_hop_cfg_common_mode_a_r13_c_::types_opts::to_string() const { @@ -217,15 +243,10 @@ const char* carrier_freqs_geran_s::following_arfcns_c_::types_opts::to_string() return convert_enum_idx(options, 3, value, "carrier_freqs_geran_s::following_arfcns_c_::types"); } -const char* mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::types_opts::to_string() const -{ - static const char* options[] = {"sf5-r15", "sf10-r15", "sf20-r15", "sf40-r15", "sf80-r15", "sf160-r15"}; - return convert_enum_idx(options, 6, value, "mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::types"); -} -uint8_t mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::types_opts::to_number() const +const char* gwus_res_cfg_r16_s::res_map_pattern_r16_c_::types_opts::to_string() const { - static const uint8_t options[] = {5, 10, 20, 40, 80, 160}; - return map_enum_number(options, 6, value, "mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::types"); + static const char* options[] = {"resourceLocationWithWUS", "resourceLocationWithoutWUS"}; + return convert_enum_idx(options, 2, value, "gwus_res_cfg_r16_s::res_map_pattern_r16_c_::types"); } const char* params_cdma2000_r11_s::sys_time_info_r11_c_::types_opts::to_string() const @@ -240,12 +261,6 @@ const char* sl_inter_freq_info_v2x_r14_s::add_spec_emission_v2x_r14_c_::types_op return convert_enum_idx(options, 2, value, "sl_inter_freq_info_v2x_r14_s::add_spec_emission_v2x_r14_c_::types"); } -const char* ssb_to_measure_r15_c::types_opts::to_string() const -{ - static const char* options[] = {"shortBitmap-r15", "mediumBitmap-r15", "longBitmap-r15"}; - return convert_enum_idx(options, 3, value, "ssb_to_measure_r15_c::types"); -} - const char* sib_type1_v1310_ies_s::bw_reduced_access_related_info_r13_s_::fdd_dl_or_tdd_sf_bitmap_br_r13_c_::types_opts::to_string() const @@ -321,6 +336,24 @@ const char* prach_cfg_sib_v1310_s::mpdcch_start_sf_css_ra_r13_c_::types_opts::to return convert_enum_idx(options, 2, value, "prach_cfg_sib_v1310_s::mpdcch_start_sf_css_ra_r13_c_::types"); } +const char* periodicity_start_pos_r16_c::types_opts::to_string() const +{ + static const char* options[] = {"periodicity10ms", + "periodicity20ms", + "periodicity40ms", + "periodicity80ms", + "periodicity160ms", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 8, value, "periodicity_start_pos_r16_c::types"); +} +uint8_t periodicity_start_pos_r16_c::types_opts::to_number() const +{ + static const uint8_t options[] = {10, 20, 40, 80, 160}; + return map_enum_number(options, 5, value, "periodicity_start_pos_r16_c::types"); +} + const char* sib8_per_plmn_r11_s::params_cdma2000_r11_c_::types_opts::to_string() const { static const char* options[] = {"explicitValue", "defaultValue"}; @@ -333,6 +366,52 @@ const char* uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::types_opts::t return convert_enum_idx(options, 2, value, "uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::types"); } +const char* applicable_disaster_info_r17_c::types_opts::to_string() const +{ + static const char* options[] = { + "noDisasterRoaming-r17", "disasterRelatedIndication-r17", "commonPLMNs-r17", "dedicatedPLMNs-r17"}; + return convert_enum_idx(options, 4, value, "applicable_disaster_info_r17_c::types"); +} + +const char* res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::types_opts::to_string() const +{ + static const char* options[] = { + "rbg-Bitmap1dot4", "rbg-Bitmap3", "rbg-Bitmap5", "rbg-Bitmap10", "rbg-Bitmap15", "rbg-Bitmap20"}; + return convert_enum_idx(options, 6, value, "res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::types"); +} +float res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::types_opts::to_number() const +{ + static const float options[] = {1.4, 3.0, 5.0, 10.0, 15.0, 20.0}; + return map_enum_number(options, 6, value, "res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::types"); +} +const char* res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::types_opts::to_number_string() const +{ + static const char* options[] = {"1.4", "3", "5", "10", "15", "20"}; + return convert_enum_idx(options, 6, value, "res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::types"); +} + +const char* res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::types_opts::to_string() const +{ + static const char* options[] = {"slotPattern10ms", "slotPattern40ms"}; + return convert_enum_idx(options, 2, value, "res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::types"); +} +uint8_t res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {10, 40}; + return map_enum_number(options, 2, value, "res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::types"); +} + +const char* res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::types_opts::to_string() const +{ + static const char* options[] = {"slotPattern10ms", "slotPattern40ms"}; + return convert_enum_idx(options, 2, value, "res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::types"); +} +uint8_t res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {10, 40}; + return map_enum_number(options, 2, value, "res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::types"); +} + const char* sc_mcch_sched_info_r14_s::sched_period_start_offset_scptm_r14_c_::types_opts::to_string() const { static const char* options[] = {"sf10", @@ -360,6 +439,12 @@ uint16_t sc_mcch_sched_info_r14_s::sched_period_start_offset_scptm_r14_c_::types return map_enum_number(options, 16, value, "sc_mcch_sched_info_r14_s::sched_period_start_offset_scptm_r14_c_::types"); } +const char* serving_satellite_info_r17_s::ephemeris_info_r17_c_::types_opts::to_string() const +{ + static const char* options[] = {"stateVectors", "orbitalParameters"}; + return convert_enum_idx(options, 2, value, "serving_satellite_info_r17_s::ephemeris_info_r17_c_::types"); +} + const char* sib_type14_r11_s::eab_param_r11_c_::types_opts::to_string() const { static const char* options[] = {"eab-Common-r11", "eab-PerPLMN-List-r11"}; @@ -382,27 +467,26 @@ const char* sib_type25_r15_s::uac_ac1_select_assist_info_r15_c_::types_opts::to_ const char* pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::types_opts::to_string() const { static const char* options[] = { - "posSib1-1-r15", "posSib1-2-r15", "posSib1-3-r15", "posSib1-4-r15", "posSib1-5-r15", "posSib1-6-r15", - "posSib1-7-r15", "posSib2-1-r15", "posSib2-2-r15", "posSib2-3-r15", "posSib2-4-r15", "posSib2-5-r15", - "posSib2-6-r15", "posSib2-7-r15", "posSib2-8-r15", "posSib2-9-r15", "posSib2-10-r15", "posSib2-11-r15", - "posSib2-12-r15", "posSib2-13-r15", "posSib2-14-r15", "posSib2-15-r15", "posSib2-16-r15", "posSib2-17-r15", - "posSib2-18-r15", "posSib2-19-r15", "posSib3-1-r15"}; - return convert_enum_idx(options, 27, value, "pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::types"); + "posSib1-1-r15", "posSib1-2-r15", "posSib1-3-r15", "posSib1-4-r15", "posSib1-5-r15", + "posSib1-6-r15", "posSib1-7-r15", "posSib2-1-r15", "posSib2-2-r15", "posSib2-3-r15", + "posSib2-4-r15", "posSib2-5-r15", "posSib2-6-r15", "posSib2-7-r15", "posSib2-8-r15", + "posSib2-9-r15", "posSib2-10-r15", "posSib2-11-r15", "posSib2-12-r15", "posSib2-13-r15", + "posSib2-14-r15", "posSib2-15-r15", "posSib2-16-r15", "posSib2-17-r15", "posSib2-18-r15", + "posSib2-19-r15", "posSib3-1-r15", "posSib1-8-v1610", "posSib2-20-v1610", "posSib2-21-v1610", + "posSib2-22-v1610", "posSib2-23-v1610", "posSib2-24-v1610", "posSib2-25-v1610", "posSib4-1-v1610", + "posSib5-1-v1610", "posSib1-9-v1700", "posSib1-10-v1700"}; + return convert_enum_idx(options, 38, value, "pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::types"); } const char* sys_info_r8_ies_s::sib_type_and_info_item_c_::types_opts::to_string() const { - static const char* options[] = {"sib2", "sib3", "sib4", "sib5", "sib6", - "sib7", "sib8", "sib9", "sib10", "sib11", - "sib12-v920", "sib13-v920", "sib14-v1130", "sib15-v1130", "sib16-v1130", - "sib17-v1250", "sib18-v1250", "sib19-v1250", "sib20-v1310", "sib21-v1430", - "sib24-v1530", "sib25-v1530", "sib26-v1530"}; - return convert_enum_idx(options, 23, value, "sib_info_item_c::types"); -} -uint8_t sib_info_item_c::types_opts::to_number() const -{ - static const uint8_t options[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 24, 25, 26}; - return map_enum_number(options, 23, value, "sib_info_item_c::types"); + static const char* options[] = {"sib2", "sib3", "sib4", "sib5", "sib6", + "sib7", "sib8", "sib9", "sib10", "sib11", + "sib12-v920", "sib13-v920", "sib14-v1130", "sib15-v1130", "sib16-v1130", + "sib17-v1250", "sib18-v1250", "sib19-v1250", "sib20-v1310", "sib21-v1430", + "sib24-v1530", "sib25-v1530", "sib26-v1530", "sib26a-v1610", "sib27-v1610", + "sib28-v1610", "sib29-v1610", "sib30-v1700", "sib31-v1700", "sib32-v1700"}; + return convert_enum_idx(options, 30, value, "sib_info_item_c::types"); } const char* sys_info_s::crit_exts_c_::crit_exts_future_r15_c_::types_opts::to_string() const @@ -1040,8 +1124,7 @@ const char* rr_cfg_ded_s::crs_intf_mitig_cfg_r15_c_::setup_c_::types_opts::to_st const char* redirected_carrier_info_r15_ies_c::types_opts::to_string() const { - static const char* options[] = { - "eutra-r15", "geran-r15", "utra-FDD-r15", "cdma2000-HRPD-r15", "cdma2000-1xRTT-r15", "utra-TDD-r15"}; + static const char* options[] = {"eutra", "geran", "utra-FDD", "cdma2000-HRPD", "cdma2000-1xRTT", "utra-TDD"}; return convert_enum_idx(options, 6, value, "redirected_carrier_info_r15_ies_c::types"); } @@ -1162,6 +1245,40 @@ const char* phys_cfg_ded_scell_r10_s::semi_static_cfi_cfg_r15_c_::setup_c_::type return convert_enum_idx(options, 2, value, "phys_cfg_ded_scell_r10_s::semi_static_cfi_cfg_r15_c_::setup_c_::types"); } +const char* thres_eutra_c::types_opts::to_string() const +{ + static const char* options[] = {"threshold-RSRP", "threshold-RSRQ"}; + return convert_enum_idx(options, 2, value, "thres_eutra_c::types"); +} + +const char* thres_nr_r15_c::types_opts::to_string() const +{ + static const char* options[] = {"nr-RSRP-r15", "nr-RSRQ-r15", "nr-SINR-r15"}; + return convert_enum_idx(options, 3, value, "thres_nr_r15_c::types"); +} + +const char* cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::types_opts::to_string() const +{ + static const char* options[] = {"condEventA3-r16", "condEventA5-r16"}; + return convert_enum_idx(options, 2, value, "cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::types"); +} +uint8_t cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {3, 5}; + return map_enum_number(options, 2, value, "cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::types"); +} + +const char* cond_recfg_trigger_nr_r17_s::cond_event_id_r17_c_::types_opts::to_string() const +{ + static const char* options[] = {"condEventB1-NR-r17"}; + return convert_enum_idx(options, 1, value, "cond_recfg_trigger_nr_r17_s::cond_event_id_r17_c_::types"); +} +uint8_t cond_recfg_trigger_nr_r17_s::cond_event_id_r17_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "cond_recfg_trigger_nr_r17_s::cond_event_id_r17_c_::types"); +} + const char* meas_ds_cfg_r12_c::setup_s_::dmtc_period_offset_r12_c_::types_opts::to_string() const { static const char* options[] = {"ms40-r12", "ms80-r12", "ms160-r12"}; @@ -1204,18 +1321,6 @@ const char* meas_gap_cfg_c::setup_s_::gap_offset_c_::types_opts::to_string() con return convert_enum_idx(options, 20, value, "meas_gap_cfg_c::setup_s_::gap_offset_c_::types"); } -const char* thres_eutra_c::types_opts::to_string() const -{ - static const char* options[] = {"threshold-RSRP", "threshold-RSRQ"}; - return convert_enum_idx(options, 2, value, "thres_eutra_c::types"); -} - -const char* thres_nr_r15_c::types_opts::to_string() const -{ - static const char* options[] = {"nr-RSRP-r15", "nr-RSRQ-r15", "nr-SINR-r15"}; - return convert_enum_idx(options, 3, value, "thres_nr_r15_c::types"); -} - const char* thres_utra_c::types_opts::to_string() const { static const char* options[] = {"utra-RSCP", "utra-EcN0"}; @@ -1361,6 +1466,39 @@ uint16_t meas_obj_to_add_mod_ext_r13_s::meas_obj_r13_c_::types_opts::to_number() return 0; } +const char* pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::types_opts::to_string() const +{ + static const char* options[] = {"fdd", "tdd"}; + return convert_enum_idx(options, 2, value, "pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::types"); +} + +const char* pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::types_opts::to_string() const +{ + static const char* options[] = {"ce-ModeA", "ce-ModeB"}; + return convert_enum_idx(options, 2, value, "pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::types"); +} + +const char* pur_periodicity_and_offset_r16_c::types_opts::to_string() const +{ + static const char* options[] = {"periodicity8", + "periodicity16", + "periodicity32", + "periodicity64", + "periodicity128", + "periodicity256", + "periodicity512", + "periodicity1024", + "periodicity2048", + "periodicity4096", + "periodicity8192"}; + return convert_enum_idx(options, 11, value, "pur_periodicity_and_offset_r16_c::types"); +} +uint16_t pur_periodicity_and_offset_r16_c::types_opts::to_number() const +{ + static const uint16_t options[] = {8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192}; + return map_enum_number(options, 11, value, "pur_periodicity_and_offset_r16_c::types"); +} + const char* report_cfg_to_add_mod_s::report_cfg_c_::types_opts::to_string() const { static const char* options[] = {"reportConfigEUTRA", "reportConfigInterRAT"}; @@ -1369,7 +1507,7 @@ const char* report_cfg_to_add_mod_s::report_cfg_c_::types_opts::to_string() cons const char* security_cfg_ho_v1530_s::handov_type_v1530_c_::types_opts::to_string() const { - static const char* options[] = {"intra5GC-r15", "fivegc-ToEPC-r15", "epc-To5GC-r15"}; + static const char* options[] = {"intra5GC", "fivegc-ToEPC", "epc-To5GC"}; return convert_enum_idx(options, 3, value, "security_cfg_ho_v1530_s::handov_type_v1530_c_::types"); } @@ -1430,9 +1568,23 @@ const char* sl_v2x_cfg_ded_r14_s::comm_tx_res_v1530_c_::setup_c_::types_opts::to return convert_enum_idx(options, 2, value, "sl_v2x_cfg_ded_r14_s::comm_tx_res_v1530_c_::setup_c_::types"); } +const char* event_type_r17_c::types_opts::to_string() const +{ + static const char* options[] = {"outOfCoverage", "eventL1"}; + return convert_enum_idx(options, 2, value, "event_type_r17_c::types"); +} +uint8_t event_type_r17_c::types_opts::to_number() const +{ + if (value == event_l1) { + return 1; + } + invalid_enum_number(value, "event_type_r17_c::types"); + return 0; +} + const char* ran_notif_area_info_r15_c::types_opts::to_string() const { - static const char* options[] = {"cellList-r15", "ran-AreaConfigList-r15"}; + static const char* options[] = {"cellList", "ran-AreaConfigList"}; return convert_enum_idx(options, 2, value, "ran_notif_area_info_r15_c::types"); } @@ -1567,8 +1719,8 @@ const char* rn_sf_cfg_r10_s::rpdcch_cfg_r10_s_::pucch_cfg_r10_c_::types_opts::to const char* redirected_carrier_info_c::types_opts::to_string() const { static const char* options[] = { - "eutra", "geran", "utra-FDD", "utra-TDD", "cdma2000-HRPD", "cdma2000-1xRTT", "utra-TDD-r10", "nr-r15"}; - return convert_enum_idx(options, 8, value, "redirected_carrier_info_c::types"); + "eutra", "geran", "utra-FDD", "utra-TDD", "cdma2000-HRPD", "cdma2000-1xRTT", "utra-TDD-r10", "nr-r15", "nr-r17"}; + return convert_enum_idx(options, 9, value, "redirected_carrier_info_c::types"); } const char* security_cfg_ho_s::handov_type_c_::types_opts::to_string() const @@ -1579,8 +1731,7 @@ const char* security_cfg_ho_s::handov_type_c_::types_opts::to_string() const const char* dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::types_opts::to_string() const { - static const char* options[] = { - "dedicatedInfoNAS-r15", "dedicatedInfoCDMA2000-1XRTT-r15", "dedicatedInfoCDMA2000-HRPD-r15"}; + static const char* options[] = {"dedicatedInfoNAS", "dedicatedInfoCDMA2000-1XRTT", "dedicatedInfoCDMA2000-HRPD"}; return convert_enum_idx(options, 3, value, "dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::types"); } @@ -1619,6 +1770,12 @@ const char* counter_check_s::crit_exts_c_::c1_c_::types_opts::to_string() const return convert_enum_idx(options, 4, value, "counter_check_s::crit_exts_c_::c1_c_::types"); } +const char* dl_ded_msg_segment_r16_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"dlDedicatedMessageSegment-r16", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "dl_ded_msg_segment_r16_s::crit_exts_c_::types"); +} + const char* dl_info_transfer_s::crit_exts_c_::c1_c_::types_opts::to_string() const { static const char* options[] = {"dlInformationTransfer-r8", "dlInformationTransfer-r15", "spare2", "spare1"}; @@ -1701,7 +1858,7 @@ const char* dl_dcch_msg_type_c::c1_c_::types_opts::to_string() const "loggedMeasurementConfiguration-r10", "rnReconfiguration-r10", "rrcConnectionResume-r13", - "spare3", + "dlDedicatedMessageSegment-r16", "spare2", "spare1"}; return convert_enum_idx(options, 16, value, "dl_dcch_msg_type_c::c1_c_::types"); @@ -1768,6 +1925,166 @@ void mbms_session_info_r9_s::to_json(json_writer& j) const j.end_obj(); } +// MBSFN-SubframeConfig-v1610 ::= SEQUENCE +SRSASN_CODE mbsfn_sf_cfg_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(sf_alloc_v1610.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mbsfn_sf_cfg_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(sf_alloc_v1610.unpack(bref)); + + return SRSASN_SUCCESS; +} +void mbsfn_sf_cfg_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("subframeAllocation-v1610"); + sf_alloc_v1610.to_json(j); + j.end_obj(); +} + +void mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::destroy_() +{ + switch (type_) { + case types::one_frame_v1610: + c.destroy >(); + break; + case types::four_frames_v1610: + c.destroy >(); + break; + default: + break; + } +} +void mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::one_frame_v1610: + c.init >(); + break; + case types::four_frames_v1610: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_"); + } +} +mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::sf_alloc_v1610_c_(const mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::one_frame_v1610: + c.init(other.c.get >()); + break; + case types::four_frames_v1610: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_"); + } +} +mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_& +mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::operator=(const mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::one_frame_v1610: + c.set(other.c.get >()); + break; + case types::four_frames_v1610: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_"); + } + + return *this; +} +fixed_bitstring<2>& mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::set_one_frame_v1610() +{ + set(types::one_frame_v1610); + return c.get >(); +} +fixed_bitstring<8>& mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::set_four_frames_v1610() +{ + set(types::four_frames_v1610); + return c.get >(); +} +void mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::one_frame_v1610: + j.write_str("oneFrame-v1610", c.get >().to_string()); + break; + case types::four_frames_v1610: + j.write_str("fourFrames-v1610", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_"); + } + j.end_obj(); +} +SRSASN_CODE mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::one_frame_v1610: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::four_frames_v1610: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::one_frame_v1610: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::four_frames_v1610: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::types_opts::to_string() const +{ + static const char* options[] = {"oneFrame-v1610", "fourFrames-v1610"}; + return convert_enum_idx(options, 2, value, "mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::types"); +} +uint8_t mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {1, 4}; + return map_enum_number(options, 2, value, "mbsfn_sf_cfg_v1610_s::sf_alloc_v1610_c_::types"); +} + // PMCH-Config-r12 ::= SEQUENCE SRSASN_CODE pmch_cfg_r12_s::pack(bit_ref& bref) const { @@ -1961,33 +2278,74 @@ uint8_t pmch_cfg_r12_s::mch_sched_period_v1430_opts::to_number() const return map_enum_number(options, 2, value, "pmch_cfg_r12_s::mch_sched_period_v1430_e_"); } -// PMCH-InfoExt-r12 ::= SEQUENCE -SRSASN_CODE pmch_info_ext_r12_s::pack(bit_ref& bref) const +// MBSFNAreaConfiguration-v1610-IEs ::= SEQUENCE +SRSASN_CODE mbsfn_area_cfg_v1610_ies_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(pmch_cfg_r12.pack(bref)); - HANDLE_CODE(pack_dyn_seq_of(bref, mbms_session_info_list_r12, 0, 29)); + HANDLE_CODE(bref.pack(common_sf_alloc_v1610_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (common_sf_alloc_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, common_sf_alloc_v1610, 1, 8)); + } return SRSASN_SUCCESS; } -SRSASN_CODE pmch_info_ext_r12_s::unpack(cbit_ref& bref) +SRSASN_CODE mbsfn_area_cfg_v1610_ies_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(pmch_cfg_r12.unpack(bref)); - HANDLE_CODE(unpack_dyn_seq_of(mbms_session_info_list_r12, bref, 0, 29)); + HANDLE_CODE(bref.unpack(common_sf_alloc_v1610_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (common_sf_alloc_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(common_sf_alloc_v1610, bref, 1, 8)); + } return SRSASN_SUCCESS; } -void pmch_info_ext_r12_s::to_json(json_writer& j) const +void mbsfn_area_cfg_v1610_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("pmch-Config-r12"); - pmch_cfg_r12.to_json(j); - j.start_array("mbms-SessionInfoList-r12"); - for (const auto& e1 : mbms_session_info_list_r12) { - e1.to_json(j); - } - j.end_array(); + if (common_sf_alloc_v1610_present) { + j.start_array("commonSF-Alloc-v1610"); + for (const auto& e1 : common_sf_alloc_v1610) { + e1.to_json(j); + } + j.end_array(); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// PMCH-InfoExt-r12 ::= SEQUENCE +SRSASN_CODE pmch_info_ext_r12_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pmch_cfg_r12.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, mbms_session_info_list_r12, 0, 29)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE pmch_info_ext_r12_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(pmch_cfg_r12.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(mbms_session_info_list_r12, bref, 0, 29)); + + return SRSASN_SUCCESS; +} +void pmch_info_ext_r12_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("pmch-Config-r12"); + pmch_cfg_r12.to_json(j); + j.start_array("mbms-SessionInfoList-r12"); + for (const auto& e1 : mbms_session_info_list_r12) { + e1.to_json(j); + } + j.end_array(); j.end_obj(); } @@ -1996,7 +2354,10 @@ SRSASN_CODE mbsfn_area_cfg_v1430_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - HANDLE_CODE(pack_dyn_seq_of(bref, common_sf_alloc_r14, 1, 8)); + HANDLE_CODE(pack_dyn_seq_of(bref, common_sf_alloc_v1430, 1, 8)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -2004,22 +2365,24 @@ SRSASN_CODE mbsfn_area_cfg_v1430_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - HANDLE_CODE(unpack_dyn_seq_of(common_sf_alloc_r14, bref, 1, 8)); + HANDLE_CODE(unpack_dyn_seq_of(common_sf_alloc_v1430, bref, 1, 8)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } void mbsfn_area_cfg_v1430_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.start_array("commonSF-Alloc-r14"); - for (const auto& e1 : common_sf_alloc_r14) { + j.start_array("commonSF-Alloc-v1430"); + for (const auto& e1 : common_sf_alloc_v1430) { e1.to_json(j); } j.end_array(); if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -3142,830 +3505,830 @@ uint16_t sc_mtch_sched_info_br_r14_s::sched_period_start_offset_scptm_r14_c_::ty options, 16, value, "sc_mtch_sched_info_br_r14_s::sched_period_start_offset_scptm_r14_c_::types"); } -// SC-MTCH-SchedulingInfo-r13 ::= SEQUENCE -SRSASN_CODE sc_mtch_sched_info_r13_s::pack(bit_ref& bref) const +// SC-MTCH-Info-BR-r14 ::= SEQUENCE +SRSASN_CODE sc_mtch_info_br_r14_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(on_dur_timer_scptm_r13.pack(bref)); - HANDLE_CODE(drx_inactivity_timer_scptm_r13.pack(bref)); - HANDLE_CODE(sched_period_start_offset_scptm_r13.pack(bref)); + HANDLE_CODE(bref.pack(sc_mtch_sched_info_r14_present, 1)); + HANDLE_CODE(bref.pack(sc_mtch_neighbour_cell_r14_present, 1)); + HANDLE_CODE(bref.pack(p_a_r14_present, 1)); + + HANDLE_CODE(pack_integer(bref, sc_mtch_carrier_freq_r14, (uint32_t)0u, (uint32_t)262143u)); + HANDLE_CODE(mbms_session_info_r14.pack(bref)); + HANDLE_CODE(g_rnti_r14.pack(bref)); + if (sc_mtch_sched_info_r14_present) { + HANDLE_CODE(sc_mtch_sched_info_r14.pack(bref)); + } + if (sc_mtch_neighbour_cell_r14_present) { + HANDLE_CODE(sc_mtch_neighbour_cell_r14.pack(bref)); + } + HANDLE_CODE(pack_integer(bref, mpdcch_nb_sc_mtch_r14, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(mpdcch_num_repeat_sc_mtch_r14.pack(bref)); + HANDLE_CODE(mpdcch_start_sf_sc_mtch_r14.pack(bref)); + HANDLE_CODE(mpdcch_pdsch_hop_cfg_sc_mtch_r14.pack(bref)); + HANDLE_CODE(mpdcch_pdsch_cemode_cfg_sc_mtch_r14.pack(bref)); + HANDLE_CODE(mpdcch_pdsch_max_bw_sc_mtch_r14.pack(bref)); + HANDLE_CODE(mpdcch_offset_sc_mtch_r14.pack(bref)); + if (p_a_r14_present) { + HANDLE_CODE(p_a_r14.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE sc_mtch_sched_info_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE sc_mtch_info_br_r14_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(on_dur_timer_scptm_r13.unpack(bref)); - HANDLE_CODE(drx_inactivity_timer_scptm_r13.unpack(bref)); - HANDLE_CODE(sched_period_start_offset_scptm_r13.unpack(bref)); + HANDLE_CODE(bref.unpack(sc_mtch_sched_info_r14_present, 1)); + HANDLE_CODE(bref.unpack(sc_mtch_neighbour_cell_r14_present, 1)); + HANDLE_CODE(bref.unpack(p_a_r14_present, 1)); + + HANDLE_CODE(unpack_integer(sc_mtch_carrier_freq_r14, bref, (uint32_t)0u, (uint32_t)262143u)); + HANDLE_CODE(mbms_session_info_r14.unpack(bref)); + HANDLE_CODE(g_rnti_r14.unpack(bref)); + if (sc_mtch_sched_info_r14_present) { + HANDLE_CODE(sc_mtch_sched_info_r14.unpack(bref)); + } + if (sc_mtch_neighbour_cell_r14_present) { + HANDLE_CODE(sc_mtch_neighbour_cell_r14.unpack(bref)); + } + HANDLE_CODE(unpack_integer(mpdcch_nb_sc_mtch_r14, bref, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(mpdcch_num_repeat_sc_mtch_r14.unpack(bref)); + HANDLE_CODE(mpdcch_start_sf_sc_mtch_r14.unpack(bref)); + HANDLE_CODE(mpdcch_pdsch_hop_cfg_sc_mtch_r14.unpack(bref)); + HANDLE_CODE(mpdcch_pdsch_cemode_cfg_sc_mtch_r14.unpack(bref)); + HANDLE_CODE(mpdcch_pdsch_max_bw_sc_mtch_r14.unpack(bref)); + HANDLE_CODE(mpdcch_offset_sc_mtch_r14.unpack(bref)); + if (p_a_r14_present) { + HANDLE_CODE(p_a_r14.unpack(bref)); + } return SRSASN_SUCCESS; } -void sc_mtch_sched_info_r13_s::to_json(json_writer& j) const +void sc_mtch_info_br_r14_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("onDurationTimerSCPTM-r13", on_dur_timer_scptm_r13.to_string()); - j.write_str("drx-InactivityTimerSCPTM-r13", drx_inactivity_timer_scptm_r13.to_string()); - j.write_fieldname("schedulingPeriodStartOffsetSCPTM-r13"); - sched_period_start_offset_scptm_r13.to_json(j); + j.write_int("sc-mtch-CarrierFreq-r14", sc_mtch_carrier_freq_r14); + j.write_fieldname("mbmsSessionInfo-r14"); + mbms_session_info_r14.to_json(j); + j.write_str("g-RNTI-r14", g_rnti_r14.to_string()); + if (sc_mtch_sched_info_r14_present) { + j.write_fieldname("sc-mtch-schedulingInfo-r14"); + sc_mtch_sched_info_r14.to_json(j); + } + if (sc_mtch_neighbour_cell_r14_present) { + j.write_str("sc-mtch-neighbourCell-r14", sc_mtch_neighbour_cell_r14.to_string()); + } + j.write_int("mpdcch-Narrowband-SC-MTCH-r14", mpdcch_nb_sc_mtch_r14); + j.write_str("mpdcch-NumRepetition-SC-MTCH-r14", mpdcch_num_repeat_sc_mtch_r14.to_string()); + j.write_fieldname("mpdcch-StartSF-SC-MTCH-r14"); + mpdcch_start_sf_sc_mtch_r14.to_json(j); + j.write_str("mpdcch-PDSCH-HoppingConfig-SC-MTCH-r14", mpdcch_pdsch_hop_cfg_sc_mtch_r14.to_string()); + j.write_str("mpdcch-PDSCH-CEmodeConfig-SC-MTCH-r14", mpdcch_pdsch_cemode_cfg_sc_mtch_r14.to_string()); + j.write_str("mpdcch-PDSCH-MaxBandwidth-SC-MTCH-r14", mpdcch_pdsch_max_bw_sc_mtch_r14.to_string()); + j.write_str("mpdcch-Offset-SC-MTCH-r14", mpdcch_offset_sc_mtch_r14.to_string()); + if (p_a_r14_present) { + j.write_str("p-a-r14", p_a_r14.to_string()); + } j.end_obj(); } -const char* sc_mtch_sched_info_r13_s::on_dur_timer_scptm_r13_opts::to_string() const -{ - static const char* options[] = {"psf1", - "psf2", - "psf3", - "psf4", - "psf5", - "psf6", - "psf8", - "psf10", - "psf20", - "psf30", - "psf40", - "psf50", - "psf60", - "psf80", - "psf100", - "psf200"}; - return convert_enum_idx(options, 16, value, "sc_mtch_sched_info_r13_s::on_dur_timer_scptm_r13_e_"); -} -uint8_t sc_mtch_sched_info_r13_s::on_dur_timer_scptm_r13_opts::to_number() const -{ - static const uint8_t options[] = {1, 2, 3, 4, 5, 6, 8, 10, 20, 30, 40, 50, 60, 80, 100, 200}; - return map_enum_number(options, 16, value, "sc_mtch_sched_info_r13_s::on_dur_timer_scptm_r13_e_"); -} - -const char* sc_mtch_sched_info_r13_s::drx_inactivity_timer_scptm_r13_opts::to_string() const +const char* sc_mtch_info_br_r14_s::mpdcch_num_repeat_sc_mtch_r14_opts::to_string() const { - static const char* options[] = {"psf0", - "psf1", - "psf2", - "psf4", - "psf8", - "psf10", - "psf20", - "psf40", - "psf80", - "psf160", - "ps320", - "psf640", - "psf960", - "psf1280", - "psf1920", - "psf2560"}; - return convert_enum_idx(options, 16, value, "sc_mtch_sched_info_r13_s::drx_inactivity_timer_scptm_r13_e_"); + static const char* options[] = {"r1", "r2", "r4", "r8", "r16", "r32", "r64", "r128", "r256"}; + return convert_enum_idx(options, 9, value, "sc_mtch_info_br_r14_s::mpdcch_num_repeat_sc_mtch_r14_e_"); } -uint16_t sc_mtch_sched_info_r13_s::drx_inactivity_timer_scptm_r13_opts::to_number() const +uint16_t sc_mtch_info_br_r14_s::mpdcch_num_repeat_sc_mtch_r14_opts::to_number() const { - static const uint16_t options[] = {0, 1, 2, 4, 8, 10, 20, 40, 80, 160, 320, 640, 960, 1280, 1920, 2560}; - return map_enum_number(options, 16, value, "sc_mtch_sched_info_r13_s::drx_inactivity_timer_scptm_r13_e_"); + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256}; + return map_enum_number(options, 9, value, "sc_mtch_info_br_r14_s::mpdcch_num_repeat_sc_mtch_r14_e_"); } -void sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::destroy_() {} -void sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set(types::options e) +void sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::destroy_() {} +void sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::set(types::options e) { destroy_(); type_ = e; } -sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::sched_period_start_offset_scptm_r13_c_( - const sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_& other) +sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::mpdcch_start_sf_sc_mtch_r14_c_( + const sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_& other) { type_ = other.type(); switch (type_) { - case types::sf10: - c.init(other.c.get()); - break; - case types::sf20: - c.init(other.c.get()); - break; - case types::sf32: - c.init(other.c.get()); - break; - case types::sf40: - c.init(other.c.get()); - break; - case types::sf64: - c.init(other.c.get()); - break; - case types::sf80: - c.init(other.c.get()); - break; - case types::sf128: - c.init(other.c.get()); - break; - case types::sf160: - c.init(other.c.get()); - break; - case types::sf256: - c.init(other.c.get()); - break; - case types::sf320: - c.init(other.c.get()); - break; - case types::sf512: - c.init(other.c.get()); - break; - case types::sf640: - c.init(other.c.get()); - break; - case types::sf1024: - c.init(other.c.get()); - break; - case types::sf2048: - c.init(other.c.get()); - break; - case types::sf4096: - c.init(other.c.get()); + case types::fdd_r14: + c.init(other.c.get()); break; - case types::sf8192: - c.init(other.c.get()); + case types::tdd_r14: + c.init(other.c.get()); break; case types::nulltype: break; default: - log_invalid_choice_id(type_, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_"); + log_invalid_choice_id(type_, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_"); } } -sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_& -sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::operator=( - const sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_& other) +sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_& sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::operator=( + const sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_& other) { if (this == &other) { return *this; } set(other.type()); switch (type_) { - case types::sf10: - c.set(other.c.get()); + case types::fdd_r14: + c.set(other.c.get()); break; - case types::sf20: - c.set(other.c.get()); - break; - case types::sf32: - c.set(other.c.get()); - break; - case types::sf40: - c.set(other.c.get()); - break; - case types::sf64: - c.set(other.c.get()); - break; - case types::sf80: - c.set(other.c.get()); - break; - case types::sf128: - c.set(other.c.get()); - break; - case types::sf160: - c.set(other.c.get()); - break; - case types::sf256: - c.set(other.c.get()); - break; - case types::sf320: - c.set(other.c.get()); + case types::tdd_r14: + c.set(other.c.get()); break; - case types::sf512: - c.set(other.c.get()); + case types::nulltype: break; - case types::sf640: - c.set(other.c.get()); + default: + log_invalid_choice_id(type_, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_"); + } + + return *this; +} +sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_e_& +sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::set_fdd_r14() +{ + set(types::fdd_r14); + return c.get(); +} +sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::tdd_r14_e_& +sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::set_tdd_r14() +{ + set(types::tdd_r14); + return c.get(); +} +void sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::fdd_r14: + j.write_str("fdd-r14", c.get().to_string()); break; - case types::sf1024: - c.set(other.c.get()); + case types::tdd_r14: + j.write_str("tdd-r14", c.get().to_string()); break; - case types::sf2048: - c.set(other.c.get()); + default: + log_invalid_choice_id(type_, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_"); + } + j.end_obj(); +} +SRSASN_CODE sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::fdd_r14: + HANDLE_CODE(c.get().pack(bref)); break; - case types::sf4096: - c.set(other.c.get()); + case types::tdd_r14: + HANDLE_CODE(c.get().pack(bref)); break; - case types::sf8192: - c.set(other.c.get()); + default: + log_invalid_choice_id(type_, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::fdd_r14: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::nulltype: + case types::tdd_r14: + HANDLE_CODE(c.get().unpack(bref)); break; default: - log_invalid_choice_id(type_, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_"); + log_invalid_choice_id(type_, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_"); + return SRSASN_ERROR_DECODE_FAIL; } + return SRSASN_SUCCESS; +} - return *this; +const char* sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_opts::to_string() const +{ + static const char* options[] = {"v1", "v1dot5", "v2", "v2dot5", "v4", "v5", "v8", "v10"}; + return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_e_"); } -uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf10() +float sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_opts::to_number() const { - set(types::sf10); - return c.get(); + static const float options[] = {1.0, 1.5, 2.0, 2.5, 4.0, 5.0, 8.0, 10.0}; + return map_enum_number(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_e_"); } -uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf20() +const char* sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_opts::to_number_string() const { - set(types::sf20); - return c.get(); + static const char* options[] = {"1", "1.5", "2", "2.5", "4", "5", "8", "10"}; + return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_e_"); } -uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf32() + +const char* sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::tdd_r14_opts::to_string() const { - set(types::sf32); - return c.get(); + static const char* options[] = {"v1", "v2", "v4", "v5", "v8", "v10", "v20"}; + return convert_enum_idx(options, 7, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::tdd_r14_e_"); } -uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf40() +uint8_t sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::tdd_r14_opts::to_number() const { - set(types::sf40); - return c.get(); + static const uint8_t options[] = {1, 2, 4, 5, 8, 10, 20}; + return map_enum_number(options, 7, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::tdd_r14_e_"); } -uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf64() + +const char* sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::types_opts::to_string() const { - set(types::sf64); - return c.get(); + static const char* options[] = {"fdd-r14", "tdd-r14"}; + return convert_enum_idx(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::types"); } -uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf80() + +const char* sc_mtch_info_br_r14_s::mpdcch_pdsch_hop_cfg_sc_mtch_r14_opts::to_string() const { - set(types::sf80); - return c.get(); + static const char* options[] = {"on", "off"}; + return convert_enum_idx(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_pdsch_hop_cfg_sc_mtch_r14_e_"); } -uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf128() + +const char* sc_mtch_info_br_r14_s::mpdcch_pdsch_cemode_cfg_sc_mtch_r14_opts::to_string() const { - set(types::sf128); - return c.get(); + static const char* options[] = {"ce-ModeA", "ce-ModeB"}; + return convert_enum_idx(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_pdsch_cemode_cfg_sc_mtch_r14_e_"); } -uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf160() + +const char* sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_opts::to_string() const { - set(types::sf160); - return c.get(); + static const char* options[] = {"bw1dot4", "bw5"}; + return convert_enum_idx(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_e_"); } -uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf256() +float sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_opts::to_number() const { - set(types::sf256); - return c.get(); + static const float options[] = {1.4, 5.0}; + return map_enum_number(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_e_"); } -uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf320() +const char* sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_opts::to_number_string() const { - set(types::sf320); - return c.get(); + static const char* options[] = {"1.4", "5"}; + return convert_enum_idx(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_e_"); } -uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf512() + +const char* sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_opts::to_string() const { - set(types::sf512); - return c.get(); + static const char* options[] = { + "zero", "oneEighth", "oneQuarter", "threeEighth", "oneHalf", "fiveEighth", "threeQuarter", "sevenEighth"}; + return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_e_"); } -uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf640() +float sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_opts::to_number() const { - set(types::sf640); - return c.get(); + static const float options[] = {0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875}; + return map_enum_number(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_e_"); } -uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf1024() +const char* sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_opts::to_number_string() const { - set(types::sf1024); - return c.get(); + static const char* options[] = {"0", "1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "7/8"}; + return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_e_"); } -uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf2048() + +const char* sc_mtch_info_br_r14_s::p_a_r14_opts::to_string() const { - set(types::sf2048); - return c.get(); + static const char* options[] = {"dB-6", "dB-4dot77", "dB-3", "dB-1dot77", "dB0", "dB1", "dB2", "dB3"}; + return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::p_a_r14_e_"); } -uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf4096() +float sc_mtch_info_br_r14_s::p_a_r14_opts::to_number() const { - set(types::sf4096); - return c.get(); + static const float options[] = {-6.0, -4.77, -3.0, -1.77, 0.0, 1.0, 2.0, 3.0}; + return map_enum_number(options, 8, value, "sc_mtch_info_br_r14_s::p_a_r14_e_"); } -uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf8192() +const char* sc_mtch_info_br_r14_s::p_a_r14_opts::to_number_string() const { - set(types::sf8192); - return c.get(); + static const char* options[] = {"-6", "-4.77", "-3", "-1.77", "0", "1", "2", "3"}; + return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::p_a_r14_e_"); } -void sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::to_json(json_writer& j) const + +// SC-MTCH-SchedulingInfo-r13 ::= SEQUENCE +SRSASN_CODE sc_mtch_sched_info_r13_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(on_dur_timer_scptm_r13.pack(bref)); + HANDLE_CODE(drx_inactivity_timer_scptm_r13.pack(bref)); + HANDLE_CODE(sched_period_start_offset_scptm_r13.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE sc_mtch_sched_info_r13_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(on_dur_timer_scptm_r13.unpack(bref)); + HANDLE_CODE(drx_inactivity_timer_scptm_r13.unpack(bref)); + HANDLE_CODE(sched_period_start_offset_scptm_r13.unpack(bref)); + + return SRSASN_SUCCESS; +} +void sc_mtch_sched_info_r13_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::sf10: - j.write_int("sf10", c.get()); - break; - case types::sf20: - j.write_int("sf20", c.get()); - break; - case types::sf32: - j.write_int("sf32", c.get()); - break; - case types::sf40: - j.write_int("sf40", c.get()); - break; - case types::sf64: - j.write_int("sf64", c.get()); - break; - case types::sf80: - j.write_int("sf80", c.get()); - break; - case types::sf128: - j.write_int("sf128", c.get()); - break; - case types::sf160: - j.write_int("sf160", c.get()); - break; - case types::sf256: - j.write_int("sf256", c.get()); - break; - case types::sf320: - j.write_int("sf320", c.get()); - break; - case types::sf512: - j.write_int("sf512", c.get()); - break; - case types::sf640: - j.write_int("sf640", c.get()); - break; - case types::sf1024: - j.write_int("sf1024", c.get()); - break; - case types::sf2048: - j.write_int("sf2048", c.get()); - break; - case types::sf4096: - j.write_int("sf4096", c.get()); - break; - case types::sf8192: - j.write_int("sf8192", c.get()); - break; - default: - log_invalid_choice_id(type_, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_"); - } + j.write_str("onDurationTimerSCPTM-r13", on_dur_timer_scptm_r13.to_string()); + j.write_str("drx-InactivityTimerSCPTM-r13", drx_inactivity_timer_scptm_r13.to_string()); + j.write_fieldname("schedulingPeriodStartOffsetSCPTM-r13"); + sched_period_start_offset_scptm_r13.to_json(j); j.end_obj(); } -SRSASN_CODE sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::pack(bit_ref& bref) const + +const char* sc_mtch_sched_info_r13_s::on_dur_timer_scptm_r13_opts::to_string() const { - type_.pack(bref); + static const char* options[] = {"psf1", + "psf2", + "psf3", + "psf4", + "psf5", + "psf6", + "psf8", + "psf10", + "psf20", + "psf30", + "psf40", + "psf50", + "psf60", + "psf80", + "psf100", + "psf200"}; + return convert_enum_idx(options, 16, value, "sc_mtch_sched_info_r13_s::on_dur_timer_scptm_r13_e_"); +} +uint8_t sc_mtch_sched_info_r13_s::on_dur_timer_scptm_r13_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3, 4, 5, 6, 8, 10, 20, 30, 40, 50, 60, 80, 100, 200}; + return map_enum_number(options, 16, value, "sc_mtch_sched_info_r13_s::on_dur_timer_scptm_r13_e_"); +} + +const char* sc_mtch_sched_info_r13_s::drx_inactivity_timer_scptm_r13_opts::to_string() const +{ + static const char* options[] = {"psf0", + "psf1", + "psf2", + "psf4", + "psf8", + "psf10", + "psf20", + "psf40", + "psf80", + "psf160", + "ps320", + "psf640", + "psf960", + "psf1280", + "psf1920", + "psf2560"}; + return convert_enum_idx(options, 16, value, "sc_mtch_sched_info_r13_s::drx_inactivity_timer_scptm_r13_e_"); +} +uint16_t sc_mtch_sched_info_r13_s::drx_inactivity_timer_scptm_r13_opts::to_number() const +{ + static const uint16_t options[] = {0, 1, 2, 4, 8, 10, 20, 40, 80, 160, 320, 640, 960, 1280, 1920, 2560}; + return map_enum_number(options, 16, value, "sc_mtch_sched_info_r13_s::drx_inactivity_timer_scptm_r13_e_"); +} + +void sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::destroy_() {} +void sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::sched_period_start_offset_scptm_r13_c_( + const sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_& other) +{ + type_ = other.type(); switch (type_) { case types::sf10: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)9u)); + c.init(other.c.get()); break; case types::sf20: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)19u)); + c.init(other.c.get()); break; case types::sf32: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)31u)); + c.init(other.c.get()); break; case types::sf40: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)39u)); + c.init(other.c.get()); break; case types::sf64: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)63u)); + c.init(other.c.get()); break; case types::sf80: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)79u)); + c.init(other.c.get()); break; case types::sf128: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + c.init(other.c.get()); break; case types::sf160: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)159u)); + c.init(other.c.get()); break; case types::sf256: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u)); + c.init(other.c.get()); break; case types::sf320: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)319u)); + c.init(other.c.get()); break; case types::sf512: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)511u)); + c.init(other.c.get()); break; case types::sf640: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)639u)); + c.init(other.c.get()); break; case types::sf1024: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1023u)); + c.init(other.c.get()); break; case types::sf2048: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)2048u)); + c.init(other.c.get()); break; case types::sf4096: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4096u)); + c.init(other.c.get()); break; case types::sf8192: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)8192u)); + c.init(other.c.get()); + break; + case types::nulltype: break; default: log_invalid_choice_id(type_, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_"); - return SRSASN_ERROR_ENCODE_FAIL; } - return SRSASN_SUCCESS; } -SRSASN_CODE sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::unpack(cbit_ref& bref) +sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_& +sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::operator=( + const sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_& other) { - types e; - e.unpack(bref); - set(e); + if (this == &other) { + return *this; + } + set(other.type()); switch (type_) { case types::sf10: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)9u)); + c.set(other.c.get()); break; case types::sf20: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)19u)); + c.set(other.c.get()); break; case types::sf32: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)31u)); + c.set(other.c.get()); break; case types::sf40: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)39u)); + c.set(other.c.get()); break; case types::sf64: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)63u)); + c.set(other.c.get()); break; case types::sf80: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)79u)); + c.set(other.c.get()); break; case types::sf128: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + c.set(other.c.get()); break; case types::sf160: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)159u)); + c.set(other.c.get()); break; case types::sf256: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u)); + c.set(other.c.get()); break; case types::sf320: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)319u)); + c.set(other.c.get()); break; case types::sf512: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)511u)); + c.set(other.c.get()); break; case types::sf640: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)639u)); + c.set(other.c.get()); break; case types::sf1024: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1023u)); + c.set(other.c.get()); break; case types::sf2048: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)2048u)); + c.set(other.c.get()); break; case types::sf4096: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4096u)); + c.set(other.c.get()); break; case types::sf8192: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)8192u)); + c.set(other.c.get()); + break; + case types::nulltype: break; default: log_invalid_choice_id(type_, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_"); - return SRSASN_ERROR_DECODE_FAIL; } - return SRSASN_SUCCESS; -} -const char* sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::types_opts::to_string() const + return *this; +} +uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf10() { - static const char* options[] = {"sf10", - "sf20", - "sf32", - "sf40", - "sf64", - "sf80", - "sf128", - "sf160", - "sf256", - "sf320", - "sf512", - "sf640", - "sf1024", - "sf2048", - "sf4096", - "sf8192"}; - return convert_enum_idx( - options, 16, value, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::types"); + set(types::sf10); + return c.get(); } -uint16_t sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::types_opts::to_number() const +uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf20() { - static const uint16_t options[] = {10, 20, 32, 40, 64, 80, 128, 160, 256, 320, 512, 640, 1024, 2048, 4096, 8192}; - return map_enum_number(options, 16, value, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::types"); + set(types::sf20); + return c.get(); } - -// PCI-ARFCN-r13 ::= SEQUENCE -SRSASN_CODE pci_arfcn_r13_s::pack(bit_ref& bref) const +uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf32() { - HANDLE_CODE(bref.pack(carrier_freq_r13_present, 1)); - - HANDLE_CODE(pack_integer(bref, pci_r13, (uint16_t)0u, (uint16_t)503u)); - if (carrier_freq_r13_present) { - HANDLE_CODE(pack_integer(bref, carrier_freq_r13, (uint32_t)0u, (uint32_t)262143u)); - } - - return SRSASN_SUCCESS; + set(types::sf32); + return c.get(); } -SRSASN_CODE pci_arfcn_r13_s::unpack(cbit_ref& bref) +uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf40() { - HANDLE_CODE(bref.unpack(carrier_freq_r13_present, 1)); - - HANDLE_CODE(unpack_integer(pci_r13, bref, (uint16_t)0u, (uint16_t)503u)); - if (carrier_freq_r13_present) { - HANDLE_CODE(unpack_integer(carrier_freq_r13, bref, (uint32_t)0u, (uint32_t)262143u)); - } - - return SRSASN_SUCCESS; + set(types::sf40); + return c.get(); } -void pci_arfcn_r13_s::to_json(json_writer& j) const +uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf64() { - j.start_obj(); - j.write_int("physCellId-r13", pci_r13); - if (carrier_freq_r13_present) { - j.write_int("carrierFreq-r13", carrier_freq_r13); - } - j.end_obj(); + set(types::sf64); + return c.get(); } - -// SC-MTCH-Info-BR-r14 ::= SEQUENCE -SRSASN_CODE sc_mtch_info_br_r14_s::pack(bit_ref& bref) const +uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf80() { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(sc_mtch_sched_info_r14_present, 1)); - HANDLE_CODE(bref.pack(sc_mtch_neighbour_cell_r14_present, 1)); - HANDLE_CODE(bref.pack(p_a_r14_present, 1)); - - HANDLE_CODE(pack_integer(bref, sc_mtch_carrier_freq_r14, (uint32_t)0u, (uint32_t)262143u)); - HANDLE_CODE(mbms_session_info_r14.pack(bref)); - HANDLE_CODE(g_rnti_r14.pack(bref)); - if (sc_mtch_sched_info_r14_present) { - HANDLE_CODE(sc_mtch_sched_info_r14.pack(bref)); - } - if (sc_mtch_neighbour_cell_r14_present) { - HANDLE_CODE(sc_mtch_neighbour_cell_r14.pack(bref)); - } - HANDLE_CODE(pack_integer(bref, mpdcch_nb_sc_mtch_r14, (uint8_t)1u, (uint8_t)16u)); - HANDLE_CODE(mpdcch_num_repeat_sc_mtch_r14.pack(bref)); - HANDLE_CODE(mpdcch_start_sf_sc_mtch_r14.pack(bref)); - HANDLE_CODE(mpdcch_pdsch_hop_cfg_sc_mtch_r14.pack(bref)); - HANDLE_CODE(mpdcch_pdsch_cemode_cfg_sc_mtch_r14.pack(bref)); - HANDLE_CODE(mpdcch_pdsch_max_bw_sc_mtch_r14.pack(bref)); - HANDLE_CODE(mpdcch_offset_sc_mtch_r14.pack(bref)); - if (p_a_r14_present) { - HANDLE_CODE(p_a_r14.pack(bref)); - } - - return SRSASN_SUCCESS; + set(types::sf80); + return c.get(); } -SRSASN_CODE sc_mtch_info_br_r14_s::unpack(cbit_ref& bref) +uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf128() { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(sc_mtch_sched_info_r14_present, 1)); - HANDLE_CODE(bref.unpack(sc_mtch_neighbour_cell_r14_present, 1)); - HANDLE_CODE(bref.unpack(p_a_r14_present, 1)); - - HANDLE_CODE(unpack_integer(sc_mtch_carrier_freq_r14, bref, (uint32_t)0u, (uint32_t)262143u)); - HANDLE_CODE(mbms_session_info_r14.unpack(bref)); - HANDLE_CODE(g_rnti_r14.unpack(bref)); - if (sc_mtch_sched_info_r14_present) { - HANDLE_CODE(sc_mtch_sched_info_r14.unpack(bref)); - } - if (sc_mtch_neighbour_cell_r14_present) { - HANDLE_CODE(sc_mtch_neighbour_cell_r14.unpack(bref)); - } - HANDLE_CODE(unpack_integer(mpdcch_nb_sc_mtch_r14, bref, (uint8_t)1u, (uint8_t)16u)); - HANDLE_CODE(mpdcch_num_repeat_sc_mtch_r14.unpack(bref)); - HANDLE_CODE(mpdcch_start_sf_sc_mtch_r14.unpack(bref)); - HANDLE_CODE(mpdcch_pdsch_hop_cfg_sc_mtch_r14.unpack(bref)); - HANDLE_CODE(mpdcch_pdsch_cemode_cfg_sc_mtch_r14.unpack(bref)); - HANDLE_CODE(mpdcch_pdsch_max_bw_sc_mtch_r14.unpack(bref)); - HANDLE_CODE(mpdcch_offset_sc_mtch_r14.unpack(bref)); - if (p_a_r14_present) { - HANDLE_CODE(p_a_r14.unpack(bref)); - } - - return SRSASN_SUCCESS; + set(types::sf128); + return c.get(); } -void sc_mtch_info_br_r14_s::to_json(json_writer& j) const +uint8_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf160() { - j.start_obj(); - j.write_int("sc-mtch-CarrierFreq-r14", sc_mtch_carrier_freq_r14); - j.write_fieldname("mbmsSessionInfo-r14"); - mbms_session_info_r14.to_json(j); - j.write_str("g-RNTI-r14", g_rnti_r14.to_string()); - if (sc_mtch_sched_info_r14_present) { - j.write_fieldname("sc-mtch-schedulingInfo-r14"); - sc_mtch_sched_info_r14.to_json(j); - } - if (sc_mtch_neighbour_cell_r14_present) { - j.write_str("sc-mtch-neighbourCell-r14", sc_mtch_neighbour_cell_r14.to_string()); - } - j.write_int("mpdcch-Narrowband-SC-MTCH-r14", mpdcch_nb_sc_mtch_r14); - j.write_str("mpdcch-NumRepetition-SC-MTCH-r14", mpdcch_num_repeat_sc_mtch_r14.to_string()); - j.write_fieldname("mpdcch-StartSF-SC-MTCH-r14"); - mpdcch_start_sf_sc_mtch_r14.to_json(j); - j.write_str("mpdcch-PDSCH-HoppingConfig-SC-MTCH-r14", mpdcch_pdsch_hop_cfg_sc_mtch_r14.to_string()); - j.write_str("mpdcch-PDSCH-CEmodeConfig-SC-MTCH-r14", mpdcch_pdsch_cemode_cfg_sc_mtch_r14.to_string()); - j.write_str("mpdcch-PDSCH-MaxBandwidth-SC-MTCH-r14", mpdcch_pdsch_max_bw_sc_mtch_r14.to_string()); - j.write_str("mpdcch-Offset-SC-MTCH-r14", mpdcch_offset_sc_mtch_r14.to_string()); - if (p_a_r14_present) { - j.write_str("p-a-r14", p_a_r14.to_string()); - } - j.end_obj(); + set(types::sf160); + return c.get(); } - -const char* sc_mtch_info_br_r14_s::mpdcch_num_repeat_sc_mtch_r14_opts::to_string() const +uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf256() { - static const char* options[] = {"r1", "r2", "r4", "r8", "r16", "r32", "r64", "r128", "r256"}; - return convert_enum_idx(options, 9, value, "sc_mtch_info_br_r14_s::mpdcch_num_repeat_sc_mtch_r14_e_"); + set(types::sf256); + return c.get(); } -uint16_t sc_mtch_info_br_r14_s::mpdcch_num_repeat_sc_mtch_r14_opts::to_number() const +uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf320() { - static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256}; - return map_enum_number(options, 9, value, "sc_mtch_info_br_r14_s::mpdcch_num_repeat_sc_mtch_r14_e_"); + set(types::sf320); + return c.get(); } - -void sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::destroy_() {} -void sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::set(types::options e) +uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf512() { - destroy_(); - type_ = e; + set(types::sf512); + return c.get(); } -sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::mpdcch_start_sf_sc_mtch_r14_c_( - const sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_& other) +uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf640() { - type_ = other.type(); - switch (type_) { - case types::fdd_r14: - c.init(other.c.get()); - break; - case types::tdd_r14: - c.init(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_"); - } + set(types::sf640); + return c.get(); } -sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_& sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::operator=( - const sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_& other) +uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf1024() { - if (this == &other) { - return *this; - } - set(other.type()); - switch (type_) { - case types::fdd_r14: - c.set(other.c.get()); - break; - case types::tdd_r14: - c.set(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_"); - } - - return *this; + set(types::sf1024); + return c.get(); } -sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_e_& -sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::set_fdd_r14() +uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf2048() { - set(types::fdd_r14); - return c.get(); + set(types::sf2048); + return c.get(); } -sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::tdd_r14_e_& -sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::set_tdd_r14() +uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf4096() { - set(types::tdd_r14); - return c.get(); + set(types::sf4096); + return c.get(); } -void sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::to_json(json_writer& j) const +uint16_t& sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::set_sf8192() +{ + set(types::sf8192); + return c.get(); +} +void sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::fdd_r14: - j.write_str("fdd-r14", c.get().to_string()); + case types::sf10: + j.write_int("sf10", c.get()); break; - case types::tdd_r14: - j.write_str("tdd-r14", c.get().to_string()); + case types::sf20: + j.write_int("sf20", c.get()); + break; + case types::sf32: + j.write_int("sf32", c.get()); + break; + case types::sf40: + j.write_int("sf40", c.get()); + break; + case types::sf64: + j.write_int("sf64", c.get()); + break; + case types::sf80: + j.write_int("sf80", c.get()); + break; + case types::sf128: + j.write_int("sf128", c.get()); + break; + case types::sf160: + j.write_int("sf160", c.get()); + break; + case types::sf256: + j.write_int("sf256", c.get()); + break; + case types::sf320: + j.write_int("sf320", c.get()); + break; + case types::sf512: + j.write_int("sf512", c.get()); + break; + case types::sf640: + j.write_int("sf640", c.get()); + break; + case types::sf1024: + j.write_int("sf1024", c.get()); + break; + case types::sf2048: + j.write_int("sf2048", c.get()); + break; + case types::sf4096: + j.write_int("sf4096", c.get()); + break; + case types::sf8192: + j.write_int("sf8192", c.get()); break; default: - log_invalid_choice_id(type_, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_"); + log_invalid_choice_id(type_, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_"); } j.end_obj(); } -SRSASN_CODE sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::pack(bit_ref& bref) const +SRSASN_CODE sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::fdd_r14: - HANDLE_CODE(c.get().pack(bref)); + case types::sf10: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)9u)); break; - case types::tdd_r14: - HANDLE_CODE(c.get().pack(bref)); + case types::sf20: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)19u)); + break; + case types::sf32: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)31u)); + break; + case types::sf40: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)39u)); + break; + case types::sf64: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)63u)); + break; + case types::sf80: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)79u)); + break; + case types::sf128: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + break; + case types::sf160: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)159u)); + break; + case types::sf256: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u)); + break; + case types::sf320: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)319u)); + break; + case types::sf512: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)511u)); + break; + case types::sf640: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)639u)); + break; + case types::sf1024: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1023u)); + break; + case types::sf2048: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)2048u)); + break; + case types::sf4096: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4096u)); + break; + case types::sf8192: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)8192u)); break; default: - log_invalid_choice_id(type_, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_"); + log_invalid_choice_id(type_, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::unpack(cbit_ref& bref) +SRSASN_CODE sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::fdd_r14: - HANDLE_CODE(c.get().unpack(bref)); + case types::sf10: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)9u)); + break; + case types::sf20: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)19u)); + break; + case types::sf32: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)31u)); + break; + case types::sf40: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)39u)); + break; + case types::sf64: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)63u)); + break; + case types::sf80: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)79u)); + break; + case types::sf128: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + break; + case types::sf160: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)159u)); + break; + case types::sf256: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u)); + break; + case types::sf320: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)319u)); + break; + case types::sf512: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)511u)); + break; + case types::sf640: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)639u)); break; - case types::tdd_r14: - HANDLE_CODE(c.get().unpack(bref)); + case types::sf1024: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1023u)); + break; + case types::sf2048: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)2048u)); + break; + case types::sf4096: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4096u)); + break; + case types::sf8192: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)8192u)); break; default: - log_invalid_choice_id(type_, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_"); + log_invalid_choice_id(type_, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_opts::to_string() const -{ - static const char* options[] = {"v1", "v1dot5", "v2", "v2dot5", "v4", "v5", "v8", "v10"}; - return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_e_"); -} -float sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_opts::to_number() const -{ - static const float options[] = {1.0, 1.5, 2.0, 2.5, 4.0, 5.0, 8.0, 10.0}; - return map_enum_number(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_e_"); -} -const char* sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_opts::to_number_string() const -{ - static const char* options[] = {"1", "1.5", "2", "2.5", "4", "5", "8", "10"}; - return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::fdd_r14_e_"); -} - -const char* sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::tdd_r14_opts::to_string() const -{ - static const char* options[] = {"v1", "v2", "v4", "v5", "v8", "v10", "v20"}; - return convert_enum_idx(options, 7, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::tdd_r14_e_"); -} -uint8_t sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::tdd_r14_opts::to_number() const +const char* sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::types_opts::to_string() const { - static const uint8_t options[] = {1, 2, 4, 5, 8, 10, 20}; - return map_enum_number(options, 7, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::tdd_r14_e_"); + static const char* options[] = {"sf10", + "sf20", + "sf32", + "sf40", + "sf64", + "sf80", + "sf128", + "sf160", + "sf256", + "sf320", + "sf512", + "sf640", + "sf1024", + "sf2048", + "sf4096", + "sf8192"}; + return convert_enum_idx( + options, 16, value, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::types"); } - -const char* sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::types_opts::to_string() const +uint16_t sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::types_opts::to_number() const { - static const char* options[] = {"fdd-r14", "tdd-r14"}; - return convert_enum_idx(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_start_sf_sc_mtch_r14_c_::types"); + static const uint16_t options[] = {10, 20, 32, 40, 64, 80, 128, 160, 256, 320, 512, 640, 1024, 2048, 4096, 8192}; + return map_enum_number(options, 16, value, "sc_mtch_sched_info_r13_s::sched_period_start_offset_scptm_r13_c_::types"); } -const char* sc_mtch_info_br_r14_s::mpdcch_pdsch_hop_cfg_sc_mtch_r14_opts::to_string() const +// PCI-ARFCN-r13 ::= SEQUENCE +SRSASN_CODE pci_arfcn_r13_s::pack(bit_ref& bref) const { - static const char* options[] = {"on", "off"}; - return convert_enum_idx(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_pdsch_hop_cfg_sc_mtch_r14_e_"); -} + HANDLE_CODE(bref.pack(carrier_freq_r13_present, 1)); -const char* sc_mtch_info_br_r14_s::mpdcch_pdsch_cemode_cfg_sc_mtch_r14_opts::to_string() const -{ - static const char* options[] = {"ce-ModeA", "ce-ModeB"}; - return convert_enum_idx(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_pdsch_cemode_cfg_sc_mtch_r14_e_"); -} + HANDLE_CODE(pack_integer(bref, pci_r13, (uint16_t)0u, (uint16_t)503u)); + if (carrier_freq_r13_present) { + HANDLE_CODE(pack_integer(bref, carrier_freq_r13, (uint32_t)0u, (uint32_t)262143u)); + } -const char* sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_opts::to_string() const -{ - static const char* options[] = {"bw1dot4", "bw5"}; - return convert_enum_idx(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_e_"); -} -float sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_opts::to_number() const -{ - static const float options[] = {1.4, 5.0}; - return map_enum_number(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_e_"); + return SRSASN_SUCCESS; } -const char* sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_opts::to_number_string() const +SRSASN_CODE pci_arfcn_r13_s::unpack(cbit_ref& bref) { - static const char* options[] = {"1.4", "5"}; - return convert_enum_idx(options, 2, value, "sc_mtch_info_br_r14_s::mpdcch_pdsch_max_bw_sc_mtch_r14_e_"); -} + HANDLE_CODE(bref.unpack(carrier_freq_r13_present, 1)); -const char* sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_opts::to_string() const -{ - static const char* options[] = { - "zero", "oneEighth", "oneQuarter", "threeEighth", "oneHalf", "fiveEighth", "threeQuarter", "sevenEighth"}; - return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_e_"); -} -float sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_opts::to_number() const -{ - static const float options[] = {0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875}; - return map_enum_number(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_e_"); -} -const char* sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_opts::to_number_string() const -{ - static const char* options[] = {"0", "1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "7/8"}; - return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::mpdcch_offset_sc_mtch_r14_e_"); -} + HANDLE_CODE(unpack_integer(pci_r13, bref, (uint16_t)0u, (uint16_t)503u)); + if (carrier_freq_r13_present) { + HANDLE_CODE(unpack_integer(carrier_freq_r13, bref, (uint32_t)0u, (uint32_t)262143u)); + } -const char* sc_mtch_info_br_r14_s::p_a_r14_opts::to_string() const -{ - static const char* options[] = {"dB-6", "dB-4dot77", "dB-3", "dB-1dot77", "dB0", "dB1", "dB2", "dB3"}; - return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::p_a_r14_e_"); -} -float sc_mtch_info_br_r14_s::p_a_r14_opts::to_number() const -{ - static const float options[] = {-6.0, -4.77, -3.0, -1.77, 0.0, 1.0, 2.0, 3.0}; - return map_enum_number(options, 8, value, "sc_mtch_info_br_r14_s::p_a_r14_e_"); + return SRSASN_SUCCESS; } -const char* sc_mtch_info_br_r14_s::p_a_r14_opts::to_number_string() const +void pci_arfcn_r13_s::to_json(json_writer& j) const { - static const char* options[] = {"-6", "-4.77", "-3", "-1.77", "0", "1", "2", "3"}; - return convert_enum_idx(options, 8, value, "sc_mtch_info_br_r14_s::p_a_r14_e_"); + j.start_obj(); + j.write_int("physCellId-r13", pci_r13); + if (carrier_freq_r13_present) { + j.write_int("carrierFreq-r13", carrier_freq_r13); + } + j.end_obj(); } // SC-MTCH-Info-r13 ::= SEQUENCE @@ -4067,6 +4430,61 @@ const char* sc_mtch_info_r13_s::p_a_r13_opts::to_number_string() const return convert_enum_idx(options, 8, value, "sc_mtch_info_r13_s::p_a_r13_e_"); } +// SCPTMConfiguration-BR-v1610 ::= SEQUENCE +SRSASN_CODE scptm_cfg_br_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(multi_tb_gap_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, sc_mtch_info_list_multi_tb_r16, 0, 128)); + if (multi_tb_gap_r16_present) { + HANDLE_CODE(multi_tb_gap_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE scptm_cfg_br_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(multi_tb_gap_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(sc_mtch_info_list_multi_tb_r16, bref, 0, 128)); + if (multi_tb_gap_r16_present) { + HANDLE_CODE(multi_tb_gap_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void scptm_cfg_br_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("sc-MTCH-InfoList-MultiTB-r16"); + for (const auto& e1 : sc_mtch_info_list_multi_tb_r16) { + e1.to_json(j); + } + j.end_array(); + if (multi_tb_gap_r16_present) { + j.write_str("multiTB-Gap-r16", multi_tb_gap_r16.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +const char* scptm_cfg_br_v1610_s::multi_tb_gap_r16_opts::to_string() const +{ + static const char* options[] = {"sf2", "sf4", "sf8", "sf16", "sf32", "sf64", "sf128", "spare"}; + return convert_enum_idx(options, 8, value, "scptm_cfg_br_v1610_s::multi_tb_gap_r16_e_"); +} +uint8_t scptm_cfg_br_v1610_s::multi_tb_gap_r16_opts::to_number() const +{ + static const uint8_t options[] = {2, 4, 8, 16, 32, 64, 128}; + return map_enum_number(options, 7, value, "scptm_cfg_br_v1610_s::multi_tb_gap_r16_e_"); +} + // SCPTMConfiguration-v1340 ::= SEQUENCE SRSASN_CODE scptm_cfg_v1340_s::pack(bit_ref& bref) const { @@ -4122,6 +4540,9 @@ SRSASN_CODE scptm_cfg_br_r14_s::pack(bit_ref& bref) const if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -4142,6 +4563,9 @@ SRSASN_CODE scptm_cfg_br_r14_s::unpack(cbit_ref& bref) if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -4168,8 +4592,7 @@ void scptm_cfg_br_r14_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -4577,15 +5000,15 @@ const char* init_ue_id_c::types_opts::to_string() const return convert_enum_idx(options, 2, value, "init_ue_id_c::types"); } -const char* init_ue_id_minus5_gc_c::types_opts::to_string() const +const char* init_ue_id_minus5_gc_r15_c::types_opts::to_string() const { static const char* options[] = {"ng-5G-S-TMSI-Part1", "randomValue"}; - return convert_enum_idx(options, 2, value, "init_ue_id_minus5_gc_c::types"); + return convert_enum_idx(options, 2, value, "init_ue_id_minus5_gc_r15_c::types"); } -int8_t init_ue_id_minus5_gc_c::types_opts::to_number() const +int8_t init_ue_id_minus5_gc_r15_c::types_opts::to_number() const { static const int8_t options[] = {-5}; - return map_enum_number(options, 1, value, "init_ue_id_minus5_gc_c::types"); + return map_enum_number(options, 1, value, "init_ue_id_minus5_gc_r15_c::types"); } const char* rrc_conn_resume_request_minus5_gc_r15_ies_s::resume_id_r15_c_::types_opts::to_string() const @@ -4618,6 +5041,17 @@ const char* rrc_conn_resume_request_r13_s::crit_exts_c_::types_opts::to_string() return convert_enum_idx(options, 2, value, "rrc_conn_resume_request_r13_s::crit_exts_c_::types"); } +const char* rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_::types_opts::to_string() const +{ + static const char* options[] = {"rrcEarlyDataRequest-5GC-r16", "criticalExtensionsFuture-r16"}; + return convert_enum_idx(options, 2, value, "rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_::types"); +} +int8_t rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_::types_opts::to_number() const +{ + static const int8_t options[] = {-5}; + return map_enum_number(options, 1, value, "rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_::types"); +} + const char* rrc_early_data_request_r15_s::crit_exts_c_::types_opts::to_string() const { static const char* options[] = {"rrcEarlyDataRequest-r15", "criticalExtensionsFuture"}; @@ -4815,6 +5249,18 @@ const char* rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::types_opts::to return convert_enum_idx(options, 2, value, "rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::types"); } +const char* rlf_report_r9_s::failed_nr_pcell_id_r16_c_::types_opts::to_string() const +{ + static const char* options[] = {"cellGlobalId", "pci-arfcn"}; + return convert_enum_idx(options, 2, value, "rlf_report_r9_s::failed_nr_pcell_id_r16_c_::types"); +} + +const char* rlf_report_r9_s::reconnect_cell_id_r16_c_::types_opts::to_string() const +{ + static const char* options[] = {"nrReconnectCellId", "eutraReconnectCellId"}; + return convert_enum_idx(options, 2, value, "rlf_report_r9_s::reconnect_cell_id_r16_c_::types"); +} + const char* tdm_assist_info_r11_c::types_opts::to_string() const { static const char* options[] = {"drx-AssistanceInfo-r11", "idc-SubframePatternList-r11"}; @@ -4827,6 +5273,12 @@ const char* inter_freq_rstd_meas_ind_r10_ies_s::rstd_inter_freq_ind_r10_c_::type return convert_enum_idx(options, 2, value, "inter_freq_rstd_meas_ind_r10_ies_s::rstd_inter_freq_ind_r10_c_::types"); } +const char* pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::types_opts::to_string() const +{ + static const char* options[] = {"pur-ReleaseRequest", "pur-SetupRequest"}; + return convert_enum_idx(options, 2, value, "pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::types"); +} + const char* proximity_ind_r9_ies_s::carrier_freq_r9_c_::types_opts::to_string() const { static const char* options[] = {"eutra-r9", "utra-r9", "eutra2-v9e0"}; @@ -4841,6 +5293,13 @@ uint8_t proximity_ind_r9_ies_s::carrier_freq_r9_c_::types_opts::to_number() cons return 0; } +const char* ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::types_opts::to_string() const +{ + static const char* options[] = { + "dedicatedInfoNAS-r16", "dedicatedInfoCDMA2000-1XRTT-r16", "dedicatedInfoCDMA2000-HRPD-r16"}; + return convert_enum_idx(options, 3, value, "ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::types"); +} + const char* ul_info_transfer_r8_ies_s::ded_info_type_c_::types_opts::to_string() const { static const char* options[] = {"dedicatedInfoNAS", "dedicatedInfoCDMA2000-1XRTT", "dedicatedInfoCDMA2000-HRPD"}; @@ -4864,6 +5323,12 @@ const char* counter_check_resp_s::crit_exts_c_::types_opts::to_string() const return convert_enum_idx(options, 2, value, "counter_check_resp_s::crit_exts_c_::types"); } +const char* fail_info_r16_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"failureInformation-r16", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "fail_info_r16_s::crit_exts_c_::types"); +} + const char* in_dev_coex_ind_r11_s::crit_exts_c_::c1_c_::types_opts::to_string() const { static const char* options[] = {"inDeviceCoexIndication-r11", "spare3", "spare2", "spare1"}; @@ -4888,6 +5353,12 @@ const char* mbms_interest_ind_r11_s::crit_exts_c_::c1_c_::types_opts::to_string( return convert_enum_idx(options, 4, value, "mbms_interest_ind_r11_s::crit_exts_c_::c1_c_::types"); } +const char* mcg_fail_info_r16_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"mcgFailureInformation", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "mcg_fail_info_r16_s::crit_exts_c_::types"); +} + const char* meas_report_app_layer_r15_s::crit_exts_c_::types_opts::to_string() const { static const char* options[] = {"measReportAppLayer-r15", "criticalExtensionsFuture"}; @@ -4901,6 +5372,12 @@ const char* meas_report_s::crit_exts_c_::c1_c_::types_opts::to_string() const return convert_enum_idx(options, 8, value, "meas_report_s::crit_exts_c_::c1_c_::types"); } +const char* pur_cfg_request_r16_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"purConfigurationRequest", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "pur_cfg_request_r16_s::crit_exts_c_::types"); +} + const char* proximity_ind_r9_s::crit_exts_c_::c1_c_::types_opts::to_string() const { static const char* options[] = {"proximityIndication-r9", "spare3", "spare2", "spare1"}; @@ -4986,6 +5463,12 @@ const char* ue_info_resp_r9_s::crit_exts_c_::c1_c_::types_opts::to_string() cons return convert_enum_idx(options, 4, value, "ue_info_resp_r9_s::crit_exts_c_::c1_c_::types"); } +const char* ul_ded_msg_segment_r16_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"ulDedicatedMessageSegment-r16", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "ul_ded_msg_segment_r16_s::crit_exts_c_::types"); +} + const char* ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::types_opts::to_string() const { static const char* options[] = {"ulHandoverPreparationTransfer-r8", "spare3", "spare2", "spare1"}; @@ -4994,10 +5477,16 @@ const char* ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::types_opts::to_string() const char* ul_info_transfer_s::crit_exts_c_::c1_c_::types_opts::to_string() const { - static const char* options[] = {"ulInformationTransfer-r8", "spare3", "spare2", "spare1"}; + static const char* options[] = {"ulInformationTransfer-r8", "ulInformationTransfer-r16", "spare2", "spare1"}; return convert_enum_idx(options, 4, value, "ul_info_transfer_s::crit_exts_c_::c1_c_::types"); } +const char* ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_::types_opts::to_string() const +{ + static const char* options[] = {"ulInformationTransferIRAT-r16", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 4, value, "ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_::types"); +} + const char* ul_info_transfer_mrdc_r15_s::crit_exts_c_::c1_c_::types_opts::to_string() const { static const char* options[] = {"ulInformationTransferMRDC-r15", "spare3", "spare2", "spare1"}; @@ -5049,11 +5538,11 @@ const char* ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::types_opts::to_string() "scgFailureInformationNR-r15", "measReportAppLayer-r15", "failureInformation-r15", - "spare5", - "spare4", - "spare3", - "spare2", - "spare1"}; + "ulDedicatedMessageSegment-r16", + "purConfigurationRequest-r16", + "failureInformation-r16", + "mcgFailureInformation-r16", + "ulInformationTransferIRAT-r16"}; return convert_enum_idx(options, 16, value, "ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::types"); } @@ -5268,63 +5757,36 @@ void mimo_ue_params_v13e0_s::to_json(json_writer& j) const j.end_obj(); } -// MeasResult3EUTRA-r15 ::= SEQUENCE -SRSASN_CODE meas_result3_eutra_r15_s::pack(bit_ref& bref) const +// MeasResultSCG-FailureMRDC-r15 ::= SEQUENCE +SRSASN_CODE meas_result_scg_fail_mrdc_r15_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(meas_result_serving_cell_r15_present, 1)); - HANDLE_CODE(bref.pack(meas_result_neigh_cell_list_r15_present, 1)); - - HANDLE_CODE(pack_integer(bref, carrier_freq_r15, (uint32_t)0u, (uint32_t)262143u)); - if (meas_result_serving_cell_r15_present) { - HANDLE_CODE(meas_result_serving_cell_r15.pack(bref)); - } - if (meas_result_neigh_cell_list_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_neigh_cell_list_r15, 1, 8)); - } + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_freq_list_eutra_r15, 1, 8)); - return SRSASN_SUCCESS; -} -SRSASN_CODE meas_result3_eutra_r15_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(meas_result_serving_cell_r15_present, 1)); - HANDLE_CODE(bref.unpack(meas_result_neigh_cell_list_r15_present, 1)); + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= location_info_r16.is_present(); + group_flags[0] |= log_meas_result_list_bt_r16.is_present(); + group_flags[0] |= log_meas_result_list_wlan_r16.is_present(); + group_flags.pack(bref); - HANDLE_CODE(unpack_integer(carrier_freq_r15, bref, (uint32_t)0u, (uint32_t)262143u)); - if (meas_result_serving_cell_r15_present) { - HANDLE_CODE(meas_result_serving_cell_r15.unpack(bref)); - } - if (meas_result_neigh_cell_list_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(meas_result_neigh_cell_list_r15, bref, 1, 8)); - } + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); - return SRSASN_SUCCESS; -} -void meas_result3_eutra_r15_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("carrierFreq-r15", carrier_freq_r15); - if (meas_result_serving_cell_r15_present) { - j.write_fieldname("measResultServingCell-r15"); - meas_result_serving_cell_r15.to_json(j); - } - if (meas_result_neigh_cell_list_r15_present) { - j.start_array("measResultNeighCellList-r15"); - for (const auto& e1 : meas_result_neigh_cell_list_r15) { - e1.to_json(j); + HANDLE_CODE(bref.pack(location_info_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(log_meas_result_list_bt_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(log_meas_result_list_wlan_r16.is_present(), 1)); + if (location_info_r16.is_present()) { + HANDLE_CODE(location_info_r16->pack(bref)); + } + if (log_meas_result_list_bt_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *log_meas_result_list_bt_r16, 1, 32)); + } + if (log_meas_result_list_wlan_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *log_meas_result_list_wlan_r16, 1, 32)); + } } - j.end_array(); } - j.end_obj(); -} - -// MeasResultSCG-FailureMRDC-r15 ::= SEQUENCE -SRSASN_CODE meas_result_scg_fail_mrdc_r15_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_freq_list_eutra_r15, 1, 8)); - return SRSASN_SUCCESS; } SRSASN_CODE meas_result_scg_fail_mrdc_r15_s::unpack(cbit_ref& bref) @@ -5332,6 +5794,33 @@ SRSASN_CODE meas_result_scg_fail_mrdc_r15_s::unpack(cbit_ref& bref) bref.unpack(ext, 1); HANDLE_CODE(unpack_dyn_seq_of(meas_result_freq_list_eutra_r15, bref, 1, 8)); + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool location_info_r16_present; + HANDLE_CODE(bref.unpack(location_info_r16_present, 1)); + location_info_r16.set_present(location_info_r16_present); + bool log_meas_result_list_bt_r16_present; + HANDLE_CODE(bref.unpack(log_meas_result_list_bt_r16_present, 1)); + log_meas_result_list_bt_r16.set_present(log_meas_result_list_bt_r16_present); + bool log_meas_result_list_wlan_r16_present; + HANDLE_CODE(bref.unpack(log_meas_result_list_wlan_r16_present, 1)); + log_meas_result_list_wlan_r16.set_present(log_meas_result_list_wlan_r16_present); + if (location_info_r16.is_present()) { + HANDLE_CODE(location_info_r16->unpack(bref)); + } + if (log_meas_result_list_bt_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*log_meas_result_list_bt_r16, bref, 1, 32)); + } + if (log_meas_result_list_wlan_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*log_meas_result_list_wlan_r16, bref, 1, 32)); + } + } + } return SRSASN_SUCCESS; } void meas_result_scg_fail_mrdc_r15_s::to_json(json_writer& j) const @@ -5342,6 +5831,26 @@ void meas_result_scg_fail_mrdc_r15_s::to_json(json_writer& j) const e1.to_json(j); } j.end_array(); + if (ext) { + if (location_info_r16.is_present()) { + j.write_fieldname("locationInfo-r16"); + location_info_r16->to_json(j); + } + if (log_meas_result_list_bt_r16.is_present()) { + j.start_array("logMeasResultListBT-r16"); + for (const auto& e1 : *log_meas_result_list_bt_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (log_meas_result_list_wlan_r16.is_present()) { + j.start_array("logMeasResultListWLAN-r16"); + for (const auto& e1 : *log_meas_result_list_wlan_r16) { + e1.to_json(j); + } + j.end_array(); + } + } j.end_obj(); } @@ -5404,6 +5913,18 @@ void scg_fail_info_v12d0b_ies_s::to_json(json_writer& j) const j.end_obj(); } +const char* v2x_band_params_eutra_nr_r16_c::types_opts::to_string() const +{ + static const char* options[] = {"eutra", "nr"}; + return convert_enum_idx(options, 2, value, "v2x_band_params_eutra_nr_r16_c::types"); +} + +const char* v2x_band_params_eutra_nr_v1630_c::types_opts::to_string() const +{ + static const char* options[] = {"eutra", "nr"}; + return convert_enum_idx(options, 2, value, "v2x_band_params_eutra_nr_v1630_c::types"); +} + const char* mbms_params_v1470_s::mbms_max_bw_r14_c_::types_opts::to_string() const { static const char* options[] = {"implicitValue", "explicitValue"}; @@ -6123,6 +6644,81 @@ void meas_result_serv_cell_scg_r12_s::to_json(json_writer& j) const j.end_obj(); } +// RLF-Report-NB-r16 ::= SEQUENCE +SRSASN_CODE rlf_report_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(reest_cell_id_r16_present, 1)); + HANDLE_CODE(bref.pack(location_info_r16_present, 1)); + HANDLE_CODE(bref.pack(time_since_fail_r16_present, 1)); + + HANDLE_CODE(failed_pcell_id_r16.pack(bref)); + if (reest_cell_id_r16_present) { + HANDLE_CODE(reest_cell_id_r16.pack(bref)); + } + if (location_info_r16_present) { + HANDLE_CODE(location_info_r16.pack(bref)); + } + HANDLE_CODE(bref.pack(meas_result_last_serv_cell_r16.nrsrq_result_r16_present, 1)); + HANDLE_CODE(pack_integer(bref, meas_result_last_serv_cell_r16.nrsrp_result_r16, (uint8_t)0u, (uint8_t)113u)); + if (meas_result_last_serv_cell_r16.nrsrq_result_r16_present) { + HANDLE_CODE(pack_integer(bref, meas_result_last_serv_cell_r16.nrsrq_result_r16, (int8_t)-30, (int8_t)46)); + } + if (time_since_fail_r16_present) { + HANDLE_CODE(pack_integer(bref, time_since_fail_r16, (uint32_t)0u, (uint32_t)172800u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rlf_report_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(reest_cell_id_r16_present, 1)); + HANDLE_CODE(bref.unpack(location_info_r16_present, 1)); + HANDLE_CODE(bref.unpack(time_since_fail_r16_present, 1)); + + HANDLE_CODE(failed_pcell_id_r16.unpack(bref)); + if (reest_cell_id_r16_present) { + HANDLE_CODE(reest_cell_id_r16.unpack(bref)); + } + if (location_info_r16_present) { + HANDLE_CODE(location_info_r16.unpack(bref)); + } + HANDLE_CODE(bref.unpack(meas_result_last_serv_cell_r16.nrsrq_result_r16_present, 1)); + HANDLE_CODE(unpack_integer(meas_result_last_serv_cell_r16.nrsrp_result_r16, bref, (uint8_t)0u, (uint8_t)113u)); + if (meas_result_last_serv_cell_r16.nrsrq_result_r16_present) { + HANDLE_CODE(unpack_integer(meas_result_last_serv_cell_r16.nrsrq_result_r16, bref, (int8_t)-30, (int8_t)46)); + } + if (time_since_fail_r16_present) { + HANDLE_CODE(unpack_integer(time_since_fail_r16, bref, (uint32_t)0u, (uint32_t)172800u)); + } + + return SRSASN_SUCCESS; +} +void rlf_report_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("failedPCellId-r16"); + failed_pcell_id_r16.to_json(j); + if (reest_cell_id_r16_present) { + j.write_fieldname("reestablishmentCellId-r16"); + reest_cell_id_r16.to_json(j); + } + if (location_info_r16_present) { + j.write_fieldname("locationInfo-r16"); + location_info_r16.to_json(j); + } + j.write_fieldname("measResultLastServCell-r16"); + j.start_obj(); + j.write_int("nrsrpResult-r16", meas_result_last_serv_cell_r16.nrsrp_result_r16); + if (meas_result_last_serv_cell_r16.nrsrq_result_r16_present) { + j.write_int("nrsrqResult-r16", meas_result_last_serv_cell_r16.nrsrq_result_r16); + } + j.end_obj(); + if (time_since_fail_r16_present) { + j.write_int("timeSinceFailure-r16", time_since_fail_r16); + } + j.end_obj(); +} + // SBCCH-SL-BCH-Message ::= SEQUENCE SRSASN_CODE sbcch_sl_bch_msg_s::pack(bit_ref& bref) const { @@ -8091,6 +8687,7 @@ SRSASN_CODE sl_v2x_precfg_r14_s::pack(bit_ref& bref) const group_flags[0] |= sync_freq_list_r15.is_present(); group_flags[0] |= slss_tx_multi_freq_r15_present; group_flags[0] |= v2x_tx_profile_list_r15.is_present(); + group_flags[1] |= anchor_carrier_freq_list_nr_r16.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -8110,6 +8707,15 @@ SRSASN_CODE sl_v2x_precfg_r14_s::pack(bit_ref& bref) const HANDLE_CODE(pack_dyn_seq_of(bref, *v2x_tx_profile_list_r15, 1, 256)); } } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(anchor_carrier_freq_list_nr_r16.is_present(), 1)); + if (anchor_carrier_freq_list_nr_r16.is_present()) { + HANDLE_CODE( + pack_dyn_seq_of(bref, *anchor_carrier_freq_list_nr_r16, 1, 8, integer_packer(0, 3279165))); + } + } } return SRSASN_SUCCESS; } @@ -8128,7 +8734,7 @@ SRSASN_CODE sl_v2x_precfg_r14_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(1); + ext_groups_unpacker_guard group_flags(2); group_flags.unpack(bref); if (group_flags[0]) { @@ -8154,6 +8760,17 @@ SRSASN_CODE sl_v2x_precfg_r14_s::unpack(cbit_ref& bref) HANDLE_CODE(unpack_dyn_seq_of(*v2x_tx_profile_list_r15, bref, 1, 256)); } } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool anchor_carrier_freq_list_nr_r16_present; + HANDLE_CODE(bref.unpack(anchor_carrier_freq_list_nr_r16_present, 1)); + anchor_carrier_freq_list_nr_r16.set_present(anchor_carrier_freq_list_nr_r16_present); + if (anchor_carrier_freq_list_nr_r16.is_present()) { + HANDLE_CODE( + unpack_dyn_seq_of(*anchor_carrier_freq_list_nr_r16, bref, 1, 8, integer_packer(0, 3279165))); + } + } } return SRSASN_SUCCESS; } @@ -8198,6 +8815,13 @@ void sl_v2x_precfg_r14_s::to_json(json_writer& j) const } j.end_array(); } + if (anchor_carrier_freq_list_nr_r16.is_present()) { + j.start_array("anchorCarrierFreqListNR-r16"); + for (const auto& e1 : *anchor_carrier_freq_list_nr_r16) { + j.write_int(e1); + } + j.end_array(); + } } j.end_obj(); } @@ -8223,6 +8847,40 @@ const char* ue_radio_paging_info_s::crit_exts_c_::c1_c_::types_opts::to_string() return convert_enum_idx(options, 8, value, "ue_radio_paging_info_s::crit_exts_c_::c1_c_::types"); } +// VarConditionalReconfiguration ::= SEQUENCE +SRSASN_CODE var_conditional_recfg_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(cond_recfg_list_r16_present, 1)); + + if (cond_recfg_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, cond_recfg_list_r16, 1, 8)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE var_conditional_recfg_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(cond_recfg_list_r16_present, 1)); + + if (cond_recfg_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(cond_recfg_list_r16, bref, 1, 8)); + } + + return SRSASN_SUCCESS; +} +void var_conditional_recfg_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (cond_recfg_list_r16_present) { + j.start_array("condReconfigurationList-r16"); + for (const auto& e1 : cond_recfg_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + // VarConnEstFailReport-r11 ::= SEQUENCE SRSASN_CODE var_conn_est_fail_report_r11_s::pack(bit_ref& bref) const { @@ -8492,6 +9150,117 @@ void var_log_meas_cfg_r15_s::to_json(json_writer& j) const j.end_obj(); } +// VarLogMeasConfig-r17 ::= SEQUENCE +SRSASN_CODE var_log_meas_cfg_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(area_cfg_r10_present, 1)); + HANDLE_CODE(bref.pack(area_cfg_v1130_present, 1)); + HANDLE_CODE(bref.pack(target_mbsfn_area_list_r12_present, 1)); + HANDLE_CODE(bref.pack(bt_name_list_r15_present, 1)); + HANDLE_CODE(bref.pack(wlan_name_list_r15_present, 1)); + HANDLE_CODE(bref.pack(logged_event_trigger_cfg_r17_present, 1)); + HANDLE_CODE(bref.pack(meas_uncom_bar_pre_r17_present, 1)); + + if (area_cfg_r10_present) { + HANDLE_CODE(area_cfg_r10.pack(bref)); + } + if (area_cfg_v1130_present) { + HANDLE_CODE(area_cfg_v1130.pack(bref)); + } + HANDLE_CODE(logging_dur_r10.pack(bref)); + HANDLE_CODE(logging_interv_r10.pack(bref)); + if (target_mbsfn_area_list_r12_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, target_mbsfn_area_list_r12, 0, 8)); + } + if (bt_name_list_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, bt_name_list_r15, 1, 4)); + } + if (wlan_name_list_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, wlan_name_list_r15, 1, 4)); + } + if (logged_event_trigger_cfg_r17_present) { + HANDLE_CODE(logged_event_trigger_cfg_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE var_log_meas_cfg_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(area_cfg_r10_present, 1)); + HANDLE_CODE(bref.unpack(area_cfg_v1130_present, 1)); + HANDLE_CODE(bref.unpack(target_mbsfn_area_list_r12_present, 1)); + HANDLE_CODE(bref.unpack(bt_name_list_r15_present, 1)); + HANDLE_CODE(bref.unpack(wlan_name_list_r15_present, 1)); + HANDLE_CODE(bref.unpack(logged_event_trigger_cfg_r17_present, 1)); + HANDLE_CODE(bref.unpack(meas_uncom_bar_pre_r17_present, 1)); + + if (area_cfg_r10_present) { + HANDLE_CODE(area_cfg_r10.unpack(bref)); + } + if (area_cfg_v1130_present) { + HANDLE_CODE(area_cfg_v1130.unpack(bref)); + } + HANDLE_CODE(logging_dur_r10.unpack(bref)); + HANDLE_CODE(logging_interv_r10.unpack(bref)); + if (target_mbsfn_area_list_r12_present) { + HANDLE_CODE(unpack_dyn_seq_of(target_mbsfn_area_list_r12, bref, 0, 8)); + } + if (bt_name_list_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(bt_name_list_r15, bref, 1, 4)); + } + if (wlan_name_list_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(wlan_name_list_r15, bref, 1, 4)); + } + if (logged_event_trigger_cfg_r17_present) { + HANDLE_CODE(logged_event_trigger_cfg_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void var_log_meas_cfg_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (area_cfg_r10_present) { + j.write_fieldname("areaConfiguration-r10"); + area_cfg_r10.to_json(j); + } + if (area_cfg_v1130_present) { + j.write_fieldname("areaConfiguration-v1130"); + area_cfg_v1130.to_json(j); + } + j.write_str("loggingDuration-r10", logging_dur_r10.to_string()); + j.write_str("loggingInterval-r10", logging_interv_r10.to_string()); + if (target_mbsfn_area_list_r12_present) { + j.start_array("targetMBSFN-AreaList-r12"); + for (const auto& e1 : target_mbsfn_area_list_r12) { + e1.to_json(j); + } + j.end_array(); + } + if (bt_name_list_r15_present) { + j.start_array("bt-NameList-r15"); + for (const auto& e1 : bt_name_list_r15) { + j.write_str(e1.to_string()); + } + j.end_array(); + } + if (wlan_name_list_r15_present) { + j.start_array("wlan-NameList-r15"); + for (const auto& e1 : wlan_name_list_r15) { + j.write_str(e1.to_string()); + } + j.end_array(); + } + if (logged_event_trigger_cfg_r17_present) { + j.write_fieldname("loggedEventTriggerConfig-r17"); + logged_event_trigger_cfg_r17.to_json(j); + } + if (meas_uncom_bar_pre_r17_present) { + j.write_str("measUncomBarPre-r17", "true"); + } + j.end_obj(); +} + // VarLogMeasReport-r10 ::= SEQUENCE SRSASN_CODE var_log_meas_report_r10_s::pack(bit_ref& bref) const { @@ -8625,6 +9394,55 @@ uint16_t var_meas_idle_cfg_r15_s::meas_idle_dur_r15_opts::to_number() const return map_enum_number(options, 7, value, "var_meas_idle_cfg_r15_s::meas_idle_dur_r15_e_"); } +// VarMeasIdleConfig-r16 ::= SEQUENCE +SRSASN_CODE var_meas_idle_cfg_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(meas_idle_carrier_list_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(validity_area_list_r16_present, 1)); + + if (meas_idle_carrier_list_nr_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_idle_carrier_list_nr_r16, 1, 8)); + } + if (validity_area_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, validity_area_list_r16, 1, 8)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE var_meas_idle_cfg_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(meas_idle_carrier_list_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(validity_area_list_r16_present, 1)); + + if (meas_idle_carrier_list_nr_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_idle_carrier_list_nr_r16, bref, 1, 8)); + } + if (validity_area_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(validity_area_list_r16, bref, 1, 8)); + } + + return SRSASN_SUCCESS; +} +void var_meas_idle_cfg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (meas_idle_carrier_list_nr_r16_present) { + j.start_array("measIdleCarrierListNR-r16"); + for (const auto& e1 : meas_idle_carrier_list_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (validity_area_list_r16_present) { + j.start_array("validityAreaList-r16"); + for (const auto& e1 : validity_area_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + // VarMeasIdleReport-r15 ::= SEQUENCE SRSASN_CODE var_meas_idle_report_r15_s::pack(bit_ref& bref) const { @@ -8649,6 +9467,59 @@ void var_meas_idle_report_r15_s::to_json(json_writer& j) const j.end_obj(); } +// VarMeasIdleReport-r16 ::= SEQUENCE +SRSASN_CODE var_meas_idle_report_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(meas_report_idle_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_report_idle_nr_r16_present, 1)); + + if (meas_report_idle_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_report_idle_r16, 1, 5, SeqOfPacker(1, 8, Packer()))); + } + if (meas_report_idle_nr_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_report_idle_nr_r16, 1, 8)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE var_meas_idle_report_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(meas_report_idle_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_report_idle_nr_r16_present, 1)); + + if (meas_report_idle_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_report_idle_r16, bref, 1, 5, SeqOfPacker(1, 8, Packer()))); + } + if (meas_report_idle_nr_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_report_idle_nr_r16, bref, 1, 8)); + } + + return SRSASN_SUCCESS; +} +void var_meas_idle_report_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (meas_report_idle_r16_present) { + j.start_array("measReportIdle-r16"); + for (const auto& e1 : meas_report_idle_r16) { + j.start_array(); + for (const auto& e2 : e1) { + e2.to_json(j); + } + j.end_array(); + } + j.end_array(); + } + if (meas_report_idle_nr_r16_present) { + j.start_array("measReportIdleNR-r16"); + for (const auto& e1 : meas_report_idle_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + // VarMeasReport ::= SEQUENCE SRSASN_CODE var_meas_report_s::pack(bit_ref& bref) const { @@ -8730,6 +9601,34 @@ void var_meas_report_s::to_json(json_writer& j) const j.end_obj(); } +// VarRLF-Report-NB-r16 ::= SEQUENCE +SRSASN_CODE var_rlf_report_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(rlf_report_r16.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, plmn_id_list_r16, 1, 16)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE var_rlf_report_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(rlf_report_r16.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(plmn_id_list_r16, bref, 1, 16)); + + return SRSASN_SUCCESS; +} +void var_rlf_report_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("rlf-Report-r16"); + rlf_report_r16.to_json(j); + j.start_array("plmn-IdentityList-r16"); + for (const auto& e1 : plmn_id_list_r16) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + // VarRLF-Report-r10 ::= SEQUENCE SRSASN_CODE var_rlf_report_r10_s::pack(bit_ref& bref) const { diff --git a/lib/src/asn1/rrc/bcch_msg.cc b/lib/src/asn1/rrc/bcch_msg.cc index 4db742bd52..e770dd8ce8 100644 --- a/lib/src/asn1/rrc/bcch_msg.cc +++ b/lib/src/asn1/rrc/bcch_msg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -270,6 +270,65 @@ void neigh_cells_per_bandclass_cdma2000_v920_s::to_json(json_writer& j) const j.end_obj(); } +// PhysCellIdRangeNR-r16 ::= SEQUENCE +SRSASN_CODE pci_range_nr_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(range_present, 1)); + + HANDLE_CODE(pack_integer(bref, start, (uint16_t)0u, (uint16_t)1007u)); + if (range_present) { + HANDLE_CODE(range.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pci_range_nr_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(range_present, 1)); + + HANDLE_CODE(unpack_integer(start, bref, (uint16_t)0u, (uint16_t)1007u)); + if (range_present) { + HANDLE_CODE(range.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void pci_range_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("start", start); + if (range_present) { + j.write_str("range", range.to_string()); + } + j.end_obj(); +} + +const char* pci_range_nr_r16_s::range_opts::to_string() const +{ + static const char* options[] = {"n4", + "n8", + "n12", + "n16", + "n24", + "n32", + "n48", + "n64", + "n84", + "n96", + "n128", + "n168", + "n252", + "n504", + "n1008", + "spare1"}; + return convert_enum_idx(options, 16, value, "pci_range_nr_r16_s::range_e_"); +} +uint16_t pci_range_nr_r16_s::range_opts::to_number() const +{ + static const uint16_t options[] = {4, 8, 12, 16, 24, 32, 48, 64, 84, 96, 128, 168, 252, 504, 1008}; + return map_enum_number(options, 15, value, "pci_range_nr_r16_s::range_e_"); +} + // RedistributionNeighCell-r13 ::= SEQUENCE SRSASN_CODE redist_neigh_cell_r13_s::pack(bit_ref& bref) const { @@ -340,6 +399,38 @@ void ac_barr_cfg1_xrtt_r9_s::to_json(json_writer& j) const j.end_obj(); } +// BeamMeasConfigIdleNR-r16 ::= SEQUENCE +SRSASN_CODE beam_meas_cfg_idle_nr_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(report_quant_rs_idx_nr_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, max_report_rs_idx_r16, (uint8_t)0u, (uint8_t)32u)); + HANDLE_CODE(bref.pack(report_rs_idx_results_nr_r16, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE beam_meas_cfg_idle_nr_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(report_quant_rs_idx_nr_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(max_report_rs_idx_r16, bref, (uint8_t)0u, (uint8_t)32u)); + HANDLE_CODE(bref.unpack(report_rs_idx_results_nr_r16, 1)); + + return SRSASN_SUCCESS; +} +void beam_meas_cfg_idle_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("reportQuantityRS-IndexNR-r16", report_quant_rs_idx_nr_r16.to_string()); + j.write_int("maxReportRS-Index-r16", max_report_rs_idx_r16); + j.write_bool("reportRS-IndexResultsNR-r16", report_rs_idx_results_nr_r16); + j.end_obj(); +} + +const char* beam_meas_cfg_idle_nr_r16_s::report_quant_rs_idx_nr_r16_opts::to_string() const +{ + static const char* options[] = {"rsrp", "rsrq", "both"}; + return convert_enum_idx(options, 3, value, "beam_meas_cfg_idle_nr_r16_s::report_quant_rs_idx_nr_r16_e_"); +} + // CSFB-RegistrationParam1XRTT ::= SEQUENCE SRSASN_CODE csfb_regist_param1_xrtt_s::pack(bit_ref& bref) const { @@ -483,6 +574,26 @@ void inter_freq_neigh_cell_info_s::to_json(json_writer& j) const j.end_obj(); } +// InterFreqNeighCellInfo-v1610 ::= SEQUENCE +SRSASN_CODE inter_freq_neigh_cell_info_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(rss_meas_pwr_bias_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE inter_freq_neigh_cell_info_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(rss_meas_pwr_bias_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void inter_freq_neigh_cell_info_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("rss-MeasPowerBias-r16", rss_meas_pwr_bias_r16.to_string()); + j.end_obj(); +} + // PLMN-IdentityInfo2-r12 ::= CHOICE void plmn_id_info2_r12_c::destroy_() { @@ -783,6 +894,442 @@ void uac_barr_per_cat_r15_s::to_json(json_writer& j) const j.end_obj(); } +// MBSFN-AreaInfo-r16 ::= SEQUENCE +SRSASN_CODE mbsfn_area_info_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(time_separation_r16_present, 1)); + + HANDLE_CODE(pack_integer(bref, mbsfn_area_id_r16, (uint16_t)0u, (uint16_t)255u)); + HANDLE_CODE(pack_integer(bref, notif_ind_r16, (uint8_t)0u, (uint8_t)7u)); + HANDLE_CODE(mcch_cfg_r16.mcch_repeat_period_r16.pack(bref)); + HANDLE_CODE(mcch_cfg_r16.mcch_mod_period_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, mcch_cfg_r16.mcch_offset_r16, (uint8_t)0u, (uint8_t)10u)); + HANDLE_CODE(mcch_cfg_r16.sf_alloc_info_r16.pack(bref)); + HANDLE_CODE(mcch_cfg_r16.sig_mcs_r16.pack(bref)); + HANDLE_CODE(subcarrier_spacing_mbms_r16.pack(bref)); + if (time_separation_r16_present) { + HANDLE_CODE(time_separation_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE mbsfn_area_info_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(time_separation_r16_present, 1)); + + HANDLE_CODE(unpack_integer(mbsfn_area_id_r16, bref, (uint16_t)0u, (uint16_t)255u)); + HANDLE_CODE(unpack_integer(notif_ind_r16, bref, (uint8_t)0u, (uint8_t)7u)); + HANDLE_CODE(mcch_cfg_r16.mcch_repeat_period_r16.unpack(bref)); + HANDLE_CODE(mcch_cfg_r16.mcch_mod_period_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(mcch_cfg_r16.mcch_offset_r16, bref, (uint8_t)0u, (uint8_t)10u)); + HANDLE_CODE(mcch_cfg_r16.sf_alloc_info_r16.unpack(bref)); + HANDLE_CODE(mcch_cfg_r16.sig_mcs_r16.unpack(bref)); + HANDLE_CODE(subcarrier_spacing_mbms_r16.unpack(bref)); + if (time_separation_r16_present) { + HANDLE_CODE(time_separation_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void mbsfn_area_info_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("mbsfn-AreaId-r16", mbsfn_area_id_r16); + j.write_int("notificationIndicator-r16", notif_ind_r16); + j.write_fieldname("mcch-Config-r16"); + j.start_obj(); + j.write_str("mcch-RepetitionPeriod-r16", mcch_cfg_r16.mcch_repeat_period_r16.to_string()); + j.write_str("mcch-ModificationPeriod-r16", mcch_cfg_r16.mcch_mod_period_r16.to_string()); + j.write_int("mcch-Offset-r16", mcch_cfg_r16.mcch_offset_r16); + j.write_str("sf-AllocInfo-r16", mcch_cfg_r16.sf_alloc_info_r16.to_string()); + j.write_str("signallingMCS-r16", mcch_cfg_r16.sig_mcs_r16.to_string()); + j.end_obj(); + j.write_str("subcarrierSpacingMBMS-r16", subcarrier_spacing_mbms_r16.to_string()); + if (time_separation_r16_present) { + j.write_str("timeSeparation-r16", time_separation_r16.to_string()); + } + j.end_obj(); +} + +const char* mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_repeat_period_r16_opts::to_string() const +{ + static const char* options[] = {"rf1", + "rf2", + "rf4", + "rf8", + "rf16", + "rf32", + "rf64", + "rf128", + "rf256", + "spare7", + "spare6", + "spare5", + "spare4", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 16, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_repeat_period_r16_e_"); +} +uint16_t mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_repeat_period_r16_opts::to_number() const +{ + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256}; + return map_enum_number(options, 9, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_repeat_period_r16_e_"); +} + +const char* mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_mod_period_r16_opts::to_string() const +{ + static const char* options[] = {"rf1", + "rf2", + "rf4", + "rf8", + "rf16", + "rf32", + "rf64", + "rf128", + "rf256", + "rf512", + "rf1024", + "spare5", + "spare4", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 16, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_mod_period_r16_e_"); +} +uint16_t mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_mod_period_r16_opts::to_number() const +{ + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}; + return map_enum_number(options, 11, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_mod_period_r16_e_"); +} + +const char* mbsfn_area_info_r16_s::mcch_cfg_r16_s_::sig_mcs_r16_opts::to_string() const +{ + static const char* options[] = {"n2", "n7", "n13", "n19"}; + return convert_enum_idx(options, 4, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::sig_mcs_r16_e_"); +} +uint8_t mbsfn_area_info_r16_s::mcch_cfg_r16_s_::sig_mcs_r16_opts::to_number() const +{ + static const uint8_t options[] = {2, 7, 13, 19}; + return map_enum_number(options, 4, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::sig_mcs_r16_e_"); +} + +const char* mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_opts::to_string() const +{ + static const char* options[] = { + "kHz7dot5", "kHz2dot5", "kHz1dot25", "kHz0dot37", "kHz15-v1710", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 8, value, "mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_e_"); +} +float mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_opts::to_number() const +{ + static const float options[] = {7.5, 2.5, 1.25, 0.37, 15.0}; + return map_enum_number(options, 5, value, "mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_e_"); +} +const char* mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_opts::to_number_string() const +{ + static const char* options[] = {"7.5", "2.5", "1.25", "0.37", "15"}; + return convert_enum_idx(options, 8, value, "mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_e_"); +} + +const char* mbsfn_area_info_r16_s::time_separation_r16_opts::to_string() const +{ + static const char* options[] = {"sl2", "sl4"}; + return convert_enum_idx(options, 2, value, "mbsfn_area_info_r16_s::time_separation_r16_e_"); +} +uint8_t mbsfn_area_info_r16_s::time_separation_r16_opts::to_number() const +{ + static const uint8_t options[] = {2, 4}; + return map_enum_number(options, 2, value, "mbsfn_area_info_r16_s::time_separation_r16_e_"); +} + +// MTC-SSB2-LP-NR-r16 ::= SEQUENCE +SRSASN_CODE mtc_ssb2_lp_nr_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pci_list_r16_present, 1)); + + if (pci_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, pci_list_r16, 1, 64, integer_packer(0, 1007))); + } + HANDLE_CODE(periodicity_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mtc_ssb2_lp_nr_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(pci_list_r16_present, 1)); + + if (pci_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(pci_list_r16, bref, 1, 64, integer_packer(0, 1007))); + } + HANDLE_CODE(periodicity_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void mtc_ssb2_lp_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (pci_list_r16_present) { + j.start_array("pci-List-r16"); + for (const auto& e1 : pci_list_r16) { + j.write_int(e1); + } + j.end_array(); + } + j.write_str("periodicity-r16", periodicity_r16.to_string()); + j.end_obj(); +} + +const char* mtc_ssb2_lp_nr_r16_s::periodicity_r16_opts::to_string() const +{ + static const char* options[] = {"sf10", "sf20", "sf40", "sf80", "sf160", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 8, value, "mtc_ssb2_lp_nr_r16_s::periodicity_r16_e_"); +} +uint8_t mtc_ssb2_lp_nr_r16_s::periodicity_r16_opts::to_number() const +{ + static const uint8_t options[] = {10, 20, 40, 80, 160}; + return map_enum_number(options, 5, value, "mtc_ssb2_lp_nr_r16_s::periodicity_r16_e_"); +} + +// MeasIdleCarrierNR-r16 ::= SEQUENCE +SRSASN_CODE meas_idle_carrier_nr_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(freq_band_list_present, 1)); + HANDLE_CODE(bref.pack(meas_cell_list_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(quality_thres_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(ssb_meas_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(beam_meas_cfg_idle_r16_present, 1)); + + HANDLE_CODE(pack_integer(bref, carrier_freq_nr_r16, (uint32_t)0u, (uint32_t)3279165u)); + HANDLE_CODE(subcarrier_spacing_ssb_r16.pack(bref)); + if (freq_band_list_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list, 1, 32, integer_packer(1, 1024))); + } + if (meas_cell_list_nr_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_cell_list_nr_r16, 1, 8)); + } + HANDLE_CODE(report_quantities_nr_r16.pack(bref)); + if (quality_thres_nr_r16_present) { + HANDLE_CODE(bref.pack(quality_thres_nr_r16.idle_rsrp_thres_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(quality_thres_nr_r16.idle_rsrq_thres_nr_r16_present, 1)); + if (quality_thres_nr_r16.idle_rsrp_thres_nr_r16_present) { + HANDLE_CODE(pack_integer(bref, quality_thres_nr_r16.idle_rsrp_thres_nr_r16, (uint8_t)0u, (uint8_t)127u)); + } + if (quality_thres_nr_r16.idle_rsrq_thres_nr_r16_present) { + HANDLE_CODE(pack_integer(bref, quality_thres_nr_r16.idle_rsrq_thres_nr_r16, (uint8_t)0u, (uint8_t)127u)); + } + } + if (ssb_meas_cfg_r16_present) { + HANDLE_CODE(bref.pack(ssb_meas_cfg_r16.max_rs_idx_cell_qual_r16_present, 1)); + HANDLE_CODE(bref.pack(ssb_meas_cfg_r16.thresh_rs_idx_r16_present, 1)); + HANDLE_CODE(bref.pack(ssb_meas_cfg_r16.meas_timing_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(ssb_meas_cfg_r16.ssb_to_measure_r16_present, 1)); + HANDLE_CODE(bref.pack(ssb_meas_cfg_r16.ss_rssi_meas_r16_present, 1)); + if (ssb_meas_cfg_r16.max_rs_idx_cell_qual_r16_present) { + HANDLE_CODE(pack_integer(bref, ssb_meas_cfg_r16.max_rs_idx_cell_qual_r16, (uint8_t)1u, (uint8_t)16u)); + } + if (ssb_meas_cfg_r16.thresh_rs_idx_r16_present) { + HANDLE_CODE(ssb_meas_cfg_r16.thresh_rs_idx_r16.pack(bref)); + } + if (ssb_meas_cfg_r16.meas_timing_cfg_r16_present) { + HANDLE_CODE(ssb_meas_cfg_r16.meas_timing_cfg_r16.pack(bref)); + } + if (ssb_meas_cfg_r16.ssb_to_measure_r16_present) { + HANDLE_CODE(ssb_meas_cfg_r16.ssb_to_measure_r16.pack(bref)); + } + HANDLE_CODE(bref.pack(ssb_meas_cfg_r16.derive_ssb_idx_from_cell_r16, 1)); + if (ssb_meas_cfg_r16.ss_rssi_meas_r16_present) { + HANDLE_CODE(ssb_meas_cfg_r16.ss_rssi_meas_r16.pack(bref)); + } + } + if (beam_meas_cfg_idle_r16_present) { + HANDLE_CODE(beam_meas_cfg_idle_r16.pack(bref)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= subcarrier_spacing_ssb_r17_present; + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(subcarrier_spacing_ssb_r17_present, 1)); + if (subcarrier_spacing_ssb_r17_present) { + HANDLE_CODE(subcarrier_spacing_ssb_r17.pack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_idle_carrier_nr_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(freq_band_list_present, 1)); + HANDLE_CODE(bref.unpack(meas_cell_list_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(quality_thres_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(ssb_meas_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(beam_meas_cfg_idle_r16_present, 1)); + + HANDLE_CODE(unpack_integer(carrier_freq_nr_r16, bref, (uint32_t)0u, (uint32_t)3279165u)); + HANDLE_CODE(subcarrier_spacing_ssb_r16.unpack(bref)); + if (freq_band_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(freq_band_list, bref, 1, 32, integer_packer(1, 1024))); + } + if (meas_cell_list_nr_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_cell_list_nr_r16, bref, 1, 8)); + } + HANDLE_CODE(report_quantities_nr_r16.unpack(bref)); + if (quality_thres_nr_r16_present) { + HANDLE_CODE(bref.unpack(quality_thres_nr_r16.idle_rsrp_thres_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(quality_thres_nr_r16.idle_rsrq_thres_nr_r16_present, 1)); + if (quality_thres_nr_r16.idle_rsrp_thres_nr_r16_present) { + HANDLE_CODE(unpack_integer(quality_thres_nr_r16.idle_rsrp_thres_nr_r16, bref, (uint8_t)0u, (uint8_t)127u)); + } + if (quality_thres_nr_r16.idle_rsrq_thres_nr_r16_present) { + HANDLE_CODE(unpack_integer(quality_thres_nr_r16.idle_rsrq_thres_nr_r16, bref, (uint8_t)0u, (uint8_t)127u)); + } + } + if (ssb_meas_cfg_r16_present) { + HANDLE_CODE(bref.unpack(ssb_meas_cfg_r16.max_rs_idx_cell_qual_r16_present, 1)); + HANDLE_CODE(bref.unpack(ssb_meas_cfg_r16.thresh_rs_idx_r16_present, 1)); + HANDLE_CODE(bref.unpack(ssb_meas_cfg_r16.meas_timing_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(ssb_meas_cfg_r16.ssb_to_measure_r16_present, 1)); + HANDLE_CODE(bref.unpack(ssb_meas_cfg_r16.ss_rssi_meas_r16_present, 1)); + if (ssb_meas_cfg_r16.max_rs_idx_cell_qual_r16_present) { + HANDLE_CODE(unpack_integer(ssb_meas_cfg_r16.max_rs_idx_cell_qual_r16, bref, (uint8_t)1u, (uint8_t)16u)); + } + if (ssb_meas_cfg_r16.thresh_rs_idx_r16_present) { + HANDLE_CODE(ssb_meas_cfg_r16.thresh_rs_idx_r16.unpack(bref)); + } + if (ssb_meas_cfg_r16.meas_timing_cfg_r16_present) { + HANDLE_CODE(ssb_meas_cfg_r16.meas_timing_cfg_r16.unpack(bref)); + } + if (ssb_meas_cfg_r16.ssb_to_measure_r16_present) { + HANDLE_CODE(ssb_meas_cfg_r16.ssb_to_measure_r16.unpack(bref)); + } + HANDLE_CODE(bref.unpack(ssb_meas_cfg_r16.derive_ssb_idx_from_cell_r16, 1)); + if (ssb_meas_cfg_r16.ss_rssi_meas_r16_present) { + HANDLE_CODE(ssb_meas_cfg_r16.ss_rssi_meas_r16.unpack(bref)); + } + } + if (beam_meas_cfg_idle_r16_present) { + HANDLE_CODE(beam_meas_cfg_idle_r16.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(subcarrier_spacing_ssb_r17_present, 1)); + if (subcarrier_spacing_ssb_r17_present) { + HANDLE_CODE(subcarrier_spacing_ssb_r17.unpack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +void meas_idle_carrier_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("carrierFreqNR-r16", carrier_freq_nr_r16); + j.write_str("subcarrierSpacingSSB-r16", subcarrier_spacing_ssb_r16.to_string()); + if (freq_band_list_present) { + j.start_array("frequencyBandList"); + for (const auto& e1 : freq_band_list) { + j.write_int(e1); + } + j.end_array(); + } + if (meas_cell_list_nr_r16_present) { + j.start_array("measCellListNR-r16"); + for (const auto& e1 : meas_cell_list_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } + j.write_str("reportQuantitiesNR-r16", report_quantities_nr_r16.to_string()); + if (quality_thres_nr_r16_present) { + j.write_fieldname("qualityThresholdNR-r16"); + j.start_obj(); + if (quality_thres_nr_r16.idle_rsrp_thres_nr_r16_present) { + j.write_int("idleRSRP-ThresholdNR-r16", quality_thres_nr_r16.idle_rsrp_thres_nr_r16); + } + if (quality_thres_nr_r16.idle_rsrq_thres_nr_r16_present) { + j.write_int("idleRSRQ-ThresholdNR-r16", quality_thres_nr_r16.idle_rsrq_thres_nr_r16); + } + j.end_obj(); + } + if (ssb_meas_cfg_r16_present) { + j.write_fieldname("ssb-MeasConfig-r16"); + j.start_obj(); + if (ssb_meas_cfg_r16.max_rs_idx_cell_qual_r16_present) { + j.write_int("maxRS-IndexCellQual-r16", ssb_meas_cfg_r16.max_rs_idx_cell_qual_r16); + } + if (ssb_meas_cfg_r16.thresh_rs_idx_r16_present) { + j.write_fieldname("threshRS-Index-r16"); + ssb_meas_cfg_r16.thresh_rs_idx_r16.to_json(j); + } + if (ssb_meas_cfg_r16.meas_timing_cfg_r16_present) { + j.write_fieldname("measTimingConfig-r16"); + ssb_meas_cfg_r16.meas_timing_cfg_r16.to_json(j); + } + if (ssb_meas_cfg_r16.ssb_to_measure_r16_present) { + j.write_fieldname("ssb-ToMeasure-r16"); + ssb_meas_cfg_r16.ssb_to_measure_r16.to_json(j); + } + j.write_bool("deriveSSB-IndexFromCell-r16", ssb_meas_cfg_r16.derive_ssb_idx_from_cell_r16); + if (ssb_meas_cfg_r16.ss_rssi_meas_r16_present) { + j.write_fieldname("ss-RSSI-Measurement-r16"); + ssb_meas_cfg_r16.ss_rssi_meas_r16.to_json(j); + } + j.end_obj(); + } + if (beam_meas_cfg_idle_r16_present) { + j.write_fieldname("beamMeasConfigIdle-r16"); + beam_meas_cfg_idle_r16.to_json(j); + } + if (ext) { + if (subcarrier_spacing_ssb_r17_present) { + j.write_str("subcarrierSpacingSSB-r17", subcarrier_spacing_ssb_r17.to_string()); + } + } + j.end_obj(); +} + +const char* meas_idle_carrier_nr_r16_s::subcarrier_spacing_ssb_r16_opts::to_string() const +{ + static const char* options[] = {"kHz15", "kHz30", "kHz120", "kHz240"}; + return convert_enum_idx(options, 4, value, "meas_idle_carrier_nr_r16_s::subcarrier_spacing_ssb_r16_e_"); +} +uint8_t meas_idle_carrier_nr_r16_s::subcarrier_spacing_ssb_r16_opts::to_number() const +{ + static const uint8_t options[] = {15, 30, 120, 240}; + return map_enum_number(options, 4, value, "meas_idle_carrier_nr_r16_s::subcarrier_spacing_ssb_r16_e_"); +} + +const char* meas_idle_carrier_nr_r16_s::report_quantities_nr_r16_opts::to_string() const +{ + static const char* options[] = {"rsrp", "rsrq", "both"}; + return convert_enum_idx(options, 3, value, "meas_idle_carrier_nr_r16_s::report_quantities_nr_r16_e_"); +} + +const char* meas_idle_carrier_nr_r16_s::subcarrier_spacing_ssb_r17_opts::to_string() const +{ + static const char* options[] = {"kHz480", "spare1"}; + return convert_enum_idx(options, 2, value, "meas_idle_carrier_nr_r16_s::subcarrier_spacing_ssb_r17_e_"); +} +uint16_t meas_idle_carrier_nr_r16_s::subcarrier_spacing_ssb_r17_opts::to_number() const +{ + static const uint16_t options[] = {480}; + return map_enum_number(options, 1, value, "meas_idle_carrier_nr_r16_s::subcarrier_spacing_ssb_r17_e_"); +} + // NeighCellCDMA2000 ::= SEQUENCE SRSASN_CODE neigh_cell_cdma2000_s::pack(bit_ref& bref) const { @@ -1155,6 +1702,93 @@ void sl_disc_cfg_other_inter_freq_r13_s::to_json(json_writer& j) const j.end_obj(); } +// TLE-EphemerisParameters-r17 ::= SEQUENCE +SRSASN_CODE tle_ephemeris_params_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, inclination_r17, (uint32_t)0u, (uint32_t)2097151u)); + HANDLE_CODE(pack_integer(bref, argument_perigee_r17, (uint32_t)0u, (uint32_t)4194303u)); + HANDLE_CODE(pack_integer(bref, right_ascension_r17, (uint32_t)0u, (uint32_t)4194303u)); + HANDLE_CODE(pack_integer(bref, mean_anomaly_r17, (uint32_t)0u, (uint32_t)4194303u)); + HANDLE_CODE(pack_integer(bref, eccentricity_r17, (uint32_t)0u, (uint32_t)16777215u)); + HANDLE_CODE(pack_integer(bref, mean_motion_r17, (uint64_t)0u, (uint64_t)17179869183u)); + HANDLE_CODE(pack_integer(bref, bstar_decimal_r17, (int32_t)-99999, (int32_t)99999)); + HANDLE_CODE(pack_integer(bref, bstar_exponent_r17, (int8_t)-9, (int8_t)9)); + HANDLE_CODE(pack_integer(bref, epoch_star_r17, (int32_t)-1048575, (int32_t)1048575)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE tle_ephemeris_params_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(inclination_r17, bref, (uint32_t)0u, (uint32_t)2097151u)); + HANDLE_CODE(unpack_integer(argument_perigee_r17, bref, (uint32_t)0u, (uint32_t)4194303u)); + HANDLE_CODE(unpack_integer(right_ascension_r17, bref, (uint32_t)0u, (uint32_t)4194303u)); + HANDLE_CODE(unpack_integer(mean_anomaly_r17, bref, (uint32_t)0u, (uint32_t)4194303u)); + HANDLE_CODE(unpack_integer(eccentricity_r17, bref, (uint32_t)0u, (uint32_t)16777215u)); + HANDLE_CODE(unpack_integer(mean_motion_r17, bref, (uint64_t)0u, (uint64_t)17179869183u)); + HANDLE_CODE(unpack_integer(bstar_decimal_r17, bref, (int32_t)-99999, (int32_t)99999)); + HANDLE_CODE(unpack_integer(bstar_exponent_r17, bref, (int8_t)-9, (int8_t)9)); + HANDLE_CODE(unpack_integer(epoch_star_r17, bref, (int32_t)-1048575, (int32_t)1048575)); + + return SRSASN_SUCCESS; +} +void tle_ephemeris_params_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("inclination-r17", inclination_r17); + j.write_int("argumentPerigee-r17", argument_perigee_r17); + j.write_int("rightAscension-r17", right_ascension_r17); + j.write_int("meanAnomaly-r17", mean_anomaly_r17); + j.write_int("eccentricity-r17", eccentricity_r17); + j.write_int("meanMotion-r17", mean_motion_r17); + j.write_int("bStarDecimal-r17", bstar_decimal_r17); + j.write_int("bStarExponent-r17", bstar_exponent_r17); + j.write_int("epochStar-r17", epoch_star_r17); + j.end_obj(); +} + +// CarrierFreqNBIOT-r16 ::= SEQUENCE +SRSASN_CODE carrier_freq_nbiot_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, carrier_freq_r16, (uint32_t)0u, (uint32_t)262143u)); + HANDLE_CODE(carrier_freq_offset_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE carrier_freq_nbiot_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(carrier_freq_r16, bref, (uint32_t)0u, (uint32_t)262143u)); + HANDLE_CODE(carrier_freq_offset_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void carrier_freq_nbiot_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("carrierFreq-r16", carrier_freq_r16); + j.write_str("carrierFreqOffset-r16", carrier_freq_offset_r16.to_string()); + j.end_obj(); +} + +const char* carrier_freq_nbiot_r16_s::carrier_freq_offset_r16_opts::to_string() const +{ + static const char* options[] = {"v-10", "v-9", "v-8dot5", "v-8", "v-7", "v-6", "v-5", "v-4dot5", "v-4", + "v-3", "v-2", "v-1", "v-0dot5", "v0", "v1", "v2", "v3", "v3dot5", + "v4", "v5", "v6", "v7", "v7dot5", "v8", "v9"}; + return convert_enum_idx(options, 25, value, "carrier_freq_nbiot_r16_s::carrier_freq_offset_r16_e_"); +} +float carrier_freq_nbiot_r16_s::carrier_freq_offset_r16_opts::to_number() const +{ + static const float options[] = {-10.0, -9.0, -8.5, -8.0, -7.0, -6.0, -5.0, -4.5, -4.0, -3.0, -2.0, -1.0, -0.5, + 0.0, 1.0, 2.0, 3.0, 3.5, 4.0, 5.0, 6.0, 7.0, 7.5, 8.0, 9.0}; + return map_enum_number(options, 25, value, "carrier_freq_nbiot_r16_s::carrier_freq_offset_r16_e_"); +} +const char* carrier_freq_nbiot_r16_s::carrier_freq_offset_r16_opts::to_number_string() const +{ + static const char* options[] = {"-10", "-9", "-8.5", "-8", "-7", "-6", "-5", "-4.5", "-4", "-3", "-2", "-1", "-0.5", + "0", "1", "2", "3", "3.5", "4", "5", "6", "7", "7.5", "8", "9"}; + return convert_enum_idx(options, 25, value, "carrier_freq_nbiot_r16_s::carrier_freq_offset_r16_e_"); +} + // CarrierFreqNR-r15 ::= SEQUENCE SRSASN_CODE carrier_freq_nr_r15_s::pack(bit_ref& bref) const { @@ -1444,6 +2078,154 @@ uint8_t carrier_freq_nr_r15_s::subcarrier_spacing_ssb_r15_opts::to_number() cons return map_enum_number(options, 4, value, "carrier_freq_nr_r15_s::subcarrier_spacing_ssb_r15_e_"); } +// CarrierFreqNR-v1610 ::= SEQUENCE +SRSASN_CODE carrier_freq_nr_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(smtc2_lp_r16_present, 1)); + HANDLE_CODE(bref.pack(ssb_position_qcl_common_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(allowed_cell_list_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(high_speed_carrier_nr_r16_present, 1)); + + if (smtc2_lp_r16_present) { + HANDLE_CODE(smtc2_lp_r16.pack(bref)); + } + if (ssb_position_qcl_common_nr_r16_present) { + HANDLE_CODE(ssb_position_qcl_common_nr_r16.pack(bref)); + } + if (allowed_cell_list_nr_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, allowed_cell_list_nr_r16, 1, 16, integer_packer(0, 1007))); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE carrier_freq_nr_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(smtc2_lp_r16_present, 1)); + HANDLE_CODE(bref.unpack(ssb_position_qcl_common_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(allowed_cell_list_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(high_speed_carrier_nr_r16_present, 1)); + + if (smtc2_lp_r16_present) { + HANDLE_CODE(smtc2_lp_r16.unpack(bref)); + } + if (ssb_position_qcl_common_nr_r16_present) { + HANDLE_CODE(ssb_position_qcl_common_nr_r16.unpack(bref)); + } + if (allowed_cell_list_nr_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(allowed_cell_list_nr_r16, bref, 1, 16, integer_packer(0, 1007))); + } + + return SRSASN_SUCCESS; +} +void carrier_freq_nr_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (smtc2_lp_r16_present) { + j.write_fieldname("smtc2-LP-r16"); + smtc2_lp_r16.to_json(j); + } + if (ssb_position_qcl_common_nr_r16_present) { + j.write_str("ssb-PositionQCL-CommonNR-r16", ssb_position_qcl_common_nr_r16.to_string()); + } + if (allowed_cell_list_nr_r16_present) { + j.start_array("allowedCellListNR-r16"); + for (const auto& e1 : allowed_cell_list_nr_r16) { + j.write_int(e1); + } + j.end_array(); + } + if (high_speed_carrier_nr_r16_present) { + j.write_str("highSpeedCarrierNR-r16", "true"); + } + j.end_obj(); +} + +// CarrierFreqNR-v1700 ::= SEQUENCE +SRSASN_CODE carrier_freq_nr_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(nr_freq_neigh_hsdn_cell_list_r17_present, 1)); + + if (nr_freq_neigh_hsdn_cell_list_r17_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, nr_freq_neigh_hsdn_cell_list_r17, 1, 8)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE carrier_freq_nr_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(nr_freq_neigh_hsdn_cell_list_r17_present, 1)); + + if (nr_freq_neigh_hsdn_cell_list_r17_present) { + HANDLE_CODE(unpack_dyn_seq_of(nr_freq_neigh_hsdn_cell_list_r17, bref, 1, 8)); + } + + return SRSASN_SUCCESS; +} +void carrier_freq_nr_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (nr_freq_neigh_hsdn_cell_list_r17_present) { + j.start_array("nr-FreqNeighHSDN-CellList-r17"); + for (const auto& e1 : nr_freq_neigh_hsdn_cell_list_r17) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// CarrierFreqNR-v1720 ::= SEQUENCE +SRSASN_CODE carrier_freq_nr_v1720_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(subcarrier_spacing_ssb_r17_present, 1)); + HANDLE_CODE(bref.pack(ssb_position_qcl_common_nr_r17_present, 1)); + + if (subcarrier_spacing_ssb_r17_present) { + HANDLE_CODE(subcarrier_spacing_ssb_r17.pack(bref)); + } + if (ssb_position_qcl_common_nr_r17_present) { + HANDLE_CODE(ssb_position_qcl_common_nr_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE carrier_freq_nr_v1720_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(subcarrier_spacing_ssb_r17_present, 1)); + HANDLE_CODE(bref.unpack(ssb_position_qcl_common_nr_r17_present, 1)); + + if (subcarrier_spacing_ssb_r17_present) { + HANDLE_CODE(subcarrier_spacing_ssb_r17.unpack(bref)); + } + if (ssb_position_qcl_common_nr_r17_present) { + HANDLE_CODE(ssb_position_qcl_common_nr_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void carrier_freq_nr_v1720_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (subcarrier_spacing_ssb_r17_present) { + j.write_str("subcarrierSpacingSSB-r17", subcarrier_spacing_ssb_r17.to_string()); + } + if (ssb_position_qcl_common_nr_r17_present) { + j.write_str("ssb-PositionQCL-CommonNR-r17", ssb_position_qcl_common_nr_r17.to_string()); + } + j.end_obj(); +} + +const char* carrier_freq_nr_v1720_s::subcarrier_spacing_ssb_r17_opts::to_string() const +{ + static const char* options[] = {"kHz480", "spare1"}; + return convert_enum_idx(options, 2, value, "carrier_freq_nr_v1720_s::subcarrier_spacing_ssb_r17_e_"); +} +uint16_t carrier_freq_nr_v1720_s::subcarrier_spacing_ssb_r17_opts::to_number() const +{ + static const uint16_t options[] = {480}; + return map_enum_number(options, 1, value, "carrier_freq_nr_v1720_s::subcarrier_spacing_ssb_r17_e_"); +} + // CarrierFreqUTRA-FDD ::= SEQUENCE SRSASN_CODE carrier_freq_utra_fdd_s::pack(bit_ref& bref) const { @@ -1809,6 +2591,76 @@ const char* eab_cfg_r11_s::eab_category_r11_opts::to_string() const return convert_enum_idx(options, 3, value, "eab_cfg_r11_s::eab_category_r11_e_"); } +// EphemerisOrbitalParameters-r17 ::= SEQUENCE +SRSASN_CODE ephemeris_orbital_params_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, semi_major_axis_r17, (uint64_t)0u, (uint64_t)8589934591u)); + HANDLE_CODE(pack_integer(bref, eccentricity_r17, (uint32_t)0u, (uint32_t)1048575u)); + HANDLE_CODE(pack_integer(bref, periapsis_r17, (uint32_t)0u, (uint32_t)268435455u)); + HANDLE_CODE(pack_integer(bref, longitude_r17, (uint32_t)0u, (uint32_t)268435455u)); + HANDLE_CODE(pack_integer(bref, inclination_r17, (int32_t)-67108864, (int32_t)67108863)); + HANDLE_CODE(pack_integer(bref, anomaly_r17, (uint32_t)0u, (uint32_t)268435455u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ephemeris_orbital_params_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(semi_major_axis_r17, bref, (uint64_t)0u, (uint64_t)8589934591u)); + HANDLE_CODE(unpack_integer(eccentricity_r17, bref, (uint32_t)0u, (uint32_t)1048575u)); + HANDLE_CODE(unpack_integer(periapsis_r17, bref, (uint32_t)0u, (uint32_t)268435455u)); + HANDLE_CODE(unpack_integer(longitude_r17, bref, (uint32_t)0u, (uint32_t)268435455u)); + HANDLE_CODE(unpack_integer(inclination_r17, bref, (int32_t)-67108864, (int32_t)67108863)); + HANDLE_CODE(unpack_integer(anomaly_r17, bref, (uint32_t)0u, (uint32_t)268435455u)); + + return SRSASN_SUCCESS; +} +void ephemeris_orbital_params_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("semiMajorAxis-r17", semi_major_axis_r17); + j.write_int("eccentricity-r17", eccentricity_r17); + j.write_int("periapsis-r17", periapsis_r17); + j.write_int("longitude-r17", longitude_r17); + j.write_int("inclination-r17", inclination_r17); + j.write_int("anomaly-r17", anomaly_r17); + j.end_obj(); +} + +// EphemerisStateVectors-r17 ::= SEQUENCE +SRSASN_CODE ephemeris_state_vectors_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, position_x_r17, (int32_t)-33554432, (int32_t)33554431)); + HANDLE_CODE(pack_integer(bref, position_y_r17, (int32_t)-33554432, (int32_t)33554431)); + HANDLE_CODE(pack_integer(bref, position_z_r17, (int32_t)-33554432, (int32_t)33554431)); + HANDLE_CODE(pack_integer(bref, velocity_vx_r17, (int32_t)-131072, (int32_t)131071)); + HANDLE_CODE(pack_integer(bref, velocity_vy_r17, (int32_t)-131072, (int32_t)131071)); + HANDLE_CODE(pack_integer(bref, velocity_vz_r17, (int32_t)-131072, (int32_t)131071)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ephemeris_state_vectors_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(position_x_r17, bref, (int32_t)-33554432, (int32_t)33554431)); + HANDLE_CODE(unpack_integer(position_y_r17, bref, (int32_t)-33554432, (int32_t)33554431)); + HANDLE_CODE(unpack_integer(position_z_r17, bref, (int32_t)-33554432, (int32_t)33554431)); + HANDLE_CODE(unpack_integer(velocity_vx_r17, bref, (int32_t)-131072, (int32_t)131071)); + HANDLE_CODE(unpack_integer(velocity_vy_r17, bref, (int32_t)-131072, (int32_t)131071)); + HANDLE_CODE(unpack_integer(velocity_vz_r17, bref, (int32_t)-131072, (int32_t)131071)); + + return SRSASN_SUCCESS; +} +void ephemeris_state_vectors_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("positionX-r17", position_x_r17); + j.write_int("positionY-r17", position_y_r17); + j.write_int("positionZ-r17", position_z_r17); + j.write_int("velocityVX-r17", velocity_vx_r17); + j.write_int("velocityVY-r17", velocity_vy_r17); + j.write_int("velocityVZ-r17", velocity_vz_r17); + j.end_obj(); +} + // InterFreqCarrierFreqInfo ::= SEQUENCE SRSASN_CODE inter_freq_carrier_freq_info_s::pack(bit_ref& bref) const { @@ -1818,7 +2670,7 @@ SRSASN_CODE inter_freq_carrier_freq_info_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(cell_resel_prio_present, 1)); HANDLE_CODE(bref.pack(q_offset_freq_present, 1)); HANDLE_CODE(bref.pack(inter_freq_neigh_cell_list_present, 1)); - HANDLE_CODE(bref.pack(inter_freq_black_cell_list_present, 1)); + HANDLE_CODE(bref.pack(inter_freq_excluded_cell_list_present, 1)); HANDLE_CODE(pack_integer(bref, dl_carrier_freq, (uint32_t)0u, (uint32_t)65535u)); HANDLE_CODE(pack_integer(bref, q_rx_lev_min, (int8_t)-70, (int8_t)-22)); @@ -1843,8 +2695,8 @@ SRSASN_CODE inter_freq_carrier_freq_info_s::pack(bit_ref& bref) const if (inter_freq_neigh_cell_list_present) { HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_neigh_cell_list, 1, 16)); } - if (inter_freq_black_cell_list_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_black_cell_list, 1, 16)); + if (inter_freq_excluded_cell_list_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_excluded_cell_list, 1, 16)); } if (ext) { @@ -1886,7 +2738,7 @@ SRSASN_CODE inter_freq_carrier_freq_info_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(cell_resel_prio_present, 1)); HANDLE_CODE(bref.unpack(q_offset_freq_present, 1)); HANDLE_CODE(bref.unpack(inter_freq_neigh_cell_list_present, 1)); - HANDLE_CODE(bref.unpack(inter_freq_black_cell_list_present, 1)); + HANDLE_CODE(bref.unpack(inter_freq_excluded_cell_list_present, 1)); HANDLE_CODE(unpack_integer(dl_carrier_freq, bref, (uint32_t)0u, (uint32_t)65535u)); HANDLE_CODE(unpack_integer(q_rx_lev_min, bref, (int8_t)-70, (int8_t)-22)); @@ -1911,8 +2763,8 @@ SRSASN_CODE inter_freq_carrier_freq_info_s::unpack(cbit_ref& bref) if (inter_freq_neigh_cell_list_present) { HANDLE_CODE(unpack_dyn_seq_of(inter_freq_neigh_cell_list, bref, 1, 16)); } - if (inter_freq_black_cell_list_present) { - HANDLE_CODE(unpack_dyn_seq_of(inter_freq_black_cell_list, bref, 1, 16)); + if (inter_freq_excluded_cell_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(inter_freq_excluded_cell_list, bref, 1, 16)); } if (ext) { @@ -1976,9 +2828,9 @@ void inter_freq_carrier_freq_info_s::to_json(json_writer& j) const } j.end_array(); } - if (inter_freq_black_cell_list_present) { - j.start_array("interFreqBlackCellList"); - for (const auto& e1 : inter_freq_black_cell_list) { + if (inter_freq_excluded_cell_list_present) { + j.start_array("interFreqExcludedCellList"); + for (const auto& e1 : inter_freq_excluded_cell_list) { e1.to_json(j); } j.end_array(); @@ -2010,7 +2862,7 @@ SRSASN_CODE inter_freq_carrier_freq_info_r12_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(cell_resel_prio_r12_present, 1)); HANDLE_CODE(bref.pack(q_offset_freq_r12_present, 1)); HANDLE_CODE(bref.pack(inter_freq_neigh_cell_list_r12_present, 1)); - HANDLE_CODE(bref.pack(inter_freq_black_cell_list_r12_present, 1)); + HANDLE_CODE(bref.pack(inter_freq_excluded_cell_list_r12_present, 1)); HANDLE_CODE(bref.pack(q_qual_min_r12_present, 1)); HANDLE_CODE(bref.pack(thresh_x_q_r12_present, 1)); HANDLE_CODE(bref.pack(q_qual_min_wb_r12_present, 1)); @@ -2041,8 +2893,8 @@ SRSASN_CODE inter_freq_carrier_freq_info_r12_s::pack(bit_ref& bref) const if (inter_freq_neigh_cell_list_r12_present) { HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_neigh_cell_list_r12, 1, 16)); } - if (inter_freq_black_cell_list_r12_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_black_cell_list_r12, 1, 16)); + if (inter_freq_excluded_cell_list_r12_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_excluded_cell_list_r12, 1, 16)); } if (q_qual_min_r12_present) { HANDLE_CODE(pack_integer(bref, q_qual_min_r12, (int8_t)-34, (int8_t)-3)); @@ -2071,7 +2923,7 @@ SRSASN_CODE inter_freq_carrier_freq_info_r12_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(cell_resel_prio_r12_present, 1)); HANDLE_CODE(bref.unpack(q_offset_freq_r12_present, 1)); HANDLE_CODE(bref.unpack(inter_freq_neigh_cell_list_r12_present, 1)); - HANDLE_CODE(bref.unpack(inter_freq_black_cell_list_r12_present, 1)); + HANDLE_CODE(bref.unpack(inter_freq_excluded_cell_list_r12_present, 1)); HANDLE_CODE(bref.unpack(q_qual_min_r12_present, 1)); HANDLE_CODE(bref.unpack(thresh_x_q_r12_present, 1)); HANDLE_CODE(bref.unpack(q_qual_min_wb_r12_present, 1)); @@ -2102,8 +2954,8 @@ SRSASN_CODE inter_freq_carrier_freq_info_r12_s::unpack(cbit_ref& bref) if (inter_freq_neigh_cell_list_r12_present) { HANDLE_CODE(unpack_dyn_seq_of(inter_freq_neigh_cell_list_r12, bref, 1, 16)); } - if (inter_freq_black_cell_list_r12_present) { - HANDLE_CODE(unpack_dyn_seq_of(inter_freq_black_cell_list_r12, bref, 1, 16)); + if (inter_freq_excluded_cell_list_r12_present) { + HANDLE_CODE(unpack_dyn_seq_of(inter_freq_excluded_cell_list_r12, bref, 1, 16)); } if (q_qual_min_r12_present) { HANDLE_CODE(unpack_integer(q_qual_min_r12, bref, (int8_t)-34, (int8_t)-3)); @@ -2155,9 +3007,9 @@ void inter_freq_carrier_freq_info_r12_s::to_json(json_writer& j) const } j.end_array(); } - if (inter_freq_black_cell_list_r12_present) { - j.start_array("interFreqBlackCellList-r12"); - for (const auto& e1 : inter_freq_black_cell_list_r12) { + if (inter_freq_excluded_cell_list_r12_present) { + j.start_array("interFreqExcludedCellList-r12"); + for (const auto& e1 : inter_freq_excluded_cell_list_r12) { e1.to_json(j); } j.end_array(); @@ -2455,6 +3307,74 @@ void inter_freq_carrier_freq_info_v1530_s::to_json(json_writer& j) const j.end_obj(); } +// InterFreqCarrierFreqInfo-v1610 ::= SEQUENCE +SRSASN_CODE inter_freq_carrier_freq_info_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(alt_cell_resel_prio_r16_present, 1)); + HANDLE_CODE(bref.pack(alt_cell_resel_sub_prio_r16_present, 1)); + HANDLE_CODE(bref.pack(rss_cfg_carrier_info_r16_present, 1)); + HANDLE_CODE(bref.pack(inter_freq_neigh_cell_list_v1610_present, 1)); + + if (alt_cell_resel_prio_r16_present) { + HANDLE_CODE(pack_integer(bref, alt_cell_resel_prio_r16, (uint8_t)0u, (uint8_t)7u)); + } + if (alt_cell_resel_sub_prio_r16_present) { + HANDLE_CODE(alt_cell_resel_sub_prio_r16.pack(bref)); + } + if (rss_cfg_carrier_info_r16_present) { + HANDLE_CODE(rss_cfg_carrier_info_r16.pack(bref)); + } + if (inter_freq_neigh_cell_list_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_neigh_cell_list_v1610, 1, 16)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE inter_freq_carrier_freq_info_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(alt_cell_resel_prio_r16_present, 1)); + HANDLE_CODE(bref.unpack(alt_cell_resel_sub_prio_r16_present, 1)); + HANDLE_CODE(bref.unpack(rss_cfg_carrier_info_r16_present, 1)); + HANDLE_CODE(bref.unpack(inter_freq_neigh_cell_list_v1610_present, 1)); + + if (alt_cell_resel_prio_r16_present) { + HANDLE_CODE(unpack_integer(alt_cell_resel_prio_r16, bref, (uint8_t)0u, (uint8_t)7u)); + } + if (alt_cell_resel_sub_prio_r16_present) { + HANDLE_CODE(alt_cell_resel_sub_prio_r16.unpack(bref)); + } + if (rss_cfg_carrier_info_r16_present) { + HANDLE_CODE(rss_cfg_carrier_info_r16.unpack(bref)); + } + if (inter_freq_neigh_cell_list_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(inter_freq_neigh_cell_list_v1610, bref, 1, 16)); + } + + return SRSASN_SUCCESS; +} +void inter_freq_carrier_freq_info_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (alt_cell_resel_prio_r16_present) { + j.write_int("altCellReselectionPriority-r16", alt_cell_resel_prio_r16); + } + if (alt_cell_resel_sub_prio_r16_present) { + j.write_str("altCellReselectionSubPriority-r16", alt_cell_resel_sub_prio_r16.to_string()); + } + if (rss_cfg_carrier_info_r16_present) { + j.write_fieldname("rss-ConfigCarrierInfo-r16"); + rss_cfg_carrier_info_r16.to_json(j); + } + if (inter_freq_neigh_cell_list_v1610_present) { + j.start_array("interFreqNeighCellList-v1610"); + for (const auto& e1 : inter_freq_neigh_cell_list_v1610) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + // IntraFreqNeighCellInfo ::= SEQUENCE SRSASN_CODE intra_freq_neigh_cell_info_s::pack(bit_ref& bref) const { @@ -2480,6 +3400,26 @@ void intra_freq_neigh_cell_info_s::to_json(json_writer& j) const j.end_obj(); } +// IntraFreqNeighCellInfo-v1610 ::= SEQUENCE +SRSASN_CODE intra_freq_neigh_cell_info_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(rss_meas_pwr_bias_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE intra_freq_neigh_cell_info_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(rss_meas_pwr_bias_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void intra_freq_neigh_cell_info_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("rss-MeasPowerBias-r16", rss_meas_pwr_bias_r16.to_string()); + j.end_obj(); +} + // MBMS-CarrierType-r14 ::= SEQUENCE SRSASN_CODE mbms_carrier_type_r14_s::pack(bit_ref& bref) const { @@ -2559,27 +3499,64 @@ SRSASN_CODE mbms_sai_inter_freq_v1140_s::pack(bit_ref& bref) const } SRSASN_CODE mbms_sai_inter_freq_v1140_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(multi_band_info_list_r11_present, 1)); - - if (multi_band_info_list_r11_present) { - HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r11, bref, 1, 8, integer_packer(1, 256))); - } + HANDLE_CODE(bref.unpack(multi_band_info_list_r11_present, 1)); + + if (multi_band_info_list_r11_present) { + HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r11, bref, 1, 8, integer_packer(1, 256))); + } + + return SRSASN_SUCCESS; +} +void mbms_sai_inter_freq_v1140_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (multi_band_info_list_r11_present) { + j.start_array("multiBandInfoList-r11"); + for (const auto& e1 : multi_band_info_list_r11) { + j.write_int(e1); + } + j.end_array(); + } + j.end_obj(); +} + +// MBSFN-AreaInfo-r17 ::= SEQUENCE +SRSASN_CODE mbsfn_area_info_r17_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(mbsfn_area_info_r17.pack(bref)); + HANDLE_CODE(pmch_bw_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mbsfn_area_info_r17_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(mbsfn_area_info_r17.unpack(bref)); + HANDLE_CODE(pmch_bw_r17.unpack(bref)); return SRSASN_SUCCESS; } -void mbms_sai_inter_freq_v1140_s::to_json(json_writer& j) const +void mbsfn_area_info_r17_s::to_json(json_writer& j) const { j.start_obj(); - if (multi_band_info_list_r11_present) { - j.start_array("multiBandInfoList-r11"); - for (const auto& e1 : multi_band_info_list_r11) { - j.write_int(e1); - } - j.end_array(); - } + j.write_fieldname("mbsfn-AreaInfo-r17"); + mbsfn_area_info_r17.to_json(j); + j.write_str("pmch-Bandwidth-r17", pmch_bw_r17.to_string()); j.end_obj(); } +const char* mbsfn_area_info_r17_s::pmch_bw_r17_opts::to_string() const +{ + static const char* options[] = {"n40", "n35", "n30", "spare1"}; + return convert_enum_idx(options, 4, value, "mbsfn_area_info_r17_s::pmch_bw_r17_e_"); +} +uint8_t mbsfn_area_info_r17_s::pmch_bw_r17_opts::to_number() const +{ + static const uint8_t options[] = {40, 35, 30}; + return map_enum_number(options, 3, value, "mbsfn_area_info_r17_s::pmch_bw_r17_e_"); +} + // MBSFN-AreaInfo-r9 ::= SEQUENCE SRSASN_CODE mbsfn_area_info_r9_s::pack(bit_ref& bref) const { @@ -2776,139 +3753,36 @@ const char* mbsfn_area_info_r9_s::subcarrier_spacing_mbms_r14_opts::to_number_st return convert_enum_idx(options, 2, value, "mbsfn_area_info_r9_s::subcarrier_spacing_mbms_r14_e_"); } -SRSASN_CODE mbsfn_area_info_r16_s::unpack(cbit_ref& bref) +// PLMN-Info-r16 ::= SEQUENCE +SRSASN_CODE plmn_info_r16_s::pack(bit_ref& bref) const { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(time_separation_r16_present, 1)); - HANDLE_CODE(unpack_integer(mbsfn_area_id_r16, bref, (uint16_t)0u, (uint16_t)255u)); - HANDLE_CODE(unpack_integer(notif_ind_r16, bref, (uint8_t)0u, (uint8_t)7u)); - HANDLE_CODE(mcch_cfg_r16.mcch_repeat_period_r16.unpack(bref)); - HANDLE_CODE(mcch_cfg_r16.mcch_mod_period_r16.unpack(bref)); - HANDLE_CODE(unpack_integer(mcch_cfg_r16.mcch_offset_r16, bref, (uint8_t)0u, (uint8_t)10u)); - HANDLE_CODE(mcch_cfg_r16.sf_alloc_info_r16.unpack(bref)); - HANDLE_CODE(mcch_cfg_r16.sig_mcs_r16.unpack(bref)); - HANDLE_CODE(subcarrier_spacing_mbms_r16.unpack(bref)); - if (time_separation_r16_present) { - HANDLE_CODE(time_separation_r16.unpack(bref)); - } + HANDLE_CODE(bref.pack(nr_band_list_r16_present, 1)); - if (ext) { - ext_groups_unpacker_guard group_flags(1); - group_flags.unpack(bref); + if (nr_band_list_r16_present) { + HANDLE_CODE(nr_band_list_r16.pack(bref)); + } - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); + return SRSASN_SUCCESS; +} +SRSASN_CODE plmn_info_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(nr_band_list_r16_present, 1)); - HANDLE_CODE(bref.unpack(pmch_bandwidth_v16xy_present, 1)); - if (pmch_bandwidth_v16xy_present) { - HANDLE_CODE(pmch_bandwidth_v16xy.unpack(bref)); - } - } + if (nr_band_list_r16_present) { + HANDLE_CODE(nr_band_list_r16.unpack(bref)); } + return SRSASN_SUCCESS; } - -void mbsfn_area_info_r16_s::to_json(json_writer& j) const +void plmn_info_r16_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("mbsfn-AreaId-r16", mbsfn_area_id_r16); - j.write_int("notificationIndicator-r16", notif_ind_r16); - j.write_fieldname("mcch-Config-r16"); - j.start_obj(); - j.write_str("mcch-RepetitionPeriod-r16", mcch_cfg_r16.mcch_repeat_period_r16.to_string()); - j.write_str("mcch-ModificationPeriod-r16", mcch_cfg_r16.mcch_mod_period_r16.to_string()); - j.write_int("mcch-Offset-r16", mcch_cfg_r16.mcch_offset_r16); - j.write_str("sf-AllocInfo-r16", mcch_cfg_r16.sf_alloc_info_r16.to_string()); - j.write_str("signallingMCS-r16", mcch_cfg_r16.sig_mcs_r16.to_string()); - j.end_obj(); - j.write_str("subcarrierSpacingMBMS-r16", subcarrier_spacing_mbms_r16.to_string()); - if (ext) { - if (time_separation_r16_present) { - j.write_str("timeSeparation-r16", time_separation_r16.to_string()); - } - if (pmch_bandwidth_v16xy_present) { - j.write_str("pmch-Bandwidth-v16xy", pmch_bandwidth_v16xy.to_string()); - } + if (nr_band_list_r16_present) { + j.write_str("nr-BandList-r16", nr_band_list_r16.to_string()); } j.end_obj(); } -std::string mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_repeat_period_r16_opts::to_string() const -{ - static const char* options[] = {"rf1", "rf2", "rf4", "rf8", "rf16", - "rf32", "rf64", "rf128", "rf256", - "spare7", "spare6", "spare5", "spare4", "spare3", "spare2", "spare1"}; - return convert_enum_idx(options, 16, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_repeat_period_r16_e_"); -} -uint16_t mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_repeat_period_r16_opts::to_number() const -{ - static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256}; - return map_enum_number(options, 9, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_repeat_period_r16_e_"); -} - -std::string mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_mod_period_r16_opts::to_string() const -{ - static const char* options[] = {"rf1", "rf2", "rf4", "rf8", "rf16", - "rf32", "rf64", "rf128", "rf256", "rf512", "rf1024", - "spare5", "spare4", "spare3", "spare2", "spare1"}; - return convert_enum_idx(options, 16, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_mod_period_r16_e_"); -} -uint16_t mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_mod_period_r16_opts::to_number() const -{ - static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}; - return map_enum_number(options, 11, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::mcch_mod_period_r16_e_"); -} - -std::string mbsfn_area_info_r16_s::mcch_cfg_r16_s_::sig_mcs_r16_opts::to_string() const -{ - static const char* options[] = {"n2", "n7", "n13", "n19"}; - return convert_enum_idx(options, 4, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::sig_mcs_r16_e_"); -} -uint8_t mbsfn_area_info_r16_s::mcch_cfg_r16_s_::sig_mcs_r16_opts::to_number() const -{ - static const uint8_t options[] = {2, 7, 13, 19}; - return map_enum_number(options, 4, value, "mbsfn_area_info_r16_s::mcch_cfg_r16_s_::sig_mcs_r16_e_"); -} - -std::string mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_opts::to_string() const -{ - static const char* options[] = {"khz7dot5", "khz2dot5", "khz1dot25", "khz0dot37", "spare4", "spare3", "spare2", "spare1"}; - return convert_enum_idx(options, 8, value, "mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_e_"); -} -float mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_opts::to_number() const -{ - static const float options[] = {7.5, 2.5, 1.25, 0.37}; - return map_enum_number(options, 4, value, "mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_e_"); -} -std::string mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_opts::to_number_string() const -{ - static const char* options[] = {"7.5", "2.5", "1.25", "0.25"}; - return convert_enum_idx(options, 2, value, "mbsfn_area_info_r16_s::subcarrier_spacing_mbms_r16_e_"); -} - -std::string mbsfn_area_info_r16_s::time_separation_r16_opts::to_string() const -{ - static const char* options[] = {"s12", "s14"}; - return convert_enum_idx(options, 2, value, "mbsfn_area_info_r16_s::time_separation_r16_opts"); -} -uint8_t mbsfn_area_info_r16_s::time_separation_r16_opts::to_number() const -{ - static const uint8_t options[] = {12, 14}; - return map_enum_number(options, 2, value, "mbsfn_area_info_r16_s::time_separation_r16_opts"); -} - -std::string mbsfn_area_info_r16_s::pmch_bandwidth_v16xy_opts::to_string() const -{ - static const char* options[] = {"n30", "n35", "n40", "spare1"}; - return convert_enum_idx(options, 4, value, "mbsfn_area_info_r16_s::pmch_bandwidth_v16xy_opts"); -} -uint8_t mbsfn_area_info_r16_s::pmch_bandwidth_v16xy_opts::to_number() const -{ - static const uint8_t options[] = {30, 35, 40}; - return map_enum_number(options, 3, value, "mbsfn_area_info_r16_s::pmch_bandwidth_v16xy_opts"); -} - - // ReselectionInfoRelay-r13 ::= SEQUENCE SRSASN_CODE resel_info_relay_r13_s::pack(bit_ref& bref) const { @@ -3175,6 +4049,113 @@ void sl_pppp_tx_cfg_idx_r15_s::to_json(json_writer& j) const j.end_obj(); } +// SatelliteInfo-r17 ::= SEQUENCE +SRSASN_CODE satellite_info_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, satellite_id_r17, (uint16_t)0u, (uint16_t)255u)); + HANDLE_CODE(bref.pack(service_info_r17.tle_ephemeris_params_r17_present, 1)); + HANDLE_CODE(bref.pack(service_info_r17.t_service_start_r17_present, 1)); + if (service_info_r17.tle_ephemeris_params_r17_present) { + HANDLE_CODE(service_info_r17.tle_ephemeris_params_r17.pack(bref)); + } + if (service_info_r17.t_service_start_r17_present) { + HANDLE_CODE(pack_integer(bref, service_info_r17.t_service_start_r17, (uint32_t)0u, (uint32_t)1048575u)); + } + HANDLE_CODE(bref.pack(footprint_info_r17.ref_point_r17_present, 1)); + HANDLE_CODE(bref.pack(footprint_info_r17.elevation_angles_r17_present, 1)); + HANDLE_CODE(bref.pack(footprint_info_r17.radius_r17_present, 1)); + if (footprint_info_r17.ref_point_r17_present) { + HANDLE_CODE(pack_integer(bref, footprint_info_r17.ref_point_r17.longitude_r17, (int32_t)-131072, (int32_t)131071)); + HANDLE_CODE(pack_integer(bref, footprint_info_r17.ref_point_r17.latitude_r17, (int32_t)-131072, (int32_t)131071)); + } + if (footprint_info_r17.elevation_angles_r17_present) { + HANDLE_CODE(bref.pack(footprint_info_r17.elevation_angles_r17.elevation_angle_left_r17_present, 1)); + HANDLE_CODE( + pack_integer(bref, footprint_info_r17.elevation_angles_r17.elevation_angle_right_r17, (int8_t)-14, (int8_t)14)); + if (footprint_info_r17.elevation_angles_r17.elevation_angle_left_r17_present) { + HANDLE_CODE(pack_integer( + bref, footprint_info_r17.elevation_angles_r17.elevation_angle_left_r17, (int8_t)-14, (int8_t)14)); + } + } + if (footprint_info_r17.radius_r17_present) { + HANDLE_CODE(pack_integer(bref, footprint_info_r17.radius_r17, (uint16_t)1u, (uint16_t)256u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE satellite_info_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(satellite_id_r17, bref, (uint16_t)0u, (uint16_t)255u)); + HANDLE_CODE(bref.unpack(service_info_r17.tle_ephemeris_params_r17_present, 1)); + HANDLE_CODE(bref.unpack(service_info_r17.t_service_start_r17_present, 1)); + if (service_info_r17.tle_ephemeris_params_r17_present) { + HANDLE_CODE(service_info_r17.tle_ephemeris_params_r17.unpack(bref)); + } + if (service_info_r17.t_service_start_r17_present) { + HANDLE_CODE(unpack_integer(service_info_r17.t_service_start_r17, bref, (uint32_t)0u, (uint32_t)1048575u)); + } + HANDLE_CODE(bref.unpack(footprint_info_r17.ref_point_r17_present, 1)); + HANDLE_CODE(bref.unpack(footprint_info_r17.elevation_angles_r17_present, 1)); + HANDLE_CODE(bref.unpack(footprint_info_r17.radius_r17_present, 1)); + if (footprint_info_r17.ref_point_r17_present) { + HANDLE_CODE( + unpack_integer(footprint_info_r17.ref_point_r17.longitude_r17, bref, (int32_t)-131072, (int32_t)131071)); + HANDLE_CODE(unpack_integer(footprint_info_r17.ref_point_r17.latitude_r17, bref, (int32_t)-131072, (int32_t)131071)); + } + if (footprint_info_r17.elevation_angles_r17_present) { + HANDLE_CODE(bref.unpack(footprint_info_r17.elevation_angles_r17.elevation_angle_left_r17_present, 1)); + HANDLE_CODE(unpack_integer( + footprint_info_r17.elevation_angles_r17.elevation_angle_right_r17, bref, (int8_t)-14, (int8_t)14)); + if (footprint_info_r17.elevation_angles_r17.elevation_angle_left_r17_present) { + HANDLE_CODE(unpack_integer( + footprint_info_r17.elevation_angles_r17.elevation_angle_left_r17, bref, (int8_t)-14, (int8_t)14)); + } + } + if (footprint_info_r17.radius_r17_present) { + HANDLE_CODE(unpack_integer(footprint_info_r17.radius_r17, bref, (uint16_t)1u, (uint16_t)256u)); + } + + return SRSASN_SUCCESS; +} +void satellite_info_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("satelliteId-r17", satellite_id_r17); + j.write_fieldname("serviceInfo-r17"); + j.start_obj(); + if (service_info_r17.tle_ephemeris_params_r17_present) { + j.write_fieldname("tle-EphemerisParameters-r17"); + service_info_r17.tle_ephemeris_params_r17.to_json(j); + } + if (service_info_r17.t_service_start_r17_present) { + j.write_int("t-ServiceStart-r17", service_info_r17.t_service_start_r17); + } + j.end_obj(); + j.write_fieldname("footprintInfo-r17"); + j.start_obj(); + if (footprint_info_r17.ref_point_r17_present) { + j.write_fieldname("referencePoint-r17"); + j.start_obj(); + j.write_int("longitude-r17", footprint_info_r17.ref_point_r17.longitude_r17); + j.write_int("latitude-r17", footprint_info_r17.ref_point_r17.latitude_r17); + j.end_obj(); + } + if (footprint_info_r17.elevation_angles_r17_present) { + j.write_fieldname("elevationAngles-r17"); + j.start_obj(); + j.write_int("elevationAngleRight-r17", footprint_info_r17.elevation_angles_r17.elevation_angle_right_r17); + if (footprint_info_r17.elevation_angles_r17.elevation_angle_left_r17_present) { + j.write_int("elevationAngleLeft-r17", footprint_info_r17.elevation_angles_r17.elevation_angle_left_r17); + } + j.end_obj(); + } + if (footprint_info_r17.radius_r17_present) { + j.write_int("radius-r17", footprint_info_r17.radius_r17); + } + j.end_obj(); + j.end_obj(); +} + // UAC-BarringInfoSet-r15 ::= SEQUENCE SRSASN_CODE uac_barr_info_set_r15_s::pack(bit_ref& bref) const { @@ -3230,6 +4211,54 @@ uint16_t uac_barr_info_set_r15_s::uac_barr_time_r15_opts::to_number() const return map_enum_number(options, 8, value, "uac_barr_info_set_r15_s::uac_barr_time_r15_e_"); } +// UAC-BarringInfoSet-v1700 ::= SEQUENCE +SRSASN_CODE uac_barr_info_set_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(uac_barr_factor_for_ai3_r17_present, 1)); + + if (uac_barr_factor_for_ai3_r17_present) { + HANDLE_CODE(uac_barr_factor_for_ai3_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE uac_barr_info_set_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(uac_barr_factor_for_ai3_r17_present, 1)); + + if (uac_barr_factor_for_ai3_r17_present) { + HANDLE_CODE(uac_barr_factor_for_ai3_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void uac_barr_info_set_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (uac_barr_factor_for_ai3_r17_present) { + j.write_str("uac-BarringFactorForAI3-r17", uac_barr_factor_for_ai3_r17.to_string()); + } + j.end_obj(); +} + +const char* uac_barr_info_set_v1700_s::uac_barr_factor_for_ai3_r17_opts::to_string() const +{ + static const char* options[] = { + "p00", "p05", "p10", "p15", "p20", "p25", "p30", "p40", "p50", "p60", "p70", "p75", "p80", "p85", "p90", "p95"}; + return convert_enum_idx(options, 16, value, "uac_barr_info_set_v1700_s::uac_barr_factor_for_ai3_r17_e_"); +} +float uac_barr_info_set_v1700_s::uac_barr_factor_for_ai3_r17_opts::to_number() const +{ + static const float options[] = {0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5}; + return map_enum_number(options, 16, value, "uac_barr_info_set_v1700_s::uac_barr_factor_for_ai3_r17_e_"); +} +const char* uac_barr_info_set_v1700_s::uac_barr_factor_for_ai3_r17_opts::to_number_string() const +{ + static const char* options[] = { + "0.0", "0.5", "1.0", "1.5", "2.0", "2.5", "3.0", "4.0", "5.0", "6.0", "7.0", "7.5", "8.0", "8.5", "9.0", "9.5"}; + return convert_enum_idx(options, 16, value, "uac_barr_info_set_v1700_s::uac_barr_factor_for_ai3_r17_e_"); +} + // UAC-BarringPerPLMN-r15 ::= SEQUENCE SRSASN_CODE uac_barr_per_plmn_r15_s::pack(bit_ref& bref) const { @@ -3331,78 +4360,163 @@ uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_& uac_barr_per_plmn_r15_s:: log_invalid_choice_id(type_, "uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_"); } - return *this; + return *this; +} +uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::uac_implicit_ac_barr_list_r15_l_& +uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::set_uac_implicit_ac_barr_list_r15() +{ + set(types::uac_implicit_ac_barr_list_r15); + return c.get(); +} +uac_barr_per_cat_list_r15_l& uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::set_uac_explicit_ac_barr_list_r15() +{ + set(types::uac_explicit_ac_barr_list_r15); + return c.get(); +} +void uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::uac_implicit_ac_barr_list_r15: + j.start_array("uac-ImplicitAC-BarringList-r15"); + for (const auto& e1 : c.get()) { + j.write_int(e1); + } + j.end_array(); + break; + case types::uac_explicit_ac_barr_list_r15: + j.start_array("uac-ExplicitAC-BarringList-r15"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_"); + } + j.end_obj(); +} +SRSASN_CODE uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::uac_implicit_ac_barr_list_r15: + HANDLE_CODE(pack_fixed_seq_of(bref, + &(c.get())[0], + c.get().size(), + integer_packer(1, 8))); + break; + case types::uac_explicit_ac_barr_list_r15: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 63)); + break; + default: + log_invalid_choice_id(type_, "uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::uac_implicit_ac_barr_list_r15: + HANDLE_CODE(unpack_fixed_seq_of(&(c.get())[0], + bref, + c.get().size(), + integer_packer(1, 8))); + break; + case types::uac_explicit_ac_barr_list_r15: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 63)); + break; + default: + log_invalid_choice_id(type_, "uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +// ApplicableDisasterInfo-r17 ::= CHOICE +void applicable_disaster_info_r17_c::set(types::options e) +{ + type_ = e; } -uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::uac_implicit_ac_barr_list_r15_l_& -uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::set_uac_implicit_ac_barr_list_r15() +void applicable_disaster_info_r17_c::set_no_disaster_roaming_r17() { - set(types::uac_implicit_ac_barr_list_r15); - return c.get(); + set(types::no_disaster_roaming_r17); } -uac_barr_per_cat_list_r15_l& uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::set_uac_explicit_ac_barr_list_r15() +void applicable_disaster_info_r17_c::set_disaster_related_ind_r17() { - set(types::uac_explicit_ac_barr_list_r15); - return c.get(); + set(types::disaster_related_ind_r17); } -void uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::to_json(json_writer& j) const +void applicable_disaster_info_r17_c::set_common_plmns_r17() +{ + set(types::common_plmns_r17); +} +applicable_disaster_info_r17_c::ded_plmns_r17_l_& applicable_disaster_info_r17_c::set_ded_plmns_r17() +{ + set(types::ded_plmns_r17); + return c; +} +void applicable_disaster_info_r17_c::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::uac_implicit_ac_barr_list_r15: - j.start_array("uac-ImplicitAC-BarringList-r15"); - for (const auto& e1 : c.get()) { - j.write_int(e1); - } - j.end_array(); + case types::no_disaster_roaming_r17: break; - case types::uac_explicit_ac_barr_list_r15: - j.start_array("uac-ExplicitAC-BarringList-r15"); - for (const auto& e1 : c.get()) { + case types::disaster_related_ind_r17: + break; + case types::common_plmns_r17: + break; + case types::ded_plmns_r17: + j.start_array("dedicatedPLMNs-r17"); + for (const auto& e1 : c) { e1.to_json(j); } j.end_array(); break; default: - log_invalid_choice_id(type_, "uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_"); + log_invalid_choice_id(type_, "applicable_disaster_info_r17_c"); } j.end_obj(); } -SRSASN_CODE uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::pack(bit_ref& bref) const +SRSASN_CODE applicable_disaster_info_r17_c::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::uac_implicit_ac_barr_list_r15: - HANDLE_CODE(pack_fixed_seq_of(bref, - &(c.get())[0], - c.get().size(), - integer_packer(1, 8))); + case types::no_disaster_roaming_r17: break; - case types::uac_explicit_ac_barr_list_r15: - HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 63)); + case types::disaster_related_ind_r17: + break; + case types::common_plmns_r17: + break; + case types::ded_plmns_r17: + HANDLE_CODE(pack_dyn_seq_of(bref, c, 1, 6)); break; default: - log_invalid_choice_id(type_, "uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_"); + log_invalid_choice_id(type_, "applicable_disaster_info_r17_c"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_::unpack(cbit_ref& bref) +SRSASN_CODE applicable_disaster_info_r17_c::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::uac_implicit_ac_barr_list_r15: - HANDLE_CODE(unpack_fixed_seq_of(&(c.get())[0], - bref, - c.get().size(), - integer_packer(1, 8))); + case types::no_disaster_roaming_r17: break; - case types::uac_explicit_ac_barr_list_r15: - HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 63)); + case types::disaster_related_ind_r17: + break; + case types::common_plmns_r17: + break; + case types::ded_plmns_r17: + HANDLE_CODE(unpack_dyn_seq_of(c, bref, 1, 6)); break; default: - log_invalid_choice_id(type_, "uac_barr_per_plmn_r15_s::uac_ac_barr_list_type_r15_c_"); + log_invalid_choice_id(type_, "applicable_disaster_info_r17_c"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; @@ -3573,6 +4687,47 @@ void cell_resel_serving_freq_info_v1310_s::to_json(json_writer& j) const j.end_obj(); } +// CellReselectionServingFreqInfo-v1610 ::= SEQUENCE +SRSASN_CODE cell_resel_serving_freq_info_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(alt_cell_resel_prio_r16_present, 1)); + HANDLE_CODE(bref.pack(alt_cell_resel_sub_prio_r16_present, 1)); + + if (alt_cell_resel_prio_r16_present) { + HANDLE_CODE(pack_integer(bref, alt_cell_resel_prio_r16, (uint8_t)0u, (uint8_t)7u)); + } + if (alt_cell_resel_sub_prio_r16_present) { + HANDLE_CODE(alt_cell_resel_sub_prio_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE cell_resel_serving_freq_info_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(alt_cell_resel_prio_r16_present, 1)); + HANDLE_CODE(bref.unpack(alt_cell_resel_sub_prio_r16_present, 1)); + + if (alt_cell_resel_prio_r16_present) { + HANDLE_CODE(unpack_integer(alt_cell_resel_prio_r16, bref, (uint8_t)0u, (uint8_t)7u)); + } + if (alt_cell_resel_sub_prio_r16_present) { + HANDLE_CODE(alt_cell_resel_sub_prio_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void cell_resel_serving_freq_info_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (alt_cell_resel_prio_r16_present) { + j.write_int("altCellReselectionPriority-r16", alt_cell_resel_prio_r16); + } + if (alt_cell_resel_sub_prio_r16_present) { + j.write_str("altCellReselectionSubPriority-r16", alt_cell_resel_sub_prio_r16.to_string()); + } + j.end_obj(); +} + // EAB-ConfigPLMN-r11 ::= SEQUENCE SRSASN_CODE eab_cfg_plmn_r11_s::pack(bit_ref& bref) const { @@ -3661,6 +4816,32 @@ void mbms_notif_cfg_v1430_s::to_json(json_writer& j) const j.end_obj(); } +// MeasIdleConfigSIB-NR-r16 ::= SEQUENCE +SRSASN_CODE meas_idle_cfg_sib_nr_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_dyn_seq_of(bref, meas_idle_carrier_list_nr_r16, 1, 8)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_idle_cfg_sib_nr_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_dyn_seq_of(meas_idle_carrier_list_nr_r16, bref, 1, 8)); + + return SRSASN_SUCCESS; +} +void meas_idle_cfg_sib_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("measIdleCarrierListNR-r16"); + for (const auto& e1 : meas_idle_carrier_list_nr_r16) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + // MeasIdleConfigSIB-r15 ::= SEQUENCE SRSASN_CODE meas_idle_cfg_sib_r15_s::pack(bit_ref& bref) const { @@ -4326,6 +5507,261 @@ uint8_t sl_disc_cfg_remote_ue_r13_s::hyst_max_r13_opts::to_number() const return map_enum_number(options, 5, value, "sl_disc_cfg_remote_ue_r13_s::hyst_max_r13_e_"); } +// ServingSatelliteInfo-r17 ::= SEQUENCE +SRSASN_CODE serving_satellite_info_r17_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(epoch_time_r17_present, 1)); + HANDLE_CODE(bref.pack(k_mac_r17_present, 1)); + + HANDLE_CODE(ephemeris_info_r17.pack(bref)); + HANDLE_CODE(bref.pack(nta_common_params_minus17.nta_common_r17_present, 1)); + HANDLE_CODE(bref.pack(nta_common_params_minus17.nta_common_drift_r17_present, 1)); + HANDLE_CODE(bref.pack(nta_common_params_minus17.nta_common_drift_variation_r17_present, 1)); + if (nta_common_params_minus17.nta_common_r17_present) { + HANDLE_CODE(pack_integer(bref, nta_common_params_minus17.nta_common_r17, (uint32_t)0u, (uint32_t)8316827u)); + } + if (nta_common_params_minus17.nta_common_drift_r17_present) { + HANDLE_CODE(pack_integer(bref, nta_common_params_minus17.nta_common_drift_r17, (int32_t)-261935, (int32_t)261935)); + } + if (nta_common_params_minus17.nta_common_drift_variation_r17_present) { + HANDLE_CODE( + pack_integer(bref, nta_common_params_minus17.nta_common_drift_variation_r17, (uint16_t)0u, (uint16_t)29479u)); + } + HANDLE_CODE(ul_sync_validity_dur_r17.pack(bref)); + if (epoch_time_r17_present) { + HANDLE_CODE(pack_integer(bref, epoch_time_r17.start_sfn_r17, (uint16_t)0u, (uint16_t)1023u)); + HANDLE_CODE(pack_integer(bref, epoch_time_r17.start_sub_frame_r17, (uint8_t)0u, (uint8_t)9u)); + } + HANDLE_CODE(pack_integer(bref, k_offset_r17, (uint16_t)0u, (uint16_t)1023u)); + if (k_mac_r17_present) { + HANDLE_CODE(pack_integer(bref, k_mac_r17, (uint16_t)1u, (uint16_t)512u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_satellite_info_r17_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(epoch_time_r17_present, 1)); + HANDLE_CODE(bref.unpack(k_mac_r17_present, 1)); + + HANDLE_CODE(ephemeris_info_r17.unpack(bref)); + HANDLE_CODE(bref.unpack(nta_common_params_minus17.nta_common_r17_present, 1)); + HANDLE_CODE(bref.unpack(nta_common_params_minus17.nta_common_drift_r17_present, 1)); + HANDLE_CODE(bref.unpack(nta_common_params_minus17.nta_common_drift_variation_r17_present, 1)); + if (nta_common_params_minus17.nta_common_r17_present) { + HANDLE_CODE(unpack_integer(nta_common_params_minus17.nta_common_r17, bref, (uint32_t)0u, (uint32_t)8316827u)); + } + if (nta_common_params_minus17.nta_common_drift_r17_present) { + HANDLE_CODE( + unpack_integer(nta_common_params_minus17.nta_common_drift_r17, bref, (int32_t)-261935, (int32_t)261935)); + } + if (nta_common_params_minus17.nta_common_drift_variation_r17_present) { + HANDLE_CODE( + unpack_integer(nta_common_params_minus17.nta_common_drift_variation_r17, bref, (uint16_t)0u, (uint16_t)29479u)); + } + HANDLE_CODE(ul_sync_validity_dur_r17.unpack(bref)); + if (epoch_time_r17_present) { + HANDLE_CODE(unpack_integer(epoch_time_r17.start_sfn_r17, bref, (uint16_t)0u, (uint16_t)1023u)); + HANDLE_CODE(unpack_integer(epoch_time_r17.start_sub_frame_r17, bref, (uint8_t)0u, (uint8_t)9u)); + } + HANDLE_CODE(unpack_integer(k_offset_r17, bref, (uint16_t)0u, (uint16_t)1023u)); + if (k_mac_r17_present) { + HANDLE_CODE(unpack_integer(k_mac_r17, bref, (uint16_t)1u, (uint16_t)512u)); + } + + return SRSASN_SUCCESS; +} +void serving_satellite_info_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ephemerisInfo-r17"); + ephemeris_info_r17.to_json(j); + j.write_fieldname("nta-CommonParameters-17"); + j.start_obj(); + if (nta_common_params_minus17.nta_common_r17_present) { + j.write_int("nta-Common-r17", nta_common_params_minus17.nta_common_r17); + } + if (nta_common_params_minus17.nta_common_drift_r17_present) { + j.write_int("nta-CommonDrift-r17", nta_common_params_minus17.nta_common_drift_r17); + } + if (nta_common_params_minus17.nta_common_drift_variation_r17_present) { + j.write_int("nta-CommonDriftVariation-r17", nta_common_params_minus17.nta_common_drift_variation_r17); + } + j.end_obj(); + j.write_str("ul-SyncValidityDuration-r17", ul_sync_validity_dur_r17.to_string()); + if (epoch_time_r17_present) { + j.write_fieldname("epochTime-r17"); + j.start_obj(); + j.write_int("startSFN-r17", epoch_time_r17.start_sfn_r17); + j.write_int("startSubFrame-r17", epoch_time_r17.start_sub_frame_r17); + j.end_obj(); + } + j.write_int("k-Offset-r17", k_offset_r17); + if (k_mac_r17_present) { + j.write_int("k-Mac-r17", k_mac_r17); + } + j.end_obj(); +} + +void serving_satellite_info_r17_s::ephemeris_info_r17_c_::destroy_() +{ + switch (type_) { + case types::state_vectors: + c.destroy(); + break; + case types::orbital_params: + c.destroy(); + break; + default: + break; + } +} +void serving_satellite_info_r17_s::ephemeris_info_r17_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::state_vectors: + c.init(); + break; + case types::orbital_params: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_satellite_info_r17_s::ephemeris_info_r17_c_"); + } +} +serving_satellite_info_r17_s::ephemeris_info_r17_c_::ephemeris_info_r17_c_( + const serving_satellite_info_r17_s::ephemeris_info_r17_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::state_vectors: + c.init(other.c.get()); + break; + case types::orbital_params: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_satellite_info_r17_s::ephemeris_info_r17_c_"); + } +} +serving_satellite_info_r17_s::ephemeris_info_r17_c_& serving_satellite_info_r17_s::ephemeris_info_r17_c_::operator=( + const serving_satellite_info_r17_s::ephemeris_info_r17_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::state_vectors: + c.set(other.c.get()); + break; + case types::orbital_params: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "serving_satellite_info_r17_s::ephemeris_info_r17_c_"); + } + + return *this; +} +ephemeris_state_vectors_r17_s& serving_satellite_info_r17_s::ephemeris_info_r17_c_::set_state_vectors() +{ + set(types::state_vectors); + return c.get(); +} +ephemeris_orbital_params_r17_s& serving_satellite_info_r17_s::ephemeris_info_r17_c_::set_orbital_params() +{ + set(types::orbital_params); + return c.get(); +} +void serving_satellite_info_r17_s::ephemeris_info_r17_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::state_vectors: + j.write_fieldname("stateVectors"); + c.get().to_json(j); + break; + case types::orbital_params: + j.write_fieldname("orbitalParameters"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "serving_satellite_info_r17_s::ephemeris_info_r17_c_"); + } + j.end_obj(); +} +SRSASN_CODE serving_satellite_info_r17_s::ephemeris_info_r17_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::state_vectors: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::orbital_params: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "serving_satellite_info_r17_s::ephemeris_info_r17_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE serving_satellite_info_r17_s::ephemeris_info_r17_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::state_vectors: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::orbital_params: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "serving_satellite_info_r17_s::ephemeris_info_r17_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* serving_satellite_info_r17_s::ul_sync_validity_dur_r17_opts::to_string() const +{ + static const char* options[] = {"s5", + "s10", + "s15", + "s20", + "s25", + "s30", + "s35", + "s40", + "s45", + "s50", + "s55", + "s60", + "s120", + "s180", + "s240", + "s900"}; + return convert_enum_idx(options, 16, value, "serving_satellite_info_r17_s::ul_sync_validity_dur_r17_e_"); +} +uint16_t serving_satellite_info_r17_s::ul_sync_validity_dur_r17_opts::to_number() const +{ + static const uint16_t options[] = {5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 120, 180, 240, 900}; + return map_enum_number(options, 16, value, "serving_satellite_info_r17_s::ul_sync_validity_dur_r17_e_"); +} + // UAC-AC1-SelectAssistInfo-r15 ::= ENUMERATED const char* uac_ac1_select_assist_info_r15_opts::to_string() const { @@ -4333,6 +5769,13 @@ const char* uac_ac1_select_assist_info_r15_opts::to_string() const return convert_enum_idx(options, 3, value, "uac_ac1_select_assist_info_r15_e"); } +// UAC-AC1-SelectAssistInfo-r16 ::= ENUMERATED +const char* uac_ac1_select_assist_info_r16_opts::to_string() const +{ + static const char* options[] = {"a", "b", "c", "notConfigured"}; + return convert_enum_idx(options, 4, value, "uac_ac1_select_assist_info_r16_e"); +} + // SystemInformation-v8a0-IEs ::= SEQUENCE SRSASN_CODE sys_info_v8a0_ies_s::pack(bit_ref& bref) const { @@ -4648,6 +6091,8 @@ SRSASN_CODE sib_type13_r9_s::pack(bit_ref& bref) const if (ext) { ext_groups_packer_guard group_flags; group_flags[0] |= notif_cfg_v1430.is_present(); + group_flags[1] |= mbsfn_area_info_list_r16.is_present(); + group_flags[2] |= mbsfn_area_info_list_r17.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -4658,6 +6103,22 @@ SRSASN_CODE sib_type13_r9_s::pack(bit_ref& bref) const HANDLE_CODE(notif_cfg_v1430->pack(bref)); } } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(mbsfn_area_info_list_r16.is_present(), 1)); + if (mbsfn_area_info_list_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *mbsfn_area_info_list_r16, 1, 8)); + } + } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(mbsfn_area_info_list_r17.is_present(), 1)); + if (mbsfn_area_info_list_r17.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *mbsfn_area_info_list_r17, 1, 8)); + } + } } return SRSASN_SUCCESS; } @@ -4673,7 +6134,7 @@ SRSASN_CODE sib_type13_r9_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(1); + ext_groups_unpacker_guard group_flags(3); group_flags.unpack(bref); if (group_flags[0]) { @@ -4689,9 +6150,22 @@ SRSASN_CODE sib_type13_r9_s::unpack(cbit_ref& bref) if (group_flags[1]) { varlength_field_unpack_guard varlen_scope(bref, false); + + bool mbsfn_area_info_list_r16_present; HANDLE_CODE(bref.unpack(mbsfn_area_info_list_r16_present, 1)); - if (mbsfn_area_info_list_r16_present) { - HANDLE_CODE(unpack_dyn_seq_of(mbsfn_area_info_list_r16, bref, 1, 8)); + mbsfn_area_info_list_r16.set_present(mbsfn_area_info_list_r16_present); + if (mbsfn_area_info_list_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*mbsfn_area_info_list_r16, bref, 1, 8)); + } + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool mbsfn_area_info_list_r17_present; + HANDLE_CODE(bref.unpack(mbsfn_area_info_list_r17_present, 1)); + mbsfn_area_info_list_r17.set_present(mbsfn_area_info_list_r17_present); + if (mbsfn_area_info_list_r17.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*mbsfn_area_info_list_r17, bref, 1, 8)); } } } @@ -4715,9 +6189,16 @@ void sib_type13_r9_s::to_json(json_writer& j) const j.write_fieldname("notificationConfig-v1430"); notif_cfg_v1430->to_json(j); } - if (mbsfn_area_info_list_r16_present) { + if (mbsfn_area_info_list_r16.is_present()) { j.start_array("mbsfn-AreaInfoList-r16"); - for (const auto& e1 : mbsfn_area_info_list_r16) { + for (const auto& e1 : *mbsfn_area_info_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (mbsfn_area_info_list_r17.is_present()) { + j.start_array("mbsfn-AreaInfoList-r17"); + for (const auto& e1 : *mbsfn_area_info_list_r17) { e1.to_json(j); } j.end_array(); @@ -6062,6 +7543,21 @@ SRSASN_CODE sib_type21_r14_s::pack(bit_ref& bref) const HANDLE_CODE(late_non_crit_ext.pack(bref)); } + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= anchor_carrier_freq_list_nr_r16.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(anchor_carrier_freq_list_nr_r16.is_present(), 1)); + if (anchor_carrier_freq_list_nr_r16.is_present()) { + HANDLE_CODE( + pack_dyn_seq_of(bref, *anchor_carrier_freq_list_nr_r16, 1, 8, integer_packer(0, 3279165))); + } + } + } return SRSASN_SUCCESS; } SRSASN_CODE sib_type21_r14_s::unpack(cbit_ref& bref) @@ -6077,6 +7573,22 @@ SRSASN_CODE sib_type21_r14_s::unpack(cbit_ref& bref) HANDLE_CODE(late_non_crit_ext.unpack(bref)); } + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool anchor_carrier_freq_list_nr_r16_present; + HANDLE_CODE(bref.unpack(anchor_carrier_freq_list_nr_r16_present, 1)); + anchor_carrier_freq_list_nr_r16.set_present(anchor_carrier_freq_list_nr_r16_present); + if (anchor_carrier_freq_list_nr_r16.is_present()) { + HANDLE_CODE( + unpack_dyn_seq_of(*anchor_carrier_freq_list_nr_r16, bref, 1, 8, integer_packer(0, 3279165))); + } + } + } return SRSASN_SUCCESS; } void sib_type21_r14_s::to_json(json_writer& j) const @@ -6089,6 +7601,15 @@ void sib_type21_r14_s::to_json(json_writer& j) const if (late_non_crit_ext_present) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } + if (ext) { + if (anchor_carrier_freq_list_nr_r16.is_present()) { + j.start_array("anchorCarrierFreqListNR-r16"); + for (const auto& e1 : *anchor_carrier_freq_list_nr_r16) { + j.write_int(e1); + } + j.end_array(); + } + } j.end_obj(); } @@ -6111,6 +7632,38 @@ SRSASN_CODE sib_type24_r15_s::pack(bit_ref& bref) const HANDLE_CODE(late_non_crit_ext.pack(bref)); } + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= carrier_freq_list_nr_v1610.is_present(); + group_flags[1] |= carrier_freq_list_nr_v1700.is_present(); + group_flags[2] |= carrier_freq_list_nr_v1720.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(carrier_freq_list_nr_v1610.is_present(), 1)); + if (carrier_freq_list_nr_v1610.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *carrier_freq_list_nr_v1610, 1, 8)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(carrier_freq_list_nr_v1700.is_present(), 1)); + if (carrier_freq_list_nr_v1700.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *carrier_freq_list_nr_v1700, 1, 8)); + } + } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(carrier_freq_list_nr_v1720.is_present(), 1)); + if (carrier_freq_list_nr_v1720.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *carrier_freq_list_nr_v1720, 1, 8)); + } + } + } return SRSASN_SUCCESS; } SRSASN_CODE sib_type24_r15_s::unpack(cbit_ref& bref) @@ -6131,6 +7684,41 @@ SRSASN_CODE sib_type24_r15_s::unpack(cbit_ref& bref) HANDLE_CODE(late_non_crit_ext.unpack(bref)); } + if (ext) { + ext_groups_unpacker_guard group_flags(3); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool carrier_freq_list_nr_v1610_present; + HANDLE_CODE(bref.unpack(carrier_freq_list_nr_v1610_present, 1)); + carrier_freq_list_nr_v1610.set_present(carrier_freq_list_nr_v1610_present); + if (carrier_freq_list_nr_v1610.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*carrier_freq_list_nr_v1610, bref, 1, 8)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool carrier_freq_list_nr_v1700_present; + HANDLE_CODE(bref.unpack(carrier_freq_list_nr_v1700_present, 1)); + carrier_freq_list_nr_v1700.set_present(carrier_freq_list_nr_v1700_present); + if (carrier_freq_list_nr_v1700.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*carrier_freq_list_nr_v1700, bref, 1, 8)); + } + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool carrier_freq_list_nr_v1720_present; + HANDLE_CODE(bref.unpack(carrier_freq_list_nr_v1720_present, 1)); + carrier_freq_list_nr_v1720.set_present(carrier_freq_list_nr_v1720_present); + if (carrier_freq_list_nr_v1720.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*carrier_freq_list_nr_v1720, bref, 1, 8)); + } + } + } return SRSASN_SUCCESS; } void sib_type24_r15_s::to_json(json_writer& j) const @@ -6151,6 +7739,29 @@ void sib_type24_r15_s::to_json(json_writer& j) const if (late_non_crit_ext_present) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } + if (ext) { + if (carrier_freq_list_nr_v1610.is_present()) { + j.start_array("carrierFreqListNR-v1610"); + for (const auto& e1 : *carrier_freq_list_nr_v1610) { + e1.to_json(j); + } + j.end_array(); + } + if (carrier_freq_list_nr_v1700.is_present()) { + j.start_array("carrierFreqListNR-v1700"); + for (const auto& e1 : *carrier_freq_list_nr_v1700) { + e1.to_json(j); + } + j.end_array(); + } + if (carrier_freq_list_nr_v1720.is_present()) { + j.start_array("carrierFreqListNR-v1720"); + for (const auto& e1 : *carrier_freq_list_nr_v1720) { + e1.to_json(j); + } + j.end_array(); + } + } j.end_obj(); } @@ -6177,6 +7788,38 @@ SRSASN_CODE sib_type25_r15_s::pack(bit_ref& bref) const HANDLE_CODE(late_non_crit_ext.pack(bref)); } + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= ab_per_rsrp_r16_present; + group_flags[1] |= uac_ac1_select_assist_info_r16.is_present(); + group_flags[2] |= uac_barr_info_set_list_v1700.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ab_per_rsrp_r16_present, 1)); + if (ab_per_rsrp_r16_present) { + HANDLE_CODE(ab_per_rsrp_r16.pack(bref)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(uac_ac1_select_assist_info_r16.is_present(), 1)); + if (uac_ac1_select_assist_info_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *uac_ac1_select_assist_info_r16, 2, 6)); + } + } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(uac_barr_info_set_list_v1700.is_present(), 1)); + if (uac_barr_info_set_list_v1700.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *uac_barr_info_set_list_v1700, 1, 8)); + } + } + } return SRSASN_SUCCESS; } SRSASN_CODE sib_type25_r15_s::unpack(cbit_ref& bref) @@ -6201,6 +7844,39 @@ SRSASN_CODE sib_type25_r15_s::unpack(cbit_ref& bref) HANDLE_CODE(late_non_crit_ext.unpack(bref)); } + if (ext) { + ext_groups_unpacker_guard group_flags(3); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(ab_per_rsrp_r16_present, 1)); + if (ab_per_rsrp_r16_present) { + HANDLE_CODE(ab_per_rsrp_r16.unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool uac_ac1_select_assist_info_r16_present; + HANDLE_CODE(bref.unpack(uac_ac1_select_assist_info_r16_present, 1)); + uac_ac1_select_assist_info_r16.set_present(uac_ac1_select_assist_info_r16_present); + if (uac_ac1_select_assist_info_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*uac_ac1_select_assist_info_r16, bref, 2, 6)); + } + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool uac_barr_info_set_list_v1700_present; + HANDLE_CODE(bref.unpack(uac_barr_info_set_list_v1700_present, 1)); + uac_barr_info_set_list_v1700.set_present(uac_barr_info_set_list_v1700_present); + if (uac_barr_info_set_list_v1700.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*uac_barr_info_set_list_v1700, bref, 1, 8)); + } + } + } return SRSASN_SUCCESS; } void sib_type25_r15_s::to_json(json_writer& j) const @@ -6232,6 +7908,25 @@ void sib_type25_r15_s::to_json(json_writer& j) const if (late_non_crit_ext_present) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } + if (ext) { + if (ab_per_rsrp_r16_present) { + j.write_str("ab-PerRSRP-r16", ab_per_rsrp_r16.to_string()); + } + if (uac_ac1_select_assist_info_r16.is_present()) { + j.start_array("uac-AC1-SelectAssistInfo-r16"); + for (const auto& e1 : *uac_ac1_select_assist_info_r16) { + j.write_str(e1.to_string()); + } + j.end_array(); + } + if (uac_barr_info_set_list_v1700.is_present()) { + j.start_array("uac-BarringInfoSetList-v1700"); + for (const auto& e1 : *uac_barr_info_set_list_v1700) { + e1.to_json(j); + } + j.end_array(); + } + } j.end_obj(); } @@ -6365,6 +8060,17 @@ SRSASN_CODE sib_type25_r15_s::uac_ac1_select_assist_info_r15_c_::unpack(cbit_ref return SRSASN_SUCCESS; } +const char* sib_type25_r15_s::ab_per_rsrp_r16_opts::to_string() const +{ + static const char* options[] = {"thresh0", "thresh1", "thresh2", "thresh3"}; + return convert_enum_idx(options, 4, value, "sib_type25_r15_s::ab_per_rsrp_r16_e_"); +} +uint8_t sib_type25_r15_s::ab_per_rsrp_r16_opts::to_number() const +{ + static const uint8_t options[] = {0, 1, 2, 3}; + return map_enum_number(options, 4, value, "sib_type25_r15_s::ab_per_rsrp_r16_e_"); +} + // SystemInformationBlockType26-r15 ::= SEQUENCE SRSASN_CODE sib_type26_r15_s::pack(bit_ref& bref) const { @@ -6493,6 +8199,202 @@ void sib_type26_r15_s::to_json(json_writer& j) const j.end_obj(); } +// SystemInformationBlockType26a-r16 ::= SEQUENCE +SRSASN_CODE sib_type26a_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, plmn_info_list_r16, 0, 6)); + HANDLE_CODE(pack_dyn_seq_of(bref, band_list_endc_r16, 1, 10, integer_packer(1, 1024))); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type26a_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(plmn_info_list_r16, bref, 0, 6)); + HANDLE_CODE(unpack_dyn_seq_of(band_list_endc_r16, bref, 1, 10, integer_packer(1, 1024))); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type26a_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("plmn-InfoList-r16"); + for (const auto& e1 : plmn_info_list_r16) { + e1.to_json(j); + } + j.end_array(); + j.start_array("bandListENDC-r16"); + for (const auto& e1 : band_list_endc_r16) { + j.write_int(e1); + } + j.end_array(); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + +// SystemInformationBlockType27-r16 ::= SEQUENCE +SRSASN_CODE sib_type27_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(carrier_freq_list_nbiot_r16_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + if (carrier_freq_list_nbiot_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, carrier_freq_list_nbiot_r16, 1, 8)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type27_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(carrier_freq_list_nbiot_r16_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + if (carrier_freq_list_nbiot_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(carrier_freq_list_nbiot_r16, bref, 1, 8)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type27_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (carrier_freq_list_nbiot_r16_present) { + j.start_array("carrierFreqListNBIOT-r16"); + for (const auto& e1 : carrier_freq_list_nbiot_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + +// SystemInformationBlockType28-r16 ::= SEQUENCE +SRSASN_CODE sib_type28_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(pack_integer(bref, segment_num_r16, (uint8_t)0u, (uint8_t)63u)); + HANDLE_CODE(segment_type_r16.pack(bref)); + HANDLE_CODE(segment_container_r16.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type28_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(unpack_integer(segment_num_r16, bref, (uint8_t)0u, (uint8_t)63u)); + HANDLE_CODE(segment_type_r16.unpack(bref)); + HANDLE_CODE(segment_container_r16.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type28_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("segmentNumber-r16", segment_num_r16); + j.write_str("segmentType-r16", segment_type_r16.to_string()); + j.write_str("segmentContainer-r16", segment_container_r16.to_string()); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + +const char* sib_type28_r16_s::segment_type_r16_opts::to_string() const +{ + static const char* options[] = {"notLastSegment", "lastSegment"}; + return convert_enum_idx(options, 2, value, "sib_type28_r16_s::segment_type_r16_e_"); +} + +// SystemInformationBlockType29-r16 ::= SEQUENCE +SRSASN_CODE sib_type29_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(res_reserv_cfg_common_dl_r16_present, 1)); + HANDLE_CODE(bref.pack(res_reserv_cfg_common_ul_r16_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + if (res_reserv_cfg_common_dl_r16_present) { + HANDLE_CODE(res_reserv_cfg_common_dl_r16.pack(bref)); + } + if (res_reserv_cfg_common_ul_r16_present) { + HANDLE_CODE(res_reserv_cfg_common_ul_r16.pack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type29_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(res_reserv_cfg_common_dl_r16_present, 1)); + HANDLE_CODE(bref.unpack(res_reserv_cfg_common_ul_r16_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + if (res_reserv_cfg_common_dl_r16_present) { + HANDLE_CODE(res_reserv_cfg_common_dl_r16.unpack(bref)); + } + if (res_reserv_cfg_common_ul_r16_present) { + HANDLE_CODE(res_reserv_cfg_common_ul_r16.unpack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type29_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (res_reserv_cfg_common_dl_r16_present) { + j.write_fieldname("resourceReservationConfigCommonDL-r16"); + res_reserv_cfg_common_dl_r16.to_json(j); + } + if (res_reserv_cfg_common_ul_r16_present) { + j.write_fieldname("resourceReservationConfigCommonUL-r16"); + res_reserv_cfg_common_ul_r16.to_json(j); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + // SystemInformationBlockType3 ::= SEQUENCE SRSASN_CODE sib_type3_s::pack(bit_ref& bref) const { @@ -6550,6 +8452,8 @@ SRSASN_CODE sib_type3_s::pack(bit_ref& bref) const group_flags[8] |= cell_resel_info_hsdn_r15.is_present(); group_flags[8] |= cell_sel_info_ce_v1530.is_present(); group_flags[8] |= crs_intf_mitig_neigh_cells_ce_r15_present; + group_flags[9] |= cell_resel_serving_freq_info_v1610.is_present(); + group_flags[10] |= t_service_r17_present; group_flags.pack(bref); if (group_flags[0]) { @@ -6652,6 +8556,22 @@ SRSASN_CODE sib_type3_s::pack(bit_ref& bref) const HANDLE_CODE(cell_sel_info_ce_v1530->pack(bref)); } } + if (group_flags[9]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(cell_resel_serving_freq_info_v1610.is_present(), 1)); + if (cell_resel_serving_freq_info_v1610.is_present()) { + HANDLE_CODE(cell_resel_serving_freq_info_v1610->pack(bref)); + } + } + if (group_flags[10]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(t_service_r17_present, 1)); + if (t_service_r17_present) { + HANDLE_CODE(pack_integer(bref, t_service_r17, (uint32_t)0u, (uint32_t)1048575u)); + } + } } return SRSASN_SUCCESS; } @@ -6693,7 +8613,7 @@ SRSASN_CODE sib_type3_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(9); + ext_groups_unpacker_guard group_flags(11); group_flags.unpack(bref); if (group_flags[0]) { @@ -6816,6 +8736,24 @@ SRSASN_CODE sib_type3_s::unpack(cbit_ref& bref) HANDLE_CODE(cell_sel_info_ce_v1530->unpack(bref)); } } + if (group_flags[9]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool cell_resel_serving_freq_info_v1610_present; + HANDLE_CODE(bref.unpack(cell_resel_serving_freq_info_v1610_present, 1)); + cell_resel_serving_freq_info_v1610.set_present(cell_resel_serving_freq_info_v1610_present); + if (cell_resel_serving_freq_info_v1610.is_present()) { + HANDLE_CODE(cell_resel_serving_freq_info_v1610->unpack(bref)); + } + } + if (group_flags[10]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(t_service_r17_present, 1)); + if (t_service_r17_present) { + HANDLE_CODE(unpack_integer(t_service_r17, bref, (uint32_t)0u, (uint32_t)1048575u)); + } + } } return SRSASN_SUCCESS; } @@ -6934,6 +8872,13 @@ void sib_type3_s::to_json(json_writer& j) const if (crs_intf_mitig_neigh_cells_ce_r15_present) { j.write_str("crs-IntfMitigNeighCellsCE-r15", "enabled"); } + if (cell_resel_serving_freq_info_v1610.is_present()) { + j.write_fieldname("cellReselectionServingFreqInfo-v1610"); + cell_resel_serving_freq_info_v1610->to_json(j); + } + if (t_service_r17_present) { + j.write_int("t-Service-r17", t_service_r17); + } } j.end_obj(); } @@ -6999,19 +8944,164 @@ int8_t sib_type3_s::cell_resel_info_common_s_::speed_state_resel_pars_s_::q_hyst options, 4, value, "sib_type3_s::cell_resel_info_common_s_::speed_state_resel_pars_s_::q_hyst_sf_s_::sf_high_e_"); } +// SystemInformationBlockType30-r17 ::= SEQUENCE +SRSASN_CODE sib_type30_r17_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(common_plmns_with_disaster_condition_r17_present, 1)); + HANDLE_CODE(bref.pack(applicable_disaster_info_list_r17_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + if (common_plmns_with_disaster_condition_r17_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, common_plmns_with_disaster_condition_r17, 1, 6)); + } + if (applicable_disaster_info_list_r17_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, applicable_disaster_info_list_r17, 1, 6)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type30_r17_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(common_plmns_with_disaster_condition_r17_present, 1)); + HANDLE_CODE(bref.unpack(applicable_disaster_info_list_r17_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + if (common_plmns_with_disaster_condition_r17_present) { + HANDLE_CODE(unpack_dyn_seq_of(common_plmns_with_disaster_condition_r17, bref, 1, 6)); + } + if (applicable_disaster_info_list_r17_present) { + HANDLE_CODE(unpack_dyn_seq_of(applicable_disaster_info_list_r17, bref, 1, 6)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type30_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (common_plmns_with_disaster_condition_r17_present) { + j.start_array("commonPLMNsWithDisasterCondition-r17"); + for (const auto& e1 : common_plmns_with_disaster_condition_r17) { + e1.to_json(j); + } + j.end_array(); + } + if (applicable_disaster_info_list_r17_present) { + j.start_array("applicableDisasterInfoList-r17"); + for (const auto& e1 : applicable_disaster_info_list_r17) { + e1.to_json(j); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + +// SystemInformationBlockType31-r17 ::= SEQUENCE +SRSASN_CODE sib_type31_r17_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(serving_satellite_info_r17.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type31_r17_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(serving_satellite_info_r17.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type31_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("servingSatelliteInfo-r17"); + serving_satellite_info_r17.to_json(j); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + +// SystemInformationBlockType32-r17 ::= SEQUENCE +SRSASN_CODE sib_type32_r17_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(satellite_info_list_r17_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + if (satellite_info_list_r17_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, satellite_info_list_r17, 1, 4)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type32_r17_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(satellite_info_list_r17_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + if (satellite_info_list_r17_present) { + HANDLE_CODE(unpack_dyn_seq_of(satellite_info_list_r17, bref, 1, 4)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type32_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (satellite_info_list_r17_present) { + j.start_array("satelliteInfoList-r17"); + for (const auto& e1 : satellite_info_list_r17) { + e1.to_json(j); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + // SystemInformationBlockType4 ::= SEQUENCE SRSASN_CODE sib_type4_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(intra_freq_neigh_cell_list_present, 1)); - HANDLE_CODE(bref.pack(intra_freq_black_cell_list_present, 1)); + HANDLE_CODE(bref.pack(intra_freq_excluded_cell_list_present, 1)); HANDLE_CODE(bref.pack(csg_pci_range_present, 1)); if (intra_freq_neigh_cell_list_present) { HANDLE_CODE(pack_dyn_seq_of(bref, intra_freq_neigh_cell_list, 1, 16)); } - if (intra_freq_black_cell_list_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, intra_freq_black_cell_list, 1, 16)); + if (intra_freq_excluded_cell_list_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, intra_freq_excluded_cell_list, 1, 16)); } if (csg_pci_range_present) { HANDLE_CODE(csg_pci_range.pack(bref)); @@ -7021,6 +9111,8 @@ SRSASN_CODE sib_type4_s::pack(bit_ref& bref) const ext_groups_packer_guard group_flags; group_flags[0] |= late_non_crit_ext_present; group_flags[1] |= intra_freq_neigh_hsdn_cell_list_r15.is_present(); + group_flags[2] |= rss_cfg_carrier_info_r16.is_present(); + group_flags[2] |= intra_freq_neigh_cell_list_v1610.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -7036,6 +9128,18 @@ SRSASN_CODE sib_type4_s::pack(bit_ref& bref) const HANDLE_CODE(pack_dyn_seq_of(bref, *intra_freq_neigh_hsdn_cell_list_r15, 1, 16)); } } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(rss_cfg_carrier_info_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(intra_freq_neigh_cell_list_v1610.is_present(), 1)); + if (rss_cfg_carrier_info_r16.is_present()) { + HANDLE_CODE(rss_cfg_carrier_info_r16->pack(bref)); + } + if (intra_freq_neigh_cell_list_v1610.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *intra_freq_neigh_cell_list_v1610, 1, 16)); + } + } } return SRSASN_SUCCESS; } @@ -7043,21 +9147,21 @@ SRSASN_CODE sib_type4_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(intra_freq_neigh_cell_list_present, 1)); - HANDLE_CODE(bref.unpack(intra_freq_black_cell_list_present, 1)); + HANDLE_CODE(bref.unpack(intra_freq_excluded_cell_list_present, 1)); HANDLE_CODE(bref.unpack(csg_pci_range_present, 1)); if (intra_freq_neigh_cell_list_present) { HANDLE_CODE(unpack_dyn_seq_of(intra_freq_neigh_cell_list, bref, 1, 16)); } - if (intra_freq_black_cell_list_present) { - HANDLE_CODE(unpack_dyn_seq_of(intra_freq_black_cell_list, bref, 1, 16)); + if (intra_freq_excluded_cell_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(intra_freq_excluded_cell_list, bref, 1, 16)); } if (csg_pci_range_present) { HANDLE_CODE(csg_pci_range.unpack(bref)); } if (ext) { - ext_groups_unpacker_guard group_flags(2); + ext_groups_unpacker_guard group_flags(3); group_flags.unpack(bref); if (group_flags[0]) { @@ -7075,6 +9179,22 @@ SRSASN_CODE sib_type4_s::unpack(cbit_ref& bref) HANDLE_CODE(unpack_dyn_seq_of(*intra_freq_neigh_hsdn_cell_list_r15, bref, 1, 16)); } } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool rss_cfg_carrier_info_r16_present; + HANDLE_CODE(bref.unpack(rss_cfg_carrier_info_r16_present, 1)); + rss_cfg_carrier_info_r16.set_present(rss_cfg_carrier_info_r16_present); + bool intra_freq_neigh_cell_list_v1610_present; + HANDLE_CODE(bref.unpack(intra_freq_neigh_cell_list_v1610_present, 1)); + intra_freq_neigh_cell_list_v1610.set_present(intra_freq_neigh_cell_list_v1610_present); + if (rss_cfg_carrier_info_r16.is_present()) { + HANDLE_CODE(rss_cfg_carrier_info_r16->unpack(bref)); + } + if (intra_freq_neigh_cell_list_v1610.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*intra_freq_neigh_cell_list_v1610, bref, 1, 16)); + } + } } return SRSASN_SUCCESS; } @@ -7088,9 +9208,9 @@ void sib_type4_s::to_json(json_writer& j) const } j.end_array(); } - if (intra_freq_black_cell_list_present) { - j.start_array("intraFreqBlackCellList"); - for (const auto& e1 : intra_freq_black_cell_list) { + if (intra_freq_excluded_cell_list_present) { + j.start_array("intraFreqExcludedCellList"); + for (const auto& e1 : intra_freq_excluded_cell_list) { e1.to_json(j); } j.end_array(); @@ -7110,6 +9230,17 @@ void sib_type4_s::to_json(json_writer& j) const } j.end_array(); } + if (rss_cfg_carrier_info_r16.is_present()) { + j.write_fieldname("rss-ConfigCarrierInfo-r16"); + rss_cfg_carrier_info_r16->to_json(j); + } + if (intra_freq_neigh_cell_list_v1610.is_present()) { + j.start_array("intraFreqNeighCellList-v1610"); + for (const auto& e1 : *intra_freq_neigh_cell_list_v1610) { + e1.to_json(j); + } + j.end_array(); + } } j.end_obj(); } @@ -7135,6 +9266,9 @@ SRSASN_CODE sib_type5_s::pack(bit_ref& bref) const group_flags[7] |= inter_freq_carrier_freq_list_v1530.is_present(); group_flags[7] |= inter_freq_carrier_freq_list_ext_v1530.is_present(); group_flags[7] |= meas_idle_cfg_sib_r15.is_present(); + group_flags[8] |= inter_freq_carrier_freq_list_v1610.is_present(); + group_flags[8] |= inter_freq_carrier_freq_list_ext_v1610.is_present(); + group_flags[8] |= meas_idle_cfg_sib_nr_r16.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -7218,6 +9352,22 @@ SRSASN_CODE sib_type5_s::pack(bit_ref& bref) const HANDLE_CODE(meas_idle_cfg_sib_r15->pack(bref)); } } + if (group_flags[8]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(inter_freq_carrier_freq_list_v1610.is_present(), 1)); + HANDLE_CODE(bref.pack(inter_freq_carrier_freq_list_ext_v1610.is_present(), 1)); + HANDLE_CODE(bref.pack(meas_idle_cfg_sib_nr_r16.is_present(), 1)); + if (inter_freq_carrier_freq_list_v1610.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *inter_freq_carrier_freq_list_v1610, 1, 8)); + } + if (inter_freq_carrier_freq_list_ext_v1610.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *inter_freq_carrier_freq_list_ext_v1610, 1, 8)); + } + if (meas_idle_cfg_sib_nr_r16.is_present()) { + HANDLE_CODE(meas_idle_cfg_sib_nr_r16->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -7227,7 +9377,7 @@ SRSASN_CODE sib_type5_s::unpack(cbit_ref& bref) HANDLE_CODE(unpack_dyn_seq_of(inter_freq_carrier_freq_list, bref, 1, 8)); if (ext) { - ext_groups_unpacker_guard group_flags(8); + ext_groups_unpacker_guard group_flags(9); group_flags.unpack(bref); if (group_flags[0]) { @@ -7333,6 +9483,28 @@ SRSASN_CODE sib_type5_s::unpack(cbit_ref& bref) HANDLE_CODE(meas_idle_cfg_sib_r15->unpack(bref)); } } + if (group_flags[8]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool inter_freq_carrier_freq_list_v1610_present; + HANDLE_CODE(bref.unpack(inter_freq_carrier_freq_list_v1610_present, 1)); + inter_freq_carrier_freq_list_v1610.set_present(inter_freq_carrier_freq_list_v1610_present); + bool inter_freq_carrier_freq_list_ext_v1610_present; + HANDLE_CODE(bref.unpack(inter_freq_carrier_freq_list_ext_v1610_present, 1)); + inter_freq_carrier_freq_list_ext_v1610.set_present(inter_freq_carrier_freq_list_ext_v1610_present); + bool meas_idle_cfg_sib_nr_r16_present; + HANDLE_CODE(bref.unpack(meas_idle_cfg_sib_nr_r16_present, 1)); + meas_idle_cfg_sib_nr_r16.set_present(meas_idle_cfg_sib_nr_r16_present); + if (inter_freq_carrier_freq_list_v1610.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*inter_freq_carrier_freq_list_v1610, bref, 1, 8)); + } + if (inter_freq_carrier_freq_list_ext_v1610.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*inter_freq_carrier_freq_list_ext_v1610, bref, 1, 8)); + } + if (meas_idle_cfg_sib_nr_r16.is_present()) { + HANDLE_CODE(meas_idle_cfg_sib_nr_r16->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -7425,6 +9597,24 @@ void sib_type5_s::to_json(json_writer& j) const j.write_fieldname("measIdleConfigSIB-r15"); meas_idle_cfg_sib_r15->to_json(j); } + if (inter_freq_carrier_freq_list_v1610.is_present()) { + j.start_array("interFreqCarrierFreqList-v1610"); + for (const auto& e1 : *inter_freq_carrier_freq_list_v1610) { + e1.to_json(j); + } + j.end_array(); + } + if (inter_freq_carrier_freq_list_ext_v1610.is_present()) { + j.start_array("interFreqCarrierFreqListExt-v1610"); + for (const auto& e1 : *inter_freq_carrier_freq_list_ext_v1610) { + e1.to_json(j); + } + j.end_array(); + } + if (meas_idle_cfg_sib_nr_r16.is_present()) { + j.write_fieldname("measIdleConfigSIB-NR-r16"); + meas_idle_cfg_sib_nr_r16->to_json(j); + } } j.end_obj(); } @@ -8113,6 +10303,39 @@ void pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::destroy_() case types::pos_sib3_minus1_r15: c.destroy(); break; + case types::pos_sib1_minus8_v1610: + c.destroy(); + break; + case types::pos_sib2_minus20_v1610: + c.destroy(); + break; + case types::pos_sib2_minus21_v1610: + c.destroy(); + break; + case types::pos_sib2_minus22_v1610: + c.destroy(); + break; + case types::pos_sib2_minus23_v1610: + c.destroy(); + break; + case types::pos_sib2_minus24_v1610: + c.destroy(); + break; + case types::pos_sib2_minus25_v1610: + c.destroy(); + break; + case types::pos_sib4_minus1_v1610: + c.destroy(); + break; + case types::pos_sib5_minus1_v1610: + c.destroy(); + break; + case types::pos_sib1_minus9_v1700: + c.destroy(); + break; + case types::pos_sib1_minus10_v1700: + c.destroy(); + break; default: break; } @@ -8203,6 +10426,39 @@ void pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set(types::optio case types::pos_sib3_minus1_r15: c.init(); break; + case types::pos_sib1_minus8_v1610: + c.init(); + break; + case types::pos_sib2_minus20_v1610: + c.init(); + break; + case types::pos_sib2_minus21_v1610: + c.init(); + break; + case types::pos_sib2_minus22_v1610: + c.init(); + break; + case types::pos_sib2_minus23_v1610: + c.init(); + break; + case types::pos_sib2_minus24_v1610: + c.init(); + break; + case types::pos_sib2_minus25_v1610: + c.init(); + break; + case types::pos_sib4_minus1_v1610: + c.init(); + break; + case types::pos_sib5_minus1_v1610: + c.init(); + break; + case types::pos_sib1_minus9_v1700: + c.init(); + break; + case types::pos_sib1_minus10_v1700: + c.init(); + break; case types::nulltype: break; default: @@ -8295,6 +10551,39 @@ pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::pos_sib_type_and_info case types::pos_sib3_minus1_r15: c.init(other.c.get()); break; + case types::pos_sib1_minus8_v1610: + c.init(other.c.get()); + break; + case types::pos_sib2_minus20_v1610: + c.init(other.c.get()); + break; + case types::pos_sib2_minus21_v1610: + c.init(other.c.get()); + break; + case types::pos_sib2_minus22_v1610: + c.init(other.c.get()); + break; + case types::pos_sib2_minus23_v1610: + c.init(other.c.get()); + break; + case types::pos_sib2_minus24_v1610: + c.init(other.c.get()); + break; + case types::pos_sib2_minus25_v1610: + c.init(other.c.get()); + break; + case types::pos_sib4_minus1_v1610: + c.init(other.c.get()); + break; + case types::pos_sib5_minus1_v1610: + c.init(other.c.get()); + break; + case types::pos_sib1_minus9_v1700: + c.init(other.c.get()); + break; + case types::pos_sib1_minus10_v1700: + c.init(other.c.get()); + break; case types::nulltype: break; default: @@ -8355,40 +10644,73 @@ pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::operator=( case types::pos_sib2_minus8_r15: c.set(other.c.get()); break; - case types::pos_sib2_minus9_r15: + case types::pos_sib2_minus9_r15: + c.set(other.c.get()); + break; + case types::pos_sib2_minus10_r15: + c.set(other.c.get()); + break; + case types::pos_sib2_minus11_r15: + c.set(other.c.get()); + break; + case types::pos_sib2_minus12_r15: + c.set(other.c.get()); + break; + case types::pos_sib2_minus13_r15: + c.set(other.c.get()); + break; + case types::pos_sib2_minus14_r15: + c.set(other.c.get()); + break; + case types::pos_sib2_minus15_r15: + c.set(other.c.get()); + break; + case types::pos_sib2_minus16_r15: + c.set(other.c.get()); + break; + case types::pos_sib2_minus17_r15: + c.set(other.c.get()); + break; + case types::pos_sib2_minus18_r15: + c.set(other.c.get()); + break; + case types::pos_sib2_minus19_r15: + c.set(other.c.get()); + break; + case types::pos_sib3_minus1_r15: c.set(other.c.get()); break; - case types::pos_sib2_minus10_r15: + case types::pos_sib1_minus8_v1610: c.set(other.c.get()); break; - case types::pos_sib2_minus11_r15: + case types::pos_sib2_minus20_v1610: c.set(other.c.get()); break; - case types::pos_sib2_minus12_r15: + case types::pos_sib2_minus21_v1610: c.set(other.c.get()); break; - case types::pos_sib2_minus13_r15: + case types::pos_sib2_minus22_v1610: c.set(other.c.get()); break; - case types::pos_sib2_minus14_r15: + case types::pos_sib2_minus23_v1610: c.set(other.c.get()); break; - case types::pos_sib2_minus15_r15: + case types::pos_sib2_minus24_v1610: c.set(other.c.get()); break; - case types::pos_sib2_minus16_r15: + case types::pos_sib2_minus25_v1610: c.set(other.c.get()); break; - case types::pos_sib2_minus17_r15: + case types::pos_sib4_minus1_v1610: c.set(other.c.get()); break; - case types::pos_sib2_minus18_r15: + case types::pos_sib5_minus1_v1610: c.set(other.c.get()); break; - case types::pos_sib2_minus19_r15: + case types::pos_sib1_minus9_v1700: c.set(other.c.get()); break; - case types::pos_sib3_minus1_r15: + case types::pos_sib1_minus10_v1700: c.set(other.c.get()); break; case types::nulltype: @@ -8534,6 +10856,61 @@ sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_po set(types::pos_sib3_minus1_r15); return c.get(); } +sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_pos_sib1_minus8_v1610() +{ + set(types::pos_sib1_minus8_v1610); + return c.get(); +} +sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_pos_sib2_minus20_v1610() +{ + set(types::pos_sib2_minus20_v1610); + return c.get(); +} +sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_pos_sib2_minus21_v1610() +{ + set(types::pos_sib2_minus21_v1610); + return c.get(); +} +sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_pos_sib2_minus22_v1610() +{ + set(types::pos_sib2_minus22_v1610); + return c.get(); +} +sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_pos_sib2_minus23_v1610() +{ + set(types::pos_sib2_minus23_v1610); + return c.get(); +} +sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_pos_sib2_minus24_v1610() +{ + set(types::pos_sib2_minus24_v1610); + return c.get(); +} +sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_pos_sib2_minus25_v1610() +{ + set(types::pos_sib2_minus25_v1610); + return c.get(); +} +sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_pos_sib4_minus1_v1610() +{ + set(types::pos_sib4_minus1_v1610); + return c.get(); +} +sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_pos_sib5_minus1_v1610() +{ + set(types::pos_sib5_minus1_v1610); + return c.get(); +} +sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_pos_sib1_minus9_v1700() +{ + set(types::pos_sib1_minus9_v1700); + return c.get(); +} +sib_pos_r15_s& pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::set_pos_sib1_minus10_v1700() +{ + set(types::pos_sib1_minus10_v1700); + return c.get(); +} void pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::to_json(json_writer& j) const { j.start_obj(); @@ -8646,6 +11023,50 @@ void pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::to_json(json_wri j.write_fieldname("posSib3-1-r15"); c.get().to_json(j); break; + case types::pos_sib1_minus8_v1610: + j.write_fieldname("posSib1-8-v1610"); + c.get().to_json(j); + break; + case types::pos_sib2_minus20_v1610: + j.write_fieldname("posSib2-20-v1610"); + c.get().to_json(j); + break; + case types::pos_sib2_minus21_v1610: + j.write_fieldname("posSib2-21-v1610"); + c.get().to_json(j); + break; + case types::pos_sib2_minus22_v1610: + j.write_fieldname("posSib2-22-v1610"); + c.get().to_json(j); + break; + case types::pos_sib2_minus23_v1610: + j.write_fieldname("posSib2-23-v1610"); + c.get().to_json(j); + break; + case types::pos_sib2_minus24_v1610: + j.write_fieldname("posSib2-24-v1610"); + c.get().to_json(j); + break; + case types::pos_sib2_minus25_v1610: + j.write_fieldname("posSib2-25-v1610"); + c.get().to_json(j); + break; + case types::pos_sib4_minus1_v1610: + j.write_fieldname("posSib4-1-v1610"); + c.get().to_json(j); + break; + case types::pos_sib5_minus1_v1610: + j.write_fieldname("posSib5-1-v1610"); + c.get().to_json(j); + break; + case types::pos_sib1_minus9_v1700: + j.write_fieldname("posSib1-9-v1700"); + c.get().to_json(j); + break; + case types::pos_sib1_minus10_v1700: + j.write_fieldname("posSib1-10-v1700"); + c.get().to_json(j); + break; default: log_invalid_choice_id(type_, "pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_"); } @@ -8736,6 +11157,50 @@ SRSASN_CODE pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::pack(bit_ case types::pos_sib3_minus1_r15: HANDLE_CODE(c.get().pack(bref)); break; + case types::pos_sib1_minus8_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::pos_sib2_minus20_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::pos_sib2_minus21_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::pos_sib2_minus22_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::pos_sib2_minus23_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::pos_sib2_minus24_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::pos_sib2_minus25_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::pos_sib4_minus1_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::pos_sib5_minus1_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::pos_sib1_minus9_v1700: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::pos_sib1_minus10_v1700: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; default: log_invalid_choice_id(type_, "pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_"); return SRSASN_ERROR_ENCODE_FAIL; @@ -8829,6 +11294,50 @@ SRSASN_CODE pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_::unpack(cb case types::pos_sib3_minus1_r15: HANDLE_CODE(c.get().unpack(bref)); break; + case types::pos_sib1_minus8_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::pos_sib2_minus20_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::pos_sib2_minus21_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::pos_sib2_minus22_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::pos_sib2_minus23_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::pos_sib2_minus24_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::pos_sib2_minus25_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::pos_sib4_minus1_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::pos_sib5_minus1_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::pos_sib1_minus9_v1700: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::pos_sib1_minus10_v1700: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; default: log_invalid_choice_id(type_, "pos_sys_info_r15_ies_s::pos_sib_type_and_info_r15_item_c_"); return SRSASN_ERROR_DECODE_FAIL; @@ -8908,6 +11417,27 @@ void sib_info_item_c::destroy_() case types::sib26_v1530: c.destroy(); break; + case types::sib26a_v1610: + c.destroy(); + break; + case types::sib27_v1610: + c.destroy(); + break; + case types::sib28_v1610: + c.destroy(); + break; + case types::sib29_v1610: + c.destroy(); + break; + case types::sib30_v1700: + c.destroy(); + break; + case types::sib31_v1700: + c.destroy(); + break; + case types::sib32_v1700: + c.destroy(); + break; default: break; } @@ -8986,6 +11516,27 @@ void sib_info_item_c::set(types::options e) case types::sib26_v1530: c.init(); break; + case types::sib26a_v1610: + c.init(); + break; + case types::sib27_v1610: + c.init(); + break; + case types::sib28_v1610: + c.init(); + break; + case types::sib29_v1610: + c.init(); + break; + case types::sib30_v1700: + c.init(); + break; + case types::sib31_v1700: + c.init(); + break; + case types::sib32_v1700: + c.init(); + break; case types::nulltype: break; default: @@ -9065,6 +11616,27 @@ sib_info_item_c::sib_info_item_c(const sib_info_item_c& other) case types::sib26_v1530: c.init(other.c.get()); break; + case types::sib26a_v1610: + c.init(other.c.get()); + break; + case types::sib27_v1610: + c.init(other.c.get()); + break; + case types::sib28_v1610: + c.init(other.c.get()); + break; + case types::sib29_v1610: + c.init(other.c.get()); + break; + case types::sib30_v1700: + c.init(other.c.get()); + break; + case types::sib31_v1700: + c.init(other.c.get()); + break; + case types::sib32_v1700: + c.init(other.c.get()); + break; case types::nulltype: break; default: @@ -9147,6 +11719,27 @@ sib_info_item_c& sib_info_item_c::operator=(const sib_info_item_c& other) case types::sib26_v1530: c.set(other.c.get()); break; + case types::sib26a_v1610: + c.set(other.c.get()); + break; + case types::sib27_v1610: + c.set(other.c.get()); + break; + case types::sib28_v1610: + c.set(other.c.get()); + break; + case types::sib29_v1610: + c.set(other.c.get()); + break; + case types::sib30_v1700: + c.set(other.c.get()); + break; + case types::sib31_v1700: + c.set(other.c.get()); + break; + case types::sib32_v1700: + c.set(other.c.get()); + break; case types::nulltype: break; default: @@ -9270,6 +11863,41 @@ sib_type26_r15_s& sib_info_item_c::set_sib26_v1530() set(types::sib26_v1530); return c.get(); } +sib_type26a_r16_s& sib_info_item_c::set_sib26a_v1610() +{ + set(types::sib26a_v1610); + return c.get(); +} +sib_type27_r16_s& sib_info_item_c::set_sib27_v1610() +{ + set(types::sib27_v1610); + return c.get(); +} +sib_type28_r16_s& sib_info_item_c::set_sib28_v1610() +{ + set(types::sib28_v1610); + return c.get(); +} +sib_type29_r16_s& sib_info_item_c::set_sib29_v1610() +{ + set(types::sib29_v1610); + return c.get(); +} +sib_type30_r17_s& sib_info_item_c::set_sib30_v1700() +{ + set(types::sib30_v1700); + return c.get(); +} +sib_type31_r17_s& sib_info_item_c::set_sib31_v1700() +{ + set(types::sib31_v1700); + return c.get(); +} +sib_type32_r17_s& sib_info_item_c::set_sib32_v1700() +{ + set(types::sib32_v1700); + return c.get(); +} void sib_info_item_c::to_json(json_writer& j) const { j.start_obj(); @@ -9366,6 +11994,34 @@ void sib_info_item_c::to_json(json_writer& j) const j.write_fieldname("sib26-v1530"); c.get().to_json(j); break; + case types::sib26a_v1610: + j.write_fieldname("sib26a-v1610"); + c.get().to_json(j); + break; + case types::sib27_v1610: + j.write_fieldname("sib27-v1610"); + c.get().to_json(j); + break; + case types::sib28_v1610: + j.write_fieldname("sib28-v1610"); + c.get().to_json(j); + break; + case types::sib29_v1610: + j.write_fieldname("sib29-v1610"); + c.get().to_json(j); + break; + case types::sib30_v1700: + j.write_fieldname("sib30-v1700"); + c.get().to_json(j); + break; + case types::sib31_v1700: + j.write_fieldname("sib31-v1700"); + c.get().to_json(j); + break; + case types::sib32_v1700: + j.write_fieldname("sib32-v1700"); + c.get().to_json(j); + break; default: log_invalid_choice_id(type_, "sib_info_item_c"); } @@ -9457,6 +12113,34 @@ SRSASN_CODE sib_info_item_c::pack(bit_ref& bref) const varlength_field_pack_guard varlen_scope(bref, false); HANDLE_CODE(c.get().pack(bref)); } break; + case types::sib26a_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib27_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib28_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib29_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib30_v1700: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib31_v1700: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib32_v1700: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; default: log_invalid_choice_id(type_, "sib_info_item_c"); return SRSASN_ERROR_ENCODE_FAIL; @@ -9551,6 +12235,34 @@ SRSASN_CODE sib_info_item_c::unpack(cbit_ref& bref) varlength_field_unpack_guard varlen_scope(bref, false); HANDLE_CODE(c.get().unpack(bref)); } break; + case types::sib26a_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib27_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib28_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib29_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib30_v1700: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib31_v1700: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib32_v1700: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; default: log_invalid_choice_id(type_, "sib_info_item_c"); return SRSASN_ERROR_DECODE_FAIL; @@ -10698,23 +13410,18 @@ const char* sib_type_v12j0_opts::to_string() const "sibType24-v1530", "sibType25-v1530", "sibType26-v1530", - "spare10", - "spare9", - "spare8", - "spare7", - "spare6", - "spare5", - "spare4", + "sibType26a-v1610", + "sibType27-v1610", + "sibType28-v1610", + "sibType29-v1610", + "sibType30-v1700", + "sibType31-v1700", + "sibType32-v1700", "spare3", "spare2", "spare1"}; return convert_enum_idx(options, 16, value, "sib_type_v12j0_e"); } -uint8_t sib_type_v12j0_opts::to_number() const -{ - static const uint8_t options[] = {19, 20, 21, 24, 25, 26}; - return map_enum_number(options, 6, value, "sib_type_v12j0_e"); -} // SchedulingInfo-v12j0 ::= SEQUENCE SRSASN_CODE sched_info_v12j0_s::pack(bit_ref& bref) const @@ -10777,6 +13484,50 @@ void sched_info_ext_r12_s::to_json(json_writer& j) const j.end_obj(); } +// SystemInformationBlockType1-v15g0-IEs ::= SEQUENCE +SRSASN_CODE sib_type1_v15g0_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(bw_reduced_access_related_info_v15g0_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (bw_reduced_access_related_info_v15g0_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, bw_reduced_access_related_info_v15g0.pos_sched_info_list_br_r15, 1, 32)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type1_v15g0_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(bw_reduced_access_related_info_v15g0_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (bw_reduced_access_related_info_v15g0_present) { + HANDLE_CODE(unpack_dyn_seq_of(bw_reduced_access_related_info_v15g0.pos_sched_info_list_br_r15, bref, 1, 32)); + } + + return SRSASN_SUCCESS; +} +void sib_type1_v15g0_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (bw_reduced_access_related_info_v15g0_present) { + j.write_fieldname("bandwidthReducedAccessRelatedInfo-v15g0"); + j.start_obj(); + j.start_array("posSchedulingInfoList-BR-r15"); + for (const auto& e1 : bw_reduced_access_related_info_v15g0.pos_sched_info_list_br_r15) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // SystemInformationBlockType1-v12j0-IEs ::= SEQUENCE SRSASN_CODE sib_type1_v12j0_ies_s::pack(bit_ref& bref) const { @@ -10790,6 +13541,9 @@ SRSASN_CODE sib_type1_v12j0_ies_s::pack(bit_ref& bref) const if (sched_info_list_ext_r12_present) { HANDLE_CODE(pack_dyn_seq_of(bref, sched_info_list_ext_r12, 1, 32)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -10805,6 +13559,9 @@ SRSASN_CODE sib_type1_v12j0_ies_s::unpack(cbit_ref& bref) if (sched_info_list_ext_r12_present) { HANDLE_CODE(unpack_dyn_seq_of(sched_info_list_ext_r12, bref, 1, 32)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -10827,8 +13584,7 @@ void sib_type1_v12j0_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } diff --git a/lib/src/asn1/rrc/common.cc b/lib/src/asn1/rrc/common.cc index 41621adf2f..0778724aaf 100644 --- a/lib/src/asn1/rrc/common.cc +++ b/lib/src/asn1/rrc/common.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/asn1/rrc/common_ext.cc b/lib/src/asn1/rrc/common_ext.cc index 836f9ac7f6..48dabcc8cd 100644 --- a/lib/src/asn1/rrc/common_ext.cc +++ b/lib/src/asn1/rrc/common_ext.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/asn1/rrc/dl_ccch_msg.cc b/lib/src/asn1/rrc/dl_ccch_msg.cc index ff0c6c2f87..71eaf70263 100644 --- a/lib/src/asn1/rrc/dl_ccch_msg.cc +++ b/lib/src/asn1/rrc/dl_ccch_msg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -426,6 +426,43 @@ void rrc_conn_reject_v1020_ies_s::to_json(json_writer& j) const j.end_obj(); } +// RRCConnectionSetup-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ded_info_nas_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (ded_info_nas_r16_present) { + HANDLE_CODE(ded_info_nas_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_setup_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ded_info_nas_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (ded_info_nas_r16_present) { + HANDLE_CODE(ded_info_nas_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_setup_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ded_info_nas_r16_present) { + j.write_str("dedicatedInfoNAS-r16", ded_info_nas_r16.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // IdleModeMobilityControlInfo ::= SEQUENCE SRSASN_CODE idle_mode_mob_ctrl_info_s::pack(bit_ref& bref) const { @@ -816,6 +853,9 @@ SRSASN_CODE rrc_conn_setup_v8a0_ies_s::pack(bit_ref& bref) const if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -827,6 +867,9 @@ SRSASN_CODE rrc_conn_setup_v8a0_ies_s::unpack(cbit_ref& bref) if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -838,8 +881,7 @@ void rrc_conn_setup_v8a0_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -885,16 +927,16 @@ void rrc_early_data_complete_v1590_ies_s::to_json(json_writer& j) const void redirected_carrier_info_r15_ies_c::destroy_() { switch (type_) { - case types::geran_r15: + case types::geran: c.destroy(); break; - case types::cdma2000_hrpd_r15: + case types::cdma2000_hrpd: c.destroy(); break; - case types::cdma2000_minus1x_rtt_r15: + case types::cdma2000_minus1x_rtt: c.destroy(); break; - case types::utra_tdd_r15: + case types::utra_tdd: c.destroy(); break; default: @@ -906,20 +948,20 @@ void redirected_carrier_info_r15_ies_c::set(types::options e) destroy_(); type_ = e; switch (type_) { - case types::eutra_r15: + case types::eutra: break; - case types::geran_r15: + case types::geran: c.init(); break; - case types::utra_fdd_r15: + case types::utra_fdd: break; - case types::cdma2000_hrpd_r15: + case types::cdma2000_hrpd: c.init(); break; - case types::cdma2000_minus1x_rtt_r15: + case types::cdma2000_minus1x_rtt: c.init(); break; - case types::utra_tdd_r15: + case types::utra_tdd: c.init(); break; case types::nulltype: @@ -932,22 +974,22 @@ redirected_carrier_info_r15_ies_c::redirected_carrier_info_r15_ies_c(const redir { type_ = other.type(); switch (type_) { - case types::eutra_r15: + case types::eutra: c.init(other.c.get()); break; - case types::geran_r15: + case types::geran: c.init(other.c.get()); break; - case types::utra_fdd_r15: + case types::utra_fdd: c.init(other.c.get()); break; - case types::cdma2000_hrpd_r15: + case types::cdma2000_hrpd: c.init(other.c.get()); break; - case types::cdma2000_minus1x_rtt_r15: + case types::cdma2000_minus1x_rtt: c.init(other.c.get()); break; - case types::utra_tdd_r15: + case types::utra_tdd: c.init(other.c.get()); break; case types::nulltype: @@ -964,22 +1006,22 @@ redirected_carrier_info_r15_ies_c::operator=(const redirected_carrier_info_r15_i } set(other.type()); switch (type_) { - case types::eutra_r15: + case types::eutra: c.set(other.c.get()); break; - case types::geran_r15: + case types::geran: c.set(other.c.get()); break; - case types::utra_fdd_r15: + case types::utra_fdd: c.set(other.c.get()); break; - case types::cdma2000_hrpd_r15: + case types::cdma2000_hrpd: c.set(other.c.get()); break; - case types::cdma2000_minus1x_rtt_r15: + case types::cdma2000_minus1x_rtt: c.set(other.c.get()); break; - case types::utra_tdd_r15: + case types::utra_tdd: c.set(other.c.get()); break; case types::nulltype: @@ -990,60 +1032,60 @@ redirected_carrier_info_r15_ies_c::operator=(const redirected_carrier_info_r15_i return *this; } -uint32_t& redirected_carrier_info_r15_ies_c::set_eutra_r15() +uint32_t& redirected_carrier_info_r15_ies_c::set_eutra() { - set(types::eutra_r15); + set(types::eutra); return c.get(); } -carrier_freqs_geran_s& redirected_carrier_info_r15_ies_c::set_geran_r15() +carrier_freqs_geran_s& redirected_carrier_info_r15_ies_c::set_geran() { - set(types::geran_r15); + set(types::geran); return c.get(); } -uint16_t& redirected_carrier_info_r15_ies_c::set_utra_fdd_r15() +uint16_t& redirected_carrier_info_r15_ies_c::set_utra_fdd() { - set(types::utra_fdd_r15); + set(types::utra_fdd); return c.get(); } -carrier_freq_cdma2000_s& redirected_carrier_info_r15_ies_c::set_cdma2000_hrpd_r15() +carrier_freq_cdma2000_s& redirected_carrier_info_r15_ies_c::set_cdma2000_hrpd() { - set(types::cdma2000_hrpd_r15); + set(types::cdma2000_hrpd); return c.get(); } -carrier_freq_cdma2000_s& redirected_carrier_info_r15_ies_c::set_cdma2000_minus1x_rtt_r15() +carrier_freq_cdma2000_s& redirected_carrier_info_r15_ies_c::set_cdma2000_minus1x_rtt() { - set(types::cdma2000_minus1x_rtt_r15); + set(types::cdma2000_minus1x_rtt); return c.get(); } -carrier_freq_list_utra_tdd_r10_l& redirected_carrier_info_r15_ies_c::set_utra_tdd_r15() +carrier_freq_list_utra_tdd_r10_l& redirected_carrier_info_r15_ies_c::set_utra_tdd() { - set(types::utra_tdd_r15); + set(types::utra_tdd); return c.get(); } void redirected_carrier_info_r15_ies_c::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::eutra_r15: - j.write_int("eutra-r15", c.get()); + case types::eutra: + j.write_int("eutra", c.get()); break; - case types::geran_r15: - j.write_fieldname("geran-r15"); + case types::geran: + j.write_fieldname("geran"); c.get().to_json(j); break; - case types::utra_fdd_r15: - j.write_int("utra-FDD-r15", c.get()); + case types::utra_fdd: + j.write_int("utra-FDD", c.get()); break; - case types::cdma2000_hrpd_r15: - j.write_fieldname("cdma2000-HRPD-r15"); + case types::cdma2000_hrpd: + j.write_fieldname("cdma2000-HRPD"); c.get().to_json(j); break; - case types::cdma2000_minus1x_rtt_r15: - j.write_fieldname("cdma2000-1xRTT-r15"); + case types::cdma2000_minus1x_rtt: + j.write_fieldname("cdma2000-1xRTT"); c.get().to_json(j); break; - case types::utra_tdd_r15: - j.start_array("utra-TDD-r15"); + case types::utra_tdd: + j.start_array("utra-TDD"); for (const auto& e1 : c.get()) { j.write_int(e1); } @@ -1058,22 +1100,22 @@ SRSASN_CODE redirected_carrier_info_r15_ies_c::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::eutra_r15: + case types::eutra: HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)0u, (uint32_t)262143u)); break; - case types::geran_r15: + case types::geran: HANDLE_CODE(c.get().pack(bref)); break; - case types::utra_fdd_r15: + case types::utra_fdd: HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)16383u)); break; - case types::cdma2000_hrpd_r15: + case types::cdma2000_hrpd: HANDLE_CODE(c.get().pack(bref)); break; - case types::cdma2000_minus1x_rtt_r15: + case types::cdma2000_minus1x_rtt: HANDLE_CODE(c.get().pack(bref)); break; - case types::utra_tdd_r15: + case types::utra_tdd: HANDLE_CODE( pack_dyn_seq_of(bref, c.get(), 1, 6, integer_packer(0, 16383))); break; @@ -1089,22 +1131,22 @@ SRSASN_CODE redirected_carrier_info_r15_ies_c::unpack(cbit_ref& bref) e.unpack(bref); set(e); switch (type_) { - case types::eutra_r15: + case types::eutra: HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)0u, (uint32_t)262143u)); break; - case types::geran_r15: + case types::geran: HANDLE_CODE(c.get().unpack(bref)); break; - case types::utra_fdd_r15: + case types::utra_fdd: HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)16383u)); break; - case types::cdma2000_hrpd_r15: + case types::cdma2000_hrpd: HANDLE_CODE(c.get().unpack(bref)); break; - case types::cdma2000_minus1x_rtt_r15: + case types::cdma2000_minus1x_rtt: HANDLE_CODE(c.get().unpack(bref)); break; - case types::utra_tdd_r15: + case types::utra_tdd: HANDLE_CODE( unpack_dyn_seq_of(c.get(), bref, 1, 6, integer_packer(0, 16383))); break; diff --git a/lib/src/asn1/rrc/dl_dcch_msg.cc b/lib/src/asn1/rrc/dl_dcch_msg.cc index 136e88df14..c616201d49 100644 --- a/lib/src/asn1/rrc/dl_dcch_msg.cc +++ b/lib/src/asn1/rrc/dl_dcch_msg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,6 +29,88 @@ using namespace asn1::rrc; * Struct Methods ******************************************************************************/ +// CondReconfigurationAddMod-r16 ::= SEQUENCE +SRSASN_CODE cond_recfg_add_mod_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(trigger_condition_r16_present, 1)); + HANDLE_CODE(bref.pack(cond_recfg_to_apply_r16_present, 1)); + + HANDLE_CODE(pack_integer(bref, cond_recfg_id_r16, (uint8_t)1u, (uint8_t)8u)); + if (trigger_condition_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, trigger_condition_r16, 1, 2, integer_packer(1, 32))); + } + if (cond_recfg_to_apply_r16_present) { + HANDLE_CODE(cond_recfg_to_apply_r16.pack(bref)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= trigger_condition_sn_r17_present; + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(trigger_condition_sn_r17_present, 1)); + if (trigger_condition_sn_r17_present) { + HANDLE_CODE(trigger_condition_sn_r17.pack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE cond_recfg_add_mod_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(trigger_condition_r16_present, 1)); + HANDLE_CODE(bref.unpack(cond_recfg_to_apply_r16_present, 1)); + + HANDLE_CODE(unpack_integer(cond_recfg_id_r16, bref, (uint8_t)1u, (uint8_t)8u)); + if (trigger_condition_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(trigger_condition_r16, bref, 1, 2, integer_packer(1, 32))); + } + if (cond_recfg_to_apply_r16_present) { + HANDLE_CODE(cond_recfg_to_apply_r16.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(trigger_condition_sn_r17_present, 1)); + if (trigger_condition_sn_r17_present) { + HANDLE_CODE(trigger_condition_sn_r17.unpack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +void cond_recfg_add_mod_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("condReconfigurationId-r16", cond_recfg_id_r16); + if (trigger_condition_r16_present) { + j.start_array("triggerCondition-r16"); + for (const auto& e1 : trigger_condition_r16) { + j.write_int(e1); + } + j.end_array(); + } + if (cond_recfg_to_apply_r16_present) { + j.write_str("condReconfigurationToApply-r16", cond_recfg_to_apply_r16.to_string()); + } + if (ext) { + if (trigger_condition_sn_r17_present) { + j.write_str("triggerConditionSN-r17", trigger_condition_sn_r17.to_string()); + } + } + j.end_obj(); +} + // SCellConfigCommon-r15 ::= SEQUENCE SRSASN_CODE scell_cfg_common_r15_s::pack(bit_ref& bref) const { @@ -149,6 +231,143 @@ void sl_tf_idx_pair_r12b_s::to_json(json_writer& j) const j.end_obj(); } +// SubframeAssignment-r15 ::= ENUMERATED +const char* sf_assign_r15_opts::to_string() const +{ + static const char* options[] = {"sa0", "sa1", "sa2", "sa3", "sa4", "sa5", "sa6"}; + return convert_enum_idx(options, 7, value, "sf_assign_r15_e"); +} +uint8_t sf_assign_r15_opts::to_number() const +{ + static const uint8_t options[] = {0, 1, 2, 3, 4, 5, 6}; + return map_enum_number(options, 7, value, "sf_assign_r15_e"); +} + +// ConditionalReconfiguration-r16 ::= SEQUENCE +SRSASN_CODE conditional_recfg_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(cond_recfg_to_add_mod_list_r16_present, 1)); + HANDLE_CODE(bref.pack(cond_recfg_to_rem_list_r16_present, 1)); + HANDLE_CODE(bref.pack(attempt_cond_reconf_r16_present, 1)); + + if (cond_recfg_to_add_mod_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, cond_recfg_to_add_mod_list_r16, 1, 8)); + } + if (cond_recfg_to_rem_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, cond_recfg_to_rem_list_r16, 1, 8, integer_packer(1, 8))); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE conditional_recfg_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(cond_recfg_to_add_mod_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(cond_recfg_to_rem_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(attempt_cond_reconf_r16_present, 1)); + + if (cond_recfg_to_add_mod_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(cond_recfg_to_add_mod_list_r16, bref, 1, 8)); + } + if (cond_recfg_to_rem_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(cond_recfg_to_rem_list_r16, bref, 1, 8, integer_packer(1, 8))); + } + + return SRSASN_SUCCESS; +} +void conditional_recfg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (cond_recfg_to_add_mod_list_r16_present) { + j.start_array("condReconfigurationToAddModList-r16"); + for (const auto& e1 : cond_recfg_to_add_mod_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (cond_recfg_to_rem_list_r16_present) { + j.start_array("condReconfigurationToRemoveList-r16"); + for (const auto& e1 : cond_recfg_to_rem_list_r16) { + j.write_int(e1); + } + j.end_array(); + } + if (attempt_cond_reconf_r16_present) { + j.write_str("attemptCondReconf-r16", "true"); + } + j.end_obj(); +} + +// RRCConnectionReconfiguration-v1700-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_recfg_v1700_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(sib_type31_ded_r17_present, 1)); + HANDLE_CODE(bref.pack(scg_state_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (sib_type31_ded_r17_present) { + HANDLE_CODE(sib_type31_ded_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_recfg_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(sib_type31_ded_r17_present, 1)); + HANDLE_CODE(bref.unpack(scg_state_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (sib_type31_ded_r17_present) { + HANDLE_CODE(sib_type31_ded_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_recfg_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (sib_type31_ded_r17_present) { + j.write_str("systemInformationBlockType31Dedicated-r17", sib_type31_ded_r17.to_string()); + } + if (scg_state_r17_present) { + j.write_str("scg-State-r17", "deactivated"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// RSRP-ChangeThresh-r16 ::= ENUMERATED +const char* rsrp_change_thresh_r16_opts::to_string() const +{ + static const char* options[] = {"dB4", + "dB6", + "dB8", + "dB10", + "dB14", + "dB18", + "dB22", + "dB26", + "dB30", + "dB34", + "spare6", + "spare5", + "spare4", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 16, value, "rsrp_change_thresh_r16_e"); +} +uint8_t rsrp_change_thresh_r16_opts::to_number() const +{ + static const uint8_t options[] = {4, 6, 8, 10, 14, 18, 22, 26, 30, 34}; + return map_enum_number(options, 10, value, "rsrp_change_thresh_r16_e"); +} + // SCellGroupToAddMod-r15 ::= SEQUENCE SRSASN_CODE scell_group_to_add_mod_r15_s::pack(bit_ref& bref) const { @@ -250,6 +469,73 @@ uint8_t sl_hop_cfg_disc_r12_s::c_r12_opts::to_number() const return map_enum_number(options, 2, value, "sl_hop_cfg_disc_r12_s::c_r12_e_"); } +// TDM-PatternConfig-r15 ::= CHOICE +void tdm_pattern_cfg_r15_c::set(types::options e) +{ + type_ = e; +} +void tdm_pattern_cfg_r15_c::set_release() +{ + set(types::release); +} +tdm_pattern_cfg_r15_c::setup_s_& tdm_pattern_cfg_r15_c::set_setup() +{ + set(types::setup); + return c; +} +void tdm_pattern_cfg_r15_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::release: + break; + case types::setup: + j.write_fieldname("setup"); + j.start_obj(); + j.write_str("subframeAssignment-r15", c.sf_assign_r15.to_string()); + j.write_int("harq-Offset-r15", c.harq_offset_r15); + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "tdm_pattern_cfg_r15_c"); + } + j.end_obj(); +} +SRSASN_CODE tdm_pattern_cfg_r15_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(c.sf_assign_r15.pack(bref)); + HANDLE_CODE(pack_integer(bref, c.harq_offset_r15, (uint8_t)0u, (uint8_t)9u)); + break; + default: + log_invalid_choice_id(type_, "tdm_pattern_cfg_r15_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE tdm_pattern_cfg_r15_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(c.sf_assign_r15.unpack(bref)); + HANDLE_CODE(unpack_integer(c.harq_offset_r15, bref, (uint8_t)0u, (uint8_t)9u)); + break; + default: + log_invalid_choice_id(type_, "tdm_pattern_cfg_r15_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + // IKE-Identity-r13 ::= SEQUENCE SRSASN_CODE ike_id_r13_s::pack(bit_ref& bref) const { @@ -398,89 +684,693 @@ SRSASN_CODE ip_address_r13_c::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -// PhysicalConfigDedicated-v1370 ::= SEQUENCE -SRSASN_CODE phys_cfg_ded_v1370_s::pack(bit_ref& bref) const +// PUR-MPDCCH-Config-r16 ::= SEQUENCE +SRSASN_CODE pur_mpdcch_cfg_r16_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(pucch_cfg_ded_v1370_present, 1)); - - if (pucch_cfg_ded_v1370_present) { - HANDLE_CODE(pucch_cfg_ded_v1370.pack(bref)); - } + HANDLE_CODE(bref.pack(mpdcch_freq_hop_r16, 1)); + HANDLE_CODE(pack_integer(bref, mpdcch_nb_r16, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(mpdcch_prb_pairs_cfg_r16.num_prb_pairs_r16.pack(bref)); + HANDLE_CODE(mpdcch_prb_pairs_cfg_r16.res_block_assign_r16.pack(bref)); + HANDLE_CODE(mpdcch_num_repeat_r16.pack(bref)); + HANDLE_CODE(mpdcch_start_sf_uess_r16.pack(bref)); + HANDLE_CODE(mpdcch_offset_pur_ss_r16.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE phys_cfg_ded_v1370_s::unpack(cbit_ref& bref) +SRSASN_CODE pur_mpdcch_cfg_r16_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(pucch_cfg_ded_v1370_present, 1)); - - if (pucch_cfg_ded_v1370_present) { - HANDLE_CODE(pucch_cfg_ded_v1370.unpack(bref)); - } + HANDLE_CODE(bref.unpack(mpdcch_freq_hop_r16, 1)); + HANDLE_CODE(unpack_integer(mpdcch_nb_r16, bref, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(mpdcch_prb_pairs_cfg_r16.num_prb_pairs_r16.unpack(bref)); + HANDLE_CODE(mpdcch_prb_pairs_cfg_r16.res_block_assign_r16.unpack(bref)); + HANDLE_CODE(mpdcch_num_repeat_r16.unpack(bref)); + HANDLE_CODE(mpdcch_start_sf_uess_r16.unpack(bref)); + HANDLE_CODE(mpdcch_offset_pur_ss_r16.unpack(bref)); return SRSASN_SUCCESS; } -void phys_cfg_ded_v1370_s::to_json(json_writer& j) const +void pur_mpdcch_cfg_r16_s::to_json(json_writer& j) const { j.start_obj(); - if (pucch_cfg_ded_v1370_present) { - j.write_fieldname("pucch-ConfigDedicated-v1370"); - pucch_cfg_ded_v1370.to_json(j); - } + j.write_bool("mpdcch-FreqHopping-r16", mpdcch_freq_hop_r16); + j.write_int("mpdcch-Narrowband-r16", mpdcch_nb_r16); + j.write_fieldname("mpdcch-PRB-PairsConfig-r16"); + j.start_obj(); + j.write_str("numberPRB-Pairs-r16", mpdcch_prb_pairs_cfg_r16.num_prb_pairs_r16.to_string()); + j.write_str("resourceBlockAssignment-r16", mpdcch_prb_pairs_cfg_r16.res_block_assign_r16.to_string()); + j.end_obj(); + j.write_str("mpdcch-NumRepetition-r16", mpdcch_num_repeat_r16.to_string()); + j.write_fieldname("mpdcch-StartSF-UESS-r16"); + mpdcch_start_sf_uess_r16.to_json(j); + j.write_str("mpdcch-Offset-PUR-SS-r16", mpdcch_offset_pur_ss_r16.to_string()); j.end_obj(); } -// RAN-AreaConfig-r15 ::= SEQUENCE -SRSASN_CODE ran_area_cfg_r15_s::pack(bit_ref& bref) const +const char* pur_mpdcch_cfg_r16_s::mpdcch_prb_pairs_cfg_r16_s_::num_prb_pairs_r16_opts::to_string() const { - HANDLE_CODE(bref.pack(ran_area_code_list_r15_present, 1)); - - HANDLE_CODE(tac_minus5_gc_r15.pack(bref)); - if (ran_area_code_list_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, ran_area_code_list_r15, 1, 32, integer_packer(0, 255))); - } - - return SRSASN_SUCCESS; + static const char* options[] = {"n2", "n4", "n6", "spare1"}; + return convert_enum_idx(options, 4, value, "pur_mpdcch_cfg_r16_s::mpdcch_prb_pairs_cfg_r16_s_::num_prb_pairs_r16_e_"); } -SRSASN_CODE ran_area_cfg_r15_s::unpack(cbit_ref& bref) +uint8_t pur_mpdcch_cfg_r16_s::mpdcch_prb_pairs_cfg_r16_s_::num_prb_pairs_r16_opts::to_number() const { - HANDLE_CODE(bref.unpack(ran_area_code_list_r15_present, 1)); - - HANDLE_CODE(tac_minus5_gc_r15.unpack(bref)); - if (ran_area_code_list_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(ran_area_code_list_r15, bref, 1, 32, integer_packer(0, 255))); - } + static const uint8_t options[] = {2, 4, 6}; + return map_enum_number(options, 3, value, "pur_mpdcch_cfg_r16_s::mpdcch_prb_pairs_cfg_r16_s_::num_prb_pairs_r16_e_"); +} - return SRSASN_SUCCESS; +const char* pur_mpdcch_cfg_r16_s::mpdcch_num_repeat_r16_opts::to_string() const +{ + static const char* options[] = {"r1", "r2", "r4", "r8", "r16", "r32", "r64", "r128", "r256"}; + return convert_enum_idx(options, 9, value, "pur_mpdcch_cfg_r16_s::mpdcch_num_repeat_r16_e_"); } -void ran_area_cfg_r15_s::to_json(json_writer& j) const +uint16_t pur_mpdcch_cfg_r16_s::mpdcch_num_repeat_r16_opts::to_number() const { - j.start_obj(); - j.write_str("trackingAreaCode-5GC-r15", tac_minus5_gc_r15.to_string()); - if (ran_area_code_list_r15_present) { - j.start_array("ran-AreaCodeList-r15"); - for (const auto& e1 : ran_area_code_list_r15) { - j.write_int(e1); - } - j.end_array(); - } - j.end_obj(); + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256}; + return map_enum_number(options, 9, value, "pur_mpdcch_cfg_r16_s::mpdcch_num_repeat_r16_e_"); } -// RadioResourceConfigCommonSCell-v1440 ::= SEQUENCE -SRSASN_CODE rr_cfg_common_scell_v1440_s::pack(bit_ref& bref) const +void pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::destroy_() {} +void pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::set(types::options e) { - HANDLE_CODE( - pack_integer(bref, ul_cfg_v1440.ul_freq_info_v1440.add_spec_emission_scell_v1440, (uint16_t)33u, (uint16_t)288u)); - - return SRSASN_SUCCESS; + destroy_(); + type_ = e; } -SRSASN_CODE rr_cfg_common_scell_v1440_s::unpack(cbit_ref& bref) +pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::mpdcch_start_sf_uess_r16_c_( + const pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_& other) { - HANDLE_CODE(unpack_integer( - ul_cfg_v1440.ul_freq_info_v1440.add_spec_emission_scell_v1440, bref, (uint16_t)33u, (uint16_t)288u)); - - return SRSASN_SUCCESS; -} + type_ = other.type(); + switch (type_) { + case types::fdd: + c.init(other.c.get()); + break; + case types::tdd: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_"); + } +} +pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_& pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::operator=( + const pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::fdd: + c.set(other.c.get()); + break; + case types::tdd: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_"); + } + + return *this; +} +pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::fdd_e_& pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::set_fdd() +{ + set(types::fdd); + return c.get(); +} +pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::tdd_e_& pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::set_tdd() +{ + set(types::tdd); + return c.get(); +} +void pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::fdd: + j.write_str("fdd", c.get().to_string()); + break; + case types::tdd: + j.write_str("tdd", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_"); + } + j.end_obj(); +} +SRSASN_CODE pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::fdd: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::tdd: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::fdd: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::tdd: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::fdd_opts::to_string() const +{ + static const char* options[] = {"v1", "v1dot5", "v2", "v2dot5", "v4", "v5", "v8", "v10"}; + return convert_enum_idx(options, 8, value, "pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::fdd_e_"); +} +float pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::fdd_opts::to_number() const +{ + static const float options[] = {1.0, 1.5, 2.0, 2.5, 4.0, 5.0, 8.0, 10.0}; + return map_enum_number(options, 8, value, "pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::fdd_e_"); +} +const char* pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::fdd_opts::to_number_string() const +{ + static const char* options[] = {"1", "1.5", "2", "2.5", "4", "5", "8", "10"}; + return convert_enum_idx(options, 8, value, "pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::fdd_e_"); +} + +const char* pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::tdd_opts::to_string() const +{ + static const char* options[] = {"v1", "v2", "v4", "v5", "v8", "v10", "v20", "spare1"}; + return convert_enum_idx(options, 8, value, "pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::tdd_e_"); +} +uint8_t pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::tdd_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 4, 5, 8, 10, 20}; + return map_enum_number(options, 7, value, "pur_mpdcch_cfg_r16_s::mpdcch_start_sf_uess_r16_c_::tdd_e_"); +} + +const char* pur_mpdcch_cfg_r16_s::mpdcch_offset_pur_ss_r16_opts::to_string() const +{ + static const char* options[] = { + "zero", "oneEighth", "oneQuarter", "threeEighth", "oneHalf", "fiveEighth", "threeQuarter", "sevenEighth"}; + return convert_enum_idx(options, 8, value, "pur_mpdcch_cfg_r16_s::mpdcch_offset_pur_ss_r16_e_"); +} +float pur_mpdcch_cfg_r16_s::mpdcch_offset_pur_ss_r16_opts::to_number() const +{ + static const float options[] = {0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875}; + return map_enum_number(options, 8, value, "pur_mpdcch_cfg_r16_s::mpdcch_offset_pur_ss_r16_e_"); +} +const char* pur_mpdcch_cfg_r16_s::mpdcch_offset_pur_ss_r16_opts::to_number_string() const +{ + static const char* options[] = {"0", "1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "7/8"}; + return convert_enum_idx(options, 8, value, "pur_mpdcch_cfg_r16_s::mpdcch_offset_pur_ss_r16_e_"); +} + +// PUR-PUCCH-Config-r16 ::= SEQUENCE +SRSASN_CODE pur_pucch_cfg_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(n1_pucch_an_r16_present, 1)); + HANDLE_CODE(bref.pack(pucch_num_repeat_ce_format1_r16_present, 1)); + + if (n1_pucch_an_r16_present) { + HANDLE_CODE(pack_integer(bref, n1_pucch_an_r16, (uint16_t)0u, (uint16_t)2047u)); + } + if (pucch_num_repeat_ce_format1_r16_present) { + HANDLE_CODE(pucch_num_repeat_ce_format1_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pur_pucch_cfg_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(n1_pucch_an_r16_present, 1)); + HANDLE_CODE(bref.unpack(pucch_num_repeat_ce_format1_r16_present, 1)); + + if (n1_pucch_an_r16_present) { + HANDLE_CODE(unpack_integer(n1_pucch_an_r16, bref, (uint16_t)0u, (uint16_t)2047u)); + } + if (pucch_num_repeat_ce_format1_r16_present) { + HANDLE_CODE(pucch_num_repeat_ce_format1_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void pur_pucch_cfg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (n1_pucch_an_r16_present) { + j.write_int("n1PUCCH-AN-r16", n1_pucch_an_r16); + } + if (pucch_num_repeat_ce_format1_r16_present) { + j.write_str("pucch-NumRepetitionCE-Format1-r16", pucch_num_repeat_ce_format1_r16.to_string()); + } + j.end_obj(); +} + +const char* pur_pucch_cfg_r16_s::pucch_num_repeat_ce_format1_r16_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n4", "n8"}; + return convert_enum_idx(options, 4, value, "pur_pucch_cfg_r16_s::pucch_num_repeat_ce_format1_r16_e_"); +} +uint8_t pur_pucch_cfg_r16_s::pucch_num_repeat_ce_format1_r16_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 4, 8}; + return map_enum_number(options, 4, value, "pur_pucch_cfg_r16_s::pucch_num_repeat_ce_format1_r16_e_"); +} + +// PUR-PUSCH-Config-r16 ::= SEQUENCE +SRSASN_CODE pur_pusch_cfg_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pur_grant_info_r16_present, 1)); + HANDLE_CODE(bref.pack(location_ce_mode_b_r16_present, 1)); + + if (pur_grant_info_r16_present) { + HANDLE_CODE(pur_grant_info_r16.pack(bref)); + } + HANDLE_CODE(bref.pack(pur_pusch_freq_hop_r16, 1)); + HANDLE_CODE(pack_integer(bref, p0_ue_pusch_r16, (int8_t)-8, (int8_t)7)); + HANDLE_CODE(alpha_r16.pack(bref)); + HANDLE_CODE(pusch_cyclic_shift_r16.pack(bref)); + HANDLE_CODE(bref.pack(pusch_nb_max_tbs_r16, 1)); + if (location_ce_mode_b_r16_present) { + HANDLE_CODE(pack_integer(bref, location_ce_mode_b_r16, (uint8_t)0u, (uint8_t)5u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pur_pusch_cfg_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(pur_grant_info_r16_present, 1)); + HANDLE_CODE(bref.unpack(location_ce_mode_b_r16_present, 1)); + + if (pur_grant_info_r16_present) { + HANDLE_CODE(pur_grant_info_r16.unpack(bref)); + } + HANDLE_CODE(bref.unpack(pur_pusch_freq_hop_r16, 1)); + HANDLE_CODE(unpack_integer(p0_ue_pusch_r16, bref, (int8_t)-8, (int8_t)7)); + HANDLE_CODE(alpha_r16.unpack(bref)); + HANDLE_CODE(pusch_cyclic_shift_r16.unpack(bref)); + HANDLE_CODE(bref.unpack(pusch_nb_max_tbs_r16, 1)); + if (location_ce_mode_b_r16_present) { + HANDLE_CODE(unpack_integer(location_ce_mode_b_r16, bref, (uint8_t)0u, (uint8_t)5u)); + } + + return SRSASN_SUCCESS; +} +void pur_pusch_cfg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (pur_grant_info_r16_present) { + j.write_fieldname("pur-GrantInfo-r16"); + pur_grant_info_r16.to_json(j); + } + j.write_bool("pur-PUSCH-FreqHopping-r16", pur_pusch_freq_hop_r16); + j.write_int("p0-UE-PUSCH-r16", p0_ue_pusch_r16); + j.write_str("alpha-r16", alpha_r16.to_string()); + j.write_str("pusch-CyclicShift-r16", pusch_cyclic_shift_r16.to_string()); + j.write_bool("pusch-NB-MaxTBS-r16", pusch_nb_max_tbs_r16); + if (location_ce_mode_b_r16_present) { + j.write_int("locationCE-ModeB-r16", location_ce_mode_b_r16); + } + j.end_obj(); +} + +void pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::destroy_() +{ + switch (type_) { + case types::ce_mode_a: + c.destroy(); + break; + case types::ce_mode_b: + c.destroy(); + break; + default: + break; + } +} +void pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ce_mode_a: + c.init(); + break; + case types::ce_mode_b: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pur_pusch_cfg_r16_s::pur_grant_info_r16_c_"); + } +} +pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::pur_grant_info_r16_c_( + const pur_pusch_cfg_r16_s::pur_grant_info_r16_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::ce_mode_a: + c.init(other.c.get()); + break; + case types::ce_mode_b: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pur_pusch_cfg_r16_s::pur_grant_info_r16_c_"); + } +} +pur_pusch_cfg_r16_s::pur_grant_info_r16_c_& +pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::operator=(const pur_pusch_cfg_r16_s::pur_grant_info_r16_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ce_mode_a: + c.set(other.c.get()); + break; + case types::ce_mode_b: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pur_pusch_cfg_r16_s::pur_grant_info_r16_c_"); + } + + return *this; +} +pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::ce_mode_a_s_& pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::set_ce_mode_a() +{ + set(types::ce_mode_a); + return c.get(); +} +pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::ce_mode_b_s_& pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::set_ce_mode_b() +{ + set(types::ce_mode_b); + return c.get(); +} +void pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ce_mode_a: + j.write_fieldname("ce-ModeA"); + j.start_obj(); + j.write_str("numRUs-r16", c.get().num_rus_r16.to_string()); + j.write_str("prb-AllocationInfo-r16", c.get().prb_alloc_info_r16.to_string()); + j.write_str("mcs-r16", c.get().mcs_r16.to_string()); + j.write_str("numRepetitions-r16", c.get().num_repeats_r16.to_string()); + j.end_obj(); + break; + case types::ce_mode_b: + j.write_fieldname("ce-ModeB"); + j.start_obj(); + j.write_bool("subPRB-Allocation-r16", c.get().sub_prb_alloc_r16); + j.write_bool("numRUs-r16", c.get().num_rus_r16); + j.write_str("prb-AllocationInfo-r16", c.get().prb_alloc_info_r16.to_string()); + j.write_str("mcs-r16", c.get().mcs_r16.to_string()); + j.write_str("numRepetitions-r16", c.get().num_repeats_r16.to_string()); + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "pur_pusch_cfg_r16_s::pur_grant_info_r16_c_"); + } + j.end_obj(); +} +SRSASN_CODE pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ce_mode_a: + HANDLE_CODE(c.get().num_rus_r16.pack(bref)); + HANDLE_CODE(c.get().prb_alloc_info_r16.pack(bref)); + HANDLE_CODE(c.get().mcs_r16.pack(bref)); + HANDLE_CODE(c.get().num_repeats_r16.pack(bref)); + break; + case types::ce_mode_b: + HANDLE_CODE(bref.pack(c.get().sub_prb_alloc_r16, 1)); + HANDLE_CODE(bref.pack(c.get().num_rus_r16, 1)); + HANDLE_CODE(c.get().prb_alloc_info_r16.pack(bref)); + HANDLE_CODE(c.get().mcs_r16.pack(bref)); + HANDLE_CODE(c.get().num_repeats_r16.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "pur_pusch_cfg_r16_s::pur_grant_info_r16_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE pur_pusch_cfg_r16_s::pur_grant_info_r16_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ce_mode_a: + HANDLE_CODE(c.get().num_rus_r16.unpack(bref)); + HANDLE_CODE(c.get().prb_alloc_info_r16.unpack(bref)); + HANDLE_CODE(c.get().mcs_r16.unpack(bref)); + HANDLE_CODE(c.get().num_repeats_r16.unpack(bref)); + break; + case types::ce_mode_b: + HANDLE_CODE(bref.unpack(c.get().sub_prb_alloc_r16, 1)); + HANDLE_CODE(bref.unpack(c.get().num_rus_r16, 1)); + HANDLE_CODE(c.get().prb_alloc_info_r16.unpack(bref)); + HANDLE_CODE(c.get().mcs_r16.unpack(bref)); + HANDLE_CODE(c.get().num_repeats_r16.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "pur_pusch_cfg_r16_s::pur_grant_info_r16_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* pur_pusch_cfg_r16_s::pusch_cyclic_shift_r16_opts::to_string() const +{ + static const char* options[] = {"n0", "n6"}; + return convert_enum_idx(options, 2, value, "pur_pusch_cfg_r16_s::pusch_cyclic_shift_r16_e_"); +} +uint8_t pur_pusch_cfg_r16_s::pusch_cyclic_shift_r16_opts::to_number() const +{ + static const uint8_t options[] = {0, 6}; + return map_enum_number(options, 2, value, "pur_pusch_cfg_r16_s::pusch_cyclic_shift_r16_e_"); +} + +// PUR-RSRP-ChangeThreshold-r16 ::= SEQUENCE +SRSASN_CODE pur_rsrp_change_thres_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(decrease_thresh_r16_present, 1)); + + HANDLE_CODE(increase_thresh_r16.pack(bref)); + if (decrease_thresh_r16_present) { + HANDLE_CODE(decrease_thresh_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pur_rsrp_change_thres_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(decrease_thresh_r16_present, 1)); + + HANDLE_CODE(increase_thresh_r16.unpack(bref)); + if (decrease_thresh_r16_present) { + HANDLE_CODE(decrease_thresh_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void pur_rsrp_change_thres_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("increaseThresh-r16", increase_thresh_r16.to_string()); + if (decrease_thresh_r16_present) { + j.write_str("decreaseThresh-r16", decrease_thresh_r16.to_string()); + } + j.end_obj(); +} + +// PhysicalConfigDedicated-v1370 ::= SEQUENCE +SRSASN_CODE phys_cfg_ded_v1370_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pucch_cfg_ded_v1370_present, 1)); + + if (pucch_cfg_ded_v1370_present) { + HANDLE_CODE(pucch_cfg_ded_v1370.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE phys_cfg_ded_v1370_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(pucch_cfg_ded_v1370_present, 1)); + + if (pucch_cfg_ded_v1370_present) { + HANDLE_CODE(pucch_cfg_ded_v1370.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void phys_cfg_ded_v1370_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (pucch_cfg_ded_v1370_present) { + j.write_fieldname("pucch-ConfigDedicated-v1370"); + pucch_cfg_ded_v1370.to_json(j); + } + j.end_obj(); +} + +// RAN-AreaConfig-r15 ::= SEQUENCE +SRSASN_CODE ran_area_cfg_r15_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ran_area_code_list_r15_present, 1)); + + HANDLE_CODE(tac_minus5_gc_r15.pack(bref)); + if (ran_area_code_list_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, ran_area_code_list_r15, 1, 32, integer_packer(0, 255))); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ran_area_cfg_r15_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ran_area_code_list_r15_present, 1)); + + HANDLE_CODE(tac_minus5_gc_r15.unpack(bref)); + if (ran_area_code_list_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(ran_area_code_list_r15, bref, 1, 32, integer_packer(0, 255))); + } + + return SRSASN_SUCCESS; +} +void ran_area_cfg_r15_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("trackingAreaCode-5GC-r15", tac_minus5_gc_r15.to_string()); + if (ran_area_code_list_r15_present) { + j.start_array("ran-AreaCodeList-r15"); + for (const auto& e1 : ran_area_code_list_r15) { + j.write_int(e1); + } + j.end_array(); + } + j.end_obj(); +} + +// RRCConnectionReconfiguration-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_recfg_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(conditional_recfg_r16_present, 1)); + HANDLE_CODE(bref.pack(daps_source_release_r16_present, 1)); + HANDLE_CODE(bref.pack(tdm_pattern_cfg2_r16_present, 1)); + HANDLE_CODE(bref.pack(sl_cfg_ded_for_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(sl_ssb_prio_eutra_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (conditional_recfg_r16_present) { + HANDLE_CODE(conditional_recfg_r16.pack(bref)); + } + if (tdm_pattern_cfg2_r16_present) { + HANDLE_CODE(tdm_pattern_cfg2_r16.pack(bref)); + } + if (sl_cfg_ded_for_nr_r16_present) { + HANDLE_CODE(sl_cfg_ded_for_nr_r16.pack(bref)); + } + if (sl_ssb_prio_eutra_r16_present) { + HANDLE_CODE(pack_integer(bref, sl_ssb_prio_eutra_r16, (uint8_t)1u, (uint8_t)8u)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_recfg_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(conditional_recfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(daps_source_release_r16_present, 1)); + HANDLE_CODE(bref.unpack(tdm_pattern_cfg2_r16_present, 1)); + HANDLE_CODE(bref.unpack(sl_cfg_ded_for_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(sl_ssb_prio_eutra_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (conditional_recfg_r16_present) { + HANDLE_CODE(conditional_recfg_r16.unpack(bref)); + } + if (tdm_pattern_cfg2_r16_present) { + HANDLE_CODE(tdm_pattern_cfg2_r16.unpack(bref)); + } + if (sl_cfg_ded_for_nr_r16_present) { + HANDLE_CODE(sl_cfg_ded_for_nr_r16.unpack(bref)); + } + if (sl_ssb_prio_eutra_r16_present) { + HANDLE_CODE(unpack_integer(sl_ssb_prio_eutra_r16, bref, (uint8_t)1u, (uint8_t)8u)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_recfg_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (conditional_recfg_r16_present) { + j.write_fieldname("conditionalReconfiguration-r16"); + conditional_recfg_r16.to_json(j); + } + if (daps_source_release_r16_present) { + j.write_str("daps-SourceRelease-r16", "true"); + } + if (tdm_pattern_cfg2_r16_present) { + j.write_fieldname("tdm-PatternConfig2-r16"); + tdm_pattern_cfg2_r16.to_json(j); + } + if (sl_cfg_ded_for_nr_r16_present) { + j.write_str("sl-ConfigDedicatedForNR-r16", sl_cfg_ded_for_nr_r16.to_string()); + } + if (sl_ssb_prio_eutra_r16_present) { + j.write_int("sl-SSB-PriorityEUTRA-r16", sl_ssb_prio_eutra_r16); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// RadioResourceConfigCommonSCell-v1440 ::= SEQUENCE +SRSASN_CODE rr_cfg_common_scell_v1440_s::pack(bit_ref& bref) const +{ + HANDLE_CODE( + pack_integer(bref, ul_cfg_v1440.ul_freq_info_v1440.add_spec_emission_scell_v1440, (uint16_t)33u, (uint16_t)288u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rr_cfg_common_scell_v1440_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer( + ul_cfg_v1440.ul_freq_info_v1440.add_spec_emission_scell_v1440, bref, (uint16_t)33u, (uint16_t)288u)); + + return SRSASN_SUCCESS; +} void rr_cfg_common_scell_v1440_s::to_json(json_writer& j) const { j.start_obj(); @@ -618,25 +1508,13 @@ SRSASN_CODE sl_tx_pool_to_add_mod_r14_s::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -void sl_tx_pool_to_add_mod_r14_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("poolIdentity-r14", pool_id_r14); - j.write_fieldname("pool-r14"); - pool_r14.to_json(j); - j.end_obj(); -} - -// SubframeAssignment-r15 ::= ENUMERATED -const char* sf_assign_r15_opts::to_string() const -{ - static const char* options[] = {"sa0", "sa1", "sa2", "sa3", "sa4", "sa5", "sa6"}; - return convert_enum_idx(options, 7, value, "sf_assign_r15_e"); -} -uint8_t sf_assign_r15_opts::to_number() const +void sl_tx_pool_to_add_mod_r14_s::to_json(json_writer& j) const { - static const uint8_t options[] = {0, 1, 2, 3, 4, 5, 6}; - return map_enum_number(options, 7, value, "sf_assign_r15_e"); + j.start_obj(); + j.write_int("poolIdentity-r14", pool_id_r14); + j.write_fieldname("pool-r14"); + pool_r14.to_json(j); + j.end_obj(); } // UplinkPowerControlCommonPSCell-r12 ::= SEQUENCE @@ -842,6 +1720,256 @@ void plmn_ran_area_cfg_r15_s::to_json(json_writer& j) const j.end_obj(); } +// PUR-Config-r16 ::= SEQUENCE +SRSASN_CODE pur_cfg_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(pur_cfg_id_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_implicit_release_after_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_start_time_params_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_rnti_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_time_align_timer_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_rsrp_change_thres_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_resp_win_timer_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_mpdcch_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_pucch_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_pusch_cfg_r16_present, 1)); + + if (pur_cfg_id_r16_present) { + HANDLE_CODE(pur_cfg_id_r16.pack(bref)); + } + if (pur_implicit_release_after_r16_present) { + HANDLE_CODE(pur_implicit_release_after_r16.pack(bref)); + } + if (pur_start_time_params_r16_present) { + HANDLE_CODE(pur_start_time_params_r16.periodicity_and_offset_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, pur_start_time_params_r16.start_sfn_r16, (uint16_t)0u, (uint16_t)1023u)); + HANDLE_CODE(pack_integer(bref, pur_start_time_params_r16.start_sub_frame_r16, (uint8_t)0u, (uint8_t)9u)); + HANDLE_CODE(pur_start_time_params_r16.hsfn_lsb_info_r16.pack(bref)); + } + HANDLE_CODE(pur_num_occasions_r16.pack(bref)); + if (pur_rnti_r16_present) { + HANDLE_CODE(pur_rnti_r16.pack(bref)); + } + if (pur_time_align_timer_r16_present) { + HANDLE_CODE(pack_integer(bref, pur_time_align_timer_r16, (uint8_t)1u, (uint8_t)8u)); + } + if (pur_rsrp_change_thres_r16_present) { + HANDLE_CODE(pur_rsrp_change_thres_r16.pack(bref)); + } + if (pur_resp_win_timer_r16_present) { + HANDLE_CODE(pur_resp_win_timer_r16.pack(bref)); + } + if (pur_mpdcch_cfg_r16_present) { + HANDLE_CODE(pur_mpdcch_cfg_r16.pack(bref)); + } + HANDLE_CODE(bref.pack(pur_pdsch_freq_hop_r16, 1)); + if (pur_pucch_cfg_r16_present) { + HANDLE_CODE(pur_pucch_cfg_r16.pack(bref)); + } + if (pur_pusch_cfg_r16_present) { + HANDLE_CODE(pur_pusch_cfg_r16.pack(bref)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= pur_pdsch_max_tbs_r17_present; + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(pur_pdsch_max_tbs_r17_present, 1)); + if (pur_pdsch_max_tbs_r17_present) { + HANDLE_CODE(bref.pack(pur_pdsch_max_tbs_r17, 1)); + } + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE pur_cfg_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(pur_cfg_id_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_implicit_release_after_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_start_time_params_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_rnti_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_time_align_timer_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_rsrp_change_thres_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_resp_win_timer_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_mpdcch_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_pucch_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_pusch_cfg_r16_present, 1)); + + if (pur_cfg_id_r16_present) { + HANDLE_CODE(pur_cfg_id_r16.unpack(bref)); + } + if (pur_implicit_release_after_r16_present) { + HANDLE_CODE(pur_implicit_release_after_r16.unpack(bref)); + } + if (pur_start_time_params_r16_present) { + HANDLE_CODE(pur_start_time_params_r16.periodicity_and_offset_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(pur_start_time_params_r16.start_sfn_r16, bref, (uint16_t)0u, (uint16_t)1023u)); + HANDLE_CODE(unpack_integer(pur_start_time_params_r16.start_sub_frame_r16, bref, (uint8_t)0u, (uint8_t)9u)); + HANDLE_CODE(pur_start_time_params_r16.hsfn_lsb_info_r16.unpack(bref)); + } + HANDLE_CODE(pur_num_occasions_r16.unpack(bref)); + if (pur_rnti_r16_present) { + HANDLE_CODE(pur_rnti_r16.unpack(bref)); + } + if (pur_time_align_timer_r16_present) { + HANDLE_CODE(unpack_integer(pur_time_align_timer_r16, bref, (uint8_t)1u, (uint8_t)8u)); + } + if (pur_rsrp_change_thres_r16_present) { + HANDLE_CODE(pur_rsrp_change_thres_r16.unpack(bref)); + } + if (pur_resp_win_timer_r16_present) { + HANDLE_CODE(pur_resp_win_timer_r16.unpack(bref)); + } + if (pur_mpdcch_cfg_r16_present) { + HANDLE_CODE(pur_mpdcch_cfg_r16.unpack(bref)); + } + HANDLE_CODE(bref.unpack(pur_pdsch_freq_hop_r16, 1)); + if (pur_pucch_cfg_r16_present) { + HANDLE_CODE(pur_pucch_cfg_r16.unpack(bref)); + } + if (pur_pusch_cfg_r16_present) { + HANDLE_CODE(pur_pusch_cfg_r16.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(pur_pdsch_max_tbs_r17_present, 1)); + if (pur_pdsch_max_tbs_r17_present) { + HANDLE_CODE(bref.unpack(pur_pdsch_max_tbs_r17, 1)); + } + } + } + return SRSASN_SUCCESS; +} +void pur_cfg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (pur_cfg_id_r16_present) { + j.write_str("pur-ConfigID-r16", pur_cfg_id_r16.to_string()); + } + if (pur_implicit_release_after_r16_present) { + j.write_str("pur-ImplicitReleaseAfter-r16", pur_implicit_release_after_r16.to_string()); + } + if (pur_start_time_params_r16_present) { + j.write_fieldname("pur-StartTimeParameters-r16"); + j.start_obj(); + j.write_fieldname("periodicityAndOffset-r16"); + pur_start_time_params_r16.periodicity_and_offset_r16.to_json(j); + j.write_int("startSFN-r16", pur_start_time_params_r16.start_sfn_r16); + j.write_int("startSubFrame-r16", pur_start_time_params_r16.start_sub_frame_r16); + j.write_str("hsfn-LSB-Info-r16", pur_start_time_params_r16.hsfn_lsb_info_r16.to_string()); + j.end_obj(); + } + j.write_str("pur-NumOccasions-r16", pur_num_occasions_r16.to_string()); + if (pur_rnti_r16_present) { + j.write_str("pur-RNTI-r16", pur_rnti_r16.to_string()); + } + if (pur_time_align_timer_r16_present) { + j.write_int("pur-TimeAlignmentTimer-r16", pur_time_align_timer_r16); + } + if (pur_rsrp_change_thres_r16_present) { + j.write_fieldname("pur-RSRP-ChangeThreshold-r16"); + pur_rsrp_change_thres_r16.to_json(j); + } + if (pur_resp_win_timer_r16_present) { + j.write_str("pur-ResponseWindowTimer-r16", pur_resp_win_timer_r16.to_string()); + } + if (pur_mpdcch_cfg_r16_present) { + j.write_fieldname("pur-MPDCCH-Config-r16"); + pur_mpdcch_cfg_r16.to_json(j); + } + j.write_bool("pur-PDSCH-FreqHopping-r16", pur_pdsch_freq_hop_r16); + if (pur_pucch_cfg_r16_present) { + j.write_fieldname("pur-PUCCH-Config-r16"); + pur_pucch_cfg_r16.to_json(j); + } + if (pur_pusch_cfg_r16_present) { + j.write_fieldname("pur-PUSCH-Config-r16"); + pur_pusch_cfg_r16.to_json(j); + } + if (ext) { + if (pur_pdsch_max_tbs_r17_present) { + j.write_bool("pur-PDSCH-maxTBS-r17", pur_pdsch_max_tbs_r17); + } + } + j.end_obj(); +} + +const char* pur_cfg_r16_s::pur_implicit_release_after_r16_opts::to_string() const +{ + static const char* options[] = {"n2", "n4", "n8", "spare"}; + return convert_enum_idx(options, 4, value, "pur_cfg_r16_s::pur_implicit_release_after_r16_e_"); +} +uint8_t pur_cfg_r16_s::pur_implicit_release_after_r16_opts::to_number() const +{ + static const uint8_t options[] = {2, 4, 8}; + return map_enum_number(options, 3, value, "pur_cfg_r16_s::pur_implicit_release_after_r16_e_"); +} + +const char* pur_cfg_r16_s::pur_num_occasions_r16_opts::to_string() const +{ + static const char* options[] = {"one", "infinite"}; + return convert_enum_idx(options, 2, value, "pur_cfg_r16_s::pur_num_occasions_r16_e_"); +} +uint8_t pur_cfg_r16_s::pur_num_occasions_r16_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "pur_cfg_r16_s::pur_num_occasions_r16_e_"); +} + +const char* pur_cfg_r16_s::pur_resp_win_timer_r16_opts::to_string() const +{ + static const char* options[] = {"sf240", "sf480", "sf960", "sf1920", "sf3840", "sf5760", "sf7680", "sf10240"}; + return convert_enum_idx(options, 8, value, "pur_cfg_r16_s::pur_resp_win_timer_r16_e_"); +} +uint16_t pur_cfg_r16_s::pur_resp_win_timer_r16_opts::to_number() const +{ + static const uint16_t options[] = {240, 480, 960, 1920, 3840, 5760, 7680, 10240}; + return map_enum_number(options, 8, value, "pur_cfg_r16_s::pur_resp_win_timer_r16_e_"); +} + +// RRC-InactiveConfig-v1610 ::= SEQUENCE +SRSASN_CODE rrc_inactive_cfg_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(ran_paging_cycle_v1610.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_inactive_cfg_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(ran_paging_cycle_v1610.unpack(bref)); + + return SRSASN_SUCCESS; +} +void rrc_inactive_cfg_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ran-PagingCycle-v1610", ran_paging_cycle_v1610.to_string()); + j.end_obj(); +} + +const char* rrc_inactive_cfg_v1610_s::ran_paging_cycle_v1610_opts::to_string() const +{ + static const char* options[] = {"rf512", "rf1024"}; + return convert_enum_idx(options, 2, value, "rrc_inactive_cfg_v1610_s::ran_paging_cycle_v1610_e_"); +} +uint16_t rrc_inactive_cfg_v1610_s::ran_paging_cycle_v1610_opts::to_number() const +{ + static const uint16_t options[] = {512, 1024}; + return map_enum_number(options, 2, value, "rrc_inactive_cfg_v1610_s::ran_paging_cycle_v1610_e_"); +} + // RRCConnectionReconfiguration-v1530-IEs ::= SEQUENCE SRSASN_CODE rrc_conn_recfg_v1530_ies_s::pack(bit_ref& bref) const { @@ -871,6 +1999,9 @@ SRSASN_CODE rrc_conn_recfg_v1530_ies_s::pack(bit_ref& bref) const if (smtc_r15_present) { HANDLE_CODE(smtc_r15.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -902,6 +2033,9 @@ SRSASN_CODE rrc_conn_recfg_v1530_ies_s::unpack(cbit_ref& bref) if (smtc_r15_present) { HANDLE_CODE(smtc_r15.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -940,6 +2074,34 @@ void rrc_conn_recfg_v1530_ies_s::to_json(json_writer& j) const j.write_fieldname("smtc-r15"); smtc_r15.to_json(j); } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// RRCConnectionRelease-v1650-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_release_v1650_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(mps_prio_ind_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_release_v1650_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(mps_prio_ind_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + return SRSASN_SUCCESS; +} +void rrc_conn_release_v1650_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (mps_prio_ind_r16_present) { + j.write_str("mpsPriorityIndication-r16", "true"); + } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); j.start_obj(); @@ -1554,73 +2716,6 @@ SRSASN_CODE sl_disc_tx_res_r13_c::setup_c_::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -// TDM-PatternConfig-r15 ::= CHOICE -void tdm_pattern_cfg_r15_c::set(types::options e) -{ - type_ = e; -} -void tdm_pattern_cfg_r15_c::set_release() -{ - set(types::release); -} -tdm_pattern_cfg_r15_c::setup_s_& tdm_pattern_cfg_r15_c::set_setup() -{ - set(types::setup); - return c; -} -void tdm_pattern_cfg_r15_c::to_json(json_writer& j) const -{ - j.start_obj(); - switch (type_) { - case types::release: - break; - case types::setup: - j.write_fieldname("setup"); - j.start_obj(); - j.write_str("subframeAssignment-r15", c.sf_assign_r15.to_string()); - j.write_int("harq-Offset-r15", c.harq_offset_r15); - j.end_obj(); - break; - default: - log_invalid_choice_id(type_, "tdm_pattern_cfg_r15_c"); - } - j.end_obj(); -} -SRSASN_CODE tdm_pattern_cfg_r15_c::pack(bit_ref& bref) const -{ - type_.pack(bref); - switch (type_) { - case types::release: - break; - case types::setup: - HANDLE_CODE(c.sf_assign_r15.pack(bref)); - HANDLE_CODE(pack_integer(bref, c.harq_offset_r15, (uint8_t)0u, (uint8_t)9u)); - break; - default: - log_invalid_choice_id(type_, "tdm_pattern_cfg_r15_c"); - return SRSASN_ERROR_ENCODE_FAIL; - } - return SRSASN_SUCCESS; -} -SRSASN_CODE tdm_pattern_cfg_r15_c::unpack(cbit_ref& bref) -{ - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::release: - break; - case types::setup: - HANDLE_CODE(c.sf_assign_r15.unpack(bref)); - HANDLE_CODE(unpack_integer(c.harq_offset_r15, bref, (uint8_t)0u, (uint8_t)9u)); - break; - default: - log_invalid_choice_id(type_, "tdm_pattern_cfg_r15_c"); - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; -} - // TunnelConfigLWIP-r13 ::= SEQUENCE SRSASN_CODE tunnel_cfg_lwip_r13_s::pack(bit_ref& bref) const { @@ -2484,6 +3579,115 @@ SRSASN_CODE rrc_conn_recfg_v1510_ies_s::nr_cfg_r15_c_::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +// RRCConnectionRelease-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_release_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(full_i_rnti_r16_present, 1)); + HANDLE_CODE(bref.pack(short_i_rnti_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(rrc_inactive_cfg_v1610_present, 1)); + HANDLE_CODE(bref.pack(release_idle_meas_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(alt_freq_priorities_r16_present, 1)); + HANDLE_CODE(bref.pack(t323_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (full_i_rnti_r16_present) { + HANDLE_CODE(full_i_rnti_r16.pack(bref)); + } + if (short_i_rnti_r16_present) { + HANDLE_CODE(short_i_rnti_r16.pack(bref)); + } + if (pur_cfg_r16_present) { + HANDLE_CODE(pur_cfg_r16.pack(bref)); + } + if (rrc_inactive_cfg_v1610_present) { + HANDLE_CODE(rrc_inactive_cfg_v1610.pack(bref)); + } + if (t323_r16_present) { + HANDLE_CODE(t323_r16.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_release_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(full_i_rnti_r16_present, 1)); + HANDLE_CODE(bref.unpack(short_i_rnti_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(rrc_inactive_cfg_v1610_present, 1)); + HANDLE_CODE(bref.unpack(release_idle_meas_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(alt_freq_priorities_r16_present, 1)); + HANDLE_CODE(bref.unpack(t323_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (full_i_rnti_r16_present) { + HANDLE_CODE(full_i_rnti_r16.unpack(bref)); + } + if (short_i_rnti_r16_present) { + HANDLE_CODE(short_i_rnti_r16.unpack(bref)); + } + if (pur_cfg_r16_present) { + HANDLE_CODE(pur_cfg_r16.unpack(bref)); + } + if (rrc_inactive_cfg_v1610_present) { + HANDLE_CODE(rrc_inactive_cfg_v1610.unpack(bref)); + } + if (t323_r16_present) { + HANDLE_CODE(t323_r16.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_release_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (full_i_rnti_r16_present) { + j.write_str("fullI-RNTI-r16", full_i_rnti_r16.to_string()); + } + if (short_i_rnti_r16_present) { + j.write_str("shortI-RNTI-r16", short_i_rnti_r16.to_string()); + } + if (pur_cfg_r16_present) { + j.write_fieldname("pur-Config-r16"); + pur_cfg_r16.to_json(j); + } + if (rrc_inactive_cfg_v1610_present) { + j.write_fieldname("rrc-InactiveConfig-v1610"); + rrc_inactive_cfg_v1610.to_json(j); + } + if (release_idle_meas_cfg_r16_present) { + j.write_str("releaseIdleMeasConfig-r16", "true"); + } + if (alt_freq_priorities_r16_present) { + j.write_str("altFreqPriorities-r16", "true"); + } + if (t323_r16_present) { + j.write_str("t323-r16", t323_r16.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +const char* rrc_conn_release_v1610_ies_s::t323_r16_opts::to_string() const +{ + static const char* options[] = {"min5", "min10", "min20", "min30", "min60", "min120", "min180", "min720"}; + return convert_enum_idx(options, 8, value, "rrc_conn_release_v1610_ies_s::t323_r16_e_"); +} +uint16_t rrc_conn_release_v1610_ies_s::t323_r16_opts::to_number() const +{ + static const uint16_t options[] = {5, 10, 20, 30, 60, 120, 180, 720}; + return map_enum_number(options, 8, value, "rrc_conn_release_v1610_ies_s::t323_r16_e_"); +} + // SL-CommTxPoolToAddMod-r12 ::= SEQUENCE SRSASN_CODE sl_comm_tx_pool_to_add_mod_r12_s::pack(bit_ref& bref) const { @@ -3363,6 +4567,43 @@ SRSASN_CODE sl_v2x_cfg_ded_r14_s::comm_tx_res_v1530_c_::setup_c_::unpack(cbit_re return SRSASN_SUCCESS; } +// ValidityArea-r16 ::= SEQUENCE +SRSASN_CODE validity_area_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(validity_cell_list_r16_present, 1)); + + HANDLE_CODE(pack_integer(bref, carrier_freq_r16, (uint32_t)0u, (uint32_t)262143u)); + if (validity_cell_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, validity_cell_list_r16, 1, 8)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE validity_area_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(validity_cell_list_r16_present, 1)); + + HANDLE_CODE(unpack_integer(carrier_freq_r16, bref, (uint32_t)0u, (uint32_t)262143u)); + if (validity_cell_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(validity_cell_list_r16, bref, 1, 8)); + } + + return SRSASN_SUCCESS; +} +void validity_area_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("carrierFreq-r16", carrier_freq_r16); + if (validity_cell_list_r16_present) { + j.start_array("validityCellList-r16"); + for (const auto& e1 : validity_cell_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + // LWA-Configuration-r13 ::= CHOICE void lwa_cfg_r13_c::set(types::options e) { @@ -3523,10 +4764,10 @@ void pwr_coordination_info_r12_s::to_json(json_writer& j) const void ran_notif_area_info_r15_c::destroy_() { switch (type_) { - case types::cell_list_r15: + case types::cell_list: c.destroy(); break; - case types::ran_area_cfg_list_r15: + case types::ran_area_cfg_list: c.destroy(); break; default: @@ -3538,10 +4779,10 @@ void ran_notif_area_info_r15_c::set(types::options e) destroy_(); type_ = e; switch (type_) { - case types::cell_list_r15: + case types::cell_list: c.init(); break; - case types::ran_area_cfg_list_r15: + case types::ran_area_cfg_list: c.init(); break; case types::nulltype: @@ -3554,10 +4795,10 @@ ran_notif_area_info_r15_c::ran_notif_area_info_r15_c(const ran_notif_area_info_r { type_ = other.type(); switch (type_) { - case types::cell_list_r15: + case types::cell_list: c.init(other.c.get()); break; - case types::ran_area_cfg_list_r15: + case types::ran_area_cfg_list: c.init(other.c.get()); break; case types::nulltype: @@ -3573,10 +4814,10 @@ ran_notif_area_info_r15_c& ran_notif_area_info_r15_c::operator=(const ran_notif_ } set(other.type()); switch (type_) { - case types::cell_list_r15: + case types::cell_list: c.set(other.c.get()); break; - case types::ran_area_cfg_list_r15: + case types::ran_area_cfg_list: c.set(other.c.get()); break; case types::nulltype: @@ -3587,29 +4828,29 @@ ran_notif_area_info_r15_c& ran_notif_area_info_r15_c::operator=(const ran_notif_ return *this; } -plmn_ran_area_cell_list_r15_l& ran_notif_area_info_r15_c::set_cell_list_r15() +plmn_ran_area_cell_list_r15_l& ran_notif_area_info_r15_c::set_cell_list() { - set(types::cell_list_r15); + set(types::cell_list); return c.get(); } -plmn_ran_area_cfg_list_r15_l& ran_notif_area_info_r15_c::set_ran_area_cfg_list_r15() +plmn_ran_area_cfg_list_r15_l& ran_notif_area_info_r15_c::set_ran_area_cfg_list() { - set(types::ran_area_cfg_list_r15); + set(types::ran_area_cfg_list); return c.get(); } void ran_notif_area_info_r15_c::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::cell_list_r15: - j.start_array("cellList-r15"); + case types::cell_list: + j.start_array("cellList"); for (const auto& e1 : c.get()) { e1.to_json(j); } j.end_array(); break; - case types::ran_area_cfg_list_r15: - j.start_array("ran-AreaConfigList-r15"); + case types::ran_area_cfg_list: + j.start_array("ran-AreaConfigList"); for (const auto& e1 : c.get()) { e1.to_json(j); } @@ -3624,10 +4865,10 @@ SRSASN_CODE ran_notif_area_info_r15_c::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::cell_list_r15: + case types::cell_list: HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 8)); break; - case types::ran_area_cfg_list_r15: + case types::ran_area_cfg_list: HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 8)); break; default: @@ -3642,10 +4883,10 @@ SRSASN_CODE ran_notif_area_info_r15_c::unpack(cbit_ref& bref) e.unpack(bref); set(e); switch (type_) { - case types::cell_list_r15: + case types::cell_list: HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 8)); break; - case types::ran_area_cfg_list_r15: + case types::ran_area_cfg_list: HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 8)); break; default: @@ -3800,6 +5041,10 @@ SRSASN_CODE rrc_conn_release_v15b0_ies_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(no_last_cell_upd_r15_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + return SRSASN_SUCCESS; } SRSASN_CODE rrc_conn_release_v15b0_ies_s::unpack(cbit_ref& bref) @@ -3807,6 +5052,10 @@ SRSASN_CODE rrc_conn_release_v15b0_ies_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(no_last_cell_upd_r15_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + return SRSASN_SUCCESS; } void rrc_conn_release_v15b0_ies_s::to_json(json_writer& j) const @@ -3817,8 +5066,7 @@ void rrc_conn_release_v15b0_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -4230,6 +5478,25 @@ SRSASN_CODE meas_idle_cfg_ded_r15_s::pack(bit_ref& bref) const } HANDLE_CODE(meas_idle_dur_r15.pack(bref)); + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= meas_idle_carrier_list_nr_r16.is_present(); + group_flags[0] |= validity_area_list_r16.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(meas_idle_carrier_list_nr_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(validity_area_list_r16.is_present(), 1)); + if (meas_idle_carrier_list_nr_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *meas_idle_carrier_list_nr_r16, 1, 8)); + } + if (validity_area_list_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *validity_area_list_r16, 1, 8)); + } + } + } return SRSASN_SUCCESS; } SRSASN_CODE meas_idle_cfg_ded_r15_s::unpack(cbit_ref& bref) @@ -4242,6 +5509,27 @@ SRSASN_CODE meas_idle_cfg_ded_r15_s::unpack(cbit_ref& bref) } HANDLE_CODE(meas_idle_dur_r15.unpack(bref)); + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool meas_idle_carrier_list_nr_r16_present; + HANDLE_CODE(bref.unpack(meas_idle_carrier_list_nr_r16_present, 1)); + meas_idle_carrier_list_nr_r16.set_present(meas_idle_carrier_list_nr_r16_present); + bool validity_area_list_r16_present; + HANDLE_CODE(bref.unpack(validity_area_list_r16_present, 1)); + validity_area_list_r16.set_present(validity_area_list_r16_present); + if (meas_idle_carrier_list_nr_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*meas_idle_carrier_list_nr_r16, bref, 1, 8)); + } + if (validity_area_list_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*validity_area_list_r16, bref, 1, 8)); + } + } + } return SRSASN_SUCCESS; } void meas_idle_cfg_ded_r15_s::to_json(json_writer& j) const @@ -4255,6 +5543,22 @@ void meas_idle_cfg_ded_r15_s::to_json(json_writer& j) const j.end_array(); } j.write_str("measIdleDuration-r15", meas_idle_dur_r15.to_string()); + if (ext) { + if (meas_idle_carrier_list_nr_r16.is_present()) { + j.start_array("measIdleCarrierListNR-r16"); + for (const auto& e1 : *meas_idle_carrier_list_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (validity_area_list_r16.is_present()) { + j.start_array("validityAreaList-r16"); + for (const auto& e1 : *validity_area_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + } j.end_obj(); } @@ -4616,6 +5920,111 @@ SRSASN_CODE scg_cfg_r12_c::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +// SCellToAddMod-r16 ::= SEQUENCE +SRSASN_CODE scell_to_add_mod_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(cell_identif_r16_present, 1)); + HANDLE_CODE(bref.pack(rr_cfg_common_scell_r16_present, 1)); + HANDLE_CODE(bref.pack(rr_cfg_ded_scell_r16_present, 1)); + HANDLE_CODE(bref.pack(ant_info_ded_scell_r16_present, 1)); + HANDLE_CODE(bref.pack(srs_switch_from_serv_cell_idx_r16_present, 1)); + HANDLE_CODE(bref.pack(scell_state_r16_present, 1)); + + HANDLE_CODE(pack_integer(bref, scell_idx_r16, (uint8_t)1u, (uint8_t)31u)); + if (cell_identif_r16_present) { + HANDLE_CODE(pack_integer(bref, cell_identif_r16.pci_r16, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(pack_integer(bref, cell_identif_r16.dl_carrier_freq_r16, (uint32_t)0u, (uint32_t)262143u)); + } + if (rr_cfg_common_scell_r16_present) { + HANDLE_CODE(rr_cfg_common_scell_r16.pack(bref)); + } + if (rr_cfg_ded_scell_r16_present) { + HANDLE_CODE(rr_cfg_ded_scell_r16.pack(bref)); + } + if (ant_info_ded_scell_r16_present) { + HANDLE_CODE(ant_info_ded_scell_r16.pack(bref)); + } + if (srs_switch_from_serv_cell_idx_r16_present) { + HANDLE_CODE(pack_integer(bref, srs_switch_from_serv_cell_idx_r16, (uint8_t)0u, (uint8_t)31u)); + } + if (scell_state_r16_present) { + HANDLE_CODE(scell_state_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE scell_to_add_mod_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(cell_identif_r16_present, 1)); + HANDLE_CODE(bref.unpack(rr_cfg_common_scell_r16_present, 1)); + HANDLE_CODE(bref.unpack(rr_cfg_ded_scell_r16_present, 1)); + HANDLE_CODE(bref.unpack(ant_info_ded_scell_r16_present, 1)); + HANDLE_CODE(bref.unpack(srs_switch_from_serv_cell_idx_r16_present, 1)); + HANDLE_CODE(bref.unpack(scell_state_r16_present, 1)); + + HANDLE_CODE(unpack_integer(scell_idx_r16, bref, (uint8_t)1u, (uint8_t)31u)); + if (cell_identif_r16_present) { + HANDLE_CODE(unpack_integer(cell_identif_r16.pci_r16, bref, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(unpack_integer(cell_identif_r16.dl_carrier_freq_r16, bref, (uint32_t)0u, (uint32_t)262143u)); + } + if (rr_cfg_common_scell_r16_present) { + HANDLE_CODE(rr_cfg_common_scell_r16.unpack(bref)); + } + if (rr_cfg_ded_scell_r16_present) { + HANDLE_CODE(rr_cfg_ded_scell_r16.unpack(bref)); + } + if (ant_info_ded_scell_r16_present) { + HANDLE_CODE(ant_info_ded_scell_r16.unpack(bref)); + } + if (srs_switch_from_serv_cell_idx_r16_present) { + HANDLE_CODE(unpack_integer(srs_switch_from_serv_cell_idx_r16, bref, (uint8_t)0u, (uint8_t)31u)); + } + if (scell_state_r16_present) { + HANDLE_CODE(scell_state_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void scell_to_add_mod_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("sCellIndex-r16", scell_idx_r16); + if (cell_identif_r16_present) { + j.write_fieldname("cellIdentification-r16"); + j.start_obj(); + j.write_int("physCellId-r16", cell_identif_r16.pci_r16); + j.write_int("dl-CarrierFreq-r16", cell_identif_r16.dl_carrier_freq_r16); + j.end_obj(); + } + if (rr_cfg_common_scell_r16_present) { + j.write_fieldname("radioResourceConfigCommonSCell-r16"); + rr_cfg_common_scell_r16.to_json(j); + } + if (rr_cfg_ded_scell_r16_present) { + j.write_fieldname("radioResourceConfigDedicatedSCell-r16"); + rr_cfg_ded_scell_r16.to_json(j); + } + if (ant_info_ded_scell_r16_present) { + j.write_fieldname("antennaInfoDedicatedSCell-r16"); + ant_info_ded_scell_r16.to_json(j); + } + if (srs_switch_from_serv_cell_idx_r16_present) { + j.write_int("srs-SwitchFromServCellIndex-r16", srs_switch_from_serv_cell_idx_r16); + } + if (scell_state_r16_present) { + j.write_str("sCellState-r16", scell_state_r16.to_string()); + } + j.end_obj(); +} + +const char* scell_to_add_mod_r16_s::scell_state_r16_opts::to_string() const +{ + static const char* options[] = {"activated", "dormant"}; + return convert_enum_idx(options, 2, value, "scell_to_add_mod_r16_s::scell_state_r16_e_"); +} + // SL-CommConfig-r12 ::= SEQUENCE SRSASN_CODE sl_comm_cfg_r12_s::pack(bit_ref& bref) const { @@ -6240,6 +7649,35 @@ const char* sl_sync_tx_ctrl_r12_s::network_ctrl_sync_tx_r12_opts::to_string() co return convert_enum_idx(options, 2, value, "sl_sync_tx_ctrl_r12_s::network_ctrl_sync_tx_r12_e_"); } +// UEInformationRequest-v1710-IEs ::= SEQUENCE +SRSASN_CODE ue_info_request_v1710_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(coarse_location_req_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_info_request_v1710_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(coarse_location_req_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + return SRSASN_SUCCESS; +} +void ue_info_request_v1710_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (coarse_location_req_r17_present) { + j.write_str("coarseLocationReq-r17", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // RRCConnectionReconfiguration-v1250-IEs ::= SEQUENCE SRSASN_CODE rrc_conn_recfg_v1250_ies_s::pack(bit_ref& bref) const { @@ -6516,6 +7954,35 @@ uint8_t rrc_conn_release_v1530_ies_s::cn_type_r15_opts::to_number() const return 0; } +// RRCConnectionResume-v1700-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_v1700_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(scg_state_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_resume_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(scg_state_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + return SRSASN_SUCCESS; +} +void rrc_conn_resume_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (scg_state_r17_present) { + j.write_str("scg-State-r17", "deactivated"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // TargetMBSFN-Area-r12 ::= SEQUENCE SRSASN_CODE target_mbsfn_area_r12_s::pack(bit_ref& bref) const { @@ -6561,6 +8028,9 @@ SRSASN_CODE ue_info_request_v1530_ies_s::pack(bit_ref& bref) const if (flight_path_info_req_r15_present) { HANDLE_CODE(flight_path_info_req_r15.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -6573,6 +8043,9 @@ SRSASN_CODE ue_info_request_v1530_ies_s::unpack(cbit_ref& bref) if (flight_path_info_req_r15_present) { HANDLE_CODE(flight_path_info_req_r15.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -6588,8 +8061,7 @@ void ue_info_request_v1530_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -7122,6 +8594,169 @@ void rrc_conn_release_v1320_ies_s::to_json(json_writer& j) const j.end_obj(); } +// RRCConnectionResume-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(idle_mode_meas_req_r16_present, 1)); + HANDLE_CODE(bref.pack(restore_mcg_scells_r16_present, 1)); + HANDLE_CODE(bref.pack(restore_scg_r16_present, 1)); + HANDLE_CODE(bref.pack(scell_to_add_mod_list_r16_present, 1)); + HANDLE_CODE(bref.pack(scell_to_release_list_r16_present, 1)); + HANDLE_CODE(bref.pack(scell_group_to_release_list_r16_present, 1)); + HANDLE_CODE(bref.pack(scell_group_to_add_mod_list_r16_present, 1)); + HANDLE_CODE(bref.pack(nr_secondary_cell_group_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(p_max_eutra_r16_present, 1)); + HANDLE_CODE(bref.pack(p_max_ue_fr1_r16_present, 1)); + HANDLE_CODE(bref.pack(tdm_pattern_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(tdm_pattern_cfg2_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (scell_to_add_mod_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, scell_to_add_mod_list_r16, 1, 31)); + } + if (scell_to_release_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, scell_to_release_list_r16, 1, 31, integer_packer(1, 31))); + } + if (scell_group_to_release_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, scell_group_to_release_list_r16, 1, 4, integer_packer(1, 4))); + } + if (scell_group_to_add_mod_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, scell_group_to_add_mod_list_r16, 1, 4)); + } + if (nr_secondary_cell_group_cfg_r16_present) { + HANDLE_CODE(nr_secondary_cell_group_cfg_r16.pack(bref)); + } + if (p_max_eutra_r16_present) { + HANDLE_CODE(pack_integer(bref, p_max_eutra_r16, (int8_t)-30, (int8_t)33)); + } + if (p_max_ue_fr1_r16_present) { + HANDLE_CODE(pack_integer(bref, p_max_ue_fr1_r16, (int8_t)-30, (int8_t)33)); + } + if (tdm_pattern_cfg_r16_present) { + HANDLE_CODE(tdm_pattern_cfg_r16.pack(bref)); + } + if (tdm_pattern_cfg2_r16_present) { + HANDLE_CODE(tdm_pattern_cfg2_r16.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_resume_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(idle_mode_meas_req_r16_present, 1)); + HANDLE_CODE(bref.unpack(restore_mcg_scells_r16_present, 1)); + HANDLE_CODE(bref.unpack(restore_scg_r16_present, 1)); + HANDLE_CODE(bref.unpack(scell_to_add_mod_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(scell_to_release_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(scell_group_to_release_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(scell_group_to_add_mod_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(nr_secondary_cell_group_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(p_max_eutra_r16_present, 1)); + HANDLE_CODE(bref.unpack(p_max_ue_fr1_r16_present, 1)); + HANDLE_CODE(bref.unpack(tdm_pattern_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(tdm_pattern_cfg2_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (scell_to_add_mod_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(scell_to_add_mod_list_r16, bref, 1, 31)); + } + if (scell_to_release_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(scell_to_release_list_r16, bref, 1, 31, integer_packer(1, 31))); + } + if (scell_group_to_release_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(scell_group_to_release_list_r16, bref, 1, 4, integer_packer(1, 4))); + } + if (scell_group_to_add_mod_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(scell_group_to_add_mod_list_r16, bref, 1, 4)); + } + if (nr_secondary_cell_group_cfg_r16_present) { + HANDLE_CODE(nr_secondary_cell_group_cfg_r16.unpack(bref)); + } + if (p_max_eutra_r16_present) { + HANDLE_CODE(unpack_integer(p_max_eutra_r16, bref, (int8_t)-30, (int8_t)33)); + } + if (p_max_ue_fr1_r16_present) { + HANDLE_CODE(unpack_integer(p_max_ue_fr1_r16, bref, (int8_t)-30, (int8_t)33)); + } + if (tdm_pattern_cfg_r16_present) { + HANDLE_CODE(tdm_pattern_cfg_r16.unpack(bref)); + } + if (tdm_pattern_cfg2_r16_present) { + HANDLE_CODE(tdm_pattern_cfg2_r16.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_resume_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (idle_mode_meas_req_r16_present) { + j.write_str("idleModeMeasurementReq-r16", "true"); + } + if (restore_mcg_scells_r16_present) { + j.write_str("restoreMCG-SCells-r16", "true"); + } + if (restore_scg_r16_present) { + j.write_str("restoreSCG-r16", "true"); + } + if (scell_to_add_mod_list_r16_present) { + j.start_array("sCellToAddModList-r16"); + for (const auto& e1 : scell_to_add_mod_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (scell_to_release_list_r16_present) { + j.start_array("sCellToReleaseList-r16"); + for (const auto& e1 : scell_to_release_list_r16) { + j.write_int(e1); + } + j.end_array(); + } + if (scell_group_to_release_list_r16_present) { + j.start_array("sCellGroupToReleaseList-r16"); + for (const auto& e1 : scell_group_to_release_list_r16) { + j.write_int(e1); + } + j.end_array(); + } + if (scell_group_to_add_mod_list_r16_present) { + j.start_array("sCellGroupToAddModList-r16"); + for (const auto& e1 : scell_group_to_add_mod_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (nr_secondary_cell_group_cfg_r16_present) { + j.write_str("nr-SecondaryCellGroupConfig-r16", nr_secondary_cell_group_cfg_r16.to_string()); + } + if (p_max_eutra_r16_present) { + j.write_int("p-MaxEUTRA-r16", p_max_eutra_r16); + } + if (p_max_ue_fr1_r16_present) { + j.write_int("p-MaxUE-FR1-r16", p_max_ue_fr1_r16); + } + if (tdm_pattern_cfg_r16_present) { + j.write_fieldname("tdm-PatternConfig-r16"); + tdm_pattern_cfg_r16.to_json(j); + } + if (tdm_pattern_cfg2_r16_present) { + j.write_fieldname("tdm-PatternConfig2-r16"); + tdm_pattern_cfg2_r16.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + // ReportProximityConfig-r9 ::= SEQUENCE SRSASN_CODE report_proximity_cfg_r9_s::pack(bit_ref& bref) const { @@ -7137,16 +8772,64 @@ SRSASN_CODE report_proximity_cfg_r9_s::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -void report_proximity_cfg_r9_s::to_json(json_writer& j) const +void report_proximity_cfg_r9_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (proximity_ind_eutra_r9_present) { + j.write_str("proximityIndicationEUTRA-r9", "enabled"); + } + if (proximity_ind_utra_r9_present) { + j.write_str("proximityIndicationUTRA-r9", "enabled"); + } + j.end_obj(); +} + +// SCG-DeactivationPreferenceConfig-r17 ::= SEQUENCE +SRSASN_CODE scg_deactivation_pref_cfg_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(scg_deactivation_pref_prohibit_timer_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE scg_deactivation_pref_cfg_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(scg_deactivation_pref_prohibit_timer_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void scg_deactivation_pref_cfg_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("scg-DeactivationPreferenceProhibitTimer-r17", scg_deactivation_pref_prohibit_timer_r17.to_string()); + j.end_obj(); +} + +const char* scg_deactivation_pref_cfg_r17_s::scg_deactivation_pref_prohibit_timer_r17_opts::to_string() const +{ + static const char* options[] = {"s0", + "s1", + "s2", + "s4", + "s8", + "s10", + "s20", + "s30", + "s60", + "s120", + "s180", + "s240", + "s300", + "s600", + "s900", + "s1800"}; + return convert_enum_idx( + options, 16, value, "scg_deactivation_pref_cfg_r17_s::scg_deactivation_pref_prohibit_timer_r17_e_"); +} +uint16_t scg_deactivation_pref_cfg_r17_s::scg_deactivation_pref_prohibit_timer_r17_opts::to_number() const { - j.start_obj(); - if (proximity_ind_eutra_r9_present) { - j.write_str("proximityIndicationEUTRA-r9", "enabled"); - } - if (proximity_ind_utra_r9_present) { - j.write_str("proximityIndicationUTRA-r9", "enabled"); - } - j.end_obj(); + static const uint16_t options[] = {0, 1, 2, 4, 8, 10, 20, 30, 60, 120, 180, 240, 300, 600, 900, 1800}; + return map_enum_number( + options, 16, value, "scg_deactivation_pref_cfg_r17_s::scg_deactivation_pref_prohibit_timer_r17_e_"); } // TrackingAreaCodeList-v1130 ::= SEQUENCE @@ -7381,6 +9064,9 @@ SRSASN_CODE other_cfg_r9_s::pack(bit_ref& bref) const group_flags[3] |= ailc_bit_cfg_r15_present; group_flags[3] |= bt_name_list_cfg_r15.is_present(); group_flags[3] |= wlan_name_list_cfg_r15.is_present(); + group_flags[4] |= overheat_assist_cfg_for_scg_r16_present; + group_flags[5] |= meas_uncom_bar_pre_r17_present; + group_flags[5] |= scg_deactivation_pref_cfg_r17.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -7447,6 +9133,26 @@ SRSASN_CODE other_cfg_r9_s::pack(bit_ref& bref) const HANDLE_CODE(wlan_name_list_cfg_r15->pack(bref)); } } + if (group_flags[4]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(overheat_assist_cfg_for_scg_r16_present, 1)); + if (overheat_assist_cfg_for_scg_r16_present) { + HANDLE_CODE(bref.pack(overheat_assist_cfg_for_scg_r16, 1)); + } + } + if (group_flags[5]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(meas_uncom_bar_pre_r17_present, 1)); + HANDLE_CODE(bref.pack(scg_deactivation_pref_cfg_r17.is_present(), 1)); + if (meas_uncom_bar_pre_r17_present) { + HANDLE_CODE(bref.pack(meas_uncom_bar_pre_r17, 1)); + } + if (scg_deactivation_pref_cfg_r17.is_present()) { + HANDLE_CODE(scg_deactivation_pref_cfg_r17->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -7460,7 +9166,7 @@ SRSASN_CODE other_cfg_r9_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(4); + ext_groups_unpacker_guard group_flags(6); group_flags.unpack(bref); if (group_flags[0]) { @@ -7545,6 +9251,28 @@ SRSASN_CODE other_cfg_r9_s::unpack(cbit_ref& bref) HANDLE_CODE(wlan_name_list_cfg_r15->unpack(bref)); } } + if (group_flags[4]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(overheat_assist_cfg_for_scg_r16_present, 1)); + if (overheat_assist_cfg_for_scg_r16_present) { + HANDLE_CODE(bref.unpack(overheat_assist_cfg_for_scg_r16, 1)); + } + } + if (group_flags[5]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(meas_uncom_bar_pre_r17_present, 1)); + bool scg_deactivation_pref_cfg_r17_present; + HANDLE_CODE(bref.unpack(scg_deactivation_pref_cfg_r17_present, 1)); + scg_deactivation_pref_cfg_r17.set_present(scg_deactivation_pref_cfg_r17_present); + if (meas_uncom_bar_pre_r17_present) { + HANDLE_CODE(bref.unpack(meas_uncom_bar_pre_r17, 1)); + } + if (scg_deactivation_pref_cfg_r17.is_present()) { + HANDLE_CODE(scg_deactivation_pref_cfg_r17->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -7601,6 +9329,16 @@ void other_cfg_r9_s::to_json(json_writer& j) const j.write_fieldname("wlan-NameListConfig-r15"); wlan_name_list_cfg_r15->to_json(j); } + if (overheat_assist_cfg_for_scg_r16_present) { + j.write_bool("overheatingAssistanceConfigForSCG-r16", overheat_assist_cfg_for_scg_r16); + } + if (meas_uncom_bar_pre_r17_present) { + j.write_bool("measUncomBarPre-r17", meas_uncom_bar_pre_r17); + } + if (scg_deactivation_pref_cfg_r17.is_present()) { + j.write_fieldname("scg-DeactivationPreferenceConfig-r17"); + scg_deactivation_pref_cfg_r17->to_json(j); + } } j.end_obj(); } @@ -8113,6 +9851,10 @@ SRSASN_CODE rrc_conn_resume_v1530_ies_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(full_cfg_r15_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + return SRSASN_SUCCESS; } SRSASN_CODE rrc_conn_resume_v1530_ies_s::unpack(cbit_ref& bref) @@ -8120,6 +9862,10 @@ SRSASN_CODE rrc_conn_resume_v1530_ies_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(full_cfg_r15_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + return SRSASN_SUCCESS; } void rrc_conn_resume_v1530_ies_s::to_json(json_writer& j) const @@ -8130,8 +9876,7 @@ void rrc_conn_resume_v1530_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -8220,6 +9965,54 @@ uint8_t carrier_info_nr_r15_s::subcarrier_spacing_ssb_r15_opts::to_number() cons return map_enum_number(options, 4, value, "carrier_info_nr_r15_s::subcarrier_spacing_ssb_r15_e_"); } +// CarrierInfoNR-r17 ::= SEQUENCE +SRSASN_CODE carrier_info_nr_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(smtc_r17_present, 1)); + + HANDLE_CODE(pack_integer(bref, carrier_freq_r17, (uint32_t)0u, (uint32_t)3279165u)); + HANDLE_CODE(subcarrier_spacing_ssb_r17.pack(bref)); + if (smtc_r17_present) { + HANDLE_CODE(smtc_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE carrier_info_nr_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(smtc_r17_present, 1)); + + HANDLE_CODE(unpack_integer(carrier_freq_r17, bref, (uint32_t)0u, (uint32_t)3279165u)); + HANDLE_CODE(subcarrier_spacing_ssb_r17.unpack(bref)); + if (smtc_r17_present) { + HANDLE_CODE(smtc_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void carrier_info_nr_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("carrierFreq-r17", carrier_freq_r17); + j.write_str("subcarrierSpacingSSB-r17", subcarrier_spacing_ssb_r17.to_string()); + if (smtc_r17_present) { + j.write_fieldname("smtc-r17"); + smtc_r17.to_json(j); + } + j.end_obj(); +} + +const char* carrier_info_nr_r17_s::subcarrier_spacing_ssb_r17_opts::to_string() const +{ + static const char* options[] = {"kHz15", "kHz30", "kHz120", "kHz240", "kHz480", "spare1"}; + return convert_enum_idx(options, 6, value, "carrier_info_nr_r17_s::subcarrier_spacing_ssb_r17_e_"); +} +uint16_t carrier_info_nr_r17_s::subcarrier_spacing_ssb_r17_opts::to_number() const +{ + static const uint16_t options[] = {15, 30, 120, 240, 480}; + return map_enum_number(options, 5, value, "carrier_info_nr_r17_s::subcarrier_spacing_ssb_r17_e_"); +} + // CounterCheck-v1530-IEs ::= SEQUENCE SRSASN_CODE counter_check_v1530_ies_s::pack(bit_ref& bref) const { @@ -8261,6 +10054,43 @@ void counter_check_v1530_ies_s::to_json(json_writer& j) const j.end_obj(); } +// DLInformationTransfer-v1610-IEs ::= SEQUENCE +SRSASN_CODE dl_info_transfer_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ded_info_f1c_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (ded_info_f1c_r16_present) { + HANDLE_CODE(ded_info_f1c_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE dl_info_transfer_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ded_info_f1c_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (ded_info_f1c_r16_present) { + HANDLE_CODE(ded_info_f1c_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void dl_info_transfer_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ded_info_f1c_r16_present) { + j.write_str("dedicatedInfoF1c-r16", ded_info_f1c_r16.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // HandoverFromEUTRAPreparationRequest-v920-IEs ::= SEQUENCE SRSASN_CODE ho_from_eutra_prep_request_v920_ies_s::pack(bit_ref& bref) const { @@ -9280,6 +11110,9 @@ SRSASN_CODE dl_info_transfer_v8a0_ies_s::pack(bit_ref& bref) const if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -9291,6 +11124,9 @@ SRSASN_CODE dl_info_transfer_v8a0_ies_s::unpack(cbit_ref& bref) if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -9302,8 +11138,7 @@ void dl_info_transfer_v8a0_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -10985,6 +12820,9 @@ void redirected_carrier_info_c::destroy_() case types::nr_r15: c.destroy(); break; + case types::nr_r17: + c.destroy(); + break; default: break; } @@ -11015,6 +12853,9 @@ void redirected_carrier_info_c::set(types::options e) case types::nr_r15: c.init(); break; + case types::nr_r17: + c.init(); + break; case types::nulltype: break; default: @@ -11049,6 +12890,9 @@ redirected_carrier_info_c::redirected_carrier_info_c(const redirected_carrier_in case types::nr_r15: c.init(other.c.get()); break; + case types::nr_r17: + c.init(other.c.get()); + break; case types::nulltype: break; default: @@ -11086,6 +12930,9 @@ redirected_carrier_info_c& redirected_carrier_info_c::operator=(const redirected case types::nr_r15: c.set(other.c.get()); break; + case types::nr_r17: + c.set(other.c.get()); + break; case types::nulltype: break; default: @@ -11134,6 +12981,11 @@ carrier_info_nr_r15_s& redirected_carrier_info_c::set_nr_r15() set(types::nr_r15); return c.get(); } +carrier_info_nr_r17_s& redirected_carrier_info_c::set_nr_r17() +{ + set(types::nr_r17); + return c.get(); +} void redirected_carrier_info_c::to_json(json_writer& j) const { j.start_obj(); @@ -11170,6 +13022,10 @@ void redirected_carrier_info_c::to_json(json_writer& j) const j.write_fieldname("nr-r15"); c.get().to_json(j); break; + case types::nr_r17: + j.write_fieldname("nr-r17"); + c.get().to_json(j); + break; default: log_invalid_choice_id(type_, "redirected_carrier_info_c"); } @@ -11206,6 +13062,10 @@ SRSASN_CODE redirected_carrier_info_c::pack(bit_ref& bref) const varlength_field_pack_guard varlen_scope(bref, false); HANDLE_CODE(c.get().pack(bref)); } break; + case types::nr_r17: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; default: log_invalid_choice_id(type_, "redirected_carrier_info_c"); return SRSASN_ERROR_ENCODE_FAIL; @@ -11245,6 +13105,10 @@ SRSASN_CODE redirected_carrier_info_c::unpack(cbit_ref& bref) varlength_field_unpack_guard varlen_scope(bref, false); HANDLE_CODE(c.get().unpack(bref)); } break; + case types::nr_r17: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; default: log_invalid_choice_id(type_, "redirected_carrier_info_c"); return SRSASN_ERROR_DECODE_FAIL; @@ -11377,6 +13241,58 @@ void counter_check_r8_ies_s::to_json(json_writer& j) const j.end_obj(); } +// DLDedicatedMessageSegment-r16-IEs ::= SEQUENCE +SRSASN_CODE dl_ded_msg_segment_r16_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(pack_integer(bref, segment_num_r16, (uint8_t)0u, (uint8_t)4u)); + HANDLE_CODE(rrc_msg_segment_container_r16.pack(bref)); + HANDLE_CODE(rrc_msg_segment_type_r16.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE dl_ded_msg_segment_r16_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(unpack_integer(segment_num_r16, bref, (uint8_t)0u, (uint8_t)4u)); + HANDLE_CODE(rrc_msg_segment_container_r16.unpack(bref)); + HANDLE_CODE(rrc_msg_segment_type_r16.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void dl_ded_msg_segment_r16_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("segmentNumber-r16", segment_num_r16); + j.write_str("rrc-MessageSegmentContainer-r16", rrc_msg_segment_container_r16.to_string()); + j.write_str("rrc-MessageSegmentType-r16", rrc_msg_segment_type_r16.to_string()); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +const char* dl_ded_msg_segment_r16_ies_s::rrc_msg_segment_type_r16_opts::to_string() const +{ + static const char* options[] = {"notLastSegment", "lastSegment"}; + return convert_enum_idx(options, 2, value, "dl_ded_msg_segment_r16_ies_s::rrc_msg_segment_type_r16_e_"); +} + // DLInformationTransfer-r15-IEs ::= SEQUENCE SRSASN_CODE dl_info_transfer_r15_ies_s::pack(bit_ref& bref) const { @@ -11435,13 +13351,13 @@ void dl_info_transfer_r15_ies_s::to_json(json_writer& j) const void dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::destroy_() { switch (type_) { - case types::ded_info_nas_r15: + case types::ded_info_nas: c.destroy(); break; - case types::ded_info_cdma2000_minus1_xrtt_r15: + case types::ded_info_cdma2000_minus1_xrtt: c.destroy(); break; - case types::ded_info_cdma2000_hrpd_r15: + case types::ded_info_cdma2000_hrpd: c.destroy(); break; default: @@ -11453,13 +13369,13 @@ void dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::set(types::options e) destroy_(); type_ = e; switch (type_) { - case types::ded_info_nas_r15: + case types::ded_info_nas: c.init(); break; - case types::ded_info_cdma2000_minus1_xrtt_r15: + case types::ded_info_cdma2000_minus1_xrtt: c.init(); break; - case types::ded_info_cdma2000_hrpd_r15: + case types::ded_info_cdma2000_hrpd: c.init(); break; case types::nulltype: @@ -11473,13 +13389,13 @@ dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::ded_info_type_r15_c_( { type_ = other.type(); switch (type_) { - case types::ded_info_nas_r15: + case types::ded_info_nas: c.init(other.c.get()); break; - case types::ded_info_cdma2000_minus1_xrtt_r15: + case types::ded_info_cdma2000_minus1_xrtt: c.init(other.c.get()); break; - case types::ded_info_cdma2000_hrpd_r15: + case types::ded_info_cdma2000_hrpd: c.init(other.c.get()); break; case types::nulltype: @@ -11496,13 +13412,13 @@ dl_info_transfer_r15_ies_s::ded_info_type_r15_c_& dl_info_transfer_r15_ies_s::de } set(other.type()); switch (type_) { - case types::ded_info_nas_r15: + case types::ded_info_nas: c.set(other.c.get()); break; - case types::ded_info_cdma2000_minus1_xrtt_r15: + case types::ded_info_cdma2000_minus1_xrtt: c.set(other.c.get()); break; - case types::ded_info_cdma2000_hrpd_r15: + case types::ded_info_cdma2000_hrpd: c.set(other.c.get()); break; case types::nulltype: @@ -11513,33 +13429,33 @@ dl_info_transfer_r15_ies_s::ded_info_type_r15_c_& dl_info_transfer_r15_ies_s::de return *this; } -dyn_octstring& dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::set_ded_info_nas_r15() +dyn_octstring& dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::set_ded_info_nas() { - set(types::ded_info_nas_r15); + set(types::ded_info_nas); return c.get(); } -dyn_octstring& dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::set_ded_info_cdma2000_minus1_xrtt_r15() +dyn_octstring& dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::set_ded_info_cdma2000_minus1_xrtt() { - set(types::ded_info_cdma2000_minus1_xrtt_r15); + set(types::ded_info_cdma2000_minus1_xrtt); return c.get(); } -dyn_octstring& dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::set_ded_info_cdma2000_hrpd_r15() +dyn_octstring& dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::set_ded_info_cdma2000_hrpd() { - set(types::ded_info_cdma2000_hrpd_r15); + set(types::ded_info_cdma2000_hrpd); return c.get(); } void dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::ded_info_nas_r15: - j.write_str("dedicatedInfoNAS-r15", c.get().to_string()); + case types::ded_info_nas: + j.write_str("dedicatedInfoNAS", c.get().to_string()); break; - case types::ded_info_cdma2000_minus1_xrtt_r15: - j.write_str("dedicatedInfoCDMA2000-1XRTT-r15", c.get().to_string()); + case types::ded_info_cdma2000_minus1_xrtt: + j.write_str("dedicatedInfoCDMA2000-1XRTT", c.get().to_string()); break; - case types::ded_info_cdma2000_hrpd_r15: - j.write_str("dedicatedInfoCDMA2000-HRPD-r15", c.get().to_string()); + case types::ded_info_cdma2000_hrpd: + j.write_str("dedicatedInfoCDMA2000-HRPD", c.get().to_string()); break; default: log_invalid_choice_id(type_, "dl_info_transfer_r15_ies_s::ded_info_type_r15_c_"); @@ -11550,13 +13466,13 @@ SRSASN_CODE dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::pack(bit_ref& bref { type_.pack(bref); switch (type_) { - case types::ded_info_nas_r15: + case types::ded_info_nas: HANDLE_CODE(c.get().pack(bref)); break; - case types::ded_info_cdma2000_minus1_xrtt_r15: + case types::ded_info_cdma2000_minus1_xrtt: HANDLE_CODE(c.get().pack(bref)); break; - case types::ded_info_cdma2000_hrpd_r15: + case types::ded_info_cdma2000_hrpd: HANDLE_CODE(c.get().pack(bref)); break; default: @@ -11571,13 +13487,13 @@ SRSASN_CODE dl_info_transfer_r15_ies_s::ded_info_type_r15_c_::unpack(cbit_ref& b e.unpack(bref); set(e); switch (type_) { - case types::ded_info_nas_r15: + case types::ded_info_nas: HANDLE_CODE(c.get().unpack(bref)); break; - case types::ded_info_cdma2000_minus1_xrtt_r15: + case types::ded_info_cdma2000_minus1_xrtt: HANDLE_CODE(c.get().unpack(bref)); break; - case types::ded_info_cdma2000_hrpd_r15: + case types::ded_info_cdma2000_hrpd: HANDLE_CODE(c.get().unpack(bref)); break; default: @@ -12844,6 +14760,88 @@ SRSASN_CODE counter_check_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +// DLDedicatedMessageSegment-r16 ::= SEQUENCE +SRSASN_CODE dl_ded_msg_segment_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE dl_ded_msg_segment_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void dl_ded_msg_segment_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void dl_ded_msg_segment_r16_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +dl_ded_msg_segment_r16_ies_s& dl_ded_msg_segment_r16_s::crit_exts_c_::set_dl_ded_msg_segment_r16() +{ + set(types::dl_ded_msg_segment_r16); + return c; +} +void dl_ded_msg_segment_r16_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void dl_ded_msg_segment_r16_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::dl_ded_msg_segment_r16: + j.write_fieldname("dlDedicatedMessageSegment-r16"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "dl_ded_msg_segment_r16_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE dl_ded_msg_segment_r16_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::dl_ded_msg_segment_r16: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "dl_ded_msg_segment_r16_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE dl_ded_msg_segment_r16_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::dl_ded_msg_segment_r16: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "dl_ded_msg_segment_r16_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + // DLInformationTransfer ::= SEQUENCE SRSASN_CODE dl_info_transfer_s::pack(bit_ref& bref) const { @@ -14642,6 +16640,9 @@ void dl_dcch_msg_type_c::c1_c_::destroy_() case types::rrc_conn_resume_r13: c.destroy(); break; + case types::dl_ded_msg_segment_r16: + c.destroy(); + break; default: break; } @@ -14690,7 +16691,8 @@ void dl_dcch_msg_type_c::c1_c_::set(types::options e) case types::rrc_conn_resume_r13: c.init(); break; - case types::spare3: + case types::dl_ded_msg_segment_r16: + c.init(); break; case types::spare2: break; @@ -14745,7 +16747,8 @@ dl_dcch_msg_type_c::c1_c_::c1_c_(const dl_dcch_msg_type_c::c1_c_& other) case types::rrc_conn_resume_r13: c.init(other.c.get()); break; - case types::spare3: + case types::dl_ded_msg_segment_r16: + c.init(other.c.get()); break; case types::spare2: break; @@ -14803,7 +16806,8 @@ dl_dcch_msg_type_c::c1_c_& dl_dcch_msg_type_c::c1_c_::operator=(const dl_dcch_ms case types::rrc_conn_resume_r13: c.set(other.c.get()); break; - case types::spare3: + case types::dl_ded_msg_segment_r16: + c.set(other.c.get()); break; case types::spare2: break; @@ -14882,9 +16886,10 @@ rrc_conn_resume_r13_s& dl_dcch_msg_type_c::c1_c_::set_rrc_conn_resume_r13() set(types::rrc_conn_resume_r13); return c.get(); } -void dl_dcch_msg_type_c::c1_c_::set_spare3() +dl_ded_msg_segment_r16_s& dl_dcch_msg_type_c::c1_c_::set_dl_ded_msg_segment_r16() { - set(types::spare3); + set(types::dl_ded_msg_segment_r16); + return c.get(); } void dl_dcch_msg_type_c::c1_c_::set_spare2() { @@ -14950,7 +16955,9 @@ void dl_dcch_msg_type_c::c1_c_::to_json(json_writer& j) const j.write_fieldname("rrcConnectionResume-r13"); c.get().to_json(j); break; - case types::spare3: + case types::dl_ded_msg_segment_r16: + j.write_fieldname("dlDedicatedMessageSegment-r16"); + c.get().to_json(j); break; case types::spare2: break; @@ -15004,7 +17011,8 @@ SRSASN_CODE dl_dcch_msg_type_c::c1_c_::pack(bit_ref& bref) const case types::rrc_conn_resume_r13: HANDLE_CODE(c.get().pack(bref)); break; - case types::spare3: + case types::dl_ded_msg_segment_r16: + HANDLE_CODE(c.get().pack(bref)); break; case types::spare2: break; @@ -15061,7 +17069,8 @@ SRSASN_CODE dl_dcch_msg_type_c::c1_c_::unpack(cbit_ref& bref) case types::rrc_conn_resume_r13: HANDLE_CODE(c.get().unpack(bref)); break; - case types::spare3: + case types::dl_ded_msg_segment_r16: + HANDLE_CODE(c.get().unpack(bref)); break; case types::spare2: break; diff --git a/lib/src/asn1/rrc/ho_cmd.cc b/lib/src/asn1/rrc/ho_cmd.cc index 7dd1a05cf0..c437e1095c 100644 --- a/lib/src/asn1/rrc/ho_cmd.cc +++ b/lib/src/asn1/rrc/ho_cmd.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -267,6 +267,27 @@ void as_cfg_nr_v1570_s::to_json(json_writer& j) const j.end_obj(); } +// AS-ConfigNR-v1620 ::= SEQUENCE +SRSASN_CODE as_cfg_nr_v1620_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(tdm_pattern_cfg2_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE as_cfg_nr_v1620_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(tdm_pattern_cfg2_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void as_cfg_nr_v1620_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("tdm-PatternConfig2-r16"); + tdm_pattern_cfg2_r16.to_json(j); + j.end_obj(); +} + // SCG-Config-r12 ::= SEQUENCE SRSASN_CODE scg_cfg_r12_s::pack(bit_ref& bref) const { @@ -493,6 +514,7 @@ SRSASN_CODE as_cfg_s::pack(bit_ref& bref) const group_flags[3] |= as_cfg_nr_r15.is_present(); group_flags[4] |= as_cfg_v1550.is_present(); group_flags[5] |= as_cfg_nr_v1570.is_present(); + group_flags[6] |= as_cfg_nr_v1620.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -544,6 +566,14 @@ SRSASN_CODE as_cfg_s::pack(bit_ref& bref) const HANDLE_CODE(as_cfg_nr_v1570->pack(bref)); } } + if (group_flags[6]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(as_cfg_nr_v1620.is_present(), 1)); + if (as_cfg_nr_v1620.is_present()) { + HANDLE_CODE(as_cfg_nr_v1620->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -561,7 +591,7 @@ SRSASN_CODE as_cfg_s::unpack(cbit_ref& bref) HANDLE_CODE(unpack_integer(source_dl_carrier_freq, bref, (uint32_t)0u, (uint32_t)65535u)); if (ext) { - ext_groups_unpacker_guard group_flags(6); + ext_groups_unpacker_guard group_flags(7); group_flags.unpack(bref); if (group_flags[0]) { @@ -623,6 +653,16 @@ SRSASN_CODE as_cfg_s::unpack(cbit_ref& bref) HANDLE_CODE(as_cfg_nr_v1570->unpack(bref)); } } + if (group_flags[6]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool as_cfg_nr_v1620_present; + HANDLE_CODE(bref.unpack(as_cfg_nr_v1620_present, 1)); + as_cfg_nr_v1620.set_present(as_cfg_nr_v1620_present); + if (as_cfg_nr_v1620.is_present()) { + HANDLE_CODE(as_cfg_nr_v1620->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -674,6 +714,10 @@ void as_cfg_s::to_json(json_writer& j) const j.write_fieldname("as-ConfigNR-v1570"); as_cfg_nr_v1570->to_json(j); } + if (as_cfg_nr_v1620.is_present()) { + j.write_fieldname("as-ConfigNR-v1620"); + as_cfg_nr_v1620->to_json(j); + } } j.end_obj(); } @@ -1066,7 +1110,7 @@ SRSASN_CODE as_context_v1130_s::pack(bit_ref& bref) const bref.pack(ext, 1); HANDLE_CODE(bref.pack(idc_ind_r11_present, 1)); HANDLE_CODE(bref.pack(mbms_interest_ind_r11_present, 1)); - HANDLE_CODE(bref.pack(pwr_pref_ind_r11_present, 1)); + HANDLE_CODE(bref.pack(ue_assist_info_r11_present, 1)); if (idc_ind_r11_present) { HANDLE_CODE(idc_ind_r11.pack(bref)); @@ -1074,8 +1118,8 @@ SRSASN_CODE as_context_v1130_s::pack(bit_ref& bref) const if (mbms_interest_ind_r11_present) { HANDLE_CODE(mbms_interest_ind_r11.pack(bref)); } - if (pwr_pref_ind_r11_present) { - HANDLE_CODE(pwr_pref_ind_r11.pack(bref)); + if (ue_assist_info_r11_present) { + HANDLE_CODE(ue_assist_info_r11.pack(bref)); } if (ext) { @@ -1117,7 +1161,7 @@ SRSASN_CODE as_context_v1130_s::unpack(cbit_ref& bref) bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(idc_ind_r11_present, 1)); HANDLE_CODE(bref.unpack(mbms_interest_ind_r11_present, 1)); - HANDLE_CODE(bref.unpack(pwr_pref_ind_r11_present, 1)); + HANDLE_CODE(bref.unpack(ue_assist_info_r11_present, 1)); if (idc_ind_r11_present) { HANDLE_CODE(idc_ind_r11.unpack(bref)); @@ -1125,8 +1169,8 @@ SRSASN_CODE as_context_v1130_s::unpack(cbit_ref& bref) if (mbms_interest_ind_r11_present) { HANDLE_CODE(mbms_interest_ind_r11.unpack(bref)); } - if (pwr_pref_ind_r11_present) { - HANDLE_CODE(pwr_pref_ind_r11.unpack(bref)); + if (ue_assist_info_r11_present) { + HANDLE_CODE(ue_assist_info_r11.unpack(bref)); } if (ext) { @@ -1169,8 +1213,8 @@ void as_context_v1130_s::to_json(json_writer& j) const if (mbms_interest_ind_r11_present) { j.write_str("mbmsInterestIndication-r11", mbms_interest_ind_r11.to_string()); } - if (pwr_pref_ind_r11_present) { - j.write_str("powerPrefIndication-r11", pwr_pref_ind_r11.to_string()); + if (ue_assist_info_r11_present) { + j.write_str("ueAssistanceInformation-r11", ue_assist_info_r11.to_string()); } if (ext) { if (sidelink_ue_info_r12_present) { @@ -1216,6 +1260,162 @@ void as_context_v1320_s::to_json(json_writer& j) const j.end_obj(); } +// ConfigRestrictInfoDAPS-r16 ::= SEQUENCE +SRSASN_CODE cfg_restrict_info_daps_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(max_sch_tb_bits_dl_r16_present, 1)); + HANDLE_CODE(bref.pack(max_sch_tb_bits_ul_r16_present, 1)); + + if (max_sch_tb_bits_dl_r16_present) { + HANDLE_CODE(pack_integer(bref, max_sch_tb_bits_dl_r16, (uint8_t)1u, (uint8_t)100u)); + } + if (max_sch_tb_bits_ul_r16_present) { + HANDLE_CODE(pack_integer(bref, max_sch_tb_bits_ul_r16, (uint8_t)1u, (uint8_t)100u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE cfg_restrict_info_daps_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(max_sch_tb_bits_dl_r16_present, 1)); + HANDLE_CODE(bref.unpack(max_sch_tb_bits_ul_r16_present, 1)); + + if (max_sch_tb_bits_dl_r16_present) { + HANDLE_CODE(unpack_integer(max_sch_tb_bits_dl_r16, bref, (uint8_t)1u, (uint8_t)100u)); + } + if (max_sch_tb_bits_ul_r16_present) { + HANDLE_CODE(unpack_integer(max_sch_tb_bits_ul_r16, bref, (uint8_t)1u, (uint8_t)100u)); + } + + return SRSASN_SUCCESS; +} +void cfg_restrict_info_daps_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (max_sch_tb_bits_dl_r16_present) { + j.write_int("maxSCH-TB-BitsDL-r16", max_sch_tb_bits_dl_r16); + } + if (max_sch_tb_bits_ul_r16_present) { + j.write_int("maxSCH-TB-BitsUL-r16", max_sch_tb_bits_ul_r16); + } + j.end_obj(); +} + +// AS-Context-v1610 ::= SEQUENCE +SRSASN_CODE as_context_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(sidelink_ue_info_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(ue_assist_info_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(cfg_restrict_info_daps_r16_present, 1)); + + if (sidelink_ue_info_nr_r16_present) { + HANDLE_CODE(sidelink_ue_info_nr_r16.pack(bref)); + } + if (ue_assist_info_nr_r16_present) { + HANDLE_CODE(ue_assist_info_nr_r16.pack(bref)); + } + if (cfg_restrict_info_daps_r16_present) { + HANDLE_CODE(cfg_restrict_info_daps_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE as_context_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(sidelink_ue_info_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(ue_assist_info_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(cfg_restrict_info_daps_r16_present, 1)); + + if (sidelink_ue_info_nr_r16_present) { + HANDLE_CODE(sidelink_ue_info_nr_r16.unpack(bref)); + } + if (ue_assist_info_nr_r16_present) { + HANDLE_CODE(ue_assist_info_nr_r16.unpack(bref)); + } + if (cfg_restrict_info_daps_r16_present) { + HANDLE_CODE(cfg_restrict_info_daps_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void as_context_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (sidelink_ue_info_nr_r16_present) { + j.write_str("sidelinkUEInformationNR-r16", sidelink_ue_info_nr_r16.to_string()); + } + if (ue_assist_info_nr_r16_present) { + j.write_str("ueAssistanceInformationNR-r16", ue_assist_info_nr_r16.to_string()); + } + if (cfg_restrict_info_daps_r16_present) { + j.write_fieldname("configRestrictInfoDAPS-r16"); + cfg_restrict_info_daps_r16.to_json(j); + } + j.end_obj(); +} + +// ConfigRestrictInfoDAPS-v1630 ::= SEQUENCE +SRSASN_CODE cfg_restrict_info_daps_v1630_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(daps_pwr_coordination_info_r16_present, 1)); + + if (daps_pwr_coordination_info_r16_present) { + HANDLE_CODE(daps_pwr_coordination_info_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE cfg_restrict_info_daps_v1630_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(daps_pwr_coordination_info_r16_present, 1)); + + if (daps_pwr_coordination_info_r16_present) { + HANDLE_CODE(daps_pwr_coordination_info_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void cfg_restrict_info_daps_v1630_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (daps_pwr_coordination_info_r16_present) { + j.write_fieldname("daps-PowerCoordinationInfo-r16"); + daps_pwr_coordination_info_r16.to_json(j); + } + j.end_obj(); +} + +// AS-Context-v1630 ::= SEQUENCE +SRSASN_CODE as_context_v1630_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(cfg_restrict_info_daps_v1630_present, 1)); + + if (cfg_restrict_info_daps_v1630_present) { + HANDLE_CODE(cfg_restrict_info_daps_v1630.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE as_context_v1630_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(cfg_restrict_info_daps_v1630_present, 1)); + + if (cfg_restrict_info_daps_v1630_present) { + HANDLE_CODE(cfg_restrict_info_daps_v1630.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void as_context_v1630_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (cfg_restrict_info_daps_v1630_present) { + j.write_fieldname("configRestrictInfoDAPS-v1630"); + cfg_restrict_info_daps_v1630.to_json(j); + } + j.end_obj(); +} + // CandidateCellInfo-r10 ::= SEQUENCE SRSASN_CODE candidate_cell_info_r10_s::pack(bit_ref& bref) const { @@ -1569,6 +1769,225 @@ SRSASN_CODE ho_cmd_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +// AS-Config-v1700 ::= SEQUENCE +SRSASN_CODE as_cfg_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(scg_state_r17_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE as_cfg_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(scg_state_r17_present, 1)); + + return SRSASN_SUCCESS; +} +void as_cfg_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (scg_state_r17_present) { + j.write_str("scg-State-r17", "deactivated"); + } + j.end_obj(); +} + +// HandoverPreparationInformation-v1700-IEs ::= SEQUENCE +SRSASN_CODE ho_prep_info_v1700_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(as_cfg_v1700_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (as_cfg_v1700_present) { + HANDLE_CODE(as_cfg_v1700.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ho_prep_info_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(as_cfg_v1700_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (as_cfg_v1700_present) { + HANDLE_CODE(as_cfg_v1700.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ho_prep_info_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (as_cfg_v1700_present) { + j.write_fieldname("as-Config-v1700"); + as_cfg_v1700.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// AS-Context-v1620 ::= SEQUENCE +SRSASN_CODE as_context_v1620_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ue_assist_info_nr_scg_r16_present, 1)); + + if (ue_assist_info_nr_scg_r16_present) { + HANDLE_CODE(ue_assist_info_nr_scg_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE as_context_v1620_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ue_assist_info_nr_scg_r16_present, 1)); + + if (ue_assist_info_nr_scg_r16_present) { + HANDLE_CODE(ue_assist_info_nr_scg_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void as_context_v1620_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ue_assist_info_nr_scg_r16_present) { + j.write_str("ueAssistanceInformationNR-SCG-r16", ue_assist_info_nr_scg_r16.to_string()); + } + j.end_obj(); +} + +// HandoverPreparationInformation-v1630-IEs ::= SEQUENCE +SRSASN_CODE ho_prep_info_v1630_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(as_context_v1630_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (as_context_v1630_present) { + HANDLE_CODE(as_context_v1630.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ho_prep_info_v1630_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(as_context_v1630_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (as_context_v1630_present) { + HANDLE_CODE(as_context_v1630.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ho_prep_info_v1630_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (as_context_v1630_present) { + j.write_fieldname("as-Context-v1630"); + as_context_v1630.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// HandoverPreparationInformation-v1620-IEs ::= SEQUENCE +SRSASN_CODE ho_prep_info_v1620_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(as_context_v1620_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (as_context_v1620_present) { + HANDLE_CODE(as_context_v1620.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ho_prep_info_v1620_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(as_context_v1620_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (as_context_v1620_present) { + HANDLE_CODE(as_context_v1620.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ho_prep_info_v1620_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (as_context_v1620_present) { + j.write_fieldname("as-Context-v1620"); + as_context_v1620.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// HandoverPreparationInformation-v1610-IEs ::= SEQUENCE +SRSASN_CODE ho_prep_info_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(as_context_v1610_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (as_context_v1610_present) { + HANDLE_CODE(as_context_v1610.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ho_prep_info_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(as_context_v1610_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (as_context_v1610_present) { + HANDLE_CODE(as_context_v1610.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ho_prep_info_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (as_context_v1610_present) { + j.write_fieldname("as-Context-v1610"); + as_context_v1610.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + // HandoverPreparationInformation-v1540-IEs ::= SEQUENCE SRSASN_CODE ho_prep_info_v1540_ies_s::pack(bit_ref& bref) const { @@ -1578,6 +1997,9 @@ SRSASN_CODE ho_prep_info_v1540_ies_s::pack(bit_ref& bref) const if (source_rb_cfg_intra5_gc_r15_present) { HANDLE_CODE(source_rb_cfg_intra5_gc_r15.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -1589,6 +2011,9 @@ SRSASN_CODE ho_prep_info_v1540_ies_s::unpack(cbit_ref& bref) if (source_rb_cfg_intra5_gc_r15_present) { HANDLE_CODE(source_rb_cfg_intra5_gc_r15.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -1600,8 +2025,7 @@ void ho_prep_info_v1540_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -1979,8 +2403,8 @@ void ho_prep_info_v920_ies_s::to_json(json_writer& j) const const char* ho_prep_info_v920_ies_s::ue_cfg_release_r9_opts::to_string() const { static const char* options[] = { - "rel9", "rel10", "rel11", "rel12", "v10j0", "v11e0", "v1280", "rel13", "rel14", "rel15"}; - return convert_enum_idx(options, 10, value, "ho_prep_info_v920_ies_s::ue_cfg_release_r9_e_"); + "rel9", "rel10", "rel11", "rel12", "v10j0", "v11e0", "v1280", "rel13", "rel14", "rel15", "rel16", "rel17"}; + return convert_enum_idx(options, 12, value, "ho_prep_info_v920_ies_s::ue_cfg_release_r9_e_"); } // RRM-Config ::= SEQUENCE diff --git a/lib/src/asn1/rrc/meascfg.cc b/lib/src/asn1/rrc/meascfg.cc index 3a888c12bc..dc8eb7ed46 100644 --- a/lib/src/asn1/rrc/meascfg.cc +++ b/lib/src/asn1/rrc/meascfg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -45,6 +45,18 @@ int8_t q_offset_range_opts::to_number() const return map_enum_number(options, 31, value, "q_offset_range_e"); } +// RSS-MeasPowerBias-r16 ::= ENUMERATED +const char* rss_meas_pwr_bias_r16_opts::to_string() const +{ + static const char* options[] = {"dB-6", "dB-3", "dB0", "dB3", "dB6", "dB9", "dB12", "rssNotUsed"}; + return convert_enum_idx(options, 8, value, "rss_meas_pwr_bias_r16_e"); +} +int8_t rss_meas_pwr_bias_r16_opts::to_number() const +{ + static const int8_t options[] = {-6, -3, 0, 3, 6, 9, 12}; + return map_enum_number(options, 7, value, "rss_meas_pwr_bias_r16_e"); +} + // SpeedStateScaleFactors ::= SEQUENCE SRSASN_CODE speed_state_scale_factors_s::pack(bit_ref& bref) const { @@ -112,456 +124,172 @@ uint16_t band_ind_geran_opts::to_number() const return map_enum_number(options, 2, value, "band_ind_geran_e"); } -// PreRegistrationInfoHRPD ::= SEQUENCE -SRSASN_CODE pre_regist_info_hrpd_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(bref.pack(pre_regist_zone_id_present, 1)); - HANDLE_CODE(bref.pack(secondary_pre_regist_zone_id_list_present, 1)); - - HANDLE_CODE(bref.pack(pre_regist_allowed, 1)); - if (pre_regist_zone_id_present) { - HANDLE_CODE(pack_integer(bref, pre_regist_zone_id, (uint16_t)0u, (uint16_t)255u)); - } - if (secondary_pre_regist_zone_id_list_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, secondary_pre_regist_zone_id_list, 1, 2, integer_packer(0, 255))); - } - - return SRSASN_SUCCESS; -} -SRSASN_CODE pre_regist_info_hrpd_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(bref.unpack(pre_regist_zone_id_present, 1)); - HANDLE_CODE(bref.unpack(secondary_pre_regist_zone_id_list_present, 1)); - - HANDLE_CODE(bref.unpack(pre_regist_allowed, 1)); - if (pre_regist_zone_id_present) { - HANDLE_CODE(unpack_integer(pre_regist_zone_id, bref, (uint16_t)0u, (uint16_t)255u)); - } - if (secondary_pre_regist_zone_id_list_present) { - HANDLE_CODE(unpack_dyn_seq_of(secondary_pre_regist_zone_id_list, bref, 1, 2, integer_packer(0, 255))); - } - - return SRSASN_SUCCESS; -} -void pre_regist_info_hrpd_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_bool("preRegistrationAllowed", pre_regist_allowed); - if (pre_regist_zone_id_present) { - j.write_int("preRegistrationZoneId", pre_regist_zone_id); - } - if (secondary_pre_regist_zone_id_list_present) { - j.start_array("secondaryPreRegistrationZoneIdList"); - for (const auto& e1 : secondary_pre_regist_zone_id_list) { - j.write_int(e1); - } - j.end_array(); - } - j.end_obj(); -} - -// CarrierFreqsGERAN ::= SEQUENCE -SRSASN_CODE carrier_freqs_geran_s::pack(bit_ref& bref) const +// MTC-SSB-NR-r15 ::= SEQUENCE +SRSASN_CODE mtc_ssb_nr_r15_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, start_arfcn, (uint16_t)0u, (uint16_t)1023u)); - HANDLE_CODE(band_ind.pack(bref)); - HANDLE_CODE(following_arfcns.pack(bref)); + HANDLE_CODE(periodicity_and_offset_r15.pack(bref)); + HANDLE_CODE(ssb_dur_r15.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE carrier_freqs_geran_s::unpack(cbit_ref& bref) +SRSASN_CODE mtc_ssb_nr_r15_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(start_arfcn, bref, (uint16_t)0u, (uint16_t)1023u)); - HANDLE_CODE(band_ind.unpack(bref)); - HANDLE_CODE(following_arfcns.unpack(bref)); + HANDLE_CODE(periodicity_and_offset_r15.unpack(bref)); + HANDLE_CODE(ssb_dur_r15.unpack(bref)); return SRSASN_SUCCESS; } -void carrier_freqs_geran_s::to_json(json_writer& j) const +void mtc_ssb_nr_r15_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("startingARFCN", start_arfcn); - j.write_str("bandIndicator", band_ind.to_string()); - j.write_fieldname("followingARFCNs"); - following_arfcns.to_json(j); + j.write_fieldname("periodicityAndOffset-r15"); + periodicity_and_offset_r15.to_json(j); + j.write_str("ssb-Duration-r15", ssb_dur_r15.to_string()); j.end_obj(); } -bool carrier_freqs_geran_s::operator==(const carrier_freqs_geran_s& other) const +bool mtc_ssb_nr_r15_s::operator==(const mtc_ssb_nr_r15_s& other) const { - return start_arfcn == other.start_arfcn and band_ind == other.band_ind and following_arfcns == other.following_arfcns; + return periodicity_and_offset_r15 == other.periodicity_and_offset_r15 and ssb_dur_r15 == other.ssb_dur_r15; } -void carrier_freqs_geran_s::following_arfcns_c_::destroy_() -{ - switch (type_) { - case types::explicit_list_of_arfcns: - c.destroy(); - break; - case types::equally_spaced_arfcns: - c.destroy(); - break; - case types::variable_bit_map_of_arfcns: - c.destroy >(); - break; - default: - break; - } -} -void carrier_freqs_geran_s::following_arfcns_c_::set(types::options e) +void mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::destroy_() {} +void mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set(types::options e) { destroy_(); type_ = e; - switch (type_) { - case types::explicit_list_of_arfcns: - c.init(); - break; - case types::equally_spaced_arfcns: - c.init(); - break; - case types::variable_bit_map_of_arfcns: - c.init >(); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); - } } -carrier_freqs_geran_s::following_arfcns_c_::following_arfcns_c_(const carrier_freqs_geran_s::following_arfcns_c_& other) +mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::periodicity_and_offset_r15_c_( + const mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_& other) { type_ = other.type(); switch (type_) { - case types::explicit_list_of_arfcns: - c.init(other.c.get()); + case types::sf5_r15: + c.init(other.c.get()); break; - case types::equally_spaced_arfcns: - c.init(other.c.get()); + case types::sf10_r15: + c.init(other.c.get()); break; - case types::variable_bit_map_of_arfcns: - c.init(other.c.get >()); + case types::sf20_r15: + c.init(other.c.get()); + break; + case types::sf40_r15: + c.init(other.c.get()); + break; + case types::sf80_r15: + c.init(other.c.get()); + break; + case types::sf160_r15: + c.init(other.c.get()); break; case types::nulltype: break; default: - log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); + log_invalid_choice_id(type_, "mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_"); } } -carrier_freqs_geran_s::following_arfcns_c_& -carrier_freqs_geran_s::following_arfcns_c_::operator=(const carrier_freqs_geran_s::following_arfcns_c_& other) +mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_& +mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::operator=(const mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_& other) { if (this == &other) { return *this; } set(other.type()); switch (type_) { - case types::explicit_list_of_arfcns: - c.set(other.c.get()); + case types::sf5_r15: + c.set(other.c.get()); break; - case types::equally_spaced_arfcns: - c.set(other.c.get()); + case types::sf10_r15: + c.set(other.c.get()); break; - case types::variable_bit_map_of_arfcns: - c.set(other.c.get >()); + case types::sf20_r15: + c.set(other.c.get()); + break; + case types::sf40_r15: + c.set(other.c.get()); + break; + case types::sf80_r15: + c.set(other.c.get()); + break; + case types::sf160_r15: + c.set(other.c.get()); break; case types::nulltype: break; default: - log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); + log_invalid_choice_id(type_, "mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_"); } return *this; } -explicit_list_of_arfcns_l& carrier_freqs_geran_s::following_arfcns_c_::set_explicit_list_of_arfcns() +uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf5_r15() { - set(types::explicit_list_of_arfcns); - return c.get(); + set(types::sf5_r15); + return c.get(); } -carrier_freqs_geran_s::following_arfcns_c_::equally_spaced_arfcns_s_& -carrier_freqs_geran_s::following_arfcns_c_::set_equally_spaced_arfcns() +uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf10_r15() { - set(types::equally_spaced_arfcns); - return c.get(); + set(types::sf10_r15); + return c.get(); } -bounded_octstring<1, 16>& carrier_freqs_geran_s::following_arfcns_c_::set_variable_bit_map_of_arfcns() +uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf20_r15() { - set(types::variable_bit_map_of_arfcns); - return c.get >(); + set(types::sf20_r15); + return c.get(); } -void carrier_freqs_geran_s::following_arfcns_c_::to_json(json_writer& j) const +uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf40_r15() +{ + set(types::sf40_r15); + return c.get(); +} +uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf80_r15() +{ + set(types::sf80_r15); + return c.get(); +} +uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf160_r15() +{ + set(types::sf160_r15); + return c.get(); +} +void mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::explicit_list_of_arfcns: - j.start_array("explicitListOfARFCNs"); - for (const auto& e1 : c.get()) { - j.write_int(e1); - } - j.end_array(); + case types::sf5_r15: + j.write_int("sf5-r15", c.get()); break; - case types::equally_spaced_arfcns: - j.write_fieldname("equallySpacedARFCNs"); - j.start_obj(); - j.write_int("arfcn-Spacing", c.get().arfcn_spacing); - j.write_int("numberOfFollowingARFCNs", c.get().nof_following_arfcns); - j.end_obj(); + case types::sf10_r15: + j.write_int("sf10-r15", c.get()); break; - case types::variable_bit_map_of_arfcns: - j.write_str("variableBitMapOfARFCNs", c.get >().to_string()); + case types::sf20_r15: + j.write_int("sf20-r15", c.get()); + break; + case types::sf40_r15: + j.write_int("sf40-r15", c.get()); + break; + case types::sf80_r15: + j.write_int("sf80-r15", c.get()); + break; + case types::sf160_r15: + j.write_int("sf160-r15", c.get()); break; default: - log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); + log_invalid_choice_id(type_, "mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_"); } j.end_obj(); } -SRSASN_CODE carrier_freqs_geran_s::following_arfcns_c_::pack(bit_ref& bref) const +SRSASN_CODE mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::explicit_list_of_arfcns: - HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 0, 31, integer_packer(0, 1023))); + case types::sf5_r15: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)4u)); break; - case types::equally_spaced_arfcns: - HANDLE_CODE(pack_integer(bref, c.get().arfcn_spacing, (uint8_t)1u, (uint8_t)8u)); - HANDLE_CODE( - pack_integer(bref, c.get().nof_following_arfcns, (uint8_t)0u, (uint8_t)31u)); + case types::sf10_r15: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)9u)); break; - case types::variable_bit_map_of_arfcns: - HANDLE_CODE((c.get >().pack(bref))); - break; - default: - log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); - return SRSASN_ERROR_ENCODE_FAIL; - } - return SRSASN_SUCCESS; -} -SRSASN_CODE carrier_freqs_geran_s::following_arfcns_c_::unpack(cbit_ref& bref) -{ - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::explicit_list_of_arfcns: - HANDLE_CODE( - unpack_dyn_seq_of(c.get(), bref, 0, 31, integer_packer(0, 1023))); - break; - case types::equally_spaced_arfcns: - HANDLE_CODE(unpack_integer(c.get().arfcn_spacing, bref, (uint8_t)1u, (uint8_t)8u)); - HANDLE_CODE( - unpack_integer(c.get().nof_following_arfcns, bref, (uint8_t)0u, (uint8_t)31u)); - break; - case types::variable_bit_map_of_arfcns: - HANDLE_CODE((c.get >().unpack(bref))); - break; - default: - log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; -} -bool carrier_freqs_geran_s::following_arfcns_c_::operator==(const following_arfcns_c_& other) const -{ - if (type_ != other.type_) { - return false; - } - switch (type_) { - case types::explicit_list_of_arfcns: - return c.get() == other.c.get(); - case types::equally_spaced_arfcns: - return c.get().arfcn_spacing == - other.c.get().arfcn_spacing and - c.get().nof_following_arfcns == - other.c.get().nof_following_arfcns; - case types::variable_bit_map_of_arfcns: - return c.get >() == other.c.get >(); - default: - return true; - } - return true; -} - -// CellReselectionSubPriority-r13 ::= ENUMERATED -const char* cell_resel_sub_prio_r13_opts::to_string() const -{ - static const char* options[] = {"oDot2", "oDot4", "oDot6", "oDot8"}; - return convert_enum_idx(options, 4, value, "cell_resel_sub_prio_r13_e"); -} -float cell_resel_sub_prio_r13_opts::to_number() const -{ - static const float options[] = {0.2, 0.4, 0.6, 0.8}; - return map_enum_number(options, 4, value, "cell_resel_sub_prio_r13_e"); -} -const char* cell_resel_sub_prio_r13_opts::to_number_string() const -{ - static const char* options[] = {"0.2", "0.4", "0.6", "0.8"}; - return convert_enum_idx(options, 4, value, "cell_resel_sub_prio_r13_e"); -} - -// MTC-SSB-NR-r15 ::= SEQUENCE -SRSASN_CODE mtc_ssb_nr_r15_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(periodicity_and_offset_r15.pack(bref)); - HANDLE_CODE(ssb_dur_r15.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE mtc_ssb_nr_r15_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(periodicity_and_offset_r15.unpack(bref)); - HANDLE_CODE(ssb_dur_r15.unpack(bref)); - - return SRSASN_SUCCESS; -} -void mtc_ssb_nr_r15_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("periodicityAndOffset-r15"); - periodicity_and_offset_r15.to_json(j); - j.write_str("ssb-Duration-r15", ssb_dur_r15.to_string()); - j.end_obj(); -} -bool mtc_ssb_nr_r15_s::operator==(const mtc_ssb_nr_r15_s& other) const -{ - return periodicity_and_offset_r15 == other.periodicity_and_offset_r15 and ssb_dur_r15 == other.ssb_dur_r15; -} - -void mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::destroy_() {} -void mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set(types::options e) -{ - destroy_(); - type_ = e; -} -mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::periodicity_and_offset_r15_c_( - const mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_& other) -{ - type_ = other.type(); - switch (type_) { - case types::sf5_r15: - c.init(other.c.get()); - break; - case types::sf10_r15: - c.init(other.c.get()); - break; - case types::sf20_r15: - c.init(other.c.get()); - break; - case types::sf40_r15: - c.init(other.c.get()); - break; - case types::sf80_r15: - c.init(other.c.get()); - break; - case types::sf160_r15: - c.init(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_"); - } -} -mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_& -mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::operator=(const mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_& other) -{ - if (this == &other) { - return *this; - } - set(other.type()); - switch (type_) { - case types::sf5_r15: - c.set(other.c.get()); - break; - case types::sf10_r15: - c.set(other.c.get()); - break; - case types::sf20_r15: - c.set(other.c.get()); - break; - case types::sf40_r15: - c.set(other.c.get()); - break; - case types::sf80_r15: - c.set(other.c.get()); - break; - case types::sf160_r15: - c.set(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_"); - } - - return *this; -} -uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf5_r15() -{ - set(types::sf5_r15); - return c.get(); -} -uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf10_r15() -{ - set(types::sf10_r15); - return c.get(); -} -uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf20_r15() -{ - set(types::sf20_r15); - return c.get(); -} -uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf40_r15() -{ - set(types::sf40_r15); - return c.get(); -} -uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf80_r15() -{ - set(types::sf80_r15); - return c.get(); -} -uint8_t& mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::set_sf160_r15() -{ - set(types::sf160_r15); - return c.get(); -} -void mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::to_json(json_writer& j) const -{ - j.start_obj(); - switch (type_) { - case types::sf5_r15: - j.write_int("sf5-r15", c.get()); - break; - case types::sf10_r15: - j.write_int("sf10-r15", c.get()); - break; - case types::sf20_r15: - j.write_int("sf20-r15", c.get()); - break; - case types::sf40_r15: - j.write_int("sf40-r15", c.get()); - break; - case types::sf80_r15: - j.write_int("sf80-r15", c.get()); - break; - case types::sf160_r15: - j.write_int("sf160-r15", c.get()); - break; - default: - log_invalid_choice_id(type_, "mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_"); - } - j.end_obj(); -} -SRSASN_CODE mtc_ssb_nr_r15_s::periodicity_and_offset_r15_c_::pack(bit_ref& bref) const -{ - type_.pack(bref); - switch (type_) { - case types::sf5_r15: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)4u)); - break; - case types::sf10_r15: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)9u)); - break; - case types::sf20_r15: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)19u)); + case types::sf20_r15: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)19u)); break; case types::sf40_r15: HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)39u)); @@ -643,25 +371,73 @@ uint8_t mtc_ssb_nr_r15_s::ssb_dur_r15_opts::to_number() const return map_enum_number(options, 5, value, "mtc_ssb_nr_r15_s::ssb_dur_r15_e_"); } -// SS-RSSI-Measurement-r15 ::= SEQUENCE -SRSASN_CODE ss_rssi_meas_r15_s::pack(bit_ref& bref) const +// PreRegistrationInfoHRPD ::= SEQUENCE +SRSASN_CODE pre_regist_info_hrpd_s::pack(bit_ref& bref) const { - HANDLE_CODE(meas_slots_r15.pack(bref)); - HANDLE_CODE(pack_integer(bref, end_symbol_r15, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(bref.pack(pre_regist_zone_id_present, 1)); + HANDLE_CODE(bref.pack(secondary_pre_regist_zone_id_list_present, 1)); - return SRSASN_SUCCESS; -} -SRSASN_CODE ss_rssi_meas_r15_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(meas_slots_r15.unpack(bref)); - HANDLE_CODE(unpack_integer(end_symbol_r15, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(bref.pack(pre_regist_allowed, 1)); + if (pre_regist_zone_id_present) { + HANDLE_CODE(pack_integer(bref, pre_regist_zone_id, (uint16_t)0u, (uint16_t)255u)); + } + if (secondary_pre_regist_zone_id_list_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, secondary_pre_regist_zone_id_list, 1, 2, integer_packer(0, 255))); + } return SRSASN_SUCCESS; } -void ss_rssi_meas_r15_s::to_json(json_writer& j) const +SRSASN_CODE pre_regist_info_hrpd_s::unpack(cbit_ref& bref) { - j.start_obj(); - j.write_str("measurementSlots-r15", meas_slots_r15.to_string()); + HANDLE_CODE(bref.unpack(pre_regist_zone_id_present, 1)); + HANDLE_CODE(bref.unpack(secondary_pre_regist_zone_id_list_present, 1)); + + HANDLE_CODE(bref.unpack(pre_regist_allowed, 1)); + if (pre_regist_zone_id_present) { + HANDLE_CODE(unpack_integer(pre_regist_zone_id, bref, (uint16_t)0u, (uint16_t)255u)); + } + if (secondary_pre_regist_zone_id_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(secondary_pre_regist_zone_id_list, bref, 1, 2, integer_packer(0, 255))); + } + + return SRSASN_SUCCESS; +} +void pre_regist_info_hrpd_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_bool("preRegistrationAllowed", pre_regist_allowed); + if (pre_regist_zone_id_present) { + j.write_int("preRegistrationZoneId", pre_regist_zone_id); + } + if (secondary_pre_regist_zone_id_list_present) { + j.start_array("secondaryPreRegistrationZoneIdList"); + for (const auto& e1 : secondary_pre_regist_zone_id_list) { + j.write_int(e1); + } + j.end_array(); + } + j.end_obj(); +} + +// SS-RSSI-Measurement-r15 ::= SEQUENCE +SRSASN_CODE ss_rssi_meas_r15_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(meas_slots_r15.pack(bref)); + HANDLE_CODE(pack_integer(bref, end_symbol_r15, (uint8_t)0u, (uint8_t)3u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ss_rssi_meas_r15_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(meas_slots_r15.unpack(bref)); + HANDLE_CODE(unpack_integer(end_symbol_r15, bref, (uint8_t)0u, (uint8_t)3u)); + + return SRSASN_SUCCESS; +} +void ss_rssi_meas_r15_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("measurementSlots-r15", meas_slots_r15.to_string()); j.write_int("endSymbol-r15", end_symbol_r15); j.end_obj(); } @@ -902,385 +678,1079 @@ bool thres_list_nr_r15_s::operator==(const thres_list_nr_r15_s& other) const (not nr_sinr_r15_present or nr_sinr_r15 == other.nr_sinr_r15); } -// MobilityStateParameters ::= SEQUENCE -SRSASN_CODE mob_state_params_s::pack(bit_ref& bref) const +// CarrierFreqsGERAN ::= SEQUENCE +SRSASN_CODE carrier_freqs_geran_s::pack(bit_ref& bref) const { - HANDLE_CODE(t_eval.pack(bref)); - HANDLE_CODE(t_hyst_normal.pack(bref)); - HANDLE_CODE(pack_integer(bref, n_cell_change_medium, (uint8_t)1u, (uint8_t)16u)); - HANDLE_CODE(pack_integer(bref, n_cell_change_high, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(pack_integer(bref, start_arfcn, (uint16_t)0u, (uint16_t)1023u)); + HANDLE_CODE(band_ind.pack(bref)); + HANDLE_CODE(following_arfcns.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE mob_state_params_s::unpack(cbit_ref& bref) +SRSASN_CODE carrier_freqs_geran_s::unpack(cbit_ref& bref) { - HANDLE_CODE(t_eval.unpack(bref)); - HANDLE_CODE(t_hyst_normal.unpack(bref)); - HANDLE_CODE(unpack_integer(n_cell_change_medium, bref, (uint8_t)1u, (uint8_t)16u)); - HANDLE_CODE(unpack_integer(n_cell_change_high, bref, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(unpack_integer(start_arfcn, bref, (uint16_t)0u, (uint16_t)1023u)); + HANDLE_CODE(band_ind.unpack(bref)); + HANDLE_CODE(following_arfcns.unpack(bref)); return SRSASN_SUCCESS; } -void mob_state_params_s::to_json(json_writer& j) const +void carrier_freqs_geran_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("t-Evaluation", t_eval.to_string()); - j.write_str("t-HystNormal", t_hyst_normal.to_string()); - j.write_int("n-CellChangeMedium", n_cell_change_medium); - j.write_int("n-CellChangeHigh", n_cell_change_high); + j.write_int("startingARFCN", start_arfcn); + j.write_str("bandIndicator", band_ind.to_string()); + j.write_fieldname("followingARFCNs"); + following_arfcns.to_json(j); j.end_obj(); } - -const char* mob_state_params_s::t_eval_opts::to_string() const -{ - static const char* options[] = {"s30", "s60", "s120", "s180", "s240", "spare3", "spare2", "spare1"}; - return convert_enum_idx(options, 8, value, "mob_state_params_s::t_eval_e_"); -} -uint8_t mob_state_params_s::t_eval_opts::to_number() const +bool carrier_freqs_geran_s::operator==(const carrier_freqs_geran_s& other) const { - static const uint8_t options[] = {30, 60, 120, 180, 240}; - return map_enum_number(options, 5, value, "mob_state_params_s::t_eval_e_"); + return start_arfcn == other.start_arfcn and band_ind == other.band_ind and following_arfcns == other.following_arfcns; } -const char* mob_state_params_s::t_hyst_normal_opts::to_string() const +void carrier_freqs_geran_s::following_arfcns_c_::destroy_() { - static const char* options[] = {"s30", "s60", "s120", "s180", "s240", "spare3", "spare2", "spare1"}; - return convert_enum_idx(options, 8, value, "mob_state_params_s::t_hyst_normal_e_"); + switch (type_) { + case types::explicit_list_of_arfcns: + c.destroy(); + break; + case types::equally_spaced_arfcns: + c.destroy(); + break; + case types::variable_bit_map_of_arfcns: + c.destroy >(); + break; + default: + break; + } } -uint8_t mob_state_params_s::t_hyst_normal_opts::to_number() const +void carrier_freqs_geran_s::following_arfcns_c_::set(types::options e) { - static const uint8_t options[] = {30, 60, 120, 180, 240}; - return map_enum_number(options, 5, value, "mob_state_params_s::t_hyst_normal_e_"); + destroy_(); + type_ = e; + switch (type_) { + case types::explicit_list_of_arfcns: + c.init(); + break; + case types::equally_spaced_arfcns: + c.init(); + break; + case types::variable_bit_map_of_arfcns: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); + } } - -// CarrierFreqCDMA2000 ::= SEQUENCE -SRSASN_CODE carrier_freq_cdma2000_s::pack(bit_ref& bref) const +carrier_freqs_geran_s::following_arfcns_c_::following_arfcns_c_(const carrier_freqs_geran_s::following_arfcns_c_& other) { - HANDLE_CODE(band_class.pack(bref)); - HANDLE_CODE(pack_integer(bref, arfcn, (uint16_t)0u, (uint16_t)2047u)); - - return SRSASN_SUCCESS; + type_ = other.type(); + switch (type_) { + case types::explicit_list_of_arfcns: + c.init(other.c.get()); + break; + case types::equally_spaced_arfcns: + c.init(other.c.get()); + break; + case types::variable_bit_map_of_arfcns: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); + } } -SRSASN_CODE carrier_freq_cdma2000_s::unpack(cbit_ref& bref) +carrier_freqs_geran_s::following_arfcns_c_& +carrier_freqs_geran_s::following_arfcns_c_::operator=(const carrier_freqs_geran_s::following_arfcns_c_& other) { - HANDLE_CODE(band_class.unpack(bref)); - HANDLE_CODE(unpack_integer(arfcn, bref, (uint16_t)0u, (uint16_t)2047u)); + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::explicit_list_of_arfcns: + c.set(other.c.get()); + break; + case types::equally_spaced_arfcns: + c.set(other.c.get()); + break; + case types::variable_bit_map_of_arfcns: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); + } - return SRSASN_SUCCESS; -} -void carrier_freq_cdma2000_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_str("bandClass", band_class.to_string()); - j.write_int("arfcn", arfcn); - j.end_obj(); + return *this; } -bool carrier_freq_cdma2000_s::operator==(const carrier_freq_cdma2000_s& other) const +explicit_list_of_arfcns_l& carrier_freqs_geran_s::following_arfcns_c_::set_explicit_list_of_arfcns() { - return band_class == other.band_class and arfcn == other.arfcn; + set(types::explicit_list_of_arfcns); + return c.get(); } - -// MeasCSI-RS-Config-r12 ::= SEQUENCE -SRSASN_CODE meas_csi_rs_cfg_r12_s::pack(bit_ref& bref) const +carrier_freqs_geran_s::following_arfcns_c_::equally_spaced_arfcns_s_& +carrier_freqs_geran_s::following_arfcns_c_::set_equally_spaced_arfcns() { - bref.pack(ext, 1); - HANDLE_CODE(pack_integer(bref, meas_csi_rs_id_r12, (uint8_t)1u, (uint8_t)96u)); - HANDLE_CODE(pack_integer(bref, pci_r12, (uint16_t)0u, (uint16_t)503u)); - HANDLE_CODE(pack_integer(bref, scrambling_id_r12, (uint16_t)0u, (uint16_t)503u)); - HANDLE_CODE(pack_integer(bref, res_cfg_r12, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(pack_integer(bref, sf_offset_r12, (uint8_t)0u, (uint8_t)4u)); - HANDLE_CODE(csi_rs_individual_offset_r12.pack(bref)); - - return SRSASN_SUCCESS; + set(types::equally_spaced_arfcns); + return c.get(); } -SRSASN_CODE meas_csi_rs_cfg_r12_s::unpack(cbit_ref& bref) +bounded_octstring<1, 16>& carrier_freqs_geran_s::following_arfcns_c_::set_variable_bit_map_of_arfcns() { - bref.unpack(ext, 1); - HANDLE_CODE(unpack_integer(meas_csi_rs_id_r12, bref, (uint8_t)1u, (uint8_t)96u)); - HANDLE_CODE(unpack_integer(pci_r12, bref, (uint16_t)0u, (uint16_t)503u)); - HANDLE_CODE(unpack_integer(scrambling_id_r12, bref, (uint16_t)0u, (uint16_t)503u)); - HANDLE_CODE(unpack_integer(res_cfg_r12, bref, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(unpack_integer(sf_offset_r12, bref, (uint8_t)0u, (uint8_t)4u)); - HANDLE_CODE(csi_rs_individual_offset_r12.unpack(bref)); - - return SRSASN_SUCCESS; + set(types::variable_bit_map_of_arfcns); + return c.get >(); } -void meas_csi_rs_cfg_r12_s::to_json(json_writer& j) const +void carrier_freqs_geran_s::following_arfcns_c_::to_json(json_writer& j) const { j.start_obj(); - j.write_int("measCSI-RS-Id-r12", meas_csi_rs_id_r12); - j.write_int("physCellId-r12", pci_r12); - j.write_int("scramblingIdentity-r12", scrambling_id_r12); - j.write_int("resourceConfig-r12", res_cfg_r12); - j.write_int("subframeOffset-r12", sf_offset_r12); - j.write_str("csi-RS-IndividualOffset-r12", csi_rs_individual_offset_r12.to_string()); + switch (type_) { + case types::explicit_list_of_arfcns: + j.start_array("explicitListOfARFCNs"); + for (const auto& e1 : c.get()) { + j.write_int(e1); + } + j.end_array(); + break; + case types::equally_spaced_arfcns: + j.write_fieldname("equallySpacedARFCNs"); + j.start_obj(); + j.write_int("arfcn-Spacing", c.get().arfcn_spacing); + j.write_int("numberOfFollowingARFCNs", c.get().nof_following_arfcns); + j.end_obj(); + break; + case types::variable_bit_map_of_arfcns: + j.write_str("variableBitMapOfARFCNs", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); + } j.end_obj(); } -bool meas_csi_rs_cfg_r12_s::operator==(const meas_csi_rs_cfg_r12_s& other) const +SRSASN_CODE carrier_freqs_geran_s::following_arfcns_c_::pack(bit_ref& bref) const { - return ext == other.ext and meas_csi_rs_id_r12 == other.meas_csi_rs_id_r12 and pci_r12 == other.pci_r12 and - scrambling_id_r12 == other.scrambling_id_r12 and res_cfg_r12 == other.res_cfg_r12 and - sf_offset_r12 == other.sf_offset_r12 and csi_rs_individual_offset_r12 == other.csi_rs_individual_offset_r12; -} - -// PhysCellIdRangeUTRA-FDD-r9 ::= SEQUENCE -SRSASN_CODE pci_range_utra_fdd_r9_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(bref.pack(range_r9_present, 1)); - - HANDLE_CODE(pack_integer(bref, start_r9, (uint16_t)0u, (uint16_t)511u)); - if (range_r9_present) { - HANDLE_CODE(pack_integer(bref, range_r9, (uint16_t)2u, (uint16_t)512u)); + type_.pack(bref); + switch (type_) { + case types::explicit_list_of_arfcns: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 0, 31, integer_packer(0, 1023))); + break; + case types::equally_spaced_arfcns: + HANDLE_CODE(pack_integer(bref, c.get().arfcn_spacing, (uint8_t)1u, (uint8_t)8u)); + HANDLE_CODE( + pack_integer(bref, c.get().nof_following_arfcns, (uint8_t)0u, (uint8_t)31u)); + break; + case types::variable_bit_map_of_arfcns: + HANDLE_CODE((c.get >().pack(bref))); + break; + default: + log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); + return SRSASN_ERROR_ENCODE_FAIL; } - return SRSASN_SUCCESS; } -SRSASN_CODE pci_range_utra_fdd_r9_s::unpack(cbit_ref& bref) +SRSASN_CODE carrier_freqs_geran_s::following_arfcns_c_::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(range_r9_present, 1)); - - HANDLE_CODE(unpack_integer(start_r9, bref, (uint16_t)0u, (uint16_t)511u)); - if (range_r9_present) { - HANDLE_CODE(unpack_integer(range_r9, bref, (uint16_t)2u, (uint16_t)512u)); + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::explicit_list_of_arfcns: + HANDLE_CODE( + unpack_dyn_seq_of(c.get(), bref, 0, 31, integer_packer(0, 1023))); + break; + case types::equally_spaced_arfcns: + HANDLE_CODE(unpack_integer(c.get().arfcn_spacing, bref, (uint8_t)1u, (uint8_t)8u)); + HANDLE_CODE( + unpack_integer(c.get().nof_following_arfcns, bref, (uint8_t)0u, (uint8_t)31u)); + break; + case types::variable_bit_map_of_arfcns: + HANDLE_CODE((c.get >().unpack(bref))); + break; + default: + log_invalid_choice_id(type_, "carrier_freqs_geran_s::following_arfcns_c_"); + return SRSASN_ERROR_DECODE_FAIL; } - return SRSASN_SUCCESS; } -void pci_range_utra_fdd_r9_s::to_json(json_writer& j) const +bool carrier_freqs_geran_s::following_arfcns_c_::operator==(const following_arfcns_c_& other) const { - j.start_obj(); - j.write_int("start-r9", start_r9); - if (range_r9_present) { - j.write_int("range-r9", range_r9); + if (type_ != other.type_) { + return false; } - j.end_obj(); -} -bool pci_range_utra_fdd_r9_s::operator==(const pci_range_utra_fdd_r9_s& other) const -{ - return start_r9 == other.start_r9 and range_r9_present == other.range_r9_present and - (not range_r9_present or range_r9 == other.range_r9); + switch (type_) { + case types::explicit_list_of_arfcns: + return c.get() == other.c.get(); + case types::equally_spaced_arfcns: + return c.get().arfcn_spacing == + other.c.get().arfcn_spacing and + c.get().nof_following_arfcns == + other.c.get().nof_following_arfcns; + case types::variable_bit_map_of_arfcns: + return c.get >() == other.c.get >(); + default: + return true; + } + return true; } -// AltTTT-CellsToAddMod-r12 ::= SEQUENCE -SRSASN_CODE alt_ttt_cells_to_add_mod_r12_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, cell_idx_r12, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(pci_range_r12.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE alt_ttt_cells_to_add_mod_r12_s::unpack(cbit_ref& bref) +// CellReselectionSubPriority-r13 ::= ENUMERATED +const char* cell_resel_sub_prio_r13_opts::to_string() const { - HANDLE_CODE(unpack_integer(cell_idx_r12, bref, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(pci_range_r12.unpack(bref)); - - return SRSASN_SUCCESS; + static const char* options[] = {"oDot2", "oDot4", "oDot6", "oDot8"}; + return convert_enum_idx(options, 4, value, "cell_resel_sub_prio_r13_e"); } -void alt_ttt_cells_to_add_mod_r12_s::to_json(json_writer& j) const +float cell_resel_sub_prio_r13_opts::to_number() const { - j.start_obj(); - j.write_int("cellIndex-r12", cell_idx_r12); - j.write_fieldname("physCellIdRange-r12"); - pci_range_r12.to_json(j); - j.end_obj(); + static const float options[] = {0.2, 0.4, 0.6, 0.8}; + return map_enum_number(options, 4, value, "cell_resel_sub_prio_r13_e"); } -bool alt_ttt_cells_to_add_mod_r12_s::operator==(const alt_ttt_cells_to_add_mod_r12_s& other) const +const char* cell_resel_sub_prio_r13_opts::to_number_string() const { - return cell_idx_r12 == other.cell_idx_r12 and pci_range_r12 == other.pci_range_r12; + static const char* options[] = {"0.2", "0.4", "0.6", "0.8"}; + return convert_enum_idx(options, 4, value, "cell_resel_sub_prio_r13_e"); } -// BlackCellsToAddMod ::= SEQUENCE -SRSASN_CODE black_cells_to_add_mod_s::pack(bit_ref& bref) const +// RSS-ConfigCarrierInfo-r16 ::= SEQUENCE +SRSASN_CODE rss_cfg_carrier_info_r16_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, cell_idx, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(pci_range.pack(bref)); + HANDLE_CODE(nb_idx_r16.pack(bref)); + HANDLE_CODE(time_offset_granularity_r16.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE black_cells_to_add_mod_s::unpack(cbit_ref& bref) +SRSASN_CODE rss_cfg_carrier_info_r16_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(cell_idx, bref, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(pci_range.unpack(bref)); + HANDLE_CODE(nb_idx_r16.unpack(bref)); + HANDLE_CODE(time_offset_granularity_r16.unpack(bref)); return SRSASN_SUCCESS; } -void black_cells_to_add_mod_s::to_json(json_writer& j) const +void rss_cfg_carrier_info_r16_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("cellIndex", cell_idx); - j.write_fieldname("physCellIdRange"); - pci_range.to_json(j); + j.write_str("narrowbandIndex-r16", nb_idx_r16.to_string()); + j.write_str("timeOffsetGranularity-r16", time_offset_granularity_r16.to_string()); j.end_obj(); } -bool black_cells_to_add_mod_s::operator==(const black_cells_to_add_mod_s& other) const +bool rss_cfg_carrier_info_r16_s::operator==(const rss_cfg_carrier_info_r16_s& other) const { - return cell_idx == other.cell_idx and pci_range == other.pci_range; + return nb_idx_r16 == other.nb_idx_r16 and time_offset_granularity_r16 == other.time_offset_granularity_r16; } -// CellsToAddMod ::= SEQUENCE -SRSASN_CODE cells_to_add_mod_s::pack(bit_ref& bref) const +const char* rss_cfg_carrier_info_r16_s::time_offset_granularity_r16_opts::to_string() const { - HANDLE_CODE(pack_integer(bref, cell_idx, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(pack_integer(bref, pci, (uint16_t)0u, (uint16_t)503u)); - HANDLE_CODE(cell_individual_offset.pack(bref)); - - return SRSASN_SUCCESS; + static const char* options[] = {"g1", "g2", "g4", "g8", "g16", "g32", "g64", "g128"}; + return convert_enum_idx(options, 8, value, "rss_cfg_carrier_info_r16_s::time_offset_granularity_r16_e_"); } -SRSASN_CODE cells_to_add_mod_s::unpack(cbit_ref& bref) +uint8_t rss_cfg_carrier_info_r16_s::time_offset_granularity_r16_opts::to_number() const { - HANDLE_CODE(unpack_integer(cell_idx, bref, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(unpack_integer(pci, bref, (uint16_t)0u, (uint16_t)503u)); - HANDLE_CODE(cell_individual_offset.unpack(bref)); + static const uint8_t options[] = {1, 2, 4, 8, 16, 32, 64, 128}; + return map_enum_number(options, 8, value, "rss_cfg_carrier_info_r16_s::time_offset_granularity_r16_e_"); +} - return SRSASN_SUCCESS; +// SSB-PositionQCL-RelationNR-r16 ::= ENUMERATED +const char* ssb_position_qcl_relation_nr_r16_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n4", "n8"}; + return convert_enum_idx(options, 4, value, "ssb_position_qcl_relation_nr_r16_e"); } -void cells_to_add_mod_s::to_json(json_writer& j) const +uint8_t ssb_position_qcl_relation_nr_r16_opts::to_number() const { - j.start_obj(); - j.write_int("cellIndex", cell_idx); - j.write_int("physCellId", pci); - j.write_str("cellIndividualOffset", cell_individual_offset.to_string()); - j.end_obj(); + static const uint8_t options[] = {1, 2, 4, 8}; + return map_enum_number(options, 4, value, "ssb_position_qcl_relation_nr_r16_e"); } -bool cells_to_add_mod_s::operator==(const cells_to_add_mod_s& other) const + +// SSB-PositionQCL-RelationNR-r17 ::= ENUMERATED +const char* ssb_position_qcl_relation_nr_r17_opts::to_string() const { - return cell_idx == other.cell_idx and pci == other.pci and cell_individual_offset == other.cell_individual_offset; + static const char* options[] = {"n32", "n64"}; + return convert_enum_idx(options, 2, value, "ssb_position_qcl_relation_nr_r17_e"); +} +uint8_t ssb_position_qcl_relation_nr_r17_opts::to_number() const +{ + static const uint8_t options[] = {32, 64}; + return map_enum_number(options, 2, value, "ssb_position_qcl_relation_nr_r17_e"); } -// CellsToAddModCDMA2000 ::= SEQUENCE -SRSASN_CODE cells_to_add_mod_cdma2000_s::pack(bit_ref& bref) const +// MobilityStateParameters ::= SEQUENCE +SRSASN_CODE mob_state_params_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, cell_idx, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(pack_integer(bref, pci, (uint16_t)0u, (uint16_t)511u)); + HANDLE_CODE(t_eval.pack(bref)); + HANDLE_CODE(t_hyst_normal.pack(bref)); + HANDLE_CODE(pack_integer(bref, n_cell_change_medium, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(pack_integer(bref, n_cell_change_high, (uint8_t)1u, (uint8_t)16u)); return SRSASN_SUCCESS; } -SRSASN_CODE cells_to_add_mod_cdma2000_s::unpack(cbit_ref& bref) +SRSASN_CODE mob_state_params_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(cell_idx, bref, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(unpack_integer(pci, bref, (uint16_t)0u, (uint16_t)511u)); + HANDLE_CODE(t_eval.unpack(bref)); + HANDLE_CODE(t_hyst_normal.unpack(bref)); + HANDLE_CODE(unpack_integer(n_cell_change_medium, bref, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(unpack_integer(n_cell_change_high, bref, (uint8_t)1u, (uint8_t)16u)); return SRSASN_SUCCESS; } -void cells_to_add_mod_cdma2000_s::to_json(json_writer& j) const +void mob_state_params_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("cellIndex", cell_idx); - j.write_int("physCellId", pci); + j.write_str("t-Evaluation", t_eval.to_string()); + j.write_str("t-HystNormal", t_hyst_normal.to_string()); + j.write_int("n-CellChangeMedium", n_cell_change_medium); + j.write_int("n-CellChangeHigh", n_cell_change_high); j.end_obj(); } -bool cells_to_add_mod_cdma2000_s::operator==(const cells_to_add_mod_cdma2000_s& other) const -{ - return cell_idx == other.cell_idx and pci == other.pci; -} -// CellsToAddModNR-r15 ::= SEQUENCE -SRSASN_CODE cells_to_add_mod_nr_r15_s::pack(bit_ref& bref) const +const char* mob_state_params_s::t_eval_opts::to_string() const { - HANDLE_CODE(pack_integer(bref, cell_idx_r15, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(pack_integer(bref, pci_r15, (uint16_t)0u, (uint16_t)1007u)); - - return SRSASN_SUCCESS; + static const char* options[] = {"s30", "s60", "s120", "s180", "s240", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 8, value, "mob_state_params_s::t_eval_e_"); } -SRSASN_CODE cells_to_add_mod_nr_r15_s::unpack(cbit_ref& bref) +uint8_t mob_state_params_s::t_eval_opts::to_number() const { - HANDLE_CODE(unpack_integer(cell_idx_r15, bref, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(unpack_integer(pci_r15, bref, (uint16_t)0u, (uint16_t)1007u)); - - return SRSASN_SUCCESS; + static const uint8_t options[] = {30, 60, 120, 180, 240}; + return map_enum_number(options, 5, value, "mob_state_params_s::t_eval_e_"); } -void cells_to_add_mod_nr_r15_s::to_json(json_writer& j) const + +const char* mob_state_params_s::t_hyst_normal_opts::to_string() const { - j.start_obj(); - j.write_int("cellIndex-r15", cell_idx_r15); - j.write_int("physCellId-r15", pci_r15); - j.end_obj(); + static const char* options[] = {"s30", "s60", "s120", "s180", "s240", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 8, value, "mob_state_params_s::t_hyst_normal_e_"); } -bool cells_to_add_mod_nr_r15_s::operator==(const cells_to_add_mod_nr_r15_s& other) const +uint8_t mob_state_params_s::t_hyst_normal_opts::to_number() const { - return cell_idx_r15 == other.cell_idx_r15 and pci_r15 == other.pci_r15; + static const uint8_t options[] = {30, 60, 120, 180, 240}; + return map_enum_number(options, 5, value, "mob_state_params_s::t_hyst_normal_e_"); } -// CellsToAddModUTRA-FDD ::= SEQUENCE -SRSASN_CODE cells_to_add_mod_utra_fdd_s::pack(bit_ref& bref) const +// CarrierFreqCDMA2000 ::= SEQUENCE +SRSASN_CODE carrier_freq_cdma2000_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, cell_idx, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(pack_integer(bref, pci, (uint16_t)0u, (uint16_t)511u)); + HANDLE_CODE(band_class.pack(bref)); + HANDLE_CODE(pack_integer(bref, arfcn, (uint16_t)0u, (uint16_t)2047u)); return SRSASN_SUCCESS; } -SRSASN_CODE cells_to_add_mod_utra_fdd_s::unpack(cbit_ref& bref) +SRSASN_CODE carrier_freq_cdma2000_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(cell_idx, bref, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(unpack_integer(pci, bref, (uint16_t)0u, (uint16_t)511u)); + HANDLE_CODE(band_class.unpack(bref)); + HANDLE_CODE(unpack_integer(arfcn, bref, (uint16_t)0u, (uint16_t)2047u)); return SRSASN_SUCCESS; } -void cells_to_add_mod_utra_fdd_s::to_json(json_writer& j) const +void carrier_freq_cdma2000_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("cellIndex", cell_idx); - j.write_int("physCellId", pci); + j.write_str("bandClass", band_class.to_string()); + j.write_int("arfcn", arfcn); j.end_obj(); } -bool cells_to_add_mod_utra_fdd_s::operator==(const cells_to_add_mod_utra_fdd_s& other) const +bool carrier_freq_cdma2000_s::operator==(const carrier_freq_cdma2000_s& other) const { - return cell_idx == other.cell_idx and pci == other.pci; + return band_class == other.band_class and arfcn == other.arfcn; } -// CellsToAddModUTRA-TDD ::= SEQUENCE -SRSASN_CODE cells_to_add_mod_utra_tdd_s::pack(bit_ref& bref) const +// CellsToAddMod-v1610 ::= SEQUENCE +SRSASN_CODE cells_to_add_mod_v1610_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, cell_idx, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(pack_integer(bref, pci, (uint8_t)0u, (uint8_t)127u)); + HANDLE_CODE(rss_meas_pwr_bias_r16.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE cells_to_add_mod_utra_tdd_s::unpack(cbit_ref& bref) +SRSASN_CODE cells_to_add_mod_v1610_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(cell_idx, bref, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(unpack_integer(pci, bref, (uint8_t)0u, (uint8_t)127u)); + HANDLE_CODE(rss_meas_pwr_bias_r16.unpack(bref)); return SRSASN_SUCCESS; } -void cells_to_add_mod_utra_tdd_s::to_json(json_writer& j) const +void cells_to_add_mod_v1610_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("cellIndex", cell_idx); - j.write_int("physCellId", pci); + j.write_str("rss-MeasPowerBias-r16", rss_meas_pwr_bias_r16.to_string()); j.end_obj(); } -bool cells_to_add_mod_utra_tdd_s::operator==(const cells_to_add_mod_utra_tdd_s& other) const +bool cells_to_add_mod_v1610_s::operator==(const cells_to_add_mod_v1610_s& other) const { - return cell_idx == other.cell_idx and pci == other.pci; + return rss_meas_pwr_bias_r16 == other.rss_meas_pwr_bias_r16; } -// WhiteCellsToAddMod-r13 ::= SEQUENCE -SRSASN_CODE white_cells_to_add_mod_r13_s::pack(bit_ref& bref) const +// MeasCSI-RS-Config-r12 ::= SEQUENCE +SRSASN_CODE meas_csi_rs_cfg_r12_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, cell_idx_r13, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(pci_range_r13.pack(bref)); + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, meas_csi_rs_id_r12, (uint8_t)1u, (uint8_t)96u)); + HANDLE_CODE(pack_integer(bref, pci_r12, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(pack_integer(bref, scrambling_id_r12, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(pack_integer(bref, res_cfg_r12, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(pack_integer(bref, sf_offset_r12, (uint8_t)0u, (uint8_t)4u)); + HANDLE_CODE(csi_rs_individual_offset_r12.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE white_cells_to_add_mod_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE meas_csi_rs_cfg_r12_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(cell_idx_r13, bref, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(pci_range_r13.unpack(bref)); - - return SRSASN_SUCCESS; + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(meas_csi_rs_id_r12, bref, (uint8_t)1u, (uint8_t)96u)); + HANDLE_CODE(unpack_integer(pci_r12, bref, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(unpack_integer(scrambling_id_r12, bref, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(unpack_integer(res_cfg_r12, bref, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(unpack_integer(sf_offset_r12, bref, (uint8_t)0u, (uint8_t)4u)); + HANDLE_CODE(csi_rs_individual_offset_r12.unpack(bref)); + + return SRSASN_SUCCESS; +} +void meas_csi_rs_cfg_r12_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("measCSI-RS-Id-r12", meas_csi_rs_id_r12); + j.write_int("physCellId-r12", pci_r12); + j.write_int("scramblingIdentity-r12", scrambling_id_r12); + j.write_int("resourceConfig-r12", res_cfg_r12); + j.write_int("subframeOffset-r12", sf_offset_r12); + j.write_str("csi-RS-IndividualOffset-r12", csi_rs_individual_offset_r12.to_string()); + j.end_obj(); +} +bool meas_csi_rs_cfg_r12_s::operator==(const meas_csi_rs_cfg_r12_s& other) const +{ + return ext == other.ext and meas_csi_rs_id_r12 == other.meas_csi_rs_id_r12 and pci_r12 == other.pci_r12 and + scrambling_id_r12 == other.scrambling_id_r12 and res_cfg_r12 == other.res_cfg_r12 and + sf_offset_r12 == other.sf_offset_r12 and csi_rs_individual_offset_r12 == other.csi_rs_individual_offset_r12; +} + +// PhysCellIdRangeUTRA-FDD-r9 ::= SEQUENCE +SRSASN_CODE pci_range_utra_fdd_r9_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(range_r9_present, 1)); + + HANDLE_CODE(pack_integer(bref, start_r9, (uint16_t)0u, (uint16_t)511u)); + if (range_r9_present) { + HANDLE_CODE(pack_integer(bref, range_r9, (uint16_t)2u, (uint16_t)512u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pci_range_utra_fdd_r9_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(range_r9_present, 1)); + + HANDLE_CODE(unpack_integer(start_r9, bref, (uint16_t)0u, (uint16_t)511u)); + if (range_r9_present) { + HANDLE_CODE(unpack_integer(range_r9, bref, (uint16_t)2u, (uint16_t)512u)); + } + + return SRSASN_SUCCESS; +} +void pci_range_utra_fdd_r9_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("start-r9", start_r9); + if (range_r9_present) { + j.write_int("range-r9", range_r9); + } + j.end_obj(); +} +bool pci_range_utra_fdd_r9_s::operator==(const pci_range_utra_fdd_r9_s& other) const +{ + return start_r9 == other.start_r9 and range_r9_present == other.range_r9_present and + (not range_r9_present or range_r9 == other.range_r9); +} + +// SSB-PositionQCL-CellsToAddNR-r16 ::= SEQUENCE +SRSASN_CODE ssb_position_qcl_cells_to_add_nr_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, pci_r16, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(ssb_position_qcl_nr_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ssb_position_qcl_cells_to_add_nr_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(pci_r16, bref, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(ssb_position_qcl_nr_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ssb_position_qcl_cells_to_add_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("physCellId-r16", pci_r16); + j.write_str("ssb-PositionQCL-NR-r16", ssb_position_qcl_nr_r16.to_string()); + j.end_obj(); +} +bool ssb_position_qcl_cells_to_add_nr_r16_s::operator==(const ssb_position_qcl_cells_to_add_nr_r16_s& other) const +{ + return pci_r16 == other.pci_r16 and ssb_position_qcl_nr_r16 == other.ssb_position_qcl_nr_r16; +} + +// SSB-PositionQCL-CellsToAddNR-r17 ::= SEQUENCE +SRSASN_CODE ssb_position_qcl_cells_to_add_nr_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, pci_nr_r17, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(ssb_position_qcl_nr_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ssb_position_qcl_cells_to_add_nr_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(pci_nr_r17, bref, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(ssb_position_qcl_nr_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ssb_position_qcl_cells_to_add_nr_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("physCellIdNR-r17", pci_nr_r17); + j.write_str("ssb-PositionQCL-NR-r17", ssb_position_qcl_nr_r17.to_string()); + j.end_obj(); +} +bool ssb_position_qcl_cells_to_add_nr_r17_s::operator==(const ssb_position_qcl_cells_to_add_nr_r17_s& other) const +{ + return pci_nr_r17 == other.pci_nr_r17 and ssb_position_qcl_nr_r17 == other.ssb_position_qcl_nr_r17; +} + +// AllowedCellsToAddMod-r13 ::= SEQUENCE +SRSASN_CODE allowed_cells_to_add_mod_r13_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, cell_idx_r13, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pci_range_r13.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE allowed_cells_to_add_mod_r13_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(cell_idx_r13, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pci_range_r13.unpack(bref)); + + return SRSASN_SUCCESS; +} +void allowed_cells_to_add_mod_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("cellIndex-r13", cell_idx_r13); + j.write_fieldname("physCellIdRange-r13"); + pci_range_r13.to_json(j); + j.end_obj(); +} +bool allowed_cells_to_add_mod_r13_s::operator==(const allowed_cells_to_add_mod_r13_s& other) const +{ + return cell_idx_r13 == other.cell_idx_r13 and pci_range_r13 == other.pci_range_r13; +} + +// AltTTT-CellsToAddMod-r12 ::= SEQUENCE +SRSASN_CODE alt_ttt_cells_to_add_mod_r12_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, cell_idx_r12, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pci_range_r12.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE alt_ttt_cells_to_add_mod_r12_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(cell_idx_r12, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pci_range_r12.unpack(bref)); + + return SRSASN_SUCCESS; +} +void alt_ttt_cells_to_add_mod_r12_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("cellIndex-r12", cell_idx_r12); + j.write_fieldname("physCellIdRange-r12"); + pci_range_r12.to_json(j); + j.end_obj(); +} +bool alt_ttt_cells_to_add_mod_r12_s::operator==(const alt_ttt_cells_to_add_mod_r12_s& other) const +{ + return cell_idx_r12 == other.cell_idx_r12 and pci_range_r12 == other.pci_range_r12; +} + +// CellsToAddMod ::= SEQUENCE +SRSASN_CODE cells_to_add_mod_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, cell_idx, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pack_integer(bref, pci, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(cell_individual_offset.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cells_to_add_mod_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(cell_idx, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(unpack_integer(pci, bref, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(cell_individual_offset.unpack(bref)); + + return SRSASN_SUCCESS; +} +void cells_to_add_mod_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("cellIndex", cell_idx); + j.write_int("physCellId", pci); + j.write_str("cellIndividualOffset", cell_individual_offset.to_string()); + j.end_obj(); +} +bool cells_to_add_mod_s::operator==(const cells_to_add_mod_s& other) const +{ + return cell_idx == other.cell_idx and pci == other.pci and cell_individual_offset == other.cell_individual_offset; +} + +// CellsToAddModCDMA2000 ::= SEQUENCE +SRSASN_CODE cells_to_add_mod_cdma2000_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, cell_idx, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pack_integer(bref, pci, (uint16_t)0u, (uint16_t)511u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cells_to_add_mod_cdma2000_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(cell_idx, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(unpack_integer(pci, bref, (uint16_t)0u, (uint16_t)511u)); + + return SRSASN_SUCCESS; +} +void cells_to_add_mod_cdma2000_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("cellIndex", cell_idx); + j.write_int("physCellId", pci); + j.end_obj(); +} +bool cells_to_add_mod_cdma2000_s::operator==(const cells_to_add_mod_cdma2000_s& other) const +{ + return cell_idx == other.cell_idx and pci == other.pci; +} + +// CellsToAddModNR-r15 ::= SEQUENCE +SRSASN_CODE cells_to_add_mod_nr_r15_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, cell_idx_r15, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pack_integer(bref, pci_r15, (uint16_t)0u, (uint16_t)1007u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cells_to_add_mod_nr_r15_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(cell_idx_r15, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(unpack_integer(pci_r15, bref, (uint16_t)0u, (uint16_t)1007u)); + + return SRSASN_SUCCESS; +} +void cells_to_add_mod_nr_r15_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("cellIndex-r15", cell_idx_r15); + j.write_int("physCellId-r15", pci_r15); + j.end_obj(); +} +bool cells_to_add_mod_nr_r15_s::operator==(const cells_to_add_mod_nr_r15_s& other) const +{ + return cell_idx_r15 == other.cell_idx_r15 and pci_r15 == other.pci_r15; +} + +// CellsToAddModNR-r16 ::= SEQUENCE +SRSASN_CODE cells_to_add_mod_nr_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, cell_idx_r16, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pack_integer(bref, pci_r16, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(cell_individual_offset_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cells_to_add_mod_nr_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(cell_idx_r16, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(unpack_integer(pci_r16, bref, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(cell_individual_offset_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void cells_to_add_mod_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("cellIndex-r16", cell_idx_r16); + j.write_int("physCellId-r16", pci_r16); + j.write_str("cellIndividualOffset-r16", cell_individual_offset_r16.to_string()); + j.end_obj(); +} +bool cells_to_add_mod_nr_r16_s::operator==(const cells_to_add_mod_nr_r16_s& other) const +{ + return cell_idx_r16 == other.cell_idx_r16 and pci_r16 == other.pci_r16 and + cell_individual_offset_r16 == other.cell_individual_offset_r16; +} + +// CellsToAddModUTRA-FDD ::= SEQUENCE +SRSASN_CODE cells_to_add_mod_utra_fdd_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, cell_idx, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pack_integer(bref, pci, (uint16_t)0u, (uint16_t)511u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cells_to_add_mod_utra_fdd_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(cell_idx, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(unpack_integer(pci, bref, (uint16_t)0u, (uint16_t)511u)); + + return SRSASN_SUCCESS; +} +void cells_to_add_mod_utra_fdd_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("cellIndex", cell_idx); + j.write_int("physCellId", pci); + j.end_obj(); +} +bool cells_to_add_mod_utra_fdd_s::operator==(const cells_to_add_mod_utra_fdd_s& other) const +{ + return cell_idx == other.cell_idx and pci == other.pci; +} + +// CellsToAddModUTRA-TDD ::= SEQUENCE +SRSASN_CODE cells_to_add_mod_utra_tdd_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, cell_idx, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pack_integer(bref, pci, (uint8_t)0u, (uint8_t)127u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cells_to_add_mod_utra_tdd_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(cell_idx, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(unpack_integer(pci, bref, (uint8_t)0u, (uint8_t)127u)); + + return SRSASN_SUCCESS; +} +void cells_to_add_mod_utra_tdd_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("cellIndex", cell_idx); + j.write_int("physCellId", pci); + j.end_obj(); +} +bool cells_to_add_mod_utra_tdd_s::operator==(const cells_to_add_mod_utra_tdd_s& other) const +{ + return cell_idx == other.cell_idx and pci == other.pci; +} + +// ExcludedCellsToAddMod ::= SEQUENCE +SRSASN_CODE excluded_cells_to_add_mod_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, cell_idx, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pci_range.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE excluded_cells_to_add_mod_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(cell_idx, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pci_range.unpack(bref)); + + return SRSASN_SUCCESS; +} +void excluded_cells_to_add_mod_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("cellIndex", cell_idx); + j.write_fieldname("physCellIdRange"); + pci_range.to_json(j); + j.end_obj(); +} +bool excluded_cells_to_add_mod_s::operator==(const excluded_cells_to_add_mod_s& other) const +{ + return cell_idx == other.cell_idx and pci_range == other.pci_range; +} + +// ThresholdEUTRA ::= CHOICE +void thres_eutra_c::destroy_() {} +void thres_eutra_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +thres_eutra_c::thres_eutra_c(const thres_eutra_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::thres_rsrp: + c.init(other.c.get()); + break; + case types::thres_rsrq: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "thres_eutra_c"); + } +} +thres_eutra_c& thres_eutra_c::operator=(const thres_eutra_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::thres_rsrp: + c.set(other.c.get()); + break; + case types::thres_rsrq: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "thres_eutra_c"); + } + + return *this; +} +uint8_t& thres_eutra_c::set_thres_rsrp() +{ + set(types::thres_rsrp); + return c.get(); +} +uint8_t& thres_eutra_c::set_thres_rsrq() +{ + set(types::thres_rsrq); + return c.get(); +} +void thres_eutra_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::thres_rsrp: + j.write_int("threshold-RSRP", c.get()); + break; + case types::thres_rsrq: + j.write_int("threshold-RSRQ", c.get()); + break; + default: + log_invalid_choice_id(type_, "thres_eutra_c"); + } + j.end_obj(); +} +SRSASN_CODE thres_eutra_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::thres_rsrp: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)97u)); + break; + case types::thres_rsrq: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)34u)); + break; + default: + log_invalid_choice_id(type_, "thres_eutra_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE thres_eutra_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::thres_rsrp: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)97u)); + break; + case types::thres_rsrq: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)34u)); + break; + default: + log_invalid_choice_id(type_, "thres_eutra_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +bool thres_eutra_c::operator==(const thres_eutra_c& other) const +{ + if (type_ != other.type_) { + return false; + } + switch (type_) { + case types::thres_rsrp: + return c.get() == other.c.get(); + case types::thres_rsrq: + return c.get() == other.c.get(); + default: + return true; + } + return true; +} + +// ThresholdNR-r15 ::= CHOICE +void thres_nr_r15_c::destroy_() {} +void thres_nr_r15_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +thres_nr_r15_c::thres_nr_r15_c(const thres_nr_r15_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::nr_rsrp_r15: + c.init(other.c.get()); + break; + case types::nr_rsrq_r15: + c.init(other.c.get()); + break; + case types::nr_sinr_r15: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "thres_nr_r15_c"); + } +} +thres_nr_r15_c& thres_nr_r15_c::operator=(const thres_nr_r15_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::nr_rsrp_r15: + c.set(other.c.get()); + break; + case types::nr_rsrq_r15: + c.set(other.c.get()); + break; + case types::nr_sinr_r15: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "thres_nr_r15_c"); + } + + return *this; +} +uint8_t& thres_nr_r15_c::set_nr_rsrp_r15() +{ + set(types::nr_rsrp_r15); + return c.get(); +} +uint8_t& thres_nr_r15_c::set_nr_rsrq_r15() +{ + set(types::nr_rsrq_r15); + return c.get(); +} +uint8_t& thres_nr_r15_c::set_nr_sinr_r15() +{ + set(types::nr_sinr_r15); + return c.get(); +} +void thres_nr_r15_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::nr_rsrp_r15: + j.write_int("nr-RSRP-r15", c.get()); + break; + case types::nr_rsrq_r15: + j.write_int("nr-RSRQ-r15", c.get()); + break; + case types::nr_sinr_r15: + j.write_int("nr-SINR-r15", c.get()); + break; + default: + log_invalid_choice_id(type_, "thres_nr_r15_c"); + } + j.end_obj(); } -void white_cells_to_add_mod_r13_s::to_json(json_writer& j) const +SRSASN_CODE thres_nr_r15_c::pack(bit_ref& bref) const { - j.start_obj(); - j.write_int("cellIndex-r13", cell_idx_r13); - j.write_fieldname("physCellIdRange-r13"); - pci_range_r13.to_json(j); - j.end_obj(); + type_.pack(bref); + switch (type_) { + case types::nr_rsrp_r15: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + break; + case types::nr_rsrq_r15: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + break; + case types::nr_sinr_r15: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + break; + default: + log_invalid_choice_id(type_, "thres_nr_r15_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; } -bool white_cells_to_add_mod_r13_s::operator==(const white_cells_to_add_mod_r13_s& other) const +SRSASN_CODE thres_nr_r15_c::unpack(cbit_ref& bref) { - return cell_idx_r13 == other.cell_idx_r13 and pci_range_r13 == other.pci_range_r13; + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::nr_rsrp_r15: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + break; + case types::nr_rsrq_r15: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + break; + case types::nr_sinr_r15: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + break; + default: + log_invalid_choice_id(type_, "thres_nr_r15_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +bool thres_nr_r15_c::operator==(const thres_nr_r15_c& other) const +{ + if (type_ != other.type_) { + return false; + } + switch (type_) { + case types::nr_rsrp_r15: + return c.get() == other.c.get(); + case types::nr_rsrq_r15: + return c.get() == other.c.get(); + case types::nr_sinr_r15: + return c.get() == other.c.get(); + default: + return true; + } + return true; +} + +// TimeToTrigger ::= ENUMERATED +const char* time_to_trigger_opts::to_string() const +{ + static const char* options[] = {"ms0", + "ms40", + "ms64", + "ms80", + "ms100", + "ms128", + "ms160", + "ms256", + "ms320", + "ms480", + "ms512", + "ms640", + "ms1024", + "ms1280", + "ms2560", + "ms5120"}; + return convert_enum_idx(options, 16, value, "time_to_trigger_e"); +} +uint16_t time_to_trigger_opts::to_number() const +{ + static const uint16_t options[] = {0, 40, 64, 80, 100, 128, 160, 256, 320, 480, 512, 640, 1024, 1280, 2560, 5120}; + return map_enum_number(options, 16, value, "time_to_trigger_e"); } // BT-NameListConfig-r15 ::= CHOICE @@ -1345,62 +1815,327 @@ SRSASN_CODE bt_name_list_cfg_r15_c::unpack(cbit_ref& bref) log_invalid_choice_id(type_, "bt_name_list_cfg_r15_c"); return SRSASN_ERROR_DECODE_FAIL; } - return SRSASN_SUCCESS; + return SRSASN_SUCCESS; +} +bool bt_name_list_cfg_r15_c::operator==(const bt_name_list_cfg_r15_c& other) const +{ + return type() == other.type() and c == other.c; +} + +// CDMA2000-Type ::= ENUMERATED +const char* cdma2000_type_opts::to_string() const +{ + static const char* options[] = {"type1XRTT", "typeHRPD"}; + return convert_enum_idx(options, 2, value, "cdma2000_type_e"); +} +uint8_t cdma2000_type_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "cdma2000_type_e"); +} + +// CSG-AllowedReportingCells-r9 ::= SEQUENCE +SRSASN_CODE csg_allowed_report_cells_r9_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pci_range_utra_fdd_list_r9_present, 1)); + + if (pci_range_utra_fdd_list_r9_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, pci_range_utra_fdd_list_r9, 1, 4)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE csg_allowed_report_cells_r9_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(pci_range_utra_fdd_list_r9_present, 1)); + + if (pci_range_utra_fdd_list_r9_present) { + HANDLE_CODE(unpack_dyn_seq_of(pci_range_utra_fdd_list_r9, bref, 1, 4)); + } + + return SRSASN_SUCCESS; +} +void csg_allowed_report_cells_r9_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (pci_range_utra_fdd_list_r9_present) { + j.start_array("physCellIdRangeUTRA-FDDList-r9"); + for (const auto& e1 : pci_range_utra_fdd_list_r9) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} +bool csg_allowed_report_cells_r9_s::operator==(const csg_allowed_report_cells_r9_s& other) const +{ + return pci_range_utra_fdd_list_r9_present == other.pci_range_utra_fdd_list_r9_present and + (not pci_range_utra_fdd_list_r9_present or pci_range_utra_fdd_list_r9 == other.pci_range_utra_fdd_list_r9); +} + +// CondReconfigurationTriggerEUTRA-r16 ::= SEQUENCE +SRSASN_CODE cond_recfg_trigger_eutra_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(cond_event_id_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cond_recfg_trigger_eutra_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(cond_event_id_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void cond_recfg_trigger_eutra_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("condEventId-r16"); + cond_event_id_r16.to_json(j); + j.end_obj(); +} +bool cond_recfg_trigger_eutra_r16_s::operator==(const cond_recfg_trigger_eutra_r16_s& other) const +{ + return cond_event_id_r16 == other.cond_event_id_r16; +} + +void cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::destroy_() +{ + switch (type_) { + case types::cond_event_a3_r16: + c.destroy(); + break; + case types::cond_event_a5_r16: + c.destroy(); + break; + default: + break; + } +} +void cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::cond_event_a3_r16: + c.init(); + break; + case types::cond_event_a5_r16: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_"); + } +} +cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::cond_event_id_r16_c_( + const cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::cond_event_a3_r16: + c.init(other.c.get()); + break; + case types::cond_event_a5_r16: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_"); + } +} +cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_& cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::operator=( + const cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::cond_event_a3_r16: + c.set(other.c.get()); + break; + case types::cond_event_a5_r16: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_"); + } + + return *this; +} +cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::cond_event_a3_r16_s_& +cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::set_cond_event_a3_r16() +{ + set(types::cond_event_a3_r16); + return c.get(); +} +cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::cond_event_a5_r16_s_& +cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::set_cond_event_a5_r16() +{ + set(types::cond_event_a5_r16); + return c.get(); +} +void cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::cond_event_a3_r16: + j.write_fieldname("condEventA3-r16"); + j.start_obj(); + j.write_int("a3-Offset-r16", c.get().a3_offset_r16); + j.write_int("hysteresis-r16", c.get().hysteresis_r16); + j.write_str("timeToTrigger-r16", c.get().time_to_trigger_r16.to_string()); + j.end_obj(); + break; + case types::cond_event_a5_r16: + j.write_fieldname("condEventA5-r16"); + j.start_obj(); + j.write_fieldname("a5-Threshold1-r16"); + c.get().a5_thres1_r16.to_json(j); + j.write_fieldname("a5-Threshold2-r16"); + c.get().a5_thres2_r16.to_json(j); + j.write_int("hysteresis-r16", c.get().hysteresis_r16); + j.write_str("timeToTrigger-r16", c.get().time_to_trigger_r16.to_string()); + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_"); + } + j.end_obj(); +} +SRSASN_CODE cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::cond_event_a3_r16: + HANDLE_CODE(pack_integer(bref, c.get().a3_offset_r16, (int8_t)-30, (int8_t)30)); + HANDLE_CODE(pack_integer(bref, c.get().hysteresis_r16, (uint8_t)0u, (uint8_t)30u)); + HANDLE_CODE(c.get().time_to_trigger_r16.pack(bref)); + break; + case types::cond_event_a5_r16: + HANDLE_CODE(c.get().a5_thres1_r16.pack(bref)); + HANDLE_CODE(c.get().a5_thres2_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, c.get().hysteresis_r16, (uint8_t)0u, (uint8_t)30u)); + HANDLE_CODE(c.get().time_to_trigger_r16.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::cond_event_a3_r16: + HANDLE_CODE(unpack_integer(c.get().a3_offset_r16, bref, (int8_t)-30, (int8_t)30)); + HANDLE_CODE(unpack_integer(c.get().hysteresis_r16, bref, (uint8_t)0u, (uint8_t)30u)); + HANDLE_CODE(c.get().time_to_trigger_r16.unpack(bref)); + break; + case types::cond_event_a5_r16: + HANDLE_CODE(c.get().a5_thres1_r16.unpack(bref)); + HANDLE_CODE(c.get().a5_thres2_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(c.get().hysteresis_r16, bref, (uint8_t)0u, (uint8_t)30u)); + HANDLE_CODE(c.get().time_to_trigger_r16.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +bool cond_recfg_trigger_eutra_r16_s::cond_event_id_r16_c_::operator==(const cond_event_id_r16_c_& other) const +{ + if (type_ != other.type_) { + return false; + } + switch (type_) { + case types::cond_event_a3_r16: + return c.get().a3_offset_r16 == other.c.get().a3_offset_r16 and + c.get().hysteresis_r16 == other.c.get().hysteresis_r16 and + c.get().time_to_trigger_r16 == + other.c.get().time_to_trigger_r16; + case types::cond_event_a5_r16: + return c.get().a5_thres1_r16 == other.c.get().a5_thres1_r16 and + c.get().a5_thres2_r16 == other.c.get().a5_thres2_r16 and + c.get().hysteresis_r16 == other.c.get().hysteresis_r16 and + c.get().time_to_trigger_r16 == + other.c.get().time_to_trigger_r16; + default: + return true; + } + return true; } -bool bt_name_list_cfg_r15_c::operator==(const bt_name_list_cfg_r15_c& other) const + +// CondReconfigurationTriggerNR-r17 ::= SEQUENCE +SRSASN_CODE cond_recfg_trigger_nr_r17_s::pack(bit_ref& bref) const { - return type() == other.type() and c == other.c; + HANDLE_CODE(cond_event_id_r17.pack(bref)); + + return SRSASN_SUCCESS; } +SRSASN_CODE cond_recfg_trigger_nr_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(cond_event_id_r17.unpack(bref)); -// CDMA2000-Type ::= ENUMERATED -const char* cdma2000_type_opts::to_string() const + return SRSASN_SUCCESS; +} +void cond_recfg_trigger_nr_r17_s::to_json(json_writer& j) const { - static const char* options[] = {"type1XRTT", "typeHRPD"}; - return convert_enum_idx(options, 2, value, "cdma2000_type_e"); + j.start_obj(); + j.write_fieldname("condEventId-r17"); + cond_event_id_r17.to_json(j); + j.end_obj(); } -uint8_t cdma2000_type_opts::to_number() const +bool cond_recfg_trigger_nr_r17_s::operator==(const cond_recfg_trigger_nr_r17_s& other) const { - static const uint8_t options[] = {1}; - return map_enum_number(options, 1, value, "cdma2000_type_e"); + return cond_event_id_r17 == other.cond_event_id_r17; } -// CSG-AllowedReportingCells-r9 ::= SEQUENCE -SRSASN_CODE csg_allowed_report_cells_r9_s::pack(bit_ref& bref) const +void cond_recfg_trigger_nr_r17_s::cond_event_id_r17_c_::to_json(json_writer& j) const { - HANDLE_CODE(bref.pack(pci_range_utra_fdd_list_r9_present, 1)); - - if (pci_range_utra_fdd_list_r9_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, pci_range_utra_fdd_list_r9, 1, 4)); - } - - return SRSASN_SUCCESS; + j.start_obj(); + j.write_fieldname("condEventB1-NR-r17"); + j.start_obj(); + j.write_fieldname("b1-ThresholdNR-r17"); + c.b1_thres_nr_r17.to_json(j); + j.write_int("hysteresis-r17", c.hysteresis_r17); + j.write_str("timeToTrigger-r17", c.time_to_trigger_r17.to_string()); + j.end_obj(); + j.end_obj(); } -SRSASN_CODE csg_allowed_report_cells_r9_s::unpack(cbit_ref& bref) +SRSASN_CODE cond_recfg_trigger_nr_r17_s::cond_event_id_r17_c_::pack(bit_ref& bref) const { - HANDLE_CODE(bref.unpack(pci_range_utra_fdd_list_r9_present, 1)); - - if (pci_range_utra_fdd_list_r9_present) { - HANDLE_CODE(unpack_dyn_seq_of(pci_range_utra_fdd_list_r9, bref, 1, 4)); - } - + pack_enum(bref, type()); + HANDLE_CODE(c.b1_thres_nr_r17.pack(bref)); + HANDLE_CODE(pack_integer(bref, c.hysteresis_r17, (uint8_t)0u, (uint8_t)30u)); + HANDLE_CODE(c.time_to_trigger_r17.pack(bref)); return SRSASN_SUCCESS; } -void csg_allowed_report_cells_r9_s::to_json(json_writer& j) const +SRSASN_CODE cond_recfg_trigger_nr_r17_s::cond_event_id_r17_c_::unpack(cbit_ref& bref) { - j.start_obj(); - if (pci_range_utra_fdd_list_r9_present) { - j.start_array("physCellIdRangeUTRA-FDDList-r9"); - for (const auto& e1 : pci_range_utra_fdd_list_r9) { - e1.to_json(j); - } - j.end_array(); + types e; + unpack_enum(e, bref); + if (e != type()) { + log_invalid_choice_id(e, "cond_recfg_trigger_nr_r17_s::cond_event_id_r17_c_"); + return SRSASN_ERROR_DECODE_FAIL; } - j.end_obj(); + HANDLE_CODE(c.b1_thres_nr_r17.unpack(bref)); + HANDLE_CODE(unpack_integer(c.hysteresis_r17, bref, (uint8_t)0u, (uint8_t)30u)); + HANDLE_CODE(c.time_to_trigger_r17.unpack(bref)); + return SRSASN_SUCCESS; } -bool csg_allowed_report_cells_r9_s::operator==(const csg_allowed_report_cells_r9_s& other) const +bool cond_recfg_trigger_nr_r17_s::cond_event_id_r17_c_::operator==(const cond_event_id_r17_c_& other) const { - return pci_range_utra_fdd_list_r9_present == other.pci_range_utra_fdd_list_r9_present and - (not pci_range_utra_fdd_list_r9_present or pci_range_utra_fdd_list_r9 == other.pci_range_utra_fdd_list_r9); + return type() == other.type() and c.b1_thres_nr_r17 == other.c.b1_thres_nr_r17 and + c.hysteresis_r17 == other.c.hysteresis_r17 and c.time_to_trigger_r17 == other.c.time_to_trigger_r17; } // MeasCycleSCell-r10 ::= ENUMERATED @@ -2356,6 +3091,59 @@ SRSASN_CODE meas_gap_cfg_c::setup_s_::gap_offset_c_::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +// MeasRSS-DedicatedConfig-r16 ::= SEQUENCE +SRSASN_CODE meas_rss_ded_cfg_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(rss_cfg_carrier_info_r16_present, 1)); + HANDLE_CODE(bref.pack(cells_to_add_mod_list_v1610_present, 1)); + + if (rss_cfg_carrier_info_r16_present) { + HANDLE_CODE(rss_cfg_carrier_info_r16.pack(bref)); + } + if (cells_to_add_mod_list_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, cells_to_add_mod_list_v1610, 1, 32)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_rss_ded_cfg_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(rss_cfg_carrier_info_r16_present, 1)); + HANDLE_CODE(bref.unpack(cells_to_add_mod_list_v1610_present, 1)); + + if (rss_cfg_carrier_info_r16_present) { + HANDLE_CODE(rss_cfg_carrier_info_r16.unpack(bref)); + } + if (cells_to_add_mod_list_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(cells_to_add_mod_list_v1610, bref, 1, 32)); + } + + return SRSASN_SUCCESS; +} +void meas_rss_ded_cfg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (rss_cfg_carrier_info_r16_present) { + j.write_fieldname("rss-ConfigCarrierInfo-r16"); + rss_cfg_carrier_info_r16.to_json(j); + } + if (cells_to_add_mod_list_v1610_present) { + j.start_array("cellsToAddModList-v1610"); + for (const auto& e1 : cells_to_add_mod_list_v1610) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} +bool meas_rss_ded_cfg_r16_s::operator==(const meas_rss_ded_cfg_r16_s& other) const +{ + return rss_cfg_carrier_info_r16_present == other.rss_cfg_carrier_info_r16_present and + (not rss_cfg_carrier_info_r16_present or rss_cfg_carrier_info_r16 == other.rss_cfg_carrier_info_r16) and + cells_to_add_mod_list_v1610_present == other.cells_to_add_mod_list_v1610_present and + (not cells_to_add_mod_list_v1610_present or cells_to_add_mod_list_v1610 == other.cells_to_add_mod_list_v1610); +} + // MeasRSSI-ReportConfig-r13 ::= SEQUENCE SRSASN_CODE meas_rssi_report_cfg_r13_s::pack(bit_ref& bref) const { @@ -2426,208 +3214,33 @@ bool meas_sensing_cfg_r15_s::operator==(const meas_sensing_cfg_r15_s& other) con sensing_resel_counter_r15 == other.sensing_resel_counter_r15 and sensing_prio_r15 == other.sensing_prio_r15; } -const char* meas_sensing_cfg_r15_s::sensing_periodicity_r15_opts::to_string() const -{ - static const char* options[] = { - "ms20", "ms50", "ms100", "ms200", "ms300", "ms400", "ms500", "ms600", "ms700", "ms800", "ms900", "ms1000"}; - return convert_enum_idx(options, 12, value, "meas_sensing_cfg_r15_s::sensing_periodicity_r15_e_"); -} -uint16_t meas_sensing_cfg_r15_s::sensing_periodicity_r15_opts::to_number() const -{ - static const uint16_t options[] = {20, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000}; - return map_enum_number(options, 12, value, "meas_sensing_cfg_r15_s::sensing_periodicity_r15_e_"); -} - -// MeasSubframePatternConfigNeigh-r10 ::= CHOICE -void meas_sf_pattern_cfg_neigh_r10_c::set(types::options e) -{ - type_ = e; -} -void meas_sf_pattern_cfg_neigh_r10_c::set_release() -{ - set(types::release); -} -meas_sf_pattern_cfg_neigh_r10_c::setup_s_& meas_sf_pattern_cfg_neigh_r10_c::set_setup() -{ - set(types::setup); - return c; -} -void meas_sf_pattern_cfg_neigh_r10_c::to_json(json_writer& j) const -{ - j.start_obj(); - switch (type_) { - case types::release: - break; - case types::setup: - j.write_fieldname("setup"); - j.start_obj(); - j.write_fieldname("measSubframePatternNeigh-r10"); - c.meas_sf_pattern_neigh_r10.to_json(j); - if (c.meas_sf_cell_list_r10_present) { - j.start_array("measSubframeCellList-r10"); - for (const auto& e1 : c.meas_sf_cell_list_r10) { - e1.to_json(j); - } - j.end_array(); - } - j.end_obj(); - break; - default: - log_invalid_choice_id(type_, "meas_sf_pattern_cfg_neigh_r10_c"); - } - j.end_obj(); -} -SRSASN_CODE meas_sf_pattern_cfg_neigh_r10_c::pack(bit_ref& bref) const -{ - type_.pack(bref); - switch (type_) { - case types::release: - break; - case types::setup: - HANDLE_CODE(bref.pack(c.meas_sf_cell_list_r10_present, 1)); - HANDLE_CODE(c.meas_sf_pattern_neigh_r10.pack(bref)); - if (c.meas_sf_cell_list_r10_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, c.meas_sf_cell_list_r10, 1, 32)); - } - break; - default: - log_invalid_choice_id(type_, "meas_sf_pattern_cfg_neigh_r10_c"); - return SRSASN_ERROR_ENCODE_FAIL; - } - return SRSASN_SUCCESS; -} -SRSASN_CODE meas_sf_pattern_cfg_neigh_r10_c::unpack(cbit_ref& bref) -{ - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::release: - break; - case types::setup: - HANDLE_CODE(bref.unpack(c.meas_sf_cell_list_r10_present, 1)); - HANDLE_CODE(c.meas_sf_pattern_neigh_r10.unpack(bref)); - if (c.meas_sf_cell_list_r10_present) { - HANDLE_CODE(unpack_dyn_seq_of(c.meas_sf_cell_list_r10, bref, 1, 32)); - } - break; - default: - log_invalid_choice_id(type_, "meas_sf_pattern_cfg_neigh_r10_c"); - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; -} -bool meas_sf_pattern_cfg_neigh_r10_c::operator==(const meas_sf_pattern_cfg_neigh_r10_c& other) const -{ - return type() == other.type() and c.meas_sf_pattern_neigh_r10 == other.c.meas_sf_pattern_neigh_r10 and - c.meas_sf_cell_list_r10_present == other.c.meas_sf_cell_list_r10_present and - (not c.meas_sf_cell_list_r10_present or c.meas_sf_cell_list_r10 == other.c.meas_sf_cell_list_r10); -} - -// PhysCellIdGERAN ::= SEQUENCE -SRSASN_CODE pci_geran_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(network_colour_code.pack(bref)); - HANDLE_CODE(base_station_colour_code.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pci_geran_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(network_colour_code.unpack(bref)); - HANDLE_CODE(base_station_colour_code.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pci_geran_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_str("networkColourCode", network_colour_code.to_string()); - j.write_str("baseStationColourCode", base_station_colour_code.to_string()); - j.end_obj(); -} -bool pci_geran_s::operator==(const pci_geran_s& other) const -{ - return network_colour_code == other.network_colour_code and - base_station_colour_code == other.base_station_colour_code; -} - -// QuantityConfigRS-NR-r15 ::= SEQUENCE -SRSASN_CODE quant_cfg_rs_nr_r15_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(bref.pack(filt_coeff_rsrp_r15_present, 1)); - HANDLE_CODE(bref.pack(filt_coeff_rsrq_r15_present, 1)); - HANDLE_CODE(bref.pack(filt_coef_sinr_r13_present, 1)); - - if (filt_coeff_rsrp_r15_present) { - HANDLE_CODE(filt_coeff_rsrp_r15.pack(bref)); - } - if (filt_coeff_rsrq_r15_present) { - HANDLE_CODE(filt_coeff_rsrq_r15.pack(bref)); - } - if (filt_coef_sinr_r13_present) { - HANDLE_CODE(filt_coef_sinr_r13.pack(bref)); - } - - return SRSASN_SUCCESS; -} -SRSASN_CODE quant_cfg_rs_nr_r15_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(bref.unpack(filt_coeff_rsrp_r15_present, 1)); - HANDLE_CODE(bref.unpack(filt_coeff_rsrq_r15_present, 1)); - HANDLE_CODE(bref.unpack(filt_coef_sinr_r13_present, 1)); - - if (filt_coeff_rsrp_r15_present) { - HANDLE_CODE(filt_coeff_rsrp_r15.unpack(bref)); - } - if (filt_coeff_rsrq_r15_present) { - HANDLE_CODE(filt_coeff_rsrq_r15.unpack(bref)); - } - if (filt_coef_sinr_r13_present) { - HANDLE_CODE(filt_coef_sinr_r13.unpack(bref)); - } - - return SRSASN_SUCCESS; -} -void quant_cfg_rs_nr_r15_s::to_json(json_writer& j) const -{ - j.start_obj(); - if (filt_coeff_rsrp_r15_present) { - j.write_str("filterCoeff-RSRP-r15", filt_coeff_rsrp_r15.to_string()); - } - if (filt_coeff_rsrq_r15_present) { - j.write_str("filterCoeff-RSRQ-r15", filt_coeff_rsrq_r15.to_string()); - } - if (filt_coef_sinr_r13_present) { - j.write_str("filterCoefficient-SINR-r13", filt_coef_sinr_r13.to_string()); - } - j.end_obj(); +const char* meas_sensing_cfg_r15_s::sensing_periodicity_r15_opts::to_string() const +{ + static const char* options[] = { + "ms20", "ms50", "ms100", "ms200", "ms300", "ms400", "ms500", "ms600", "ms700", "ms800", "ms900", "ms1000"}; + return convert_enum_idx(options, 12, value, "meas_sensing_cfg_r15_s::sensing_periodicity_r15_e_"); } -bool quant_cfg_rs_nr_r15_s::operator==(const quant_cfg_rs_nr_r15_s& other) const +uint16_t meas_sensing_cfg_r15_s::sensing_periodicity_r15_opts::to_number() const { - return filt_coeff_rsrp_r15_present == other.filt_coeff_rsrp_r15_present and - (not filt_coeff_rsrp_r15_present or filt_coeff_rsrp_r15 == other.filt_coeff_rsrp_r15) and - filt_coeff_rsrq_r15_present == other.filt_coeff_rsrq_r15_present and - (not filt_coeff_rsrq_r15_present or filt_coeff_rsrq_r15 == other.filt_coeff_rsrq_r15) and - filt_coef_sinr_r13_present == other.filt_coef_sinr_r13_present and - (not filt_coef_sinr_r13_present or filt_coef_sinr_r13 == other.filt_coef_sinr_r13); + static const uint16_t options[] = {20, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000}; + return map_enum_number(options, 12, value, "meas_sensing_cfg_r15_s::sensing_periodicity_r15_e_"); } -// RMTC-Config-r13 ::= CHOICE -void rmtc_cfg_r13_c::set(types::options e) +// MeasSubframePatternConfigNeigh-r10 ::= CHOICE +void meas_sf_pattern_cfg_neigh_r10_c::set(types::options e) { type_ = e; } -void rmtc_cfg_r13_c::set_release() +void meas_sf_pattern_cfg_neigh_r10_c::set_release() { set(types::release); } -rmtc_cfg_r13_c::setup_s_& rmtc_cfg_r13_c::set_setup() +meas_sf_pattern_cfg_neigh_r10_c::setup_s_& meas_sf_pattern_cfg_neigh_r10_c::set_setup() { set(types::setup); return c; } -void rmtc_cfg_r13_c::to_json(json_writer& j) const +void meas_sf_pattern_cfg_neigh_r10_c::to_json(json_writer& j) const { j.start_obj(); switch (type_) { @@ -2636,40 +3249,42 @@ void rmtc_cfg_r13_c::to_json(json_writer& j) const case types::setup: j.write_fieldname("setup"); j.start_obj(); - j.write_str("rmtc-Period-r13", c.rmtc_period_r13.to_string()); - if (c.rmtc_sf_offset_r13_present) { - j.write_int("rmtc-SubframeOffset-r13", c.rmtc_sf_offset_r13); + j.write_fieldname("measSubframePatternNeigh-r10"); + c.meas_sf_pattern_neigh_r10.to_json(j); + if (c.meas_sf_cell_list_r10_present) { + j.start_array("measSubframeCellList-r10"); + for (const auto& e1 : c.meas_sf_cell_list_r10) { + e1.to_json(j); + } + j.end_array(); } - j.write_str("measDuration-r13", c.meas_dur_r13.to_string()); j.end_obj(); break; default: - log_invalid_choice_id(type_, "rmtc_cfg_r13_c"); + log_invalid_choice_id(type_, "meas_sf_pattern_cfg_neigh_r10_c"); } j.end_obj(); } -SRSASN_CODE rmtc_cfg_r13_c::pack(bit_ref& bref) const +SRSASN_CODE meas_sf_pattern_cfg_neigh_r10_c::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { case types::release: break; case types::setup: - bref.pack(c.ext, 1); - HANDLE_CODE(bref.pack(c.rmtc_sf_offset_r13_present, 1)); - HANDLE_CODE(c.rmtc_period_r13.pack(bref)); - if (c.rmtc_sf_offset_r13_present) { - HANDLE_CODE(pack_integer(bref, c.rmtc_sf_offset_r13, (uint16_t)0u, (uint16_t)639u)); + HANDLE_CODE(bref.pack(c.meas_sf_cell_list_r10_present, 1)); + HANDLE_CODE(c.meas_sf_pattern_neigh_r10.pack(bref)); + if (c.meas_sf_cell_list_r10_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, c.meas_sf_cell_list_r10, 1, 32)); } - HANDLE_CODE(c.meas_dur_r13.pack(bref)); break; default: - log_invalid_choice_id(type_, "rmtc_cfg_r13_c"); + log_invalid_choice_id(type_, "meas_sf_pattern_cfg_neigh_r10_c"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rmtc_cfg_r13_c::unpack(cbit_ref& bref) +SRSASN_CODE meas_sf_pattern_cfg_neigh_r10_c::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -2678,238 +3293,171 @@ SRSASN_CODE rmtc_cfg_r13_c::unpack(cbit_ref& bref) case types::release: break; case types::setup: - bref.unpack(c.ext, 1); - HANDLE_CODE(bref.unpack(c.rmtc_sf_offset_r13_present, 1)); - HANDLE_CODE(c.rmtc_period_r13.unpack(bref)); - if (c.rmtc_sf_offset_r13_present) { - HANDLE_CODE(unpack_integer(c.rmtc_sf_offset_r13, bref, (uint16_t)0u, (uint16_t)639u)); + HANDLE_CODE(bref.unpack(c.meas_sf_cell_list_r10_present, 1)); + HANDLE_CODE(c.meas_sf_pattern_neigh_r10.unpack(bref)); + if (c.meas_sf_cell_list_r10_present) { + HANDLE_CODE(unpack_dyn_seq_of(c.meas_sf_cell_list_r10, bref, 1, 32)); } - HANDLE_CODE(c.meas_dur_r13.unpack(bref)); break; default: - log_invalid_choice_id(type_, "rmtc_cfg_r13_c"); + log_invalid_choice_id(type_, "meas_sf_pattern_cfg_neigh_r10_c"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -bool rmtc_cfg_r13_c::operator==(const rmtc_cfg_r13_c& other) const -{ - return type() == other.type() and c.ext == other.c.ext and c.rmtc_period_r13 == other.c.rmtc_period_r13 and - c.rmtc_sf_offset_r13_present == other.c.rmtc_sf_offset_r13_present and - (not c.rmtc_sf_offset_r13_present or c.rmtc_sf_offset_r13 == other.c.rmtc_sf_offset_r13) and - c.meas_dur_r13 == other.c.meas_dur_r13; -} - -const char* rmtc_cfg_r13_c::setup_s_::rmtc_period_r13_opts::to_string() const -{ - static const char* options[] = {"ms40", "ms80", "ms160", "ms320", "ms640"}; - return convert_enum_idx(options, 5, value, "rmtc_cfg_r13_c::setup_s_::rmtc_period_r13_e_"); -} -uint16_t rmtc_cfg_r13_c::setup_s_::rmtc_period_r13_opts::to_number() const -{ - static const uint16_t options[] = {40, 80, 160, 320, 640}; - return map_enum_number(options, 5, value, "rmtc_cfg_r13_c::setup_s_::rmtc_period_r13_e_"); -} - -const char* rmtc_cfg_r13_c::setup_s_::meas_dur_r13_opts::to_string() const -{ - static const char* options[] = {"sym1", "sym14", "sym28", "sym42", "sym70"}; - return convert_enum_idx(options, 5, value, "rmtc_cfg_r13_c::setup_s_::meas_dur_r13_e_"); -} -uint8_t rmtc_cfg_r13_c::setup_s_::meas_dur_r13_opts::to_number() const +bool meas_sf_pattern_cfg_neigh_r10_c::operator==(const meas_sf_pattern_cfg_neigh_r10_c& other) const { - static const uint8_t options[] = {1, 14, 28, 42, 70}; - return map_enum_number(options, 5, value, "rmtc_cfg_r13_c::setup_s_::meas_dur_r13_e_"); + return type() == other.type() and c.meas_sf_pattern_neigh_r10 == other.c.meas_sf_pattern_neigh_r10 and + c.meas_sf_cell_list_r10_present == other.c.meas_sf_cell_list_r10_present and + (not c.meas_sf_cell_list_r10_present or c.meas_sf_cell_list_r10 == other.c.meas_sf_cell_list_r10); } -// RS-ConfigSSB-NR-r15 ::= SEQUENCE -SRSASN_CODE rs_cfg_ssb_nr_r15_s::pack(bit_ref& bref) const +// PhysCellIdGERAN ::= SEQUENCE +SRSASN_CODE pci_geran_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(meas_timing_cfg_r15.pack(bref)); - HANDLE_CODE(subcarrier_spacing_ssb_r15.pack(bref)); - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= ssb_to_measure_r15.is_present(); - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(network_colour_code.pack(bref)); + HANDLE_CODE(base_station_colour_code.pack(bref)); - HANDLE_CODE(bref.pack(ssb_to_measure_r15.is_present(), 1)); - if (ssb_to_measure_r15.is_present()) { - HANDLE_CODE(ssb_to_measure_r15->pack(bref)); - } - } - } return SRSASN_SUCCESS; } -SRSASN_CODE rs_cfg_ssb_nr_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE pci_geran_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(meas_timing_cfg_r15.unpack(bref)); - HANDLE_CODE(subcarrier_spacing_ssb_r15.unpack(bref)); - - if (ext) { - ext_groups_unpacker_guard group_flags(1); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(network_colour_code.unpack(bref)); + HANDLE_CODE(base_station_colour_code.unpack(bref)); - bool ssb_to_measure_r15_present; - HANDLE_CODE(bref.unpack(ssb_to_measure_r15_present, 1)); - ssb_to_measure_r15.set_present(ssb_to_measure_r15_present); - if (ssb_to_measure_r15.is_present()) { - HANDLE_CODE(ssb_to_measure_r15->unpack(bref)); - } - } - } return SRSASN_SUCCESS; } -void rs_cfg_ssb_nr_r15_s::to_json(json_writer& j) const +void pci_geran_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("measTimingConfig-r15"); - meas_timing_cfg_r15.to_json(j); - j.write_str("subcarrierSpacingSSB-r15", subcarrier_spacing_ssb_r15.to_string()); - if (ext) { - if (ssb_to_measure_r15.is_present()) { - j.write_fieldname("ssb-ToMeasure-r15"); - ssb_to_measure_r15->to_json(j); - } - } + j.write_str("networkColourCode", network_colour_code.to_string()); + j.write_str("baseStationColourCode", base_station_colour_code.to_string()); j.end_obj(); } -bool rs_cfg_ssb_nr_r15_s::operator==(const rs_cfg_ssb_nr_r15_s& other) const +bool pci_geran_s::operator==(const pci_geran_s& other) const { - return ext == other.ext and meas_timing_cfg_r15 == other.meas_timing_cfg_r15 and - subcarrier_spacing_ssb_r15 == other.subcarrier_spacing_ssb_r15 and - (not ext or (ssb_to_measure_r15.is_present() == other.ssb_to_measure_r15.is_present() and - (not ssb_to_measure_r15.is_present() or *ssb_to_measure_r15 == *other.ssb_to_measure_r15))); + return network_colour_code == other.network_colour_code and + base_station_colour_code == other.base_station_colour_code; } -const char* rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::to_string() const -{ - static const char* options[] = {"kHz15", "kHz30", "kHz120", "kHz240"}; - return convert_enum_idx(options, 4, value, "rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_e_"); -} -uint8_t rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::to_number() const +// QuantityConfigRS-NR-r15 ::= SEQUENCE +SRSASN_CODE quant_cfg_rs_nr_r15_s::pack(bit_ref& bref) const { - static const uint8_t options[] = {15, 30, 120, 240}; - return map_enum_number(options, 4, value, "rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_e_"); -} + HANDLE_CODE(bref.pack(filt_coeff_rsrp_r15_present, 1)); + HANDLE_CODE(bref.pack(filt_coeff_rsrq_r15_present, 1)); + HANDLE_CODE(bref.pack(filt_coef_sinr_r13_present, 1)); -void rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::set(types::options e) -{ - type_ = e; -} -void rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::set_release() -{ - set(types::release); -} -ssb_to_measure_r15_c& rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::set_setup() -{ - set(types::setup); - return c; -} -void rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::to_json(json_writer& j) const -{ - j.start_obj(); - switch (type_) { - case types::release: - break; - case types::setup: - j.write_fieldname("setup"); - c.to_json(j); - break; - default: - log_invalid_choice_id(type_, "rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_"); + if (filt_coeff_rsrp_r15_present) { + HANDLE_CODE(filt_coeff_rsrp_r15.pack(bref)); } - j.end_obj(); + if (filt_coeff_rsrq_r15_present) { + HANDLE_CODE(filt_coeff_rsrq_r15.pack(bref)); + } + if (filt_coef_sinr_r13_present) { + HANDLE_CODE(filt_coef_sinr_r13.pack(bref)); + } + + return SRSASN_SUCCESS; } -SRSASN_CODE rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::pack(bit_ref& bref) const +SRSASN_CODE quant_cfg_rs_nr_r15_s::unpack(cbit_ref& bref) { - type_.pack(bref); - switch (type_) { - case types::release: - break; - case types::setup: - HANDLE_CODE(c.pack(bref)); - break; - default: - log_invalid_choice_id(type_, "rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_"); - return SRSASN_ERROR_ENCODE_FAIL; + HANDLE_CODE(bref.unpack(filt_coeff_rsrp_r15_present, 1)); + HANDLE_CODE(bref.unpack(filt_coeff_rsrq_r15_present, 1)); + HANDLE_CODE(bref.unpack(filt_coef_sinr_r13_present, 1)); + + if (filt_coeff_rsrp_r15_present) { + HANDLE_CODE(filt_coeff_rsrp_r15.unpack(bref)); + } + if (filt_coeff_rsrq_r15_present) { + HANDLE_CODE(filt_coeff_rsrq_r15.unpack(bref)); + } + if (filt_coef_sinr_r13_present) { + HANDLE_CODE(filt_coef_sinr_r13.unpack(bref)); } + return SRSASN_SUCCESS; } -SRSASN_CODE rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::unpack(cbit_ref& bref) +void quant_cfg_rs_nr_r15_s::to_json(json_writer& j) const { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::release: - break; - case types::setup: - HANDLE_CODE(c.unpack(bref)); - break; - default: - log_invalid_choice_id(type_, "rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_"); - return SRSASN_ERROR_DECODE_FAIL; + j.start_obj(); + if (filt_coeff_rsrp_r15_present) { + j.write_str("filterCoeff-RSRP-r15", filt_coeff_rsrp_r15.to_string()); + } + if (filt_coeff_rsrq_r15_present) { + j.write_str("filterCoeff-RSRQ-r15", filt_coeff_rsrq_r15.to_string()); } - return SRSASN_SUCCESS; + if (filt_coef_sinr_r13_present) { + j.write_str("filterCoefficient-SINR-r13", filt_coef_sinr_r13.to_string()); + } + j.end_obj(); } -bool rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::operator==(const ssb_to_measure_r15_c_& other) const +bool quant_cfg_rs_nr_r15_s::operator==(const quant_cfg_rs_nr_r15_s& other) const { - return type() == other.type() and c == other.c; + return filt_coeff_rsrp_r15_present == other.filt_coeff_rsrp_r15_present and + (not filt_coeff_rsrp_r15_present or filt_coeff_rsrp_r15 == other.filt_coeff_rsrp_r15) and + filt_coeff_rsrq_r15_present == other.filt_coeff_rsrq_r15_present and + (not filt_coeff_rsrq_r15_present or filt_coeff_rsrq_r15 == other.filt_coeff_rsrq_r15) and + filt_coef_sinr_r13_present == other.filt_coef_sinr_r13_present and + (not filt_coef_sinr_r13_present or filt_coef_sinr_r13 == other.filt_coef_sinr_r13); } -// RSRQ-RangeConfig-r12 ::= CHOICE -void rsrq_range_cfg_r12_c::set(types::options e) +// RMTC-Config-r13 ::= CHOICE +void rmtc_cfg_r13_c::set(types::options e) { type_ = e; } -void rsrq_range_cfg_r12_c::set_release() +void rmtc_cfg_r13_c::set_release() { set(types::release); } -int8_t& rsrq_range_cfg_r12_c::set_setup() +rmtc_cfg_r13_c::setup_s_& rmtc_cfg_r13_c::set_setup() { set(types::setup); return c; } -void rsrq_range_cfg_r12_c::to_json(json_writer& j) const +void rmtc_cfg_r13_c::to_json(json_writer& j) const { j.start_obj(); switch (type_) { case types::release: break; case types::setup: - j.write_int("setup", c); + j.write_fieldname("setup"); + j.start_obj(); + j.write_str("rmtc-Period-r13", c.rmtc_period_r13.to_string()); + if (c.rmtc_sf_offset_r13_present) { + j.write_int("rmtc-SubframeOffset-r13", c.rmtc_sf_offset_r13); + } + j.write_str("measDuration-r13", c.meas_dur_r13.to_string()); + j.end_obj(); break; default: - log_invalid_choice_id(type_, "rsrq_range_cfg_r12_c"); + log_invalid_choice_id(type_, "rmtc_cfg_r13_c"); } j.end_obj(); } -SRSASN_CODE rsrq_range_cfg_r12_c::pack(bit_ref& bref) const +SRSASN_CODE rmtc_cfg_r13_c::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { case types::release: break; case types::setup: - HANDLE_CODE(pack_integer(bref, c, (int8_t)-30, (int8_t)46)); + bref.pack(c.ext, 1); + HANDLE_CODE(bref.pack(c.rmtc_sf_offset_r13_present, 1)); + HANDLE_CODE(c.rmtc_period_r13.pack(bref)); + if (c.rmtc_sf_offset_r13_present) { + HANDLE_CODE(pack_integer(bref, c.rmtc_sf_offset_r13, (uint16_t)0u, (uint16_t)639u)); + } + HANDLE_CODE(c.meas_dur_r13.pack(bref)); break; default: - log_invalid_choice_id(type_, "rsrq_range_cfg_r12_c"); + log_invalid_choice_id(type_, "rmtc_cfg_r13_c"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rsrq_range_cfg_r12_c::unpack(cbit_ref& bref) +SRSASN_CODE rmtc_cfg_r13_c::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -2918,399 +3466,719 @@ SRSASN_CODE rsrq_range_cfg_r12_c::unpack(cbit_ref& bref) case types::release: break; case types::setup: - HANDLE_CODE(unpack_integer(c, bref, (int8_t)-30, (int8_t)46)); + bref.unpack(c.ext, 1); + HANDLE_CODE(bref.unpack(c.rmtc_sf_offset_r13_present, 1)); + HANDLE_CODE(c.rmtc_period_r13.unpack(bref)); + if (c.rmtc_sf_offset_r13_present) { + HANDLE_CODE(unpack_integer(c.rmtc_sf_offset_r13, bref, (uint16_t)0u, (uint16_t)639u)); + } + HANDLE_CODE(c.meas_dur_r13.unpack(bref)); break; default: - log_invalid_choice_id(type_, "rsrq_range_cfg_r12_c"); + log_invalid_choice_id(type_, "rmtc_cfg_r13_c"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -bool rsrq_range_cfg_r12_c::operator==(const rsrq_range_cfg_r12_c& other) const +bool rmtc_cfg_r13_c::operator==(const rmtc_cfg_r13_c& other) const { - return type() == other.type() and c == other.c; + return type() == other.type() and c.ext == other.c.ext and c.rmtc_period_r13 == other.c.rmtc_period_r13 and + c.rmtc_sf_offset_r13_present == other.c.rmtc_sf_offset_r13_present and + (not c.rmtc_sf_offset_r13_present or c.rmtc_sf_offset_r13 == other.c.rmtc_sf_offset_r13) and + c.meas_dur_r13 == other.c.meas_dur_r13; } -// ReportInterval ::= ENUMERATED -const char* report_interv_opts::to_string() const +const char* rmtc_cfg_r13_c::setup_s_::rmtc_period_r13_opts::to_string() const { - static const char* options[] = {"ms120", - "ms240", - "ms480", - "ms640", - "ms1024", - "ms2048", - "ms5120", - "ms10240", - "min1", - "min6", - "min12", - "min30", - "min60", - "spare3", - "spare2", - "spare1"}; - return convert_enum_idx(options, 16, value, "report_interv_e"); + static const char* options[] = {"ms40", "ms80", "ms160", "ms320", "ms640"}; + return convert_enum_idx(options, 5, value, "rmtc_cfg_r13_c::setup_s_::rmtc_period_r13_e_"); } -uint16_t report_interv_opts::to_number() const +uint16_t rmtc_cfg_r13_c::setup_s_::rmtc_period_r13_opts::to_number() const { - static const uint16_t options[] = {120, 240, 480, 640, 1024, 2048, 5120, 10240, 1, 6, 12, 30, 60}; - return map_enum_number(options, 13, value, "report_interv_e"); + static const uint16_t options[] = {40, 80, 160, 320, 640}; + return map_enum_number(options, 5, value, "rmtc_cfg_r13_c::setup_s_::rmtc_period_r13_e_"); } -// ReportQuantityNR-r15 ::= SEQUENCE -SRSASN_CODE report_quant_nr_r15_s::pack(bit_ref& bref) const +const char* rmtc_cfg_r13_c::setup_s_::meas_dur_r13_opts::to_string() const { - HANDLE_CODE(bref.pack(ss_rsrp, 1)); - HANDLE_CODE(bref.pack(ss_rsrq, 1)); - HANDLE_CODE(bref.pack(ss_sinr, 1)); + static const char* options[] = {"sym1", "sym14", "sym28", "sym42", "sym70"}; + return convert_enum_idx(options, 5, value, "rmtc_cfg_r13_c::setup_s_::meas_dur_r13_e_"); +} +uint8_t rmtc_cfg_r13_c::setup_s_::meas_dur_r13_opts::to_number() const +{ + static const uint8_t options[] = {1, 14, 28, 42, 70}; + return map_enum_number(options, 5, value, "rmtc_cfg_r13_c::setup_s_::meas_dur_r13_e_"); +} + +// RMTC-ConfigNR-r16 ::= SEQUENCE +SRSASN_CODE rmtc_cfg_nr_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(rmtc_sf_offset_nr_r16_present, 1)); + HANDLE_CODE(rmtc_periodicity_nr_r16.pack(bref)); + if (rmtc_sf_offset_nr_r16_present) { + HANDLE_CODE(pack_integer(bref, rmtc_sf_offset_nr_r16, (uint16_t)0u, (uint16_t)639u)); + } + HANDLE_CODE(meas_dur_nr_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, rmtc_freq_nr_r16, (uint32_t)0u, (uint32_t)3279165u)); + HANDLE_CODE(ref_scs_cp_nr_r16.pack(bref)); + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= rmtc_bw_nr_r17_present; + group_flags[0] |= meas_dur_nr_r17_present; + group_flags[0] |= ref_scs_cp_nr_r17_present; + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(rmtc_bw_nr_r17_present, 1)); + HANDLE_CODE(bref.pack(meas_dur_nr_r17_present, 1)); + HANDLE_CODE(bref.pack(ref_scs_cp_nr_r17_present, 1)); + if (rmtc_bw_nr_r17_present) { + HANDLE_CODE(rmtc_bw_nr_r17.pack(bref)); + } + if (meas_dur_nr_r17_present) { + HANDLE_CODE(meas_dur_nr_r17.pack(bref)); + } + if (ref_scs_cp_nr_r17_present) { + HANDLE_CODE(ref_scs_cp_nr_r17.pack(bref)); + } + } + } return SRSASN_SUCCESS; } -SRSASN_CODE report_quant_nr_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE rmtc_cfg_nr_r16_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(ss_rsrp, 1)); - HANDLE_CODE(bref.unpack(ss_rsrq, 1)); - HANDLE_CODE(bref.unpack(ss_sinr, 1)); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(rmtc_sf_offset_nr_r16_present, 1)); + + HANDLE_CODE(rmtc_periodicity_nr_r16.unpack(bref)); + if (rmtc_sf_offset_nr_r16_present) { + HANDLE_CODE(unpack_integer(rmtc_sf_offset_nr_r16, bref, (uint16_t)0u, (uint16_t)639u)); + } + HANDLE_CODE(meas_dur_nr_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(rmtc_freq_nr_r16, bref, (uint32_t)0u, (uint32_t)3279165u)); + HANDLE_CODE(ref_scs_cp_nr_r16.unpack(bref)); + + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(bref.unpack(rmtc_bw_nr_r17_present, 1)); + HANDLE_CODE(bref.unpack(meas_dur_nr_r17_present, 1)); + HANDLE_CODE(bref.unpack(ref_scs_cp_nr_r17_present, 1)); + if (rmtc_bw_nr_r17_present) { + HANDLE_CODE(rmtc_bw_nr_r17.unpack(bref)); + } + if (meas_dur_nr_r17_present) { + HANDLE_CODE(meas_dur_nr_r17.unpack(bref)); + } + if (ref_scs_cp_nr_r17_present) { + HANDLE_CODE(ref_scs_cp_nr_r17.unpack(bref)); + } + } + } return SRSASN_SUCCESS; } -void report_quant_nr_r15_s::to_json(json_writer& j) const +void rmtc_cfg_nr_r16_s::to_json(json_writer& j) const { j.start_obj(); - j.write_bool("ss-rsrp", ss_rsrp); - j.write_bool("ss-rsrq", ss_rsrq); - j.write_bool("ss-sinr", ss_sinr); + j.write_str("rmtc-PeriodicityNR-r16", rmtc_periodicity_nr_r16.to_string()); + if (rmtc_sf_offset_nr_r16_present) { + j.write_int("rmtc-SubframeOffsetNR-r16", rmtc_sf_offset_nr_r16); + } + j.write_str("measDurationNR-r16", meas_dur_nr_r16.to_string()); + j.write_int("rmtc-FrequencyNR-r16", rmtc_freq_nr_r16); + j.write_str("refSCS-CP-NR-r16", ref_scs_cp_nr_r16.to_string()); + if (ext) { + if (rmtc_bw_nr_r17_present) { + j.write_str("rmtc-BandwidthNR-r17", rmtc_bw_nr_r17.to_string()); + } + if (meas_dur_nr_r17_present) { + j.write_str("measDurationNR-r17", meas_dur_nr_r17.to_string()); + } + if (ref_scs_cp_nr_r17_present) { + j.write_str("refSCS-CP-NR-r17", ref_scs_cp_nr_r17.to_string()); + } + } j.end_obj(); } -bool report_quant_nr_r15_s::operator==(const report_quant_nr_r15_s& other) const +bool rmtc_cfg_nr_r16_s::operator==(const rmtc_cfg_nr_r16_s& other) const { - return ss_rsrp == other.ss_rsrp and ss_rsrq == other.ss_rsrq and ss_sinr == other.ss_sinr; + return ext == other.ext and rmtc_periodicity_nr_r16 == other.rmtc_periodicity_nr_r16 and + rmtc_sf_offset_nr_r16_present == other.rmtc_sf_offset_nr_r16_present and + (not rmtc_sf_offset_nr_r16_present or rmtc_sf_offset_nr_r16 == other.rmtc_sf_offset_nr_r16) and + meas_dur_nr_r16 == other.meas_dur_nr_r16 and rmtc_freq_nr_r16 == other.rmtc_freq_nr_r16 and + ref_scs_cp_nr_r16 == other.ref_scs_cp_nr_r16 and + (not ext or (rmtc_bw_nr_r17_present == other.rmtc_bw_nr_r17_present and + (not rmtc_bw_nr_r17_present or rmtc_bw_nr_r17 == other.rmtc_bw_nr_r17) and + meas_dur_nr_r17_present == other.meas_dur_nr_r17_present and + (not meas_dur_nr_r17_present or meas_dur_nr_r17 == other.meas_dur_nr_r17) and + ref_scs_cp_nr_r17_present == other.ref_scs_cp_nr_r17_present and + (not ref_scs_cp_nr_r17_present or ref_scs_cp_nr_r17 == other.ref_scs_cp_nr_r17))); } -// ReportQuantityWLAN-r13 ::= SEQUENCE -SRSASN_CODE report_quant_wlan_r13_s::pack(bit_ref& bref) const +const char* rmtc_cfg_nr_r16_s::rmtc_periodicity_nr_r16_opts::to_string() const +{ + static const char* options[] = {"ms40", "ms80", "ms160", "ms320", "ms640"}; + return convert_enum_idx(options, 5, value, "rmtc_cfg_nr_r16_s::rmtc_periodicity_nr_r16_e_"); +} +uint16_t rmtc_cfg_nr_r16_s::rmtc_periodicity_nr_r16_opts::to_number() const +{ + static const uint16_t options[] = {40, 80, 160, 320, 640}; + return map_enum_number(options, 5, value, "rmtc_cfg_nr_r16_s::rmtc_periodicity_nr_r16_e_"); +} + +const char* rmtc_cfg_nr_r16_s::meas_dur_nr_r16_opts::to_string() const +{ + static const char* options[] = {"sym1", "sym14or12", "sym28or24", "sym42or36", "sym70or60"}; + return convert_enum_idx(options, 5, value, "rmtc_cfg_nr_r16_s::meas_dur_nr_r16_e_"); +} +uint8_t rmtc_cfg_nr_r16_s::meas_dur_nr_r16_opts::to_number() const +{ + static const uint8_t options[] = {1, 14, 28, 42, 70}; + return map_enum_number(options, 5, value, "rmtc_cfg_nr_r16_s::meas_dur_nr_r16_e_"); +} + +const char* rmtc_cfg_nr_r16_s::ref_scs_cp_nr_r16_opts::to_string() const +{ + static const char* options[] = {"kHz15", "kHz30", "kHz60-NCP", "kHz60-ECP"}; + return convert_enum_idx(options, 4, value, "rmtc_cfg_nr_r16_s::ref_scs_cp_nr_r16_e_"); +} + +const char* rmtc_cfg_nr_r16_s::rmtc_bw_nr_r17_opts::to_string() const +{ + static const char* options[] = {"mhz100", "mhz400", "mhz800", "mhz1600", "mhz2000"}; + return convert_enum_idx(options, 5, value, "rmtc_cfg_nr_r16_s::rmtc_bw_nr_r17_e_"); +} +uint16_t rmtc_cfg_nr_r16_s::rmtc_bw_nr_r17_opts::to_number() const +{ + static const uint16_t options[] = {100, 400, 800, 1600, 2000}; + return map_enum_number(options, 5, value, "rmtc_cfg_nr_r16_s::rmtc_bw_nr_r17_e_"); +} + +const char* rmtc_cfg_nr_r16_s::meas_dur_nr_r17_opts::to_string() const +{ + static const char* options[] = {"sym140", "sym560", "sym1120"}; + return convert_enum_idx(options, 3, value, "rmtc_cfg_nr_r16_s::meas_dur_nr_r17_e_"); +} +uint16_t rmtc_cfg_nr_r16_s::meas_dur_nr_r17_opts::to_number() const +{ + static const uint16_t options[] = {140, 560, 1120}; + return map_enum_number(options, 3, value, "rmtc_cfg_nr_r16_s::meas_dur_nr_r17_e_"); +} + +const char* rmtc_cfg_nr_r16_s::ref_scs_cp_nr_r17_opts::to_string() const +{ + static const char* options[] = {"kHz120", "kHz480", "kHz960"}; + return convert_enum_idx(options, 3, value, "rmtc_cfg_nr_r16_s::ref_scs_cp_nr_r17_e_"); +} +uint16_t rmtc_cfg_nr_r16_s::ref_scs_cp_nr_r17_opts::to_number() const +{ + static const uint16_t options[] = {120, 480, 960}; + return map_enum_number(options, 3, value, "rmtc_cfg_nr_r16_s::ref_scs_cp_nr_r17_e_"); +} + +// RS-ConfigSSB-NR-r15 ::= SEQUENCE +SRSASN_CODE rs_cfg_ssb_nr_r15_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(band_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.pack(carrier_info_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.pack(available_admission_capacity_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.pack(backhaul_dl_bw_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.pack(backhaul_ul_bw_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.pack(ch_utilization_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.pack(station_count_request_wlan_r13_present, 1)); + HANDLE_CODE(meas_timing_cfg_r15.pack(bref)); + HANDLE_CODE(subcarrier_spacing_ssb_r15.pack(bref)); + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= ssb_to_measure_r15.is_present(); + group_flags[1] |= ssb_position_qcl_common_nr_r16_present; + group_flags[1] |= ssb_position_qcl_cells_to_add_mod_list_nr_r16.is_present(); + group_flags[1] |= ssb_position_qcl_cells_to_rem_list_nr_r16.is_present(); + group_flags[2] |= subcarrier_spacing_ssb_r17_present; + group_flags[2] |= ssb_position_qcl_common_nr_r17_present; + group_flags[2] |= ssb_position_qcl_cells_to_add_mod_list_nr_r17.is_present(); + group_flags[2] |= ssb_position_qcl_cells_to_rem_list_nr_r17.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ssb_to_measure_r15.is_present(), 1)); + if (ssb_to_measure_r15.is_present()) { + HANDLE_CODE(ssb_to_measure_r15->pack(bref)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ssb_position_qcl_common_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(ssb_position_qcl_cells_to_add_mod_list_nr_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(ssb_position_qcl_cells_to_rem_list_nr_r16.is_present(), 1)); + if (ssb_position_qcl_common_nr_r16_present) { + HANDLE_CODE(ssb_position_qcl_common_nr_r16.pack(bref)); + } + if (ssb_position_qcl_cells_to_add_mod_list_nr_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *ssb_position_qcl_cells_to_add_mod_list_nr_r16, 1, 32)); + } + if (ssb_position_qcl_cells_to_rem_list_nr_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of( + bref, *ssb_position_qcl_cells_to_rem_list_nr_r16, 1, 32, integer_packer(0, 1007))); + } + } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(bref.pack(subcarrier_spacing_ssb_r17_present, 1)); + HANDLE_CODE(bref.pack(ssb_position_qcl_common_nr_r17_present, 1)); + HANDLE_CODE(bref.pack(ssb_position_qcl_cells_to_add_mod_list_nr_r17.is_present(), 1)); + HANDLE_CODE(bref.pack(ssb_position_qcl_cells_to_rem_list_nr_r17.is_present(), 1)); + if (subcarrier_spacing_ssb_r17_present) { + HANDLE_CODE(subcarrier_spacing_ssb_r17.pack(bref)); + } + if (ssb_position_qcl_common_nr_r17_present) { + HANDLE_CODE(ssb_position_qcl_common_nr_r17.pack(bref)); + } + if (ssb_position_qcl_cells_to_add_mod_list_nr_r17.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *ssb_position_qcl_cells_to_add_mod_list_nr_r17, 1, 32)); + } + if (ssb_position_qcl_cells_to_rem_list_nr_r17.is_present()) { + HANDLE_CODE(pack_dyn_seq_of( + bref, *ssb_position_qcl_cells_to_rem_list_nr_r17, 1, 32, integer_packer(0, 1007))); + } + } + } return SRSASN_SUCCESS; } -SRSASN_CODE report_quant_wlan_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE rs_cfg_ssb_nr_r15_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(band_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.unpack(carrier_info_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.unpack(available_admission_capacity_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.unpack(backhaul_dl_bw_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.unpack(backhaul_ul_bw_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.unpack(ch_utilization_request_wlan_r13_present, 1)); - HANDLE_CODE(bref.unpack(station_count_request_wlan_r13_present, 1)); + HANDLE_CODE(meas_timing_cfg_r15.unpack(bref)); + HANDLE_CODE(subcarrier_spacing_ssb_r15.unpack(bref)); + + if (ext) { + ext_groups_unpacker_guard group_flags(3); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool ssb_to_measure_r15_present; + HANDLE_CODE(bref.unpack(ssb_to_measure_r15_present, 1)); + ssb_to_measure_r15.set_present(ssb_to_measure_r15_present); + if (ssb_to_measure_r15.is_present()) { + HANDLE_CODE(ssb_to_measure_r15->unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(ssb_position_qcl_common_nr_r16_present, 1)); + bool ssb_position_qcl_cells_to_add_mod_list_nr_r16_present; + HANDLE_CODE(bref.unpack(ssb_position_qcl_cells_to_add_mod_list_nr_r16_present, 1)); + ssb_position_qcl_cells_to_add_mod_list_nr_r16.set_present(ssb_position_qcl_cells_to_add_mod_list_nr_r16_present); + bool ssb_position_qcl_cells_to_rem_list_nr_r16_present; + HANDLE_CODE(bref.unpack(ssb_position_qcl_cells_to_rem_list_nr_r16_present, 1)); + ssb_position_qcl_cells_to_rem_list_nr_r16.set_present(ssb_position_qcl_cells_to_rem_list_nr_r16_present); + if (ssb_position_qcl_common_nr_r16_present) { + HANDLE_CODE(ssb_position_qcl_common_nr_r16.unpack(bref)); + } + if (ssb_position_qcl_cells_to_add_mod_list_nr_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*ssb_position_qcl_cells_to_add_mod_list_nr_r16, bref, 1, 32)); + } + if (ssb_position_qcl_cells_to_rem_list_nr_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of( + *ssb_position_qcl_cells_to_rem_list_nr_r16, bref, 1, 32, integer_packer(0, 1007))); + } + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(bref.unpack(subcarrier_spacing_ssb_r17_present, 1)); + HANDLE_CODE(bref.unpack(ssb_position_qcl_common_nr_r17_present, 1)); + bool ssb_position_qcl_cells_to_add_mod_list_nr_r17_present; + HANDLE_CODE(bref.unpack(ssb_position_qcl_cells_to_add_mod_list_nr_r17_present, 1)); + ssb_position_qcl_cells_to_add_mod_list_nr_r17.set_present(ssb_position_qcl_cells_to_add_mod_list_nr_r17_present); + bool ssb_position_qcl_cells_to_rem_list_nr_r17_present; + HANDLE_CODE(bref.unpack(ssb_position_qcl_cells_to_rem_list_nr_r17_present, 1)); + ssb_position_qcl_cells_to_rem_list_nr_r17.set_present(ssb_position_qcl_cells_to_rem_list_nr_r17_present); + if (subcarrier_spacing_ssb_r17_present) { + HANDLE_CODE(subcarrier_spacing_ssb_r17.unpack(bref)); + } + if (ssb_position_qcl_common_nr_r17_present) { + HANDLE_CODE(ssb_position_qcl_common_nr_r17.unpack(bref)); + } + if (ssb_position_qcl_cells_to_add_mod_list_nr_r17.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*ssb_position_qcl_cells_to_add_mod_list_nr_r17, bref, 1, 32)); + } + if (ssb_position_qcl_cells_to_rem_list_nr_r17.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of( + *ssb_position_qcl_cells_to_rem_list_nr_r17, bref, 1, 32, integer_packer(0, 1007))); + } + } + } return SRSASN_SUCCESS; } -void report_quant_wlan_r13_s::to_json(json_writer& j) const +void rs_cfg_ssb_nr_r15_s::to_json(json_writer& j) const { j.start_obj(); - if (band_request_wlan_r13_present) { - j.write_str("bandRequestWLAN-r13", "true"); - } - if (carrier_info_request_wlan_r13_present) { - j.write_str("carrierInfoRequestWLAN-r13", "true"); - } - if (available_admission_capacity_request_wlan_r13_present) { - j.write_str("availableAdmissionCapacityRequestWLAN-r13", "true"); - } - if (backhaul_dl_bw_request_wlan_r13_present) { - j.write_str("backhaulDL-BandwidthRequestWLAN-r13", "true"); - } - if (backhaul_ul_bw_request_wlan_r13_present) { - j.write_str("backhaulUL-BandwidthRequestWLAN-r13", "true"); - } - if (ch_utilization_request_wlan_r13_present) { - j.write_str("channelUtilizationRequestWLAN-r13", "true"); - } - if (station_count_request_wlan_r13_present) { - j.write_str("stationCountRequestWLAN-r13", "true"); + j.write_fieldname("measTimingConfig-r15"); + meas_timing_cfg_r15.to_json(j); + j.write_str("subcarrierSpacingSSB-r15", subcarrier_spacing_ssb_r15.to_string()); + if (ext) { + if (ssb_to_measure_r15.is_present()) { + j.write_fieldname("ssb-ToMeasure-r15"); + ssb_to_measure_r15->to_json(j); + } + if (ssb_position_qcl_common_nr_r16_present) { + j.write_str("ssb-PositionQCL-CommonNR-r16", ssb_position_qcl_common_nr_r16.to_string()); + } + if (ssb_position_qcl_cells_to_add_mod_list_nr_r16.is_present()) { + j.start_array("ssb-PositionQCL-CellsToAddModListNR-r16"); + for (const auto& e1 : *ssb_position_qcl_cells_to_add_mod_list_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (ssb_position_qcl_cells_to_rem_list_nr_r16.is_present()) { + j.start_array("ssb-PositionQCL-CellsToRemoveListNR-r16"); + for (const auto& e1 : *ssb_position_qcl_cells_to_rem_list_nr_r16) { + j.write_int(e1); + } + j.end_array(); + } + if (subcarrier_spacing_ssb_r17_present) { + j.write_str("subcarrierSpacingSSB-r17", subcarrier_spacing_ssb_r17.to_string()); + } + if (ssb_position_qcl_common_nr_r17_present) { + j.write_str("ssb-PositionQCL-CommonNR-r17", ssb_position_qcl_common_nr_r17.to_string()); + } + if (ssb_position_qcl_cells_to_add_mod_list_nr_r17.is_present()) { + j.start_array("ssb-PositionQCL-CellsToAddModListNR-r17"); + for (const auto& e1 : *ssb_position_qcl_cells_to_add_mod_list_nr_r17) { + e1.to_json(j); + } + j.end_array(); + } + if (ssb_position_qcl_cells_to_rem_list_nr_r17.is_present()) { + j.start_array("ssb-PositionQCL-CellsToRemoveListNR-r17"); + for (const auto& e1 : *ssb_position_qcl_cells_to_rem_list_nr_r17) { + j.write_int(e1); + } + j.end_array(); + } } j.end_obj(); } -bool report_quant_wlan_r13_s::operator==(const report_quant_wlan_r13_s& other) const +bool rs_cfg_ssb_nr_r15_s::operator==(const rs_cfg_ssb_nr_r15_s& other) const { - return ext == other.ext and band_request_wlan_r13_present == other.band_request_wlan_r13_present and - carrier_info_request_wlan_r13_present == other.carrier_info_request_wlan_r13_present and - available_admission_capacity_request_wlan_r13_present == - other.available_admission_capacity_request_wlan_r13_present and - backhaul_dl_bw_request_wlan_r13_present == other.backhaul_dl_bw_request_wlan_r13_present and - backhaul_ul_bw_request_wlan_r13_present == other.backhaul_ul_bw_request_wlan_r13_present and - ch_utilization_request_wlan_r13_present == other.ch_utilization_request_wlan_r13_present and - station_count_request_wlan_r13_present == other.station_count_request_wlan_r13_present; + return ext == other.ext and meas_timing_cfg_r15 == other.meas_timing_cfg_r15 and + subcarrier_spacing_ssb_r15 == other.subcarrier_spacing_ssb_r15 and + (not ext or + (ssb_to_measure_r15.is_present() == other.ssb_to_measure_r15.is_present() and + (not ssb_to_measure_r15.is_present() or *ssb_to_measure_r15 == *other.ssb_to_measure_r15) and + ssb_position_qcl_common_nr_r16_present == other.ssb_position_qcl_common_nr_r16_present and + (not ssb_position_qcl_common_nr_r16_present or + ssb_position_qcl_common_nr_r16 == other.ssb_position_qcl_common_nr_r16) and + ssb_position_qcl_cells_to_add_mod_list_nr_r16.is_present() == + other.ssb_position_qcl_cells_to_add_mod_list_nr_r16.is_present() and + (not ssb_position_qcl_cells_to_add_mod_list_nr_r16.is_present() or + *ssb_position_qcl_cells_to_add_mod_list_nr_r16 == *other.ssb_position_qcl_cells_to_add_mod_list_nr_r16) and + ssb_position_qcl_cells_to_rem_list_nr_r16.is_present() == + other.ssb_position_qcl_cells_to_rem_list_nr_r16.is_present() and + (not ssb_position_qcl_cells_to_rem_list_nr_r16.is_present() or + *ssb_position_qcl_cells_to_rem_list_nr_r16 == *other.ssb_position_qcl_cells_to_rem_list_nr_r16) and + subcarrier_spacing_ssb_r17_present == other.subcarrier_spacing_ssb_r17_present and + (not subcarrier_spacing_ssb_r17_present or + subcarrier_spacing_ssb_r17 == other.subcarrier_spacing_ssb_r17) and + ssb_position_qcl_common_nr_r17_present == other.ssb_position_qcl_common_nr_r17_present and + (not ssb_position_qcl_common_nr_r17_present or + ssb_position_qcl_common_nr_r17 == other.ssb_position_qcl_common_nr_r17) and + ssb_position_qcl_cells_to_add_mod_list_nr_r17.is_present() == + other.ssb_position_qcl_cells_to_add_mod_list_nr_r17.is_present() and + (not ssb_position_qcl_cells_to_add_mod_list_nr_r17.is_present() or + *ssb_position_qcl_cells_to_add_mod_list_nr_r17 == *other.ssb_position_qcl_cells_to_add_mod_list_nr_r17) and + ssb_position_qcl_cells_to_rem_list_nr_r17.is_present() == + other.ssb_position_qcl_cells_to_rem_list_nr_r17.is_present() and + (not ssb_position_qcl_cells_to_rem_list_nr_r17.is_present() or + *ssb_position_qcl_cells_to_rem_list_nr_r17 == *other.ssb_position_qcl_cells_to_rem_list_nr_r17))); } -// ThresholdEUTRA ::= CHOICE -void thres_eutra_c::destroy_() {} -void thres_eutra_c::set(types::options e) +const char* rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::to_string() const { - destroy_(); - type_ = e; + static const char* options[] = {"kHz15", "kHz30", "kHz120", "kHz240"}; + return convert_enum_idx(options, 4, value, "rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_e_"); } -thres_eutra_c::thres_eutra_c(const thres_eutra_c& other) +uint8_t rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::to_number() const { - type_ = other.type(); - switch (type_) { - case types::thres_rsrp: - c.init(other.c.get()); - break; - case types::thres_rsrq: - c.init(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "thres_eutra_c"); - } + static const uint8_t options[] = {15, 30, 120, 240}; + return map_enum_number(options, 4, value, "rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_e_"); } -thres_eutra_c& thres_eutra_c::operator=(const thres_eutra_c& other) -{ - if (this == &other) { - return *this; - } - set(other.type()); - switch (type_) { - case types::thres_rsrp: - c.set(other.c.get()); - break; - case types::thres_rsrq: - c.set(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "thres_eutra_c"); - } - return *this; +void rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::set(types::options e) +{ + type_ = e; } -uint8_t& thres_eutra_c::set_thres_rsrp() +void rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::set_release() { - set(types::thres_rsrp); - return c.get(); + set(types::release); } -uint8_t& thres_eutra_c::set_thres_rsrq() +ssb_to_measure_r15_c& rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::set_setup() { - set(types::thres_rsrq); - return c.get(); + set(types::setup); + return c; } -void thres_eutra_c::to_json(json_writer& j) const +void rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::thres_rsrp: - j.write_int("threshold-RSRP", c.get()); + case types::release: break; - case types::thres_rsrq: - j.write_int("threshold-RSRQ", c.get()); + case types::setup: + j.write_fieldname("setup"); + c.to_json(j); break; default: - log_invalid_choice_id(type_, "thres_eutra_c"); + log_invalid_choice_id(type_, "rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_"); } j.end_obj(); } -SRSASN_CODE thres_eutra_c::pack(bit_ref& bref) const +SRSASN_CODE rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::thres_rsrp: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)97u)); + case types::release: break; - case types::thres_rsrq: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)34u)); + case types::setup: + HANDLE_CODE(c.pack(bref)); break; default: - log_invalid_choice_id(type_, "thres_eutra_c"); + log_invalid_choice_id(type_, "rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE thres_eutra_c::unpack(cbit_ref& bref) +SRSASN_CODE rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::thres_rsrp: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)97u)); + case types::release: break; - case types::thres_rsrq: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)34u)); + case types::setup: + HANDLE_CODE(c.unpack(bref)); break; default: - log_invalid_choice_id(type_, "thres_eutra_c"); + log_invalid_choice_id(type_, "rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -bool thres_eutra_c::operator==(const thres_eutra_c& other) const +bool rs_cfg_ssb_nr_r15_s::ssb_to_measure_r15_c_::operator==(const ssb_to_measure_r15_c_& other) const { - if (type_ != other.type_) { - return false; - } - switch (type_) { - case types::thres_rsrp: - return c.get() == other.c.get(); - case types::thres_rsrq: - return c.get() == other.c.get(); - default: - return true; - } - return true; + return type() == other.type() and c == other.c; } -// ThresholdNR-r15 ::= CHOICE -void thres_nr_r15_c::destroy_() {} -void thres_nr_r15_c::set(types::options e) +const char* rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r17_opts::to_string() const { - destroy_(); - type_ = e; + static const char* options[] = {"kHz480", "kHz960"}; + return convert_enum_idx(options, 2, value, "rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r17_e_"); } -thres_nr_r15_c::thres_nr_r15_c(const thres_nr_r15_c& other) +uint16_t rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r17_opts::to_number() const { - type_ = other.type(); - switch (type_) { - case types::nr_rsrp_r15: - c.init(other.c.get()); - break; - case types::nr_rsrq_r15: - c.init(other.c.get()); - break; - case types::nr_sinr_r15: - c.init(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "thres_nr_r15_c"); - } + static const uint16_t options[] = {480, 960}; + return map_enum_number(options, 2, value, "rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r17_e_"); } -thres_nr_r15_c& thres_nr_r15_c::operator=(const thres_nr_r15_c& other) -{ - if (this == &other) { - return *this; - } - set(other.type()); - switch (type_) { - case types::nr_rsrp_r15: - c.set(other.c.get()); - break; - case types::nr_rsrq_r15: - c.set(other.c.get()); - break; - case types::nr_sinr_r15: - c.set(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "thres_nr_r15_c"); - } - return *this; -} -uint8_t& thres_nr_r15_c::set_nr_rsrp_r15() +// RSRQ-RangeConfig-r12 ::= CHOICE +void rsrq_range_cfg_r12_c::set(types::options e) { - set(types::nr_rsrp_r15); - return c.get(); + type_ = e; } -uint8_t& thres_nr_r15_c::set_nr_rsrq_r15() +void rsrq_range_cfg_r12_c::set_release() { - set(types::nr_rsrq_r15); - return c.get(); + set(types::release); } -uint8_t& thres_nr_r15_c::set_nr_sinr_r15() +int8_t& rsrq_range_cfg_r12_c::set_setup() { - set(types::nr_sinr_r15); - return c.get(); + set(types::setup); + return c; } -void thres_nr_r15_c::to_json(json_writer& j) const +void rsrq_range_cfg_r12_c::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::nr_rsrp_r15: - j.write_int("nr-RSRP-r15", c.get()); - break; - case types::nr_rsrq_r15: - j.write_int("nr-RSRQ-r15", c.get()); - break; - case types::nr_sinr_r15: - j.write_int("nr-SINR-r15", c.get()); + case types::release: + break; + case types::setup: + j.write_int("setup", c); break; default: - log_invalid_choice_id(type_, "thres_nr_r15_c"); + log_invalid_choice_id(type_, "rsrq_range_cfg_r12_c"); } j.end_obj(); } -SRSASN_CODE thres_nr_r15_c::pack(bit_ref& bref) const +SRSASN_CODE rsrq_range_cfg_r12_c::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::nr_rsrp_r15: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); - break; - case types::nr_rsrq_r15: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + case types::release: break; - case types::nr_sinr_r15: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + case types::setup: + HANDLE_CODE(pack_integer(bref, c, (int8_t)-30, (int8_t)46)); break; default: - log_invalid_choice_id(type_, "thres_nr_r15_c"); + log_invalid_choice_id(type_, "rsrq_range_cfg_r12_c"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE thres_nr_r15_c::unpack(cbit_ref& bref) +SRSASN_CODE rsrq_range_cfg_r12_c::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::nr_rsrp_r15: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); - break; - case types::nr_rsrq_r15: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + case types::release: break; - case types::nr_sinr_r15: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + case types::setup: + HANDLE_CODE(unpack_integer(c, bref, (int8_t)-30, (int8_t)46)); break; default: - log_invalid_choice_id(type_, "thres_nr_r15_c"); + log_invalid_choice_id(type_, "rsrq_range_cfg_r12_c"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -bool thres_nr_r15_c::operator==(const thres_nr_r15_c& other) const +bool rsrq_range_cfg_r12_c::operator==(const rsrq_range_cfg_r12_c& other) const { - if (type_ != other.type_) { - return false; + return type() == other.type() and c == other.c; +} + +// ReportInterval ::= ENUMERATED +const char* report_interv_opts::to_string() const +{ + static const char* options[] = {"ms120", + "ms240", + "ms480", + "ms640", + "ms1024", + "ms2048", + "ms5120", + "ms10240", + "min1", + "min6", + "min12", + "min30", + "min60", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 16, value, "report_interv_e"); +} +uint16_t report_interv_opts::to_number() const +{ + static const uint16_t options[] = {120, 240, 480, 640, 1024, 2048, 5120, 10240, 1, 6, 12, 30, 60}; + return map_enum_number(options, 13, value, "report_interv_e"); +} + +// ReportQuantityNR-r15 ::= SEQUENCE +SRSASN_CODE report_quant_nr_r15_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ss_rsrp, 1)); + HANDLE_CODE(bref.pack(ss_rsrq, 1)); + HANDLE_CODE(bref.pack(ss_sinr, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE report_quant_nr_r15_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ss_rsrp, 1)); + HANDLE_CODE(bref.unpack(ss_rsrq, 1)); + HANDLE_CODE(bref.unpack(ss_sinr, 1)); + + return SRSASN_SUCCESS; +} +void report_quant_nr_r15_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_bool("ss-rsrp", ss_rsrp); + j.write_bool("ss-rsrq", ss_rsrq); + j.write_bool("ss-sinr", ss_sinr); + j.end_obj(); +} +bool report_quant_nr_r15_s::operator==(const report_quant_nr_r15_s& other) const +{ + return ss_rsrp == other.ss_rsrp and ss_rsrq == other.ss_rsrq and ss_sinr == other.ss_sinr; +} + +// ReportQuantityWLAN-r13 ::= SEQUENCE +SRSASN_CODE report_quant_wlan_r13_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(band_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.pack(carrier_info_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.pack(available_admission_capacity_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.pack(backhaul_dl_bw_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.pack(backhaul_ul_bw_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.pack(ch_utilization_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.pack(station_count_request_wlan_r13_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE report_quant_wlan_r13_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(band_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.unpack(carrier_info_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.unpack(available_admission_capacity_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.unpack(backhaul_dl_bw_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.unpack(backhaul_ul_bw_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.unpack(ch_utilization_request_wlan_r13_present, 1)); + HANDLE_CODE(bref.unpack(station_count_request_wlan_r13_present, 1)); + + return SRSASN_SUCCESS; +} +void report_quant_wlan_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (band_request_wlan_r13_present) { + j.write_str("bandRequestWLAN-r13", "true"); } - switch (type_) { - case types::nr_rsrp_r15: - return c.get() == other.c.get(); - case types::nr_rsrq_r15: - return c.get() == other.c.get(); - case types::nr_sinr_r15: - return c.get() == other.c.get(); - default: - return true; + if (carrier_info_request_wlan_r13_present) { + j.write_str("carrierInfoRequestWLAN-r13", "true"); } - return true; + if (available_admission_capacity_request_wlan_r13_present) { + j.write_str("availableAdmissionCapacityRequestWLAN-r13", "true"); + } + if (backhaul_dl_bw_request_wlan_r13_present) { + j.write_str("backhaulDL-BandwidthRequestWLAN-r13", "true"); + } + if (backhaul_ul_bw_request_wlan_r13_present) { + j.write_str("backhaulUL-BandwidthRequestWLAN-r13", "true"); + } + if (ch_utilization_request_wlan_r13_present) { + j.write_str("channelUtilizationRequestWLAN-r13", "true"); + } + if (station_count_request_wlan_r13_present) { + j.write_str("stationCountRequestWLAN-r13", "true"); + } + j.end_obj(); +} +bool report_quant_wlan_r13_s::operator==(const report_quant_wlan_r13_s& other) const +{ + return ext == other.ext and band_request_wlan_r13_present == other.band_request_wlan_r13_present and + carrier_info_request_wlan_r13_present == other.carrier_info_request_wlan_r13_present and + available_admission_capacity_request_wlan_r13_present == + other.available_admission_capacity_request_wlan_r13_present and + backhaul_dl_bw_request_wlan_r13_present == other.backhaul_dl_bw_request_wlan_r13_present and + backhaul_ul_bw_request_wlan_r13_present == other.backhaul_ul_bw_request_wlan_r13_present and + ch_utilization_request_wlan_r13_present == other.ch_utilization_request_wlan_r13_present and + station_count_request_wlan_r13_present == other.station_count_request_wlan_r13_present; } // ThresholdUTRA ::= CHOICE @@ -3432,33 +4300,6 @@ bool thres_utra_c::operator==(const thres_utra_c& other) const return true; } -// TimeToTrigger ::= ENUMERATED -const char* time_to_trigger_opts::to_string() const -{ - static const char* options[] = {"ms0", - "ms40", - "ms64", - "ms80", - "ms100", - "ms128", - "ms160", - "ms256", - "ms320", - "ms480", - "ms512", - "ms640", - "ms1024", - "ms1280", - "ms2560", - "ms5120"}; - return convert_enum_idx(options, 16, value, "time_to_trigger_e"); -} -uint16_t time_to_trigger_opts::to_number() const -{ - static const uint16_t options[] = {0, 40, 64, 80, 100, 128, 160, 256, 320, 480, 512, 640, 1024, 1280, 2560, 5120}; - return map_enum_number(options, 16, value, "time_to_trigger_e"); -} - // UL-DelayConfig-r13 ::= CHOICE void ul_delay_cfg_r13_c::set(types::options e) { @@ -3553,6 +4394,78 @@ uint16_t ul_delay_cfg_r13_c::setup_s_::delay_thres_r13_opts::to_number() const return map_enum_number(options, 12, value, "ul_delay_cfg_r13_c::setup_s_::delay_thres_r13_e_"); } +// UL-DelayValueConfig-r16 ::= CHOICE +void ul_delay_value_cfg_r16_c::set(types::options e) +{ + type_ = e; +} +void ul_delay_value_cfg_r16_c::set_release() +{ + set(types::release); +} +ul_delay_value_cfg_r16_c::setup_s_& ul_delay_value_cfg_r16_c::set_setup() +{ + set(types::setup); + return c; +} +void ul_delay_value_cfg_r16_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::release: + break; + case types::setup: + j.write_fieldname("setup"); + j.start_obj(); + j.start_array("delay-DRBlist-r16"); + for (const auto& e1 : c.delay_dr_blist_r16) { + j.write_int(e1); + } + j.end_array(); + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "ul_delay_value_cfg_r16_c"); + } + j.end_obj(); +} +SRSASN_CODE ul_delay_value_cfg_r16_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(pack_dyn_seq_of(bref, c.delay_dr_blist_r16, 1, 11, integer_packer(1, 32))); + break; + default: + log_invalid_choice_id(type_, "ul_delay_value_cfg_r16_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ul_delay_value_cfg_r16_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(unpack_dyn_seq_of(c.delay_dr_blist_r16, bref, 1, 11, integer_packer(1, 32))); + break; + default: + log_invalid_choice_id(type_, "ul_delay_value_cfg_r16_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +bool ul_delay_value_cfg_r16_c::operator==(const ul_delay_value_cfg_r16_c& other) const +{ + return type() == other.type() and c.delay_dr_blist_r16 == other.c.delay_dr_blist_r16; +} + // WLAN-CarrierInfo-r13 ::= SEQUENCE SRSASN_CODE wlan_carrier_info_r13_s::pack(bit_ref& bref) const { @@ -3832,8 +4745,8 @@ SRSASN_CODE meas_obj_eutra_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(offset_freq_present, 1)); HANDLE_CODE(bref.pack(cells_to_rem_list_present, 1)); HANDLE_CODE(bref.pack(cells_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(black_cells_to_rem_list_present, 1)); - HANDLE_CODE(bref.pack(black_cells_to_add_mod_list_present, 1)); + HANDLE_CODE(bref.pack(excluded_cells_to_rem_list_present, 1)); + HANDLE_CODE(bref.pack(excluded_cells_to_add_mod_list_present, 1)); HANDLE_CODE(bref.pack(cell_for_which_to_report_cgi_present, 1)); HANDLE_CODE(pack_integer(bref, carrier_freq, (uint32_t)0u, (uint32_t)65535u)); @@ -3849,11 +4762,11 @@ SRSASN_CODE meas_obj_eutra_s::pack(bit_ref& bref) const if (cells_to_add_mod_list_present) { HANDLE_CODE(pack_dyn_seq_of(bref, cells_to_add_mod_list, 1, 32)); } - if (black_cells_to_rem_list_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, black_cells_to_rem_list, 1, 32, integer_packer(1, 32))); + if (excluded_cells_to_rem_list_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, excluded_cells_to_rem_list, 1, 32, integer_packer(1, 32))); } - if (black_cells_to_add_mod_list_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, black_cells_to_add_mod_list, 1, 32)); + if (excluded_cells_to_add_mod_list_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, excluded_cells_to_add_mod_list, 1, 32)); } if (cell_for_which_to_report_cgi_present) { HANDLE_CODE(pack_integer(bref, cell_for_which_to_report_cgi, (uint16_t)0u, (uint16_t)503u)); @@ -3869,14 +4782,15 @@ SRSASN_CODE meas_obj_eutra_s::pack(bit_ref& bref) const group_flags[2] |= t312_r12.is_present(); group_flags[2] |= reduced_meas_performance_r12_present; group_flags[2] |= meas_ds_cfg_r12.is_present(); - group_flags[3] |= white_cells_to_rem_list_r13.is_present(); - group_flags[3] |= white_cells_to_add_mod_list_r13.is_present(); + group_flags[3] |= allowed_cells_to_rem_list_r13.is_present(); + group_flags[3] |= allowed_cells_to_add_mod_list_r13.is_present(); group_flags[3] |= rmtc_cfg_r13.is_present(); group_flags[3] |= carrier_freq_r13_present; group_flags[4] |= tx_res_pool_to_rem_list_r14.is_present(); group_flags[4] |= tx_res_pool_to_add_list_r14.is_present(); group_flags[4] |= fembms_mixed_carrier_r14_present; group_flags[5] |= meas_sensing_cfg_r15.is_present(); + group_flags[6] |= meas_rss_ded_cfg_r16.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -3926,15 +4840,15 @@ SRSASN_CODE meas_obj_eutra_s::pack(bit_ref& bref) const if (group_flags[3]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(white_cells_to_rem_list_r13.is_present(), 1)); - HANDLE_CODE(bref.pack(white_cells_to_add_mod_list_r13.is_present(), 1)); + HANDLE_CODE(bref.pack(allowed_cells_to_rem_list_r13.is_present(), 1)); + HANDLE_CODE(bref.pack(allowed_cells_to_add_mod_list_r13.is_present(), 1)); HANDLE_CODE(bref.pack(rmtc_cfg_r13.is_present(), 1)); HANDLE_CODE(bref.pack(carrier_freq_r13_present, 1)); - if (white_cells_to_rem_list_r13.is_present()) { - HANDLE_CODE(pack_dyn_seq_of(bref, *white_cells_to_rem_list_r13, 1, 32, integer_packer(1, 32))); + if (allowed_cells_to_rem_list_r13.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *allowed_cells_to_rem_list_r13, 1, 32, integer_packer(1, 32))); } - if (white_cells_to_add_mod_list_r13.is_present()) { - HANDLE_CODE(pack_dyn_seq_of(bref, *white_cells_to_add_mod_list_r13, 1, 32)); + if (allowed_cells_to_add_mod_list_r13.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *allowed_cells_to_add_mod_list_r13, 1, 32)); } if (rmtc_cfg_r13.is_present()) { HANDLE_CODE(rmtc_cfg_r13->pack(bref)); @@ -3967,6 +4881,14 @@ SRSASN_CODE meas_obj_eutra_s::pack(bit_ref& bref) const HANDLE_CODE(meas_sensing_cfg_r15->pack(bref)); } } + if (group_flags[6]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(meas_rss_ded_cfg_r16.is_present(), 1)); + if (meas_rss_ded_cfg_r16.is_present()) { + HANDLE_CODE(meas_rss_ded_cfg_r16->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -3976,8 +4898,8 @@ SRSASN_CODE meas_obj_eutra_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(offset_freq_present, 1)); HANDLE_CODE(bref.unpack(cells_to_rem_list_present, 1)); HANDLE_CODE(bref.unpack(cells_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.unpack(black_cells_to_rem_list_present, 1)); - HANDLE_CODE(bref.unpack(black_cells_to_add_mod_list_present, 1)); + HANDLE_CODE(bref.unpack(excluded_cells_to_rem_list_present, 1)); + HANDLE_CODE(bref.unpack(excluded_cells_to_add_mod_list_present, 1)); HANDLE_CODE(bref.unpack(cell_for_which_to_report_cgi_present, 1)); HANDLE_CODE(unpack_integer(carrier_freq, bref, (uint32_t)0u, (uint32_t)65535u)); @@ -3993,18 +4915,18 @@ SRSASN_CODE meas_obj_eutra_s::unpack(cbit_ref& bref) if (cells_to_add_mod_list_present) { HANDLE_CODE(unpack_dyn_seq_of(cells_to_add_mod_list, bref, 1, 32)); } - if (black_cells_to_rem_list_present) { - HANDLE_CODE(unpack_dyn_seq_of(black_cells_to_rem_list, bref, 1, 32, integer_packer(1, 32))); + if (excluded_cells_to_rem_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(excluded_cells_to_rem_list, bref, 1, 32, integer_packer(1, 32))); } - if (black_cells_to_add_mod_list_present) { - HANDLE_CODE(unpack_dyn_seq_of(black_cells_to_add_mod_list, bref, 1, 32)); + if (excluded_cells_to_add_mod_list_present) { + HANDLE_CODE(unpack_dyn_seq_of(excluded_cells_to_add_mod_list, bref, 1, 32)); } if (cell_for_which_to_report_cgi_present) { HANDLE_CODE(unpack_integer(cell_for_which_to_report_cgi, bref, (uint16_t)0u, (uint16_t)503u)); } if (ext) { - ext_groups_unpacker_guard group_flags(6); + ext_groups_unpacker_guard group_flags(7); group_flags.unpack(bref); if (group_flags[0]) { @@ -4064,21 +4986,21 @@ SRSASN_CODE meas_obj_eutra_s::unpack(cbit_ref& bref) if (group_flags[3]) { varlength_field_unpack_guard varlen_scope(bref, false); - bool white_cells_to_rem_list_r13_present; - HANDLE_CODE(bref.unpack(white_cells_to_rem_list_r13_present, 1)); - white_cells_to_rem_list_r13.set_present(white_cells_to_rem_list_r13_present); - bool white_cells_to_add_mod_list_r13_present; - HANDLE_CODE(bref.unpack(white_cells_to_add_mod_list_r13_present, 1)); - white_cells_to_add_mod_list_r13.set_present(white_cells_to_add_mod_list_r13_present); + bool allowed_cells_to_rem_list_r13_present; + HANDLE_CODE(bref.unpack(allowed_cells_to_rem_list_r13_present, 1)); + allowed_cells_to_rem_list_r13.set_present(allowed_cells_to_rem_list_r13_present); + bool allowed_cells_to_add_mod_list_r13_present; + HANDLE_CODE(bref.unpack(allowed_cells_to_add_mod_list_r13_present, 1)); + allowed_cells_to_add_mod_list_r13.set_present(allowed_cells_to_add_mod_list_r13_present); bool rmtc_cfg_r13_present; HANDLE_CODE(bref.unpack(rmtc_cfg_r13_present, 1)); rmtc_cfg_r13.set_present(rmtc_cfg_r13_present); HANDLE_CODE(bref.unpack(carrier_freq_r13_present, 1)); - if (white_cells_to_rem_list_r13.is_present()) { - HANDLE_CODE(unpack_dyn_seq_of(*white_cells_to_rem_list_r13, bref, 1, 32, integer_packer(1, 32))); + if (allowed_cells_to_rem_list_r13.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*allowed_cells_to_rem_list_r13, bref, 1, 32, integer_packer(1, 32))); } - if (white_cells_to_add_mod_list_r13.is_present()) { - HANDLE_CODE(unpack_dyn_seq_of(*white_cells_to_add_mod_list_r13, bref, 1, 32)); + if (allowed_cells_to_add_mod_list_r13.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*allowed_cells_to_add_mod_list_r13, bref, 1, 32)); } if (rmtc_cfg_r13.is_present()) { HANDLE_CODE(rmtc_cfg_r13->unpack(bref)); @@ -4117,6 +5039,16 @@ SRSASN_CODE meas_obj_eutra_s::unpack(cbit_ref& bref) HANDLE_CODE(meas_sensing_cfg_r15->unpack(bref)); } } + if (group_flags[6]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool meas_rss_ded_cfg_r16_present; + HANDLE_CODE(bref.unpack(meas_rss_ded_cfg_r16_present, 1)); + meas_rss_ded_cfg_r16.set_present(meas_rss_ded_cfg_r16_present); + if (meas_rss_ded_cfg_r16.is_present()) { + HANDLE_CODE(meas_rss_ded_cfg_r16->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -4144,16 +5076,16 @@ void meas_obj_eutra_s::to_json(json_writer& j) const } j.end_array(); } - if (black_cells_to_rem_list_present) { - j.start_array("blackCellsToRemoveList"); - for (const auto& e1 : black_cells_to_rem_list) { + if (excluded_cells_to_rem_list_present) { + j.start_array("excludedCellsToRemoveList"); + for (const auto& e1 : excluded_cells_to_rem_list) { j.write_int(e1); } j.end_array(); } - if (black_cells_to_add_mod_list_present) { - j.start_array("blackCellsToAddModList"); - for (const auto& e1 : black_cells_to_add_mod_list) { + if (excluded_cells_to_add_mod_list_present) { + j.start_array("excludedCellsToAddModList"); + for (const auto& e1 : excluded_cells_to_add_mod_list) { e1.to_json(j); } j.end_array(); @@ -4197,16 +5129,16 @@ void meas_obj_eutra_s::to_json(json_writer& j) const j.write_fieldname("measDS-Config-r12"); meas_ds_cfg_r12->to_json(j); } - if (white_cells_to_rem_list_r13.is_present()) { - j.start_array("whiteCellsToRemoveList-r13"); - for (const auto& e1 : *white_cells_to_rem_list_r13) { + if (allowed_cells_to_rem_list_r13.is_present()) { + j.start_array("allowedCellsToRemoveList-r13"); + for (const auto& e1 : *allowed_cells_to_rem_list_r13) { j.write_int(e1); } j.end_array(); } - if (white_cells_to_add_mod_list_r13.is_present()) { - j.start_array("whiteCellsToAddModList-r13"); - for (const auto& e1 : *white_cells_to_add_mod_list_r13) { + if (allowed_cells_to_add_mod_list_r13.is_present()) { + j.start_array("allowedCellsToAddModList-r13"); + for (const auto& e1 : *allowed_cells_to_add_mod_list_r13) { e1.to_json(j); } j.end_array(); @@ -4239,6 +5171,10 @@ void meas_obj_eutra_s::to_json(json_writer& j) const j.write_fieldname("measSensing-Config-r15"); meas_sensing_cfg_r15->to_json(j); } + if (meas_rss_ded_cfg_r16.is_present()) { + j.write_fieldname("measRSS-DedicatedConfig-r16"); + meas_rss_ded_cfg_r16->to_json(j); + } } j.end_obj(); } @@ -4252,11 +5188,11 @@ bool meas_obj_eutra_s::operator==(const meas_obj_eutra_s& other) const (not cells_to_rem_list_present or cells_to_rem_list == other.cells_to_rem_list) and cells_to_add_mod_list_present == other.cells_to_add_mod_list_present and (not cells_to_add_mod_list_present or cells_to_add_mod_list == other.cells_to_add_mod_list) and - black_cells_to_rem_list_present == other.black_cells_to_rem_list_present and - (not black_cells_to_rem_list_present or black_cells_to_rem_list == other.black_cells_to_rem_list) and - black_cells_to_add_mod_list_present == other.black_cells_to_add_mod_list_present and - (not black_cells_to_add_mod_list_present or - black_cells_to_add_mod_list == other.black_cells_to_add_mod_list) and + excluded_cells_to_rem_list_present == other.excluded_cells_to_rem_list_present and + (not excluded_cells_to_rem_list_present or excluded_cells_to_rem_list == other.excluded_cells_to_rem_list) and + excluded_cells_to_add_mod_list_present == other.excluded_cells_to_add_mod_list_present and + (not excluded_cells_to_add_mod_list_present or + excluded_cells_to_add_mod_list == other.excluded_cells_to_add_mod_list) and cell_for_which_to_report_cgi_present == other.cell_for_which_to_report_cgi_present and (not cell_for_which_to_report_cgi_present or cell_for_which_to_report_cgi == other.cell_for_which_to_report_cgi) and @@ -4281,12 +5217,12 @@ bool meas_obj_eutra_s::operator==(const meas_obj_eutra_s& other) const reduced_meas_performance_r12 == other.reduced_meas_performance_r12) and meas_ds_cfg_r12.is_present() == other.meas_ds_cfg_r12.is_present() and (not meas_ds_cfg_r12.is_present() or *meas_ds_cfg_r12 == *other.meas_ds_cfg_r12) and - white_cells_to_rem_list_r13.is_present() == other.white_cells_to_rem_list_r13.is_present() and - (not white_cells_to_rem_list_r13.is_present() or - *white_cells_to_rem_list_r13 == *other.white_cells_to_rem_list_r13) and - white_cells_to_add_mod_list_r13.is_present() == other.white_cells_to_add_mod_list_r13.is_present() and - (not white_cells_to_add_mod_list_r13.is_present() or - *white_cells_to_add_mod_list_r13 == *other.white_cells_to_add_mod_list_r13) and + allowed_cells_to_rem_list_r13.is_present() == other.allowed_cells_to_rem_list_r13.is_present() and + (not allowed_cells_to_rem_list_r13.is_present() or + *allowed_cells_to_rem_list_r13 == *other.allowed_cells_to_rem_list_r13) and + allowed_cells_to_add_mod_list_r13.is_present() == other.allowed_cells_to_add_mod_list_r13.is_present() and + (not allowed_cells_to_add_mod_list_r13.is_present() or + *allowed_cells_to_add_mod_list_r13 == *other.allowed_cells_to_add_mod_list_r13) and rmtc_cfg_r13.is_present() == other.rmtc_cfg_r13.is_present() and (not rmtc_cfg_r13.is_present() or *rmtc_cfg_r13 == *other.rmtc_cfg_r13) and carrier_freq_r13_present == other.carrier_freq_r13_present and @@ -4300,7 +5236,9 @@ bool meas_obj_eutra_s::operator==(const meas_obj_eutra_s& other) const fembms_mixed_carrier_r14_present == other.fembms_mixed_carrier_r14_present and (not fembms_mixed_carrier_r14_present or fembms_mixed_carrier_r14 == other.fembms_mixed_carrier_r14) and meas_sensing_cfg_r15.is_present() == other.meas_sensing_cfg_r15.is_present() and - (not meas_sensing_cfg_r15.is_present() or *meas_sensing_cfg_r15 == *other.meas_sensing_cfg_r15))); + (not meas_sensing_cfg_r15.is_present() or *meas_sensing_cfg_r15 == *other.meas_sensing_cfg_r15) and + meas_rss_ded_cfg_r16.is_present() == other.meas_rss_ded_cfg_r16.is_present() and + (not meas_rss_ded_cfg_r16.is_present() or *meas_rss_ded_cfg_r16 == *other.meas_rss_ded_cfg_r16))); } void meas_obj_eutra_s::t312_r12_c_::set(types::options e) @@ -4475,8 +5413,8 @@ SRSASN_CODE meas_obj_nr_r15_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(thresh_rs_idx_r15_present, 1)); HANDLE_CODE(bref.pack(max_rs_idx_cell_qual_r15_present, 1)); HANDLE_CODE(bref.pack(offset_freq_r15_present, 1)); - HANDLE_CODE(bref.pack(black_cells_to_rem_list_r15_present, 1)); - HANDLE_CODE(bref.pack(black_cells_to_add_mod_list_r15_present, 1)); + HANDLE_CODE(bref.pack(excluded_cells_to_rem_list_r15_present, 1)); + HANDLE_CODE(bref.pack(excluded_cells_to_add_mod_list_r15_present, 1)); HANDLE_CODE(bref.pack(cells_for_which_to_report_sftd_r15_present, 1)); HANDLE_CODE(pack_integer(bref, carrier_freq_r15, (uint32_t)0u, (uint32_t)3279165u)); @@ -4490,11 +5428,11 @@ SRSASN_CODE meas_obj_nr_r15_s::pack(bit_ref& bref) const if (offset_freq_r15_present) { HANDLE_CODE(pack_integer(bref, offset_freq_r15, (int8_t)-15, (int8_t)15)); } - if (black_cells_to_rem_list_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, black_cells_to_rem_list_r15, 1, 32, integer_packer(1, 32))); + if (excluded_cells_to_rem_list_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, excluded_cells_to_rem_list_r15, 1, 32, integer_packer(1, 32))); } - if (black_cells_to_add_mod_list_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, black_cells_to_add_mod_list_r15, 1, 32)); + if (excluded_cells_to_add_mod_list_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, excluded_cells_to_add_mod_list_r15, 1, 32)); } HANDLE_CODE(pack_integer(bref, quant_cfg_set_r15, (uint8_t)1u, (uint8_t)2u)); if (cells_for_which_to_report_sftd_r15_present) { @@ -4507,6 +5445,9 @@ SRSASN_CODE meas_obj_nr_r15_s::pack(bit_ref& bref) const group_flags[0] |= derive_ssb_idx_from_cell_r15_present; group_flags[0] |= ss_rssi_meas_r15.is_present(); group_flags[0] |= band_nr_r15.is_present(); + group_flags[1] |= rmtc_cfg_nr_r16.is_present(); + group_flags[2] |= cells_to_rem_list_r16.is_present(); + group_flags[2] |= cells_to_add_mod_list_r16.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -4529,6 +5470,26 @@ SRSASN_CODE meas_obj_nr_r15_s::pack(bit_ref& bref) const HANDLE_CODE(band_nr_r15->pack(bref)); } } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(rmtc_cfg_nr_r16.is_present(), 1)); + if (rmtc_cfg_nr_r16.is_present()) { + HANDLE_CODE(rmtc_cfg_nr_r16->pack(bref)); + } + } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(cells_to_rem_list_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(cells_to_add_mod_list_r16.is_present(), 1)); + if (cells_to_rem_list_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *cells_to_rem_list_r16, 1, 32, integer_packer(1, 32))); + } + if (cells_to_add_mod_list_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *cells_to_add_mod_list_r16, 1, 32)); + } + } } return SRSASN_SUCCESS; } @@ -4538,8 +5499,8 @@ SRSASN_CODE meas_obj_nr_r15_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(thresh_rs_idx_r15_present, 1)); HANDLE_CODE(bref.unpack(max_rs_idx_cell_qual_r15_present, 1)); HANDLE_CODE(bref.unpack(offset_freq_r15_present, 1)); - HANDLE_CODE(bref.unpack(black_cells_to_rem_list_r15_present, 1)); - HANDLE_CODE(bref.unpack(black_cells_to_add_mod_list_r15_present, 1)); + HANDLE_CODE(bref.unpack(excluded_cells_to_rem_list_r15_present, 1)); + HANDLE_CODE(bref.unpack(excluded_cells_to_add_mod_list_r15_present, 1)); HANDLE_CODE(bref.unpack(cells_for_which_to_report_sftd_r15_present, 1)); HANDLE_CODE(unpack_integer(carrier_freq_r15, bref, (uint32_t)0u, (uint32_t)3279165u)); @@ -4553,11 +5514,11 @@ SRSASN_CODE meas_obj_nr_r15_s::unpack(cbit_ref& bref) if (offset_freq_r15_present) { HANDLE_CODE(unpack_integer(offset_freq_r15, bref, (int8_t)-15, (int8_t)15)); } - if (black_cells_to_rem_list_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(black_cells_to_rem_list_r15, bref, 1, 32, integer_packer(1, 32))); + if (excluded_cells_to_rem_list_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(excluded_cells_to_rem_list_r15, bref, 1, 32, integer_packer(1, 32))); } - if (black_cells_to_add_mod_list_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(black_cells_to_add_mod_list_r15, bref, 1, 32)); + if (excluded_cells_to_add_mod_list_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(excluded_cells_to_add_mod_list_r15, bref, 1, 32)); } HANDLE_CODE(unpack_integer(quant_cfg_set_r15, bref, (uint8_t)1u, (uint8_t)2u)); if (cells_for_which_to_report_sftd_r15_present) { @@ -4565,7 +5526,7 @@ SRSASN_CODE meas_obj_nr_r15_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(1); + ext_groups_unpacker_guard group_flags(3); group_flags.unpack(bref); if (group_flags[0]) { @@ -4592,6 +5553,32 @@ SRSASN_CODE meas_obj_nr_r15_s::unpack(cbit_ref& bref) HANDLE_CODE(band_nr_r15->unpack(bref)); } } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool rmtc_cfg_nr_r16_present; + HANDLE_CODE(bref.unpack(rmtc_cfg_nr_r16_present, 1)); + rmtc_cfg_nr_r16.set_present(rmtc_cfg_nr_r16_present); + if (rmtc_cfg_nr_r16.is_present()) { + HANDLE_CODE(rmtc_cfg_nr_r16->unpack(bref)); + } + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool cells_to_rem_list_r16_present; + HANDLE_CODE(bref.unpack(cells_to_rem_list_r16_present, 1)); + cells_to_rem_list_r16.set_present(cells_to_rem_list_r16_present); + bool cells_to_add_mod_list_r16_present; + HANDLE_CODE(bref.unpack(cells_to_add_mod_list_r16_present, 1)); + cells_to_add_mod_list_r16.set_present(cells_to_add_mod_list_r16_present); + if (cells_to_rem_list_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*cells_to_rem_list_r16, bref, 1, 32, integer_packer(1, 32))); + } + if (cells_to_add_mod_list_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*cells_to_add_mod_list_r16, bref, 1, 32)); + } + } } return SRSASN_SUCCESS; } @@ -4611,16 +5598,16 @@ void meas_obj_nr_r15_s::to_json(json_writer& j) const if (offset_freq_r15_present) { j.write_int("offsetFreq-r15", offset_freq_r15); } - if (black_cells_to_rem_list_r15_present) { - j.start_array("blackCellsToRemoveList-r15"); - for (const auto& e1 : black_cells_to_rem_list_r15) { + if (excluded_cells_to_rem_list_r15_present) { + j.start_array("excludedCellsToRemoveList-r15"); + for (const auto& e1 : excluded_cells_to_rem_list_r15) { j.write_int(e1); } j.end_array(); } - if (black_cells_to_add_mod_list_r15_present) { - j.start_array("blackCellsToAddModList-r15"); - for (const auto& e1 : black_cells_to_add_mod_list_r15) { + if (excluded_cells_to_add_mod_list_r15_present) { + j.start_array("excludedCellsToAddModList-r15"); + for (const auto& e1 : excluded_cells_to_add_mod_list_r15) { e1.to_json(j); } j.end_array(); @@ -4648,6 +5635,24 @@ void meas_obj_nr_r15_s::to_json(json_writer& j) const j.write_fieldname("bandNR-r15"); band_nr_r15->to_json(j); } + if (rmtc_cfg_nr_r16.is_present()) { + j.write_fieldname("rmtc-ConfigNR-r16"); + rmtc_cfg_nr_r16->to_json(j); + } + if (cells_to_rem_list_r16.is_present()) { + j.start_array("cellsToRemoveList-r16"); + for (const auto& e1 : *cells_to_rem_list_r16) { + j.write_int(e1); + } + j.end_array(); + } + if (cells_to_add_mod_list_r16.is_present()) { + j.start_array("cellsToAddModList-r16"); + for (const auto& e1 : *cells_to_add_mod_list_r16) { + e1.to_json(j); + } + j.end_array(); + } } j.end_obj(); } @@ -4660,26 +5665,34 @@ bool meas_obj_nr_r15_s::operator==(const meas_obj_nr_r15_s& other) const (not max_rs_idx_cell_qual_r15_present or max_rs_idx_cell_qual_r15 == other.max_rs_idx_cell_qual_r15) and offset_freq_r15_present == other.offset_freq_r15_present and (not offset_freq_r15_present or offset_freq_r15 == other.offset_freq_r15) and - black_cells_to_rem_list_r15_present == other.black_cells_to_rem_list_r15_present and - (not black_cells_to_rem_list_r15_present or - black_cells_to_rem_list_r15 == other.black_cells_to_rem_list_r15) and - black_cells_to_add_mod_list_r15_present == other.black_cells_to_add_mod_list_r15_present and - (not black_cells_to_add_mod_list_r15_present or - black_cells_to_add_mod_list_r15 == other.black_cells_to_add_mod_list_r15) and + excluded_cells_to_rem_list_r15_present == other.excluded_cells_to_rem_list_r15_present and + (not excluded_cells_to_rem_list_r15_present or + excluded_cells_to_rem_list_r15 == other.excluded_cells_to_rem_list_r15) and + excluded_cells_to_add_mod_list_r15_present == other.excluded_cells_to_add_mod_list_r15_present and + (not excluded_cells_to_add_mod_list_r15_present or + excluded_cells_to_add_mod_list_r15 == other.excluded_cells_to_add_mod_list_r15) and quant_cfg_set_r15 == other.quant_cfg_set_r15 and cells_for_which_to_report_sftd_r15_present == other.cells_for_which_to_report_sftd_r15_present and (not cells_for_which_to_report_sftd_r15_present or cells_for_which_to_report_sftd_r15 == other.cells_for_which_to_report_sftd_r15) and - (not ext or (cell_for_which_to_report_cgi_r15_present == other.cell_for_which_to_report_cgi_r15_present and - (not cell_for_which_to_report_cgi_r15_present or - cell_for_which_to_report_cgi_r15 == other.cell_for_which_to_report_cgi_r15) and - derive_ssb_idx_from_cell_r15_present == other.derive_ssb_idx_from_cell_r15_present and - (not derive_ssb_idx_from_cell_r15_present or - derive_ssb_idx_from_cell_r15 == other.derive_ssb_idx_from_cell_r15) and - ss_rssi_meas_r15.is_present() == other.ss_rssi_meas_r15.is_present() and - (not ss_rssi_meas_r15.is_present() or *ss_rssi_meas_r15 == *other.ss_rssi_meas_r15) and - band_nr_r15.is_present() == other.band_nr_r15.is_present() and - (not band_nr_r15.is_present() or *band_nr_r15 == *other.band_nr_r15))); + (not ext or + (cell_for_which_to_report_cgi_r15_present == other.cell_for_which_to_report_cgi_r15_present and + (not cell_for_which_to_report_cgi_r15_present or + cell_for_which_to_report_cgi_r15 == other.cell_for_which_to_report_cgi_r15) and + derive_ssb_idx_from_cell_r15_present == other.derive_ssb_idx_from_cell_r15_present and + (not derive_ssb_idx_from_cell_r15_present or + derive_ssb_idx_from_cell_r15 == other.derive_ssb_idx_from_cell_r15) and + ss_rssi_meas_r15.is_present() == other.ss_rssi_meas_r15.is_present() and + (not ss_rssi_meas_r15.is_present() or *ss_rssi_meas_r15 == *other.ss_rssi_meas_r15) and + band_nr_r15.is_present() == other.band_nr_r15.is_present() and + (not band_nr_r15.is_present() or *band_nr_r15 == *other.band_nr_r15) and + rmtc_cfg_nr_r16.is_present() == other.rmtc_cfg_nr_r16.is_present() and + (not rmtc_cfg_nr_r16.is_present() or *rmtc_cfg_nr_r16 == *other.rmtc_cfg_nr_r16) and + cells_to_rem_list_r16.is_present() == other.cells_to_rem_list_r16.is_present() and + (not cells_to_rem_list_r16.is_present() or *cells_to_rem_list_r16 == *other.cells_to_rem_list_r16) and + cells_to_add_mod_list_r16.is_present() == other.cells_to_add_mod_list_r16.is_present() and + (not cells_to_add_mod_list_r16.is_present() or + *cells_to_add_mod_list_r16 == *other.cells_to_add_mod_list_r16))); } void meas_obj_nr_r15_s::band_nr_r15_c_::set(types::options e) @@ -5998,7 +7011,7 @@ SRSASN_CODE report_cfg_eutra_s::pack(bit_ref& bref) const group_flags[2] |= trigger_quant_csi_rs_r12_present; group_flags[3] |= report_sstd_meas_r13_present; group_flags[3] |= rs_sinr_cfg_r13.is_present(); - group_flags[3] |= use_white_cell_list_r13_present; + group_flags[3] |= use_allowed_cell_list_r13_present; group_flags[3] |= meas_rssi_report_cfg_r13.is_present(); group_flags[3] |= include_multi_band_info_r13_present; group_flags[3] |= ul_delay_cfg_r13.is_present(); @@ -6010,6 +7023,10 @@ SRSASN_CODE report_cfg_eutra_s::pack(bit_ref& bref) const group_flags[7] |= purpose_r15_present; group_flags[7] |= nof_trigger_cells_r15_present; group_flags[7] |= a4_a5_report_on_leave_r15_present; + group_flags[8] |= cond_recfg_trigger_eutra_r16.is_present(); + group_flags[8] |= ul_delay_value_cfg_r16.is_present(); + group_flags[9] |= include_uncom_bar_pre_meas_r17_present; + group_flags[9] |= coarse_location_req_r17_present; group_flags.pack(bref); if (group_flags[0]) { @@ -6065,7 +7082,7 @@ SRSASN_CODE report_cfg_eutra_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(report_sstd_meas_r13_present, 1)); HANDLE_CODE(bref.pack(rs_sinr_cfg_r13.is_present(), 1)); - HANDLE_CODE(bref.pack(use_white_cell_list_r13_present, 1)); + HANDLE_CODE(bref.pack(use_allowed_cell_list_r13_present, 1)); HANDLE_CODE(bref.pack(meas_rssi_report_cfg_r13.is_present(), 1)); HANDLE_CODE(bref.pack(include_multi_band_info_r13_present, 1)); HANDLE_CODE(bref.pack(ul_delay_cfg_r13.is_present(), 1)); @@ -6075,8 +7092,8 @@ SRSASN_CODE report_cfg_eutra_s::pack(bit_ref& bref) const if (rs_sinr_cfg_r13.is_present()) { HANDLE_CODE(rs_sinr_cfg_r13->pack(bref)); } - if (use_white_cell_list_r13_present) { - HANDLE_CODE(bref.pack(use_white_cell_list_r13, 1)); + if (use_allowed_cell_list_r13_present) { + HANDLE_CODE(bref.pack(use_allowed_cell_list_r13, 1)); } if (meas_rssi_report_cfg_r13.is_present()) { HANDLE_CODE(meas_rssi_report_cfg_r13->pack(bref)); @@ -6130,6 +7147,27 @@ SRSASN_CODE report_cfg_eutra_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(a4_a5_report_on_leave_r15, 1)); } } + if (group_flags[8]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(cond_recfg_trigger_eutra_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(ul_delay_value_cfg_r16.is_present(), 1)); + if (cond_recfg_trigger_eutra_r16.is_present()) { + HANDLE_CODE(cond_recfg_trigger_eutra_r16->pack(bref)); + } + if (ul_delay_value_cfg_r16.is_present()) { + HANDLE_CODE(ul_delay_value_cfg_r16->pack(bref)); + } + } + if (group_flags[9]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(include_uncom_bar_pre_meas_r17_present, 1)); + HANDLE_CODE(bref.pack(coarse_location_req_r17_present, 1)); + if (include_uncom_bar_pre_meas_r17_present) { + HANDLE_CODE(bref.pack(include_uncom_bar_pre_meas_r17, 1)); + } + } } return SRSASN_SUCCESS; } @@ -6144,7 +7182,7 @@ SRSASN_CODE report_cfg_eutra_s::unpack(cbit_ref& bref) HANDLE_CODE(report_amount.unpack(bref)); if (ext) { - ext_groups_unpacker_guard group_flags(8); + ext_groups_unpacker_guard group_flags(10); group_flags.unpack(bref); if (group_flags[0]) { @@ -6208,7 +7246,7 @@ SRSASN_CODE report_cfg_eutra_s::unpack(cbit_ref& bref) bool rs_sinr_cfg_r13_present; HANDLE_CODE(bref.unpack(rs_sinr_cfg_r13_present, 1)); rs_sinr_cfg_r13.set_present(rs_sinr_cfg_r13_present); - HANDLE_CODE(bref.unpack(use_white_cell_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(use_allowed_cell_list_r13_present, 1)); bool meas_rssi_report_cfg_r13_present; HANDLE_CODE(bref.unpack(meas_rssi_report_cfg_r13_present, 1)); meas_rssi_report_cfg_r13.set_present(meas_rssi_report_cfg_r13_present); @@ -6222,8 +7260,8 @@ SRSASN_CODE report_cfg_eutra_s::unpack(cbit_ref& bref) if (rs_sinr_cfg_r13.is_present()) { HANDLE_CODE(rs_sinr_cfg_r13->unpack(bref)); } - if (use_white_cell_list_r13_present) { - HANDLE_CODE(bref.unpack(use_white_cell_list_r13, 1)); + if (use_allowed_cell_list_r13_present) { + HANDLE_CODE(bref.unpack(use_allowed_cell_list_r13, 1)); } if (meas_rssi_report_cfg_r13.is_present()) { HANDLE_CODE(meas_rssi_report_cfg_r13->unpack(bref)); @@ -6281,6 +7319,31 @@ SRSASN_CODE report_cfg_eutra_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(a4_a5_report_on_leave_r15, 1)); } } + if (group_flags[8]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool cond_recfg_trigger_eutra_r16_present; + HANDLE_CODE(bref.unpack(cond_recfg_trigger_eutra_r16_present, 1)); + cond_recfg_trigger_eutra_r16.set_present(cond_recfg_trigger_eutra_r16_present); + bool ul_delay_value_cfg_r16_present; + HANDLE_CODE(bref.unpack(ul_delay_value_cfg_r16_present, 1)); + ul_delay_value_cfg_r16.set_present(ul_delay_value_cfg_r16_present); + if (cond_recfg_trigger_eutra_r16.is_present()) { + HANDLE_CODE(cond_recfg_trigger_eutra_r16->unpack(bref)); + } + if (ul_delay_value_cfg_r16.is_present()) { + HANDLE_CODE(ul_delay_value_cfg_r16->unpack(bref)); + } + } + if (group_flags[9]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(include_uncom_bar_pre_meas_r17_present, 1)); + HANDLE_CODE(bref.unpack(coarse_location_req_r17_present, 1)); + if (include_uncom_bar_pre_meas_r17_present) { + HANDLE_CODE(bref.unpack(include_uncom_bar_pre_meas_r17, 1)); + } + } } return SRSASN_SUCCESS; } @@ -6341,8 +7404,8 @@ void report_cfg_eutra_s::to_json(json_writer& j) const j.write_fieldname("rs-sinr-Config-r13"); rs_sinr_cfg_r13->to_json(j); } - if (use_white_cell_list_r13_present) { - j.write_bool("useWhiteCellList-r13", use_white_cell_list_r13); + if (use_allowed_cell_list_r13_present) { + j.write_bool("useAllowedCellList-r13", use_allowed_cell_list_r13); } if (meas_rssi_report_cfg_r13.is_present()) { j.write_fieldname("measRSSI-ReportConfig-r13"); @@ -6381,6 +7444,20 @@ void report_cfg_eutra_s::to_json(json_writer& j) const if (a4_a5_report_on_leave_r15_present) { j.write_bool("a4-a5-ReportOnLeave-r15", a4_a5_report_on_leave_r15); } + if (cond_recfg_trigger_eutra_r16.is_present()) { + j.write_fieldname("condReconfigurationTriggerEUTRA-r16"); + cond_recfg_trigger_eutra_r16->to_json(j); + } + if (ul_delay_value_cfg_r16.is_present()) { + j.write_fieldname("ul-DelayValueConfig-r16"); + ul_delay_value_cfg_r16->to_json(j); + } + if (include_uncom_bar_pre_meas_r17_present) { + j.write_bool("includeUncomBarPreMeas-r17", include_uncom_bar_pre_meas_r17); + } + if (coarse_location_req_r17_present) { + j.write_str("coarseLocationReq-r17", "true"); + } } j.end_obj(); } @@ -6415,8 +7492,8 @@ bool report_cfg_eutra_s::operator==(const report_cfg_eutra_s& other) const (not report_sstd_meas_r13_present or report_sstd_meas_r13 == other.report_sstd_meas_r13) and rs_sinr_cfg_r13.is_present() == other.rs_sinr_cfg_r13.is_present() and (not rs_sinr_cfg_r13.is_present() or *rs_sinr_cfg_r13 == *other.rs_sinr_cfg_r13) and - use_white_cell_list_r13_present == other.use_white_cell_list_r13_present and - (not use_white_cell_list_r13_present or use_white_cell_list_r13 == other.use_white_cell_list_r13) and + use_allowed_cell_list_r13_present == other.use_allowed_cell_list_r13_present and + (not use_allowed_cell_list_r13_present or use_allowed_cell_list_r13 == other.use_allowed_cell_list_r13) and meas_rssi_report_cfg_r13.is_present() == other.meas_rssi_report_cfg_r13.is_present() and (not meas_rssi_report_cfg_r13.is_present() or *meas_rssi_report_cfg_r13 == *other.meas_rssi_report_cfg_r13) and @@ -6438,7 +7515,16 @@ bool report_cfg_eutra_s::operator==(const report_cfg_eutra_s& other) const nof_trigger_cells_r15_present == other.nof_trigger_cells_r15_present and (not nof_trigger_cells_r15_present or nof_trigger_cells_r15 == other.nof_trigger_cells_r15) and a4_a5_report_on_leave_r15_present == other.a4_a5_report_on_leave_r15_present and - (not a4_a5_report_on_leave_r15_present or a4_a5_report_on_leave_r15 == other.a4_a5_report_on_leave_r15))); + (not a4_a5_report_on_leave_r15_present or a4_a5_report_on_leave_r15 == other.a4_a5_report_on_leave_r15) and + cond_recfg_trigger_eutra_r16.is_present() == other.cond_recfg_trigger_eutra_r16.is_present() and + (not cond_recfg_trigger_eutra_r16.is_present() or + *cond_recfg_trigger_eutra_r16 == *other.cond_recfg_trigger_eutra_r16) and + ul_delay_value_cfg_r16.is_present() == other.ul_delay_value_cfg_r16.is_present() and + (not ul_delay_value_cfg_r16.is_present() or *ul_delay_value_cfg_r16 == *other.ul_delay_value_cfg_r16) and + include_uncom_bar_pre_meas_r17_present == other.include_uncom_bar_pre_meas_r17_present and + (not include_uncom_bar_pre_meas_r17_present or + include_uncom_bar_pre_meas_r17 == other.include_uncom_bar_pre_meas_r17) and + coarse_location_req_r17_present == other.coarse_location_req_r17_present)); } void report_cfg_eutra_s::trigger_type_c_::destroy_() @@ -6814,6 +7900,9 @@ SRSASN_CODE report_cfg_inter_rat_s::pack(bit_ref& bref) const group_flags[6] |= report_quant_rs_idx_nr_r15.is_present(); group_flags[6] |= report_rs_idx_results_nr_present; group_flags[6] |= report_sftd_meas_r15_present; + group_flags[7] |= use_autonomous_gaps_nr_r16_present; + group_flags[7] |= meas_rssi_report_cfg_nr_r16.is_present(); + group_flags[8] |= cond_recfg_trigger_nr_r17.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -6882,6 +7971,23 @@ SRSASN_CODE report_cfg_inter_rat_s::pack(bit_ref& bref) const HANDLE_CODE(report_sftd_meas_r15.pack(bref)); } } + if (group_flags[7]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(use_autonomous_gaps_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_rssi_report_cfg_nr_r16.is_present(), 1)); + if (meas_rssi_report_cfg_nr_r16.is_present()) { + HANDLE_CODE(meas_rssi_report_cfg_nr_r16->pack(bref)); + } + } + if (group_flags[8]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(cond_recfg_trigger_nr_r17.is_present(), 1)); + if (cond_recfg_trigger_nr_r17.is_present()) { + HANDLE_CODE(cond_recfg_trigger_nr_r17->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -6894,7 +8000,7 @@ SRSASN_CODE report_cfg_inter_rat_s::unpack(cbit_ref& bref) HANDLE_CODE(report_amount.unpack(bref)); if (ext) { - ext_groups_unpacker_guard group_flags(7); + ext_groups_unpacker_guard group_flags(9); group_flags.unpack(bref); if (group_flags[0]) { @@ -6971,6 +8077,27 @@ SRSASN_CODE report_cfg_inter_rat_s::unpack(cbit_ref& bref) HANDLE_CODE(report_sftd_meas_r15.unpack(bref)); } } + if (group_flags[7]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(use_autonomous_gaps_nr_r16_present, 1)); + bool meas_rssi_report_cfg_nr_r16_present; + HANDLE_CODE(bref.unpack(meas_rssi_report_cfg_nr_r16_present, 1)); + meas_rssi_report_cfg_nr_r16.set_present(meas_rssi_report_cfg_nr_r16_present); + if (meas_rssi_report_cfg_nr_r16.is_present()) { + HANDLE_CODE(meas_rssi_report_cfg_nr_r16->unpack(bref)); + } + } + if (group_flags[8]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool cond_recfg_trigger_nr_r17_present; + HANDLE_CODE(bref.unpack(cond_recfg_trigger_nr_r17_present, 1)); + cond_recfg_trigger_nr_r17.set_present(cond_recfg_trigger_nr_r17_present); + if (cond_recfg_trigger_nr_r17.is_present()) { + HANDLE_CODE(cond_recfg_trigger_nr_r17->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -7020,6 +8147,17 @@ void report_cfg_inter_rat_s::to_json(json_writer& j) const if (report_sftd_meas_r15_present) { j.write_str("reportSFTD-Meas-r15", report_sftd_meas_r15.to_string()); } + if (use_autonomous_gaps_nr_r16_present) { + j.write_str("useAutonomousGapsNR-r16", "setup"); + } + if (meas_rssi_report_cfg_nr_r16.is_present()) { + j.write_fieldname("measRSSI-ReportConfigNR-r16"); + meas_rssi_report_cfg_nr_r16->to_json(j); + } + if (cond_recfg_trigger_nr_r17.is_present()) { + j.write_fieldname("condReconfigurationTriggerNR-r17"); + cond_recfg_trigger_nr_r17->to_json(j); + } } j.end_obj(); } @@ -7049,7 +8187,14 @@ bool report_cfg_inter_rat_s::operator==(const report_cfg_inter_rat_s& other) con report_rs_idx_results_nr_present == other.report_rs_idx_results_nr_present and (not report_rs_idx_results_nr_present or report_rs_idx_results_nr == other.report_rs_idx_results_nr) and report_sftd_meas_r15_present == other.report_sftd_meas_r15_present and - (not report_sftd_meas_r15_present or report_sftd_meas_r15 == other.report_sftd_meas_r15))); + (not report_sftd_meas_r15_present or report_sftd_meas_r15 == other.report_sftd_meas_r15) and + use_autonomous_gaps_nr_r16_present == other.use_autonomous_gaps_nr_r16_present and + meas_rssi_report_cfg_nr_r16.is_present() == other.meas_rssi_report_cfg_nr_r16.is_present() and + (not meas_rssi_report_cfg_nr_r16.is_present() or + *meas_rssi_report_cfg_nr_r16 == *other.meas_rssi_report_cfg_nr_r16) and + cond_recfg_trigger_nr_r17.is_present() == other.cond_recfg_trigger_nr_r17.is_present() and + (not cond_recfg_trigger_nr_r17.is_present() or + *cond_recfg_trigger_nr_r17 == *other.cond_recfg_trigger_nr_r17))); } void report_cfg_inter_rat_s::trigger_type_c_::destroy_() @@ -8647,34 +9792,319 @@ SRSASN_CODE meas_obj_to_add_mod_ext_r13_s::meas_obj_r13_c_::pack(bit_ref& bref) } return SRSASN_SUCCESS; } -SRSASN_CODE meas_obj_to_add_mod_ext_r13_s::meas_obj_r13_c_::unpack(cbit_ref& bref) +SRSASN_CODE meas_obj_to_add_mod_ext_r13_s::meas_obj_r13_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::meas_obj_eutra_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::meas_obj_utra_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::meas_obj_geran_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::meas_obj_cdma2000_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::meas_obj_wlan_v1320: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::meas_obj_nr_r15: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + default: + log_invalid_choice_id(type_, "meas_obj_to_add_mod_ext_r13_s::meas_obj_r13_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +// PUR-PeriodicityAndOffset-r16 ::= CHOICE +void pur_periodicity_and_offset_r16_c::destroy_() {} +void pur_periodicity_and_offset_r16_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +pur_periodicity_and_offset_r16_c::pur_periodicity_and_offset_r16_c(const pur_periodicity_and_offset_r16_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::periodicity8: + c.init(other.c.get()); + break; + case types::periodicity16: + c.init(other.c.get()); + break; + case types::periodicity32: + c.init(other.c.get()); + break; + case types::periodicity64: + c.init(other.c.get()); + break; + case types::periodicity128: + c.init(other.c.get()); + break; + case types::periodicity256: + c.init(other.c.get()); + break; + case types::periodicity512: + c.init(other.c.get()); + break; + case types::periodicity1024: + c.init(other.c.get()); + break; + case types::periodicity2048: + c.init(other.c.get()); + break; + case types::periodicity4096: + c.init(other.c.get()); + break; + case types::periodicity8192: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pur_periodicity_and_offset_r16_c"); + } +} +pur_periodicity_and_offset_r16_c& +pur_periodicity_and_offset_r16_c::operator=(const pur_periodicity_and_offset_r16_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::periodicity8: + c.set(other.c.get()); + break; + case types::periodicity16: + c.set(other.c.get()); + break; + case types::periodicity32: + c.set(other.c.get()); + break; + case types::periodicity64: + c.set(other.c.get()); + break; + case types::periodicity128: + c.set(other.c.get()); + break; + case types::periodicity256: + c.set(other.c.get()); + break; + case types::periodicity512: + c.set(other.c.get()); + break; + case types::periodicity1024: + c.set(other.c.get()); + break; + case types::periodicity2048: + c.set(other.c.get()); + break; + case types::periodicity4096: + c.set(other.c.get()); + break; + case types::periodicity8192: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pur_periodicity_and_offset_r16_c"); + } + + return *this; +} +uint8_t& pur_periodicity_and_offset_r16_c::set_periodicity8() +{ + set(types::periodicity8); + return c.get(); +} +uint8_t& pur_periodicity_and_offset_r16_c::set_periodicity16() +{ + set(types::periodicity16); + return c.get(); +} +uint8_t& pur_periodicity_and_offset_r16_c::set_periodicity32() +{ + set(types::periodicity32); + return c.get(); +} +uint8_t& pur_periodicity_and_offset_r16_c::set_periodicity64() +{ + set(types::periodicity64); + return c.get(); +} +uint8_t& pur_periodicity_and_offset_r16_c::set_periodicity128() +{ + set(types::periodicity128); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_r16_c::set_periodicity256() +{ + set(types::periodicity256); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_r16_c::set_periodicity512() +{ + set(types::periodicity512); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_r16_c::set_periodicity1024() +{ + set(types::periodicity1024); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_r16_c::set_periodicity2048() +{ + set(types::periodicity2048); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_r16_c::set_periodicity4096() +{ + set(types::periodicity4096); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_r16_c::set_periodicity8192() +{ + set(types::periodicity8192); + return c.get(); +} +void pur_periodicity_and_offset_r16_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::periodicity8: + j.write_int("periodicity8", c.get()); + break; + case types::periodicity16: + j.write_int("periodicity16", c.get()); + break; + case types::periodicity32: + j.write_int("periodicity32", c.get()); + break; + case types::periodicity64: + j.write_int("periodicity64", c.get()); + break; + case types::periodicity128: + j.write_int("periodicity128", c.get()); + break; + case types::periodicity256: + j.write_int("periodicity256", c.get()); + break; + case types::periodicity512: + j.write_int("periodicity512", c.get()); + break; + case types::periodicity1024: + j.write_int("periodicity1024", c.get()); + break; + case types::periodicity2048: + j.write_int("periodicity2048", c.get()); + break; + case types::periodicity4096: + j.write_int("periodicity4096", c.get()); + break; + case types::periodicity8192: + j.write_int("periodicity8192", c.get()); + break; + default: + log_invalid_choice_id(type_, "pur_periodicity_and_offset_r16_c"); + } + j.end_obj(); +} +SRSASN_CODE pur_periodicity_and_offset_r16_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::periodicity8: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)1u, (uint8_t)7u)); + break; + case types::periodicity16: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)1u, (uint8_t)15u)); + break; + case types::periodicity32: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)1u, (uint8_t)31u)); + break; + case types::periodicity64: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)1u, (uint8_t)63u)); + break; + case types::periodicity128: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)1u, (uint8_t)127u)); + break; + case types::periodicity256: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)255u)); + break; + case types::periodicity512: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)511u)); + break; + case types::periodicity1024: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)1023u)); + break; + case types::periodicity2048: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)2047u)); + break; + case types::periodicity4096: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)4095u)); + break; + case types::periodicity8192: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)8191u)); + break; + default: + log_invalid_choice_id(type_, "pur_periodicity_and_offset_r16_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE pur_periodicity_and_offset_r16_c::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::meas_obj_eutra_r13: - HANDLE_CODE(c.get().unpack(bref)); + case types::periodicity8: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)1u, (uint8_t)7u)); break; - case types::meas_obj_utra_r13: - HANDLE_CODE(c.get().unpack(bref)); + case types::periodicity16: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)1u, (uint8_t)15u)); break; - case types::meas_obj_geran_r13: - HANDLE_CODE(c.get().unpack(bref)); + case types::periodicity32: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)1u, (uint8_t)31u)); break; - case types::meas_obj_cdma2000_r13: - HANDLE_CODE(c.get().unpack(bref)); + case types::periodicity64: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)1u, (uint8_t)63u)); + break; + case types::periodicity128: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)1u, (uint8_t)127u)); + break; + case types::periodicity256: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)255u)); + break; + case types::periodicity512: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)511u)); + break; + case types::periodicity1024: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)1023u)); + break; + case types::periodicity2048: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)2047u)); + break; + case types::periodicity4096: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)4095u)); + break; + case types::periodicity8192: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)8191u)); break; - case types::meas_obj_wlan_v1320: { - varlength_field_unpack_guard varlen_scope(bref, false); - HANDLE_CODE(c.get().unpack(bref)); - } break; - case types::meas_obj_nr_r15: { - varlength_field_unpack_guard varlen_scope(bref, false); - HANDLE_CODE(c.get().unpack(bref)); - } break; default: - log_invalid_choice_id(type_, "meas_obj_to_add_mod_ext_r13_s::meas_obj_r13_c_"); + log_invalid_choice_id(type_, "pur_periodicity_and_offset_r16_c"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; @@ -11008,6 +12438,98 @@ SRSASN_CODE meas_cfg_s::height_thresh_ref_r15_c_::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +// EventType-r17 ::= CHOICE +void event_type_r17_c::set(types::options e) +{ + type_ = e; +} +void event_type_r17_c::set_out_of_coverage() +{ + set(types::out_of_coverage); +} +event_type_r17_c::event_l1_s_& event_type_r17_c::set_event_l1() +{ + set(types::event_l1); + return c; +} +void event_type_r17_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::out_of_coverage: + break; + case types::event_l1: + j.write_fieldname("eventL1"); + j.start_obj(); + j.write_fieldname("l1-Threshold-r17"); + c.l1_thres_r17.to_json(j); + j.write_int("hysteresis-r17", c.hysteresis_r17); + j.write_str("timeToTrigger-r17", c.time_to_trigger_r17.to_string()); + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "event_type_r17_c"); + } + j.end_obj(); +} +SRSASN_CODE event_type_r17_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::out_of_coverage: + break; + case types::event_l1: + HANDLE_CODE(c.l1_thres_r17.pack(bref)); + HANDLE_CODE(pack_integer(bref, c.hysteresis_r17, (uint8_t)0u, (uint8_t)30u)); + HANDLE_CODE(c.time_to_trigger_r17.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "event_type_r17_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE event_type_r17_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::out_of_coverage: + break; + case types::event_l1: + HANDLE_CODE(c.l1_thres_r17.unpack(bref)); + HANDLE_CODE(unpack_integer(c.hysteresis_r17, bref, (uint8_t)0u, (uint8_t)30u)); + HANDLE_CODE(c.time_to_trigger_r17.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "event_type_r17_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +// LoggedEventTriggerConfig-r17 ::= SEQUENCE +SRSASN_CODE logged_event_trigger_cfg_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(event_type_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE logged_event_trigger_cfg_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(event_type_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void logged_event_trigger_cfg_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("eventType-r17"); + event_type_r17.to_json(j); + j.end_obj(); +} + // CarrierFreqGERAN ::= SEQUENCE SRSASN_CODE carrier_freq_geran_s::pack(bit_ref& bref) const { @@ -11031,6 +12553,49 @@ void carrier_freq_geran_s::to_json(json_writer& j) const j.end_obj(); } +// LoggedMeasurementConfiguration-v1700-IEs ::= SEQUENCE +SRSASN_CODE logged_meas_cfg_v1700_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(logged_event_trigger_cfg_r17_present, 1)); + HANDLE_CODE(bref.pack(meas_uncom_bar_pre_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (logged_event_trigger_cfg_r17_present) { + HANDLE_CODE(logged_event_trigger_cfg_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE logged_meas_cfg_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(logged_event_trigger_cfg_r17_present, 1)); + HANDLE_CODE(bref.unpack(meas_uncom_bar_pre_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (logged_event_trigger_cfg_r17_present) { + HANDLE_CODE(logged_event_trigger_cfg_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void logged_meas_cfg_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (logged_event_trigger_cfg_r17_present) { + j.write_fieldname("loggedEventTriggerConfig-r17"); + logged_event_trigger_cfg_r17.to_json(j); + } + if (meas_uncom_bar_pre_r17_present) { + j.write_str("measUncomBarPre-r17", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // LoggedMeasurementConfiguration-v1530-IEs ::= SEQUENCE SRSASN_CODE logged_meas_cfg_v1530_ies_s::pack(bit_ref& bref) const { @@ -11044,6 +12609,9 @@ SRSASN_CODE logged_meas_cfg_v1530_ies_s::pack(bit_ref& bref) const if (wlan_name_list_r15_present) { HANDLE_CODE(pack_dyn_seq_of(bref, wlan_name_list_r15, 1, 4)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -11059,6 +12627,9 @@ SRSASN_CODE logged_meas_cfg_v1530_ies_s::unpack(cbit_ref& bref) if (wlan_name_list_r15_present) { HANDLE_CODE(unpack_dyn_seq_of(wlan_name_list_r15, bref, 1, 4)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -11081,8 +12652,7 @@ void logged_meas_cfg_v1530_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -11111,6 +12681,32 @@ void cell_global_id_eutra_s::to_json(json_writer& j) const j.end_obj(); } +// DAPS-PowerCoordinationInfo-r16 ::= SEQUENCE +SRSASN_CODE daps_pwr_coordination_info_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, p_daps_source_r16, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(pack_integer(bref, p_daps_target_r16, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(pack_integer(bref, pwr_ctrl_mode_r16, (uint8_t)1u, (uint8_t)2u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE daps_pwr_coordination_info_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(p_daps_source_r16, bref, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(unpack_integer(p_daps_target_r16, bref, (uint8_t)1u, (uint8_t)16u)); + HANDLE_CODE(unpack_integer(pwr_ctrl_mode_r16, bref, (uint8_t)1u, (uint8_t)2u)); + + return SRSASN_SUCCESS; +} +void daps_pwr_coordination_info_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("p-DAPS-Source-r16", p_daps_source_r16); + j.write_int("p-DAPS-Target-r16", p_daps_target_r16); + j.write_int("powerControlMode-r16", pwr_ctrl_mode_r16); + j.end_obj(); +} + // CarrierBandwidthEUTRA ::= SEQUENCE SRSASN_CODE carrier_bw_eutra_s::pack(bit_ref& bref) const { @@ -11262,6 +12858,39 @@ void carrier_freq_eutra_v9e0_s::to_json(json_writer& j) const j.end_obj(); } +// DAPS-Config-r16 ::= SEQUENCE +SRSASN_CODE daps_cfg_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(daps_pwr_coordination_info_r16_present, 1)); + + if (daps_pwr_coordination_info_r16_present) { + HANDLE_CODE(daps_pwr_coordination_info_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE daps_cfg_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(daps_pwr_coordination_info_r16_present, 1)); + + if (daps_pwr_coordination_info_r16_present) { + HANDLE_CODE(daps_pwr_coordination_info_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void daps_cfg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (daps_pwr_coordination_info_r16_present) { + j.write_fieldname("daps-PowerCoordinationInfo-r16"); + daps_pwr_coordination_info_r16.to_json(j); + } + j.end_obj(); +} + // MobilityControlInfoV2X-r14 ::= SEQUENCE SRSASN_CODE mob_ctrl_info_v2x_r14_s::pack(bit_ref& bref) const { @@ -11372,6 +13001,7 @@ SRSASN_CODE mob_ctrl_info_s::pack(bit_ref& bref) const group_flags[2] |= same_sfn_ind_r14_present; group_flags[3] |= mib_repeat_status_r14_present; group_flags[3] |= sched_info_sib1_br_r14_present; + group_flags[4] |= daps_cfg_r16.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -11417,6 +13047,14 @@ SRSASN_CODE mob_ctrl_info_s::pack(bit_ref& bref) const HANDLE_CODE(pack_integer(bref, sched_info_sib1_br_r14, (uint8_t)0u, (uint8_t)31u)); } } + if (group_flags[4]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(daps_cfg_r16.is_present(), 1)); + if (daps_cfg_r16.is_present()) { + HANDLE_CODE(daps_cfg_r16->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -11446,7 +13084,7 @@ SRSASN_CODE mob_ctrl_info_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(4); + ext_groups_unpacker_guard group_flags(5); group_flags.unpack(bref); if (group_flags[0]) { @@ -11498,6 +13136,16 @@ SRSASN_CODE mob_ctrl_info_s::unpack(cbit_ref& bref) HANDLE_CODE(unpack_integer(sched_info_sib1_br_r14, bref, (uint8_t)0u, (uint8_t)31u)); } } + if (group_flags[4]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool daps_cfg_r16_present; + HANDLE_CODE(bref.unpack(daps_cfg_r16_present, 1)); + daps_cfg_r16.set_present(daps_cfg_r16_present); + if (daps_cfg_r16.is_present()) { + HANDLE_CODE(daps_cfg_r16->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -11555,48 +13203,187 @@ void mob_ctrl_info_s::to_json(json_writer& j) const if (sched_info_sib1_br_r14_present) { j.write_int("schedulingInfoSIB1-BR-r14", sched_info_sib1_br_r14); } + if (daps_cfg_r16.is_present()) { + j.write_fieldname("daps-Config-r16"); + daps_cfg_r16->to_json(j); + } + } + j.end_obj(); +} + +const char* mob_ctrl_info_s::t304_opts::to_string() const +{ + static const char* options[] = {"ms50", "ms100", "ms150", "ms200", "ms500", "ms1000", "ms2000", "ms10000-v1310"}; + return convert_enum_idx(options, 8, value, "mob_ctrl_info_s::t304_e_"); +} +uint16_t mob_ctrl_info_s::t304_opts::to_number() const +{ + static const uint16_t options[] = {50, 100, 150, 200, 500, 1000, 2000, 10000}; + return map_enum_number(options, 8, value, "mob_ctrl_info_s::t304_e_"); +} + +const char* mob_ctrl_info_s::ho_without_wt_change_r14_opts::to_string() const +{ + static const char* options[] = {"keepLWA-Config", "sendEndMarker"}; + return convert_enum_idx(options, 2, value, "mob_ctrl_info_s::ho_without_wt_change_r14_e_"); +} + +// TraceReference-r10 ::= SEQUENCE +SRSASN_CODE trace_ref_r10_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(plmn_id_r10.pack(bref)); + HANDLE_CODE(trace_id_r10.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE trace_ref_r10_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(plmn_id_r10.unpack(bref)); + HANDLE_CODE(trace_id_r10.unpack(bref)); + + return SRSASN_SUCCESS; +} +void trace_ref_r10_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("plmn-Identity-r10"); + plmn_id_r10.to_json(j); + j.write_str("traceId-r10", trace_id_r10.to_string()); + j.end_obj(); +} + +// MeasResultNR-r15 ::= SEQUENCE +SRSASN_CODE meas_result_nr_r15_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(rsrp_result_r15_present, 1)); + HANDLE_CODE(bref.pack(rsrq_result_r15_present, 1)); + HANDLE_CODE(bref.pack(rs_sinr_result_r15_present, 1)); + + if (rsrp_result_r15_present) { + HANDLE_CODE(pack_integer(bref, rsrp_result_r15, (uint8_t)0u, (uint8_t)127u)); + } + if (rsrq_result_r15_present) { + HANDLE_CODE(pack_integer(bref, rsrq_result_r15, (uint8_t)0u, (uint8_t)127u)); + } + if (rs_sinr_result_r15_present) { + HANDLE_CODE(pack_integer(bref, rs_sinr_result_r15, (uint8_t)0u, (uint8_t)127u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_result_nr_r15_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(rsrp_result_r15_present, 1)); + HANDLE_CODE(bref.unpack(rsrq_result_r15_present, 1)); + HANDLE_CODE(bref.unpack(rs_sinr_result_r15_present, 1)); + + if (rsrp_result_r15_present) { + HANDLE_CODE(unpack_integer(rsrp_result_r15, bref, (uint8_t)0u, (uint8_t)127u)); + } + if (rsrq_result_r15_present) { + HANDLE_CODE(unpack_integer(rsrq_result_r15, bref, (uint8_t)0u, (uint8_t)127u)); + } + if (rs_sinr_result_r15_present) { + HANDLE_CODE(unpack_integer(rs_sinr_result_r15, bref, (uint8_t)0u, (uint8_t)127u)); + } + + return SRSASN_SUCCESS; +} +void meas_result_nr_r15_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (rsrp_result_r15_present) { + j.write_int("rsrpResult-r15", rsrp_result_r15); + } + if (rsrq_result_r15_present) { + j.write_int("rsrqResult-r15", rsrq_result_r15); + } + if (rs_sinr_result_r15_present) { + j.write_int("rs-sinr-Result-r15", rs_sinr_result_r15); } j.end_obj(); } -const char* mob_ctrl_info_s::t304_opts::to_string() const +// PLMN-IdentityInfoNR-r15 ::= SEQUENCE +SRSASN_CODE plmn_id_info_nr_r15_s::pack(bit_ref& bref) const { - static const char* options[] = {"ms50", "ms100", "ms150", "ms200", "ms500", "ms1000", "ms2000", "ms10000-v1310"}; - return convert_enum_idx(options, 8, value, "mob_ctrl_info_s::t304_e_"); + HANDLE_CODE(bref.pack(tac_r15_present, 1)); + HANDLE_CODE(bref.pack(ran_area_code_r15_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, plmn_id_list_r15, 1, 12)); + if (tac_r15_present) { + HANDLE_CODE(tac_r15.pack(bref)); + } + if (ran_area_code_r15_present) { + HANDLE_CODE(pack_integer(bref, ran_area_code_r15, (uint16_t)0u, (uint16_t)255u)); + } + HANDLE_CODE(cell_id_r15.pack(bref)); + + return SRSASN_SUCCESS; } -uint16_t mob_ctrl_info_s::t304_opts::to_number() const +SRSASN_CODE plmn_id_info_nr_r15_s::unpack(cbit_ref& bref) { - static const uint16_t options[] = {50, 100, 150, 200, 500, 1000, 2000, 10000}; - return map_enum_number(options, 8, value, "mob_ctrl_info_s::t304_e_"); -} + HANDLE_CODE(bref.unpack(tac_r15_present, 1)); + HANDLE_CODE(bref.unpack(ran_area_code_r15_present, 1)); -const char* mob_ctrl_info_s::ho_without_wt_change_r14_opts::to_string() const + HANDLE_CODE(unpack_dyn_seq_of(plmn_id_list_r15, bref, 1, 12)); + if (tac_r15_present) { + HANDLE_CODE(tac_r15.unpack(bref)); + } + if (ran_area_code_r15_present) { + HANDLE_CODE(unpack_integer(ran_area_code_r15, bref, (uint16_t)0u, (uint16_t)255u)); + } + HANDLE_CODE(cell_id_r15.unpack(bref)); + + return SRSASN_SUCCESS; +} +void plmn_id_info_nr_r15_s::to_json(json_writer& j) const { - static const char* options[] = {"keepLWA-Config", "sendEndMarker"}; - return convert_enum_idx(options, 2, value, "mob_ctrl_info_s::ho_without_wt_change_r14_e_"); + j.start_obj(); + j.start_array("plmn-IdentityList-r15"); + for (const auto& e1 : plmn_id_list_r15) { + e1.to_json(j); + } + j.end_array(); + if (tac_r15_present) { + j.write_str("trackingAreaCode-r15", tac_r15.to_string()); + } + if (ran_area_code_r15_present) { + j.write_int("ran-AreaCode-r15", ran_area_code_r15); + } + j.write_str("cellIdentity-r15", cell_id_r15.to_string()); + j.end_obj(); } -// TraceReference-r10 ::= SEQUENCE -SRSASN_CODE trace_ref_r10_s::pack(bit_ref& bref) const +// PLMN-IdentityInfoNR-v1710 ::= SEQUENCE +SRSASN_CODE plmn_id_info_nr_v1710_s::pack(bit_ref& bref) const { - HANDLE_CODE(plmn_id_r10.pack(bref)); - HANDLE_CODE(trace_id_r10.pack(bref)); + HANDLE_CODE(bref.pack(gnb_id_len_r17_present, 1)); + + if (gnb_id_len_r17_present) { + HANDLE_CODE(pack_integer(bref, gnb_id_len_r17, (uint8_t)22u, (uint8_t)32u)); + } return SRSASN_SUCCESS; } -SRSASN_CODE trace_ref_r10_s::unpack(cbit_ref& bref) +SRSASN_CODE plmn_id_info_nr_v1710_s::unpack(cbit_ref& bref) { - HANDLE_CODE(plmn_id_r10.unpack(bref)); - HANDLE_CODE(trace_id_r10.unpack(bref)); + HANDLE_CODE(bref.unpack(gnb_id_len_r17_present, 1)); + + if (gnb_id_len_r17_present) { + HANDLE_CODE(unpack_integer(gnb_id_len_r17, bref, (uint8_t)22u, (uint8_t)32u)); + } return SRSASN_SUCCESS; } -void trace_ref_r10_s::to_json(json_writer& j) const +void plmn_id_info_nr_v1710_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("plmn-Identity-r10"); - plmn_id_r10.to_json(j); - j.write_str("traceId-r10", trace_id_r10.to_string()); + if (gnb_id_len_r17_present) { + j.write_int("gNB-ID-Length-r17", gnb_id_len_r17); + } j.end_obj(); } @@ -11728,6 +13515,42 @@ SRSASN_CODE cell_global_id_cdma2000_c::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +// MeasResultSSB-Index-r15 ::= SEQUENCE +SRSASN_CODE meas_result_ssb_idx_r15_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(meas_result_ssb_idx_r15_present, 1)); + + HANDLE_CODE(pack_integer(bref, ssb_idx_r15, (uint8_t)0u, (uint8_t)63u)); + if (meas_result_ssb_idx_r15_present) { + HANDLE_CODE(meas_result_ssb_idx_r15.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_result_ssb_idx_r15_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(meas_result_ssb_idx_r15_present, 1)); + + HANDLE_CODE(unpack_integer(ssb_idx_r15, bref, (uint8_t)0u, (uint8_t)63u)); + if (meas_result_ssb_idx_r15_present) { + HANDLE_CODE(meas_result_ssb_idx_r15.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void meas_result_ssb_idx_r15_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ssb-Index-r15", ssb_idx_r15); + if (meas_result_ssb_idx_r15_present) { + j.write_fieldname("measResultSSB-Index-r15"); + meas_result_ssb_idx_r15.to_json(j); + } + j.end_obj(); +} + // AdditionalSI-Info-r9 ::= SEQUENCE SRSASN_CODE add_si_info_r9_s::pack(bit_ref& bref) const { @@ -11792,6 +13615,112 @@ void bler_result_r12_s::to_json(json_writer& j) const j.end_obj(); } +// CGI-InfoNR-r15 ::= SEQUENCE +SRSASN_CODE cgi_info_nr_r15_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(plmn_id_info_list_r15_present, 1)); + HANDLE_CODE(bref.pack(freq_band_list_r15_present, 1)); + HANDLE_CODE(bref.pack(no_sib1_r15_present, 1)); + + if (plmn_id_info_list_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, plmn_id_info_list_r15, 1, 12)); + } + if (freq_band_list_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list_r15, 1, 32, integer_packer(1, 1024))); + } + if (no_sib1_r15_present) { + HANDLE_CODE(pack_integer(bref, no_sib1_r15.ssb_subcarrier_offset_r15, (uint8_t)0u, (uint8_t)15u)); + HANDLE_CODE(pack_integer(bref, no_sib1_r15.pdcch_cfg_sib1_r15, (uint16_t)0u, (uint16_t)255u)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= plmn_id_info_list_v1710.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(plmn_id_info_list_v1710.is_present(), 1)); + if (plmn_id_info_list_v1710.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *plmn_id_info_list_v1710, 1, 12)); + } + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE cgi_info_nr_r15_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(plmn_id_info_list_r15_present, 1)); + HANDLE_CODE(bref.unpack(freq_band_list_r15_present, 1)); + HANDLE_CODE(bref.unpack(no_sib1_r15_present, 1)); + + if (plmn_id_info_list_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(plmn_id_info_list_r15, bref, 1, 12)); + } + if (freq_band_list_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(freq_band_list_r15, bref, 1, 32, integer_packer(1, 1024))); + } + if (no_sib1_r15_present) { + HANDLE_CODE(unpack_integer(no_sib1_r15.ssb_subcarrier_offset_r15, bref, (uint8_t)0u, (uint8_t)15u)); + HANDLE_CODE(unpack_integer(no_sib1_r15.pdcch_cfg_sib1_r15, bref, (uint16_t)0u, (uint16_t)255u)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool plmn_id_info_list_v1710_present; + HANDLE_CODE(bref.unpack(plmn_id_info_list_v1710_present, 1)); + plmn_id_info_list_v1710.set_present(plmn_id_info_list_v1710_present); + if (plmn_id_info_list_v1710.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*plmn_id_info_list_v1710, bref, 1, 12)); + } + } + } + return SRSASN_SUCCESS; +} +void cgi_info_nr_r15_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (plmn_id_info_list_r15_present) { + j.start_array("plmn-IdentityInfoList-r15"); + for (const auto& e1 : plmn_id_info_list_r15) { + e1.to_json(j); + } + j.end_array(); + } + if (freq_band_list_r15_present) { + j.start_array("frequencyBandList-r15"); + for (const auto& e1 : freq_band_list_r15) { + j.write_int(e1); + } + j.end_array(); + } + if (no_sib1_r15_present) { + j.write_fieldname("noSIB1-r15"); + j.start_obj(); + j.write_int("ssb-SubcarrierOffset-r15", no_sib1_r15.ssb_subcarrier_offset_r15); + j.write_int("pdcch-ConfigSIB1-r15", no_sib1_r15.pdcch_cfg_sib1_r15); + j.end_obj(); + } + if (ext) { + if (plmn_id_info_list_v1710.is_present()) { + j.start_array("plmn-IdentityInfoList-v1710"); + for (const auto& e1 : *plmn_id_info_list_v1710) { + e1.to_json(j); + } + j.end_array(); + } + } + j.end_obj(); +} + // CellGlobalIdUTRA ::= SEQUENCE SRSASN_CODE cell_global_id_utra_s::pack(bit_ref& bref) const { @@ -11886,37 +13815,115 @@ SRSASN_CODE cell_global_id_geran_s::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -void cell_global_id_geran_s::to_json(json_writer& j) const +void cell_global_id_geran_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("plmn-Identity"); + plmn_id.to_json(j); + j.write_str("locationAreaCode", location_area_code.to_string()); + j.write_str("cellIdentity", cell_id.to_string()); + j.end_obj(); +} + +// DataBLER-MCH-Result-r12 ::= SEQUENCE +SRSASN_CODE data_bler_mch_result_r12_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, mch_idx_r12, (uint8_t)1u, (uint8_t)15u)); + HANDLE_CODE(data_bler_result_r12.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE data_bler_mch_result_r12_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(mch_idx_r12, bref, (uint8_t)1u, (uint8_t)15u)); + HANDLE_CODE(data_bler_result_r12.unpack(bref)); + + return SRSASN_SUCCESS; +} +void data_bler_mch_result_r12_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("mch-Index-r12", mch_idx_r12); + j.write_fieldname("dataBLER-Result-r12"); + data_bler_result_r12.to_json(j); + j.end_obj(); +} + +// MeasResultCellNR-r15 ::= SEQUENCE +SRSASN_CODE meas_result_cell_nr_r15_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(meas_result_rs_idx_list_r15_present, 1)); + + HANDLE_CODE(pack_integer(bref, pci_r15, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(meas_result_cell_r15.pack(bref)); + if (meas_result_rs_idx_list_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_rs_idx_list_r15, 1, 32)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= cgi_info_r15.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(cgi_info_r15.is_present(), 1)); + if (cgi_info_r15.is_present()) { + HANDLE_CODE(cgi_info_r15->pack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_result_cell_nr_r15_s::unpack(cbit_ref& bref) { - j.start_obj(); - j.write_fieldname("plmn-Identity"); - plmn_id.to_json(j); - j.write_str("locationAreaCode", location_area_code.to_string()); - j.write_str("cellIdentity", cell_id.to_string()); - j.end_obj(); -} + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(meas_result_rs_idx_list_r15_present, 1)); -// DataBLER-MCH-Result-r12 ::= SEQUENCE -SRSASN_CODE data_bler_mch_result_r12_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, mch_idx_r12, (uint8_t)1u, (uint8_t)15u)); - HANDLE_CODE(data_bler_result_r12.pack(bref)); + HANDLE_CODE(unpack_integer(pci_r15, bref, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(meas_result_cell_r15.unpack(bref)); + if (meas_result_rs_idx_list_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_rs_idx_list_r15, bref, 1, 32)); + } - return SRSASN_SUCCESS; -} -SRSASN_CODE data_bler_mch_result_r12_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(mch_idx_r12, bref, (uint8_t)1u, (uint8_t)15u)); - HANDLE_CODE(data_bler_result_r12.unpack(bref)); + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool cgi_info_r15_present; + HANDLE_CODE(bref.unpack(cgi_info_r15_present, 1)); + cgi_info_r15.set_present(cgi_info_r15_present); + if (cgi_info_r15.is_present()) { + HANDLE_CODE(cgi_info_r15->unpack(bref)); + } + } + } return SRSASN_SUCCESS; } -void data_bler_mch_result_r12_s::to_json(json_writer& j) const +void meas_result_cell_nr_r15_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("mch-Index-r12", mch_idx_r12); - j.write_fieldname("dataBLER-Result-r12"); - data_bler_result_r12.to_json(j); + j.write_int("pci-r15", pci_r15); + j.write_fieldname("measResultCell-r15"); + meas_result_cell_r15.to_json(j); + if (meas_result_rs_idx_list_r15_present) { + j.start_array("measResultRS-IndexList-r15"); + for (const auto& e1 : meas_result_rs_idx_list_r15) { + e1.to_json(j); + } + j.end_array(); + } + if (ext) { + if (cgi_info_r15.is_present()) { + j.write_fieldname("cgi-Info-r15"); + cgi_info_r15->to_json(j); + } + } j.end_obj(); } @@ -13010,60 +15017,6 @@ void meas_result_geran_s::to_json(json_writer& j) const j.end_obj(); } -// MeasResultNR-r15 ::= SEQUENCE -SRSASN_CODE meas_result_nr_r15_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(rsrp_result_r15_present, 1)); - HANDLE_CODE(bref.pack(rsrq_result_r15_present, 1)); - HANDLE_CODE(bref.pack(rs_sinr_result_r15_present, 1)); - - if (rsrp_result_r15_present) { - HANDLE_CODE(pack_integer(bref, rsrp_result_r15, (uint8_t)0u, (uint8_t)127u)); - } - if (rsrq_result_r15_present) { - HANDLE_CODE(pack_integer(bref, rsrq_result_r15, (uint8_t)0u, (uint8_t)127u)); - } - if (rs_sinr_result_r15_present) { - HANDLE_CODE(pack_integer(bref, rs_sinr_result_r15, (uint8_t)0u, (uint8_t)127u)); - } - - return SRSASN_SUCCESS; -} -SRSASN_CODE meas_result_nr_r15_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(rsrp_result_r15_present, 1)); - HANDLE_CODE(bref.unpack(rsrq_result_r15_present, 1)); - HANDLE_CODE(bref.unpack(rs_sinr_result_r15_present, 1)); - - if (rsrp_result_r15_present) { - HANDLE_CODE(unpack_integer(rsrp_result_r15, bref, (uint8_t)0u, (uint8_t)127u)); - } - if (rsrq_result_r15_present) { - HANDLE_CODE(unpack_integer(rsrq_result_r15, bref, (uint8_t)0u, (uint8_t)127u)); - } - if (rs_sinr_result_r15_present) { - HANDLE_CODE(unpack_integer(rs_sinr_result_r15, bref, (uint8_t)0u, (uint8_t)127u)); - } - - return SRSASN_SUCCESS; -} -void meas_result_nr_r15_s::to_json(json_writer& j) const -{ - j.start_obj(); - if (rsrp_result_r15_present) { - j.write_int("rsrpResult-r15", rsrp_result_r15); - } - if (rsrq_result_r15_present) { - j.write_int("rsrqResult-r15", rsrq_result_r15); - } - if (rs_sinr_result_r15_present) { - j.write_int("rs-sinr-Result-r15", rs_sinr_result_r15); - } - j.end_obj(); -} - // MeasResultsCDMA2000 ::= SEQUENCE SRSASN_CODE meas_results_cdma2000_s::pack(bit_ref& bref) const { @@ -13091,57 +15044,6 @@ void meas_results_cdma2000_s::to_json(json_writer& j) const j.end_obj(); } -// PLMN-IdentityInfoNR-r15 ::= SEQUENCE -SRSASN_CODE plmn_id_info_nr_r15_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(bref.pack(tac_r15_present, 1)); - HANDLE_CODE(bref.pack(ran_area_code_r15_present, 1)); - - HANDLE_CODE(pack_dyn_seq_of(bref, plmn_id_list_r15, 1, 12)); - if (tac_r15_present) { - HANDLE_CODE(tac_r15.pack(bref)); - } - if (ran_area_code_r15_present) { - HANDLE_CODE(pack_integer(bref, ran_area_code_r15, (uint16_t)0u, (uint16_t)255u)); - } - HANDLE_CODE(cell_id_r15.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE plmn_id_info_nr_r15_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(bref.unpack(tac_r15_present, 1)); - HANDLE_CODE(bref.unpack(ran_area_code_r15_present, 1)); - - HANDLE_CODE(unpack_dyn_seq_of(plmn_id_list_r15, bref, 1, 12)); - if (tac_r15_present) { - HANDLE_CODE(tac_r15.unpack(bref)); - } - if (ran_area_code_r15_present) { - HANDLE_CODE(unpack_integer(ran_area_code_r15, bref, (uint16_t)0u, (uint16_t)255u)); - } - HANDLE_CODE(cell_id_r15.unpack(bref)); - - return SRSASN_SUCCESS; -} -void plmn_id_info_nr_r15_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.start_array("plmn-IdentityList-r15"); - for (const auto& e1 : plmn_id_list_r15) { - e1.to_json(j); - } - j.end_array(); - if (tac_r15_present) { - j.write_str("trackingAreaCode-r15", tac_r15.to_string()); - } - if (ran_area_code_r15_present) { - j.write_int("ran-AreaCode-r15", ran_area_code_r15); - } - j.write_str("cellIdentity-r15", cell_id_r15.to_string()); - j.end_obj(); -} - // RSRQ-Type-r12 ::= SEQUENCE SRSASN_CODE rsrq_type_r12_s::pack(bit_ref& bref) const { @@ -13433,170 +15335,105 @@ void meas_result2_utra_r9_s::to_json(json_writer& j) const j.end_obj(); } -// MeasResultMBSFN-r12 ::= SEQUENCE -SRSASN_CODE meas_result_mbsfn_r12_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(sig_bler_result_r12_present, 1)); - HANDLE_CODE(bref.pack(data_bler_mch_result_list_r12_present, 1)); - - HANDLE_CODE(pack_integer(bref, mbsfn_area_r12.mbsfn_area_id_r12, (uint16_t)0u, (uint16_t)255u)); - HANDLE_CODE(pack_integer(bref, mbsfn_area_r12.carrier_freq_r12, (uint32_t)0u, (uint32_t)262143u)); - HANDLE_CODE(pack_integer(bref, rsrp_result_mbsfn_r12, (uint8_t)0u, (uint8_t)97u)); - HANDLE_CODE(pack_integer(bref, rsrq_result_mbsfn_r12, (uint8_t)0u, (uint8_t)31u)); - if (sig_bler_result_r12_present) { - HANDLE_CODE(sig_bler_result_r12.pack(bref)); - } - if (data_bler_mch_result_list_r12_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, data_bler_mch_result_list_r12, 1, 15)); - } - - return SRSASN_SUCCESS; -} -SRSASN_CODE meas_result_mbsfn_r12_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(sig_bler_result_r12_present, 1)); - HANDLE_CODE(bref.unpack(data_bler_mch_result_list_r12_present, 1)); - - HANDLE_CODE(unpack_integer(mbsfn_area_r12.mbsfn_area_id_r12, bref, (uint16_t)0u, (uint16_t)255u)); - HANDLE_CODE(unpack_integer(mbsfn_area_r12.carrier_freq_r12, bref, (uint32_t)0u, (uint32_t)262143u)); - HANDLE_CODE(unpack_integer(rsrp_result_mbsfn_r12, bref, (uint8_t)0u, (uint8_t)97u)); - HANDLE_CODE(unpack_integer(rsrq_result_mbsfn_r12, bref, (uint8_t)0u, (uint8_t)31u)); - if (sig_bler_result_r12_present) { - HANDLE_CODE(sig_bler_result_r12.unpack(bref)); - } - if (data_bler_mch_result_list_r12_present) { - HANDLE_CODE(unpack_dyn_seq_of(data_bler_mch_result_list_r12, bref, 1, 15)); - } - - return SRSASN_SUCCESS; -} -void meas_result_mbsfn_r12_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("mbsfn-Area-r12"); - j.start_obj(); - j.write_int("mbsfn-AreaId-r12", mbsfn_area_r12.mbsfn_area_id_r12); - j.write_int("carrierFreq-r12", mbsfn_area_r12.carrier_freq_r12); - j.end_obj(); - j.write_int("rsrpResultMBSFN-r12", rsrp_result_mbsfn_r12); - j.write_int("rsrqResultMBSFN-r12", rsrq_result_mbsfn_r12); - if (sig_bler_result_r12_present) { - j.write_fieldname("signallingBLER-Result-r12"); - sig_bler_result_r12.to_json(j); - } - if (data_bler_mch_result_list_r12_present) { - j.start_array("dataBLER-MCH-ResultList-r12"); - for (const auto& e1 : data_bler_mch_result_list_r12) { - e1.to_json(j); - } - j.end_array(); - } - j.end_obj(); -} - -// MeasResultSSB-Index-r15 ::= SEQUENCE -SRSASN_CODE meas_result_ssb_idx_r15_s::pack(bit_ref& bref) const +// MeasResultFreqFailNR-r15 ::= SEQUENCE +SRSASN_CODE meas_result_freq_fail_nr_r15_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(meas_result_ssb_idx_r15_present, 1)); + HANDLE_CODE(bref.pack(meas_result_cell_list_r15_present, 1)); - HANDLE_CODE(pack_integer(bref, ssb_idx_r15, (uint8_t)0u, (uint8_t)63u)); - if (meas_result_ssb_idx_r15_present) { - HANDLE_CODE(meas_result_ssb_idx_r15.pack(bref)); + HANDLE_CODE(pack_integer(bref, carrier_freq_r15, (uint32_t)0u, (uint32_t)3279165u)); + if (meas_result_cell_list_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_cell_list_r15, 1, 8)); } return SRSASN_SUCCESS; } -SRSASN_CODE meas_result_ssb_idx_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE meas_result_freq_fail_nr_r15_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(meas_result_ssb_idx_r15_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_cell_list_r15_present, 1)); - HANDLE_CODE(unpack_integer(ssb_idx_r15, bref, (uint8_t)0u, (uint8_t)63u)); - if (meas_result_ssb_idx_r15_present) { - HANDLE_CODE(meas_result_ssb_idx_r15.unpack(bref)); + HANDLE_CODE(unpack_integer(carrier_freq_r15, bref, (uint32_t)0u, (uint32_t)3279165u)); + if (meas_result_cell_list_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_cell_list_r15, bref, 1, 8)); } return SRSASN_SUCCESS; } -void meas_result_ssb_idx_r15_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("ssb-Index-r15", ssb_idx_r15); - if (meas_result_ssb_idx_r15_present) { - j.write_fieldname("measResultSSB-Index-r15"); - meas_result_ssb_idx_r15.to_json(j); +void meas_result_freq_fail_nr_r15_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("carrierFreq-r15", carrier_freq_r15); + if (meas_result_cell_list_r15_present) { + j.start_array("measResultCellList-r15"); + for (const auto& e1 : meas_result_cell_list_r15) { + e1.to_json(j); + } + j.end_array(); } j.end_obj(); } -// CGI-InfoNR-r15 ::= SEQUENCE -SRSASN_CODE cgi_info_nr_r15_s::pack(bit_ref& bref) const +// MeasResultMBSFN-r12 ::= SEQUENCE +SRSASN_CODE meas_result_mbsfn_r12_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(plmn_id_info_list_r15_present, 1)); - HANDLE_CODE(bref.pack(freq_band_list_r15_present, 1)); - HANDLE_CODE(bref.pack(no_sib1_r15_present, 1)); + HANDLE_CODE(bref.pack(sig_bler_result_r12_present, 1)); + HANDLE_CODE(bref.pack(data_bler_mch_result_list_r12_present, 1)); - if (plmn_id_info_list_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, plmn_id_info_list_r15, 1, 12)); - } - if (freq_band_list_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list_r15, 1, 32, integer_packer(1, 1024))); + HANDLE_CODE(pack_integer(bref, mbsfn_area_r12.mbsfn_area_id_r12, (uint16_t)0u, (uint16_t)255u)); + HANDLE_CODE(pack_integer(bref, mbsfn_area_r12.carrier_freq_r12, (uint32_t)0u, (uint32_t)262143u)); + HANDLE_CODE(pack_integer(bref, rsrp_result_mbsfn_r12, (uint8_t)0u, (uint8_t)97u)); + HANDLE_CODE(pack_integer(bref, rsrq_result_mbsfn_r12, (uint8_t)0u, (uint8_t)31u)); + if (sig_bler_result_r12_present) { + HANDLE_CODE(sig_bler_result_r12.pack(bref)); } - if (no_sib1_r15_present) { - HANDLE_CODE(pack_integer(bref, no_sib1_r15.ssb_subcarrier_offset_r15, (uint8_t)0u, (uint8_t)15u)); - HANDLE_CODE(pack_integer(bref, no_sib1_r15.pdcch_cfg_sib1_r15, (uint16_t)0u, (uint16_t)255u)); + if (data_bler_mch_result_list_r12_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, data_bler_mch_result_list_r12, 1, 15)); } return SRSASN_SUCCESS; } -SRSASN_CODE cgi_info_nr_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE meas_result_mbsfn_r12_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(plmn_id_info_list_r15_present, 1)); - HANDLE_CODE(bref.unpack(freq_band_list_r15_present, 1)); - HANDLE_CODE(bref.unpack(no_sib1_r15_present, 1)); + HANDLE_CODE(bref.unpack(sig_bler_result_r12_present, 1)); + HANDLE_CODE(bref.unpack(data_bler_mch_result_list_r12_present, 1)); - if (plmn_id_info_list_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(plmn_id_info_list_r15, bref, 1, 12)); - } - if (freq_band_list_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(freq_band_list_r15, bref, 1, 32, integer_packer(1, 1024))); + HANDLE_CODE(unpack_integer(mbsfn_area_r12.mbsfn_area_id_r12, bref, (uint16_t)0u, (uint16_t)255u)); + HANDLE_CODE(unpack_integer(mbsfn_area_r12.carrier_freq_r12, bref, (uint32_t)0u, (uint32_t)262143u)); + HANDLE_CODE(unpack_integer(rsrp_result_mbsfn_r12, bref, (uint8_t)0u, (uint8_t)97u)); + HANDLE_CODE(unpack_integer(rsrq_result_mbsfn_r12, bref, (uint8_t)0u, (uint8_t)31u)); + if (sig_bler_result_r12_present) { + HANDLE_CODE(sig_bler_result_r12.unpack(bref)); } - if (no_sib1_r15_present) { - HANDLE_CODE(unpack_integer(no_sib1_r15.ssb_subcarrier_offset_r15, bref, (uint8_t)0u, (uint8_t)15u)); - HANDLE_CODE(unpack_integer(no_sib1_r15.pdcch_cfg_sib1_r15, bref, (uint16_t)0u, (uint16_t)255u)); + if (data_bler_mch_result_list_r12_present) { + HANDLE_CODE(unpack_dyn_seq_of(data_bler_mch_result_list_r12, bref, 1, 15)); } return SRSASN_SUCCESS; } -void cgi_info_nr_r15_s::to_json(json_writer& j) const +void meas_result_mbsfn_r12_s::to_json(json_writer& j) const { j.start_obj(); - if (plmn_id_info_list_r15_present) { - j.start_array("plmn-IdentityInfoList-r15"); - for (const auto& e1 : plmn_id_info_list_r15) { - e1.to_json(j); - } - j.end_array(); + j.write_fieldname("mbsfn-Area-r12"); + j.start_obj(); + j.write_int("mbsfn-AreaId-r12", mbsfn_area_r12.mbsfn_area_id_r12); + j.write_int("carrierFreq-r12", mbsfn_area_r12.carrier_freq_r12); + j.end_obj(); + j.write_int("rsrpResultMBSFN-r12", rsrp_result_mbsfn_r12); + j.write_int("rsrqResultMBSFN-r12", rsrq_result_mbsfn_r12); + if (sig_bler_result_r12_present) { + j.write_fieldname("signallingBLER-Result-r12"); + sig_bler_result_r12.to_json(j); } - if (freq_band_list_r15_present) { - j.start_array("frequencyBandList-r15"); - for (const auto& e1 : freq_band_list_r15) { - j.write_int(e1); + if (data_bler_mch_result_list_r12_present) { + j.start_array("dataBLER-MCH-ResultList-r12"); + for (const auto& e1 : data_bler_mch_result_list_r12) { + e1.to_json(j); } j.end_array(); } - if (no_sib1_r15_present) { - j.write_fieldname("noSIB1-r15"); - j.start_obj(); - j.write_int("ssb-SubcarrierOffset-r15", no_sib1_r15.ssb_subcarrier_offset_r15); - j.write_int("pdcch-ConfigSIB1-r15", no_sib1_r15.pdcch_cfg_sib1_r15); - j.end_obj(); - } j.end_obj(); } @@ -13646,6 +15483,10 @@ SRSASN_CODE log_meas_info_r10_s::pack(bit_ref& bref) const group_flags[4] |= log_meas_result_list_bt_r15.is_present(); group_flags[4] |= log_meas_result_list_wlan_r15.is_present(); group_flags[5] |= any_cell_sel_detected_r15_present; + group_flags[6] |= meas_result_list_nr_r16.is_present(); + group_flags[7] |= meas_result_list_nr_v1640.is_present(); + group_flags[7] |= meas_result_list_ext_nr_r16.is_present(); + group_flags[8] |= uncom_bar_pre_meas_result_r17_present; group_flags.pack(bref); if (group_flags[0]) { @@ -13706,6 +15547,35 @@ SRSASN_CODE log_meas_info_r10_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(any_cell_sel_detected_r15_present, 1)); } + if (group_flags[6]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(meas_result_list_nr_r16.is_present(), 1)); + if (meas_result_list_nr_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *meas_result_list_nr_r16, 1, 8)); + } + } + if (group_flags[7]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(meas_result_list_nr_v1640.is_present(), 1)); + HANDLE_CODE(bref.pack(meas_result_list_ext_nr_r16.is_present(), 1)); + if (meas_result_list_nr_v1640.is_present()) { + HANDLE_CODE( + pack_integer(bref, meas_result_list_nr_v1640->carrier_freq_nr_r16, (uint32_t)0u, (uint32_t)3279165u)); + } + if (meas_result_list_ext_nr_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *meas_result_list_ext_nr_r16, 1, 7)); + } + } + if (group_flags[8]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(uncom_bar_pre_meas_result_r17_present, 1)); + if (uncom_bar_pre_meas_result_r17_present) { + HANDLE_CODE(uncom_bar_pre_meas_result_r17.pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -13743,7 +15613,7 @@ SRSASN_CODE log_meas_info_r10_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(6); + ext_groups_unpacker_guard group_flags(9); group_flags.unpack(bref); if (group_flags[0]) { @@ -13816,6 +15686,41 @@ SRSASN_CODE log_meas_info_r10_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(any_cell_sel_detected_r15_present, 1)); } + if (group_flags[6]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool meas_result_list_nr_r16_present; + HANDLE_CODE(bref.unpack(meas_result_list_nr_r16_present, 1)); + meas_result_list_nr_r16.set_present(meas_result_list_nr_r16_present); + if (meas_result_list_nr_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*meas_result_list_nr_r16, bref, 1, 8)); + } + } + if (group_flags[7]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool meas_result_list_nr_v1640_present; + HANDLE_CODE(bref.unpack(meas_result_list_nr_v1640_present, 1)); + meas_result_list_nr_v1640.set_present(meas_result_list_nr_v1640_present); + bool meas_result_list_ext_nr_r16_present; + HANDLE_CODE(bref.unpack(meas_result_list_ext_nr_r16_present, 1)); + meas_result_list_ext_nr_r16.set_present(meas_result_list_ext_nr_r16_present); + if (meas_result_list_nr_v1640.is_present()) { + HANDLE_CODE( + unpack_integer(meas_result_list_nr_v1640->carrier_freq_nr_r16, bref, (uint32_t)0u, (uint32_t)3279165u)); + } + if (meas_result_list_ext_nr_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*meas_result_list_ext_nr_r16, bref, 1, 7)); + } + } + if (group_flags[8]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(uncom_bar_pre_meas_result_r17_present, 1)); + if (uncom_bar_pre_meas_result_r17_present) { + HANDLE_CODE(uncom_bar_pre_meas_result_r17.unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -13923,83 +15828,28 @@ void log_meas_info_r10_s::to_json(json_writer& j) const if (any_cell_sel_detected_r15_present) { j.write_str("anyCellSelectionDetected-r15", "true"); } - } - j.end_obj(); -} - -// MeasResultCellNR-r15 ::= SEQUENCE -SRSASN_CODE meas_result_cell_nr_r15_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(meas_result_rs_idx_list_r15_present, 1)); - - HANDLE_CODE(pack_integer(bref, pci_r15, (uint16_t)0u, (uint16_t)1007u)); - HANDLE_CODE(meas_result_cell_r15.pack(bref)); - if (meas_result_rs_idx_list_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_rs_idx_list_r15, 1, 32)); - } - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= cgi_info_r15.is_present(); - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(cgi_info_r15.is_present(), 1)); - if (cgi_info_r15.is_present()) { - HANDLE_CODE(cgi_info_r15->pack(bref)); + if (meas_result_list_nr_r16.is_present()) { + j.start_array("measResultListNR-r16"); + for (const auto& e1 : *meas_result_list_nr_r16) { + e1.to_json(j); } + j.end_array(); } - } - return SRSASN_SUCCESS; -} -SRSASN_CODE meas_result_cell_nr_r15_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(meas_result_rs_idx_list_r15_present, 1)); - - HANDLE_CODE(unpack_integer(pci_r15, bref, (uint16_t)0u, (uint16_t)1007u)); - HANDLE_CODE(meas_result_cell_r15.unpack(bref)); - if (meas_result_rs_idx_list_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(meas_result_rs_idx_list_r15, bref, 1, 32)); - } - - if (ext) { - ext_groups_unpacker_guard group_flags(1); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool cgi_info_r15_present; - HANDLE_CODE(bref.unpack(cgi_info_r15_present, 1)); - cgi_info_r15.set_present(cgi_info_r15_present); - if (cgi_info_r15.is_present()) { - HANDLE_CODE(cgi_info_r15->unpack(bref)); - } + if (meas_result_list_nr_v1640.is_present()) { + j.write_fieldname("measResultListNR-v1640"); + j.start_obj(); + j.write_int("carrierFreqNR-r16", meas_result_list_nr_v1640->carrier_freq_nr_r16); + j.end_obj(); } - } - return SRSASN_SUCCESS; -} -void meas_result_cell_nr_r15_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("pci-r15", pci_r15); - j.write_fieldname("measResultCell-r15"); - meas_result_cell_r15.to_json(j); - if (meas_result_rs_idx_list_r15_present) { - j.start_array("measResultRS-IndexList-r15"); - for (const auto& e1 : meas_result_rs_idx_list_r15) { - e1.to_json(j); + if (meas_result_list_ext_nr_r16.is_present()) { + j.start_array("measResultListExtNR-r16"); + for (const auto& e1 : *meas_result_list_ext_nr_r16) { + e1.to_json(j); + } + j.end_array(); } - j.end_array(); - } - if (ext) { - if (cgi_info_r15.is_present()) { - j.write_fieldname("cgi-Info-r15"); - cgi_info_r15->to_json(j); + if (uncom_bar_pre_meas_result_r17_present) { + j.write_str("uncomBarPreMeasResult-r17", uncom_bar_pre_meas_result_r17.to_string()); } } j.end_obj(); @@ -14669,6 +16519,31 @@ uint8_t ul_pdcp_delay_result_r13_s::qci_id_r13_opts::to_number() const return map_enum_number(options, 4, value, "ul_pdcp_delay_result_r13_s::qci_id_r13_e_"); } +// UL-PDCP-DelayValueResult-r16 ::= SEQUENCE +SRSASN_CODE ul_pdcp_delay_value_result_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, drb_id_r16, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(pack_integer(bref, average_delay_r16, (uint16_t)0u, (uint16_t)10000u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ul_pdcp_delay_value_result_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(drb_id_r16, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(unpack_integer(average_delay_r16, bref, (uint16_t)0u, (uint16_t)10000u)); + + return SRSASN_SUCCESS; +} +void ul_pdcp_delay_value_result_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("drb-Id-r16", drb_id_r16); + j.write_int("averageDelay-r16", average_delay_r16); + j.end_obj(); +} + // MeasResultForECID-r9 ::= SEQUENCE SRSASN_CODE meas_result_for_ecid_r9_s::pack(bit_ref& bref) const { @@ -14692,6 +16567,31 @@ void meas_result_for_ecid_r9_s::to_json(json_writer& j) const j.end_obj(); } +// MeasResultForRSSI-NR-r16 ::= SEQUENCE +SRSASN_CODE meas_result_for_rssi_nr_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, rssi_result_nr_r16, (uint8_t)0u, (uint8_t)76u)); + HANDLE_CODE(pack_integer(bref, ch_occupancy_nr_r16, (uint8_t)0u, (uint8_t)100u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_result_for_rssi_nr_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(rssi_result_nr_r16, bref, (uint8_t)0u, (uint8_t)76u)); + HANDLE_CODE(unpack_integer(ch_occupancy_nr_r16, bref, (uint8_t)0u, (uint8_t)100u)); + + return SRSASN_SUCCESS; +} +void meas_result_for_rssi_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("rssi-ResultNR-r16", rssi_result_nr_r16); + j.write_int("channelOccupancyNR-r16", ch_occupancy_nr_r16); + j.end_obj(); +} + // MeasResultForRSSI-r13 ::= SEQUENCE SRSASN_CODE meas_result_for_rssi_r13_s::pack(bit_ref& bref) const { @@ -14806,6 +16706,10 @@ SRSASN_CODE meas_results_s::pack(bit_ref& bref) const group_flags[7] |= log_meas_result_list_wlan_r15.is_present(); group_flags[7] |= meas_result_sensing_r15.is_present(); group_flags[7] |= height_ue_r15_present; + group_flags[8] |= ul_pdcp_delay_value_result_list_r16.is_present(); + group_flags[8] |= meas_result_for_rssi_nr_r16.is_present(); + group_flags[9] |= uncom_bar_pre_meas_result_r17_present; + group_flags[9] |= coarse_location_info_r17_present; group_flags.pack(bref); if (group_flags[0]) { @@ -14924,6 +16828,30 @@ SRSASN_CODE meas_results_s::pack(bit_ref& bref) const HANDLE_CODE(pack_integer(bref, height_ue_r15, (int16_t)-400, (int16_t)8880)); } } + if (group_flags[8]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ul_pdcp_delay_value_result_list_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(meas_result_for_rssi_nr_r16.is_present(), 1)); + if (ul_pdcp_delay_value_result_list_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *ul_pdcp_delay_value_result_list_r16, 1, 11)); + } + if (meas_result_for_rssi_nr_r16.is_present()) { + HANDLE_CODE(meas_result_for_rssi_nr_r16->pack(bref)); + } + } + if (group_flags[9]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(uncom_bar_pre_meas_result_r17_present, 1)); + HANDLE_CODE(bref.pack(coarse_location_info_r17_present, 1)); + if (uncom_bar_pre_meas_result_r17_present) { + HANDLE_CODE(uncom_bar_pre_meas_result_r17.pack(bref)); + } + if (coarse_location_info_r17_present) { + HANDLE_CODE(coarse_location_info_r17.pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -14940,7 +16868,7 @@ SRSASN_CODE meas_results_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(8); + ext_groups_unpacker_guard group_flags(10); group_flags.unpack(bref); if (group_flags[0]) { @@ -15093,6 +17021,34 @@ SRSASN_CODE meas_results_s::unpack(cbit_ref& bref) HANDLE_CODE(unpack_integer(height_ue_r15, bref, (int16_t)-400, (int16_t)8880)); } } + if (group_flags[8]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool ul_pdcp_delay_value_result_list_r16_present; + HANDLE_CODE(bref.unpack(ul_pdcp_delay_value_result_list_r16_present, 1)); + ul_pdcp_delay_value_result_list_r16.set_present(ul_pdcp_delay_value_result_list_r16_present); + bool meas_result_for_rssi_nr_r16_present; + HANDLE_CODE(bref.unpack(meas_result_for_rssi_nr_r16_present, 1)); + meas_result_for_rssi_nr_r16.set_present(meas_result_for_rssi_nr_r16_present); + if (ul_pdcp_delay_value_result_list_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*ul_pdcp_delay_value_result_list_r16, bref, 1, 11)); + } + if (meas_result_for_rssi_nr_r16.is_present()) { + HANDLE_CODE(meas_result_for_rssi_nr_r16->unpack(bref)); + } + } + if (group_flags[9]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(uncom_bar_pre_meas_result_r17_present, 1)); + HANDLE_CODE(bref.unpack(coarse_location_info_r17_present, 1)); + if (uncom_bar_pre_meas_result_r17_present) { + HANDLE_CODE(uncom_bar_pre_meas_result_r17.unpack(bref)); + } + if (coarse_location_info_r17_present) { + HANDLE_CODE(coarse_location_info_r17.unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -15225,6 +17181,23 @@ void meas_results_s::to_json(json_writer& j) const if (height_ue_r15_present) { j.write_int("heightUE-r15", height_ue_r15); } + if (ul_pdcp_delay_value_result_list_r16.is_present()) { + j.start_array("ul-PDCP-DelayValueResultList-r16"); + for (const auto& e1 : *ul_pdcp_delay_value_result_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (meas_result_for_rssi_nr_r16.is_present()) { + j.write_fieldname("measResultForRSSI-NR-r16"); + meas_result_for_rssi_nr_r16->to_json(j); + } + if (uncom_bar_pre_meas_result_r17_present) { + j.write_str("uncomBarPreMeasResult-r17", uncom_bar_pre_meas_result_r17.to_string()); + } + if (coarse_location_info_r17_present) { + j.write_str("coarseLocationInfo-r17", coarse_location_info_r17.to_string()); + } } j.end_obj(); } diff --git a/lib/src/asn1/rrc/paging.cc b/lib/src/asn1/rrc/paging.cc index 4c63956de3..b0a5c95ab9 100644 --- a/lib/src/asn1/rrc/paging.cc +++ b/lib/src/asn1/rrc/paging.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,12 +29,157 @@ using namespace asn1::rrc; * Struct Methods ******************************************************************************/ +// PagingRecord-v1700 ::= SEQUENCE +SRSASN_CODE paging_record_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(paging_cause_r17_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE paging_record_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(paging_cause_r17_present, 1)); + + return SRSASN_SUCCESS; +} +void paging_record_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (paging_cause_r17_present) { + j.write_str("pagingCause-r17", "voice"); + } + j.end_obj(); +} + +// PagingRecord-v1610 ::= SEQUENCE +SRSASN_CODE paging_record_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(access_type_r16_present, 1)); + HANDLE_CODE(bref.pack(mt_edt_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE paging_record_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(access_type_r16_present, 1)); + HANDLE_CODE(bref.unpack(mt_edt_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void paging_record_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (access_type_r16_present) { + j.write_str("accessType-r16", "non3GPP"); + } + if (mt_edt_r16_present) { + j.write_str("mt-EDT-r16", "true"); + } + j.end_obj(); +} + +// Paging-v1700-IEs ::= SEQUENCE +SRSASN_CODE paging_v1700_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(paging_record_list_v1700_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (paging_record_list_v1700_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, paging_record_list_v1700, 1, 16)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE paging_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(paging_record_list_v1700_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (paging_record_list_v1700_present) { + HANDLE_CODE(unpack_dyn_seq_of(paging_record_list_v1700, bref, 1, 16)); + } + + return SRSASN_SUCCESS; +} +void paging_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (paging_record_list_v1700_present) { + j.start_array("pagingRecordList-v1700"); + for (const auto& e1 : paging_record_list_v1700) { + e1.to_json(j); + } + j.end_array(); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// Paging-v1610-IEs ::= SEQUENCE +SRSASN_CODE paging_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(paging_record_list_v1610_present, 1)); + HANDLE_CODE(bref.pack(uac_param_mod_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (paging_record_list_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, paging_record_list_v1610, 1, 16)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE paging_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(paging_record_list_v1610_present, 1)); + HANDLE_CODE(bref.unpack(uac_param_mod_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (paging_record_list_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(paging_record_list_v1610, bref, 1, 16)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void paging_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (paging_record_list_v1610_present) { + j.start_array("pagingRecordList-v1610"); + for (const auto& e1 : paging_record_list_v1610) { + e1.to_json(j); + } + j.end_array(); + } + if (uac_param_mod_r16_present) { + j.write_str("uac-ParamModification-r16", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + // Paging-v1530-IEs ::= SEQUENCE SRSASN_CODE paging_v1530_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(access_type_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + return SRSASN_SUCCESS; } SRSASN_CODE paging_v1530_ies_s::unpack(cbit_ref& bref) @@ -42,6 +187,10 @@ SRSASN_CODE paging_v1530_ies_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(access_type_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + return SRSASN_SUCCESS; } void paging_v1530_ies_s::to_json(json_writer& j) const @@ -52,8 +201,7 @@ void paging_v1530_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -862,6 +1010,35 @@ SRSASN_CODE ue_paging_coverage_info_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bre return SRSASN_SUCCESS; } +// UERadioPagingInformation-v1610-IEs ::= SEQUENCE +SRSASN_CODE ue_radio_paging_info_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(access_stratum_release_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_radio_paging_info_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(access_stratum_release_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + return SRSASN_SUCCESS; +} +void ue_radio_paging_info_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (access_stratum_release_r16_present) { + j.write_str("accessStratumRelease-r16", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // UERadioPagingInformation-v1310-IEs ::= SEQUENCE SRSASN_CODE ue_radio_paging_info_v1310_ies_s::pack(bit_ref& bref) const { @@ -872,6 +1049,9 @@ SRSASN_CODE ue_radio_paging_info_v1310_ies_s::pack(bit_ref& bref) const HANDLE_CODE( pack_dyn_seq_of(bref, supported_band_list_eutra_for_paging_r13, 1, 64, integer_packer(1, 256))); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -884,6 +1064,9 @@ SRSASN_CODE ue_radio_paging_info_v1310_ies_s::unpack(cbit_ref& bref) HANDLE_CODE( unpack_dyn_seq_of(supported_band_list_eutra_for_paging_r13, bref, 1, 64, integer_packer(1, 256))); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -899,8 +1082,7 @@ void ue_radio_paging_info_v1310_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } diff --git a/lib/src/asn1/rrc/phy_ded.cc b/lib/src/asn1/rrc/phy_ded.cc index 156c05f0d0..1b6e03ae3d 100644 --- a/lib/src/asn1/rrc/phy_ded.cc +++ b/lib/src/asn1/rrc/phy_ded.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,6 +29,819 @@ using namespace asn1::rrc; * Struct Methods ******************************************************************************/ +// PeriodicityStartPos-r16 ::= CHOICE +void periodicity_start_pos_r16_c::destroy_() {} +void periodicity_start_pos_r16_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +periodicity_start_pos_r16_c::periodicity_start_pos_r16_c(const periodicity_start_pos_r16_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::periodicity10ms: + break; + case types::periodicity20ms: + c.init(other.c.get()); + break; + case types::periodicity40ms: + c.init(other.c.get()); + break; + case types::periodicity80ms: + c.init(other.c.get()); + break; + case types::periodicity160ms: + c.init(other.c.get()); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "periodicity_start_pos_r16_c"); + } +} +periodicity_start_pos_r16_c& periodicity_start_pos_r16_c::operator=(const periodicity_start_pos_r16_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::periodicity10ms: + break; + case types::periodicity20ms: + c.set(other.c.get()); + break; + case types::periodicity40ms: + c.set(other.c.get()); + break; + case types::periodicity80ms: + c.set(other.c.get()); + break; + case types::periodicity160ms: + c.set(other.c.get()); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "periodicity_start_pos_r16_c"); + } + + return *this; +} +void periodicity_start_pos_r16_c::set_periodicity10ms() +{ + set(types::periodicity10ms); +} +uint8_t& periodicity_start_pos_r16_c::set_periodicity20ms() +{ + set(types::periodicity20ms); + return c.get(); +} +uint8_t& periodicity_start_pos_r16_c::set_periodicity40ms() +{ + set(types::periodicity40ms); + return c.get(); +} +uint8_t& periodicity_start_pos_r16_c::set_periodicity80ms() +{ + set(types::periodicity80ms); + return c.get(); +} +uint8_t& periodicity_start_pos_r16_c::set_periodicity160ms() +{ + set(types::periodicity160ms); + return c.get(); +} +void periodicity_start_pos_r16_c::set_spare3() +{ + set(types::spare3); +} +void periodicity_start_pos_r16_c::set_spare2() +{ + set(types::spare2); +} +void periodicity_start_pos_r16_c::set_spare1() +{ + set(types::spare1); +} +void periodicity_start_pos_r16_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::periodicity10ms: + break; + case types::periodicity20ms: + j.write_int("periodicity20ms", c.get()); + break; + case types::periodicity40ms: + j.write_int("periodicity40ms", c.get()); + break; + case types::periodicity80ms: + j.write_int("periodicity80ms", c.get()); + break; + case types::periodicity160ms: + j.write_int("periodicity160ms", c.get()); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "periodicity_start_pos_r16_c"); + } + j.end_obj(); +} +SRSASN_CODE periodicity_start_pos_r16_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::periodicity10ms: + break; + case types::periodicity20ms: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)1u)); + break; + case types::periodicity40ms: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)3u)); + break; + case types::periodicity80ms: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)7u)); + break; + case types::periodicity160ms: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)15u)); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "periodicity_start_pos_r16_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE periodicity_start_pos_r16_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::periodicity10ms: + break; + case types::periodicity20ms: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)1u)); + break; + case types::periodicity40ms: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)3u)); + break; + case types::periodicity80ms: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)7u)); + break; + case types::periodicity160ms: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)15u)); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "periodicity_start_pos_r16_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +// ResourceReservationConfigDL-r16 ::= SEQUENCE +SRSASN_CODE res_reserv_cfg_dl_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(res_reserv_freq_r16_present, 1)); + HANDLE_CODE(bref.pack(symbol_bitmap1_r16_present, 1)); + HANDLE_CODE(bref.pack(symbol_bitmap2_r16_present, 1)); + + HANDLE_CODE(periodicity_start_pos_r16.pack(bref)); + if (res_reserv_freq_r16_present) { + HANDLE_CODE(res_reserv_freq_r16.pack(bref)); + } + HANDLE_CODE(slot_bitmap_r16.pack(bref)); + if (symbol_bitmap1_r16_present) { + HANDLE_CODE(symbol_bitmap1_r16.pack(bref)); + } + if (symbol_bitmap2_r16_present) { + HANDLE_CODE(symbol_bitmap2_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE res_reserv_cfg_dl_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(res_reserv_freq_r16_present, 1)); + HANDLE_CODE(bref.unpack(symbol_bitmap1_r16_present, 1)); + HANDLE_CODE(bref.unpack(symbol_bitmap2_r16_present, 1)); + + HANDLE_CODE(periodicity_start_pos_r16.unpack(bref)); + if (res_reserv_freq_r16_present) { + HANDLE_CODE(res_reserv_freq_r16.unpack(bref)); + } + HANDLE_CODE(slot_bitmap_r16.unpack(bref)); + if (symbol_bitmap1_r16_present) { + HANDLE_CODE(symbol_bitmap1_r16.unpack(bref)); + } + if (symbol_bitmap2_r16_present) { + HANDLE_CODE(symbol_bitmap2_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void res_reserv_cfg_dl_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("periodicityStartPos-r16"); + periodicity_start_pos_r16.to_json(j); + if (res_reserv_freq_r16_present) { + j.write_fieldname("resourceReservationFreq-r16"); + res_reserv_freq_r16.to_json(j); + } + j.write_fieldname("slotBitmap-r16"); + slot_bitmap_r16.to_json(j); + if (symbol_bitmap1_r16_present) { + j.write_str("symbolBitmap1-r16", symbol_bitmap1_r16.to_string()); + } + if (symbol_bitmap2_r16_present) { + j.write_str("symbolBitmap2-r16", symbol_bitmap2_r16.to_string()); + } + j.end_obj(); +} + +void res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::destroy_() +{ + switch (type_) { + case types::rbg_bitmap1dot4: + c.destroy >(); + break; + case types::rbg_bitmap3: + c.destroy >(); + break; + case types::rbg_bitmap5: + c.destroy >(); + break; + case types::rbg_bitmap10: + c.destroy >(); + break; + case types::rbg_bitmap15: + c.destroy >(); + break; + case types::rbg_bitmap20: + c.destroy >(); + break; + default: + break; + } +} +void res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::rbg_bitmap1dot4: + c.init >(); + break; + case types::rbg_bitmap3: + c.init >(); + break; + case types::rbg_bitmap5: + c.init >(); + break; + case types::rbg_bitmap10: + c.init >(); + break; + case types::rbg_bitmap15: + c.init >(); + break; + case types::rbg_bitmap20: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_"); + } +} +res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::res_reserv_freq_r16_c_( + const res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::rbg_bitmap1dot4: + c.init(other.c.get >()); + break; + case types::rbg_bitmap3: + c.init(other.c.get >()); + break; + case types::rbg_bitmap5: + c.init(other.c.get >()); + break; + case types::rbg_bitmap10: + c.init(other.c.get >()); + break; + case types::rbg_bitmap15: + c.init(other.c.get >()); + break; + case types::rbg_bitmap20: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_"); + } +} +res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_& +res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::operator=(const res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::rbg_bitmap1dot4: + c.set(other.c.get >()); + break; + case types::rbg_bitmap3: + c.set(other.c.get >()); + break; + case types::rbg_bitmap5: + c.set(other.c.get >()); + break; + case types::rbg_bitmap10: + c.set(other.c.get >()); + break; + case types::rbg_bitmap15: + c.set(other.c.get >()); + break; + case types::rbg_bitmap20: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_"); + } + + return *this; +} +fixed_bitstring<6>& res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::set_rbg_bitmap1dot4() +{ + set(types::rbg_bitmap1dot4); + return c.get >(); +} +fixed_bitstring<8>& res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::set_rbg_bitmap3() +{ + set(types::rbg_bitmap3); + return c.get >(); +} +fixed_bitstring<13>& res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::set_rbg_bitmap5() +{ + set(types::rbg_bitmap5); + return c.get >(); +} +fixed_bitstring<17>& res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::set_rbg_bitmap10() +{ + set(types::rbg_bitmap10); + return c.get >(); +} +fixed_bitstring<19>& res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::set_rbg_bitmap15() +{ + set(types::rbg_bitmap15); + return c.get >(); +} +fixed_bitstring<25>& res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::set_rbg_bitmap20() +{ + set(types::rbg_bitmap20); + return c.get >(); +} +void res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::rbg_bitmap1dot4: + j.write_str("rbg-Bitmap1dot4", c.get >().to_string()); + break; + case types::rbg_bitmap3: + j.write_str("rbg-Bitmap3", c.get >().to_string()); + break; + case types::rbg_bitmap5: + j.write_str("rbg-Bitmap5", c.get >().to_string()); + break; + case types::rbg_bitmap10: + j.write_str("rbg-Bitmap10", c.get >().to_string()); + break; + case types::rbg_bitmap15: + j.write_str("rbg-Bitmap15", c.get >().to_string()); + break; + case types::rbg_bitmap20: + j.write_str("rbg-Bitmap20", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_"); + } + j.end_obj(); +} +SRSASN_CODE res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::rbg_bitmap1dot4: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::rbg_bitmap3: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::rbg_bitmap5: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::rbg_bitmap10: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::rbg_bitmap15: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::rbg_bitmap20: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rbg_bitmap1dot4: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::rbg_bitmap3: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::rbg_bitmap5: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::rbg_bitmap10: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::rbg_bitmap15: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::rbg_bitmap20: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::res_reserv_freq_r16_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +void res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::destroy_() +{ + switch (type_) { + case types::slot_pattern10ms: + c.destroy >(); + break; + case types::slot_pattern40ms: + c.destroy >(); + break; + default: + break; + } +} +void res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::slot_pattern10ms: + c.init >(); + break; + case types::slot_pattern40ms: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_"); + } +} +res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::slot_bitmap_r16_c_( + const res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::slot_pattern10ms: + c.init(other.c.get >()); + break; + case types::slot_pattern40ms: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_"); + } +} +res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_& +res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::operator=(const res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::slot_pattern10ms: + c.set(other.c.get >()); + break; + case types::slot_pattern40ms: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_"); + } + + return *this; +} +fixed_bitstring<20>& res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::set_slot_pattern10ms() +{ + set(types::slot_pattern10ms); + return c.get >(); +} +fixed_bitstring<80>& res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::set_slot_pattern40ms() +{ + set(types::slot_pattern40ms); + return c.get >(); +} +void res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::slot_pattern10ms: + j.write_str("slotPattern10ms", c.get >().to_string()); + break; + case types::slot_pattern40ms: + j.write_str("slotPattern40ms", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_"); + } + j.end_obj(); +} +SRSASN_CODE res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::slot_pattern10ms: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::slot_pattern40ms: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::slot_pattern10ms: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::slot_pattern40ms: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_dl_r16_s::slot_bitmap_r16_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +// ResourceReservationConfigUL-r16 ::= SEQUENCE +SRSASN_CODE res_reserv_cfg_ul_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(slot_bitmap_r16_present, 1)); + HANDLE_CODE(bref.pack(symbol_bitmap1_r16_present, 1)); + HANDLE_CODE(bref.pack(symbol_bitmap2_r16_present, 1)); + + HANDLE_CODE(periodicity_start_pos_r16.pack(bref)); + if (slot_bitmap_r16_present) { + HANDLE_CODE(slot_bitmap_r16.pack(bref)); + } + if (symbol_bitmap1_r16_present) { + HANDLE_CODE(symbol_bitmap1_r16.pack(bref)); + } + if (symbol_bitmap2_r16_present) { + HANDLE_CODE(symbol_bitmap2_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE res_reserv_cfg_ul_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(slot_bitmap_r16_present, 1)); + HANDLE_CODE(bref.unpack(symbol_bitmap1_r16_present, 1)); + HANDLE_CODE(bref.unpack(symbol_bitmap2_r16_present, 1)); + + HANDLE_CODE(periodicity_start_pos_r16.unpack(bref)); + if (slot_bitmap_r16_present) { + HANDLE_CODE(slot_bitmap_r16.unpack(bref)); + } + if (symbol_bitmap1_r16_present) { + HANDLE_CODE(symbol_bitmap1_r16.unpack(bref)); + } + if (symbol_bitmap2_r16_present) { + HANDLE_CODE(symbol_bitmap2_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void res_reserv_cfg_ul_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("periodicityStartPos-r16"); + periodicity_start_pos_r16.to_json(j); + if (slot_bitmap_r16_present) { + j.write_fieldname("slotBitmap-r16"); + slot_bitmap_r16.to_json(j); + } + if (symbol_bitmap1_r16_present) { + j.write_str("symbolBitmap1-r16", symbol_bitmap1_r16.to_string()); + } + if (symbol_bitmap2_r16_present) { + j.write_str("symbolBitmap2-r16", symbol_bitmap2_r16.to_string()); + } + j.end_obj(); +} + +void res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::destroy_() +{ + switch (type_) { + case types::slot_pattern10ms: + c.destroy >(); + break; + case types::slot_pattern40ms: + c.destroy >(); + break; + default: + break; + } +} +void res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::slot_pattern10ms: + c.init >(); + break; + case types::slot_pattern40ms: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_"); + } +} +res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::slot_bitmap_r16_c_( + const res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::slot_pattern10ms: + c.init(other.c.get >()); + break; + case types::slot_pattern40ms: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_"); + } +} +res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_& +res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::operator=(const res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::slot_pattern10ms: + c.set(other.c.get >()); + break; + case types::slot_pattern40ms: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_"); + } + + return *this; +} +fixed_bitstring<20>& res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::set_slot_pattern10ms() +{ + set(types::slot_pattern10ms); + return c.get >(); +} +fixed_bitstring<80>& res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::set_slot_pattern40ms() +{ + set(types::slot_pattern40ms); + return c.get >(); +} +void res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::slot_pattern10ms: + j.write_str("slotPattern10ms", c.get >().to_string()); + break; + case types::slot_pattern40ms: + j.write_str("slotPattern40ms", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_"); + } + j.end_obj(); +} +SRSASN_CODE res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::slot_pattern10ms: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::slot_pattern40ms: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::slot_pattern10ms: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::slot_pattern40ms: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_ul_r16_s::slot_bitmap_r16_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + // NZP-FrequencyDensity-r14 ::= ENUMERATED const char* nzp_freq_density_r14_opts::to_string() const { @@ -9046,6 +9859,86 @@ uint8_t ant_info_ul_stti_r15_s::tx_mode_ul_stti_r15_opts::to_number() const return map_enum_number(options, 2, value, "ant_info_ul_stti_r15_s::tx_mode_ul_stti_r15_e_"); } +// CE-PDSCH-14HARQ-Config-r17 ::= SEQUENCE +SRSASN_CODE ce_pdsch_minus14_harq_cfg_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(ce_harq_ack_delay_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ce_pdsch_minus14_harq_cfg_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(ce_harq_ack_delay_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ce_pdsch_minus14_harq_cfg_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ce-HARQ-AckDelay-r17", ce_harq_ack_delay_r17.to_string()); + j.end_obj(); +} + +const char* ce_pdsch_minus14_harq_cfg_r17_s::ce_harq_ack_delay_r17_opts::to_string() const +{ + static const char* options[] = {"alt-1", "alt-2e"}; + return convert_enum_idx(options, 2, value, "ce_pdsch_minus14_harq_cfg_r17_s::ce_harq_ack_delay_r17_e_"); +} +int8_t ce_pdsch_minus14_harq_cfg_r17_s::ce_harq_ack_delay_r17_opts::to_number() const +{ + static const int8_t options[] = {-1, -2}; + return map_enum_number(options, 2, value, "ce_pdsch_minus14_harq_cfg_r17_s::ce_harq_ack_delay_r17_e_"); +} + +// CE-PDSCH-MultiTB-Config-r16 ::= SEQUENCE +SRSASN_CODE ce_pdsch_multi_tb_cfg_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(interleaving_r16_present, 1)); + HANDLE_CODE(bref.pack(harq_ack_bundling_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ce_pdsch_multi_tb_cfg_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(interleaving_r16_present, 1)); + HANDLE_CODE(bref.unpack(harq_ack_bundling_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void ce_pdsch_multi_tb_cfg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (interleaving_r16_present) { + j.write_str("interleaving-r16", "on"); + } + if (harq_ack_bundling_r16_present) { + j.write_str("harq-AckBundling-r16", "on"); + } + j.end_obj(); +} + +// CE-PUSCH-MultiTB-Config-r16 ::= SEQUENCE +SRSASN_CODE ce_pusch_multi_tb_cfg_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(interleaving_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ce_pusch_multi_tb_cfg_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(interleaving_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void ce_pusch_multi_tb_cfg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (interleaving_r16_present) { + j.write_str("interleaving-r16", "on"); + } + j.end_obj(); +} + // CQI-ReportConfig-r15 ::= CHOICE void cqi_report_cfg_r15_c::set(types::options e) { @@ -10517,6 +11410,133 @@ bool srs_cc_set_idx_r14_s::operator==(const srs_cc_set_idx_r14_s& other) const return cc_set_idx_r14 == other.cc_set_idx_r14 and cc_idx_in_one_cc_set_r14 == other.cc_idx_in_one_cc_set_r14; } +// SRS-ConfigAdd-r16 ::= SEQUENCE +SRSASN_CODE srs_cfg_add_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(srs_guard_symbol_as_add_r16_present, 1)); + HANDLE_CODE(bref.pack(srs_guard_symbol_fh_add_r16_present, 1)); + + HANDLE_CODE(srs_rep_num_add_r16.pack(bref)); + HANDLE_CODE(srs_bw_add_r16.pack(bref)); + HANDLE_CODE(srs_hop_bw_add_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, srs_freq_domain_pos_add_r16, (uint8_t)0u, (uint8_t)23u)); + HANDLE_CODE(srs_ant_port_add_r16.pack(bref)); + HANDLE_CODE(srs_cyclic_shift_add_r16.pack(bref)); + HANDLE_CODE(srs_tx_comb_num_add_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, srs_tx_comb_add_r16, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(pack_integer(bref, srs_start_pos_add_r16, (uint8_t)1u, (uint8_t)13u)); + HANDLE_CODE(pack_integer(bref, srs_dur_add_r16, (uint8_t)1u, (uint8_t)13u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE srs_cfg_add_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(srs_guard_symbol_as_add_r16_present, 1)); + HANDLE_CODE(bref.unpack(srs_guard_symbol_fh_add_r16_present, 1)); + + HANDLE_CODE(srs_rep_num_add_r16.unpack(bref)); + HANDLE_CODE(srs_bw_add_r16.unpack(bref)); + HANDLE_CODE(srs_hop_bw_add_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(srs_freq_domain_pos_add_r16, bref, (uint8_t)0u, (uint8_t)23u)); + HANDLE_CODE(srs_ant_port_add_r16.unpack(bref)); + HANDLE_CODE(srs_cyclic_shift_add_r16.unpack(bref)); + HANDLE_CODE(srs_tx_comb_num_add_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(srs_tx_comb_add_r16, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(unpack_integer(srs_start_pos_add_r16, bref, (uint8_t)1u, (uint8_t)13u)); + HANDLE_CODE(unpack_integer(srs_dur_add_r16, bref, (uint8_t)1u, (uint8_t)13u)); + + return SRSASN_SUCCESS; +} +void srs_cfg_add_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("srs-RepNumAdd-r16", srs_rep_num_add_r16.to_string()); + j.write_str("srs-BandwidthAdd-r16", srs_bw_add_r16.to_string()); + j.write_str("srs-HoppingBandwidthAdd-r16", srs_hop_bw_add_r16.to_string()); + j.write_int("srs-FreqDomainPosAdd-r16", srs_freq_domain_pos_add_r16); + j.write_str("srs-AntennaPortAdd-r16", srs_ant_port_add_r16.to_string()); + j.write_str("srs-CyclicShiftAdd-r16", srs_cyclic_shift_add_r16.to_string()); + j.write_str("srs-TransmissionCombNumAdd-r16", srs_tx_comb_num_add_r16.to_string()); + j.write_int("srs-TransmissionCombAdd-r16", srs_tx_comb_add_r16); + j.write_int("srs-StartPosAdd-r16", srs_start_pos_add_r16); + j.write_int("srs-DurationAdd-r16", srs_dur_add_r16); + if (srs_guard_symbol_as_add_r16_present) { + j.write_str("srs-GuardSymbolAS-Add-r16", "enabled"); + } + if (srs_guard_symbol_fh_add_r16_present) { + j.write_str("srs-GuardSymbolFH-Add-r16", "enabled"); + } + j.end_obj(); +} +bool srs_cfg_add_r16_s::operator==(const srs_cfg_add_r16_s& other) const +{ + return srs_rep_num_add_r16 == other.srs_rep_num_add_r16 and srs_bw_add_r16 == other.srs_bw_add_r16 and + srs_hop_bw_add_r16 == other.srs_hop_bw_add_r16 and + srs_freq_domain_pos_add_r16 == other.srs_freq_domain_pos_add_r16 and + srs_ant_port_add_r16 == other.srs_ant_port_add_r16 and + srs_cyclic_shift_add_r16 == other.srs_cyclic_shift_add_r16 and + srs_tx_comb_num_add_r16 == other.srs_tx_comb_num_add_r16 and + srs_tx_comb_add_r16 == other.srs_tx_comb_add_r16 and srs_start_pos_add_r16 == other.srs_start_pos_add_r16 and + srs_dur_add_r16 == other.srs_dur_add_r16 and + srs_guard_symbol_as_add_r16_present == other.srs_guard_symbol_as_add_r16_present and + srs_guard_symbol_fh_add_r16_present == other.srs_guard_symbol_fh_add_r16_present; +} + +const char* srs_cfg_add_r16_s::srs_rep_num_add_r16_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n3", "n4", "n6", "n7", "n8", "n9", "n12", "n13"}; + return convert_enum_idx(options, 10, value, "srs_cfg_add_r16_s::srs_rep_num_add_r16_e_"); +} +uint8_t srs_cfg_add_r16_s::srs_rep_num_add_r16_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3, 4, 6, 7, 8, 9, 12, 13}; + return map_enum_number(options, 10, value, "srs_cfg_add_r16_s::srs_rep_num_add_r16_e_"); +} + +const char* srs_cfg_add_r16_s::srs_bw_add_r16_opts::to_string() const +{ + static const char* options[] = {"bw0", "bw1", "bw2", "bw3"}; + return convert_enum_idx(options, 4, value, "srs_cfg_add_r16_s::srs_bw_add_r16_e_"); +} +uint8_t srs_cfg_add_r16_s::srs_bw_add_r16_opts::to_number() const +{ + static const uint8_t options[] = {0, 1, 2, 3}; + return map_enum_number(options, 4, value, "srs_cfg_add_r16_s::srs_bw_add_r16_e_"); +} + +const char* srs_cfg_add_r16_s::srs_hop_bw_add_r16_opts::to_string() const +{ + static const char* options[] = {"hbw0", "hbw1", "hbw2", "hbw3"}; + return convert_enum_idx(options, 4, value, "srs_cfg_add_r16_s::srs_hop_bw_add_r16_e_"); +} +uint8_t srs_cfg_add_r16_s::srs_hop_bw_add_r16_opts::to_number() const +{ + static const uint8_t options[] = {0, 1, 2, 3}; + return map_enum_number(options, 4, value, "srs_cfg_add_r16_s::srs_hop_bw_add_r16_e_"); +} + +const char* srs_cfg_add_r16_s::srs_cyclic_shift_add_r16_opts::to_string() const +{ + static const char* options[] = {"cs0", "cs1", "cs2", "cs3", "cs4", "cs5", "cs6", "cs7", "cs8", "cs9", "cs10", "cs11"}; + return convert_enum_idx(options, 12, value, "srs_cfg_add_r16_s::srs_cyclic_shift_add_r16_e_"); +} +uint8_t srs_cfg_add_r16_s::srs_cyclic_shift_add_r16_opts::to_number() const +{ + static const uint8_t options[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + return map_enum_number(options, 12, value, "srs_cfg_add_r16_s::srs_cyclic_shift_add_r16_e_"); +} + +const char* srs_cfg_add_r16_s::srs_tx_comb_num_add_r16_opts::to_string() const +{ + static const char* options[] = {"n2", "n4"}; + return convert_enum_idx(options, 2, value, "srs_cfg_add_r16_s::srs_tx_comb_num_add_r16_e_"); +} +uint8_t srs_cfg_add_r16_s::srs_tx_comb_num_add_r16_opts::to_number() const +{ + static const uint8_t options[] = {2, 4}; + return map_enum_number(options, 2, value, "srs_cfg_add_r16_s::srs_tx_comb_num_add_r16_e_"); +} + // SRS-ConfigAp-r10 ::= SEQUENCE SRSASN_CODE srs_cfg_ap_r10_s::pack(bit_ref& bref) const { @@ -13397,15 +14417,72 @@ const char* pdsch_cfg_ded_v1530_s::alt_mcs_table_scaling_cfg_r15_opts::to_string static const char* options[] = {"oDot5", "oDot625", "oDot75", "oDot875"}; return convert_enum_idx(options, 4, value, "pdsch_cfg_ded_v1530_s::alt_mcs_table_scaling_cfg_r15_e_"); } -float pdsch_cfg_ded_v1530_s::alt_mcs_table_scaling_cfg_r15_opts::to_number() const +float pdsch_cfg_ded_v1530_s::alt_mcs_table_scaling_cfg_r15_opts::to_number() const +{ + static const float options[] = {0.5, 0.625, 0.75, 0.875}; + return map_enum_number(options, 4, value, "pdsch_cfg_ded_v1530_s::alt_mcs_table_scaling_cfg_r15_e_"); +} +const char* pdsch_cfg_ded_v1530_s::alt_mcs_table_scaling_cfg_r15_opts::to_number_string() const +{ + static const char* options[] = {"0.5", "0.625", "0.75", "0.875"}; + return convert_enum_idx(options, 4, value, "pdsch_cfg_ded_v1530_s::alt_mcs_table_scaling_cfg_r15_e_"); +} + +// PDSCH-ConfigDedicated-v1610 ::= SEQUENCE +SRSASN_CODE pdsch_cfg_ded_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(ce_pdsch_multi_tb_cfg_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdsch_cfg_ded_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(ce_pdsch_multi_tb_cfg_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void pdsch_cfg_ded_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ce-PDSCH-MultiTB-Config-r16"); + ce_pdsch_multi_tb_cfg_r16.to_json(j); + j.end_obj(); +} + +// PDSCH-ConfigDedicated-v1700 ::= SEQUENCE +SRSASN_CODE pdsch_cfg_ded_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ce_pdsch_minus14_harq_cfg_r17_present, 1)); + HANDLE_CODE(bref.pack(ce_pdsch_max_tbs_r17_present, 1)); + + if (ce_pdsch_minus14_harq_cfg_r17_present) { + HANDLE_CODE(ce_pdsch_minus14_harq_cfg_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdsch_cfg_ded_v1700_s::unpack(cbit_ref& bref) { - static const float options[] = {0.5, 0.625, 0.75, 0.875}; - return map_enum_number(options, 4, value, "pdsch_cfg_ded_v1530_s::alt_mcs_table_scaling_cfg_r15_e_"); + HANDLE_CODE(bref.unpack(ce_pdsch_minus14_harq_cfg_r17_present, 1)); + HANDLE_CODE(bref.unpack(ce_pdsch_max_tbs_r17_present, 1)); + + if (ce_pdsch_minus14_harq_cfg_r17_present) { + HANDLE_CODE(ce_pdsch_minus14_harq_cfg_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; } -const char* pdsch_cfg_ded_v1530_s::alt_mcs_table_scaling_cfg_r15_opts::to_number_string() const +void pdsch_cfg_ded_v1700_s::to_json(json_writer& j) const { - static const char* options[] = {"0.5", "0.625", "0.75", "0.875"}; - return convert_enum_idx(options, 4, value, "pdsch_cfg_ded_v1530_s::alt_mcs_table_scaling_cfg_r15_e_"); + j.start_obj(); + if (ce_pdsch_minus14_harq_cfg_r17_present) { + j.write_fieldname("ce-PDSCH-14HARQ-Config-r17"); + ce_pdsch_minus14_harq_cfg_r17.to_json(j); + } + if (ce_pdsch_max_tbs_r17_present) { + j.write_str("ce-PDSCH-maxTBS-r17", "enabled"); + } + j.end_obj(); } // PUCCH-ConfigDedicated ::= SEQUENCE @@ -16170,6 +17247,27 @@ SRSASN_CODE pusch_cfg_ded_v1530_s::ce_pusch_sub_prb_cfg_r15_c_::unpack(cbit_ref& return SRSASN_SUCCESS; } +// PUSCH-ConfigDedicated-v1610 ::= SEQUENCE +SRSASN_CODE pusch_cfg_ded_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(ce_pusch_multi_tb_cfg_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE pusch_cfg_ded_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(ce_pusch_multi_tb_cfg_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void pusch_cfg_ded_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ce-PUSCH-MultiTB-Config-r16"); + ce_pusch_multi_tb_cfg_r16.to_json(j); + j.end_obj(); +} + // PUSCH-EnhancementsConfig-r14 ::= CHOICE void pusch_enhance_cfg_r14_c::set(types::options e) { @@ -16767,6 +17865,68 @@ bool phys_cfg_ded_stti_r15_c::operator==(const phys_cfg_ded_stti_r15_c& other) c (not c.short_tti_r15_present or c.short_tti_r15 == other.c.short_tti_r15); } +// ResourceReservationConfigDedicatedDL-r16 ::= SEQUENCE +SRSASN_CODE res_reserv_cfg_ded_dl_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(res_reserv_ded_dl_r16_present, 1)); + + if (res_reserv_ded_dl_r16_present) { + HANDLE_CODE(res_reserv_ded_dl_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE res_reserv_cfg_ded_dl_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(res_reserv_ded_dl_r16_present, 1)); + + if (res_reserv_ded_dl_r16_present) { + HANDLE_CODE(res_reserv_ded_dl_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void res_reserv_cfg_ded_dl_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (res_reserv_ded_dl_r16_present) { + j.write_fieldname("resourceReservationDedicatedDL-r16"); + res_reserv_ded_dl_r16.to_json(j); + } + j.end_obj(); +} + +// ResourceReservationConfigDedicatedUL-r16 ::= SEQUENCE +SRSASN_CODE res_reserv_cfg_ded_ul_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(res_reserv_ded_ul_r16_present, 1)); + + if (res_reserv_ded_ul_r16_present) { + HANDLE_CODE(res_reserv_ded_ul_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE res_reserv_cfg_ded_ul_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(res_reserv_ded_ul_r16_present, 1)); + + if (res_reserv_ded_ul_r16_present) { + HANDLE_CODE(res_reserv_ded_ul_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void res_reserv_cfg_ded_ul_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (res_reserv_ded_ul_r16_present) { + j.write_fieldname("resourceReservationDedicatedUL-r16"); + res_reserv_ded_ul_r16.to_json(j); + } + j.end_obj(); +} + // SPUCCH-Config-v1550 ::= CHOICE void spucch_cfg_v1550_c::set(types::options e) { @@ -17326,6 +18486,136 @@ uint8_t srs_ul_cfg_ded_v1310_c::setup_s_::tx_comb_num_r13_opts::to_number() cons return map_enum_number(options, 2, value, "srs_ul_cfg_ded_v1310_c::setup_s_::tx_comb_num_r13_e_"); } +// SoundingRS-UL-ConfigDedicatedAdd-r16 ::= SEQUENCE +SRSASN_CODE srs_ul_cfg_ded_add_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(srs_cfg_ap_dci_format4_r16_present, 1)); + HANDLE_CODE(bref.pack(srs_activ_ap_r13_present, 1)); + + HANDLE_CODE(pack_integer(bref, srs_cfg_idx_ap_r16, (uint8_t)0u, (uint8_t)31u)); + if (srs_cfg_ap_dci_format4_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, srs_cfg_ap_dci_format4_r16, 1, 3)); + } + if (srs_activ_ap_r13_present) { + HANDLE_CODE(srs_activ_ap_r13.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE srs_ul_cfg_ded_add_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(srs_cfg_ap_dci_format4_r16_present, 1)); + HANDLE_CODE(bref.unpack(srs_activ_ap_r13_present, 1)); + + HANDLE_CODE(unpack_integer(srs_cfg_idx_ap_r16, bref, (uint8_t)0u, (uint8_t)31u)); + if (srs_cfg_ap_dci_format4_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(srs_cfg_ap_dci_format4_r16, bref, 1, 3)); + } + if (srs_activ_ap_r13_present) { + HANDLE_CODE(srs_activ_ap_r13.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void srs_ul_cfg_ded_add_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("srs-ConfigIndexAp-r16", srs_cfg_idx_ap_r16); + if (srs_cfg_ap_dci_format4_r16_present) { + j.start_array("srs-ConfigApDCI-Format4-r16"); + for (const auto& e1 : srs_cfg_ap_dci_format4_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (srs_activ_ap_r13_present) { + j.write_fieldname("srs-ActivateAp-r13"); + srs_activ_ap_r13.to_json(j); + } + j.end_obj(); +} +bool srs_ul_cfg_ded_add_r16_s::operator==(const srs_ul_cfg_ded_add_r16_s& other) const +{ + return srs_cfg_idx_ap_r16 == other.srs_cfg_idx_ap_r16 and + srs_cfg_ap_dci_format4_r16_present == other.srs_cfg_ap_dci_format4_r16_present and + (not srs_cfg_ap_dci_format4_r16_present or srs_cfg_ap_dci_format4_r16 == other.srs_cfg_ap_dci_format4_r16) and + srs_activ_ap_r13_present == other.srs_activ_ap_r13_present and + (not srs_activ_ap_r13_present or srs_activ_ap_r13 == other.srs_activ_ap_r13); +} + +void srs_ul_cfg_ded_add_r16_s::srs_activ_ap_r13_c_::set(types::options e) +{ + type_ = e; +} +void srs_ul_cfg_ded_add_r16_s::srs_activ_ap_r13_c_::set_release() +{ + set(types::release); +} +srs_ul_cfg_ded_add_r16_s::srs_activ_ap_r13_c_::setup_s_& srs_ul_cfg_ded_add_r16_s::srs_activ_ap_r13_c_::set_setup() +{ + set(types::setup); + return c; +} +void srs_ul_cfg_ded_add_r16_s::srs_activ_ap_r13_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::release: + break; + case types::setup: + j.write_fieldname("setup"); + j.start_obj(); + j.write_fieldname("srs-ConfigApDCI-Format0-r16"); + c.srs_cfg_ap_dci_format0_r16.to_json(j); + j.write_fieldname("srs-ConfigApDCI-Format1a2b2c-r16"); + c.srs_cfg_ap_dci_format1a2b2c_r16.to_json(j); + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "srs_ul_cfg_ded_add_r16_s::srs_activ_ap_r13_c_"); + } + j.end_obj(); +} +SRSASN_CODE srs_ul_cfg_ded_add_r16_s::srs_activ_ap_r13_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(c.srs_cfg_ap_dci_format0_r16.pack(bref)); + HANDLE_CODE(c.srs_cfg_ap_dci_format1a2b2c_r16.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "srs_ul_cfg_ded_add_r16_s::srs_activ_ap_r13_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE srs_ul_cfg_ded_add_r16_s::srs_activ_ap_r13_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(c.srs_cfg_ap_dci_format0_r16.unpack(bref)); + HANDLE_CODE(c.srs_cfg_ap_dci_format1a2b2c_r16.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "srs_ul_cfg_ded_add_r16_s::srs_activ_ap_r13_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} +bool srs_ul_cfg_ded_add_r16_s::srs_activ_ap_r13_c_::operator==(const srs_activ_ap_r13_c_& other) const +{ + return type() == other.type() and c.srs_cfg_ap_dci_format0_r16 == other.c.srs_cfg_ap_dci_format0_r16 and + c.srs_cfg_ap_dci_format1a2b2c_r16 == other.c.srs_cfg_ap_dci_format1a2b2c_r16; +} + // SoundingRS-UL-ConfigDedicatedAperiodic-r10 ::= CHOICE void srs_ul_cfg_ded_aperiodic_r10_c::set(types::options e) { @@ -18043,6 +19333,115 @@ uint8_t srs_ul_cfg_ded_up_pts_ext_r13_c::setup_s_::tx_comb_num_r13_opts::to_numb return map_enum_number(options, 2, value, "srs_ul_cfg_ded_up_pts_ext_r13_c::setup_s_::tx_comb_num_r13_e_"); } +// SoundingRS-VirtualCellID-r16 ::= SEQUENCE +SRSASN_CODE srs_virtual_cell_id_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, srs_virtual_cell_id_r16, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(bref.pack(srs_virtual_cell_id_all_srs_r16, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE srs_virtual_cell_id_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(srs_virtual_cell_id_r16, bref, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(bref.unpack(srs_virtual_cell_id_all_srs_r16, 1)); + + return SRSASN_SUCCESS; +} +void srs_virtual_cell_id_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("srs-VirtualCellID-r16", srs_virtual_cell_id_r16); + j.write_bool("srs-VirtualCellID-AllSRS-r16", srs_virtual_cell_id_all_srs_r16); + j.end_obj(); +} +bool srs_virtual_cell_id_r16_s::operator==(const srs_virtual_cell_id_r16_s& other) const +{ + return srs_virtual_cell_id_r16 == other.srs_virtual_cell_id_r16 and + srs_virtual_cell_id_all_srs_r16 == other.srs_virtual_cell_id_all_srs_r16; +} + +// UplinkPowerControlAddSRS-r16 ::= SEQUENCE +SRSASN_CODE ul_pwr_ctrl_add_srs_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(tpc_idx_srs_add_r16_present, 1)); + HANDLE_CODE(bref.pack(start_bit_of_format3_b_srs_add_r16_present, 1)); + HANDLE_CODE(bref.pack(field_type_format3_b_srs_add_r16_present, 1)); + HANDLE_CODE(bref.pack(p0_ue_srs_add_r16_present, 1)); + + if (tpc_idx_srs_add_r16_present) { + HANDLE_CODE(tpc_idx_srs_add_r16.pack(bref)); + } + if (start_bit_of_format3_b_srs_add_r16_present) { + HANDLE_CODE(pack_integer(bref, start_bit_of_format3_b_srs_add_r16, (uint8_t)0u, (uint8_t)31u)); + } + if (field_type_format3_b_srs_add_r16_present) { + HANDLE_CODE(pack_integer(bref, field_type_format3_b_srs_add_r16, (uint8_t)1u, (uint8_t)2u)); + } + if (p0_ue_srs_add_r16_present) { + HANDLE_CODE(pack_integer(bref, p0_ue_srs_add_r16, (int8_t)-16, (int8_t)15)); + } + HANDLE_CODE(bref.pack(accumulation_enabled_srs_add_r16, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ul_pwr_ctrl_add_srs_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(tpc_idx_srs_add_r16_present, 1)); + HANDLE_CODE(bref.unpack(start_bit_of_format3_b_srs_add_r16_present, 1)); + HANDLE_CODE(bref.unpack(field_type_format3_b_srs_add_r16_present, 1)); + HANDLE_CODE(bref.unpack(p0_ue_srs_add_r16_present, 1)); + + if (tpc_idx_srs_add_r16_present) { + HANDLE_CODE(tpc_idx_srs_add_r16.unpack(bref)); + } + if (start_bit_of_format3_b_srs_add_r16_present) { + HANDLE_CODE(unpack_integer(start_bit_of_format3_b_srs_add_r16, bref, (uint8_t)0u, (uint8_t)31u)); + } + if (field_type_format3_b_srs_add_r16_present) { + HANDLE_CODE(unpack_integer(field_type_format3_b_srs_add_r16, bref, (uint8_t)1u, (uint8_t)2u)); + } + if (p0_ue_srs_add_r16_present) { + HANDLE_CODE(unpack_integer(p0_ue_srs_add_r16, bref, (int8_t)-16, (int8_t)15)); + } + HANDLE_CODE(bref.unpack(accumulation_enabled_srs_add_r16, 1)); + + return SRSASN_SUCCESS; +} +void ul_pwr_ctrl_add_srs_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (tpc_idx_srs_add_r16_present) { + j.write_fieldname("tpc-IndexSRS-Add-r16"); + tpc_idx_srs_add_r16.to_json(j); + } + if (start_bit_of_format3_b_srs_add_r16_present) { + j.write_int("startingBitOfFormat3B-SRS-Add-r16", start_bit_of_format3_b_srs_add_r16); + } + if (field_type_format3_b_srs_add_r16_present) { + j.write_int("fieldTypeFormat3B-SRS-Add-r16", field_type_format3_b_srs_add_r16); + } + if (p0_ue_srs_add_r16_present) { + j.write_int("p0-UE-SRS-Add-r16", p0_ue_srs_add_r16); + } + j.write_bool("accumulationEnabledSRS-Add-r16", accumulation_enabled_srs_add_r16); + j.end_obj(); +} +bool ul_pwr_ctrl_add_srs_r16_s::operator==(const ul_pwr_ctrl_add_srs_r16_s& other) const +{ + return tpc_idx_srs_add_r16_present == other.tpc_idx_srs_add_r16_present and + (not tpc_idx_srs_add_r16_present or tpc_idx_srs_add_r16 == other.tpc_idx_srs_add_r16) and + start_bit_of_format3_b_srs_add_r16_present == other.start_bit_of_format3_b_srs_add_r16_present and + (not start_bit_of_format3_b_srs_add_r16_present or + start_bit_of_format3_b_srs_add_r16 == other.start_bit_of_format3_b_srs_add_r16) and + field_type_format3_b_srs_add_r16_present == other.field_type_format3_b_srs_add_r16_present and + (not field_type_format3_b_srs_add_r16_present or + field_type_format3_b_srs_add_r16 == other.field_type_format3_b_srs_add_r16) and + p0_ue_srs_add_r16_present == other.p0_ue_srs_add_r16_present and + (not p0_ue_srs_add_r16_present or p0_ue_srs_add_r16 == other.p0_ue_srs_add_r16) and + accumulation_enabled_srs_add_r16 == other.accumulation_enabled_srs_add_r16; +} + // UplinkPowerControlDedicated ::= SEQUENCE SRSASN_CODE ul_pwr_ctrl_ded_s::pack(bit_ref& bref) const { @@ -18356,6 +19755,34 @@ bool ul_pwr_ctrl_ded_v1530_s::operator==(const ul_pwr_ctrl_ded_v1530_s& other) c (not p0_ue_pusch_r15_present or p0_ue_pusch_r15 == other.p0_ue_pusch_r15); } +// WidebandPRG-r16 ::= SEQUENCE +SRSASN_CODE wideband_prg_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(wideband_prg_sf_r16, 1)); + HANDLE_CODE(bref.pack(wideband_prg_slot_subslot_r16, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE wideband_prg_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(wideband_prg_sf_r16, 1)); + HANDLE_CODE(bref.unpack(wideband_prg_slot_subslot_r16, 1)); + + return SRSASN_SUCCESS; +} +void wideband_prg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_bool("widebandPRG-Subframe-r16", wideband_prg_sf_r16); + j.write_bool("widebandPRG-SlotSubslot-r16", wideband_prg_slot_subslot_r16); + j.end_obj(); +} +bool wideband_prg_r16_s::operator==(const wideband_prg_r16_s& other) const +{ + return wideband_prg_sf_r16 == other.wideband_prg_sf_r16 and + wideband_prg_slot_subslot_r16 == other.wideband_prg_slot_subslot_r16; +} + // PhysicalConfigDedicated ::= SEQUENCE SRSASN_CODE phys_cfg_ded_s::pack(bit_ref& bref) const { @@ -18478,6 +19905,18 @@ SRSASN_CODE phys_cfg_ded_s::pack(bit_ref& bref) const group_flags[10] |= semi_static_cfi_cfg_r15.is_present(); group_flags[10] |= blind_pdsch_repeat_cfg_r15.is_present(); group_flags[11] |= spucch_cfg_v1550.is_present(); + group_flags[12] |= pdsch_cfg_ded_v1610.is_present(); + group_flags[12] |= pusch_cfg_ded_v1610.is_present(); + group_flags[12] |= ce_csi_rs_feedback_r16_present; + group_flags[12] |= res_reserv_cfg_ded_dl_r16.is_present(); + group_flags[12] |= res_reserv_cfg_ded_ul_r16.is_present(); + group_flags[12] |= srs_ul_cfg_ded_add_r16.is_present(); + group_flags[12] |= ul_pwr_ctrl_add_srs_r16.is_present(); + group_flags[12] |= srs_virtual_cell_id_r16.is_present(); + group_flags[12] |= wideband_prg_r16.is_present(); + group_flags[13] |= pdsch_cfg_ded_v1700.is_present(); + group_flags[13] |= ntn_cfg_ded_r17.is_present(); + group_flags[14] |= ul_segmented_precompensation_gap_r17_present; group_flags.pack(bref); if (group_flags[0]) { @@ -18822,6 +20261,70 @@ SRSASN_CODE phys_cfg_ded_s::pack(bit_ref& bref) const HANDLE_CODE(spucch_cfg_v1550->pack(bref)); } } + if (group_flags[12]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(pdsch_cfg_ded_v1610.is_present(), 1)); + HANDLE_CODE(bref.pack(pusch_cfg_ded_v1610.is_present(), 1)); + HANDLE_CODE(bref.pack(ce_csi_rs_feedback_r16_present, 1)); + HANDLE_CODE(bref.pack(res_reserv_cfg_ded_dl_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(res_reserv_cfg_ded_ul_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(srs_ul_cfg_ded_add_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(ul_pwr_ctrl_add_srs_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(srs_virtual_cell_id_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(wideband_prg_r16.is_present(), 1)); + if (pdsch_cfg_ded_v1610.is_present()) { + HANDLE_CODE(pdsch_cfg_ded_v1610->pack(bref)); + } + if (pusch_cfg_ded_v1610.is_present()) { + HANDLE_CODE(pusch_cfg_ded_v1610->pack(bref)); + } + if (res_reserv_cfg_ded_dl_r16.is_present()) { + HANDLE_CODE(res_reserv_cfg_ded_dl_r16->pack(bref)); + } + if (res_reserv_cfg_ded_ul_r16.is_present()) { + HANDLE_CODE(res_reserv_cfg_ded_ul_r16->pack(bref)); + } + if (srs_ul_cfg_ded_add_r16.is_present()) { + HANDLE_CODE(srs_ul_cfg_ded_add_r16->pack(bref)); + } + if (ul_pwr_ctrl_add_srs_r16.is_present()) { + HANDLE_CODE(ul_pwr_ctrl_add_srs_r16->pack(bref)); + } + if (srs_virtual_cell_id_r16.is_present()) { + HANDLE_CODE(srs_virtual_cell_id_r16->pack(bref)); + } + if (wideband_prg_r16.is_present()) { + HANDLE_CODE(wideband_prg_r16->pack(bref)); + } + } + if (group_flags[13]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(pdsch_cfg_ded_v1700.is_present(), 1)); + HANDLE_CODE(bref.pack(ntn_cfg_ded_r17.is_present(), 1)); + if (pdsch_cfg_ded_v1700.is_present()) { + HANDLE_CODE(pdsch_cfg_ded_v1700->pack(bref)); + } + if (ntn_cfg_ded_r17.is_present()) { + HANDLE_CODE(bref.pack(ntn_cfg_ded_r17->pucch_tx_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_cfg_ded_r17->pusch_tx_dur_r17_present, 1)); + if (ntn_cfg_ded_r17->pucch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_ded_r17->pucch_tx_dur_r17.pack(bref)); + } + if (ntn_cfg_ded_r17->pusch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_ded_r17->pusch_tx_dur_r17.pack(bref)); + } + } + } + if (group_flags[14]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ul_segmented_precompensation_gap_r17_present, 1)); + if (ul_segmented_precompensation_gap_r17_present) { + HANDLE_CODE(ul_segmented_precompensation_gap_r17.pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -18871,7 +20374,7 @@ SRSASN_CODE phys_cfg_ded_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(12); + ext_groups_unpacker_guard group_flags(15); group_flags.unpack(bref); if (group_flags[0]) { @@ -19358,6 +20861,90 @@ SRSASN_CODE phys_cfg_ded_s::unpack(cbit_ref& bref) HANDLE_CODE(spucch_cfg_v1550->unpack(bref)); } } + if (group_flags[12]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool pdsch_cfg_ded_v1610_present; + HANDLE_CODE(bref.unpack(pdsch_cfg_ded_v1610_present, 1)); + pdsch_cfg_ded_v1610.set_present(pdsch_cfg_ded_v1610_present); + bool pusch_cfg_ded_v1610_present; + HANDLE_CODE(bref.unpack(pusch_cfg_ded_v1610_present, 1)); + pusch_cfg_ded_v1610.set_present(pusch_cfg_ded_v1610_present); + HANDLE_CODE(bref.unpack(ce_csi_rs_feedback_r16_present, 1)); + bool res_reserv_cfg_ded_dl_r16_present; + HANDLE_CODE(bref.unpack(res_reserv_cfg_ded_dl_r16_present, 1)); + res_reserv_cfg_ded_dl_r16.set_present(res_reserv_cfg_ded_dl_r16_present); + bool res_reserv_cfg_ded_ul_r16_present; + HANDLE_CODE(bref.unpack(res_reserv_cfg_ded_ul_r16_present, 1)); + res_reserv_cfg_ded_ul_r16.set_present(res_reserv_cfg_ded_ul_r16_present); + bool srs_ul_cfg_ded_add_r16_present; + HANDLE_CODE(bref.unpack(srs_ul_cfg_ded_add_r16_present, 1)); + srs_ul_cfg_ded_add_r16.set_present(srs_ul_cfg_ded_add_r16_present); + bool ul_pwr_ctrl_add_srs_r16_present; + HANDLE_CODE(bref.unpack(ul_pwr_ctrl_add_srs_r16_present, 1)); + ul_pwr_ctrl_add_srs_r16.set_present(ul_pwr_ctrl_add_srs_r16_present); + bool srs_virtual_cell_id_r16_present; + HANDLE_CODE(bref.unpack(srs_virtual_cell_id_r16_present, 1)); + srs_virtual_cell_id_r16.set_present(srs_virtual_cell_id_r16_present); + bool wideband_prg_r16_present; + HANDLE_CODE(bref.unpack(wideband_prg_r16_present, 1)); + wideband_prg_r16.set_present(wideband_prg_r16_present); + if (pdsch_cfg_ded_v1610.is_present()) { + HANDLE_CODE(pdsch_cfg_ded_v1610->unpack(bref)); + } + if (pusch_cfg_ded_v1610.is_present()) { + HANDLE_CODE(pusch_cfg_ded_v1610->unpack(bref)); + } + if (res_reserv_cfg_ded_dl_r16.is_present()) { + HANDLE_CODE(res_reserv_cfg_ded_dl_r16->unpack(bref)); + } + if (res_reserv_cfg_ded_ul_r16.is_present()) { + HANDLE_CODE(res_reserv_cfg_ded_ul_r16->unpack(bref)); + } + if (srs_ul_cfg_ded_add_r16.is_present()) { + HANDLE_CODE(srs_ul_cfg_ded_add_r16->unpack(bref)); + } + if (ul_pwr_ctrl_add_srs_r16.is_present()) { + HANDLE_CODE(ul_pwr_ctrl_add_srs_r16->unpack(bref)); + } + if (srs_virtual_cell_id_r16.is_present()) { + HANDLE_CODE(srs_virtual_cell_id_r16->unpack(bref)); + } + if (wideband_prg_r16.is_present()) { + HANDLE_CODE(wideband_prg_r16->unpack(bref)); + } + } + if (group_flags[13]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool pdsch_cfg_ded_v1700_present; + HANDLE_CODE(bref.unpack(pdsch_cfg_ded_v1700_present, 1)); + pdsch_cfg_ded_v1700.set_present(pdsch_cfg_ded_v1700_present); + bool ntn_cfg_ded_r17_present; + HANDLE_CODE(bref.unpack(ntn_cfg_ded_r17_present, 1)); + ntn_cfg_ded_r17.set_present(ntn_cfg_ded_r17_present); + if (pdsch_cfg_ded_v1700.is_present()) { + HANDLE_CODE(pdsch_cfg_ded_v1700->unpack(bref)); + } + if (ntn_cfg_ded_r17.is_present()) { + HANDLE_CODE(bref.unpack(ntn_cfg_ded_r17->pucch_tx_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_cfg_ded_r17->pusch_tx_dur_r17_present, 1)); + if (ntn_cfg_ded_r17->pucch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_ded_r17->pucch_tx_dur_r17.unpack(bref)); + } + if (ntn_cfg_ded_r17->pusch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_ded_r17->pusch_tx_dur_r17.unpack(bref)); + } + } + } + if (group_flags[14]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(ul_segmented_precompensation_gap_r17_present, 1)); + if (ul_segmented_precompensation_gap_r17_present) { + HANDLE_CODE(ul_segmented_precompensation_gap_r17.unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -19728,6 +21315,61 @@ void phys_cfg_ded_s::to_json(json_writer& j) const j.write_fieldname("spucch-Config-v1550"); spucch_cfg_v1550->to_json(j); } + if (pdsch_cfg_ded_v1610.is_present()) { + j.write_fieldname("pdsch-ConfigDedicated-v1610"); + pdsch_cfg_ded_v1610->to_json(j); + } + if (pusch_cfg_ded_v1610.is_present()) { + j.write_fieldname("pusch-ConfigDedicated-v1610"); + pusch_cfg_ded_v1610->to_json(j); + } + if (ce_csi_rs_feedback_r16_present) { + j.write_str("ce-CSI-RS-Feedback-r16", "enabled"); + } + if (res_reserv_cfg_ded_dl_r16.is_present()) { + j.write_fieldname("resourceReservationConfigDedicatedDL-r16"); + res_reserv_cfg_ded_dl_r16->to_json(j); + } + if (res_reserv_cfg_ded_ul_r16.is_present()) { + j.write_fieldname("resourceReservationConfigDedicatedUL-r16"); + res_reserv_cfg_ded_ul_r16->to_json(j); + } + if (srs_ul_cfg_ded_add_r16.is_present()) { + j.write_fieldname("soundingRS-UL-ConfigDedicatedAdd-r16"); + srs_ul_cfg_ded_add_r16->to_json(j); + } + if (ul_pwr_ctrl_add_srs_r16.is_present()) { + j.write_fieldname("uplinkPowerControlAddSRS-r16"); + ul_pwr_ctrl_add_srs_r16->to_json(j); + } + if (srs_virtual_cell_id_r16.is_present()) { + j.write_fieldname("soundingRS-VirtualCellID-r16"); + srs_virtual_cell_id_r16->to_json(j); + } + if (wideband_prg_r16.is_present()) { + j.write_fieldname("widebandPRG-r16"); + wideband_prg_r16->to_json(j); + } + if (pdsch_cfg_ded_v1700.is_present()) { + j.write_fieldname("pdsch-ConfigDedicated-v1700"); + pdsch_cfg_ded_v1700->to_json(j); + } + if (ntn_cfg_ded_r17.is_present()) { + j.write_fieldname("ntn-ConfigDedicated-r17"); + j.start_obj(); + if (ntn_cfg_ded_r17->pucch_tx_dur_r17_present) { + j.write_fieldname("pucch-TxDuration-r17"); + ntn_cfg_ded_r17->pucch_tx_dur_r17.to_json(j); + } + if (ntn_cfg_ded_r17->pusch_tx_dur_r17_present) { + j.write_fieldname("pusch-TxDuration-r17"); + ntn_cfg_ded_r17->pusch_tx_dur_r17.to_json(j); + } + j.end_obj(); + } + if (ul_segmented_precompensation_gap_r17_present) { + j.write_str("uplinkSegmentedPrecompensationGap-r17", ul_segmented_precompensation_gap_r17.to_string()); + } } j.end_obj(); } @@ -20602,3 +22244,9 @@ phys_cfg_ded_s::blind_pdsch_repeat_cfg_r15_c_::setup_s_::mcs_restrict_slot_subsl value, "phys_cfg_ded_s::blind_pdsch_repeat_cfg_r15_c_::setup_s_::mcs_restrict_slot_subslot_pdsch_repeats_r15_e_"); } + +const char* phys_cfg_ded_s::ul_segmented_precompensation_gap_r17_opts::to_string() const +{ + static const char* options[] = {"sym1", "sl1", "sf1"}; + return convert_enum_idx(options, 3, value, "phys_cfg_ded_s::ul_segmented_precompensation_gap_r17_e_"); +} diff --git a/lib/src/asn1/rrc/rr_common.cc b/lib/src/asn1/rrc/rr_common.cc index f6a43cf554..c05a88228d 100644 --- a/lib/src/asn1/rrc/rr_common.cc +++ b/lib/src/asn1/rrc/rr_common.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -527,6 +527,30 @@ uint8_t tdd_cfg_v1130_s::special_sf_patterns_v1130_opts::to_number() const return map_enum_number(options, 2, value, "tdd_cfg_v1130_s::special_sf_patterns_v1130_e_"); } +// GWUS-NumGroups-r16 ::= ENUMERATED +const char* gwus_num_groups_r16_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n4", "n8"}; + return convert_enum_idx(options, 4, value, "gwus_num_groups_r16_e"); +} +uint8_t gwus_num_groups_r16_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 4, 8}; + return map_enum_number(options, 4, value, "gwus_num_groups_r16_e"); +} + +// GWUS-PagingProbThresh-r16 ::= ENUMERATED +const char* gwus_paging_prob_thresh_r16_opts::to_string() const +{ + static const char* options[] = {"p20", "p30", "p40", "p50", "p60", "p70", "p80", "p90"}; + return convert_enum_idx(options, 8, value, "gwus_paging_prob_thresh_r16_e"); +} +uint8_t gwus_paging_prob_thresh_r16_opts::to_number() const +{ + static const uint8_t options[] = {20, 30, 40, 50, 60, 70, 80, 90}; + return map_enum_number(options, 8, value, "gwus_paging_prob_thresh_r16_e"); +} + // PRACH-ParametersCE-r13 ::= SEQUENCE SRSASN_CODE prach_params_ce_r13_s::pack(bit_ref& bref) const { @@ -1289,6 +1313,347 @@ uint16_t edt_prach_params_ce_r15_s::edt_prach_params_ce_r15_s_::prach_start_sf_r options, 8, value, "edt_prach_params_ce_r15_s::edt_prach_params_ce_r15_s_::prach_start_sf_r15_e_"); } +// GWUS-ResourceConfig-r16 ::= SEQUENCE +SRSASN_CODE gwus_res_cfg_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(num_groups_list_r16_present, 1)); + HANDLE_CODE(bref.pack(groups_for_service_list_r16_present, 1)); + + HANDLE_CODE(res_map_pattern_r16.pack(bref)); + if (num_groups_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, num_groups_list_r16, 1, 4)); + } + if (groups_for_service_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, groups_for_service_list_r16, 1, 3, integer_packer(1, 31))); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE gwus_res_cfg_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(num_groups_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(groups_for_service_list_r16_present, 1)); + + HANDLE_CODE(res_map_pattern_r16.unpack(bref)); + if (num_groups_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(num_groups_list_r16, bref, 1, 4)); + } + if (groups_for_service_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(groups_for_service_list_r16, bref, 1, 3, integer_packer(1, 31))); + } + + return SRSASN_SUCCESS; +} +void gwus_res_cfg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("resourceMappingPattern-r16"); + res_map_pattern_r16.to_json(j); + if (num_groups_list_r16_present) { + j.start_array("numGroupsList-r16"); + for (const auto& e1 : num_groups_list_r16) { + j.write_str(e1.to_string()); + } + j.end_array(); + } + if (groups_for_service_list_r16_present) { + j.start_array("groupsForServiceList-r16"); + for (const auto& e1 : groups_for_service_list_r16) { + j.write_int(e1); + } + j.end_array(); + } + j.end_obj(); +} + +void gwus_res_cfg_r16_s::res_map_pattern_r16_c_::destroy_() {} +void gwus_res_cfg_r16_s::res_map_pattern_r16_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +gwus_res_cfg_r16_s::res_map_pattern_r16_c_::res_map_pattern_r16_c_( + const gwus_res_cfg_r16_s::res_map_pattern_r16_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::res_location_with_wus: + c.init(other.c.get()); + break; + case types::res_location_without_wus: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "gwus_res_cfg_r16_s::res_map_pattern_r16_c_"); + } +} +gwus_res_cfg_r16_s::res_map_pattern_r16_c_& +gwus_res_cfg_r16_s::res_map_pattern_r16_c_::operator=(const gwus_res_cfg_r16_s::res_map_pattern_r16_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::res_location_with_wus: + c.set(other.c.get()); + break; + case types::res_location_without_wus: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "gwus_res_cfg_r16_s::res_map_pattern_r16_c_"); + } + + return *this; +} +gwus_res_cfg_r16_s::res_map_pattern_r16_c_::res_location_with_wus_e_& +gwus_res_cfg_r16_s::res_map_pattern_r16_c_::set_res_location_with_wus() +{ + set(types::res_location_with_wus); + return c.get(); +} +gwus_res_cfg_r16_s::res_map_pattern_r16_c_::res_location_without_wus_e_& +gwus_res_cfg_r16_s::res_map_pattern_r16_c_::set_res_location_without_wus() +{ + set(types::res_location_without_wus); + return c.get(); +} +void gwus_res_cfg_r16_s::res_map_pattern_r16_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::res_location_with_wus: + j.write_str("resourceLocationWithWUS", c.get().to_string()); + break; + case types::res_location_without_wus: + j.write_str("resourceLocationWithoutWUS", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "gwus_res_cfg_r16_s::res_map_pattern_r16_c_"); + } + j.end_obj(); +} +SRSASN_CODE gwus_res_cfg_r16_s::res_map_pattern_r16_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::res_location_with_wus: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::res_location_without_wus: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "gwus_res_cfg_r16_s::res_map_pattern_r16_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE gwus_res_cfg_r16_s::res_map_pattern_r16_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::res_location_with_wus: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::res_location_without_wus: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "gwus_res_cfg_r16_s::res_map_pattern_r16_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* gwus_res_cfg_r16_s::res_map_pattern_r16_c_::res_location_with_wus_opts::to_string() const +{ + static const char* options[] = {"primary", "secondary", "primary3FDM"}; + return convert_enum_idx(options, 3, value, "gwus_res_cfg_r16_s::res_map_pattern_r16_c_::res_location_with_wus_e_"); +} +uint8_t gwus_res_cfg_r16_s::res_map_pattern_r16_c_::res_location_with_wus_opts::to_number() const +{ + if (value == primary3_fdm) { + return 3; + } + invalid_enum_number(value, "gwus_res_cfg_r16_s::res_map_pattern_r16_c_::res_location_with_wus_e_"); + return 0; +} + +const char* gwus_res_cfg_r16_s::res_map_pattern_r16_c_::res_location_without_wus_opts::to_string() const +{ + static const char* options[] = {"n0", "n2"}; + return convert_enum_idx(options, 2, value, "gwus_res_cfg_r16_s::res_map_pattern_r16_c_::res_location_without_wus_e_"); +} +uint8_t gwus_res_cfg_r16_s::res_map_pattern_r16_c_::res_location_without_wus_opts::to_number() const +{ + static const uint8_t options[] = {0, 2}; + return map_enum_number(options, 2, value, "gwus_res_cfg_r16_s::res_map_pattern_r16_c_::res_location_without_wus_e_"); +} + +// GWUS-TimeParameters-r16 ::= SEQUENCE +SRSASN_CODE gwus_time_params_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(num_pos_r16_present, 1)); + HANDLE_CODE(bref.pack(time_offset_e_drx_long_r16_present, 1)); + HANDLE_CODE(bref.pack(num_drx_cycles_relaxed_r16_present, 1)); + HANDLE_CODE(bref.pack(pwr_boost_r16_present, 1)); + + HANDLE_CODE(max_dur_factor_r16.pack(bref)); + if (num_pos_r16_present) { + HANDLE_CODE(num_pos_r16.pack(bref)); + } + HANDLE_CODE(time_offset_drx_r16.pack(bref)); + HANDLE_CODE(time_offset_e_drx_short_r16.pack(bref)); + if (time_offset_e_drx_long_r16_present) { + HANDLE_CODE(time_offset_e_drx_long_r16.pack(bref)); + } + if (num_drx_cycles_relaxed_r16_present) { + HANDLE_CODE(num_drx_cycles_relaxed_r16.pack(bref)); + } + if (pwr_boost_r16_present) { + HANDLE_CODE(pwr_boost_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE gwus_time_params_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(num_pos_r16_present, 1)); + HANDLE_CODE(bref.unpack(time_offset_e_drx_long_r16_present, 1)); + HANDLE_CODE(bref.unpack(num_drx_cycles_relaxed_r16_present, 1)); + HANDLE_CODE(bref.unpack(pwr_boost_r16_present, 1)); + + HANDLE_CODE(max_dur_factor_r16.unpack(bref)); + if (num_pos_r16_present) { + HANDLE_CODE(num_pos_r16.unpack(bref)); + } + HANDLE_CODE(time_offset_drx_r16.unpack(bref)); + HANDLE_CODE(time_offset_e_drx_short_r16.unpack(bref)); + if (time_offset_e_drx_long_r16_present) { + HANDLE_CODE(time_offset_e_drx_long_r16.unpack(bref)); + } + if (num_drx_cycles_relaxed_r16_present) { + HANDLE_CODE(num_drx_cycles_relaxed_r16.unpack(bref)); + } + if (pwr_boost_r16_present) { + HANDLE_CODE(pwr_boost_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void gwus_time_params_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("maxDurationFactor-r16", max_dur_factor_r16.to_string()); + if (num_pos_r16_present) { + j.write_str("numPOs-r16", num_pos_r16.to_string()); + } + j.write_str("timeOffsetDRX-r16", time_offset_drx_r16.to_string()); + j.write_str("timeOffset-eDRX-Short-r16", time_offset_e_drx_short_r16.to_string()); + if (time_offset_e_drx_long_r16_present) { + j.write_str("timeOffset-eDRX-Long-r16", time_offset_e_drx_long_r16.to_string()); + } + if (num_drx_cycles_relaxed_r16_present) { + j.write_str("numDRX-CyclesRelaxed-r16", num_drx_cycles_relaxed_r16.to_string()); + } + if (pwr_boost_r16_present) { + j.write_str("powerBoost-r16", pwr_boost_r16.to_string()); + } + j.end_obj(); +} + +const char* gwus_time_params_r16_s::max_dur_factor_r16_opts::to_string() const +{ + static const char* options[] = {"one32th", "one16th", "one8th", "one4th"}; + return convert_enum_idx(options, 4, value, "gwus_time_params_r16_s::max_dur_factor_r16_e_"); +} +uint8_t gwus_time_params_r16_s::max_dur_factor_r16_opts::to_number() const +{ + static const uint8_t options[] = {32, 16, 8, 4}; + return map_enum_number(options, 4, value, "gwus_time_params_r16_s::max_dur_factor_r16_e_"); +} + +const char* gwus_time_params_r16_s::num_pos_r16_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n4", "spare1"}; + return convert_enum_idx(options, 4, value, "gwus_time_params_r16_s::num_pos_r16_e_"); +} +uint8_t gwus_time_params_r16_s::num_pos_r16_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 4}; + return map_enum_number(options, 3, value, "gwus_time_params_r16_s::num_pos_r16_e_"); +} + +const char* gwus_time_params_r16_s::time_offset_drx_r16_opts::to_string() const +{ + static const char* options[] = {"ms40", "ms80", "ms160", "ms240"}; + return convert_enum_idx(options, 4, value, "gwus_time_params_r16_s::time_offset_drx_r16_e_"); +} +uint8_t gwus_time_params_r16_s::time_offset_drx_r16_opts::to_number() const +{ + static const uint8_t options[] = {40, 80, 160, 240}; + return map_enum_number(options, 4, value, "gwus_time_params_r16_s::time_offset_drx_r16_e_"); +} + +const char* gwus_time_params_r16_s::time_offset_e_drx_short_r16_opts::to_string() const +{ + static const char* options[] = {"ms40", "ms80", "ms160", "ms240"}; + return convert_enum_idx(options, 4, value, "gwus_time_params_r16_s::time_offset_e_drx_short_r16_e_"); +} +uint8_t gwus_time_params_r16_s::time_offset_e_drx_short_r16_opts::to_number() const +{ + static const uint8_t options[] = {40, 80, 160, 240}; + return map_enum_number(options, 4, value, "gwus_time_params_r16_s::time_offset_e_drx_short_r16_e_"); +} + +const char* gwus_time_params_r16_s::time_offset_e_drx_long_r16_opts::to_string() const +{ + static const char* options[] = {"ms1000", "ms2000"}; + return convert_enum_idx(options, 2, value, "gwus_time_params_r16_s::time_offset_e_drx_long_r16_e_"); +} +uint16_t gwus_time_params_r16_s::time_offset_e_drx_long_r16_opts::to_number() const +{ + static const uint16_t options[] = {1000, 2000}; + return map_enum_number(options, 2, value, "gwus_time_params_r16_s::time_offset_e_drx_long_r16_e_"); +} + +const char* gwus_time_params_r16_s::num_drx_cycles_relaxed_r16_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n4", "n8"}; + return convert_enum_idx(options, 4, value, "gwus_time_params_r16_s::num_drx_cycles_relaxed_r16_e_"); +} +uint8_t gwus_time_params_r16_s::num_drx_cycles_relaxed_r16_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 4, 8}; + return map_enum_number(options, 4, value, "gwus_time_params_r16_s::num_drx_cycles_relaxed_r16_e_"); +} + +const char* gwus_time_params_r16_s::pwr_boost_r16_opts::to_string() const +{ + static const char* options[] = {"dB0", "dB1dot8", "dB3", "dB4dot8"}; + return convert_enum_idx(options, 4, value, "gwus_time_params_r16_s::pwr_boost_r16_e_"); +} +float gwus_time_params_r16_s::pwr_boost_r16_opts::to_number() const +{ + static const float options[] = {0.0, 1.8, 3.0, 4.8}; + return map_enum_number(options, 4, value, "gwus_time_params_r16_s::pwr_boost_r16_e_"); +} +const char* gwus_time_params_r16_s::pwr_boost_r16_opts::to_number_string() const +{ + static const char* options[] = {"0", "1.8", "3", "4.8"}; + return convert_enum_idx(options, 4, value, "gwus_time_params_r16_s::pwr_boost_r16_e_"); +} + // PRACH-ConfigInfo ::= SEQUENCE SRSASN_CODE prach_cfg_info_s::pack(bit_ref& bref) const { @@ -1481,6 +1846,42 @@ void bcch_cfg_v1310_s::to_json(json_writer& j) const j.end_obj(); } +// CRS-ChEstMPDCCH-ConfigCommon-r16 ::= SEQUENCE +SRSASN_CODE crs_ch_est_mpdcch_cfg_common_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pwr_ratio_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE crs_ch_est_mpdcch_cfg_common_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(pwr_ratio_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void crs_ch_est_mpdcch_cfg_common_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("powerRatio-r16", pwr_ratio_r16.to_string()); + j.end_obj(); +} + +const char* crs_ch_est_mpdcch_cfg_common_r16_s::pwr_ratio_r16_opts::to_string() const +{ + static const char* options[] = {"dB-4dot77", "dB-3", "dB-1dot77", "dB0", "dB1", "dB2", "dB3", "dB4dot77"}; + return convert_enum_idx(options, 8, value, "crs_ch_est_mpdcch_cfg_common_r16_s::pwr_ratio_r16_e_"); +} +float crs_ch_est_mpdcch_cfg_common_r16_s::pwr_ratio_r16_opts::to_number() const +{ + static const float options[] = {-4.77, -3.0, -1.77, 0.0, 1.0, 2.0, 3.0, 4.77}; + return map_enum_number(options, 8, value, "crs_ch_est_mpdcch_cfg_common_r16_s::pwr_ratio_r16_e_"); +} +const char* crs_ch_est_mpdcch_cfg_common_r16_s::pwr_ratio_r16_opts::to_number_string() const +{ + static const char* options[] = {"-4.77", "-3", "-1.77", "0", "1", "2", "3", "4.77"}; + return convert_enum_idx(options, 8, value, "crs_ch_est_mpdcch_cfg_common_r16_s::pwr_ratio_r16_e_"); +} + // FreqHoppingParameters-r13 ::= SEQUENCE SRSASN_CODE freq_hop_params_r13_s::pack(bit_ref& bref) const { @@ -2101,6 +2502,122 @@ uint8_t freq_hop_params_r13_s::interv_ul_hop_cfg_common_mode_b_r13_c_::interv_td options, 4, value, "freq_hop_params_r13_s::interv_ul_hop_cfg_common_mode_b_r13_c_::interv_tdd_r13_e_"); } +// GWUS-Config-r16 ::= SEQUENCE +SRSASN_CODE gwus_cfg_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(group_alternation_r16_present, 1)); + HANDLE_CODE(bref.pack(common_seq_r16_present, 1)); + HANDLE_CODE(bref.pack(time_params_r16_present, 1)); + HANDLE_CODE(bref.pack(res_cfg_e_drx_short_r16_present, 1)); + HANDLE_CODE(bref.pack(res_cfg_e_drx_long_r16_present, 1)); + HANDLE_CODE(bref.pack(prob_thresh_list_r16_present, 1)); + HANDLE_CODE(bref.pack(group_narrow_band_list_r16_present, 1)); + + if (common_seq_r16_present) { + HANDLE_CODE(common_seq_r16.pack(bref)); + } + if (time_params_r16_present) { + HANDLE_CODE(time_params_r16.pack(bref)); + } + HANDLE_CODE(res_cfg_drx_r16.pack(bref)); + if (res_cfg_e_drx_short_r16_present) { + HANDLE_CODE(res_cfg_e_drx_short_r16.pack(bref)); + } + if (res_cfg_e_drx_long_r16_present) { + HANDLE_CODE(res_cfg_e_drx_long_r16.pack(bref)); + } + if (prob_thresh_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, prob_thresh_list_r16, 1, 3)); + } + if (group_narrow_band_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, group_narrow_band_list_r16, 1, 16, BitPacker(1))); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE gwus_cfg_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(group_alternation_r16_present, 1)); + HANDLE_CODE(bref.unpack(common_seq_r16_present, 1)); + HANDLE_CODE(bref.unpack(time_params_r16_present, 1)); + HANDLE_CODE(bref.unpack(res_cfg_e_drx_short_r16_present, 1)); + HANDLE_CODE(bref.unpack(res_cfg_e_drx_long_r16_present, 1)); + HANDLE_CODE(bref.unpack(prob_thresh_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(group_narrow_band_list_r16_present, 1)); + + if (common_seq_r16_present) { + HANDLE_CODE(common_seq_r16.unpack(bref)); + } + if (time_params_r16_present) { + HANDLE_CODE(time_params_r16.unpack(bref)); + } + HANDLE_CODE(res_cfg_drx_r16.unpack(bref)); + if (res_cfg_e_drx_short_r16_present) { + HANDLE_CODE(res_cfg_e_drx_short_r16.unpack(bref)); + } + if (res_cfg_e_drx_long_r16_present) { + HANDLE_CODE(res_cfg_e_drx_long_r16.unpack(bref)); + } + if (prob_thresh_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(prob_thresh_list_r16, bref, 1, 3)); + } + if (group_narrow_band_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(group_narrow_band_list_r16, bref, 1, 16, BitPacker(1))); + } + + return SRSASN_SUCCESS; +} +void gwus_cfg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (group_alternation_r16_present) { + j.write_str("groupAlternation-r16", "true"); + } + if (common_seq_r16_present) { + j.write_str("commonSequence-r16", common_seq_r16.to_string()); + } + if (time_params_r16_present) { + j.write_fieldname("timeParameters-r16"); + time_params_r16.to_json(j); + } + j.write_fieldname("resourceConfigDRX-r16"); + res_cfg_drx_r16.to_json(j); + if (res_cfg_e_drx_short_r16_present) { + j.write_fieldname("resourceConfig-eDRX-Short-r16"); + res_cfg_e_drx_short_r16.to_json(j); + } + if (res_cfg_e_drx_long_r16_present) { + j.write_fieldname("resourceConfig-eDRX-Long-r16"); + res_cfg_e_drx_long_r16.to_json(j); + } + if (prob_thresh_list_r16_present) { + j.start_array("probThreshList-r16"); + for (const auto& e1 : prob_thresh_list_r16) { + j.write_str(e1.to_string()); + } + j.end_array(); + } + if (group_narrow_band_list_r16_present) { + j.start_array("groupNarrowBandList-r16"); + for (const auto& e1 : group_narrow_band_list_r16) { + j.write_bool(e1); + } + j.end_array(); + } + j.end_obj(); +} + +const char* gwus_cfg_r16_s::common_seq_r16_opts::to_string() const +{ + static const char* options[] = {"g0", "g126"}; + return convert_enum_idx(options, 2, value, "gwus_cfg_r16_s::common_seq_r16_e_"); +} +uint8_t gwus_cfg_r16_s::common_seq_r16_opts::to_number() const +{ + static const uint8_t options[] = {0, 126}; + return map_enum_number(options, 2, value, "gwus_cfg_r16_s::common_seq_r16_e_"); +} + // HighSpeedConfig-r14 ::= SEQUENCE SRSASN_CODE high_speed_cfg_r14_s::pack(bit_ref& bref) const { @@ -2144,6 +2661,33 @@ void high_speed_cfg_v1530_s::to_json(json_writer& j) const j.end_obj(); } +// HighSpeedConfig-v1610 ::= SEQUENCE +SRSASN_CODE high_speed_cfg_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(high_speed_enh_meas_flag2_r16_present, 1)); + HANDLE_CODE(bref.pack(high_speed_enh_demod_flag2_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE high_speed_cfg_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(high_speed_enh_meas_flag2_r16_present, 1)); + HANDLE_CODE(bref.unpack(high_speed_enh_demod_flag2_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void high_speed_cfg_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (high_speed_enh_meas_flag2_r16_present) { + j.write_str("highSpeedEnhMeasFlag2-r16", "true"); + } + if (high_speed_enh_demod_flag2_r16_present) { + j.write_str("highSpeedEnhDemodFlag2-r16", "true"); + } + j.end_obj(); +} + // PCCH-Config ::= SEQUENCE SRSASN_CODE pcch_cfg_s::pack(bit_ref& bref) const { @@ -2253,6 +2797,22 @@ uint16_t pcch_cfg_v1310_s::nb_v1310_opts::to_number() const return map_enum_number(options, 3, value, "pcch_cfg_v1310_s::nb_v1310_e_"); } +// PCCH-Config-v1700 ::= SEQUENCE +SRSASN_CODE pcch_cfg_v1700_s::pack(bit_ref& bref) const +{ + return SRSASN_SUCCESS; +} +SRSASN_CODE pcch_cfg_v1700_s::unpack(cbit_ref& bref) +{ + return SRSASN_SUCCESS; +} +void pcch_cfg_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ranPagingInIdlePO-r17", "true"); + j.end_obj(); +} + // PDSCH-ConfigCommon ::= SEQUENCE SRSASN_CODE pdsch_cfg_common_s::pack(bit_ref& bref) const { @@ -2617,6 +3177,37 @@ void prach_cfg_sib_v1530_s::to_json(json_writer& j) const j.end_obj(); } +// PRACH-TxDuration-r17 ::= SEQUENCE +SRSASN_CODE prach_tx_dur_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(prach_tx_dur_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE prach_tx_dur_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(prach_tx_dur_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void prach_tx_dur_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("prach-TxDuration-r17", prach_tx_dur_r17.to_string()); + j.end_obj(); +} + +const char* prach_tx_dur_r17_s::prach_tx_dur_r17_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n4", "n8", "n16", "n32", "n64", "n128"}; + return convert_enum_idx(options, 8, value, "prach_tx_dur_r17_s::prach_tx_dur_r17_e_"); +} +uint8_t prach_tx_dur_r17_s::prach_tx_dur_r17_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 4, 8, 16, 32, 64, 128}; + return map_enum_number(options, 8, value, "prach_tx_dur_r17_s::prach_tx_dur_r17_e_"); +} + // PUCCH-ConfigCommon ::= SEQUENCE SRSASN_CODE pucch_cfg_common_s::pack(bit_ref& bref) const { @@ -2825,6 +3416,37 @@ uint8_t pucch_cfg_common_v1430_s::pucch_num_repeat_ce_msg4_level3_r14_opts::to_n return map_enum_number(options, 2, value, "pucch_cfg_common_v1430_s::pucch_num_repeat_ce_msg4_level3_r14_e_"); } +// PUCCH-TxDuration-r17 ::= SEQUENCE +SRSASN_CODE pucch_tx_dur_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pucch_tx_dur_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE pucch_tx_dur_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(pucch_tx_dur_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void pucch_tx_dur_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pucch-TxDuration-r17", pucch_tx_dur_r17.to_string()); + j.end_obj(); +} + +const char* pucch_tx_dur_r17_s::pucch_tx_dur_r17_opts::to_string() const +{ + static const char* options[] = {"sf2", "sf4", "sf8", "sf16", "sf32", "sf64", "sf128"}; + return convert_enum_idx(options, 7, value, "pucch_tx_dur_r17_s::pucch_tx_dur_r17_e_"); +} +uint8_t pucch_tx_dur_r17_s::pucch_tx_dur_r17_opts::to_number() const +{ + static const uint8_t options[] = {2, 4, 8, 16, 32, 64, 128}; + return map_enum_number(options, 7, value, "pucch_tx_dur_r17_s::pucch_tx_dur_r17_e_"); +} + // PUSCH-ConfigCommon ::= SEQUENCE SRSASN_CODE pusch_cfg_common_s::pack(bit_ref& bref) const { @@ -2969,6 +3591,37 @@ uint16_t pusch_cfg_common_v1310_s::pusch_max_num_repeat_cemode_b_r13_opts::to_nu return map_enum_number(options, 8, value, "pusch_cfg_common_v1310_s::pusch_max_num_repeat_cemode_b_r13_e_"); } +// PUSCH-TxDuration-r17 ::= SEQUENCE +SRSASN_CODE pusch_tx_dur_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pusch_tx_dur_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE pusch_tx_dur_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(pusch_tx_dur_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void pusch_tx_dur_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("pusch-TxDuration-r17", pusch_tx_dur_r17.to_string()); + j.end_obj(); +} + +const char* pusch_tx_dur_r17_s::pusch_tx_dur_r17_opts::to_string() const +{ + static const char* options[] = {"n2", "n4", "n8", "n16", "n32", "n64", "n128", "n256"}; + return convert_enum_idx(options, 8, value, "pusch_tx_dur_r17_s::pusch_tx_dur_r17_e_"); +} +uint16_t pusch_tx_dur_r17_s::pusch_tx_dur_r17_opts::to_number() const +{ + static const uint16_t options[] = {2, 4, 8, 16, 32, 64, 128, 256}; + return map_enum_number(options, 8, value, "pusch_tx_dur_r17_s::pusch_tx_dur_r17_e_"); +} + // RACH-ConfigCommon ::= SEQUENCE SRSASN_CODE rach_cfg_common_s::pack(bit_ref& bref) const { @@ -3543,6 +4196,29 @@ bool ul_pwr_ctrl_common_v1530_s::operator==(const ul_pwr_ctrl_common_v1530_s& ot return delta_flist_spucch_r15 == other.delta_flist_spucch_r15; } +// UplinkPowerControlCommon-v1610 ::= SEQUENCE +SRSASN_CODE ul_pwr_ctrl_common_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(alpha_srs_add_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, p0_nominal_srs_add_r16, (int8_t)-126, (int8_t)24)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ul_pwr_ctrl_common_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(alpha_srs_add_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(p0_nominal_srs_add_r16, bref, (int8_t)-126, (int8_t)24)); + + return SRSASN_SUCCESS; +} +void ul_pwr_ctrl_common_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("alphaSRS-Add-r16", alpha_srs_add_r16.to_string()); + j.write_int("p0-NominalSRS-Add-r16", p0_nominal_srs_add_r16); + j.end_obj(); +} + // WUS-Config-r15 ::= SEQUENCE SRSASN_CODE wus_cfg_r15_s::pack(bit_ref& bref) const { @@ -3698,6 +4374,37 @@ const char* wus_cfg_v1560_s::pwr_boost_r15_opts::to_number_string() const return convert_enum_idx(options, 4, value, "wus_cfg_v1560_s::pwr_boost_r15_e_"); } +// WUS-Config-v1610 ::= SEQUENCE +SRSASN_CODE wus_cfg_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(num_drx_cycles_relaxed_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE wus_cfg_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(num_drx_cycles_relaxed_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void wus_cfg_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("numDRX-CyclesRelaxed-r16", num_drx_cycles_relaxed_r16.to_string()); + j.end_obj(); +} + +const char* wus_cfg_v1610_s::num_drx_cycles_relaxed_r16_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n4", "n8"}; + return convert_enum_idx(options, 4, value, "wus_cfg_v1610_s::num_drx_cycles_relaxed_r16_e_"); +} +uint8_t wus_cfg_v1610_s::num_drx_cycles_relaxed_r16_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 4, 8}; + return map_enum_number(options, 4, value, "wus_cfg_v1610_s::num_drx_cycles_relaxed_r16_e_"); +} + // RadioResourceConfigCommonSIB ::= SEQUENCE SRSASN_CODE rr_cfg_common_sib_s::pack(bit_ref& bref) const { @@ -3734,6 +4441,17 @@ SRSASN_CODE rr_cfg_common_sib_s::pack(bit_ref& bref) const group_flags[5] |= high_speed_cfg_v1530.is_present(); group_flags[6] |= ul_pwr_ctrl_common_v1540.is_present(); group_flags[7] |= wus_cfg_v1560.is_present(); + group_flags[8] |= wus_cfg_v1610.is_present(); + group_flags[8] |= high_speed_cfg_v1610.is_present(); + group_flags[8] |= crs_ch_est_mpdcch_cfg_common_r16.is_present(); + group_flags[8] |= gwus_cfg_r16.is_present(); + group_flags[8] |= ul_pwr_ctrl_common_v1610.is_present(); + group_flags[8] |= rss_meas_cfg_r16_present; + group_flags[8] |= rss_meas_non_ncl_r16_present; + group_flags[8] |= punctured_subcarriers_dl_r16_present; + group_flags[8] |= high_speed_inter_rat_nr_r16_present; + group_flags[9] |= pcch_cfg_v1700.is_present(); + group_flags[9] |= ntn_cfg_common_r17.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -3844,6 +4562,65 @@ SRSASN_CODE rr_cfg_common_sib_s::pack(bit_ref& bref) const HANDLE_CODE(wus_cfg_v1560->pack(bref)); } } + if (group_flags[8]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(wus_cfg_v1610.is_present(), 1)); + HANDLE_CODE(bref.pack(high_speed_cfg_v1610.is_present(), 1)); + HANDLE_CODE(bref.pack(crs_ch_est_mpdcch_cfg_common_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(gwus_cfg_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(ul_pwr_ctrl_common_v1610.is_present(), 1)); + HANDLE_CODE(bref.pack(rss_meas_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(rss_meas_non_ncl_r16_present, 1)); + HANDLE_CODE(bref.pack(punctured_subcarriers_dl_r16_present, 1)); + HANDLE_CODE(bref.pack(high_speed_inter_rat_nr_r16_present, 1)); + if (wus_cfg_v1610.is_present()) { + HANDLE_CODE(wus_cfg_v1610->pack(bref)); + } + if (high_speed_cfg_v1610.is_present()) { + HANDLE_CODE(high_speed_cfg_v1610->pack(bref)); + } + if (crs_ch_est_mpdcch_cfg_common_r16.is_present()) { + HANDLE_CODE(crs_ch_est_mpdcch_cfg_common_r16->pack(bref)); + } + if (gwus_cfg_r16.is_present()) { + HANDLE_CODE(gwus_cfg_r16->pack(bref)); + } + if (ul_pwr_ctrl_common_v1610.is_present()) { + HANDLE_CODE(ul_pwr_ctrl_common_v1610->pack(bref)); + } + if (punctured_subcarriers_dl_r16_present) { + HANDLE_CODE(punctured_subcarriers_dl_r16.pack(bref)); + } + if (high_speed_inter_rat_nr_r16_present) { + HANDLE_CODE(bref.pack(high_speed_inter_rat_nr_r16, 1)); + } + } + if (group_flags[9]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(pcch_cfg_v1700.is_present(), 1)); + HANDLE_CODE(bref.pack(ntn_cfg_common_r17.is_present(), 1)); + if (pcch_cfg_v1700.is_present()) { + HANDLE_CODE(pcch_cfg_v1700->pack(bref)); + } + if (ntn_cfg_common_r17.is_present()) { + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->ta_report_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->prach_tx_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->pucch_tx_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->pusch_tx_dur_r17_present, 1)); + HANDLE_CODE(ntn_cfg_common_r17->t318_r17.pack(bref)); + if (ntn_cfg_common_r17->prach_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->prach_tx_dur_r17.pack(bref)); + } + if (ntn_cfg_common_r17->pucch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->pucch_tx_dur_r17.pack(bref)); + } + if (ntn_cfg_common_r17->pusch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->pusch_tx_dur_r17.pack(bref)); + } + } + } } return SRSASN_SUCCESS; } @@ -3862,7 +4639,7 @@ SRSASN_CODE rr_cfg_common_sib_s::unpack(cbit_ref& bref) HANDLE_CODE(ul_cp_len.unpack(bref)); if (ext) { - ext_groups_unpacker_guard group_flags(8); + ext_groups_unpacker_guard group_flags(10); group_flags.unpack(bref); if (group_flags[0]) { @@ -4011,6 +4788,79 @@ SRSASN_CODE rr_cfg_common_sib_s::unpack(cbit_ref& bref) HANDLE_CODE(wus_cfg_v1560->unpack(bref)); } } + if (group_flags[8]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool wus_cfg_v1610_present; + HANDLE_CODE(bref.unpack(wus_cfg_v1610_present, 1)); + wus_cfg_v1610.set_present(wus_cfg_v1610_present); + bool high_speed_cfg_v1610_present; + HANDLE_CODE(bref.unpack(high_speed_cfg_v1610_present, 1)); + high_speed_cfg_v1610.set_present(high_speed_cfg_v1610_present); + bool crs_ch_est_mpdcch_cfg_common_r16_present; + HANDLE_CODE(bref.unpack(crs_ch_est_mpdcch_cfg_common_r16_present, 1)); + crs_ch_est_mpdcch_cfg_common_r16.set_present(crs_ch_est_mpdcch_cfg_common_r16_present); + bool gwus_cfg_r16_present; + HANDLE_CODE(bref.unpack(gwus_cfg_r16_present, 1)); + gwus_cfg_r16.set_present(gwus_cfg_r16_present); + bool ul_pwr_ctrl_common_v1610_present; + HANDLE_CODE(bref.unpack(ul_pwr_ctrl_common_v1610_present, 1)); + ul_pwr_ctrl_common_v1610.set_present(ul_pwr_ctrl_common_v1610_present); + HANDLE_CODE(bref.unpack(rss_meas_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(rss_meas_non_ncl_r16_present, 1)); + HANDLE_CODE(bref.unpack(punctured_subcarriers_dl_r16_present, 1)); + HANDLE_CODE(bref.unpack(high_speed_inter_rat_nr_r16_present, 1)); + if (wus_cfg_v1610.is_present()) { + HANDLE_CODE(wus_cfg_v1610->unpack(bref)); + } + if (high_speed_cfg_v1610.is_present()) { + HANDLE_CODE(high_speed_cfg_v1610->unpack(bref)); + } + if (crs_ch_est_mpdcch_cfg_common_r16.is_present()) { + HANDLE_CODE(crs_ch_est_mpdcch_cfg_common_r16->unpack(bref)); + } + if (gwus_cfg_r16.is_present()) { + HANDLE_CODE(gwus_cfg_r16->unpack(bref)); + } + if (ul_pwr_ctrl_common_v1610.is_present()) { + HANDLE_CODE(ul_pwr_ctrl_common_v1610->unpack(bref)); + } + if (punctured_subcarriers_dl_r16_present) { + HANDLE_CODE(punctured_subcarriers_dl_r16.unpack(bref)); + } + if (high_speed_inter_rat_nr_r16_present) { + HANDLE_CODE(bref.unpack(high_speed_inter_rat_nr_r16, 1)); + } + } + if (group_flags[9]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool pcch_cfg_v1700_present; + HANDLE_CODE(bref.unpack(pcch_cfg_v1700_present, 1)); + pcch_cfg_v1700.set_present(pcch_cfg_v1700_present); + bool ntn_cfg_common_r17_present; + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17_present, 1)); + ntn_cfg_common_r17.set_present(ntn_cfg_common_r17_present); + if (pcch_cfg_v1700.is_present()) { + HANDLE_CODE(pcch_cfg_v1700->unpack(bref)); + } + if (ntn_cfg_common_r17.is_present()) { + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->ta_report_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->prach_tx_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->pucch_tx_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->pusch_tx_dur_r17_present, 1)); + HANDLE_CODE(ntn_cfg_common_r17->t318_r17.unpack(bref)); + if (ntn_cfg_common_r17->prach_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->prach_tx_dur_r17.unpack(bref)); + } + if (ntn_cfg_common_r17->pucch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->pucch_tx_dur_r17.unpack(bref)); + } + if (ntn_cfg_common_r17->pusch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->pusch_tx_dur_r17.unpack(bref)); + } + } + } } return SRSASN_SUCCESS; } @@ -4113,10 +4963,78 @@ void rr_cfg_common_sib_s::to_json(json_writer& j) const j.write_fieldname("wus-Config-v1560"); wus_cfg_v1560->to_json(j); } + if (wus_cfg_v1610.is_present()) { + j.write_fieldname("wus-Config-v1610"); + wus_cfg_v1610->to_json(j); + } + if (high_speed_cfg_v1610.is_present()) { + j.write_fieldname("highSpeedConfig-v1610"); + high_speed_cfg_v1610->to_json(j); + } + if (crs_ch_est_mpdcch_cfg_common_r16.is_present()) { + j.write_fieldname("crs-ChEstMPDCCH-ConfigCommon-r16"); + crs_ch_est_mpdcch_cfg_common_r16->to_json(j); + } + if (gwus_cfg_r16.is_present()) { + j.write_fieldname("gwus-Config-r16"); + gwus_cfg_r16->to_json(j); + } + if (ul_pwr_ctrl_common_v1610.is_present()) { + j.write_fieldname("uplinkPowerControlCommon-v1610"); + ul_pwr_ctrl_common_v1610->to_json(j); + } + if (rss_meas_cfg_r16_present) { + j.write_str("rss-MeasConfig-r16", "enabled"); + } + if (rss_meas_non_ncl_r16_present) { + j.write_str("rss-MeasNonNCL-r16", "enabled"); + } + if (punctured_subcarriers_dl_r16_present) { + j.write_str("puncturedSubcarriersDL-r16", punctured_subcarriers_dl_r16.to_string()); + } + if (high_speed_inter_rat_nr_r16_present) { + j.write_bool("highSpeedInterRAT-NR-r16", high_speed_inter_rat_nr_r16); + } + if (pcch_cfg_v1700.is_present()) { + j.write_fieldname("pcch-Config-v1700"); + pcch_cfg_v1700->to_json(j); + } + if (ntn_cfg_common_r17.is_present()) { + j.write_fieldname("ntn-ConfigCommon-r17"); + j.start_obj(); + if (ntn_cfg_common_r17->ta_report_r17_present) { + j.write_str("ta-Report-r17", "enabled"); + } + j.write_str("t318-r17", ntn_cfg_common_r17->t318_r17.to_string()); + if (ntn_cfg_common_r17->prach_tx_dur_r17_present) { + j.write_fieldname("prach-TxDuration-r17"); + ntn_cfg_common_r17->prach_tx_dur_r17.to_json(j); + } + if (ntn_cfg_common_r17->pucch_tx_dur_r17_present) { + j.write_fieldname("pucch-TxDuration-r17"); + ntn_cfg_common_r17->pucch_tx_dur_r17.to_json(j); + } + if (ntn_cfg_common_r17->pusch_tx_dur_r17_present) { + j.write_fieldname("pusch-TxDuration-r17"); + ntn_cfg_common_r17->pusch_tx_dur_r17.to_json(j); + } + j.end_obj(); + } } j.end_obj(); } +const char* rr_cfg_common_sib_s::ntn_cfg_common_r17_s_::t318_r17_opts::to_string() const +{ + static const char* options[] = {"ms0", "ms50", "ms100", "ms200", "ms500", "ms1000", "ms2000", "ms4000"}; + return convert_enum_idx(options, 8, value, "rr_cfg_common_sib_s::ntn_cfg_common_r17_s_::t318_r17_e_"); +} +uint16_t rr_cfg_common_sib_s::ntn_cfg_common_r17_s_::t318_r17_opts::to_number() const +{ + static const uint16_t options[] = {0, 50, 100, 200, 500, 1000, 2000, 4000}; + return map_enum_number(options, 8, value, "rr_cfg_common_sib_s::ntn_cfg_common_r17_s_::t318_r17_e_"); +} + // TimeAlignmentTimer ::= ENUMERATED const char* time_align_timer_opts::to_string() const { @@ -4592,6 +5510,7 @@ SRSASN_CODE rr_cfg_common_scell_r10_s::pack(bit_ref& bref) const group_flags[4] |= srs_flex_timing_r14_present; group_flags[5] |= mbsfn_sf_cfg_list_v1430.is_present(); group_flags[6] |= ul_pwr_ctrl_common_scell_v1530.is_present(); + group_flags[7] |= high_speed_enh_meas_flag_scell_r16_present; group_flags.pack(bref); if (group_flags[0]) { @@ -4703,6 +5622,14 @@ SRSASN_CODE rr_cfg_common_scell_r10_s::pack(bit_ref& bref) const HANDLE_CODE(ul_pwr_ctrl_common_scell_v1530->pack(bref)); } } + if (group_flags[7]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(high_speed_enh_meas_flag_scell_r16_present, 1)); + if (high_speed_enh_meas_flag_scell_r16_present) { + HANDLE_CODE(bref.pack(high_speed_enh_meas_flag_scell_r16, 1)); + } + } } return SRSASN_SUCCESS; } @@ -4750,7 +5677,7 @@ SRSASN_CODE rr_cfg_common_scell_r10_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(7); + ext_groups_unpacker_guard group_flags(8); group_flags.unpack(bref); if (group_flags[0]) { @@ -4886,6 +5813,14 @@ SRSASN_CODE rr_cfg_common_scell_r10_s::unpack(cbit_ref& bref) HANDLE_CODE(ul_pwr_ctrl_common_scell_v1530->unpack(bref)); } } + if (group_flags[7]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(high_speed_enh_meas_flag_scell_r16_present, 1)); + if (high_speed_enh_meas_flag_scell_r16_present) { + HANDLE_CODE(bref.unpack(high_speed_enh_meas_flag_scell_r16, 1)); + } + } } return SRSASN_SUCCESS; } @@ -5028,6 +5963,9 @@ void rr_cfg_common_scell_r10_s::to_json(json_writer& j) const j.write_fieldname("uplinkPowerControlCommonSCell-v1530"); ul_pwr_ctrl_common_scell_v1530->to_json(j); } + if (high_speed_enh_meas_flag_scell_r16_present) { + j.write_bool("highSpeedEnhMeasFlagSCell-r16", high_speed_enh_meas_flag_scell_r16); + } } j.end_obj(); } @@ -5114,7 +6052,10 @@ bool rr_cfg_common_scell_r10_s::operator==(const rr_cfg_common_scell_r10_s& othe (not mbsfn_sf_cfg_list_v1430.is_present() or *mbsfn_sf_cfg_list_v1430 == *other.mbsfn_sf_cfg_list_v1430) and ul_pwr_ctrl_common_scell_v1530.is_present() == other.ul_pwr_ctrl_common_scell_v1530.is_present() and (not ul_pwr_ctrl_common_scell_v1530.is_present() or - *ul_pwr_ctrl_common_scell_v1530 == *other.ul_pwr_ctrl_common_scell_v1530))); + *ul_pwr_ctrl_common_scell_v1530 == *other.ul_pwr_ctrl_common_scell_v1530) and + high_speed_enh_meas_flag_scell_r16_present == other.high_speed_enh_meas_flag_scell_r16_present and + (not high_speed_enh_meas_flag_scell_r16_present or + high_speed_enh_meas_flag_scell_r16 == other.high_speed_enh_meas_flag_scell_r16))); } const char* rr_cfg_common_scell_r10_s::non_ul_cfg_r10_s_::dl_bw_r10_opts::to_string() const @@ -5510,6 +6451,10 @@ SRSASN_CODE rr_cfg_common_s::pack(bit_ref& bref) const group_flags[5] |= tdd_cfg_v1450.is_present(); group_flags[6] |= ul_pwr_ctrl_common_v1530.is_present(); group_flags[6] |= high_speed_cfg_v1530.is_present(); + group_flags[7] |= high_speed_cfg_v1610.is_present(); + group_flags[7] |= ul_pwr_ctrl_common_v1610.is_present(); + group_flags[7] |= high_speed_inter_rat_nr_r16_present; + group_flags[8] |= ntn_cfg_common_r17.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -5604,6 +6549,43 @@ SRSASN_CODE rr_cfg_common_s::pack(bit_ref& bref) const HANDLE_CODE(high_speed_cfg_v1530->pack(bref)); } } + if (group_flags[7]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(high_speed_cfg_v1610.is_present(), 1)); + HANDLE_CODE(bref.pack(ul_pwr_ctrl_common_v1610.is_present(), 1)); + HANDLE_CODE(bref.pack(high_speed_inter_rat_nr_r16_present, 1)); + if (high_speed_cfg_v1610.is_present()) { + HANDLE_CODE(high_speed_cfg_v1610->pack(bref)); + } + if (ul_pwr_ctrl_common_v1610.is_present()) { + HANDLE_CODE(ul_pwr_ctrl_common_v1610->pack(bref)); + } + if (high_speed_inter_rat_nr_r16_present) { + HANDLE_CODE(bref.pack(high_speed_inter_rat_nr_r16, 1)); + } + } + if (group_flags[8]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ntn_cfg_common_r17.is_present(), 1)); + if (ntn_cfg_common_r17.is_present()) { + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->ta_report_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->prach_tx_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->pucch_tx_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->pusch_tx_dur_r17_present, 1)); + HANDLE_CODE(ntn_cfg_common_r17->t318_r17.pack(bref)); + if (ntn_cfg_common_r17->prach_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->prach_tx_dur_r17.pack(bref)); + } + if (ntn_cfg_common_r17->pucch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->pucch_tx_dur_r17.pack(bref)); + } + if (ntn_cfg_common_r17->pusch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->pusch_tx_dur_r17.pack(bref)); + } + } + } } return SRSASN_SUCCESS; } @@ -5652,7 +6634,7 @@ SRSASN_CODE rr_cfg_common_s::unpack(cbit_ref& bref) HANDLE_CODE(ul_cp_len.unpack(bref)); if (ext) { - ext_groups_unpacker_guard group_flags(7); + ext_groups_unpacker_guard group_flags(9); group_flags.unpack(bref); if (group_flags[0]) { @@ -5779,6 +6761,49 @@ SRSASN_CODE rr_cfg_common_s::unpack(cbit_ref& bref) HANDLE_CODE(high_speed_cfg_v1530->unpack(bref)); } } + if (group_flags[7]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool high_speed_cfg_v1610_present; + HANDLE_CODE(bref.unpack(high_speed_cfg_v1610_present, 1)); + high_speed_cfg_v1610.set_present(high_speed_cfg_v1610_present); + bool ul_pwr_ctrl_common_v1610_present; + HANDLE_CODE(bref.unpack(ul_pwr_ctrl_common_v1610_present, 1)); + ul_pwr_ctrl_common_v1610.set_present(ul_pwr_ctrl_common_v1610_present); + HANDLE_CODE(bref.unpack(high_speed_inter_rat_nr_r16_present, 1)); + if (high_speed_cfg_v1610.is_present()) { + HANDLE_CODE(high_speed_cfg_v1610->unpack(bref)); + } + if (ul_pwr_ctrl_common_v1610.is_present()) { + HANDLE_CODE(ul_pwr_ctrl_common_v1610->unpack(bref)); + } + if (high_speed_inter_rat_nr_r16_present) { + HANDLE_CODE(bref.unpack(high_speed_inter_rat_nr_r16, 1)); + } + } + if (group_flags[8]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool ntn_cfg_common_r17_present; + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17_present, 1)); + ntn_cfg_common_r17.set_present(ntn_cfg_common_r17_present); + if (ntn_cfg_common_r17.is_present()) { + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->ta_report_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->prach_tx_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->pucch_tx_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->pusch_tx_dur_r17_present, 1)); + HANDLE_CODE(ntn_cfg_common_r17->t318_r17.unpack(bref)); + if (ntn_cfg_common_r17->prach_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->prach_tx_dur_r17.unpack(bref)); + } + if (ntn_cfg_common_r17->pucch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->pucch_tx_dur_r17.unpack(bref)); + } + if (ntn_cfg_common_r17->pusch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->pusch_tx_dur_r17.unpack(bref)); + } + } + } } return SRSASN_SUCCESS; } @@ -5890,6 +6915,49 @@ void rr_cfg_common_s::to_json(json_writer& j) const j.write_fieldname("highSpeedConfig-v1530"); high_speed_cfg_v1530->to_json(j); } + if (high_speed_cfg_v1610.is_present()) { + j.write_fieldname("highSpeedConfig-v1610"); + high_speed_cfg_v1610->to_json(j); + } + if (ul_pwr_ctrl_common_v1610.is_present()) { + j.write_fieldname("uplinkPowerControlCommon-v1610"); + ul_pwr_ctrl_common_v1610->to_json(j); + } + if (high_speed_inter_rat_nr_r16_present) { + j.write_bool("highSpeedInterRAT-NR-r16", high_speed_inter_rat_nr_r16); + } + if (ntn_cfg_common_r17.is_present()) { + j.write_fieldname("ntn-ConfigCommon-r17"); + j.start_obj(); + if (ntn_cfg_common_r17->ta_report_r17_present) { + j.write_str("ta-Report-r17", "enabled"); + } + j.write_str("t318-r17", ntn_cfg_common_r17->t318_r17.to_string()); + if (ntn_cfg_common_r17->prach_tx_dur_r17_present) { + j.write_fieldname("prach-TxDuration-r17"); + ntn_cfg_common_r17->prach_tx_dur_r17.to_json(j); + } + if (ntn_cfg_common_r17->pucch_tx_dur_r17_present) { + j.write_fieldname("pucch-TxDuration-r17"); + ntn_cfg_common_r17->pucch_tx_dur_r17.to_json(j); + } + if (ntn_cfg_common_r17->pusch_tx_dur_r17_present) { + j.write_fieldname("pusch-TxDuration-r17"); + ntn_cfg_common_r17->pusch_tx_dur_r17.to_json(j); + } + j.end_obj(); + } } j.end_obj(); } + +const char* rr_cfg_common_s::ntn_cfg_common_r17_s_::t318_r17_opts::to_string() const +{ + static const char* options[] = {"ms0", "ms50", "ms100", "ms200", "ms500", "ms1000", "ms2000", "ms4000", "ms6000"}; + return convert_enum_idx(options, 9, value, "rr_cfg_common_s::ntn_cfg_common_r17_s_::t318_r17_e_"); +} +uint16_t rr_cfg_common_s::ntn_cfg_common_r17_s_::t318_r17_opts::to_number() const +{ + static const uint16_t options[] = {0, 50, 100, 200, 500, 1000, 2000, 4000, 6000}; + return map_enum_number(options, 9, value, "rr_cfg_common_s::ntn_cfg_common_r17_s_::t318_r17_e_"); +} diff --git a/lib/src/asn1/rrc/rr_ded.cc b/lib/src/asn1/rrc/rr_ded.cc index 47dfb61dd8..291f1c55e0 100644 --- a/lib/src/asn1/rrc/rr_ded.cc +++ b/lib/src/asn1/rrc/rr_ded.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -386,6 +386,98 @@ bool dl_um_rlc_s::operator==(const dl_um_rlc_s& other) const return sn_field_len == other.sn_field_len and t_reordering == other.t_reordering; } +// DiscardTimerExt-r17 ::= ENUMERATED +const char* discard_timer_ext_r17_opts::to_string() const +{ + static const char* options[] = {"ms2000", "spare"}; + return convert_enum_idx(options, 2, value, "discard_timer_ext_r17_e"); +} +uint16_t discard_timer_ext_r17_opts::to_number() const +{ + static const uint16_t options[] = {2000}; + return map_enum_number(options, 1, value, "discard_timer_ext_r17_e"); +} + +// EthernetHeaderCompression-r16 ::= SEQUENCE +SRSASN_CODE ethernet_hdr_compress_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ehc_dl_r16_present, 1)); + HANDLE_CODE(bref.pack(ehc_ul_r16_present, 1)); + + HANDLE_CODE(ehc_common_r16.ehc_cid_len_r16.pack(bref)); + if (ehc_dl_r16_present) { + HANDLE_CODE(bref.pack(ehc_dl_r16.drb_continue_ehc_dl_r16_present, 1)); + } + if (ehc_ul_r16_present) { + HANDLE_CODE(bref.pack(ehc_ul_r16.drb_continue_ehc_ul_r16_present, 1)); + HANDLE_CODE(pack_integer(bref, ehc_ul_r16.max_cid_ehc_ul_r16, (uint16_t)1u, (uint16_t)32767u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ethernet_hdr_compress_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ehc_dl_r16_present, 1)); + HANDLE_CODE(bref.unpack(ehc_ul_r16_present, 1)); + + HANDLE_CODE(ehc_common_r16.ehc_cid_len_r16.unpack(bref)); + if (ehc_dl_r16_present) { + HANDLE_CODE(bref.unpack(ehc_dl_r16.drb_continue_ehc_dl_r16_present, 1)); + } + if (ehc_ul_r16_present) { + HANDLE_CODE(bref.unpack(ehc_ul_r16.drb_continue_ehc_ul_r16_present, 1)); + HANDLE_CODE(unpack_integer(ehc_ul_r16.max_cid_ehc_ul_r16, bref, (uint16_t)1u, (uint16_t)32767u)); + } + + return SRSASN_SUCCESS; +} +void ethernet_hdr_compress_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ehc-Common-r16"); + j.start_obj(); + j.write_str("ehc-CID-Length-r16", ehc_common_r16.ehc_cid_len_r16.to_string()); + j.end_obj(); + if (ehc_dl_r16_present) { + j.write_fieldname("ehc-Downlink-r16"); + j.start_obj(); + if (ehc_dl_r16.drb_continue_ehc_dl_r16_present) { + j.write_str("drb-ContinueEHC-DL-r16", "true"); + } + j.end_obj(); + } + if (ehc_ul_r16_present) { + j.write_fieldname("ehc-Uplink-r16"); + j.start_obj(); + j.write_int("maxCID-EHC-UL-r16", ehc_ul_r16.max_cid_ehc_ul_r16); + if (ehc_ul_r16.drb_continue_ehc_ul_r16_present) { + j.write_str("drb-ContinueEHC-UL-r16", "true"); + } + j.end_obj(); + } + j.end_obj(); +} +bool ethernet_hdr_compress_r16_s::operator==(const ethernet_hdr_compress_r16_s& other) const +{ + return ext == other.ext and ehc_common_r16.ehc_cid_len_r16 == other.ehc_common_r16.ehc_cid_len_r16 and + ehc_dl_r16.drb_continue_ehc_dl_r16_present == other.ehc_dl_r16.drb_continue_ehc_dl_r16_present and + ehc_ul_r16.max_cid_ehc_ul_r16 == other.ehc_ul_r16.max_cid_ehc_ul_r16 and + ehc_ul_r16.drb_continue_ehc_ul_r16_present == other.ehc_ul_r16.drb_continue_ehc_ul_r16_present; +} + +const char* ethernet_hdr_compress_r16_s::ehc_common_r16_s_::ehc_cid_len_r16_opts::to_string() const +{ + static const char* options[] = {"bits7", "bits15"}; + return convert_enum_idx(options, 2, value, "ethernet_hdr_compress_r16_s::ehc_common_r16_s_::ehc_cid_len_r16_e_"); +} +uint8_t ethernet_hdr_compress_r16_s::ehc_common_r16_s_::ehc_cid_len_r16_opts::to_number() const +{ + static const uint8_t options[] = {7, 15}; + return map_enum_number(options, 2, value, "ethernet_hdr_compress_r16_s::ehc_common_r16_s_::ehc_cid_len_r16_e_"); +} + // LogicalChannelConfig ::= SEQUENCE SRSASN_CODE lc_ch_cfg_s::pack(bit_ref& bref) const { @@ -412,6 +504,7 @@ SRSASN_CODE lc_ch_cfg_s::pack(bit_ref& bref) const group_flags[3] |= lc_ch_sr_restrict_r15.is_present(); group_flags[3] |= ch_access_prio_r15.is_present(); group_flags[3] |= lch_cell_restrict_r15_present; + group_flags[4] |= bit_rate_multiplier_r16_present; group_flags.pack(bref); if (group_flags[0]) { @@ -459,6 +552,14 @@ SRSASN_CODE lc_ch_cfg_s::pack(bit_ref& bref) const HANDLE_CODE(lch_cell_restrict_r15.pack(bref)); } } + if (group_flags[4]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(bit_rate_multiplier_r16_present, 1)); + if (bit_rate_multiplier_r16_present) { + HANDLE_CODE(bit_rate_multiplier_r16.pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -478,7 +579,7 @@ SRSASN_CODE lc_ch_cfg_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(4); + ext_groups_unpacker_guard group_flags(5); group_flags.unpack(bref); if (group_flags[0]) { @@ -532,6 +633,14 @@ SRSASN_CODE lc_ch_cfg_s::unpack(cbit_ref& bref) HANDLE_CODE(lch_cell_restrict_r15.unpack(bref)); } } + if (group_flags[4]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(bit_rate_multiplier_r16_present, 1)); + if (bit_rate_multiplier_r16_present) { + HANDLE_CODE(bit_rate_multiplier_r16.unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -577,6 +686,9 @@ void lc_ch_cfg_s::to_json(json_writer& j) const if (lch_cell_restrict_r15_present) { j.write_str("lch-CellRestriction-r15", lch_cell_restrict_r15.to_string()); } + if (bit_rate_multiplier_r16_present) { + j.write_str("bitRateMultiplier-r16", bit_rate_multiplier_r16.to_string()); + } } j.end_obj(); } @@ -604,7 +716,9 @@ bool lc_ch_cfg_s::operator==(const lc_ch_cfg_s& other) const ch_access_prio_r15.is_present() == other.ch_access_prio_r15.is_present() and (not ch_access_prio_r15.is_present() or *ch_access_prio_r15 == *other.ch_access_prio_r15) and lch_cell_restrict_r15_present == other.lch_cell_restrict_r15_present and - (not lch_cell_restrict_r15_present or lch_cell_restrict_r15 == other.lch_cell_restrict_r15))); + (not lch_cell_restrict_r15_present or lch_cell_restrict_r15 == other.lch_cell_restrict_r15) and + bit_rate_multiplier_r16_present == other.bit_rate_multiplier_r16_present and + (not bit_rate_multiplier_r16_present or bit_rate_multiplier_r16 == other.bit_rate_multiplier_r16))); } const char* lc_ch_cfg_s::ul_specific_params_s_::prioritised_bit_rate_opts::to_string() const @@ -864,6 +978,17 @@ bool lc_ch_cfg_s::ch_access_prio_r15_c_::operator==(const ch_access_prio_r15_c_& return type() == other.type() and c == other.c; } +const char* lc_ch_cfg_s::bit_rate_multiplier_r16_opts::to_string() const +{ + static const char* options[] = {"x40", "x70", "x100", "x200"}; + return convert_enum_idx(options, 4, value, "lc_ch_cfg_s::bit_rate_multiplier_r16_e_"); +} +uint8_t lc_ch_cfg_s::bit_rate_multiplier_r16_opts::to_number() const +{ + static const uint8_t options[] = {40, 70, 100, 200}; + return map_enum_number(options, 4, value, "lc_ch_cfg_s::bit_rate_multiplier_r16_e_"); +} + // P-a ::= ENUMERATED const char* p_a_opts::to_string() const { @@ -1158,6 +1283,18 @@ bool rlc_cfg_r15_s::mode_r15_c_::operator==(const mode_r15_c_& other) const return true; } +// T-ReorderingExt-r17 ::= ENUMERATED +const char* t_reordering_ext_r17_opts::to_string() const +{ + static const char* options[] = {"ms2200", "ms3200"}; + return convert_enum_idx(options, 2, value, "t_reordering_ext_r17_e"); +} +uint16_t t_reordering_ext_r17_opts::to_number() const +{ + static const uint16_t options[] = {2200, 3200}; + return map_enum_number(options, 2, value, "t_reordering_ext_r17_e"); +} + // UL-AM-RLC ::= SEQUENCE SRSASN_CODE ul_am_rlc_s::pack(bit_ref& bref) const { @@ -1525,6 +1662,8 @@ SRSASN_CODE pdcp_cfg_s::pack(bit_ref& bref) const group_flags[4] |= ul_only_hdr_compress_r14.is_present(); group_flags[5] |= ul_data_compress_r15.is_present(); group_flags[5] |= pdcp_dupl_cfg_r15.is_present(); + group_flags[6] |= ethernet_hdr_compress_r16.is_present(); + group_flags[7] |= discard_timer_ext_r17.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -1591,6 +1730,22 @@ SRSASN_CODE pdcp_cfg_s::pack(bit_ref& bref) const HANDLE_CODE(pdcp_dupl_cfg_r15->pack(bref)); } } + if (group_flags[6]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ethernet_hdr_compress_r16.is_present(), 1)); + if (ethernet_hdr_compress_r16.is_present()) { + HANDLE_CODE(ethernet_hdr_compress_r16->pack(bref)); + } + } + if (group_flags[7]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(discard_timer_ext_r17.is_present(), 1)); + if (discard_timer_ext_r17.is_present()) { + HANDLE_CODE(discard_timer_ext_r17->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -1613,7 +1768,7 @@ SRSASN_CODE pdcp_cfg_s::unpack(cbit_ref& bref) HANDLE_CODE(hdr_compress.unpack(bref)); if (ext) { - ext_groups_unpacker_guard group_flags(6); + ext_groups_unpacker_guard group_flags(8); group_flags.unpack(bref); if (group_flags[0]) { @@ -1692,6 +1847,26 @@ SRSASN_CODE pdcp_cfg_s::unpack(cbit_ref& bref) HANDLE_CODE(pdcp_dupl_cfg_r15->unpack(bref)); } } + if (group_flags[6]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool ethernet_hdr_compress_r16_present; + HANDLE_CODE(bref.unpack(ethernet_hdr_compress_r16_present, 1)); + ethernet_hdr_compress_r16.set_present(ethernet_hdr_compress_r16_present); + if (ethernet_hdr_compress_r16.is_present()) { + HANDLE_CODE(ethernet_hdr_compress_r16->unpack(bref)); + } + } + if (group_flags[7]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool discard_timer_ext_r17_present; + HANDLE_CODE(bref.unpack(discard_timer_ext_r17_present, 1)); + discard_timer_ext_r17.set_present(discard_timer_ext_r17_present); + if (discard_timer_ext_r17.is_present()) { + HANDLE_CODE(discard_timer_ext_r17->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -1760,6 +1935,14 @@ void pdcp_cfg_s::to_json(json_writer& j) const j.write_fieldname("pdcp-DuplicationConfig-r15"); pdcp_dupl_cfg_r15->to_json(j); } + if (ethernet_hdr_compress_r16.is_present()) { + j.write_fieldname("ethernetHeaderCompression-r16"); + ethernet_hdr_compress_r16->to_json(j); + } + if (discard_timer_ext_r17.is_present()) { + j.write_fieldname("discardTimerExt-r17"); + discard_timer_ext_r17->to_json(j); + } } j.end_obj(); } @@ -1793,7 +1976,12 @@ bool pdcp_cfg_s::operator==(const pdcp_cfg_s& other) const (not ul_data_compress_r15->dictionary_r15_present or ul_data_compress_r15->dictionary_r15 == other.ul_data_compress_r15->dictionary_r15) and pdcp_dupl_cfg_r15.is_present() == other.pdcp_dupl_cfg_r15.is_present() and - (not pdcp_dupl_cfg_r15.is_present() or *pdcp_dupl_cfg_r15 == *other.pdcp_dupl_cfg_r15))); + (not pdcp_dupl_cfg_r15.is_present() or *pdcp_dupl_cfg_r15 == *other.pdcp_dupl_cfg_r15) and + ethernet_hdr_compress_r16.is_present() == other.ethernet_hdr_compress_r16.is_present() and + (not ethernet_hdr_compress_r16.is_present() or + *ethernet_hdr_compress_r16 == *other.ethernet_hdr_compress_r16) and + discard_timer_ext_r17.is_present() == other.discard_timer_ext_r17.is_present() and + (not discard_timer_ext_r17.is_present() or *discard_timer_ext_r17 == *other.discard_timer_ext_r17))); } const char* pdcp_cfg_s::discard_timer_opts::to_string() const @@ -3138,6 +3326,31 @@ bool rlc_cfg_v1530_c::operator==(const rlc_cfg_v1530_c& other) const return type() == other.type(); } +// RLC-Config-v1700 ::= SEQUENCE +SRSASN_CODE rlc_cfg_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(t_reordering_ext_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rlc_cfg_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(t_reordering_ext_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void rlc_cfg_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("t-ReorderingExt-r17"); + t_reordering_ext_r17.to_json(j); + j.end_obj(); +} +bool rlc_cfg_v1700_s::operator==(const rlc_cfg_v1700_s& other) const +{ + return t_reordering_ext_r17 == other.t_reordering_ext_r17; +} + // SPS-ConfigSL-r14 ::= SEQUENCE SRSASN_CODE sps_cfg_sl_r14_s::pack(bit_ref& bref) const { @@ -4158,6 +4371,8 @@ SRSASN_CODE drb_to_add_mod_s::pack(bit_ref& bref) const group_flags[4] |= rlc_cfg_v1530.is_present(); group_flags[4] |= rlc_bearer_cfg_secondary_r15.is_present(); group_flags[4] |= lc_ch_id_r15_present; + group_flags[5] |= daps_ho_r16_present; + group_flags[6] |= rlc_cfg_v1700.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -4229,6 +4444,19 @@ SRSASN_CODE drb_to_add_mod_s::pack(bit_ref& bref) const HANDLE_CODE(pack_integer(bref, lc_ch_id_r15, (uint8_t)32u, (uint8_t)38u)); } } + if (group_flags[5]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(daps_ho_r16_present, 1)); + } + if (group_flags[6]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(rlc_cfg_v1700.is_present(), 1)); + if (rlc_cfg_v1700.is_present()) { + HANDLE_CODE(rlc_cfg_v1700->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -4259,7 +4487,7 @@ SRSASN_CODE drb_to_add_mod_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(5); + ext_groups_unpacker_guard group_flags(7); group_flags.unpack(bref); if (group_flags[0]) { @@ -4343,6 +4571,21 @@ SRSASN_CODE drb_to_add_mod_s::unpack(cbit_ref& bref) HANDLE_CODE(unpack_integer(lc_ch_id_r15, bref, (uint8_t)32u, (uint8_t)38u)); } } + if (group_flags[5]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(daps_ho_r16_present, 1)); + } + if (group_flags[6]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool rlc_cfg_v1700_present; + HANDLE_CODE(bref.unpack(rlc_cfg_v1700_present, 1)); + rlc_cfg_v1700.set_present(rlc_cfg_v1700_present); + if (rlc_cfg_v1700.is_present()) { + HANDLE_CODE(rlc_cfg_v1700->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -4414,6 +4657,13 @@ void drb_to_add_mod_s::to_json(json_writer& j) const if (lc_ch_id_r15_present) { j.write_int("logicalChannelIdentity-r15", lc_ch_id_r15); } + if (daps_ho_r16_present) { + j.write_str("daps-HO-r16", "true"); + } + if (rlc_cfg_v1700.is_present()) { + j.write_fieldname("rlc-Config-v1700"); + rlc_cfg_v1700->to_json(j); + } } j.end_obj(); } @@ -4451,7 +4701,10 @@ bool drb_to_add_mod_s::operator==(const drb_to_add_mod_s& other) const (not rlc_bearer_cfg_secondary_r15.is_present() or *rlc_bearer_cfg_secondary_r15 == *other.rlc_bearer_cfg_secondary_r15) and lc_ch_id_r15_present == other.lc_ch_id_r15_present and - (not lc_ch_id_r15_present or lc_ch_id_r15 == other.lc_ch_id_r15))); + (not lc_ch_id_r15_present or lc_ch_id_r15 == other.lc_ch_id_r15) and + daps_ho_r16_present == other.daps_ho_r16_present and + rlc_cfg_v1700.is_present() == other.rlc_cfg_v1700.is_present() and + (not rlc_cfg_v1700.is_present() or *rlc_cfg_v1700 == *other.rlc_cfg_v1700))); } const char* drb_to_add_mod_s::drb_type_lwip_r13_opts::to_string() const @@ -5394,6 +5647,39 @@ uint8_t data_inactivity_timer_r14_opts::to_number() const return map_enum_number(options, 16, value, "data_inactivity_timer_r14_e"); } +// OffsetThresholdTA-r17 ::= ENUMERATED +const char* offset_thres_ta_r17_opts::to_string() const +{ + static const char* options[] = {"ms0dot5", + "ms1", + "ms2", + "ms3", + "ms4", + "ms5", + "ms6", + "ms7", + "ms8", + "ms9", + "ms10", + "ms11", + "ms12", + "ms13", + "ms14", + "ms15"}; + return convert_enum_idx(options, 16, value, "offset_thres_ta_r17_e"); +} +float offset_thres_ta_r17_opts::to_number() const +{ + static const float options[] = {0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0}; + return map_enum_number(options, 16, value, "offset_thres_ta_r17_e"); +} +const char* offset_thres_ta_r17_opts::to_number_string() const +{ + static const char* options[] = { + "0.5", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"}; + return convert_enum_idx(options, 16, value, "offset_thres_ta_r17_e"); +} + // PeriodicBSR-Timer-r12 ::= ENUMERATED const char* periodic_bsr_timer_r12_opts::to_string() const { @@ -5867,6 +6153,18 @@ SRSASN_CODE sps_cfg_dl_stti_r15_c::setup_s_::two_ant_port_activ_r15_c_::unpack(c return SRSASN_SUCCESS; } +// SR-ProhibitTimerOffset-r17 ::= ENUMERATED +const char* sr_prohibit_timer_offset_r17_opts::to_string() const +{ + static const char* options[] = {"ms90", "ms180", "ms270", "ms360", "ms450", "ms540", "ms1080", "spare"}; + return convert_enum_idx(options, 8, value, "sr_prohibit_timer_offset_r17_e"); +} +uint16_t sr_prohibit_timer_offset_r17_opts::to_number() const +{ + static const uint16_t options[] = {90, 180, 270, 360, 450, 540, 1080}; + return map_enum_number(options, 7, value, "sr_prohibit_timer_offset_r17_e"); +} + // SRB-ToAddMod ::= SEQUENCE SRSASN_CODE srb_to_add_mod_s::pack(bit_ref& bref) const { @@ -5889,6 +6187,7 @@ SRSASN_CODE srb_to_add_mod_s::pack(bit_ref& bref) const group_flags[0] |= rlc_bearer_cfg_secondary_r15.is_present(); group_flags[0] |= srb_id_v1530_present; group_flags[1] |= rlc_cfg_v1560.is_present(); + group_flags[2] |= rlc_cfg_v1700.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -5916,6 +6215,14 @@ SRSASN_CODE srb_to_add_mod_s::pack(bit_ref& bref) const HANDLE_CODE(rlc_cfg_v1560->pack(bref)); } } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(rlc_cfg_v1700.is_present(), 1)); + if (rlc_cfg_v1700.is_present()) { + HANDLE_CODE(rlc_cfg_v1700->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -5934,7 +6241,7 @@ SRSASN_CODE srb_to_add_mod_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(2); + ext_groups_unpacker_guard group_flags(3); group_flags.unpack(bref); if (group_flags[0]) { @@ -5968,6 +6275,16 @@ SRSASN_CODE srb_to_add_mod_s::unpack(cbit_ref& bref) HANDLE_CODE(rlc_cfg_v1560->unpack(bref)); } } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool rlc_cfg_v1700_present; + HANDLE_CODE(bref.unpack(rlc_cfg_v1700_present, 1)); + rlc_cfg_v1700.set_present(rlc_cfg_v1700_present); + if (rlc_cfg_v1700.is_present()) { + HANDLE_CODE(rlc_cfg_v1700->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -6002,6 +6319,10 @@ void srb_to_add_mod_s::to_json(json_writer& j) const j.write_fieldname("rlc-Config-v1560"); rlc_cfg_v1560->to_json(j); } + if (rlc_cfg_v1700.is_present()) { + j.write_fieldname("rlc-Config-v1700"); + rlc_cfg_v1700->to_json(j); + } } j.end_obj(); } @@ -6019,7 +6340,9 @@ bool srb_to_add_mod_s::operator==(const srb_to_add_mod_s& other) const srb_id_v1530_present == other.srb_id_v1530_present and (not srb_id_v1530_present or srb_id_v1530 == other.srb_id_v1530) and rlc_cfg_v1560.is_present() == other.rlc_cfg_v1560.is_present() and - (not rlc_cfg_v1560.is_present() or *rlc_cfg_v1560 == *other.rlc_cfg_v1560))); + (not rlc_cfg_v1560.is_present() or *rlc_cfg_v1560 == *other.rlc_cfg_v1560) and + rlc_cfg_v1700.is_present() == other.rlc_cfg_v1700.is_present() and + (not rlc_cfg_v1700.is_present() or *rlc_cfg_v1700 == *other.rlc_cfg_v1700))); } void srb_to_add_mod_s::rlc_cfg_c_::set(types::options e) @@ -6152,6 +6475,69 @@ bool srb_to_add_mod_s::lc_ch_cfg_c_::operator==(const lc_ch_cfg_c_& other) const return type() == other.type() and c == other.c; } +// CRS-ChEstMPDCCH-ConfigDedicated-r16 ::= SEQUENCE +SRSASN_CODE crs_ch_est_mpdcch_cfg_ded_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pwr_ratio_r16_present, 1)); + HANDLE_CODE(bref.pack(localized_map_type_r16_present, 1)); + + if (pwr_ratio_r16_present) { + HANDLE_CODE(pwr_ratio_r16.pack(bref)); + } + if (localized_map_type_r16_present) { + HANDLE_CODE(localized_map_type_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE crs_ch_est_mpdcch_cfg_ded_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(pwr_ratio_r16_present, 1)); + HANDLE_CODE(bref.unpack(localized_map_type_r16_present, 1)); + + if (pwr_ratio_r16_present) { + HANDLE_CODE(pwr_ratio_r16.unpack(bref)); + } + if (localized_map_type_r16_present) { + HANDLE_CODE(localized_map_type_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void crs_ch_est_mpdcch_cfg_ded_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (pwr_ratio_r16_present) { + j.write_str("powerRatio-r16", pwr_ratio_r16.to_string()); + } + if (localized_map_type_r16_present) { + j.write_str("localizedMappingType-r16", localized_map_type_r16.to_string()); + } + j.end_obj(); +} + +const char* crs_ch_est_mpdcch_cfg_ded_r16_s::pwr_ratio_r16_opts::to_string() const +{ + static const char* options[] = {"dB-4dot77", "dB-3", "dB-1dot77", "dB0", "dB1", "dB2", "dB3", "dB4dot77"}; + return convert_enum_idx(options, 8, value, "crs_ch_est_mpdcch_cfg_ded_r16_s::pwr_ratio_r16_e_"); +} +float crs_ch_est_mpdcch_cfg_ded_r16_s::pwr_ratio_r16_opts::to_number() const +{ + static const float options[] = {-4.77, -3.0, -1.77, 0.0, 1.0, 2.0, 3.0, 4.77}; + return map_enum_number(options, 8, value, "crs_ch_est_mpdcch_cfg_ded_r16_s::pwr_ratio_r16_e_"); +} +const char* crs_ch_est_mpdcch_cfg_ded_r16_s::pwr_ratio_r16_opts::to_number_string() const +{ + static const char* options[] = {"-4.77", "-3", "-1.77", "0", "1", "2", "3", "4.77"}; + return convert_enum_idx(options, 8, value, "crs_ch_est_mpdcch_cfg_ded_r16_s::pwr_ratio_r16_e_"); +} + +const char* crs_ch_est_mpdcch_cfg_ded_r16_s::localized_map_type_r16_opts::to_string() const +{ + static const char* options[] = {"predefined", "csi-Based", "reciprocityBased"}; + return convert_enum_idx(options, 3, value, "crs_ch_est_mpdcch_cfg_ded_r16_s::localized_map_type_r16_e_"); +} + // MAC-MainConfig ::= SEQUENCE SRSASN_CODE mac_main_cfg_s::pack(bit_ref& bref) const { @@ -6200,6 +6586,9 @@ SRSASN_CODE mac_main_cfg_s::pack(bit_ref& bref) const group_flags[8] |= short_tti_and_spt_r15.is_present(); group_flags[8] |= mpdcch_ul_harq_ack_feedback_cfg_r15_present; group_flags[8] |= dormant_state_timers_r15.is_present(); + group_flags[9] |= ce_etws_cmas_rx_in_conn_r16_present; + group_flags[10] |= offset_thres_ta_r17.is_present(); + group_flags[10] |= sr_prohibit_timer_offset_r17.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -6312,6 +6701,23 @@ SRSASN_CODE mac_main_cfg_s::pack(bit_ref& bref) const HANDLE_CODE(dormant_state_timers_r15->pack(bref)); } } + if (group_flags[9]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ce_etws_cmas_rx_in_conn_r16_present, 1)); + } + if (group_flags[10]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(offset_thres_ta_r17.is_present(), 1)); + HANDLE_CODE(bref.pack(sr_prohibit_timer_offset_r17.is_present(), 1)); + if (offset_thres_ta_r17.is_present()) { + HANDLE_CODE(offset_thres_ta_r17->pack(bref)); + } + if (sr_prohibit_timer_offset_r17.is_present()) { + HANDLE_CODE(sr_prohibit_timer_offset_r17->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -6343,7 +6749,7 @@ SRSASN_CODE mac_main_cfg_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(9); + ext_groups_unpacker_guard group_flags(11); group_flags.unpack(bref); if (group_flags[0]) { @@ -6482,6 +6888,27 @@ SRSASN_CODE mac_main_cfg_s::unpack(cbit_ref& bref) HANDLE_CODE(dormant_state_timers_r15->unpack(bref)); } } + if (group_flags[9]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(ce_etws_cmas_rx_in_conn_r16_present, 1)); + } + if (group_flags[10]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool offset_thres_ta_r17_present; + HANDLE_CODE(bref.unpack(offset_thres_ta_r17_present, 1)); + offset_thres_ta_r17.set_present(offset_thres_ta_r17_present); + bool sr_prohibit_timer_offset_r17_present; + HANDLE_CODE(bref.unpack(sr_prohibit_timer_offset_r17_present, 1)); + sr_prohibit_timer_offset_r17.set_present(sr_prohibit_timer_offset_r17_present); + if (offset_thres_ta_r17.is_present()) { + HANDLE_CODE(offset_thres_ta_r17->unpack(bref)); + } + if (sr_prohibit_timer_offset_r17.is_present()) { + HANDLE_CODE(sr_prohibit_timer_offset_r17->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -6594,6 +7021,17 @@ void mac_main_cfg_s::to_json(json_writer& j) const j.write_fieldname("dormantStateTimers-r15"); dormant_state_timers_r15->to_json(j); } + if (ce_etws_cmas_rx_in_conn_r16_present) { + j.write_str("ce-ETWS-CMAS-RxInConn-r16", "true"); + } + if (offset_thres_ta_r17.is_present()) { + j.write_fieldname("offsetThresholdTA-r17"); + offset_thres_ta_r17->to_json(j); + } + if (sr_prohibit_timer_offset_r17.is_present()) { + j.write_fieldname("sr-ProhibitTimerOffset-r17"); + sr_prohibit_timer_offset_r17->to_json(j); + } } j.end_obj(); } @@ -8151,6 +8589,84 @@ uint8_t rlf_timers_and_consts_r9_c::setup_s_::n311_r9_opts::to_number() const return map_enum_number(options, 8, value, "rlf_timers_and_consts_r9_c::setup_s_::n311_r9_e_"); } +// RLF-TimersAndConstantsMCG-Failure-r16 ::= CHOICE +void rlf_timers_and_consts_mcg_fail_r16_c::set(types::options e) +{ + type_ = e; +} +void rlf_timers_and_consts_mcg_fail_r16_c::set_release() +{ + set(types::release); +} +rlf_timers_and_consts_mcg_fail_r16_c::setup_s_& rlf_timers_and_consts_mcg_fail_r16_c::set_setup() +{ + set(types::setup); + return c; +} +void rlf_timers_and_consts_mcg_fail_r16_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::release: + break; + case types::setup: + j.write_fieldname("setup"); + j.start_obj(); + j.write_str("t316-r16", c.t316_r16.to_string()); + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "rlf_timers_and_consts_mcg_fail_r16_c"); + } + j.end_obj(); +} +SRSASN_CODE rlf_timers_and_consts_mcg_fail_r16_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::release: + break; + case types::setup: + bref.pack(c.ext, 1); + HANDLE_CODE(c.t316_r16.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "rlf_timers_and_consts_mcg_fail_r16_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rlf_timers_and_consts_mcg_fail_r16_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::release: + break; + case types::setup: + bref.unpack(c.ext, 1); + HANDLE_CODE(c.t316_r16.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "rlf_timers_and_consts_mcg_fail_r16_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rlf_timers_and_consts_mcg_fail_r16_c::setup_s_::t316_r16_opts::to_string() const +{ + static const char* options[] = { + "ms50", "ms100", "ms200", "ms300", "ms400", "ms500", "ms600", "ms1000", "ms1500", "ms2000"}; + return convert_enum_idx(options, 10, value, "rlf_timers_and_consts_mcg_fail_r16_c::setup_s_::t316_r16_e_"); +} +uint16_t rlf_timers_and_consts_mcg_fail_r16_c::setup_s_::t316_r16_opts::to_number() const +{ + static const uint16_t options[] = {50, 100, 200, 300, 400, 500, 600, 1000, 1500, 2000}; + return map_enum_number(options, 10, value, "rlf_timers_and_consts_mcg_fail_r16_c::setup_s_::t316_r16_e_"); +} + // SPS-Config ::= SEQUENCE SRSASN_CODE sps_cfg_s::pack(bit_ref& bref) const { @@ -8507,6 +9023,9 @@ SRSASN_CODE rr_cfg_ded_s::pack(bit_ref& bref) const group_flags[6] |= drb_to_release_list_r15.is_present(); group_flags[6] |= dummy.is_present(); group_flags[7] |= sps_cfg_v1540.is_present(); + group_flags[8] |= rlf_timers_and_consts_mcg_fail_r16.is_present(); + group_flags[8] |= crs_ch_est_mpdcch_cfg_ded_r16.is_present(); + group_flags[8] |= new_ue_id_r16_present; group_flags.pack(bref); if (group_flags[0]) { @@ -8605,6 +9124,22 @@ SRSASN_CODE rr_cfg_ded_s::pack(bit_ref& bref) const HANDLE_CODE(sps_cfg_v1540->pack(bref)); } } + if (group_flags[8]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(rlf_timers_and_consts_mcg_fail_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(crs_ch_est_mpdcch_cfg_ded_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(new_ue_id_r16_present, 1)); + if (rlf_timers_and_consts_mcg_fail_r16.is_present()) { + HANDLE_CODE(rlf_timers_and_consts_mcg_fail_r16->pack(bref)); + } + if (crs_ch_est_mpdcch_cfg_ded_r16.is_present()) { + HANDLE_CODE(crs_ch_est_mpdcch_cfg_ded_r16->pack(bref)); + } + if (new_ue_id_r16_present) { + HANDLE_CODE(new_ue_id_r16.pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -8638,7 +9173,7 @@ SRSASN_CODE rr_cfg_ded_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(8); + ext_groups_unpacker_guard group_flags(9); group_flags.unpack(bref); if (group_flags[0]) { @@ -8767,6 +9302,26 @@ SRSASN_CODE rr_cfg_ded_s::unpack(cbit_ref& bref) HANDLE_CODE(sps_cfg_v1540->unpack(bref)); } } + if (group_flags[8]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool rlf_timers_and_consts_mcg_fail_r16_present; + HANDLE_CODE(bref.unpack(rlf_timers_and_consts_mcg_fail_r16_present, 1)); + rlf_timers_and_consts_mcg_fail_r16.set_present(rlf_timers_and_consts_mcg_fail_r16_present); + bool crs_ch_est_mpdcch_cfg_ded_r16_present; + HANDLE_CODE(bref.unpack(crs_ch_est_mpdcch_cfg_ded_r16_present, 1)); + crs_ch_est_mpdcch_cfg_ded_r16.set_present(crs_ch_est_mpdcch_cfg_ded_r16_present); + HANDLE_CODE(bref.unpack(new_ue_id_r16_present, 1)); + if (rlf_timers_and_consts_mcg_fail_r16.is_present()) { + HANDLE_CODE(rlf_timers_and_consts_mcg_fail_r16->unpack(bref)); + } + if (crs_ch_est_mpdcch_cfg_ded_r16.is_present()) { + HANDLE_CODE(crs_ch_est_mpdcch_cfg_ded_r16->unpack(bref)); + } + if (new_ue_id_r16_present) { + HANDLE_CODE(new_ue_id_r16.unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -8882,6 +9437,17 @@ void rr_cfg_ded_s::to_json(json_writer& j) const j.write_fieldname("sps-Config-v1540"); sps_cfg_v1540->to_json(j); } + if (rlf_timers_and_consts_mcg_fail_r16.is_present()) { + j.write_fieldname("rlf-TimersAndConstantsMCG-Failure-r16"); + rlf_timers_and_consts_mcg_fail_r16->to_json(j); + } + if (crs_ch_est_mpdcch_cfg_ded_r16.is_present()) { + j.write_fieldname("crs-ChEstMPDCCH-ConfigDedicated-r16"); + crs_ch_est_mpdcch_cfg_ded_r16->to_json(j); + } + if (new_ue_id_r16_present) { + j.write_str("newUE-Identity-r16", new_ue_id_r16.to_string()); + } } j.end_obj(); } @@ -10287,6 +10853,45 @@ uint8_t cqi_report_cfg_scell_r15_s::alt_cqi_table_minus1024_qam_r15_opts::to_num return 0; } +// CQI-ReportPeriodicSCell-v1730 ::= SEQUENCE +SRSASN_CODE cqi_report_periodic_scell_v1730_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ri_cfg_idx2_dormant_r17_present, 1)); + + HANDLE_CODE(pack_integer(bref, cqi_pmi_cfg_idx2_dormant_r17, (uint16_t)0u, (uint16_t)1023u)); + if (ri_cfg_idx2_dormant_r17_present) { + HANDLE_CODE(pack_integer(bref, ri_cfg_idx2_dormant_r17, (uint16_t)0u, (uint16_t)1023u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE cqi_report_periodic_scell_v1730_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ri_cfg_idx2_dormant_r17_present, 1)); + + HANDLE_CODE(unpack_integer(cqi_pmi_cfg_idx2_dormant_r17, bref, (uint16_t)0u, (uint16_t)1023u)); + if (ri_cfg_idx2_dormant_r17_present) { + HANDLE_CODE(unpack_integer(ri_cfg_idx2_dormant_r17, bref, (uint16_t)0u, (uint16_t)1023u)); + } + + return SRSASN_SUCCESS; +} +void cqi_report_periodic_scell_v1730_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("cqi-pmi-ConfigIndex2Dormant-r17", cqi_pmi_cfg_idx2_dormant_r17); + if (ri_cfg_idx2_dormant_r17_present) { + j.write_int("ri-ConfigIndex2Dormant-r17", ri_cfg_idx2_dormant_r17); + } + j.end_obj(); +} +bool cqi_report_periodic_scell_v1730_s::operator==(const cqi_report_periodic_scell_v1730_s& other) const +{ + return cqi_pmi_cfg_idx2_dormant_r17 == other.cqi_pmi_cfg_idx2_dormant_r17 and + ri_cfg_idx2_dormant_r17_present == other.ri_cfg_idx2_dormant_r17_present and + (not ri_cfg_idx2_dormant_r17_present or ri_cfg_idx2_dormant_r17 == other.ri_cfg_idx2_dormant_r17); +} + // CQI-ShortConfigSCell-r15 ::= CHOICE void cqi_short_cfg_scell_r15_c::set(types::options e) { @@ -12098,6 +12703,10 @@ SRSASN_CODE phys_cfg_ded_scell_r10_s::pack(bit_ref& bref) const group_flags[7] |= semi_static_cfi_cfg_r15.is_present(); group_flags[7] |= blind_pdsch_repeat_cfg_r15.is_present(); group_flags[8] |= spucch_cfg_v1550.is_present(); + group_flags[9] |= srs_ul_cfg_ded_add_r16.is_present(); + group_flags[9] |= ul_pwr_ctrl_add_srs_r16.is_present(); + group_flags[9] |= srs_virtual_cell_id_r16.is_present(); + group_flags[9] |= wideband_prg_r16.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -12362,6 +12971,26 @@ SRSASN_CODE phys_cfg_ded_scell_r10_s::pack(bit_ref& bref) const HANDLE_CODE(spucch_cfg_v1550->pack(bref)); } } + if (group_flags[9]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(srs_ul_cfg_ded_add_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(ul_pwr_ctrl_add_srs_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(srs_virtual_cell_id_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(wideband_prg_r16.is_present(), 1)); + if (srs_ul_cfg_ded_add_r16.is_present()) { + HANDLE_CODE(srs_ul_cfg_ded_add_r16->pack(bref)); + } + if (ul_pwr_ctrl_add_srs_r16.is_present()) { + HANDLE_CODE(ul_pwr_ctrl_add_srs_r16->pack(bref)); + } + if (srs_virtual_cell_id_r16.is_present()) { + HANDLE_CODE(srs_virtual_cell_id_r16->pack(bref)); + } + if (wideband_prg_r16.is_present()) { + HANDLE_CODE(wideband_prg_r16->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -12421,7 +13050,7 @@ SRSASN_CODE phys_cfg_ded_scell_r10_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(9); + ext_groups_unpacker_guard group_flags(10); group_flags.unpack(bref); if (group_flags[0]) { @@ -12796,6 +13425,34 @@ SRSASN_CODE phys_cfg_ded_scell_r10_s::unpack(cbit_ref& bref) HANDLE_CODE(spucch_cfg_v1550->unpack(bref)); } } + if (group_flags[9]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool srs_ul_cfg_ded_add_r16_present; + HANDLE_CODE(bref.unpack(srs_ul_cfg_ded_add_r16_present, 1)); + srs_ul_cfg_ded_add_r16.set_present(srs_ul_cfg_ded_add_r16_present); + bool ul_pwr_ctrl_add_srs_r16_present; + HANDLE_CODE(bref.unpack(ul_pwr_ctrl_add_srs_r16_present, 1)); + ul_pwr_ctrl_add_srs_r16.set_present(ul_pwr_ctrl_add_srs_r16_present); + bool srs_virtual_cell_id_r16_present; + HANDLE_CODE(bref.unpack(srs_virtual_cell_id_r16_present, 1)); + srs_virtual_cell_id_r16.set_present(srs_virtual_cell_id_r16_present); + bool wideband_prg_r16_present; + HANDLE_CODE(bref.unpack(wideband_prg_r16_present, 1)); + wideband_prg_r16.set_present(wideband_prg_r16_present); + if (srs_ul_cfg_ded_add_r16.is_present()) { + HANDLE_CODE(srs_ul_cfg_ded_add_r16->unpack(bref)); + } + if (ul_pwr_ctrl_add_srs_r16.is_present()) { + HANDLE_CODE(ul_pwr_ctrl_add_srs_r16->unpack(bref)); + } + if (srs_virtual_cell_id_r16.is_present()) { + HANDLE_CODE(srs_virtual_cell_id_r16->unpack(bref)); + } + if (wideband_prg_r16.is_present()) { + HANDLE_CODE(wideband_prg_r16->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -13113,6 +13770,22 @@ void phys_cfg_ded_scell_r10_s::to_json(json_writer& j) const j.write_fieldname("spucch-Config-v1550"); spucch_cfg_v1550->to_json(j); } + if (srs_ul_cfg_ded_add_r16.is_present()) { + j.write_fieldname("soundingRS-UL-ConfigDedicatedAdd-r16"); + srs_ul_cfg_ded_add_r16->to_json(j); + } + if (ul_pwr_ctrl_add_srs_r16.is_present()) { + j.write_fieldname("uplinkPowerControlAddSRS-r16"); + ul_pwr_ctrl_add_srs_r16->to_json(j); + } + if (srs_virtual_cell_id_r16.is_present()) { + j.write_fieldname("soundingRS-VirtualCellID-r16"); + srs_virtual_cell_id_r16->to_json(j); + } + if (wideband_prg_r16.is_present()) { + j.write_fieldname("widebandPRG-r16"); + wideband_prg_r16->to_json(j); + } } j.end_obj(); } @@ -13293,7 +13966,15 @@ bool phys_cfg_ded_scell_r10_s::operator==(const phys_cfg_ded_scell_r10_s& other) (not blind_pdsch_repeat_cfg_r15.is_present() or *blind_pdsch_repeat_cfg_r15 == *other.blind_pdsch_repeat_cfg_r15) and spucch_cfg_v1550.is_present() == other.spucch_cfg_v1550.is_present() and - (not spucch_cfg_v1550.is_present() or *spucch_cfg_v1550 == *other.spucch_cfg_v1550))); + (not spucch_cfg_v1550.is_present() or *spucch_cfg_v1550 == *other.spucch_cfg_v1550) and + srs_ul_cfg_ded_add_r16.is_present() == other.srs_ul_cfg_ded_add_r16.is_present() and + (not srs_ul_cfg_ded_add_r16.is_present() or *srs_ul_cfg_ded_add_r16 == *other.srs_ul_cfg_ded_add_r16) and + ul_pwr_ctrl_add_srs_r16.is_present() == other.ul_pwr_ctrl_add_srs_r16.is_present() and + (not ul_pwr_ctrl_add_srs_r16.is_present() or *ul_pwr_ctrl_add_srs_r16 == *other.ul_pwr_ctrl_add_srs_r16) and + srs_virtual_cell_id_r16.is_present() == other.srs_virtual_cell_id_r16.is_present() and + (not srs_virtual_cell_id_r16.is_present() or *srs_virtual_cell_id_r16 == *other.srs_virtual_cell_id_r16) and + wideband_prg_r16.is_present() == other.wideband_prg_r16.is_present() and + (not wideband_prg_r16.is_present() or *wideband_prg_r16 == *other.wideband_prg_r16))); } void phys_cfg_ded_scell_r10_s::pucch_scell_c_::set(types::options e) @@ -14171,6 +14852,31 @@ bool phys_cfg_ded_scell_v1370_s::pucch_scell_v1370_c_::operator==(const pucch_sc (not c.pucch_cfg_ded_v1370_present or c.pucch_cfg_ded_v1370 == other.c.pucch_cfg_ded_v1370); } +// PhysicalConfigDedicatedSCell-v1730 ::= SEQUENCE +SRSASN_CODE phys_cfg_ded_scell_v1730_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(cqi_report_periodic_scell_v1730.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE phys_cfg_ded_scell_v1730_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(cqi_report_periodic_scell_v1730.unpack(bref)); + + return SRSASN_SUCCESS; +} +void phys_cfg_ded_scell_v1730_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("cqi-ReportPeriodicSCell-v1730"); + cqi_report_periodic_scell_v1730.to_json(j); + j.end_obj(); +} +bool phys_cfg_ded_scell_v1730_s::operator==(const phys_cfg_ded_scell_v1730_s& other) const +{ + return cqi_report_periodic_scell_v1730 == other.cqi_report_periodic_scell_v1730; +} + // AntennaInfoDedicated-v10i0 ::= SEQUENCE SRSASN_CODE ant_info_ded_v10i0_s::pack(bit_ref& bref) const { @@ -14236,6 +14942,7 @@ SRSASN_CODE rr_cfg_ded_scell_r10_s::pack(bit_ref& bref) const group_flags[4] |= crs_intf_mitig_enabled_r15_present; group_flags[4] |= neigh_cells_crs_info_r15.is_present(); group_flags[4] |= sps_cfg_v1530.is_present(); + group_flags[5] |= phys_cfg_ded_scell_v1730.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -14286,6 +14993,14 @@ SRSASN_CODE rr_cfg_ded_scell_r10_s::pack(bit_ref& bref) const HANDLE_CODE(sps_cfg_v1530->pack(bref)); } } + if (group_flags[5]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(phys_cfg_ded_scell_v1730.is_present(), 1)); + if (phys_cfg_ded_scell_v1730.is_present()) { + HANDLE_CODE(phys_cfg_ded_scell_v1730->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -14299,7 +15014,7 @@ SRSASN_CODE rr_cfg_ded_scell_r10_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(5); + ext_groups_unpacker_guard group_flags(6); group_flags.unpack(bref); if (group_flags[0]) { @@ -14362,6 +15077,16 @@ SRSASN_CODE rr_cfg_ded_scell_r10_s::unpack(cbit_ref& bref) HANDLE_CODE(sps_cfg_v1530->unpack(bref)); } } + if (group_flags[5]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool phys_cfg_ded_scell_v1730_present; + HANDLE_CODE(bref.unpack(phys_cfg_ded_scell_v1730_present, 1)); + phys_cfg_ded_scell_v1730.set_present(phys_cfg_ded_scell_v1730_present); + if (phys_cfg_ded_scell_v1730.is_present()) { + HANDLE_CODE(phys_cfg_ded_scell_v1730->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -14400,6 +15125,10 @@ void rr_cfg_ded_scell_r10_s::to_json(json_writer& j) const j.write_fieldname("sps-Config-v1530"); sps_cfg_v1530->to_json(j); } + if (phys_cfg_ded_scell_v1730.is_present()) { + j.write_fieldname("physicalConfigDedicatedSCell-v1730"); + phys_cfg_ded_scell_v1730->to_json(j); + } } j.end_obj(); } @@ -14425,7 +15154,10 @@ bool rr_cfg_ded_scell_r10_s::operator==(const rr_cfg_ded_scell_r10_s& other) con (not neigh_cells_crs_info_r15.is_present() or *neigh_cells_crs_info_r15 == *other.neigh_cells_crs_info_r15) and sps_cfg_v1530.is_present() == other.sps_cfg_v1530.is_present() and - (not sps_cfg_v1530.is_present() or *sps_cfg_v1530 == *other.sps_cfg_v1530))); + (not sps_cfg_v1530.is_present() or *sps_cfg_v1530 == *other.sps_cfg_v1530) and + phys_cfg_ded_scell_v1730.is_present() == other.phys_cfg_ded_scell_v1730.is_present() and + (not phys_cfg_ded_scell_v1730.is_present() or + *phys_cfg_ded_scell_v1730 == *other.phys_cfg_ded_scell_v1730))); } // SCellToAddModExt-r13 ::= SEQUENCE diff --git a/lib/src/asn1/rrc/security.cc b/lib/src/asn1/rrc/security.cc index ce556ccd71..d8bc17d0ce 100644 --- a/lib/src/asn1/rrc/security.cc +++ b/lib/src/asn1/rrc/security.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -89,14 +89,14 @@ void security_cfg_ho_v1530_s::to_json(json_writer& j) const void security_cfg_ho_v1530_s::handov_type_v1530_c_::destroy_() { switch (type_) { - case types::intra5_gc_r15: - c.destroy(); + case types::intra5_gc: + c.destroy(); break; - case types::fivegc_to_epc_r15: - c.destroy(); + case types::fivegc_to_epc: + c.destroy(); break; - case types::epc_to5_gc_r15: - c.destroy(); + case types::epc_to5_gc: + c.destroy(); break; default: break; @@ -107,14 +107,14 @@ void security_cfg_ho_v1530_s::handov_type_v1530_c_::set(types::options e) destroy_(); type_ = e; switch (type_) { - case types::intra5_gc_r15: - c.init(); + case types::intra5_gc: + c.init(); break; - case types::fivegc_to_epc_r15: - c.init(); + case types::fivegc_to_epc: + c.init(); break; - case types::epc_to5_gc_r15: - c.init(); + case types::epc_to5_gc: + c.init(); break; case types::nulltype: break; @@ -127,14 +127,14 @@ security_cfg_ho_v1530_s::handov_type_v1530_c_::handov_type_v1530_c_( { type_ = other.type(); switch (type_) { - case types::intra5_gc_r15: - c.init(other.c.get()); + case types::intra5_gc: + c.init(other.c.get()); break; - case types::fivegc_to_epc_r15: - c.init(other.c.get()); + case types::fivegc_to_epc: + c.init(other.c.get()); break; - case types::epc_to5_gc_r15: - c.init(other.c.get()); + case types::epc_to5_gc: + c.init(other.c.get()); break; case types::nulltype: break; @@ -150,14 +150,14 @@ security_cfg_ho_v1530_s::handov_type_v1530_c_::operator=(const security_cfg_ho_v } set(other.type()); switch (type_) { - case types::intra5_gc_r15: - c.set(other.c.get()); + case types::intra5_gc: + c.set(other.c.get()); break; - case types::fivegc_to_epc_r15: - c.set(other.c.get()); + case types::fivegc_to_epc: + c.set(other.c.get()); break; - case types::epc_to5_gc_r15: - c.set(other.c.get()); + case types::epc_to5_gc: + c.set(other.c.get()); break; case types::nulltype: break; @@ -167,56 +167,56 @@ security_cfg_ho_v1530_s::handov_type_v1530_c_::operator=(const security_cfg_ho_v return *this; } -security_cfg_ho_v1530_s::handov_type_v1530_c_::intra5_gc_r15_s_& -security_cfg_ho_v1530_s::handov_type_v1530_c_::set_intra5_gc_r15() +security_cfg_ho_v1530_s::handov_type_v1530_c_::intra5_gc_s_& +security_cfg_ho_v1530_s::handov_type_v1530_c_::set_intra5_gc() { - set(types::intra5_gc_r15); - return c.get(); + set(types::intra5_gc); + return c.get(); } -security_cfg_ho_v1530_s::handov_type_v1530_c_::fivegc_to_epc_r15_s_& -security_cfg_ho_v1530_s::handov_type_v1530_c_::set_fivegc_to_epc_r15() +security_cfg_ho_v1530_s::handov_type_v1530_c_::fivegc_to_epc_s_& +security_cfg_ho_v1530_s::handov_type_v1530_c_::set_fivegc_to_epc() { - set(types::fivegc_to_epc_r15); - return c.get(); + set(types::fivegc_to_epc); + return c.get(); } -security_cfg_ho_v1530_s::handov_type_v1530_c_::epc_to5_gc_r15_s_& -security_cfg_ho_v1530_s::handov_type_v1530_c_::set_epc_to5_gc_r15() +security_cfg_ho_v1530_s::handov_type_v1530_c_::epc_to5_gc_s_& +security_cfg_ho_v1530_s::handov_type_v1530_c_::set_epc_to5_gc() { - set(types::epc_to5_gc_r15); - return c.get(); + set(types::epc_to5_gc); + return c.get(); } void security_cfg_ho_v1530_s::handov_type_v1530_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::intra5_gc_r15: - j.write_fieldname("intra5GC-r15"); + case types::intra5_gc: + j.write_fieldname("intra5GC"); j.start_obj(); - if (c.get().security_algorithm_cfg_r15_present) { + if (c.get().security_algorithm_cfg_r15_present) { j.write_fieldname("securityAlgorithmConfig-r15"); - c.get().security_algorithm_cfg_r15.to_json(j); + c.get().security_algorithm_cfg_r15.to_json(j); } - j.write_bool("keyChangeIndicator-r15", c.get().key_change_ind_r15); - j.write_int("nextHopChainingCount-r15", c.get().next_hop_chaining_count_r15); - if (c.get().nas_container_r15_present) { - j.write_str("nas-Container-r15", c.get().nas_container_r15.to_string()); + j.write_bool("keyChangeIndicator-r15", c.get().key_change_ind_r15); + j.write_int("nextHopChainingCount-r15", c.get().next_hop_chaining_count_r15); + if (c.get().nas_container_r15_present) { + j.write_str("nas-Container-r15", c.get().nas_container_r15.to_string()); } j.end_obj(); break; - case types::fivegc_to_epc_r15: - j.write_fieldname("fivegc-ToEPC-r15"); + case types::fivegc_to_epc: + j.write_fieldname("fivegc-ToEPC"); j.start_obj(); j.write_fieldname("securityAlgorithmConfig-r15"); - c.get().security_algorithm_cfg_r15.to_json(j); - j.write_int("nextHopChainingCount-r15", c.get().next_hop_chaining_count_r15); + c.get().security_algorithm_cfg_r15.to_json(j); + j.write_int("nextHopChainingCount-r15", c.get().next_hop_chaining_count_r15); j.end_obj(); break; - case types::epc_to5_gc_r15: - j.write_fieldname("epc-To5GC-r15"); + case types::epc_to5_gc: + j.write_fieldname("epc-To5GC"); j.start_obj(); j.write_fieldname("securityAlgorithmConfig-r15"); - c.get().security_algorithm_cfg_r15.to_json(j); - j.write_str("nas-Container-r15", c.get().nas_container_r15.to_string()); + c.get().security_algorithm_cfg_r15.to_json(j); + j.write_str("nas-Container-r15", c.get().nas_container_r15.to_string()); j.end_obj(); break; default: @@ -228,26 +228,25 @@ SRSASN_CODE security_cfg_ho_v1530_s::handov_type_v1530_c_::pack(bit_ref& bref) c { type_.pack(bref); switch (type_) { - case types::intra5_gc_r15: - HANDLE_CODE(bref.pack(c.get().security_algorithm_cfg_r15_present, 1)); - HANDLE_CODE(bref.pack(c.get().nas_container_r15_present, 1)); - if (c.get().security_algorithm_cfg_r15_present) { - HANDLE_CODE(c.get().security_algorithm_cfg_r15.pack(bref)); + case types::intra5_gc: + HANDLE_CODE(bref.pack(c.get().security_algorithm_cfg_r15_present, 1)); + HANDLE_CODE(bref.pack(c.get().nas_container_r15_present, 1)); + if (c.get().security_algorithm_cfg_r15_present) { + HANDLE_CODE(c.get().security_algorithm_cfg_r15.pack(bref)); } - HANDLE_CODE(bref.pack(c.get().key_change_ind_r15, 1)); - HANDLE_CODE(pack_integer(bref, c.get().next_hop_chaining_count_r15, (uint8_t)0u, (uint8_t)7u)); - if (c.get().nas_container_r15_present) { - HANDLE_CODE(c.get().nas_container_r15.pack(bref)); + HANDLE_CODE(bref.pack(c.get().key_change_ind_r15, 1)); + HANDLE_CODE(pack_integer(bref, c.get().next_hop_chaining_count_r15, (uint8_t)0u, (uint8_t)7u)); + if (c.get().nas_container_r15_present) { + HANDLE_CODE(c.get().nas_container_r15.pack(bref)); } break; - case types::fivegc_to_epc_r15: - HANDLE_CODE(c.get().security_algorithm_cfg_r15.pack(bref)); - HANDLE_CODE( - pack_integer(bref, c.get().next_hop_chaining_count_r15, (uint8_t)0u, (uint8_t)7u)); + case types::fivegc_to_epc: + HANDLE_CODE(c.get().security_algorithm_cfg_r15.pack(bref)); + HANDLE_CODE(pack_integer(bref, c.get().next_hop_chaining_count_r15, (uint8_t)0u, (uint8_t)7u)); break; - case types::epc_to5_gc_r15: - HANDLE_CODE(c.get().security_algorithm_cfg_r15.pack(bref)); - HANDLE_CODE(c.get().nas_container_r15.pack(bref)); + case types::epc_to5_gc: + HANDLE_CODE(c.get().security_algorithm_cfg_r15.pack(bref)); + HANDLE_CODE(c.get().nas_container_r15.pack(bref)); break; default: log_invalid_choice_id(type_, "security_cfg_ho_v1530_s::handov_type_v1530_c_"); @@ -261,27 +260,26 @@ SRSASN_CODE security_cfg_ho_v1530_s::handov_type_v1530_c_::unpack(cbit_ref& bref e.unpack(bref); set(e); switch (type_) { - case types::intra5_gc_r15: - HANDLE_CODE(bref.unpack(c.get().security_algorithm_cfg_r15_present, 1)); - HANDLE_CODE(bref.unpack(c.get().nas_container_r15_present, 1)); - if (c.get().security_algorithm_cfg_r15_present) { - HANDLE_CODE(c.get().security_algorithm_cfg_r15.unpack(bref)); + case types::intra5_gc: + HANDLE_CODE(bref.unpack(c.get().security_algorithm_cfg_r15_present, 1)); + HANDLE_CODE(bref.unpack(c.get().nas_container_r15_present, 1)); + if (c.get().security_algorithm_cfg_r15_present) { + HANDLE_CODE(c.get().security_algorithm_cfg_r15.unpack(bref)); } - HANDLE_CODE(bref.unpack(c.get().key_change_ind_r15, 1)); - HANDLE_CODE( - unpack_integer(c.get().next_hop_chaining_count_r15, bref, (uint8_t)0u, (uint8_t)7u)); - if (c.get().nas_container_r15_present) { - HANDLE_CODE(c.get().nas_container_r15.unpack(bref)); + HANDLE_CODE(bref.unpack(c.get().key_change_ind_r15, 1)); + HANDLE_CODE(unpack_integer(c.get().next_hop_chaining_count_r15, bref, (uint8_t)0u, (uint8_t)7u)); + if (c.get().nas_container_r15_present) { + HANDLE_CODE(c.get().nas_container_r15.unpack(bref)); } break; - case types::fivegc_to_epc_r15: - HANDLE_CODE(c.get().security_algorithm_cfg_r15.unpack(bref)); + case types::fivegc_to_epc: + HANDLE_CODE(c.get().security_algorithm_cfg_r15.unpack(bref)); HANDLE_CODE( - unpack_integer(c.get().next_hop_chaining_count_r15, bref, (uint8_t)0u, (uint8_t)7u)); + unpack_integer(c.get().next_hop_chaining_count_r15, bref, (uint8_t)0u, (uint8_t)7u)); break; - case types::epc_to5_gc_r15: - HANDLE_CODE(c.get().security_algorithm_cfg_r15.unpack(bref)); - HANDLE_CODE(c.get().nas_container_r15.unpack(bref)); + case types::epc_to5_gc: + HANDLE_CODE(c.get().security_algorithm_cfg_r15.unpack(bref)); + HANDLE_CODE(c.get().nas_container_r15.unpack(bref)); break; default: log_invalid_choice_id(type_, "security_cfg_ho_v1530_s::handov_type_v1530_c_"); diff --git a/lib/src/asn1/rrc/si.cc b/lib/src/asn1/rrc/si.cc index 0ccdce4dc1..0bdab9ac18 100644 --- a/lib/src/asn1/rrc/si.cc +++ b/lib/src/asn1/rrc/si.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -37,6 +37,7 @@ SRSASN_CODE mib_s::pack(bit_ref& bref) const HANDLE_CODE(sys_frame_num.pack(bref)); HANDLE_CODE(pack_integer(bref, sched_info_sib1_br_r13, (uint8_t)0u, (uint8_t)31u)); HANDLE_CODE(bref.pack(sys_info_unchanged_br_r15, 1)); + HANDLE_CODE(part_earfcn_minus17.pack(bref)); HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; @@ -48,6 +49,7 @@ SRSASN_CODE mib_s::unpack(cbit_ref& bref) HANDLE_CODE(sys_frame_num.unpack(bref)); HANDLE_CODE(unpack_integer(sched_info_sib1_br_r13, bref, (uint8_t)0u, (uint8_t)31u)); HANDLE_CODE(bref.unpack(sys_info_unchanged_br_r15, 1)); + HANDLE_CODE(part_earfcn_minus17.unpack(bref)); HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; @@ -61,6 +63,8 @@ void mib_s::to_json(json_writer& j) const j.write_str("systemFrameNumber", sys_frame_num.to_string()); j.write_int("schedulingInfoSIB1-BR-r13", sched_info_sib1_br_r13); j.write_bool("systemInfoUnchanged-BR-r15", sys_info_unchanged_br_r15); + j.write_fieldname("partEARFCN-17"); + part_earfcn_minus17.to_json(j); j.write_str("spare", spare.to_string()); j.end_obj(); } @@ -76,6 +80,133 @@ uint8_t mib_s::dl_bw_opts::to_number() const return map_enum_number(options, 6, value, "mib_s::dl_bw_e_"); } +void mib_s::part_earfcn_minus17_c_::destroy_() +{ + switch (type_) { + case types::spare: + c.destroy >(); + break; + case types::earfcn_lsb: + c.destroy >(); + break; + default: + break; + } +} +void mib_s::part_earfcn_minus17_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::spare: + c.init >(); + break; + case types::earfcn_lsb: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mib_s::part_earfcn_minus17_c_"); + } +} +mib_s::part_earfcn_minus17_c_::part_earfcn_minus17_c_(const mib_s::part_earfcn_minus17_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::spare: + c.init(other.c.get >()); + break; + case types::earfcn_lsb: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mib_s::part_earfcn_minus17_c_"); + } +} +mib_s::part_earfcn_minus17_c_& mib_s::part_earfcn_minus17_c_::operator=(const mib_s::part_earfcn_minus17_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::spare: + c.set(other.c.get >()); + break; + case types::earfcn_lsb: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mib_s::part_earfcn_minus17_c_"); + } + + return *this; +} +fixed_bitstring<2>& mib_s::part_earfcn_minus17_c_::set_spare() +{ + set(types::spare); + return c.get >(); +} +fixed_bitstring<2>& mib_s::part_earfcn_minus17_c_::set_earfcn_lsb() +{ + set(types::earfcn_lsb); + return c.get >(); +} +void mib_s::part_earfcn_minus17_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::spare: + j.write_str("spare", c.get >().to_string()); + break; + case types::earfcn_lsb: + j.write_str("earfcn-LSB", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "mib_s::part_earfcn_minus17_c_"); + } + j.end_obj(); +} +SRSASN_CODE mib_s::part_earfcn_minus17_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::spare: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::earfcn_lsb: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "mib_s::part_earfcn_minus17_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE mib_s::part_earfcn_minus17_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::spare: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::earfcn_lsb: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "mib_s::part_earfcn_minus17_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + // GNSS-ID-r15 ::= SEQUENCE SRSASN_CODE gnss_id_r15_s::pack(bit_ref& bref) const { @@ -100,8 +231,42 @@ void gnss_id_r15_s::to_json(json_writer& j) const const char* gnss_id_r15_s::gnss_id_r15_opts::to_string() const { - static const char* options[] = {"gps", "sbas", "qzss", "galileo", "glonass", "bds"}; - return convert_enum_idx(options, 6, value, "gnss_id_r15_s::gnss_id_r15_e_"); + static const char* options[] = {"gps", "sbas", "qzss", "galileo", "glonass", "bds", "navic-v1610"}; + return convert_enum_idx(options, 7, value, "gnss_id_r15_s::gnss_id_r15_e_"); +} + +// PLMN-IdentityInfo-v1700 ::= SEQUENCE +SRSASN_CODE plmn_id_info_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(tracking_area_list_r17_present, 1)); + + if (tracking_area_list_r17_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, tracking_area_list_r17, 1, 12)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE plmn_id_info_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(tracking_area_list_r17_present, 1)); + + if (tracking_area_list_r17_present) { + HANDLE_CODE(unpack_dyn_seq_of(tracking_area_list_r17, bref, 1, 12)); + } + + return SRSASN_SUCCESS; +} +void plmn_id_info_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (tracking_area_list_r17_present) { + j.start_array("trackingAreaList-r17"); + for (const auto& e1 : tracking_area_list_r17) { + j.write_str(e1.to_string()); + } + j.end_array(); + } + j.end_obj(); } // SBAS-ID-r15 ::= SEQUENCE @@ -132,6 +297,38 @@ const char* sbas_id_r15_s::sbas_id_r15_opts::to_string() const return convert_enum_idx(options, 4, value, "sbas_id_r15_s::sbas_id_r15_e_"); } +// PLMN-IdentityInfo-v1610 ::= SEQUENCE +SRSASN_CODE plmn_id_info_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(cp_cio_t_minus5_gs_optim_r16_present, 1)); + HANDLE_CODE(bref.pack(up_cio_t_minus5_gs_optim_r16_present, 1)); + HANDLE_CODE(bref.pack(iab_support_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE plmn_id_info_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(cp_cio_t_minus5_gs_optim_r16_present, 1)); + HANDLE_CODE(bref.unpack(up_cio_t_minus5_gs_optim_r16_present, 1)); + HANDLE_CODE(bref.unpack(iab_support_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void plmn_id_info_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (cp_cio_t_minus5_gs_optim_r16_present) { + j.write_str("cp-CIoT-5GS-Optimisation-r16", "true"); + } + if (up_cio_t_minus5_gs_optim_r16_present) { + j.write_str("up-CIoT-5GS-Optimisation-r16", "true"); + } + if (iab_support_r16_present) { + j.write_str("iab-Support-r16", "true"); + } + j.end_obj(); +} + // PosSIB-Type-r15 ::= SEQUENCE SRSASN_CODE pos_sib_type_r15_s::pack(bit_ref& bref) const { @@ -188,12 +385,79 @@ void pos_sib_type_r15_s::to_json(json_writer& j) const const char* pos_sib_type_r15_s::pos_sib_type_r15_opts::to_string() const { static const char* options[] = { - "posSibType1-1", "posSibType1-2", "posSibType1-3", "posSibType1-4", "posSibType1-5", "posSibType1-6", - "posSibType1-7", "posSibType2-1", "posSibType2-2", "posSibType2-3", "posSibType2-4", "posSibType2-5", - "posSibType2-6", "posSibType2-7", "posSibType2-8", "posSibType2-9", "posSibType2-10", "posSibType2-11", - "posSibType2-12", "posSibType2-13", "posSibType2-14", "posSibType2-15", "posSibType2-16", "posSibType2-17", - "posSibType2-18", "posSibType2-19", "posSibType3-1"}; - return convert_enum_idx(options, 27, value, "pos_sib_type_r15_s::pos_sib_type_r15_e_"); + "posSibType1-1", "posSibType1-2", "posSibType1-3", "posSibType1-4", + "posSibType1-5", "posSibType1-6", "posSibType1-7", "posSibType2-1", + "posSibType2-2", "posSibType2-3", "posSibType2-4", "posSibType2-5", + "posSibType2-6", "posSibType2-7", "posSibType2-8", "posSibType2-9", + "posSibType2-10", "posSibType2-11", "posSibType2-12", "posSibType2-13", + "posSibType2-14", "posSibType2-15", "posSibType2-16", "posSibType2-17", + "posSibType2-18", "posSibType2-19", "posSibType3-1", "posSibType1-8-v1610", + "posSibType2-20-v1610", "posSibType2-21-v1610", "posSibType2-22-v1610", "posSibType2-23-v1610", + "posSibType2-24-v1610", "posSibType2-25-v1610", "posSibType4-1-v1610", "posSibType5-1-v1610", + "posSibType1-9-v1700", "posSibType1-10-v1700"}; + return convert_enum_idx(options, 38, value, "pos_sib_type_r15_s::pos_sib_type_r15_e_"); +} + +// SystemInformationBlockType1-v1700-IEs ::= SEQUENCE +SRSASN_CODE sib_type1_v1700_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(cell_access_related_info_ntn_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (cell_access_related_info_ntn_r17_present) { + HANDLE_CODE(bref.pack(cell_access_related_info_ntn_r17.plmn_id_list_v1700_present, 1)); + HANDLE_CODE(cell_access_related_info_ntn_r17.cell_barred_ntn_r17.pack(bref)); + if (cell_access_related_info_ntn_r17.plmn_id_list_v1700_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, cell_access_related_info_ntn_r17.plmn_id_list_v1700, 1, 6)); + } + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type1_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(cell_access_related_info_ntn_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (cell_access_related_info_ntn_r17_present) { + HANDLE_CODE(bref.unpack(cell_access_related_info_ntn_r17.plmn_id_list_v1700_present, 1)); + HANDLE_CODE(cell_access_related_info_ntn_r17.cell_barred_ntn_r17.unpack(bref)); + if (cell_access_related_info_ntn_r17.plmn_id_list_v1700_present) { + HANDLE_CODE(unpack_dyn_seq_of(cell_access_related_info_ntn_r17.plmn_id_list_v1700, bref, 1, 6)); + } + } + + return SRSASN_SUCCESS; +} +void sib_type1_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (cell_access_related_info_ntn_r17_present) { + j.write_fieldname("cellAccessRelatedInfo-NTN-r17"); + j.start_obj(); + j.write_str("cellBarred-NTN-r17", cell_access_related_info_ntn_r17.cell_barred_ntn_r17.to_string()); + if (cell_access_related_info_ntn_r17.plmn_id_list_v1700_present) { + j.start_array("plmn-IdentityList-v1700"); + for (const auto& e1 : cell_access_related_info_ntn_r17.plmn_id_list_v1700) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +const char* sib_type1_v1700_ies_s::cell_access_related_info_ntn_r17_s_::cell_barred_ntn_r17_opts::to_string() const +{ + static const char* options[] = {"barred", "notBarred"}; + return convert_enum_idx( + options, 2, value, "sib_type1_v1700_ies_s::cell_access_related_info_ntn_r17_s_::cell_barred_ntn_r17_e_"); } // PLMN-IdentityInfo-v1530 ::= SEQUENCE @@ -260,6 +524,67 @@ uint16_t pos_sched_info_r15_s::pos_si_periodicity_r15_opts::to_number() const return map_enum_number(options, 7, value, "pos_sched_info_r15_s::pos_si_periodicity_r15_e_"); } +// SystemInformationBlockType1-v1610-IEs ::= SEQUENCE +SRSASN_CODE sib_type1_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(edrx_allowed_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(tx_in_ctrl_ch_region_r16_present, 1)); + HANDLE_CODE(bref.pack(camping_allowed_in_ce_r16_present, 1)); + HANDLE_CODE(bref.pack(plmn_id_list_v1610_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (plmn_id_list_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, plmn_id_list_v1610, 1, 6)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type1_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(edrx_allowed_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(tx_in_ctrl_ch_region_r16_present, 1)); + HANDLE_CODE(bref.unpack(camping_allowed_in_ce_r16_present, 1)); + HANDLE_CODE(bref.unpack(plmn_id_list_v1610_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (plmn_id_list_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(plmn_id_list_v1610, bref, 1, 6)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type1_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (edrx_allowed_minus5_gc_r16_present) { + j.write_str("eDRX-Allowed-5GC-r16", "true"); + } + if (tx_in_ctrl_ch_region_r16_present) { + j.write_str("transmissionInControlChRegion-r16", "true"); + } + if (camping_allowed_in_ce_r16_present) { + j.write_str("campingAllowedInCE-r16", "true"); + } + if (plmn_id_list_v1610_present) { + j.start_array("plmn-IdentityList-v1610"); + for (const auto& e1 : plmn_id_list_v1610) { + e1.to_json(j); + } + j.end_array(); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + // CellSelectionInfoCE-v1530 ::= SEQUENCE SRSASN_CODE cell_sel_info_ce_v1530_s::pack(bit_ref& bref) const { @@ -297,6 +622,10 @@ SRSASN_CODE sib_type1_v1540_ies_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(si_pos_offset_r15_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + return SRSASN_SUCCESS; } SRSASN_CODE sib_type1_v1540_ies_s::unpack(cbit_ref& bref) @@ -304,6 +633,10 @@ SRSASN_CODE sib_type1_v1540_ies_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(si_pos_offset_r15_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + return SRSASN_SUCCESS; } void sib_type1_v1540_ies_s::to_json(json_writer& j) const @@ -314,8 +647,7 @@ void sib_type1_v1540_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -2052,16 +2384,12 @@ void plmn_info_r15_s::to_json(json_writer& j) const const char* sib_type_opts::to_string() const { static const char* options[] = { - "sibType3", "sibType4", "sibType5", "sibType6", "sibType7", "sibType8", - "sibType9", "sibType10", "sibType11", "sibType12-v920", "sibType13-v920", "sibType14-v1130", - "sibType15-v1130", "sibType16-v1130", "sibType17-v1250", "sibType18-v1250", "sibType19-v1250", "sibType20-v1310", - "sibType21-v1430", "sibType24-v1530", "sibType25-v1530", "sibType26-v1530"}; - return convert_enum_idx(options, 22, value, "sib_type_e"); -} -uint8_t sib_type_opts::to_number() const -{ - static const uint8_t options[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 24, 25, 26}; - return map_enum_number(options, 22, value, "sib_type_e"); + "sibType3", "sibType4", "sibType5", "sibType6", "sibType7", "sibType8", + "sibType9", "sibType10", "sibType11", "sibType12-v920", "sibType13-v920", "sibType14-v1130", + "sibType15-v1130", "sibType16-v1130", "sibType17-v1250", "sibType18-v1250", "sibType19-v1250", "sibType20-v1310", + "sibType21-v1430", "sibType24-v1530", "sibType25-v1530", "sibType26-v1530", "sibType26a-v1610", "sibType27-v1610", + "sibType28-v1610", "sibType29-v1610"}; + return convert_enum_idx(options, 26, value, "sib_type_e"); } // SystemInformationBlockType1-v1250-IEs ::= SEQUENCE @@ -2647,6 +2975,17 @@ SRSASN_CODE sib_type2_s::pack(bit_ref& bref) const group_flags[10] |= idle_mode_meass_r15_present; group_flags[10] |= reduced_cp_latency_enabled_r15_present; group_flags[11] |= mbms_rom_service_ind_r15_present; + group_flags[12] |= rlos_enabled_r16_present; + group_flags[12] |= early_security_reactivation_r16_present; + group_flags[12] |= cp_edt_minus5_gc_r16_present; + group_flags[12] |= up_edt_minus5_gc_r16_present; + group_flags[12] |= cp_pur_epc_r16_present; + group_flags[12] |= up_pur_epc_r16_present; + group_flags[12] |= cp_pur_minus5_gc_r16_present; + group_flags[12] |= up_pur_minus5_gc_r16_present; + group_flags[12] |= mpdcch_cqi_report_r16_present; + group_flags[12] |= rai_activation_enh_r16_present; + group_flags[12] |= idle_mode_meass_nr_r16_present; group_flags.pack(bref); if (group_flags[0]) { @@ -2754,6 +3093,24 @@ SRSASN_CODE sib_type2_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(mbms_rom_service_ind_r15_present, 1)); } + if (group_flags[12]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(rlos_enabled_r16_present, 1)); + HANDLE_CODE(bref.pack(early_security_reactivation_r16_present, 1)); + HANDLE_CODE(bref.pack(cp_edt_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(up_edt_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(cp_pur_epc_r16_present, 1)); + HANDLE_CODE(bref.pack(up_pur_epc_r16_present, 1)); + HANDLE_CODE(bref.pack(cp_pur_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(up_pur_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(mpdcch_cqi_report_r16_present, 1)); + HANDLE_CODE(bref.pack(rai_activation_enh_r16_present, 1)); + HANDLE_CODE(bref.pack(idle_mode_meass_nr_r16_present, 1)); + if (mpdcch_cqi_report_r16_present) { + HANDLE_CODE(mpdcch_cqi_report_r16.pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -2791,7 +3148,7 @@ SRSASN_CODE sib_type2_s::unpack(cbit_ref& bref) HANDLE_CODE(time_align_timer_common.unpack(bref)); if (ext) { - ext_groups_unpacker_guard group_flags(12); + ext_groups_unpacker_guard group_flags(13); group_flags.unpack(bref); if (group_flags[0]) { @@ -2921,6 +3278,24 @@ SRSASN_CODE sib_type2_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(mbms_rom_service_ind_r15_present, 1)); } + if (group_flags[12]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(rlos_enabled_r16_present, 1)); + HANDLE_CODE(bref.unpack(early_security_reactivation_r16_present, 1)); + HANDLE_CODE(bref.unpack(cp_edt_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(up_edt_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(cp_pur_epc_r16_present, 1)); + HANDLE_CODE(bref.unpack(up_pur_epc_r16_present, 1)); + HANDLE_CODE(bref.unpack(cp_pur_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(up_pur_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(mpdcch_cqi_report_r16_present, 1)); + HANDLE_CODE(bref.unpack(rai_activation_enh_r16_present, 1)); + HANDLE_CODE(bref.unpack(idle_mode_meass_nr_r16_present, 1)); + if (mpdcch_cqi_report_r16_present) { + HANDLE_CODE(mpdcch_cqi_report_r16.unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -3065,6 +3440,39 @@ void sib_type2_s::to_json(json_writer& j) const if (mbms_rom_service_ind_r15_present) { j.write_str("mbms-ROM-ServiceIndication-r15", "true"); } + if (rlos_enabled_r16_present) { + j.write_str("rlos-Enabled-r16", "true"); + } + if (early_security_reactivation_r16_present) { + j.write_str("earlySecurityReactivation-r16", "true"); + } + if (cp_edt_minus5_gc_r16_present) { + j.write_str("cp-EDT-5GC-r16", "true"); + } + if (up_edt_minus5_gc_r16_present) { + j.write_str("up-EDT-5GC-r16", "true"); + } + if (cp_pur_epc_r16_present) { + j.write_str("cp-PUR-EPC-r16", "true"); + } + if (up_pur_epc_r16_present) { + j.write_str("up-PUR-EPC-r16", "true"); + } + if (cp_pur_minus5_gc_r16_present) { + j.write_str("cp-PUR-5GC-r16", "true"); + } + if (up_pur_minus5_gc_r16_present) { + j.write_str("up-PUR-5GC-r16", "true"); + } + if (mpdcch_cqi_report_r16_present) { + j.write_str("mpdcch-CQI-Reporting-r16", mpdcch_cqi_report_r16.to_string()); + } + if (rai_activation_enh_r16_present) { + j.write_str("rai-ActivationEnh-r16", "true"); + } + if (idle_mode_meass_nr_r16_present) { + j.write_str("idleModeMeasurementsNR-r16", "true"); + } } j.end_obj(); } @@ -3080,6 +3488,17 @@ uint8_t sib_type2_s::freq_info_s_::ul_bw_opts::to_number() const return map_enum_number(options, 6, value, "sib_type2_s::freq_info_s_::ul_bw_e_"); } +const char* sib_type2_s::mpdcch_cqi_report_r16_opts::to_string() const +{ + static const char* options[] = {"fourBits", "both"}; + return convert_enum_idx(options, 2, value, "sib_type2_s::mpdcch_cqi_report_r16_e_"); +} +uint8_t sib_type2_s::mpdcch_cqi_report_r16_opts::to_number() const +{ + static const uint8_t options[] = {4}; + return map_enum_number(options, 1, value, "sib_type2_s::mpdcch_cqi_report_r16_e_"); +} + // SystemInformationBlockType1-v890-IEs ::= SEQUENCE SRSASN_CODE sib_type1_v890_ies_s::pack(bit_ref& bref) const { diff --git a/lib/src/asn1/rrc/uecap.cc b/lib/src/asn1/rrc/uecap.cc index 4718c554cc..7f7f5473a9 100644 --- a/lib/src/asn1/rrc/uecap.cc +++ b/lib/src/asn1/rrc/uecap.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,6 +29,71 @@ using namespace asn1::rrc; * Struct Methods ******************************************************************************/ +// UECapabilityEnquiry-v1710-IEs ::= SEQUENCE +SRSASN_CODE ue_cap_enquiry_v1710_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(sidelink_request_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_cap_enquiry_v1710_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(sidelink_request_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + return SRSASN_SUCCESS; +} +void ue_cap_enquiry_v1710_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (sidelink_request_r17_present) { + j.write_str("sidelinkRequest-r17", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// UECapabilityEnquiry-v1610-IEs ::= SEQUENCE +SRSASN_CODE ue_cap_enquiry_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(rrc_seg_allowed_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_cap_enquiry_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(rrc_seg_allowed_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_cap_enquiry_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (rrc_seg_allowed_r16_present) { + j.write_str("rrc-SegAllowed-r16", "enabled"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + // CA-BandwidthClass-r10 ::= ENUMERATED const char* ca_bw_class_r10_opts::to_string() const { @@ -45,6 +110,9 @@ SRSASN_CODE ue_cap_enquiry_v1560_ies_s::pack(bit_ref& bref) const if (requested_cap_common_r15_present) { HANDLE_CODE(requested_cap_common_r15.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -56,6 +124,9 @@ SRSASN_CODE ue_cap_enquiry_v1560_ies_s::unpack(cbit_ref& bref) if (requested_cap_common_r15_present) { HANDLE_CODE(requested_cap_common_r15.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -67,8 +138,7 @@ void ue_cap_enquiry_v1560_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -681,6 +751,12 @@ SRSASN_CODE ue_radio_paging_info_r12_s::pack(bit_ref& bref) const group_flags[1] |= wake_up_signal_tdd_r15_present; group_flags[1] |= wake_up_signal_min_gap_e_drx_r15_present; group_flags[1] |= wake_up_signal_min_gap_e_drx_tdd_r15_present; + group_flags[2] |= ue_category_dl_v1610_present; + group_flags[2] |= group_wake_up_signal_r16_present; + group_flags[2] |= group_wake_up_signal_tdd_r16_present; + group_flags[2] |= group_wake_up_signal_alternation_r16_present; + group_flags[2] |= group_wake_up_signal_alternation_tdd_r16_present; + group_flags[3] |= inactive_state_po_determination_r17_present; group_flags.pack(bref); if (group_flags[0]) { @@ -704,6 +780,20 @@ SRSASN_CODE ue_radio_paging_info_r12_s::pack(bit_ref& bref) const HANDLE_CODE(wake_up_signal_min_gap_e_drx_tdd_r15.pack(bref)); } } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ue_category_dl_v1610_present, 1)); + HANDLE_CODE(bref.pack(group_wake_up_signal_r16_present, 1)); + HANDLE_CODE(bref.pack(group_wake_up_signal_tdd_r16_present, 1)); + HANDLE_CODE(bref.pack(group_wake_up_signal_alternation_r16_present, 1)); + HANDLE_CODE(bref.pack(group_wake_up_signal_alternation_tdd_r16_present, 1)); + } + if (group_flags[3]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(inactive_state_po_determination_r17_present, 1)); + } } return SRSASN_SUCCESS; } @@ -717,7 +807,7 @@ SRSASN_CODE ue_radio_paging_info_r12_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(2); + ext_groups_unpacker_guard group_flags(4); group_flags.unpack(bref); if (group_flags[0]) { @@ -741,6 +831,20 @@ SRSASN_CODE ue_radio_paging_info_r12_s::unpack(cbit_ref& bref) HANDLE_CODE(wake_up_signal_min_gap_e_drx_tdd_r15.unpack(bref)); } } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(ue_category_dl_v1610_present, 1)); + HANDLE_CODE(bref.unpack(group_wake_up_signal_r16_present, 1)); + HANDLE_CODE(bref.unpack(group_wake_up_signal_tdd_r16_present, 1)); + HANDLE_CODE(bref.unpack(group_wake_up_signal_alternation_r16_present, 1)); + HANDLE_CODE(bref.unpack(group_wake_up_signal_alternation_tdd_r16_present, 1)); + } + if (group_flags[3]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(inactive_state_po_determination_r17_present, 1)); + } } return SRSASN_SUCCESS; } @@ -772,6 +876,24 @@ void ue_radio_paging_info_r12_s::to_json(json_writer& j) const if (wake_up_signal_min_gap_e_drx_tdd_r15_present) { j.write_str("wakeUpSignalMinGap-eDRX-TDD-r15", wake_up_signal_min_gap_e_drx_tdd_r15.to_string()); } + if (ue_category_dl_v1610_present) { + j.write_str("ue-CategoryDL-v1610", "m2"); + } + if (group_wake_up_signal_r16_present) { + j.write_str("groupWakeUpSignal-r16", "true"); + } + if (group_wake_up_signal_tdd_r16_present) { + j.write_str("groupWakeUpSignalTDD-r16", "true"); + } + if (group_wake_up_signal_alternation_r16_present) { + j.write_str("groupWakeUpSignalAlternation-r16", "true"); + } + if (group_wake_up_signal_alternation_tdd_r16_present) { + j.write_str("groupWakeUpSignalAlternationTDD-r16", "true"); + } + if (inactive_state_po_determination_r17_present) { + j.write_str("inactiveStatePO-Determination-r17", "true"); + } } j.end_obj(); } @@ -3908,6 +4030,348 @@ void band_combination_params_v1530_s::to_json(json_writer& j) const j.end_obj(); } +// InterRAT-BandInfoNR-r16 ::= SEQUENCE +SRSASN_CODE inter_rat_band_info_nr_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(inter_rat_need_for_gaps_nr_r16, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE inter_rat_band_info_nr_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(inter_rat_need_for_gaps_nr_r16, 1)); + + return SRSASN_SUCCESS; +} +void inter_rat_band_info_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_bool("interRAT-NeedForGapsNR-r16", inter_rat_need_for_gaps_nr_r16); + j.end_obj(); +} + +// SRS-CapabilityPerBandPair-v1610 ::= SEQUENCE +SRSASN_CODE srs_cap_per_band_pair_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(add_srs_carrier_switching_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE srs_cap_per_band_pair_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(add_srs_carrier_switching_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void srs_cap_per_band_pair_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (add_srs_carrier_switching_r16_present) { + j.write_str("addSRS-CarrierSwitching-r16", "supported"); + } + j.end_obj(); +} + +// BandParameters-v1610 ::= SEQUENCE +SRSASN_CODE band_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(intra_freq_daps_r16_present, 1)); + HANDLE_CODE(bref.pack(add_srs_freq_hop_r16_present, 1)); + HANDLE_CODE(bref.pack(add_srs_ant_switching_r16_present, 1)); + HANDLE_CODE(bref.pack(srs_cap_per_band_pair_list_v1610_present, 1)); + + if (intra_freq_daps_r16_present) { + HANDLE_CODE(bref.pack(intra_freq_daps_r16.intra_freq_async_daps_r16_present, 1)); + HANDLE_CODE(bref.pack(intra_freq_daps_r16.dummy_present, 1)); + HANDLE_CODE(bref.pack(intra_freq_daps_r16.intra_freq_two_tags_daps_r16_present, 1)); + } + if (add_srs_ant_switching_r16_present) { + HANDLE_CODE(bref.pack(add_srs_ant_switching_r16.add_srs_minus1_t2_r_r16_present, 1)); + HANDLE_CODE(bref.pack(add_srs_ant_switching_r16.add_srs_minus1_t4_r_r16_present, 1)); + HANDLE_CODE(bref.pack(add_srs_ant_switching_r16.add_srs_minus2_t4_r_minus2pairs_r16_present, 1)); + HANDLE_CODE(bref.pack(add_srs_ant_switching_r16.add_srs_minus2_t4_r_minus3pairs_r16_present, 1)); + } + if (srs_cap_per_band_pair_list_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, srs_cap_per_band_pair_list_v1610, 1, 64)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE band_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(intra_freq_daps_r16_present, 1)); + HANDLE_CODE(bref.unpack(add_srs_freq_hop_r16_present, 1)); + HANDLE_CODE(bref.unpack(add_srs_ant_switching_r16_present, 1)); + HANDLE_CODE(bref.unpack(srs_cap_per_band_pair_list_v1610_present, 1)); + + if (intra_freq_daps_r16_present) { + HANDLE_CODE(bref.unpack(intra_freq_daps_r16.intra_freq_async_daps_r16_present, 1)); + HANDLE_CODE(bref.unpack(intra_freq_daps_r16.dummy_present, 1)); + HANDLE_CODE(bref.unpack(intra_freq_daps_r16.intra_freq_two_tags_daps_r16_present, 1)); + } + if (add_srs_ant_switching_r16_present) { + HANDLE_CODE(bref.unpack(add_srs_ant_switching_r16.add_srs_minus1_t2_r_r16_present, 1)); + HANDLE_CODE(bref.unpack(add_srs_ant_switching_r16.add_srs_minus1_t4_r_r16_present, 1)); + HANDLE_CODE(bref.unpack(add_srs_ant_switching_r16.add_srs_minus2_t4_r_minus2pairs_r16_present, 1)); + HANDLE_CODE(bref.unpack(add_srs_ant_switching_r16.add_srs_minus2_t4_r_minus3pairs_r16_present, 1)); + } + if (srs_cap_per_band_pair_list_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(srs_cap_per_band_pair_list_v1610, bref, 1, 64)); + } + + return SRSASN_SUCCESS; +} +void band_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (intra_freq_daps_r16_present) { + j.write_fieldname("intraFreqDAPS-r16"); + j.start_obj(); + if (intra_freq_daps_r16.intra_freq_async_daps_r16_present) { + j.write_str("intraFreqAsyncDAPS-r16", "supported"); + } + if (intra_freq_daps_r16.dummy_present) { + j.write_str("dummy", "supported"); + } + if (intra_freq_daps_r16.intra_freq_two_tags_daps_r16_present) { + j.write_str("intraFreqTwoTAGs-DAPS-r16", "supported"); + } + j.end_obj(); + } + if (add_srs_freq_hop_r16_present) { + j.write_str("addSRS-FrequencyHopping-r16", "supported"); + } + if (add_srs_ant_switching_r16_present) { + j.write_fieldname("addSRS-AntennaSwitching-r16"); + j.start_obj(); + if (add_srs_ant_switching_r16.add_srs_minus1_t2_r_r16_present) { + j.write_str("addSRS-1T2R-r16", "supported"); + } + if (add_srs_ant_switching_r16.add_srs_minus1_t4_r_r16_present) { + j.write_str("addSRS-1T4R-r16", "supported"); + } + if (add_srs_ant_switching_r16.add_srs_minus2_t4_r_minus2pairs_r16_present) { + j.write_str("addSRS-2T4R-2pairs-r16", "supported"); + } + if (add_srs_ant_switching_r16.add_srs_minus2_t4_r_minus3pairs_r16_present) { + j.write_str("addSRS-2T4R-3pairs-r16", "supported"); + } + j.end_obj(); + } + if (srs_cap_per_band_pair_list_v1610_present) { + j.start_array("srs-CapabilityPerBandPairList-v1610"); + for (const auto& e1 : srs_cap_per_band_pair_list_v1610) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// MeasGapInfoNR-r16 ::= SEQUENCE +SRSASN_CODE meas_gap_info_nr_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(inter_rat_band_list_nr_en_dc_r16_present, 1)); + HANDLE_CODE(bref.pack(inter_rat_band_list_nr_sa_r16_present, 1)); + + if (inter_rat_band_list_nr_en_dc_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, inter_rat_band_list_nr_en_dc_r16, 1, 1024)); + } + if (inter_rat_band_list_nr_sa_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, inter_rat_band_list_nr_sa_r16, 1, 1024)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_gap_info_nr_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(inter_rat_band_list_nr_en_dc_r16_present, 1)); + HANDLE_CODE(bref.unpack(inter_rat_band_list_nr_sa_r16_present, 1)); + + if (inter_rat_band_list_nr_en_dc_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(inter_rat_band_list_nr_en_dc_r16, bref, 1, 1024)); + } + if (inter_rat_band_list_nr_sa_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(inter_rat_band_list_nr_sa_r16, bref, 1, 1024)); + } + + return SRSASN_SUCCESS; +} +void meas_gap_info_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (inter_rat_band_list_nr_en_dc_r16_present) { + j.start_array("interRAT-BandListNR-EN-DC-r16"); + for (const auto& e1 : inter_rat_band_list_nr_en_dc_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (inter_rat_band_list_nr_sa_r16_present) { + j.start_array("interRAT-BandListNR-SA-r16"); + for (const auto& e1 : inter_rat_band_list_nr_sa_r16) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// BandCombinationParameters-v1610 ::= SEQUENCE +SRSASN_CODE band_combination_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(meas_gap_info_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(band_param_list_v1610_present, 1)); + HANDLE_CODE(bref.pack(inter_freq_daps_r16_present, 1)); + + if (meas_gap_info_nr_r16_present) { + HANDLE_CODE(meas_gap_info_nr_r16.pack(bref)); + } + if (band_param_list_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, band_param_list_v1610, 1, 64)); + } + if (inter_freq_daps_r16_present) { + HANDLE_CODE(bref.pack(inter_freq_daps_r16.inter_freq_async_daps_r16_present, 1)); + HANDLE_CODE(bref.pack(inter_freq_daps_r16.inter_freq_multi_ul_tx_daps_r16_present, 1)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE band_combination_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(meas_gap_info_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(band_param_list_v1610_present, 1)); + HANDLE_CODE(bref.unpack(inter_freq_daps_r16_present, 1)); + + if (meas_gap_info_nr_r16_present) { + HANDLE_CODE(meas_gap_info_nr_r16.unpack(bref)); + } + if (band_param_list_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(band_param_list_v1610, bref, 1, 64)); + } + if (inter_freq_daps_r16_present) { + HANDLE_CODE(bref.unpack(inter_freq_daps_r16.inter_freq_async_daps_r16_present, 1)); + HANDLE_CODE(bref.unpack(inter_freq_daps_r16.inter_freq_multi_ul_tx_daps_r16_present, 1)); + } + + return SRSASN_SUCCESS; +} +void band_combination_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (meas_gap_info_nr_r16_present) { + j.write_fieldname("measGapInfoNR-r16"); + meas_gap_info_nr_r16.to_json(j); + } + if (band_param_list_v1610_present) { + j.start_array("bandParameterList-v1610"); + for (const auto& e1 : band_param_list_v1610) { + e1.to_json(j); + } + j.end_array(); + } + if (inter_freq_daps_r16_present) { + j.write_fieldname("interFreqDAPS-r16"); + j.start_obj(); + if (inter_freq_daps_r16.inter_freq_async_daps_r16_present) { + j.write_str("interFreqAsyncDAPS-r16", "supported"); + } + if (inter_freq_daps_r16.inter_freq_multi_ul_tx_daps_r16_present) { + j.write_str("interFreqMultiUL-TransmissionDAPS-r16", "supported"); + } + j.end_obj(); + } + j.end_obj(); +} + +// ScalingFactorSidelink-r16 ::= ENUMERATED +const char* scaling_factor_sidelink_r16_opts::to_string() const +{ + static const char* options[] = {"f0p4", "f0p75", "f0p8", "f1"}; + return convert_enum_idx(options, 4, value, "scaling_factor_sidelink_r16_e"); +} + +// BandCombinationParameters-v1630 ::= SEQUENCE +SRSASN_CODE band_combination_params_v1630_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(v2x_supported_tx_band_comb_list_per_bc_v1630_present, 1)); + HANDLE_CODE(bref.pack(v2x_supported_rx_band_comb_list_per_bc_v1630_present, 1)); + HANDLE_CODE(bref.pack(scaling_factor_tx_sidelink_r16_present, 1)); + HANDLE_CODE(bref.pack(scaling_factor_rx_sidelink_r16_present, 1)); + HANDLE_CODE(bref.pack(inter_band_pwr_sharing_sync_daps_r16_present, 1)); + HANDLE_CODE(bref.pack(inter_band_pwr_sharing_async_daps_r16_present, 1)); + + if (v2x_supported_tx_band_comb_list_per_bc_v1630_present) { + HANDLE_CODE(v2x_supported_tx_band_comb_list_per_bc_v1630.pack(bref)); + } + if (v2x_supported_rx_band_comb_list_per_bc_v1630_present) { + HANDLE_CODE(v2x_supported_rx_band_comb_list_per_bc_v1630.pack(bref)); + } + if (scaling_factor_tx_sidelink_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, scaling_factor_tx_sidelink_r16, 1, 512)); + } + if (scaling_factor_rx_sidelink_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, scaling_factor_rx_sidelink_r16, 1, 512)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE band_combination_params_v1630_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(v2x_supported_tx_band_comb_list_per_bc_v1630_present, 1)); + HANDLE_CODE(bref.unpack(v2x_supported_rx_band_comb_list_per_bc_v1630_present, 1)); + HANDLE_CODE(bref.unpack(scaling_factor_tx_sidelink_r16_present, 1)); + HANDLE_CODE(bref.unpack(scaling_factor_rx_sidelink_r16_present, 1)); + HANDLE_CODE(bref.unpack(inter_band_pwr_sharing_sync_daps_r16_present, 1)); + HANDLE_CODE(bref.unpack(inter_band_pwr_sharing_async_daps_r16_present, 1)); + + if (v2x_supported_tx_band_comb_list_per_bc_v1630_present) { + HANDLE_CODE(v2x_supported_tx_band_comb_list_per_bc_v1630.unpack(bref)); + } + if (v2x_supported_rx_band_comb_list_per_bc_v1630_present) { + HANDLE_CODE(v2x_supported_rx_band_comb_list_per_bc_v1630.unpack(bref)); + } + if (scaling_factor_tx_sidelink_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(scaling_factor_tx_sidelink_r16, bref, 1, 512)); + } + if (scaling_factor_rx_sidelink_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(scaling_factor_rx_sidelink_r16, bref, 1, 512)); + } + + return SRSASN_SUCCESS; +} +void band_combination_params_v1630_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (v2x_supported_tx_band_comb_list_per_bc_v1630_present) { + j.write_str("v2x-SupportedTxBandCombListPerBC-v1630", v2x_supported_tx_band_comb_list_per_bc_v1630.to_string()); + } + if (v2x_supported_rx_band_comb_list_per_bc_v1630_present) { + j.write_str("v2x-SupportedRxBandCombListPerBC-v1630", v2x_supported_rx_band_comb_list_per_bc_v1630.to_string()); + } + if (scaling_factor_tx_sidelink_r16_present) { + j.start_array("scalingFactorTxSidelink-r16"); + for (const auto& e1 : scaling_factor_tx_sidelink_r16) { + j.write_str(e1.to_string()); + } + j.end_array(); + } + if (scaling_factor_rx_sidelink_r16_present) { + j.start_array("scalingFactorRxSidelink-r16"); + for (const auto& e1 : scaling_factor_rx_sidelink_r16) { + j.write_str(e1.to_string()); + } + j.end_array(); + } + if (inter_band_pwr_sharing_sync_daps_r16_present) { + j.write_str("interBandPowerSharingSyncDAPS-r16", "supported"); + } + if (inter_band_pwr_sharing_async_daps_r16_present) { + j.write_str("interBandPowerSharingAsyncDAPS-r16", "supported"); + } + j.end_obj(); +} + // BandCombinationParametersExt-r10 ::= SEQUENCE SRSASN_CODE band_combination_params_ext_r10_s::pack(bit_ref& bref) const { @@ -5020,35 +5484,216 @@ void mac_params_v1530_s::to_json(json_writer& j) const j.end_obj(); } -// MIMO-UE-BeamformedCapabilities-r13 ::= SEQUENCE -SRSASN_CODE mimo_ue_bf_cap_r13_s::pack(bit_ref& bref) const +// MBMS-SupportedBandInfo-r16 ::= SEQUENCE +SRSASN_CODE mbms_supported_band_info_r16_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(alt_codebook_r13_present, 1)); + HANDLE_CODE(bref.pack(subcarrier_spacing_mbms_khz2dot5_r16_present, 1)); + HANDLE_CODE(bref.pack(subcarrier_spacing_mbms_khz0dot37_r16_present, 1)); - HANDLE_CODE(pack_dyn_seq_of(bref, mimo_bf_cap_r13, 1, 4)); + if (subcarrier_spacing_mbms_khz0dot37_r16_present) { + HANDLE_CODE(bref.pack(subcarrier_spacing_mbms_khz0dot37_r16.time_separation_slot2_r16_present, 1)); + HANDLE_CODE(bref.pack(subcarrier_spacing_mbms_khz0dot37_r16.time_separation_slot4_r16_present, 1)); + } return SRSASN_SUCCESS; } -SRSASN_CODE mimo_ue_bf_cap_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE mbms_supported_band_info_r16_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(alt_codebook_r13_present, 1)); + HANDLE_CODE(bref.unpack(subcarrier_spacing_mbms_khz2dot5_r16_present, 1)); + HANDLE_CODE(bref.unpack(subcarrier_spacing_mbms_khz0dot37_r16_present, 1)); - HANDLE_CODE(unpack_dyn_seq_of(mimo_bf_cap_r13, bref, 1, 4)); + if (subcarrier_spacing_mbms_khz0dot37_r16_present) { + HANDLE_CODE(bref.unpack(subcarrier_spacing_mbms_khz0dot37_r16.time_separation_slot2_r16_present, 1)); + HANDLE_CODE(bref.unpack(subcarrier_spacing_mbms_khz0dot37_r16.time_separation_slot4_r16_present, 1)); + } return SRSASN_SUCCESS; } -void mimo_ue_bf_cap_r13_s::to_json(json_writer& j) const +void mbms_supported_band_info_r16_s::to_json(json_writer& j) const { j.start_obj(); - if (alt_codebook_r13_present) { - j.write_str("altCodebook-r13", "supported"); - } - j.start_array("mimo-BeamformedCapabilities-r13"); - for (const auto& e1 : mimo_bf_cap_r13) { - e1.to_json(j); + if (subcarrier_spacing_mbms_khz2dot5_r16_present) { + j.write_str("subcarrierSpacingMBMS-khz2dot5-r16", "supported"); } - j.end_array(); - j.end_obj(); + if (subcarrier_spacing_mbms_khz0dot37_r16_present) { + j.write_fieldname("subcarrierSpacingMBMS-khz0dot37-r16"); + j.start_obj(); + if (subcarrier_spacing_mbms_khz0dot37_r16.time_separation_slot2_r16_present) { + j.write_str("timeSeparationSlot2-r16", "supported"); + } + if (subcarrier_spacing_mbms_khz0dot37_r16.time_separation_slot4_r16_present) { + j.write_str("timeSeparationSlot4-r16", "supported"); + } + j.end_obj(); + } + j.end_obj(); +} + +// MBMS-Parameters-v1610 ::= SEQUENCE +SRSASN_CODE mbms_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(mbms_scaling_factor2dot5_r16_present, 1)); + HANDLE_CODE(bref.pack(mbms_scaling_factor0dot37_r16_present, 1)); + + if (mbms_scaling_factor2dot5_r16_present) { + HANDLE_CODE(mbms_scaling_factor2dot5_r16.pack(bref)); + } + if (mbms_scaling_factor0dot37_r16_present) { + HANDLE_CODE(mbms_scaling_factor0dot37_r16.pack(bref)); + } + HANDLE_CODE(pack_dyn_seq_of(bref, mbms_supported_band_info_list_r16, 1, 64)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mbms_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(mbms_scaling_factor2dot5_r16_present, 1)); + HANDLE_CODE(bref.unpack(mbms_scaling_factor0dot37_r16_present, 1)); + + if (mbms_scaling_factor2dot5_r16_present) { + HANDLE_CODE(mbms_scaling_factor2dot5_r16.unpack(bref)); + } + if (mbms_scaling_factor0dot37_r16_present) { + HANDLE_CODE(mbms_scaling_factor0dot37_r16.unpack(bref)); + } + HANDLE_CODE(unpack_dyn_seq_of(mbms_supported_band_info_list_r16, bref, 1, 64)); + + return SRSASN_SUCCESS; +} +void mbms_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (mbms_scaling_factor2dot5_r16_present) { + j.write_str("mbms-ScalingFactor2dot5-r16", mbms_scaling_factor2dot5_r16.to_string()); + } + if (mbms_scaling_factor0dot37_r16_present) { + j.write_str("mbms-ScalingFactor0dot37-r16", mbms_scaling_factor0dot37_r16.to_string()); + } + j.start_array("mbms-SupportedBandInfoList-r16"); + for (const auto& e1 : mbms_supported_band_info_list_r16) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +const char* mbms_params_v1610_s::mbms_scaling_factor2dot5_r16_opts::to_string() const +{ + static const char* options[] = {"n2", "n4", "n6", "n8"}; + return convert_enum_idx(options, 4, value, "mbms_params_v1610_s::mbms_scaling_factor2dot5_r16_e_"); +} +uint8_t mbms_params_v1610_s::mbms_scaling_factor2dot5_r16_opts::to_number() const +{ + static const uint8_t options[] = {2, 4, 6, 8}; + return map_enum_number(options, 4, value, "mbms_params_v1610_s::mbms_scaling_factor2dot5_r16_e_"); +} + +const char* mbms_params_v1610_s::mbms_scaling_factor0dot37_r16_opts::to_string() const +{ + static const char* options[] = {"n12", "n16", "n20", "n24"}; + return convert_enum_idx(options, 4, value, "mbms_params_v1610_s::mbms_scaling_factor0dot37_r16_e_"); +} +uint8_t mbms_params_v1610_s::mbms_scaling_factor0dot37_r16_opts::to_number() const +{ + static const uint8_t options[] = {12, 16, 20, 24}; + return map_enum_number(options, 4, value, "mbms_params_v1610_s::mbms_scaling_factor0dot37_r16_e_"); +} + +// MBMS-SupportedBandInfo-v1700 ::= SEQUENCE +SRSASN_CODE mbms_supported_band_info_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pmch_bw_n40_r17_present, 1)); + HANDLE_CODE(bref.pack(pmch_bw_n35_r17_present, 1)); + HANDLE_CODE(bref.pack(pmch_bw_n30_r17_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mbms_supported_band_info_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(pmch_bw_n40_r17_present, 1)); + HANDLE_CODE(bref.unpack(pmch_bw_n35_r17_present, 1)); + HANDLE_CODE(bref.unpack(pmch_bw_n30_r17_present, 1)); + + return SRSASN_SUCCESS; +} +void mbms_supported_band_info_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (pmch_bw_n40_r17_present) { + j.write_str("pmch-Bandwidth-n40-r17", "supported"); + } + if (pmch_bw_n35_r17_present) { + j.write_str("pmch-Bandwidth-n35-r17", "supported"); + } + if (pmch_bw_n30_r17_present) { + j.write_str("pmch-Bandwidth-n30-r17", "supported"); + } + j.end_obj(); +} + +// MBMS-Parameters-v1700 ::= SEQUENCE +SRSASN_CODE mbms_params_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(mbms_supported_band_info_list_v1700_present, 1)); + + if (mbms_supported_band_info_list_v1700_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, mbms_supported_band_info_list_v1700, 1, 64)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE mbms_params_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(mbms_supported_band_info_list_v1700_present, 1)); + + if (mbms_supported_band_info_list_v1700_present) { + HANDLE_CODE(unpack_dyn_seq_of(mbms_supported_band_info_list_v1700, bref, 1, 64)); + } + + return SRSASN_SUCCESS; +} +void mbms_params_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (mbms_supported_band_info_list_v1700_present) { + j.start_array("mbms-SupportedBandInfoList-v1700"); + for (const auto& e1 : mbms_supported_band_info_list_v1700) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// MIMO-UE-BeamformedCapabilities-r13 ::= SEQUENCE +SRSASN_CODE mimo_ue_bf_cap_r13_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(alt_codebook_r13_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, mimo_bf_cap_r13, 1, 4)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mimo_ue_bf_cap_r13_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(alt_codebook_r13_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(mimo_bf_cap_r13, bref, 1, 4)); + + return SRSASN_SUCCESS; +} +void mimo_ue_bf_cap_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (alt_codebook_r13_present) { + j.write_str("altCodebook-r13", "supported"); + } + j.start_array("mimo-BeamformedCapabilities-r13"); + for (const auto& e1 : mimo_bf_cap_r13) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); } // MIMO-UE-ParametersPerTM-r13 ::= SEQUENCE @@ -5259,26 +5904,26 @@ void mimo_ue_params_per_tm_v1430_s::to_json(json_writer& j) const const char* mimo_ue_params_per_tm_v1430_s::nzp_csi_rs_aperiodic_info_r14_s_::nmax_res_r14_opts::to_string() const { - static const char* options[] = {"ffs1", "ffs2", "ffs3", "ffs4"}; + static const char* options[] = {"n1", "n2", "n4", "n8"}; return convert_enum_idx( options, 4, value, "mimo_ue_params_per_tm_v1430_s::nzp_csi_rs_aperiodic_info_r14_s_::nmax_res_r14_e_"); } uint8_t mimo_ue_params_per_tm_v1430_s::nzp_csi_rs_aperiodic_info_r14_s_::nmax_res_r14_opts::to_number() const { - static const uint8_t options[] = {1, 2, 3, 4}; + static const uint8_t options[] = {1, 2, 4, 8}; return map_enum_number( options, 4, value, "mimo_ue_params_per_tm_v1430_s::nzp_csi_rs_aperiodic_info_r14_s_::nmax_res_r14_e_"); } const char* mimo_ue_params_per_tm_v1430_s::nzp_csi_rs_periodic_info_r14_s_::nmax_res_r14_opts::to_string() const { - static const char* options[] = {"ffs1", "ffs2", "ffs3", "ffs4"}; + static const char* options[] = {"n1", "n2", "n4", "n8"}; return convert_enum_idx( options, 4, value, "mimo_ue_params_per_tm_v1430_s::nzp_csi_rs_periodic_info_r14_s_::nmax_res_r14_e_"); } uint8_t mimo_ue_params_per_tm_v1430_s::nzp_csi_rs_periodic_info_r14_s_::nmax_res_r14_opts::to_number() const { - static const uint8_t options[] = {1, 2, 3, 4}; + static const uint8_t options[] = {1, 2, 4, 8}; return map_enum_number( options, 4, value, "mimo_ue_params_per_tm_v1430_s::nzp_csi_rs_periodic_info_r14_s_::nmax_res_r14_e_"); } @@ -5440,6 +6085,154 @@ void meas_params_v1020_s::to_json(json_writer& j) const j.end_obj(); } +// MeasParameters-v1610 ::= SEQUENCE +SRSASN_CODE meas_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(band_info_nr_v1610_present, 1)); + HANDLE_CODE(bref.pack(alt_freq_prio_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_dl_ch_quality_report_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_meas_rss_ded_r16_present, 1)); + HANDLE_CODE(bref.pack(eutra_idle_inactive_meass_r16_present, 1)); + HANDLE_CODE(bref.pack(nr_idle_inactive_meas_fr1_r16_present, 1)); + HANDLE_CODE(bref.pack(nr_idle_inactive_meas_fr2_r16_present, 1)); + HANDLE_CODE(bref.pack(idle_inactive_validity_area_list_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_gap_patterns_nronly_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_gap_patterns_nronly_endc_r16_present, 1)); + + if (band_info_nr_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, band_info_nr_v1610, 1, 64)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(band_info_nr_v1610_present, 1)); + HANDLE_CODE(bref.unpack(alt_freq_prio_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_dl_ch_quality_report_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_meas_rss_ded_r16_present, 1)); + HANDLE_CODE(bref.unpack(eutra_idle_inactive_meass_r16_present, 1)); + HANDLE_CODE(bref.unpack(nr_idle_inactive_meas_fr1_r16_present, 1)); + HANDLE_CODE(bref.unpack(nr_idle_inactive_meas_fr2_r16_present, 1)); + HANDLE_CODE(bref.unpack(idle_inactive_validity_area_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_gap_patterns_nronly_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_gap_patterns_nronly_endc_r16_present, 1)); + + if (band_info_nr_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(band_info_nr_v1610, bref, 1, 64)); + } + + return SRSASN_SUCCESS; +} +void meas_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (band_info_nr_v1610_present) { + j.start_array("bandInfoNR-v1610"); + for (const auto& e1 : band_info_nr_v1610) { + e1.to_json(j); + } + j.end_array(); + } + if (alt_freq_prio_r16_present) { + j.write_str("altFreqPriority-r16", "supported"); + } + if (ce_dl_ch_quality_report_r16_present) { + j.write_str("ce-DL-ChannelQualityReporting-r16", "supported"); + } + if (ce_meas_rss_ded_r16_present) { + j.write_str("ce-MeasRSS-Dedicated-r16", "supported"); + } + if (eutra_idle_inactive_meass_r16_present) { + j.write_str("eutra-IdleInactiveMeasurements-r16", "supported"); + } + if (nr_idle_inactive_meas_fr1_r16_present) { + j.write_str("nr-IdleInactiveMeasFR1-r16", "supported"); + } + if (nr_idle_inactive_meas_fr2_r16_present) { + j.write_str("nr-IdleInactiveMeasFR2-r16", "supported"); + } + if (idle_inactive_validity_area_list_r16_present) { + j.write_str("idleInactiveValidityAreaList-r16", "supported"); + } + if (meas_gap_patterns_nronly_r16_present) { + j.write_str("measGapPatterns-NRonly-r16", "supported"); + } + if (meas_gap_patterns_nronly_endc_r16_present) { + j.write_str("measGapPatterns-NRonly-ENDC-r16", "supported"); + } + j.end_obj(); +} + +// SharedSpectrumMeasNR-r17 ::= SEQUENCE +SRSASN_CODE shared_spec_meas_nr_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(nr_rssi_ch_occupancy_report_r17, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE shared_spec_meas_nr_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(nr_rssi_ch_occupancy_report_r17, 1)); + + return SRSASN_SUCCESS; +} +void shared_spec_meas_nr_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_bool("nr-RSSI-ChannelOccupancyReporting-r17", nr_rssi_ch_occupancy_report_r17); + j.end_obj(); +} + +// MeasParameters-v1700 ::= SEQUENCE +SRSASN_CODE meas_params_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(shared_spec_meas_nr_en_dc_r17_present, 1)); + HANDLE_CODE(bref.pack(shared_spec_meas_nr_sa_r17_present, 1)); + + if (shared_spec_meas_nr_en_dc_r17_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, shared_spec_meas_nr_en_dc_r17, 1, 1024)); + } + if (shared_spec_meas_nr_sa_r17_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, shared_spec_meas_nr_sa_r17, 1, 1024)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_params_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(shared_spec_meas_nr_en_dc_r17_present, 1)); + HANDLE_CODE(bref.unpack(shared_spec_meas_nr_sa_r17_present, 1)); + + if (shared_spec_meas_nr_en_dc_r17_present) { + HANDLE_CODE(unpack_dyn_seq_of(shared_spec_meas_nr_en_dc_r17, bref, 1, 1024)); + } + if (shared_spec_meas_nr_sa_r17_present) { + HANDLE_CODE(unpack_dyn_seq_of(shared_spec_meas_nr_sa_r17, bref, 1, 1024)); + } + + return SRSASN_SUCCESS; +} +void meas_params_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (shared_spec_meas_nr_en_dc_r17_present) { + j.start_array("sharedSpectrumMeasNR-EN-DC-r17"); + for (const auto& e1 : shared_spec_meas_nr_en_dc_r17) { + e1.to_json(j); + } + j.end_array(); + } + if (shared_spec_meas_nr_sa_r17_present) { + j.start_array("sharedSpectrumMeasNR-SA-r17"); + for (const auto& e1 : shared_spec_meas_nr_sa_r17) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + // NAICS-Capability-Entry-r12 ::= SEQUENCE SRSASN_CODE naics_cap_entry_r12_s::pack(bit_ref& bref) const { @@ -6769,76 +7562,375 @@ const char* phy_layer_params_v1530_s::stti_spt_cap_r15_s_::sps_stti_r15_opts::to return convert_enum_idx(options, 3, value, "phy_layer_params_v1530_s::stti_spt_cap_r15_s_::sps_stti_r15_e_"); } -// SupportedBandEUTRA ::= SEQUENCE -SRSASN_CODE supported_band_eutra_s::pack(bit_ref& bref) const +// CE-MultiTB-Parameters-r16 ::= SEQUENCE +SRSASN_CODE ce_multi_tb_params_r16_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, band_eutra, (uint8_t)1u, (uint8_t)64u)); - HANDLE_CODE(bref.pack(half_duplex, 1)); + HANDLE_CODE(bref.pack(pdsch_multi_tb_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(pdsch_multi_tb_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(pusch_multi_tb_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(pusch_multi_tb_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_multi_tb_minus64_qam_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_multi_tb_early_termination_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_multi_tb_freq_hop_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_multi_tb_harq_ack_bundling_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_multi_tb_interleaving_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_multi_tb_sub_prb_r16_present, 1)); return SRSASN_SUCCESS; } -SRSASN_CODE supported_band_eutra_s::unpack(cbit_ref& bref) +SRSASN_CODE ce_multi_tb_params_r16_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(band_eutra, bref, (uint8_t)1u, (uint8_t)64u)); - HANDLE_CODE(bref.unpack(half_duplex, 1)); + HANDLE_CODE(bref.unpack(pdsch_multi_tb_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(pdsch_multi_tb_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(pusch_multi_tb_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(pusch_multi_tb_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_multi_tb_minus64_qam_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_multi_tb_early_termination_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_multi_tb_freq_hop_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_multi_tb_harq_ack_bundling_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_multi_tb_interleaving_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_multi_tb_sub_prb_r16_present, 1)); return SRSASN_SUCCESS; } -void supported_band_eutra_s::to_json(json_writer& j) const +void ce_multi_tb_params_r16_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("bandEUTRA", band_eutra); - j.write_bool("halfDuplex", half_duplex); + if (pdsch_multi_tb_ce_mode_a_r16_present) { + j.write_str("pdsch-MultiTB-CE-ModeA-r16", "supported"); + } + if (pdsch_multi_tb_ce_mode_b_r16_present) { + j.write_str("pdsch-MultiTB-CE-ModeB-r16", "supported"); + } + if (pusch_multi_tb_ce_mode_a_r16_present) { + j.write_str("pusch-MultiTB-CE-ModeA-r16", "supported"); + } + if (pusch_multi_tb_ce_mode_b_r16_present) { + j.write_str("pusch-MultiTB-CE-ModeB-r16", "supported"); + } + if (ce_multi_tb_minus64_qam_r16_present) { + j.write_str("ce-MultiTB-64QAM-r16", "supported"); + } + if (ce_multi_tb_early_termination_r16_present) { + j.write_str("ce-MultiTB-EarlyTermination-r16", "supported"); + } + if (ce_multi_tb_freq_hop_r16_present) { + j.write_str("ce-MultiTB-FrequencyHopping-r16", "supported"); + } + if (ce_multi_tb_harq_ack_bundling_r16_present) { + j.write_str("ce-MultiTB-HARQ-AckBundling-r16", "supported"); + } + if (ce_multi_tb_interleaving_r16_present) { + j.write_str("ce-MultiTB-Interleaving-r16", "supported"); + } + if (ce_multi_tb_sub_prb_r16_present) { + j.write_str("ce-MultiTB-SubPRB-r16", "supported"); + } j.end_obj(); } -// RF-Parameters ::= SEQUENCE -SRSASN_CODE rf_params_s::pack(bit_ref& bref) const +// CE-ResourceResvParameters-r16 ::= SEQUENCE +SRSASN_CODE ce_res_resv_params_r16_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_list_eutra, 1, 64)); + HANDLE_CODE(bref.pack(sf_res_resv_dl_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(sf_res_resv_dl_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(sf_res_resv_ul_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(sf_res_resv_ul_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(slot_symbol_res_resv_dl_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(slot_symbol_res_resv_dl_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(slot_symbol_res_resv_ul_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(slot_symbol_res_resv_ul_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(subcarrier_puncturing_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(subcarrier_puncturing_ce_mode_b_r16_present, 1)); return SRSASN_SUCCESS; } -SRSASN_CODE rf_params_s::unpack(cbit_ref& bref) +SRSASN_CODE ce_res_resv_params_r16_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_dyn_seq_of(supported_band_list_eutra, bref, 1, 64)); + HANDLE_CODE(bref.unpack(sf_res_resv_dl_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(sf_res_resv_dl_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(sf_res_resv_ul_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(sf_res_resv_ul_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(slot_symbol_res_resv_dl_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(slot_symbol_res_resv_dl_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(slot_symbol_res_resv_ul_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(slot_symbol_res_resv_ul_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(subcarrier_puncturing_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(subcarrier_puncturing_ce_mode_b_r16_present, 1)); return SRSASN_SUCCESS; } -void rf_params_s::to_json(json_writer& j) const +void ce_res_resv_params_r16_s::to_json(json_writer& j) const { j.start_obj(); - j.start_array("supportedBandListEUTRA"); - for (const auto& e1 : supported_band_list_eutra) { - e1.to_json(j); + if (sf_res_resv_dl_ce_mode_a_r16_present) { + j.write_str("subframeResourceResvDL-CE-ModeA-r16", "supported"); + } + if (sf_res_resv_dl_ce_mode_b_r16_present) { + j.write_str("subframeResourceResvDL-CE-ModeB-r16", "supported"); + } + if (sf_res_resv_ul_ce_mode_a_r16_present) { + j.write_str("subframeResourceResvUL-CE-ModeA-r16", "supported"); + } + if (sf_res_resv_ul_ce_mode_b_r16_present) { + j.write_str("subframeResourceResvUL-CE-ModeB-r16", "supported"); + } + if (slot_symbol_res_resv_dl_ce_mode_a_r16_present) { + j.write_str("slotSymbolResourceResvDL-CE-ModeA-r16", "supported"); + } + if (slot_symbol_res_resv_dl_ce_mode_b_r16_present) { + j.write_str("slotSymbolResourceResvDL-CE-ModeB-r16", "supported"); + } + if (slot_symbol_res_resv_ul_ce_mode_a_r16_present) { + j.write_str("slotSymbolResourceResvUL-CE-ModeA-r16", "supported"); + } + if (slot_symbol_res_resv_ul_ce_mode_b_r16_present) { + j.write_str("slotSymbolResourceResvUL-CE-ModeB-r16", "supported"); + } + if (subcarrier_puncturing_ce_mode_a_r16_present) { + j.write_str("subcarrierPuncturingCE-ModeA-r16", "supported"); + } + if (subcarrier_puncturing_ce_mode_b_r16_present) { + j.write_str("subcarrierPuncturingCE-ModeB-r16", "supported"); } - j.end_array(); j.end_obj(); } -// RF-Parameters-v1020 ::= SEQUENCE -SRSASN_CODE rf_params_v1020_s::pack(bit_ref& bref) const +// PhyLayerParameters-v1610 ::= SEQUENCE +SRSASN_CODE phy_layer_params_v1610_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_combination_r10, 1, 128, SeqOfPacker(1, 64, Packer()))); + HANDLE_CODE(bref.pack(ce_cap_v1610_present, 1)); + HANDLE_CODE(bref.pack(wideband_prg_slot_r16_present, 1)); + HANDLE_CODE(bref.pack(wideband_prg_subslot_r16_present, 1)); + HANDLE_CODE(bref.pack(wideband_prg_sf_r16_present, 1)); + HANDLE_CODE(bref.pack(add_srs_r16_present, 1)); + HANDLE_CODE(bref.pack(virtual_cell_id_basic_srs_r16_present, 1)); + HANDLE_CODE(bref.pack(virtual_cell_id_add_srs_r16_present, 1)); - return SRSASN_SUCCESS; -} -SRSASN_CODE rf_params_v1020_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_dyn_seq_of(supported_band_combination_r10, bref, 1, 128, SeqOfPacker(1, 64, Packer()))); + if (ce_cap_v1610_present) { + HANDLE_CODE(bref.pack(ce_cap_v1610.ce_csi_rs_feedback_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.ce_csi_rs_feedback_codebook_restrict_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.crs_ch_est_mpdcch_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.crs_ch_est_mpdcch_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.crs_ch_est_mpdcch_csi_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.crs_ch_est_mpdcch_reciprocity_tdd_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.etws_cmas_rx_in_conn_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.etws_cmas_rx_in_conn_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.mpdcch_in_lte_ctrl_region_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.mpdcch_in_lte_ctrl_region_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.pdsch_in_lte_ctrl_region_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.pdsch_in_lte_ctrl_region_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.multi_tb_params_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1610.res_resv_params_r16_present, 1)); + if (ce_cap_v1610.multi_tb_params_r16_present) { + HANDLE_CODE(ce_cap_v1610.multi_tb_params_r16.pack(bref)); + } + if (ce_cap_v1610.res_resv_params_r16_present) { + HANDLE_CODE(ce_cap_v1610.res_resv_params_r16.pack(bref)); + } + } + if (add_srs_r16_present) { + HANDLE_CODE(bref.pack(add_srs_r16.add_srs_freq_hop_r16_present, 1)); + HANDLE_CODE(bref.pack(add_srs_r16.add_srs_ant_switching_r16_present, 1)); + HANDLE_CODE(bref.pack(add_srs_r16.add_srs_carrier_switching_r16_present, 1)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE phy_layer_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ce_cap_v1610_present, 1)); + HANDLE_CODE(bref.unpack(wideband_prg_slot_r16_present, 1)); + HANDLE_CODE(bref.unpack(wideband_prg_subslot_r16_present, 1)); + HANDLE_CODE(bref.unpack(wideband_prg_sf_r16_present, 1)); + HANDLE_CODE(bref.unpack(add_srs_r16_present, 1)); + HANDLE_CODE(bref.unpack(virtual_cell_id_basic_srs_r16_present, 1)); + HANDLE_CODE(bref.unpack(virtual_cell_id_add_srs_r16_present, 1)); + + if (ce_cap_v1610_present) { + HANDLE_CODE(bref.unpack(ce_cap_v1610.ce_csi_rs_feedback_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.ce_csi_rs_feedback_codebook_restrict_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.crs_ch_est_mpdcch_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.crs_ch_est_mpdcch_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.crs_ch_est_mpdcch_csi_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.crs_ch_est_mpdcch_reciprocity_tdd_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.etws_cmas_rx_in_conn_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.etws_cmas_rx_in_conn_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.mpdcch_in_lte_ctrl_region_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.mpdcch_in_lte_ctrl_region_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.pdsch_in_lte_ctrl_region_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.pdsch_in_lte_ctrl_region_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.multi_tb_params_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1610.res_resv_params_r16_present, 1)); + if (ce_cap_v1610.multi_tb_params_r16_present) { + HANDLE_CODE(ce_cap_v1610.multi_tb_params_r16.unpack(bref)); + } + if (ce_cap_v1610.res_resv_params_r16_present) { + HANDLE_CODE(ce_cap_v1610.res_resv_params_r16.unpack(bref)); + } + } + if (add_srs_r16_present) { + HANDLE_CODE(bref.unpack(add_srs_r16.add_srs_freq_hop_r16_present, 1)); + HANDLE_CODE(bref.unpack(add_srs_r16.add_srs_ant_switching_r16_present, 1)); + HANDLE_CODE(bref.unpack(add_srs_r16.add_srs_carrier_switching_r16_present, 1)); + } return SRSASN_SUCCESS; } -void rf_params_v1020_s::to_json(json_writer& j) const +void phy_layer_params_v1610_s::to_json(json_writer& j) const { j.start_obj(); - j.start_array("supportedBandCombination-r10"); - for (const auto& e1 : supported_band_combination_r10) { - j.start_array(); - for (const auto& e2 : e1) { - e2.to_json(j); + if (ce_cap_v1610_present) { + j.write_fieldname("ce-Capabilities-v1610"); + j.start_obj(); + if (ce_cap_v1610.ce_csi_rs_feedback_r16_present) { + j.write_str("ce-CSI-RS-Feedback-r16", "supported"); } - j.end_array(); + if (ce_cap_v1610.ce_csi_rs_feedback_codebook_restrict_r16_present) { + j.write_str("ce-CSI-RS-FeedbackCodebookRestriction-r16", "supported"); + } + if (ce_cap_v1610.crs_ch_est_mpdcch_ce_mode_a_r16_present) { + j.write_str("crs-ChEstMPDCCH-CE-ModeA-r16", "supported"); + } + if (ce_cap_v1610.crs_ch_est_mpdcch_ce_mode_b_r16_present) { + j.write_str("crs-ChEstMPDCCH-CE-ModeB-r16", "supported"); + } + if (ce_cap_v1610.crs_ch_est_mpdcch_csi_r16_present) { + j.write_str("crs-ChEstMPDCCH-CSI-r16", "supported"); + } + if (ce_cap_v1610.crs_ch_est_mpdcch_reciprocity_tdd_r16_present) { + j.write_str("crs-ChEstMPDCCH-ReciprocityTDD-r16", "supported"); + } + if (ce_cap_v1610.etws_cmas_rx_in_conn_ce_mode_a_r16_present) { + j.write_str("etws-CMAS-RxInConnCE-ModeA-r16", "supported"); + } + if (ce_cap_v1610.etws_cmas_rx_in_conn_ce_mode_b_r16_present) { + j.write_str("etws-CMAS-RxInConnCE-ModeB-r16", "supported"); + } + if (ce_cap_v1610.mpdcch_in_lte_ctrl_region_ce_mode_a_r16_present) { + j.write_str("mpdcch-InLteControlRegionCE-ModeA-r16", "supported"); + } + if (ce_cap_v1610.mpdcch_in_lte_ctrl_region_ce_mode_b_r16_present) { + j.write_str("mpdcch-InLteControlRegionCE-ModeB-r16", "supported"); + } + if (ce_cap_v1610.pdsch_in_lte_ctrl_region_ce_mode_a_r16_present) { + j.write_str("pdsch-InLteControlRegionCE-ModeA-r16", "supported"); + } + if (ce_cap_v1610.pdsch_in_lte_ctrl_region_ce_mode_b_r16_present) { + j.write_str("pdsch-InLteControlRegionCE-ModeB-r16", "supported"); + } + if (ce_cap_v1610.multi_tb_params_r16_present) { + j.write_fieldname("multiTB-Parameters-r16"); + ce_cap_v1610.multi_tb_params_r16.to_json(j); + } + if (ce_cap_v1610.res_resv_params_r16_present) { + j.write_fieldname("resourceResvParameters-r16"); + ce_cap_v1610.res_resv_params_r16.to_json(j); + } + j.end_obj(); + } + if (wideband_prg_slot_r16_present) { + j.write_str("widebandPRG-Slot-r16", "supported"); + } + if (wideband_prg_subslot_r16_present) { + j.write_str("widebandPRG-Subslot-r16", "supported"); + } + if (wideband_prg_sf_r16_present) { + j.write_str("widebandPRG-Subframe-r16", "supported"); + } + if (add_srs_r16_present) { + j.write_fieldname("addSRS-r16"); + j.start_obj(); + if (add_srs_r16.add_srs_freq_hop_r16_present) { + j.write_str("addSRS-FrequencyHopping-r16", "supported"); + } + if (add_srs_r16.add_srs_ant_switching_r16_present) { + j.write_str("addSRS-AntennaSwitching-r16", "useBasic"); + } + if (add_srs_r16.add_srs_carrier_switching_r16_present) { + j.write_str("addSRS-CarrierSwitching-r16", "supported"); + } + j.end_obj(); + } + if (virtual_cell_id_basic_srs_r16_present) { + j.write_str("virtualCellID-BasicSRS-r16", "supported"); + } + if (virtual_cell_id_add_srs_r16_present) { + j.write_str("virtualCellID-AddSRS-r16", "supported"); + } + j.end_obj(); +} + +// SupportedBandEUTRA ::= SEQUENCE +SRSASN_CODE supported_band_eutra_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, band_eutra, (uint8_t)1u, (uint8_t)64u)); + HANDLE_CODE(bref.pack(half_duplex, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE supported_band_eutra_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(band_eutra, bref, (uint8_t)1u, (uint8_t)64u)); + HANDLE_CODE(bref.unpack(half_duplex, 1)); + + return SRSASN_SUCCESS; +} +void supported_band_eutra_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("bandEUTRA", band_eutra); + j.write_bool("halfDuplex", half_duplex); + j.end_obj(); +} + +// RF-Parameters ::= SEQUENCE +SRSASN_CODE rf_params_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_list_eutra, 1, 64)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rf_params_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_dyn_seq_of(supported_band_list_eutra, bref, 1, 64)); + + return SRSASN_SUCCESS; +} +void rf_params_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("supportedBandListEUTRA"); + for (const auto& e1 : supported_band_list_eutra) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// RF-Parameters-v1020 ::= SEQUENCE +SRSASN_CODE rf_params_v1020_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_combination_r10, 1, 128, SeqOfPacker(1, 64, Packer()))); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rf_params_v1020_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_dyn_seq_of(supported_band_combination_r10, bref, 1, 128, SeqOfPacker(1, 64, Packer()))); + + return SRSASN_SUCCESS; +} +void rf_params_v1020_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("supportedBandCombination-r10"); + for (const auto& e1 : supported_band_combination_r10) { + j.start_array(); + for (const auto& e2 : e1) { + e2.to_json(j); + } + j.end_array(); } j.end_array(); j.end_obj(); @@ -7977,6 +9069,134 @@ void rf_params_v1530_s::to_json(json_writer& j) const j.end_obj(); } +// RF-Parameters-v1610 ::= SEQUENCE +SRSASN_CODE rf_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(supported_band_combination_v1610_present, 1)); + HANDLE_CODE(bref.pack(supported_band_combination_add_v1610_present, 1)); + HANDLE_CODE(bref.pack(supported_band_combination_reduced_v1610_present, 1)); + + if (supported_band_combination_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_combination_v1610, 1, 128)); + } + if (supported_band_combination_add_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_combination_add_v1610, 1, 256)); + } + if (supported_band_combination_reduced_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_combination_reduced_v1610, 1, 384)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rf_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(supported_band_combination_v1610_present, 1)); + HANDLE_CODE(bref.unpack(supported_band_combination_add_v1610_present, 1)); + HANDLE_CODE(bref.unpack(supported_band_combination_reduced_v1610_present, 1)); + + if (supported_band_combination_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(supported_band_combination_v1610, bref, 1, 128)); + } + if (supported_band_combination_add_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(supported_band_combination_add_v1610, bref, 1, 256)); + } + if (supported_band_combination_reduced_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(supported_band_combination_reduced_v1610, bref, 1, 384)); + } + + return SRSASN_SUCCESS; +} +void rf_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (supported_band_combination_v1610_present) { + j.start_array("supportedBandCombination-v1610"); + for (const auto& e1 : supported_band_combination_v1610) { + e1.to_json(j); + } + j.end_array(); + } + if (supported_band_combination_add_v1610_present) { + j.start_array("supportedBandCombinationAdd-v1610"); + for (const auto& e1 : supported_band_combination_add_v1610) { + e1.to_json(j); + } + j.end_array(); + } + if (supported_band_combination_reduced_v1610_present) { + j.start_array("supportedBandCombinationReduced-v1610"); + for (const auto& e1 : supported_band_combination_reduced_v1610) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// RF-Parameters-v1630 ::= SEQUENCE +SRSASN_CODE rf_params_v1630_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(supported_band_combination_v1630_present, 1)); + HANDLE_CODE(bref.pack(supported_band_combination_add_v1630_present, 1)); + HANDLE_CODE(bref.pack(supported_band_combination_reduced_v1630_present, 1)); + + if (supported_band_combination_v1630_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_combination_v1630, 1, 128)); + } + if (supported_band_combination_add_v1630_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_combination_add_v1630, 1, 256)); + } + if (supported_band_combination_reduced_v1630_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_combination_reduced_v1630, 1, 384)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rf_params_v1630_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(supported_band_combination_v1630_present, 1)); + HANDLE_CODE(bref.unpack(supported_band_combination_add_v1630_present, 1)); + HANDLE_CODE(bref.unpack(supported_band_combination_reduced_v1630_present, 1)); + + if (supported_band_combination_v1630_present) { + HANDLE_CODE(unpack_dyn_seq_of(supported_band_combination_v1630, bref, 1, 128)); + } + if (supported_band_combination_add_v1630_present) { + HANDLE_CODE(unpack_dyn_seq_of(supported_band_combination_add_v1630, bref, 1, 256)); + } + if (supported_band_combination_reduced_v1630_present) { + HANDLE_CODE(unpack_dyn_seq_of(supported_band_combination_reduced_v1630, bref, 1, 384)); + } + + return SRSASN_SUCCESS; +} +void rf_params_v1630_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (supported_band_combination_v1630_present) { + j.start_array("supportedBandCombination-v1630"); + for (const auto& e1 : supported_band_combination_v1630) { + e1.to_json(j); + } + j.end_array(); + } + if (supported_band_combination_add_v1630_present) { + j.start_array("supportedBandCombinationAdd-v1630"); + for (const auto& e1 : supported_band_combination_add_v1630) { + e1.to_json(j); + } + j.end_array(); + } + if (supported_band_combination_reduced_v1630_present) { + j.start_array("supportedBandCombinationReduced-v1630"); + for (const auto& e1 : supported_band_combination_reduced_v1630) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + // SupportedBandEUTRA-v9e0 ::= SEQUENCE SRSASN_CODE supported_band_eutra_v9e0_s::pack(bit_ref& bref) const { @@ -8410,46 +9630,1666 @@ const char* sl_params_v1530_s::slss_supported_tx_freq_r15_opts::to_string() cons return convert_enum_idx(options, 2, value, "sl_params_v1530_s::slss_supported_tx_freq_r15_e_"); } -// NeighCellSI-AcquisitionParameters-v15a0 ::= SEQUENCE -SRSASN_CODE neigh_cell_si_acquisition_params_v15a0_s::pack(bit_ref& bref) const +// V2X-BandParametersEUTRA-NR-r16 ::= CHOICE +void v2x_band_params_eutra_nr_r16_c::destroy_() { - HANDLE_CODE(bref.pack(eutra_cgi_report_nedc_r15_present, 1)); - - return SRSASN_SUCCESS; + switch (type_) { + case types::eutra: + c.destroy(); + break; + case types::nr: + c.destroy(); + break; + default: + break; + } } -SRSASN_CODE neigh_cell_si_acquisition_params_v15a0_s::unpack(cbit_ref& bref) +void v2x_band_params_eutra_nr_r16_c::set(types::options e) { - HANDLE_CODE(bref.unpack(eutra_cgi_report_nedc_r15_present, 1)); + destroy_(); + type_ = e; + switch (type_) { + case types::eutra: + c.init(); + break; + case types::nr: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "v2x_band_params_eutra_nr_r16_c"); + } +} +v2x_band_params_eutra_nr_r16_c::v2x_band_params_eutra_nr_r16_c(const v2x_band_params_eutra_nr_r16_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::eutra: + c.init(other.c.get()); + break; + case types::nr: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "v2x_band_params_eutra_nr_r16_c"); + } +} +v2x_band_params_eutra_nr_r16_c& v2x_band_params_eutra_nr_r16_c::operator=(const v2x_band_params_eutra_nr_r16_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::eutra: + c.set(other.c.get()); + break; + case types::nr: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "v2x_band_params_eutra_nr_r16_c"); + } - return SRSASN_SUCCESS; + return *this; } -void neigh_cell_si_acquisition_params_v15a0_s::to_json(json_writer& j) const +v2x_band_params_eutra_nr_r16_c::eutra_s_& v2x_band_params_eutra_nr_r16_c::set_eutra() +{ + set(types::eutra); + return c.get(); +} +v2x_band_params_eutra_nr_r16_c::nr_s_& v2x_band_params_eutra_nr_r16_c::set_nr() +{ + set(types::nr); + return c.get(); +} +void v2x_band_params_eutra_nr_r16_c::to_json(json_writer& j) const { j.start_obj(); - if (eutra_cgi_report_nedc_r15_present) { - j.write_str("eutra-CGI-Reporting-NEDC-r15", "supported"); + switch (type_) { + case types::eutra: + j.write_fieldname("eutra"); + j.start_obj(); + if (c.get().v2x_band_params1_r16_present) { + j.write_fieldname("v2x-BandParameters1-r16"); + c.get().v2x_band_params1_r16.to_json(j); + } + if (c.get().v2x_band_params2_r16_present) { + j.write_fieldname("v2x-BandParameters2-r16"); + c.get().v2x_band_params2_r16.to_json(j); + } + j.end_obj(); + break; + case types::nr: + j.write_fieldname("nr"); + j.start_obj(); + if (c.get().v2x_band_params_nr_r16_present) { + j.write_str("v2x-BandParametersNR-r16", c.get().v2x_band_params_nr_r16.to_string()); + } + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "v2x_band_params_eutra_nr_r16_c"); } j.end_obj(); } +SRSASN_CODE v2x_band_params_eutra_nr_r16_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::eutra: + HANDLE_CODE(bref.pack(c.get().v2x_band_params1_r16_present, 1)); + HANDLE_CODE(bref.pack(c.get().v2x_band_params2_r16_present, 1)); + if (c.get().v2x_band_params1_r16_present) { + HANDLE_CODE(c.get().v2x_band_params1_r16.pack(bref)); + } + if (c.get().v2x_band_params2_r16_present) { + HANDLE_CODE(c.get().v2x_band_params2_r16.pack(bref)); + } + break; + case types::nr: + HANDLE_CODE(bref.pack(c.get().v2x_band_params_nr_r16_present, 1)); + if (c.get().v2x_band_params_nr_r16_present) { + HANDLE_CODE(c.get().v2x_band_params_nr_r16.pack(bref)); + } + break; + default: + log_invalid_choice_id(type_, "v2x_band_params_eutra_nr_r16_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE v2x_band_params_eutra_nr_r16_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::eutra: + HANDLE_CODE(bref.unpack(c.get().v2x_band_params1_r16_present, 1)); + HANDLE_CODE(bref.unpack(c.get().v2x_band_params2_r16_present, 1)); + if (c.get().v2x_band_params1_r16_present) { + HANDLE_CODE(c.get().v2x_band_params1_r16.unpack(bref)); + } + if (c.get().v2x_band_params2_r16_present) { + HANDLE_CODE(c.get().v2x_band_params2_r16.unpack(bref)); + } + break; + case types::nr: + HANDLE_CODE(bref.unpack(c.get().v2x_band_params_nr_r16_present, 1)); + if (c.get().v2x_band_params_nr_r16_present) { + HANDLE_CODE(c.get().v2x_band_params_nr_r16.unpack(bref)); + } + break; + default: + log_invalid_choice_id(type_, "v2x_band_params_eutra_nr_r16_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} -// PhyLayerParameters-v1540 ::= SEQUENCE -SRSASN_CODE phy_layer_params_v1540_s::pack(bit_ref& bref) const +// SL-Parameters-v1610 ::= SEQUENCE +SRSASN_CODE sl_params_v1610_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(stti_spt_cap_v1540_present, 1)); - HANDLE_CODE(bref.pack(crs_im_tm1_to_tm9_one_rx_port_v1540_present, 1)); - HANDLE_CODE(bref.pack(cch_im_ref_rec_type_a_one_rx_port_v1540_present, 1)); + HANDLE_CODE(bref.pack(sl_param_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(dummy_present, 1)); + + if (sl_param_nr_r16_present) { + HANDLE_CODE(sl_param_nr_r16.pack(bref)); + } + if (dummy_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, dummy, 1, 512)); + } return SRSASN_SUCCESS; } -SRSASN_CODE phy_layer_params_v1540_s::unpack(cbit_ref& bref) +SRSASN_CODE sl_params_v1610_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(stti_spt_cap_v1540_present, 1)); - HANDLE_CODE(bref.unpack(crs_im_tm1_to_tm9_one_rx_port_v1540_present, 1)); - HANDLE_CODE(bref.unpack(cch_im_ref_rec_type_a_one_rx_port_v1540_present, 1)); + HANDLE_CODE(bref.unpack(sl_param_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(dummy_present, 1)); + + if (sl_param_nr_r16_present) { + HANDLE_CODE(sl_param_nr_r16.unpack(bref)); + } + if (dummy_present) { + HANDLE_CODE(unpack_dyn_seq_of(dummy, bref, 1, 512)); + } return SRSASN_SUCCESS; } -void phy_layer_params_v1540_s::to_json(json_writer& j) const +void sl_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (sl_param_nr_r16_present) { + j.write_str("sl-ParameterNR-r16", sl_param_nr_r16.to_string()); + } + if (dummy_present) { + j.start_array("dummy"); + for (const auto& e1 : dummy) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// V2X-BandParametersEUTRA-NR-v1630 ::= CHOICE +void v2x_band_params_eutra_nr_v1630_c::set(types::options e) +{ + type_ = e; +} +void v2x_band_params_eutra_nr_v1630_c::set_eutra() +{ + set(types::eutra); +} +v2x_band_params_eutra_nr_v1630_c::nr_s_& v2x_band_params_eutra_nr_v1630_c::set_nr() +{ + set(types::nr); + return c; +} +void v2x_band_params_eutra_nr_v1630_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::eutra: + break; + case types::nr: + j.write_fieldname("nr"); + j.start_obj(); + if (c.tx_sidelink_r16_present) { + j.write_str("tx-Sidelink-r16", "supported"); + } + if (c.rx_sidelink_r16_present) { + j.write_str("rx-Sidelink-r16", "supported"); + } + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "v2x_band_params_eutra_nr_v1630_c"); + } + j.end_obj(); +} +SRSASN_CODE v2x_band_params_eutra_nr_v1630_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::eutra: + break; + case types::nr: + HANDLE_CODE(bref.pack(c.tx_sidelink_r16_present, 1)); + HANDLE_CODE(bref.pack(c.rx_sidelink_r16_present, 1)); + break; + default: + log_invalid_choice_id(type_, "v2x_band_params_eutra_nr_v1630_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE v2x_band_params_eutra_nr_v1630_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::eutra: + break; + case types::nr: + HANDLE_CODE(bref.unpack(c.tx_sidelink_r16_present, 1)); + HANDLE_CODE(bref.unpack(c.rx_sidelink_r16_present, 1)); + break; + default: + log_invalid_choice_id(type_, "v2x_band_params_eutra_nr_v1630_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +// V2X-BandCombinationParametersEUTRA-NR-v1630 ::= SEQUENCE +SRSASN_CODE v2x_band_combination_params_eutra_nr_v1630_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_dyn_seq_of(bref, band_list_sidelink_eutra_nr_r16, 1, 64)); + HANDLE_CODE(pack_dyn_seq_of(bref, band_list_sidelink_eutra_nr_v1630, 1, 64)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE v2x_band_combination_params_eutra_nr_v1630_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_dyn_seq_of(band_list_sidelink_eutra_nr_r16, bref, 1, 64)); + HANDLE_CODE(unpack_dyn_seq_of(band_list_sidelink_eutra_nr_v1630, bref, 1, 64)); + + return SRSASN_SUCCESS; +} +void v2x_band_combination_params_eutra_nr_v1630_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("bandListSidelinkEUTRA-NR-r16"); + for (const auto& e1 : band_list_sidelink_eutra_nr_r16) { + e1.to_json(j); + } + j.end_array(); + j.start_array("bandListSidelinkEUTRA-NR-v1630"); + for (const auto& e1 : band_list_sidelink_eutra_nr_v1630) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// SL-Parameters-v1630 ::= SEQUENCE +SRSASN_CODE sl_params_v1630_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(v2x_supported_band_combination_list_eutra_nr_r16_present, 1)); + + if (v2x_supported_band_combination_list_eutra_nr_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, v2x_supported_band_combination_list_eutra_nr_r16, 1, 512)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sl_params_v1630_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(v2x_supported_band_combination_list_eutra_nr_r16_present, 1)); + + if (v2x_supported_band_combination_list_eutra_nr_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(v2x_supported_band_combination_list_eutra_nr_r16, bref, 1, 512)); + } + + return SRSASN_SUCCESS; +} +void sl_params_v1630_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (v2x_supported_band_combination_list_eutra_nr_r16_present) { + j.start_array("v2x-SupportedBandCombinationListEUTRA-NR-r16"); + for (const auto& e1 : v2x_supported_band_combination_list_eutra_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); +} + +// V2X-BandParametersEUTRA-NR-v1710 ::= SEQUENCE +SRSASN_CODE v2x_band_params_eutra_nr_v1710_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(v2x_band_params_eutra_nr_v1710_present, 1)); + + if (v2x_band_params_eutra_nr_v1710_present) { + HANDLE_CODE(v2x_band_params_eutra_nr_v1710.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE v2x_band_params_eutra_nr_v1710_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(v2x_band_params_eutra_nr_v1710_present, 1)); + + if (v2x_band_params_eutra_nr_v1710_present) { + HANDLE_CODE(v2x_band_params_eutra_nr_v1710.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void v2x_band_params_eutra_nr_v1710_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (v2x_band_params_eutra_nr_v1710_present) { + j.write_str("v2x-BandParametersEUTRA-NR-v1710", v2x_band_params_eutra_nr_v1710.to_string()); + } + j.end_obj(); +} + +// SL-Parameters-v1710 ::= SEQUENCE +SRSASN_CODE sl_params_v1710_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(v2x_supported_band_combination_list_eutra_nr_v1710_present, 1)); + + if (v2x_supported_band_combination_list_eutra_nr_v1710_present) { + HANDLE_CODE(pack_dyn_seq_of( + bref, v2x_supported_band_combination_list_eutra_nr_v1710, 1, 512, SeqOfPacker(1, 64, Packer()))); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sl_params_v1710_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(v2x_supported_band_combination_list_eutra_nr_v1710_present, 1)); + + if (v2x_supported_band_combination_list_eutra_nr_v1710_present) { + HANDLE_CODE(unpack_dyn_seq_of( + v2x_supported_band_combination_list_eutra_nr_v1710, bref, 1, 512, SeqOfPacker(1, 64, Packer()))); + } + + return SRSASN_SUCCESS; +} +void sl_params_v1710_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (v2x_supported_band_combination_list_eutra_nr_v1710_present) { + j.start_array("v2x-SupportedBandCombinationListEUTRA-NR-v1710"); + for (const auto& e1 : v2x_supported_band_combination_list_eutra_nr_v1710) { + j.start_array(); + for (const auto& e2 : e1) { + e2.to_json(j); + } + j.end_array(); + } + j.end_array(); + } + j.end_obj(); +} + +// PhyLayerParameters-v1730 ::= SEQUENCE +SRSASN_CODE phy_layer_params_v1730_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(csi_sf_set2_for_dormant_scell_r17_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE phy_layer_params_v1730_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(csi_sf_set2_for_dormant_scell_r17_present, 1)); + + return SRSASN_SUCCESS; +} +void phy_layer_params_v1730_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (csi_sf_set2_for_dormant_scell_r17_present) { + j.write_str("csi-SubframeSet2ForDormantSCell-r17", "supported"); + } + j.end_obj(); +} + +// NTN-Parameters-v1720 ::= SEQUENCE +SRSASN_CODE ntn_params_v1720_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ntn_segmented_precompensation_gaps_r17_present, 1)); + + if (ntn_segmented_precompensation_gaps_r17_present) { + HANDLE_CODE(ntn_segmented_precompensation_gaps_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ntn_params_v1720_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ntn_segmented_precompensation_gaps_r17_present, 1)); + + if (ntn_segmented_precompensation_gaps_r17_present) { + HANDLE_CODE(ntn_segmented_precompensation_gaps_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ntn_params_v1720_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ntn_segmented_precompensation_gaps_r17_present) { + j.write_str("ntn-SegmentedPrecompensationGaps-r17", ntn_segmented_precompensation_gaps_r17.to_string()); + } + j.end_obj(); +} + +const char* ntn_params_v1720_s::ntn_segmented_precompensation_gaps_r17_opts::to_string() const +{ + static const char* options[] = {"sym1", "sl1", "sf1"}; + return convert_enum_idx(options, 3, value, "ntn_params_v1720_s::ntn_segmented_precompensation_gaps_r17_e_"); +} + +// UE-EUTRA-Capability-v1730-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v1730_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(phy_layer_params_v1730.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v1730_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(phy_layer_params_v1730.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v1730_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("phyLayerParameters-v1730"); + phy_layer_params_v1730.to_json(j); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// IRAT-ParametersNR-v1710 ::= SEQUENCE +SRSASN_CODE irat_params_nr_v1710_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(extended_band_n77_minus2_r17_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE irat_params_nr_v1710_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(extended_band_n77_minus2_r17_present, 1)); + + return SRSASN_SUCCESS; +} +void irat_params_nr_v1710_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (extended_band_n77_minus2_r17_present) { + j.write_str("extendedBand-n77-2-r17", "supported"); + } + j.end_obj(); +} + +// NeighCellSI-AcquisitionParameters-v1710 ::= SEQUENCE +SRSASN_CODE neigh_cell_si_acquisition_params_v1710_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(gnb_id_len_report_nr_en_dc_r17_present, 1)); + HANDLE_CODE(bref.pack(gnb_id_len_report_nr_no_en_dc_r17_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE neigh_cell_si_acquisition_params_v1710_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(gnb_id_len_report_nr_en_dc_r17_present, 1)); + HANDLE_CODE(bref.unpack(gnb_id_len_report_nr_no_en_dc_r17_present, 1)); + + return SRSASN_SUCCESS; +} +void neigh_cell_si_acquisition_params_v1710_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (gnb_id_len_report_nr_en_dc_r17_present) { + j.write_str("gNB-ID-Length-Reporting-NR-EN-DC-r17", "supported"); + } + if (gnb_id_len_report_nr_no_en_dc_r17_present) { + j.write_str("gNB-ID-Length-Reporting-NR-NoEN-DC-r17", "supported"); + } + j.end_obj(); +} + +// UE-EUTRA-Capability-v1720-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v1720_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(ntn_params_v1720.pack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v1720_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(ntn_params_v1720.unpack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v1720_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ntn-Parameters-v1720"); + ntn_params_v1720.to_json(j); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// IRAT-ParametersNR-v1700 ::= SEQUENCE +SRSASN_CODE irat_params_nr_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(eutra_minus5_gc_ho_to_nr_tdd_fr2_minus2_r17_present, 1)); + HANDLE_CODE(bref.pack(eutra_epc_ho_to_nr_tdd_fr2_minus2_r17_present, 1)); + HANDLE_CODE(bref.pack(ce_eutra_minus5_gc_ho_to_nr_tdd_fr2_minus2_r17_present, 1)); + HANDLE_CODE(bref.pack(ims_voice_over_nr_fr2_minus2_r17_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE irat_params_nr_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(eutra_minus5_gc_ho_to_nr_tdd_fr2_minus2_r17_present, 1)); + HANDLE_CODE(bref.unpack(eutra_epc_ho_to_nr_tdd_fr2_minus2_r17_present, 1)); + HANDLE_CODE(bref.unpack(ce_eutra_minus5_gc_ho_to_nr_tdd_fr2_minus2_r17_present, 1)); + HANDLE_CODE(bref.unpack(ims_voice_over_nr_fr2_minus2_r17_present, 1)); + + return SRSASN_SUCCESS; +} +void irat_params_nr_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (eutra_minus5_gc_ho_to_nr_tdd_fr2_minus2_r17_present) { + j.write_str("eutra-5GC-HO-ToNR-TDD-FR2-2-r17", "supported"); + } + if (eutra_epc_ho_to_nr_tdd_fr2_minus2_r17_present) { + j.write_str("eutra-EPC-HO-ToNR-TDD-FR2-2-r17", "supported"); + } + if (ce_eutra_minus5_gc_ho_to_nr_tdd_fr2_minus2_r17_present) { + j.write_str("ce-EUTRA-5GC-HO-ToNR-TDD-FR2-2-r17", "supported"); + } + if (ims_voice_over_nr_fr2_minus2_r17_present) { + j.write_str("ims-VoiceOverNR-FR2-2-r17", "supported"); + } + j.end_obj(); +} + +// NTN-Parameters-r17 ::= SEQUENCE +SRSASN_CODE ntn_params_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ntn_connect_epc_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_ta_report_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_pur_timer_delay_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_offset_timing_enh_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_scenario_support_r17_present, 1)); + + if (ntn_scenario_support_r17_present) { + HANDLE_CODE(ntn_scenario_support_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ntn_params_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ntn_connect_epc_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_ta_report_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_pur_timer_delay_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_offset_timing_enh_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_scenario_support_r17_present, 1)); + + if (ntn_scenario_support_r17_present) { + HANDLE_CODE(ntn_scenario_support_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ntn_params_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ntn_connect_epc_r17_present) { + j.write_str("ntn-Connectivity-EPC-r17", "supported"); + } + if (ntn_ta_report_r17_present) { + j.write_str("ntn-TA-Report-r17", "supported"); + } + if (ntn_pur_timer_delay_r17_present) { + j.write_str("ntn-PUR-TimerDelay-r17", "supported"); + } + if (ntn_offset_timing_enh_r17_present) { + j.write_str("ntn-OffsetTimingEnh-r17", "supported"); + } + if (ntn_scenario_support_r17_present) { + j.write_str("ntn-ScenarioSupport-r17", ntn_scenario_support_r17.to_string()); + } + j.end_obj(); +} + +const char* ntn_params_r17_s::ntn_scenario_support_r17_opts::to_string() const +{ + static const char* options[] = {"ngso", "gso"}; + return convert_enum_idx(options, 2, value, "ntn_params_r17_s::ntn_scenario_support_r17_e_"); +} + +// PhyLayerParameters-v1700 ::= SEQUENCE +SRSASN_CODE phy_layer_params_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ce_cap_v1700_present, 1)); + + if (ce_cap_v1700_present) { + HANDLE_CODE(bref.pack(ce_cap_v1700.ce_pdsch_minus14_harq_processes_r17_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1700.ce_pdsch_minus14_harq_processes_alt2_r17_present, 1)); + HANDLE_CODE(bref.pack(ce_cap_v1700.ce_pdsch_max_tbs_r17_present, 1)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE phy_layer_params_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ce_cap_v1700_present, 1)); + + if (ce_cap_v1700_present) { + HANDLE_CODE(bref.unpack(ce_cap_v1700.ce_pdsch_minus14_harq_processes_r17_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1700.ce_pdsch_minus14_harq_processes_alt2_r17_present, 1)); + HANDLE_CODE(bref.unpack(ce_cap_v1700.ce_pdsch_max_tbs_r17_present, 1)); + } + + return SRSASN_SUCCESS; +} +void phy_layer_params_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ce_cap_v1700_present) { + j.write_fieldname("ce-Capabilities-v1700"); + j.start_obj(); + if (ce_cap_v1700.ce_pdsch_minus14_harq_processes_r17_present) { + j.write_str("ce-PDSCH-14HARQProcesses-r17", "supported"); + } + if (ce_cap_v1700.ce_pdsch_minus14_harq_processes_alt2_r17_present) { + j.write_str("ce-PDSCH-14HARQProcesses-Alt2-r17", "supported"); + } + if (ce_cap_v1700.ce_pdsch_max_tbs_r17_present) { + j.write_str("ce-PDSCH-MaxTBS-r17", "supported"); + } + j.end_obj(); + } + j.end_obj(); +} + +// UE-BasedNetwPerfMeasParameters-v1700 ::= SEQUENCE +SRSASN_CODE ue_based_netw_perf_meas_params_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(logged_meas_idle_event_l1_r17_present, 1)); + HANDLE_CODE(bref.pack(logged_meas_idle_event_out_of_coverage_r17_present, 1)); + HANDLE_CODE(bref.pack(logged_meas_uncom_bar_pre_r17_present, 1)); + HANDLE_CODE(bref.pack(imm_meas_uncom_bar_pre_r17_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_based_netw_perf_meas_params_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(logged_meas_idle_event_l1_r17_present, 1)); + HANDLE_CODE(bref.unpack(logged_meas_idle_event_out_of_coverage_r17_present, 1)); + HANDLE_CODE(bref.unpack(logged_meas_uncom_bar_pre_r17_present, 1)); + HANDLE_CODE(bref.unpack(imm_meas_uncom_bar_pre_r17_present, 1)); + + return SRSASN_SUCCESS; +} +void ue_based_netw_perf_meas_params_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (logged_meas_idle_event_l1_r17_present) { + j.write_str("loggedMeasIdleEventL1-r17", "supported"); + } + if (logged_meas_idle_event_out_of_coverage_r17_present) { + j.write_str("loggedMeasIdleEventOutOfCoverage-r17", "supported"); + } + if (logged_meas_uncom_bar_pre_r17_present) { + j.write_str("loggedMeasUncomBarPre-r17", "supported"); + } + if (imm_meas_uncom_bar_pre_r17_present) { + j.write_str("immMeasUncomBarPre-r17", "supported"); + } + j.end_obj(); +} + +// UE-EUTRA-Capability-v1710-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v1710_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(neigh_cell_si_acquisition_params_v1710_present, 1)); + HANDLE_CODE(bref.pack(sl_params_v1710_present, 1)); + HANDLE_CODE(bref.pack(sidelink_requested_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(irat_params_nr_v1710.pack(bref)); + if (neigh_cell_si_acquisition_params_v1710_present) { + HANDLE_CODE(neigh_cell_si_acquisition_params_v1710.pack(bref)); + } + if (sl_params_v1710_present) { + HANDLE_CODE(sl_params_v1710.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v1710_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(neigh_cell_si_acquisition_params_v1710_present, 1)); + HANDLE_CODE(bref.unpack(sl_params_v1710_present, 1)); + HANDLE_CODE(bref.unpack(sidelink_requested_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(irat_params_nr_v1710.unpack(bref)); + if (neigh_cell_si_acquisition_params_v1710_present) { + HANDLE_CODE(neigh_cell_si_acquisition_params_v1710.unpack(bref)); + } + if (sl_params_v1710_present) { + HANDLE_CODE(sl_params_v1710.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v1710_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("irat-ParametersNR-v1710"); + irat_params_nr_v1710.to_json(j); + if (neigh_cell_si_acquisition_params_v1710_present) { + j.write_fieldname("neighCellSI-AcquisitionParameters-v1710"); + neigh_cell_si_acquisition_params_v1710.to_json(j); + } + if (sl_params_v1710_present) { + j.write_fieldname("sl-Parameters-v1710"); + sl_params_v1710.to_json(j); + } + if (sidelink_requested_r17_present) { + j.write_str("sidelinkRequested-r17", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// Other-Parameters-v1690 ::= SEQUENCE +SRSASN_CODE other_params_v1690_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ul_rrc_segmentation_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE other_params_v1690_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ul_rrc_segmentation_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void other_params_v1690_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ul_rrc_segmentation_r16_present) { + j.write_str("ul-RRC-Segmentation-r16", "supported"); + } + j.end_obj(); +} + +// UE-EUTRA-Capability-v1700-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v1700_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(meas_params_v1700_present, 1)); + HANDLE_CODE(bref.pack(ue_based_netw_perf_meas_params_v1700_present, 1)); + HANDLE_CODE(bref.pack(ntn_params_r17_present, 1)); + HANDLE_CODE(bref.pack(irat_params_nr_v1700_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (meas_params_v1700_present) { + HANDLE_CODE(meas_params_v1700.pack(bref)); + } + if (ue_based_netw_perf_meas_params_v1700_present) { + HANDLE_CODE(ue_based_netw_perf_meas_params_v1700.pack(bref)); + } + HANDLE_CODE(phy_layer_params_v1700.pack(bref)); + if (ntn_params_r17_present) { + HANDLE_CODE(ntn_params_r17.pack(bref)); + } + if (irat_params_nr_v1700_present) { + HANDLE_CODE(irat_params_nr_v1700.pack(bref)); + } + HANDLE_CODE(mbms_params_v1700.pack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(meas_params_v1700_present, 1)); + HANDLE_CODE(bref.unpack(ue_based_netw_perf_meas_params_v1700_present, 1)); + HANDLE_CODE(bref.unpack(ntn_params_r17_present, 1)); + HANDLE_CODE(bref.unpack(irat_params_nr_v1700_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (meas_params_v1700_present) { + HANDLE_CODE(meas_params_v1700.unpack(bref)); + } + if (ue_based_netw_perf_meas_params_v1700_present) { + HANDLE_CODE(ue_based_netw_perf_meas_params_v1700.unpack(bref)); + } + HANDLE_CODE(phy_layer_params_v1700.unpack(bref)); + if (ntn_params_r17_present) { + HANDLE_CODE(ntn_params_r17.unpack(bref)); + } + if (irat_params_nr_v1700_present) { + HANDLE_CODE(irat_params_nr_v1700.unpack(bref)); + } + HANDLE_CODE(mbms_params_v1700.unpack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (meas_params_v1700_present) { + j.write_fieldname("measParameters-v1700"); + meas_params_v1700.to_json(j); + } + if (ue_based_netw_perf_meas_params_v1700_present) { + j.write_fieldname("ue-BasedNetwPerfMeasParameters-v1700"); + ue_based_netw_perf_meas_params_v1700.to_json(j); + } + j.write_fieldname("phyLayerParameters-v1700"); + phy_layer_params_v1700.to_json(j); + if (ntn_params_r17_present) { + j.write_fieldname("ntn-Parameters-r17"); + ntn_params_r17.to_json(j); + } + if (irat_params_nr_v1700_present) { + j.write_fieldname("irat-ParametersNR-v1700"); + irat_params_nr_v1700.to_json(j); + } + j.write_fieldname("mbms-Parameters-v1700"); + mbms_params_v1700.to_json(j); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// IRAT-ParametersNR-v1660 ::= SEQUENCE +SRSASN_CODE irat_params_nr_v1660_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(extended_band_n77_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE irat_params_nr_v1660_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(extended_band_n77_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void irat_params_nr_v1660_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (extended_band_n77_r16_present) { + j.write_str("extendedBand-n77-r16", "supported"); + } + j.end_obj(); +} + +// UE-EUTRA-Capability-v1690-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v1690_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(other_params_v1690.pack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v1690_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(other_params_v1690.unpack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v1690_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("other-Parameters-v1690"); + other_params_v1690.to_json(j); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// MeasParameters-v1630 ::= SEQUENCE +SRSASN_CODE meas_params_v1630_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(nr_idle_inactive_beam_meas_fr1_r16_present, 1)); + HANDLE_CODE(bref.pack(nr_idle_inactive_beam_meas_fr2_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_meas_rss_ded_same_rbs_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_params_v1630_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(nr_idle_inactive_beam_meas_fr1_r16_present, 1)); + HANDLE_CODE(bref.unpack(nr_idle_inactive_beam_meas_fr2_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_meas_rss_ded_same_rbs_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void meas_params_v1630_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (nr_idle_inactive_beam_meas_fr1_r16_present) { + j.write_str("nr-IdleInactiveBeamMeasFR1-r16", "supported"); + } + if (nr_idle_inactive_beam_meas_fr2_r16_present) { + j.write_str("nr-IdleInactiveBeamMeasFR2-r16", "supported"); + } + if (ce_meas_rss_ded_same_rbs_r16_present) { + j.write_str("ce-MeasRSS-DedicatedSameRBs-r16", "supported"); + } + j.end_obj(); +} + +// Other-Parameters-v1650 ::= SEQUENCE +SRSASN_CODE other_params_v1650_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(mps_prio_ind_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE other_params_v1650_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(mps_prio_ind_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void other_params_v1650_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (mps_prio_ind_r16_present) { + j.write_str("mpsPriorityIndication-r16", "supported"); + } + j.end_obj(); +} + +// UE-EUTRA-Capability-v1660-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v1660_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(irat_params_nr_v1660.pack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v1660_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(irat_params_nr_v1660.unpack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v1660_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("irat-ParametersNR-v1660"); + irat_params_nr_v1660.to_json(j); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// EUTRA-5GC-Parameters-v1610 ::= SEQUENCE +SRSASN_CODE eutra_minus5_gc_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ce_inactive_state_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_eutra_minus5_gc_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE eutra_minus5_gc_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ce_inactive_state_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_eutra_minus5_gc_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void eutra_minus5_gc_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ce_inactive_state_r16_present) { + j.write_str("ce-InactiveState-r16", "supported"); + } + if (ce_eutra_minus5_gc_r16_present) { + j.write_str("ce-EUTRA-5GC-r16", "supported"); + } + j.end_obj(); +} + +// IRAT-ParametersNR-v1610 ::= SEQUENCE +SRSASN_CODE irat_params_nr_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(nr_ho_to_en_dc_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_eutra_minus5_gc_ho_to_nr_fdd_fr1_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_eutra_minus5_gc_ho_to_nr_tdd_fr1_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_eutra_minus5_gc_ho_to_nr_fdd_fr2_r16_present, 1)); + HANDLE_CODE(bref.pack(ce_eutra_minus5_gc_ho_to_nr_tdd_fr2_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE irat_params_nr_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(nr_ho_to_en_dc_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_eutra_minus5_gc_ho_to_nr_fdd_fr1_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_eutra_minus5_gc_ho_to_nr_tdd_fr1_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_eutra_minus5_gc_ho_to_nr_fdd_fr2_r16_present, 1)); + HANDLE_CODE(bref.unpack(ce_eutra_minus5_gc_ho_to_nr_tdd_fr2_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void irat_params_nr_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (nr_ho_to_en_dc_r16_present) { + j.write_str("nr-HO-ToEN-DC-r16", "supported"); + } + if (ce_eutra_minus5_gc_ho_to_nr_fdd_fr1_r16_present) { + j.write_str("ce-EUTRA-5GC-HO-ToNR-FDD-FR1-r16", "supported"); + } + if (ce_eutra_minus5_gc_ho_to_nr_tdd_fr1_r16_present) { + j.write_str("ce-EUTRA-5GC-HO-ToNR-TDD-FR1-r16", "supported"); + } + if (ce_eutra_minus5_gc_ho_to_nr_fdd_fr2_r16_present) { + j.write_str("ce-EUTRA-5GC-HO-ToNR-FDD-FR2-r16", "supported"); + } + if (ce_eutra_minus5_gc_ho_to_nr_tdd_fr2_r16_present) { + j.write_str("ce-EUTRA-5GC-HO-ToNR-TDD-FR2-r16", "supported"); + } + j.end_obj(); +} + +// MAC-Parameters-v1630 ::= SEQUENCE +SRSASN_CODE mac_params_v1630_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(direct_scg_scell_activation_nedc_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mac_params_v1630_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(direct_scg_scell_activation_nedc_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void mac_params_v1630_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (direct_scg_scell_activation_nedc_r16_present) { + j.write_str("directSCG-SCellActivationNEDC-r16", "supported"); + } + j.end_obj(); +} + +// MobilityParameters-v1610 ::= SEQUENCE +SRSASN_CODE mob_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(cho_r16_present, 1)); + HANDLE_CODE(bref.pack(cho_fdd_tdd_r16_present, 1)); + HANDLE_CODE(bref.pack(cho_fail_r16_present, 1)); + HANDLE_CODE(bref.pack(cho_two_trigger_events_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mob_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(cho_r16_present, 1)); + HANDLE_CODE(bref.unpack(cho_fdd_tdd_r16_present, 1)); + HANDLE_CODE(bref.unpack(cho_fail_r16_present, 1)); + HANDLE_CODE(bref.unpack(cho_two_trigger_events_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void mob_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (cho_r16_present) { + j.write_str("cho-r16", "supported"); + } + if (cho_fdd_tdd_r16_present) { + j.write_str("cho-FDD-TDD-r16", "supported"); + } + if (cho_fail_r16_present) { + j.write_str("cho-Failure-r16", "supported"); + } + if (cho_two_trigger_events_r16_present) { + j.write_str("cho-TwoTriggerEvents-r16", "supported"); + } + j.end_obj(); +} + +// NeighCellSI-AcquisitionParameters-v1610 ::= SEQUENCE +SRSASN_CODE neigh_cell_si_acquisition_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(eutra_si_acquisition_for_ho_endc_r16_present, 1)); + HANDLE_CODE(bref.pack(nr_autonomous_gaps_endc_fr1_r16_present, 1)); + HANDLE_CODE(bref.pack(nr_autonomous_gaps_endc_fr2_r16_present, 1)); + HANDLE_CODE(bref.pack(nr_autonomous_gaps_fr1_r16_present, 1)); + HANDLE_CODE(bref.pack(nr_autonomous_gaps_fr2_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE neigh_cell_si_acquisition_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(eutra_si_acquisition_for_ho_endc_r16_present, 1)); + HANDLE_CODE(bref.unpack(nr_autonomous_gaps_endc_fr1_r16_present, 1)); + HANDLE_CODE(bref.unpack(nr_autonomous_gaps_endc_fr2_r16_present, 1)); + HANDLE_CODE(bref.unpack(nr_autonomous_gaps_fr1_r16_present, 1)); + HANDLE_CODE(bref.unpack(nr_autonomous_gaps_fr2_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void neigh_cell_si_acquisition_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (eutra_si_acquisition_for_ho_endc_r16_present) { + j.write_str("eutra-SI-AcquisitionForHO-ENDC-r16", "supported"); + } + if (nr_autonomous_gaps_endc_fr1_r16_present) { + j.write_str("nr-AutonomousGaps-ENDC-FR1-r16", "supported"); + } + if (nr_autonomous_gaps_endc_fr2_r16_present) { + j.write_str("nr-AutonomousGaps-ENDC-FR2-r16", "supported"); + } + if (nr_autonomous_gaps_fr1_r16_present) { + j.write_str("nr-AutonomousGaps-FR1-r16", "supported"); + } + if (nr_autonomous_gaps_fr2_r16_present) { + j.write_str("nr-AutonomousGaps-FR2-r16", "supported"); + } + j.end_obj(); +} + +// PUR-Parameters-r16 ::= SEQUENCE +SRSASN_CODE pur_params_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pur_cp_minus5_gc_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_cp_minus5_gc_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_up_minus5_gc_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_up_minus5_gc_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_cp_epc_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_cp_epc_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_up_epc_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_up_epc_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_cp_l1_ack_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_freq_hop_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_pusch_nb_max_tbs_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_rsrp_validation_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_sub_prb_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_sub_prb_ce_mode_b_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE pur_params_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(pur_cp_minus5_gc_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_cp_minus5_gc_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_up_minus5_gc_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_up_minus5_gc_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_cp_epc_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_cp_epc_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_up_epc_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_up_epc_ce_mode_b_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_cp_l1_ack_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_freq_hop_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_pusch_nb_max_tbs_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_rsrp_validation_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_sub_prb_ce_mode_a_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_sub_prb_ce_mode_b_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void pur_params_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (pur_cp_minus5_gc_ce_mode_a_r16_present) { + j.write_str("pur-CP-5GC-CE-ModeA-r16", "supported"); + } + if (pur_cp_minus5_gc_ce_mode_b_r16_present) { + j.write_str("pur-CP-5GC-CE-ModeB-r16", "supported"); + } + if (pur_up_minus5_gc_ce_mode_a_r16_present) { + j.write_str("pur-UP-5GC-CE-ModeA-r16", "supported"); + } + if (pur_up_minus5_gc_ce_mode_b_r16_present) { + j.write_str("pur-UP-5GC-CE-ModeB-r16", "supported"); + } + if (pur_cp_epc_ce_mode_a_r16_present) { + j.write_str("pur-CP-EPC-CE-ModeA-r16", "supported"); + } + if (pur_cp_epc_ce_mode_b_r16_present) { + j.write_str("pur-CP-EPC-CE-ModeB-r16", "supported"); + } + if (pur_up_epc_ce_mode_a_r16_present) { + j.write_str("pur-UP-EPC-CE-ModeA-r16", "supported"); + } + if (pur_up_epc_ce_mode_b_r16_present) { + j.write_str("pur-UP-EPC-CE-ModeB-r16", "supported"); + } + if (pur_cp_l1_ack_r16_present) { + j.write_str("pur-CP-L1Ack-r16", "supported"); + } + if (pur_freq_hop_r16_present) { + j.write_str("pur-FrequencyHopping-r16", "supported"); + } + if (pur_pusch_nb_max_tbs_r16_present) { + j.write_str("pur-PUSCH-NB-MaxTBS-r16", "supported"); + } + if (pur_rsrp_validation_r16_present) { + j.write_str("pur-RSRP-Validation-r16", "supported"); + } + if (pur_sub_prb_ce_mode_a_r16_present) { + j.write_str("pur-SubPRB-CE-ModeA-r16", "supported"); + } + if (pur_sub_prb_ce_mode_b_r16_present) { + j.write_str("pur-SubPRB-CE-ModeB-r16", "supported"); + } + j.end_obj(); +} + +// UE-EUTRA-Capability-v1650-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v1650_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(other_params_v1650_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (other_params_v1650_present) { + HANDLE_CODE(other_params_v1650.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v1650_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(other_params_v1650_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (other_params_v1650_present) { + HANDLE_CODE(other_params_v1650.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v1650_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (other_params_v1650_present) { + j.write_fieldname("otherParameters-v1650"); + other_params_v1650.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// UE-EUTRA-CapabilityAddXDD-Mode-v1630 ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_add_xdd_mode_v1630_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(meas_params_v1630.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_add_xdd_mode_v1630_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(meas_params_v1630.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_add_xdd_mode_v1630_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measParameters-v1630"); + meas_params_v1630.to_json(j); + j.end_obj(); +} + +// HighSpeedEnhParameters-v1610 ::= SEQUENCE +SRSASN_CODE high_speed_enh_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(meas_enhance_scell_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_enhance2_r16_present, 1)); + HANDLE_CODE(bref.pack(demod_enhance2_r16_present, 1)); + HANDLE_CODE(bref.pack(inter_rat_enhancement_nr_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE high_speed_enh_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(meas_enhance_scell_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_enhance2_r16_present, 1)); + HANDLE_CODE(bref.unpack(demod_enhance2_r16_present, 1)); + HANDLE_CODE(bref.unpack(inter_rat_enhancement_nr_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void high_speed_enh_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (meas_enhance_scell_r16_present) { + j.write_str("measurementEnhancementsSCell-r16", "supported"); + } + if (meas_enhance2_r16_present) { + j.write_str("measurementEnhancements2-r16", "supported"); + } + if (demod_enhance2_r16_present) { + j.write_str("demodulationEnhancements2-r16", "supported"); + } + if (inter_rat_enhancement_nr_r16_present) { + j.write_str("interRAT-enhancementNR-r16", "supported"); + } + j.end_obj(); +} + +// MAC-Parameters-v1610 ::= SEQUENCE +SRSASN_CODE mac_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(direct_mcg_scell_activation_resume_r16_present, 1)); + HANDLE_CODE(bref.pack(direct_scg_scell_activation_resume_r16_present, 1)); + HANDLE_CODE(bref.pack(early_data_up_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(rai_support_enh_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mac_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(direct_mcg_scell_activation_resume_r16_present, 1)); + HANDLE_CODE(bref.unpack(direct_scg_scell_activation_resume_r16_present, 1)); + HANDLE_CODE(bref.unpack(early_data_up_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(rai_support_enh_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void mac_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (direct_mcg_scell_activation_resume_r16_present) { + j.write_str("directMCG-SCellActivationResume-r16", "supported"); + } + if (direct_scg_scell_activation_resume_r16_present) { + j.write_str("directSCG-SCellActivationResume-r16", "supported"); + } + if (early_data_up_minus5_gc_r16_present) { + j.write_str("earlyData-UP-5GC-r16", "supported"); + } + if (rai_support_enh_r16_present) { + j.write_str("rai-SupportEnh-r16", "supported"); + } + j.end_obj(); +} + +// MMTEL-Parameters-v1610 ::= SEQUENCE +SRSASN_CODE mmtel_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(recommended_bit_rate_multiplier_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mmtel_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(recommended_bit_rate_multiplier_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void mmtel_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (recommended_bit_rate_multiplier_r16_present) { + j.write_str("recommendedBitRateMultiplier-r16", "supported"); + } + j.end_obj(); +} + +// NeighCellSI-AcquisitionParameters-v15a0 ::= SEQUENCE +SRSASN_CODE neigh_cell_si_acquisition_params_v15a0_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(eutra_cgi_report_nedc_r15_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE neigh_cell_si_acquisition_params_v15a0_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(eutra_cgi_report_nedc_r15_present, 1)); + + return SRSASN_SUCCESS; +} +void neigh_cell_si_acquisition_params_v15a0_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (eutra_cgi_report_nedc_r15_present) { + j.write_str("eutra-CGI-Reporting-NEDC-r15", "supported"); + } + j.end_obj(); +} + +// Other-Parameters-v1610 ::= SEQUENCE +SRSASN_CODE other_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(resume_with_stored_mcg_scells_r16_present, 1)); + HANDLE_CODE(bref.pack(resume_with_mcg_scell_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(resume_with_stored_scg_r16_present, 1)); + HANDLE_CODE(bref.pack(resume_with_scg_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(mcg_rlf_recovery_via_scg_r16_present, 1)); + HANDLE_CODE(bref.pack(overheat_ind_for_scg_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE other_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(resume_with_stored_mcg_scells_r16_present, 1)); + HANDLE_CODE(bref.unpack(resume_with_mcg_scell_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(resume_with_stored_scg_r16_present, 1)); + HANDLE_CODE(bref.unpack(resume_with_scg_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(mcg_rlf_recovery_via_scg_r16_present, 1)); + HANDLE_CODE(bref.unpack(overheat_ind_for_scg_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void other_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (resume_with_stored_mcg_scells_r16_present) { + j.write_str("resumeWithStoredMCG-SCells-r16", "supported"); + } + if (resume_with_mcg_scell_cfg_r16_present) { + j.write_str("resumeWithMCG-SCellConfig-r16", "supported"); + } + if (resume_with_stored_scg_r16_present) { + j.write_str("resumeWithStoredSCG-r16", "supported"); + } + if (resume_with_scg_cfg_r16_present) { + j.write_str("resumeWithSCG-Config-r16", "supported"); + } + if (mcg_rlf_recovery_via_scg_r16_present) { + j.write_str("mcgRLF-RecoveryViaSCG-r16", "supported"); + } + if (overheat_ind_for_scg_r16_present) { + j.write_str("overheatingIndForSCG-r16", "supported"); + } + j.end_obj(); +} + +// PDCP-Parameters-v1610 ::= SEQUENCE +SRSASN_CODE pdcp_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pdcp_version_change_without_ho_r16_present, 1)); + HANDLE_CODE(bref.pack(ehc_r16_present, 1)); + HANDLE_CODE(bref.pack(continue_ehc_context_r16_present, 1)); + HANDLE_CODE(bref.pack(max_num_ehc_contexts_r16_present, 1)); + HANDLE_CODE(bref.pack(joint_ehc_rohc_cfg_r16_present, 1)); + + if (max_num_ehc_contexts_r16_present) { + HANDLE_CODE(max_num_ehc_contexts_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdcp_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(pdcp_version_change_without_ho_r16_present, 1)); + HANDLE_CODE(bref.unpack(ehc_r16_present, 1)); + HANDLE_CODE(bref.unpack(continue_ehc_context_r16_present, 1)); + HANDLE_CODE(bref.unpack(max_num_ehc_contexts_r16_present, 1)); + HANDLE_CODE(bref.unpack(joint_ehc_rohc_cfg_r16_present, 1)); + + if (max_num_ehc_contexts_r16_present) { + HANDLE_CODE(max_num_ehc_contexts_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void pdcp_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (pdcp_version_change_without_ho_r16_present) { + j.write_str("pdcp-VersionChangeWithoutHO-r16", "supported"); + } + if (ehc_r16_present) { + j.write_str("ehc-r16", "supported"); + } + if (continue_ehc_context_r16_present) { + j.write_str("continueEHC-Context-r16", "supported"); + } + if (max_num_ehc_contexts_r16_present) { + j.write_str("maxNumberEHC-Contexts-r16", max_num_ehc_contexts_r16.to_string()); + } + if (joint_ehc_rohc_cfg_r16_present) { + j.write_str("jointEHC-ROHC-Config-r16", "supported"); + } + j.end_obj(); +} + +const char* pdcp_params_v1610_s::max_num_ehc_contexts_r16_opts::to_string() const +{ + static const char* options[] = {"cs2", + "cs4", + "cs8", + "cs16", + "cs32", + "cs64", + "cs128", + "cs256", + "cs512", + "cs1024", + "cs2048", + "cs4096", + "cs8192", + "cs16384", + "cs32768", + "cs65536"}; + return convert_enum_idx(options, 16, value, "pdcp_params_v1610_s::max_num_ehc_contexts_r16_e_"); +} +uint32_t pdcp_params_v1610_s::max_num_ehc_contexts_r16_opts::to_number() const +{ + static const uint32_t options[] = {2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536}; + return map_enum_number(options, 16, value, "pdcp_params_v1610_s::max_num_ehc_contexts_r16_e_"); +} + +// PhyLayerParameters-v1540 ::= SEQUENCE +SRSASN_CODE phy_layer_params_v1540_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(stti_spt_cap_v1540_present, 1)); + HANDLE_CODE(bref.pack(crs_im_tm1_to_tm9_one_rx_port_v1540_present, 1)); + HANDLE_CODE(bref.pack(cch_im_ref_rec_type_a_one_rx_port_v1540_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE phy_layer_params_v1540_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(stti_spt_cap_v1540_present, 1)); + HANDLE_CODE(bref.unpack(crs_im_tm1_to_tm9_one_rx_port_v1540_present, 1)); + HANDLE_CODE(bref.unpack(cch_im_ref_rec_type_a_one_rx_port_v1540_present, 1)); + + return SRSASN_SUCCESS; +} +void phy_layer_params_v1540_s::to_json(json_writer& j) const { j.start_obj(); if (stti_spt_cap_v1540_present) { @@ -8458,33 +11298,242 @@ void phy_layer_params_v1540_s::to_json(json_writer& j) const j.write_str("slotPDSCH-TxDiv-TM8-r15", "supported"); j.end_obj(); } - if (crs_im_tm1_to_tm9_one_rx_port_v1540_present) { - j.write_str("crs-IM-TM1-toTM9-OneRX-Port-v1540", "supported"); + if (crs_im_tm1_to_tm9_one_rx_port_v1540_present) { + j.write_str("crs-IM-TM1-toTM9-OneRX-Port-v1540", "supported"); + } + if (cch_im_ref_rec_type_a_one_rx_port_v1540_present) { + j.write_str("cch-IM-RefRecTypeA-OneRX-Port-v1540", "supported"); + } + j.end_obj(); +} + +// PhyLayerParameters-v1550 ::= SEQUENCE +SRSASN_CODE phy_layer_params_v1550_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(dmrs_overhead_reduction_r15_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE phy_layer_params_v1550_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(dmrs_overhead_reduction_r15_present, 1)); + + return SRSASN_SUCCESS; +} +void phy_layer_params_v1550_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (dmrs_overhead_reduction_r15_present) { + j.write_str("dmrs-OverheadReduction-r15", "supported"); + } + j.end_obj(); +} + +// UE-BasedNetwPerfMeasParameters-v1610 ::= SEQUENCE +SRSASN_CODE ue_based_netw_perf_meas_params_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ul_pdcp_avg_delay_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_based_netw_perf_meas_params_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ul_pdcp_avg_delay_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void ue_based_netw_perf_meas_params_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ul_pdcp_avg_delay_r16_present) { + j.write_str("ul-PDCP-AvgDelay-r16", "supported"); + } + j.end_obj(); +} + +// UE-EUTRA-Capability-v1630-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v1630_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(rf_params_v1630_present, 1)); + HANDLE_CODE(bref.pack(sl_params_v1630_present, 1)); + HANDLE_CODE(bref.pack(early_security_reactivation_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_params_v1630_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (rf_params_v1630_present) { + HANDLE_CODE(rf_params_v1630.pack(bref)); + } + if (sl_params_v1630_present) { + HANDLE_CODE(sl_params_v1630.pack(bref)); + } + HANDLE_CODE(mac_params_v1630.pack(bref)); + if (meas_params_v1630_present) { + HANDLE_CODE(meas_params_v1630.pack(bref)); + } + HANDLE_CODE(fdd_add_ue_eutra_cap_v1630.pack(bref)); + HANDLE_CODE(tdd_add_ue_eutra_cap_v1630.pack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v1630_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(rf_params_v1630_present, 1)); + HANDLE_CODE(bref.unpack(sl_params_v1630_present, 1)); + HANDLE_CODE(bref.unpack(early_security_reactivation_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_params_v1630_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (rf_params_v1630_present) { + HANDLE_CODE(rf_params_v1630.unpack(bref)); + } + if (sl_params_v1630_present) { + HANDLE_CODE(sl_params_v1630.unpack(bref)); + } + HANDLE_CODE(mac_params_v1630.unpack(bref)); + if (meas_params_v1630_present) { + HANDLE_CODE(meas_params_v1630.unpack(bref)); + } + HANDLE_CODE(fdd_add_ue_eutra_cap_v1630.unpack(bref)); + HANDLE_CODE(tdd_add_ue_eutra_cap_v1630.unpack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v1630_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (rf_params_v1630_present) { + j.write_fieldname("rf-Parameters-v1630"); + rf_params_v1630.to_json(j); + } + if (sl_params_v1630_present) { + j.write_fieldname("sl-Parameters-v1630"); + sl_params_v1630.to_json(j); } - if (cch_im_ref_rec_type_a_one_rx_port_v1540_present) { - j.write_str("cch-IM-RefRecTypeA-OneRX-Port-v1540", "supported"); + if (early_security_reactivation_r16_present) { + j.write_str("earlySecurityReactivation-r16", "supported"); + } + j.write_fieldname("mac-Parameters-v1630"); + mac_params_v1630.to_json(j); + if (meas_params_v1630_present) { + j.write_fieldname("measParameters-v1630"); + meas_params_v1630.to_json(j); + } + j.write_fieldname("fdd-Add-UE-EUTRA-Capabilities-v1630"); + fdd_add_ue_eutra_cap_v1630.to_json(j); + j.write_fieldname("tdd-Add-UE-EUTRA-Capabilities-v1630"); + tdd_add_ue_eutra_cap_v1630.to_json(j); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); } j.end_obj(); } -// PhyLayerParameters-v1550 ::= SEQUENCE -SRSASN_CODE phy_layer_params_v1550_s::pack(bit_ref& bref) const +// UE-EUTRA-CapabilityAddXDD-Mode-v1610 ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_add_xdd_mode_v1610_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(dmrs_overhead_reduction_r15_present, 1)); + HANDLE_CODE(bref.pack(phy_layer_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(pur_params_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(eutra_minus5_gc_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(irat_params_nr_v1610_present, 1)); + HANDLE_CODE(bref.pack(neigh_cell_si_acquisition_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(mob_params_v1610_present, 1)); + + if (phy_layer_params_v1610_present) { + HANDLE_CODE(phy_layer_params_v1610.pack(bref)); + } + if (pur_params_r16_present) { + HANDLE_CODE(pur_params_r16.pack(bref)); + } + if (meas_params_v1610_present) { + HANDLE_CODE(meas_params_v1610.pack(bref)); + } + if (eutra_minus5_gc_params_v1610_present) { + HANDLE_CODE(eutra_minus5_gc_params_v1610.pack(bref)); + } + if (irat_params_nr_v1610_present) { + HANDLE_CODE(irat_params_nr_v1610.pack(bref)); + } + if (neigh_cell_si_acquisition_params_v1610_present) { + HANDLE_CODE(neigh_cell_si_acquisition_params_v1610.pack(bref)); + } + if (mob_params_v1610_present) { + HANDLE_CODE(mob_params_v1610.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE phy_layer_params_v1550_s::unpack(cbit_ref& bref) +SRSASN_CODE ue_eutra_cap_add_xdd_mode_v1610_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(dmrs_overhead_reduction_r15_present, 1)); + HANDLE_CODE(bref.unpack(phy_layer_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(pur_params_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(eutra_minus5_gc_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(irat_params_nr_v1610_present, 1)); + HANDLE_CODE(bref.unpack(neigh_cell_si_acquisition_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(mob_params_v1610_present, 1)); + + if (phy_layer_params_v1610_present) { + HANDLE_CODE(phy_layer_params_v1610.unpack(bref)); + } + if (pur_params_r16_present) { + HANDLE_CODE(pur_params_r16.unpack(bref)); + } + if (meas_params_v1610_present) { + HANDLE_CODE(meas_params_v1610.unpack(bref)); + } + if (eutra_minus5_gc_params_v1610_present) { + HANDLE_CODE(eutra_minus5_gc_params_v1610.unpack(bref)); + } + if (irat_params_nr_v1610_present) { + HANDLE_CODE(irat_params_nr_v1610.unpack(bref)); + } + if (neigh_cell_si_acquisition_params_v1610_present) { + HANDLE_CODE(neigh_cell_si_acquisition_params_v1610.unpack(bref)); + } + if (mob_params_v1610_present) { + HANDLE_CODE(mob_params_v1610.unpack(bref)); + } return SRSASN_SUCCESS; } -void phy_layer_params_v1550_s::to_json(json_writer& j) const +void ue_eutra_cap_add_xdd_mode_v1610_s::to_json(json_writer& j) const { j.start_obj(); - if (dmrs_overhead_reduction_r15_present) { - j.write_str("dmrs-OverheadReduction-r15", "supported"); + if (phy_layer_params_v1610_present) { + j.write_fieldname("phyLayerParameters-v1610"); + phy_layer_params_v1610.to_json(j); + } + if (pur_params_r16_present) { + j.write_fieldname("pur-Parameters-r16"); + pur_params_r16.to_json(j); + } + if (meas_params_v1610_present) { + j.write_fieldname("measParameters-v1610"); + meas_params_v1610.to_json(j); + } + if (eutra_minus5_gc_params_v1610_present) { + j.write_fieldname("eutra-5GC-Parameters-v1610"); + eutra_minus5_gc_params_v1610.to_json(j); + } + if (irat_params_nr_v1610_present) { + j.write_fieldname("irat-ParametersNR-v1610"); + irat_params_nr_v1610.to_json(j); + } + if (neigh_cell_si_acquisition_params_v1610_present) { + j.write_fieldname("neighCellSI-AcquisitionParameters-v1610"); + neigh_cell_si_acquisition_params_v1610.to_json(j); + } + if (mob_params_v1610_present) { + j.write_fieldname("mobilityParameters-v1610"); + mob_params_v1610.to_json(j); } j.end_obj(); } @@ -8541,6 +11590,242 @@ void eutra_minus5_gc_params_r15_s::to_json(json_writer& j) const j.end_obj(); } +// UE-EUTRA-Capability-v1610-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(high_speed_enh_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(neigh_cell_si_acquisition_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(mbms_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(pdcp_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(mac_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(phy_layer_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(meas_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(pur_params_r16_present, 1)); + HANDLE_CODE(bref.pack(eutra_minus5_gc_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(other_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(dl_ded_msg_segmentation_r16_present, 1)); + HANDLE_CODE(bref.pack(irat_params_nr_v1610_present, 1)); + HANDLE_CODE(bref.pack(rf_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(mob_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(sl_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(fdd_add_ue_eutra_cap_v1610_present, 1)); + HANDLE_CODE(bref.pack(tdd_add_ue_eutra_cap_v1610_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (high_speed_enh_params_v1610_present) { + HANDLE_CODE(high_speed_enh_params_v1610.pack(bref)); + } + if (neigh_cell_si_acquisition_params_v1610_present) { + HANDLE_CODE(neigh_cell_si_acquisition_params_v1610.pack(bref)); + } + if (mbms_params_v1610_present) { + HANDLE_CODE(mbms_params_v1610.pack(bref)); + } + if (pdcp_params_v1610_present) { + HANDLE_CODE(pdcp_params_v1610.pack(bref)); + } + if (mac_params_v1610_present) { + HANDLE_CODE(mac_params_v1610.pack(bref)); + } + if (phy_layer_params_v1610_present) { + HANDLE_CODE(phy_layer_params_v1610.pack(bref)); + } + if (meas_params_v1610_present) { + HANDLE_CODE(meas_params_v1610.pack(bref)); + } + if (pur_params_r16_present) { + HANDLE_CODE(pur_params_r16.pack(bref)); + } + if (eutra_minus5_gc_params_v1610_present) { + HANDLE_CODE(eutra_minus5_gc_params_v1610.pack(bref)); + } + if (other_params_v1610_present) { + HANDLE_CODE(other_params_v1610.pack(bref)); + } + HANDLE_CODE(mmtel_params_v1610.pack(bref)); + if (irat_params_nr_v1610_present) { + HANDLE_CODE(irat_params_nr_v1610.pack(bref)); + } + if (rf_params_v1610_present) { + HANDLE_CODE(rf_params_v1610.pack(bref)); + } + if (mob_params_v1610_present) { + HANDLE_CODE(mob_params_v1610.pack(bref)); + } + HANDLE_CODE(ue_based_netw_perf_meas_params_v1610.pack(bref)); + if (sl_params_v1610_present) { + HANDLE_CODE(sl_params_v1610.pack(bref)); + } + if (fdd_add_ue_eutra_cap_v1610_present) { + HANDLE_CODE(fdd_add_ue_eutra_cap_v1610.pack(bref)); + } + if (tdd_add_ue_eutra_cap_v1610_present) { + HANDLE_CODE(tdd_add_ue_eutra_cap_v1610.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(high_speed_enh_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(neigh_cell_si_acquisition_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(mbms_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(pdcp_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(mac_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(phy_layer_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(meas_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(pur_params_r16_present, 1)); + HANDLE_CODE(bref.unpack(eutra_minus5_gc_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(other_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(dl_ded_msg_segmentation_r16_present, 1)); + HANDLE_CODE(bref.unpack(irat_params_nr_v1610_present, 1)); + HANDLE_CODE(bref.unpack(rf_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(mob_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(sl_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(fdd_add_ue_eutra_cap_v1610_present, 1)); + HANDLE_CODE(bref.unpack(tdd_add_ue_eutra_cap_v1610_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (high_speed_enh_params_v1610_present) { + HANDLE_CODE(high_speed_enh_params_v1610.unpack(bref)); + } + if (neigh_cell_si_acquisition_params_v1610_present) { + HANDLE_CODE(neigh_cell_si_acquisition_params_v1610.unpack(bref)); + } + if (mbms_params_v1610_present) { + HANDLE_CODE(mbms_params_v1610.unpack(bref)); + } + if (pdcp_params_v1610_present) { + HANDLE_CODE(pdcp_params_v1610.unpack(bref)); + } + if (mac_params_v1610_present) { + HANDLE_CODE(mac_params_v1610.unpack(bref)); + } + if (phy_layer_params_v1610_present) { + HANDLE_CODE(phy_layer_params_v1610.unpack(bref)); + } + if (meas_params_v1610_present) { + HANDLE_CODE(meas_params_v1610.unpack(bref)); + } + if (pur_params_r16_present) { + HANDLE_CODE(pur_params_r16.unpack(bref)); + } + if (eutra_minus5_gc_params_v1610_present) { + HANDLE_CODE(eutra_minus5_gc_params_v1610.unpack(bref)); + } + if (other_params_v1610_present) { + HANDLE_CODE(other_params_v1610.unpack(bref)); + } + HANDLE_CODE(mmtel_params_v1610.unpack(bref)); + if (irat_params_nr_v1610_present) { + HANDLE_CODE(irat_params_nr_v1610.unpack(bref)); + } + if (rf_params_v1610_present) { + HANDLE_CODE(rf_params_v1610.unpack(bref)); + } + if (mob_params_v1610_present) { + HANDLE_CODE(mob_params_v1610.unpack(bref)); + } + HANDLE_CODE(ue_based_netw_perf_meas_params_v1610.unpack(bref)); + if (sl_params_v1610_present) { + HANDLE_CODE(sl_params_v1610.unpack(bref)); + } + if (fdd_add_ue_eutra_cap_v1610_present) { + HANDLE_CODE(fdd_add_ue_eutra_cap_v1610.unpack(bref)); + } + if (tdd_add_ue_eutra_cap_v1610_present) { + HANDLE_CODE(tdd_add_ue_eutra_cap_v1610.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (high_speed_enh_params_v1610_present) { + j.write_fieldname("highSpeedEnhParameters-v1610"); + high_speed_enh_params_v1610.to_json(j); + } + if (neigh_cell_si_acquisition_params_v1610_present) { + j.write_fieldname("neighCellSI-AcquisitionParameters-v1610"); + neigh_cell_si_acquisition_params_v1610.to_json(j); + } + if (mbms_params_v1610_present) { + j.write_fieldname("mbms-Parameters-v1610"); + mbms_params_v1610.to_json(j); + } + if (pdcp_params_v1610_present) { + j.write_fieldname("pdcp-Parameters-v1610"); + pdcp_params_v1610.to_json(j); + } + if (mac_params_v1610_present) { + j.write_fieldname("mac-Parameters-v1610"); + mac_params_v1610.to_json(j); + } + if (phy_layer_params_v1610_present) { + j.write_fieldname("phyLayerParameters-v1610"); + phy_layer_params_v1610.to_json(j); + } + if (meas_params_v1610_present) { + j.write_fieldname("measParameters-v1610"); + meas_params_v1610.to_json(j); + } + if (pur_params_r16_present) { + j.write_fieldname("pur-Parameters-r16"); + pur_params_r16.to_json(j); + } + if (eutra_minus5_gc_params_v1610_present) { + j.write_fieldname("eutra-5GC-Parameters-v1610"); + eutra_minus5_gc_params_v1610.to_json(j); + } + if (other_params_v1610_present) { + j.write_fieldname("otherParameters-v1610"); + other_params_v1610.to_json(j); + } + if (dl_ded_msg_segmentation_r16_present) { + j.write_str("dl-DedicatedMessageSegmentation-r16", "supported"); + } + j.write_fieldname("mmtel-Parameters-v1610"); + mmtel_params_v1610.to_json(j); + if (irat_params_nr_v1610_present) { + j.write_fieldname("irat-ParametersNR-v1610"); + irat_params_nr_v1610.to_json(j); + } + if (rf_params_v1610_present) { + j.write_fieldname("rf-Parameters-v1610"); + rf_params_v1610.to_json(j); + } + if (mob_params_v1610_present) { + j.write_fieldname("mobilityParameters-v1610"); + mob_params_v1610.to_json(j); + } + j.write_fieldname("ue-BasedNetwPerfMeasParameters-v1610"); + ue_based_netw_perf_meas_params_v1610.to_json(j); + if (sl_params_v1610_present) { + j.write_fieldname("sl-Parameters-v1610"); + sl_params_v1610.to_json(j); + } + if (fdd_add_ue_eutra_cap_v1610_present) { + j.write_fieldname("fdd-Add-UE-EUTRA-Capabilities-v1610"); + fdd_add_ue_eutra_cap_v1610.to_json(j); + } + if (tdd_add_ue_eutra_cap_v1610_present) { + j.write_fieldname("tdd-Add-UE-EUTRA-Capabilities-v1610"); + tdd_add_ue_eutra_cap_v1610.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + // UE-EUTRA-CapabilityAddXDD-Mode-v15a0 ::= SEQUENCE SRSASN_CODE ue_eutra_cap_add_xdd_mode_v15a0_s::pack(bit_ref& bref) const { @@ -8706,6 +11991,9 @@ SRSASN_CODE ue_eutra_cap_v15a0_ies_s::pack(bit_ref& bref) const if (tdd_add_ue_eutra_cap_v15a0_present) { HANDLE_CODE(tdd_add_ue_eutra_cap_v15a0.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -8726,6 +12014,9 @@ SRSASN_CODE ue_eutra_cap_v15a0_ies_s::unpack(cbit_ref& bref) if (tdd_add_ue_eutra_cap_v15a0_present) { HANDLE_CODE(tdd_add_ue_eutra_cap_v15a0.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -8748,8 +12039,7 @@ void ue_eutra_cap_v15a0_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -11675,7 +14965,7 @@ void mac_params_v1310_s::to_json(json_writer& j) const SRSASN_CODE meas_params_v1310_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(rs_sinr_meas_r13_present, 1)); - HANDLE_CODE(bref.pack(white_cell_list_r13_present, 1)); + HANDLE_CODE(bref.pack(allowed_cell_list_r13_present, 1)); HANDLE_CODE(bref.pack(extended_max_obj_id_r13_present, 1)); HANDLE_CODE(bref.pack(ul_pdcp_delay_r13_present, 1)); HANDLE_CODE(bref.pack(extended_freq_priorities_r13_present, 1)); @@ -11687,7 +14977,7 @@ SRSASN_CODE meas_params_v1310_s::pack(bit_ref& bref) const SRSASN_CODE meas_params_v1310_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(rs_sinr_meas_r13_present, 1)); - HANDLE_CODE(bref.unpack(white_cell_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(allowed_cell_list_r13_present, 1)); HANDLE_CODE(bref.unpack(extended_max_obj_id_r13_present, 1)); HANDLE_CODE(bref.unpack(ul_pdcp_delay_r13_present, 1)); HANDLE_CODE(bref.unpack(extended_freq_priorities_r13_present, 1)); @@ -11702,8 +14992,8 @@ void meas_params_v1310_s::to_json(json_writer& j) const if (rs_sinr_meas_r13_present) { j.write_str("rs-SINR-Meas-r13", "supported"); } - if (white_cell_list_r13_present) { - j.write_str("whiteCellList-r13", "supported"); + if (allowed_cell_list_r13_present) { + j.write_str("allowedCellList-r13", "supported"); } if (extended_max_obj_id_r13_present) { j.write_str("extendedMaxObjectId-r13", "supported"); @@ -14004,13 +17294,14 @@ void ue_eutra_cap_v940_ies_s::to_json(json_writer& j) const // AccessStratumRelease ::= ENUMERATED const char* access_stratum_release_opts::to_string() const { - static const char* options[] = {"rel8", "rel9", "rel10", "rel11", "rel12", "rel13", "rel14", "rel15"}; - return convert_enum_idx(options, 8, value, "access_stratum_release_e"); + static const char* options[] = { + "rel8", "rel9", "rel10", "rel11", "rel12", "rel13", "rel14", "rel15", "rel16", "rel17"}; + return convert_enum_idx(options, 10, value, "access_stratum_release_e"); } uint8_t access_stratum_release_opts::to_number() const { - static const uint8_t options[] = {8, 9, 10, 11, 12, 13, 14, 15}; - return map_enum_number(options, 8, value, "access_stratum_release_e"); + static const uint8_t options[] = {8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; + return map_enum_number(options, 10, value, "access_stratum_release_e"); } // PhyLayerParameters ::= SEQUENCE @@ -14267,6 +17558,153 @@ void ue_eutra_cap_s::to_json(json_writer& j) const j.end_obj(); } +// MeasParameters-v16c0 ::= SEQUENCE +SRSASN_CODE meas_params_v16c0_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(nr_cell_individual_offset_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_params_v16c0_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(nr_cell_individual_offset_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void meas_params_v16c0_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (nr_cell_individual_offset_r16_present) { + j.write_str("nr-CellIndividualOffset-r16", "supported"); + } + j.end_obj(); +} + +// UE-EUTRA-Capability-v16c0-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v16c0_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(meas_params_v16c0.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v16c0_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(meas_params_v16c0.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v16c0_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("measParameters-v16c0"); + meas_params_v16c0.to_json(j); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// UE-EUTRA-Capability-v15x0-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v15x0_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v15x0_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v15x0_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// UE-EUTRA-Capability-v14x0-IEs ::= SEQUENCE +SRSASN_CODE ue_eutra_cap_v14x0_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_eutra_cap_v14x0_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_eutra_cap_v14x0_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + // PhyLayerParameters-v14a0 ::= SEQUENCE SRSASN_CODE phy_layer_params_v14a0_s::pack(bit_ref& bref) const { @@ -14298,6 +17736,9 @@ SRSASN_CODE ue_eutra_cap_v14b0_ies_s::pack(bit_ref& bref) const if (rf_params_v14b0_present) { HANDLE_CODE(rf_params_v14b0.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -14309,6 +17750,9 @@ SRSASN_CODE ue_eutra_cap_v14b0_ies_s::unpack(cbit_ref& bref) if (rf_params_v14b0_present) { HANDLE_CODE(rf_params_v14b0.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -14321,8 +17765,7 @@ void ue_eutra_cap_v14b0_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } diff --git a/lib/src/asn1/rrc/ul_ccch_msg.cc b/lib/src/asn1/rrc/ul_ccch_msg.cc index 9adbf9f5e1..e3a79dc96b 100644 --- a/lib/src/asn1/rrc/ul_ccch_msg.cc +++ b/lib/src/asn1/rrc/ul_ccch_msg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,6 +29,41 @@ using namespace asn1::rrc; * Struct Methods ******************************************************************************/ +// RRCEarlyDataRequest-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_early_data_request_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(establishment_cause_v1610.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_early_data_request_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(establishment_cause_v1610.unpack(bref)); + + return SRSASN_SUCCESS; +} +void rrc_early_data_request_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("establishmentCause-v1610", establishment_cause_v1610.to_string()); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +const char* rrc_early_data_request_v1610_ies_s::establishment_cause_v1610_opts::to_string() const +{ + static const char* options[] = {"mt-Access", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 4, value, "rrc_early_data_request_v1610_ies_s::establishment_cause_v1610_e_"); +} + // EstablishmentCause ::= ENUMERATED const char* establishment_cause_opts::to_string() const { @@ -43,12 +78,12 @@ const char* establishment_cause_opts::to_string() const return convert_enum_idx(options, 8, value, "establishment_cause_e"); } -// EstablishmentCause-5GC ::= ENUMERATED -const char* establishment_cause_minus5_gc_opts::to_string() const +// EstablishmentCause-5GC-r15 ::= ENUMERATED +const char* establishment_cause_minus5_gc_r15_opts::to_string() const { static const char* options[] = { "emergency", "highPriorityAccess", "mt-Access", "mo-Signalling", "mo-Data", "mo-VoiceCall", "spare2", "spare1"}; - return convert_enum_idx(options, 8, value, "establishment_cause_minus5_gc_e"); + return convert_enum_idx(options, 8, value, "establishment_cause_minus5_gc_r15_e"); } // InitialUE-Identity ::= CHOICE @@ -180,8 +215,8 @@ SRSASN_CODE init_ue_id_c::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -// InitialUE-Identity-5GC ::= CHOICE -void init_ue_id_minus5_gc_c::destroy_() +// InitialUE-Identity-5GC-r15 ::= CHOICE +void init_ue_id_minus5_gc_r15_c::destroy_() { switch (type_) { case types::ng_minus5_g_s_tmsi_part1: @@ -194,7 +229,7 @@ void init_ue_id_minus5_gc_c::destroy_() break; } } -void init_ue_id_minus5_gc_c::set(types::options e) +void init_ue_id_minus5_gc_r15_c::set(types::options e) { destroy_(); type_ = e; @@ -208,10 +243,10 @@ void init_ue_id_minus5_gc_c::set(types::options e) case types::nulltype: break; default: - log_invalid_choice_id(type_, "init_ue_id_minus5_gc_c"); + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_r15_c"); } } -init_ue_id_minus5_gc_c::init_ue_id_minus5_gc_c(const init_ue_id_minus5_gc_c& other) +init_ue_id_minus5_gc_r15_c::init_ue_id_minus5_gc_r15_c(const init_ue_id_minus5_gc_r15_c& other) { type_ = other.type(); switch (type_) { @@ -224,10 +259,10 @@ init_ue_id_minus5_gc_c::init_ue_id_minus5_gc_c(const init_ue_id_minus5_gc_c& oth case types::nulltype: break; default: - log_invalid_choice_id(type_, "init_ue_id_minus5_gc_c"); + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_r15_c"); } } -init_ue_id_minus5_gc_c& init_ue_id_minus5_gc_c::operator=(const init_ue_id_minus5_gc_c& other) +init_ue_id_minus5_gc_r15_c& init_ue_id_minus5_gc_r15_c::operator=(const init_ue_id_minus5_gc_r15_c& other) { if (this == &other) { return *this; @@ -243,22 +278,22 @@ init_ue_id_minus5_gc_c& init_ue_id_minus5_gc_c::operator=(const init_ue_id_minus case types::nulltype: break; default: - log_invalid_choice_id(type_, "init_ue_id_minus5_gc_c"); + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_r15_c"); } return *this; } -fixed_bitstring<40>& init_ue_id_minus5_gc_c::set_ng_minus5_g_s_tmsi_part1() +fixed_bitstring<40>& init_ue_id_minus5_gc_r15_c::set_ng_minus5_g_s_tmsi_part1() { set(types::ng_minus5_g_s_tmsi_part1); return c.get >(); } -fixed_bitstring<40>& init_ue_id_minus5_gc_c::set_random_value() +fixed_bitstring<40>& init_ue_id_minus5_gc_r15_c::set_random_value() { set(types::random_value); return c.get >(); } -void init_ue_id_minus5_gc_c::to_json(json_writer& j) const +void init_ue_id_minus5_gc_r15_c::to_json(json_writer& j) const { j.start_obj(); switch (type_) { @@ -269,11 +304,11 @@ void init_ue_id_minus5_gc_c::to_json(json_writer& j) const j.write_str("randomValue", c.get >().to_string()); break; default: - log_invalid_choice_id(type_, "init_ue_id_minus5_gc_c"); + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_r15_c"); } j.end_obj(); } -SRSASN_CODE init_ue_id_minus5_gc_c::pack(bit_ref& bref) const +SRSASN_CODE init_ue_id_minus5_gc_r15_c::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { @@ -284,12 +319,12 @@ SRSASN_CODE init_ue_id_minus5_gc_c::pack(bit_ref& bref) const HANDLE_CODE(c.get >().pack(bref)); break; default: - log_invalid_choice_id(type_, "init_ue_id_minus5_gc_c"); + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_r15_c"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE init_ue_id_minus5_gc_c::unpack(cbit_ref& bref) +SRSASN_CODE init_ue_id_minus5_gc_r15_c::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -302,7 +337,7 @@ SRSASN_CODE init_ue_id_minus5_gc_c::unpack(cbit_ref& bref) HANDLE_CODE(c.get >().unpack(bref)); break; default: - log_invalid_choice_id(type_, "init_ue_id_minus5_gc_c"); + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_r15_c"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; @@ -317,6 +352,9 @@ SRSASN_CODE rrc_early_data_request_v1590_ies_s::pack(bit_ref& bref) const if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -328,6 +366,9 @@ SRSASN_CODE rrc_early_data_request_v1590_ies_s::unpack(cbit_ref& bref) if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -339,8 +380,7 @@ void rrc_early_data_request_v1590_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -388,7 +428,7 @@ const char* resume_cause_opts::to_string() const "mo-Data", "delayTolerantAccess-v1020", "mo-VoiceCall-v1280", - "spare1"}; + "mt-EDT-v1610"}; return convert_enum_idx(options, 8, value, "resume_cause_e"); } @@ -436,16 +476,16 @@ void rrc_conn_reest_request_r8_ies_s::to_json(json_writer& j) const // RRCConnectionRequest-5GC-r15-IEs ::= SEQUENCE SRSASN_CODE rrc_conn_request_minus5_gc_r15_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(ue_id.pack(bref)); - HANDLE_CODE(establishment_cause.pack(bref)); + HANDLE_CODE(ue_id_r15.pack(bref)); + HANDLE_CODE(establishment_cause_r15.pack(bref)); HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } SRSASN_CODE rrc_conn_request_minus5_gc_r15_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(ue_id.unpack(bref)); - HANDLE_CODE(establishment_cause.unpack(bref)); + HANDLE_CODE(ue_id_r15.unpack(bref)); + HANDLE_CODE(establishment_cause_r15.unpack(bref)); HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; @@ -453,9 +493,9 @@ SRSASN_CODE rrc_conn_request_minus5_gc_r15_ies_s::unpack(cbit_ref& bref) void rrc_conn_request_minus5_gc_r15_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("ue-Identity"); - ue_id.to_json(j); - j.write_str("establishmentCause", establishment_cause.to_string()); + j.write_fieldname("ue-Identity-r15"); + ue_id_r15.to_json(j); + j.write_str("establishmentCause-r15", establishment_cause_r15.to_string()); j.write_str("spare", spare.to_string()); j.end_obj(); } @@ -806,6 +846,58 @@ SRSASN_CODE rrc_conn_resume_request_r13_ies_s::resume_id_r13_c_::unpack(cbit_ref return SRSASN_SUCCESS; } +// RRCEarlyDataRequest-5GC-r16-IEs ::= SEQUENCE +SRSASN_CODE rrc_early_data_request_minus5_gc_r16_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(ng_minus5_g_s_tmsi_r16.pack(bref)); + HANDLE_CODE(establishment_cause_r16.pack(bref)); + HANDLE_CODE(ded_info_nas_r16.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_early_data_request_minus5_gc_r16_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(ng_minus5_g_s_tmsi_r16.unpack(bref)); + HANDLE_CODE(establishment_cause_r16.unpack(bref)); + HANDLE_CODE(ded_info_nas_r16.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_early_data_request_minus5_gc_r16_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("ng-5G-S-TMSI-r16", ng_minus5_g_s_tmsi_r16.to_string()); + j.write_str("establishmentCause-r16", establishment_cause_r16.to_string()); + j.write_str("dedicatedInfoNAS-r16", ded_info_nas_r16.to_string()); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +const char* rrc_early_data_request_minus5_gc_r16_ies_s::establishment_cause_r16_opts::to_string() const +{ + static const char* options[] = {"mo-Data", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 4, value, "rrc_early_data_request_minus5_gc_r16_ies_s::establishment_cause_r16_e_"); +} + // RRCEarlyDataRequest-r15-IEs ::= SEQUENCE SRSASN_CODE rrc_early_data_request_r15_ies_s::pack(bit_ref& bref) const { @@ -1259,18 +1351,84 @@ void rrc_early_data_request_r15_s::to_json(json_writer& j) const j.end_obj(); } +void rrc_early_data_request_r15_s::crit_exts_c_::destroy_() +{ + switch (type_) { + case types::rrc_early_data_request_r15: + c.destroy(); + break; + case types::crit_exts_future: + c.destroy(); + break; + default: + break; + } +} void rrc_early_data_request_r15_s::crit_exts_c_::set(types::options e) { + destroy_(); type_ = e; + switch (type_) { + case types::rrc_early_data_request_r15: + c.init(); + break; + case types::crit_exts_future: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_r15_s::crit_exts_c_"); + } +} +rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_c_(const rrc_early_data_request_r15_s::crit_exts_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::rrc_early_data_request_r15: + c.init(other.c.get()); + break; + case types::crit_exts_future: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_r15_s::crit_exts_c_"); + } +} +rrc_early_data_request_r15_s::crit_exts_c_& +rrc_early_data_request_r15_s::crit_exts_c_::operator=(const rrc_early_data_request_r15_s::crit_exts_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::rrc_early_data_request_r15: + c.set(other.c.get()); + break; + case types::crit_exts_future: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_r15_s::crit_exts_c_"); + } + + return *this; } rrc_early_data_request_r15_ies_s& rrc_early_data_request_r15_s::crit_exts_c_::set_rrc_early_data_request_r15() { set(types::rrc_early_data_request_r15); - return c; + return c.get(); } -void rrc_early_data_request_r15_s::crit_exts_c_::set_crit_exts_future() +rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_& +rrc_early_data_request_r15_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); + return c.get(); } void rrc_early_data_request_r15_s::crit_exts_c_::to_json(json_writer& j) const { @@ -1278,9 +1436,11 @@ void rrc_early_data_request_r15_s::crit_exts_c_::to_json(json_writer& j) const switch (type_) { case types::rrc_early_data_request_r15: j.write_fieldname("rrcEarlyDataRequest-r15"); - c.to_json(j); + c.get().to_json(j); break; case types::crit_exts_future: + j.write_fieldname("criticalExtensionsFuture"); + c.get().to_json(j); break; default: log_invalid_choice_id(type_, "rrc_early_data_request_r15_s::crit_exts_c_"); @@ -1292,9 +1452,10 @@ SRSASN_CODE rrc_early_data_request_r15_s::crit_exts_c_::pack(bit_ref& bref) cons type_.pack(bref); switch (type_) { case types::rrc_early_data_request_r15: - HANDLE_CODE(c.pack(bref)); + HANDLE_CODE(c.get().pack(bref)); break; case types::crit_exts_future: + HANDLE_CODE(c.get().pack(bref)); break; default: log_invalid_choice_id(type_, "rrc_early_data_request_r15_s::crit_exts_c_"); @@ -1309,9 +1470,10 @@ SRSASN_CODE rrc_early_data_request_r15_s::crit_exts_c_::unpack(cbit_ref& bref) set(e); switch (type_) { case types::rrc_early_data_request_r15: - HANDLE_CODE(c.unpack(bref)); + HANDLE_CODE(c.get().unpack(bref)); break; case types::crit_exts_future: + HANDLE_CODE(c.get().unpack(bref)); break; default: log_invalid_choice_id(type_, "rrc_early_data_request_r15_s::crit_exts_c_"); @@ -1320,6 +1482,68 @@ SRSASN_CODE rrc_early_data_request_r15_s::crit_exts_c_::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +void rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_::set(types::options e) +{ + type_ = e; +} +rrc_early_data_request_minus5_gc_r16_ies_s& +rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_::set_rrc_early_data_request_minus5_gc_r16() +{ + set(types::rrc_early_data_request_minus5_gc_r16); + return c; +} +void rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_::set_crit_exts_future_r16() +{ + set(types::crit_exts_future_r16); +} +void rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::rrc_early_data_request_minus5_gc_r16: + j.write_fieldname("rrcEarlyDataRequest-5GC-r16"); + c.to_json(j); + break; + case types::crit_exts_future_r16: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::rrc_early_data_request_minus5_gc_r16: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future_r16: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rrc_early_data_request_minus5_gc_r16: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future_r16: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_r15_s::crit_exts_c_::crit_exts_future_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + // UL-CCCH-MessageType ::= CHOICE void ul_ccch_msg_type_c::destroy_() { diff --git a/lib/src/asn1/rrc/ul_dcch_msg.cc b/lib/src/asn1/rrc/ul_dcch_msg.cc index e11254a37f..5074201f3a 100644 --- a/lib/src/asn1/rrc/ul_dcch_msg.cc +++ b/lib/src/asn1/rrc/ul_dcch_msg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -177,6 +177,223 @@ SRSASN_CODE tmgi_r9_s::plmn_id_r9_c_::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +// GNSS-ValidityDuration-r17 ::= ENUMERATED +const char* gnss_validity_dur_r17_opts::to_string() const +{ + static const char* options[] = {"s10", + "s20", + "s30", + "s40", + "s50", + "s60", + "min5", + "min10", + "min15", + "min20", + "min25", + "min30", + "min50", + "min90", + "min120", + "infinity"}; + return convert_enum_idx(options, 16, value, "gnss_validity_dur_r17_e"); +} + +// RRCConnectionSetupComplete-v1710-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_complete_v1710_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_setup_complete_v1710_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_setup_complete_v1710_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (gnss_validity_dur_r17_present) { + j.write_str("gnss-ValidityDuration-r17", gnss_validity_dur_r17.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// RRCConnectionSetupComplete-v1690-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_complete_v1690_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ul_rrc_segmentation_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_setup_complete_v1690_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ul_rrc_segmentation_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_setup_complete_v1690_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ul_rrc_segmentation_r16_present) { + j.write_str("ul-RRC-Segmentation-r16", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// ResultsPerSSB-IndexIdle-r16 ::= SEQUENCE +SRSASN_CODE results_per_ssb_idx_idle_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ssb_results_r16_present, 1)); + + HANDLE_CODE(pack_integer(bref, ssb_idx_r16, (uint8_t)0u, (uint8_t)63u)); + if (ssb_results_r16_present) { + HANDLE_CODE(bref.pack(ssb_results_r16.ssb_rsrp_result_r16_present, 1)); + HANDLE_CODE(bref.pack(ssb_results_r16.ssb_rsrq_result_r16_present, 1)); + if (ssb_results_r16.ssb_rsrp_result_r16_present) { + HANDLE_CODE(pack_integer(bref, ssb_results_r16.ssb_rsrp_result_r16, (uint8_t)0u, (uint8_t)127u)); + } + if (ssb_results_r16.ssb_rsrq_result_r16_present) { + HANDLE_CODE(pack_integer(bref, ssb_results_r16.ssb_rsrq_result_r16, (uint8_t)0u, (uint8_t)127u)); + } + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE results_per_ssb_idx_idle_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ssb_results_r16_present, 1)); + + HANDLE_CODE(unpack_integer(ssb_idx_r16, bref, (uint8_t)0u, (uint8_t)63u)); + if (ssb_results_r16_present) { + HANDLE_CODE(bref.unpack(ssb_results_r16.ssb_rsrp_result_r16_present, 1)); + HANDLE_CODE(bref.unpack(ssb_results_r16.ssb_rsrq_result_r16_present, 1)); + if (ssb_results_r16.ssb_rsrp_result_r16_present) { + HANDLE_CODE(unpack_integer(ssb_results_r16.ssb_rsrp_result_r16, bref, (uint8_t)0u, (uint8_t)127u)); + } + if (ssb_results_r16.ssb_rsrq_result_r16_present) { + HANDLE_CODE(unpack_integer(ssb_results_r16.ssb_rsrq_result_r16, bref, (uint8_t)0u, (uint8_t)127u)); + } + } + + return SRSASN_SUCCESS; +} +void results_per_ssb_idx_idle_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("ssb-Index-r16", ssb_idx_r16); + if (ssb_results_r16_present) { + j.write_fieldname("ssb-Results-r16"); + j.start_obj(); + if (ssb_results_r16.ssb_rsrp_result_r16_present) { + j.write_int("ssb-RSRP-Result-r16", ssb_results_r16.ssb_rsrp_result_r16); + } + if (ssb_results_r16.ssb_rsrq_result_r16_present) { + j.write_int("ssb-RSRQ-Result-r16", ssb_results_r16.ssb_rsrq_result_r16); + } + j.end_obj(); + } + j.end_obj(); +} + +// RRCConnectionSetupComplete-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_complete_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(rlos_request_r16_present, 1)); + HANDLE_CODE(bref.pack(cp_cio_t_minus5_gs_optim_r16_present, 1)); + HANDLE_CODE(bref.pack(up_cio_t_minus5_gs_optim_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_cfg_id_r16_present, 1)); + HANDLE_CODE(bref.pack(lte_m_r16_present, 1)); + HANDLE_CODE(bref.pack(iab_node_ind_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (pur_cfg_id_r16_present) { + HANDLE_CODE(pur_cfg_id_r16.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_setup_complete_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(rlos_request_r16_present, 1)); + HANDLE_CODE(bref.unpack(cp_cio_t_minus5_gs_optim_r16_present, 1)); + HANDLE_CODE(bref.unpack(up_cio_t_minus5_gs_optim_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_cfg_id_r16_present, 1)); + HANDLE_CODE(bref.unpack(lte_m_r16_present, 1)); + HANDLE_CODE(bref.unpack(iab_node_ind_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (pur_cfg_id_r16_present) { + HANDLE_CODE(pur_cfg_id_r16.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_setup_complete_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (rlos_request_r16_present) { + j.write_str("rlos-Request-r16", "true"); + } + if (cp_cio_t_minus5_gs_optim_r16_present) { + j.write_str("cp-CIoT-5GS-Optimisation-r16", "true"); + } + if (up_cio_t_minus5_gs_optim_r16_present) { + j.write_str("up-CIoT-5GS-Optimisation-r16", "true"); + } + if (pur_cfg_id_r16_present) { + j.write_str("pur-ConfigID-r16", pur_cfg_id_r16.to_string()); + } + if (lte_m_r16_present) { + j.write_str("lte-M-r16", "true"); + } + if (iab_node_ind_r16_present) { + j.write_str("iab-NodeIndication-r16", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + // MeasResultIdleEUTRA-r15 ::= SEQUENCE SRSASN_CODE meas_result_idle_eutra_r15_s::pack(bit_ref& bref) const { @@ -211,6 +428,105 @@ void meas_result_idle_eutra_r15_s::to_json(json_writer& j) const j.end_obj(); } +// MeasResultsPerCellIdleNR-r16 ::= SEQUENCE +SRSASN_CODE meas_results_per_cell_idle_nr_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, pci_nr_r16, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(bref.pack(meas_idle_result_nr_r16.rsrp_result_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_idle_result_nr_r16.rsrq_result_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_idle_result_nr_r16.result_rs_idx_list_r16_present, 1)); + if (meas_idle_result_nr_r16.rsrp_result_nr_r16_present) { + HANDLE_CODE(pack_integer(bref, meas_idle_result_nr_r16.rsrp_result_nr_r16, (uint8_t)0u, (uint8_t)127u)); + } + if (meas_idle_result_nr_r16.rsrq_result_nr_r16_present) { + HANDLE_CODE(pack_integer(bref, meas_idle_result_nr_r16.rsrq_result_nr_r16, (uint8_t)0u, (uint8_t)127u)); + } + if (meas_idle_result_nr_r16.result_rs_idx_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_idle_result_nr_r16.result_rs_idx_list_r16, 1, 32)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_results_per_cell_idle_nr_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(pci_nr_r16, bref, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(bref.unpack(meas_idle_result_nr_r16.rsrp_result_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_idle_result_nr_r16.rsrq_result_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_idle_result_nr_r16.result_rs_idx_list_r16_present, 1)); + if (meas_idle_result_nr_r16.rsrp_result_nr_r16_present) { + HANDLE_CODE(unpack_integer(meas_idle_result_nr_r16.rsrp_result_nr_r16, bref, (uint8_t)0u, (uint8_t)127u)); + } + if (meas_idle_result_nr_r16.rsrq_result_nr_r16_present) { + HANDLE_CODE(unpack_integer(meas_idle_result_nr_r16.rsrq_result_nr_r16, bref, (uint8_t)0u, (uint8_t)127u)); + } + if (meas_idle_result_nr_r16.result_rs_idx_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_idle_result_nr_r16.result_rs_idx_list_r16, bref, 1, 32)); + } + + return SRSASN_SUCCESS; +} +void meas_results_per_cell_idle_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("physCellIdNR-r16", pci_nr_r16); + j.write_fieldname("measIdleResultNR-r16"); + j.start_obj(); + if (meas_idle_result_nr_r16.rsrp_result_nr_r16_present) { + j.write_int("rsrpResultNR-r16", meas_idle_result_nr_r16.rsrp_result_nr_r16); + } + if (meas_idle_result_nr_r16.rsrq_result_nr_r16_present) { + j.write_int("rsrqResultNR-r16", meas_idle_result_nr_r16.rsrq_result_nr_r16); + } + if (meas_idle_result_nr_r16.result_rs_idx_list_r16_present) { + j.start_array("resultRS-IndexList-r16"); + for (const auto& e1 : meas_idle_result_nr_r16.result_rs_idx_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); + j.end_obj(); +} + +// RRCConnectionReconfigurationComplete-v1710-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_recfg_complete_v1710_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_recfg_complete_v1710_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_recfg_complete_v1710_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (gnss_validity_dur_r17_present) { + j.write_str("gnss-ValidityDuration-r17", gnss_validity_dur_r17.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // RRCConnectionSetupComplete-v1540-IEs ::= SEQUENCE SRSASN_CODE rrc_conn_setup_complete_v1540_ies_s::pack(bit_ref& bref) const { @@ -221,6 +537,9 @@ SRSASN_CODE rrc_conn_setup_complete_v1540_ies_s::pack(bit_ref& bref) const if (guami_type_r15_present) { HANDLE_CODE(guami_type_r15.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -233,6 +552,9 @@ SRSASN_CODE rrc_conn_setup_complete_v1540_ies_s::unpack(cbit_ref& bref) if (guami_type_r15_present) { HANDLE_CODE(guami_type_r15.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -247,8 +569,7 @@ void rrc_conn_setup_complete_v1540_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -421,6 +742,77 @@ SRSASN_CODE s_nssai_r15_c::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +// MeasResultIdleNR-r16 ::= SEQUENCE +SRSASN_CODE meas_result_idle_nr_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, carrier_freq_nr_r16, (uint32_t)0u, (uint32_t)3279165u)); + HANDLE_CODE(pack_dyn_seq_of(bref, meas_results_per_cell_list_idle_nr_r16, 1, 8)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_result_idle_nr_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(carrier_freq_nr_r16, bref, (uint32_t)0u, (uint32_t)3279165u)); + HANDLE_CODE(unpack_dyn_seq_of(meas_results_per_cell_list_idle_nr_r16, bref, 1, 8)); + + return SRSASN_SUCCESS; +} +void meas_result_idle_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("carrierFreqNR-r16", carrier_freq_nr_r16); + j.start_array("measResultsPerCellListIdleNR-r16"); + for (const auto& e1 : meas_results_per_cell_list_idle_nr_r16) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// RRCConnectionReconfigurationComplete-v1700-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_recfg_complete_v1700_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(sel_cond_recfg_to_apply_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (sel_cond_recfg_to_apply_r17_present) { + HANDLE_CODE(pack_integer(bref, sel_cond_recfg_to_apply_r17, (uint8_t)1u, (uint8_t)8u)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_recfg_complete_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(sel_cond_recfg_to_apply_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (sel_cond_recfg_to_apply_r17_present) { + HANDLE_CODE(unpack_integer(sel_cond_recfg_to_apply_r17, bref, (uint8_t)1u, (uint8_t)8u)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_recfg_complete_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (sel_cond_recfg_to_apply_r17_present) { + j.write_int("selectedCondReconfigurationToApply-r17", sel_cond_recfg_to_apply_r17); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + // RRCConnectionSetupComplete-v1530-IEs ::= SEQUENCE SRSASN_CODE rrc_conn_setup_complete_v1530_ies_s::pack(bit_ref& bref) const { @@ -717,6 +1109,26 @@ SRSASN_CODE meas_result_idle_r15_s::meas_result_neigh_cells_r15_c_::unpack(cbit_ return SRSASN_SUCCESS; } +// OverheatingAssistance-v1710 ::= SEQUENCE +SRSASN_CODE overheat_assist_v1710_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(overheat_assist_for_scg_fr2_minus2_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE overheat_assist_v1710_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(overheat_assist_for_scg_fr2_minus2_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void overheat_assist_v1710_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("overheatingAssistanceForSCG-FR2-2-r17", overheat_assist_for_scg_fr2_minus2_r17.to_string()); + j.end_obj(); +} + // PerCC-GapIndication-r14 ::= SEQUENCE SRSASN_CODE per_cc_gap_ind_r14_s::pack(bit_ref& bref) const { @@ -746,37 +1158,104 @@ const char* per_cc_gap_ind_r14_s::gap_ind_r14_opts::to_string() const return convert_enum_idx(options, 3, value, "per_cc_gap_ind_r14_s::gap_ind_r14_e_"); } -// RRCConnectionReconfigurationComplete-v1530-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_recfg_complete_v1530_ies_s::pack(bit_ref& bref) const +// RACH-Report-v1610 ::= SEQUENCE +SRSASN_CODE rach_report_v1610_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(log_meas_available_bt_r15_present, 1)); - HANDLE_CODE(bref.pack(log_meas_available_wlan_r15_present, 1)); - HANDLE_CODE(bref.pack(flight_path_info_available_r15_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + HANDLE_CODE(pack_integer(bref, init_cel_r16, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(bref.pack(edt_fallback_r16, 1)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_recfg_complete_v1530_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rach_report_v1610_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(log_meas_available_bt_r15_present, 1)); - HANDLE_CODE(bref.unpack(log_meas_available_wlan_r15_present, 1)); - HANDLE_CODE(bref.unpack(flight_path_info_available_r15_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + HANDLE_CODE(unpack_integer(init_cel_r16, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(bref.unpack(edt_fallback_r16, 1)); return SRSASN_SUCCESS; } -void rrc_conn_recfg_complete_v1530_ies_s::to_json(json_writer& j) const +void rach_report_v1610_s::to_json(json_writer& j) const { j.start_obj(); - if (log_meas_available_bt_r15_present) { - j.write_str("logMeasAvailableBT-r15", "true"); - } + j.write_int("initialCEL-r16", init_cel_r16); + j.write_bool("edt-Fallback-r16", edt_fallback_r16); + j.end_obj(); +} + +// RRCConnectionReconfigurationComplete-v1530-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_recfg_complete_v1530_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(log_meas_available_bt_r15_present, 1)); + HANDLE_CODE(bref.pack(log_meas_available_wlan_r15_present, 1)); + HANDLE_CODE(bref.pack(flight_path_info_available_r15_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_recfg_complete_v1530_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(log_meas_available_bt_r15_present, 1)); + HANDLE_CODE(bref.unpack(log_meas_available_wlan_r15_present, 1)); + HANDLE_CODE(bref.unpack(flight_path_info_available_r15_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_recfg_complete_v1530_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (log_meas_available_bt_r15_present) { + j.write_str("logMeasAvailableBT-r15", "true"); + } if (log_meas_available_wlan_r15_present) { j.write_str("logMeasAvailableWLAN-r15", "true"); } if (flight_path_info_available_r15_present) { j.write_str("flightPathInfoAvailable-r15", "true"); } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// RRCConnectionReestablishmentComplete-v1710-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_complete_v1710_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reest_complete_v1710_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_reest_complete_v1710_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (gnss_validity_dur_r17_present) { + j.write_str("gnss-ValidityDuration-r17", gnss_validity_dur_r17.to_string()); + } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); j.start_obj(); @@ -827,6 +1306,43 @@ void rrc_conn_setup_complete_v1430_ies_s::to_json(json_writer& j) const j.end_obj(); } +// UEInformationResponse-v1710-IEs ::= SEQUENCE +SRSASN_CODE ue_info_resp_v1710_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(coarse_location_info_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (coarse_location_info_r17_present) { + HANDLE_CODE(coarse_location_info_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_info_resp_v1710_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(coarse_location_info_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (coarse_location_info_r17_present) { + HANDLE_CODE(coarse_location_info_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_info_resp_v1710_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (coarse_location_info_r17_present) { + j.write_str("coarseLocationInfo-r17", coarse_location_info_r17.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // VictimSystemType-r11 ::= SEQUENCE SRSASN_CODE victim_sys_type_r11_s::pack(bit_ref& bref) const { @@ -1168,7 +1684,7 @@ const char* affected_carrier_freq_comb_info_mrdc_r15_s::interference_direction_m SRSASN_CODE flight_path_info_report_r15_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(flight_path_r15_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(dummy_present, 1)); if (flight_path_r15_present) { HANDLE_CODE(pack_dyn_seq_of(bref, flight_path_r15, 1, 20)); @@ -1179,7 +1695,7 @@ SRSASN_CODE flight_path_info_report_r15_s::pack(bit_ref& bref) const SRSASN_CODE flight_path_info_report_r15_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(flight_path_r15_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(dummy_present, 1)); if (flight_path_r15_present) { HANDLE_CODE(unpack_dyn_seq_of(flight_path_r15, bref, 1, 20)); @@ -1197,8 +1713,8 @@ void flight_path_info_report_r15_s::to_json(json_writer& j) const } j.end_array(); } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); + if (dummy_present) { + j.write_fieldname("dummy"); j.start_obj(); j.end_obj(); } @@ -1255,6 +1771,10 @@ SRSASN_CODE rrc_conn_reest_complete_v1530_ies_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(flight_path_info_available_r15_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + return SRSASN_SUCCESS; } SRSASN_CODE rrc_conn_reest_complete_v1530_ies_s::unpack(cbit_ref& bref) @@ -1264,6 +1784,10 @@ SRSASN_CODE rrc_conn_reest_complete_v1530_ies_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(flight_path_info_available_r15_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + return SRSASN_SUCCESS; } void rrc_conn_reest_complete_v1530_ies_s::to_json(json_writer& j) const @@ -1280,8 +1804,7 @@ void rrc_conn_reest_complete_v1530_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -1322,12 +1845,201 @@ void rrc_conn_setup_complete_v1330_ies_s::to_json(json_writer& j) const j.end_obj(); } +// UEAssistanceInformation-v1710-IEs ::= SEQUENCE +SRSASN_CODE ueassist_info_v1710_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(overheat_assist_v1710_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (overheat_assist_v1710_present) { + HANDLE_CODE(overheat_assist_v1710.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueassist_info_v1710_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(overheat_assist_v1710_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (overheat_assist_v1710_present) { + HANDLE_CODE(overheat_assist_v1710.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueassist_info_v1710_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (overheat_assist_v1710_present) { + j.write_fieldname("overheatingAssistance-v1710"); + overheat_assist_v1710.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// UEInformationResponse-v1610-IEs ::= SEQUENCE +SRSASN_CODE ue_info_resp_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(rach_report_v1610_present, 1)); + HANDLE_CODE(bref.pack(meas_result_list_ext_idle_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_result_list_idle_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (rach_report_v1610_present) { + HANDLE_CODE(rach_report_v1610.pack(bref)); + } + if (meas_result_list_ext_idle_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_list_ext_idle_r16, 1, 5, SeqOfPacker(1, 8, Packer()))); + } + if (meas_result_list_idle_nr_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_list_idle_nr_r16, 1, 8)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_info_resp_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(rach_report_v1610_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_list_ext_idle_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_list_idle_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (rach_report_v1610_present) { + HANDLE_CODE(rach_report_v1610.unpack(bref)); + } + if (meas_result_list_ext_idle_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_list_ext_idle_r16, bref, 1, 5, SeqOfPacker(1, 8, Packer()))); + } + if (meas_result_list_idle_nr_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_list_idle_nr_r16, bref, 1, 8)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_info_resp_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (rach_report_v1610_present) { + j.write_fieldname("rach-Report-v1610"); + rach_report_v1610.to_json(j); + } + if (meas_result_list_ext_idle_r16_present) { + j.start_array("measResultListExtIdle-r16"); + for (const auto& e1 : meas_result_list_ext_idle_r16) { + j.start_array(); + for (const auto& e2 : e1) { + e2.to_json(j); + } + j.end_array(); + } + j.end_array(); + } + if (meas_result_list_idle_nr_r16_present) { + j.start_array("measResultListIdleNR-r16"); + for (const auto& e1 : meas_result_list_idle_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// VictimSystemType-v1610 ::= SEQUENCE +SRSASN_CODE victim_sys_type_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(navic_r16_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE victim_sys_type_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(navic_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void victim_sys_type_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (navic_r16_present) { + j.write_str("navic-r16", "true"); + } + j.end_obj(); +} + +// InDeviceCoexIndication-v1610-IEs ::= SEQUENCE +SRSASN_CODE in_dev_coex_ind_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(victim_sys_type_v1610_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (victim_sys_type_v1610_present) { + HANDLE_CODE(victim_sys_type_v1610.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE in_dev_coex_ind_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(victim_sys_type_v1610_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (victim_sys_type_v1610_present) { + HANDLE_CODE(victim_sys_type_v1610.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void in_dev_coex_ind_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (victim_sys_type_v1610_present) { + j.write_fieldname("victimSystemType-v1610"); + victim_sys_type_v1610.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // MRDC-AssistanceInfo-r15 ::= SEQUENCE SRSASN_CODE mrdc_assist_info_r15_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(pack_dyn_seq_of(bref, affected_carrier_freq_comb_info_list_mrdc_r15, 1, 128)); + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= affected_carrier_freq_comb_info_list_mrdc_v1610.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(affected_carrier_freq_comb_info_list_mrdc_v1610.is_present(), 1)); + if (affected_carrier_freq_comb_info_list_mrdc_v1610.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *affected_carrier_freq_comb_info_list_mrdc_v1610, 1, 128)); + } + } + } return SRSASN_SUCCESS; } SRSASN_CODE mrdc_assist_info_r15_s::unpack(cbit_ref& bref) @@ -1335,6 +2047,22 @@ SRSASN_CODE mrdc_assist_info_r15_s::unpack(cbit_ref& bref) bref.unpack(ext, 1); HANDLE_CODE(unpack_dyn_seq_of(affected_carrier_freq_comb_info_list_mrdc_r15, bref, 1, 128)); + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool affected_carrier_freq_comb_info_list_mrdc_v1610_present; + HANDLE_CODE(bref.unpack(affected_carrier_freq_comb_info_list_mrdc_v1610_present, 1)); + affected_carrier_freq_comb_info_list_mrdc_v1610.set_present( + affected_carrier_freq_comb_info_list_mrdc_v1610_present); + if (affected_carrier_freq_comb_info_list_mrdc_v1610.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*affected_carrier_freq_comb_info_list_mrdc_v1610, bref, 1, 128)); + } + } + } return SRSASN_SUCCESS; } void mrdc_assist_info_r15_s::to_json(json_writer& j) const @@ -1345,6 +2073,35 @@ void mrdc_assist_info_r15_s::to_json(json_writer& j) const e1.to_json(j); } j.end_array(); + if (ext) { + if (affected_carrier_freq_comb_info_list_mrdc_v1610.is_present()) { + j.start_array("affectedCarrierFreqCombInfoListMRDC-v1610"); + for (const auto& e1 : *affected_carrier_freq_comb_info_list_mrdc_v1610) { + e1.to_json(j); + } + j.end_array(); + } + } + j.end_obj(); +} + +// OverheatingAssistance-v1610 ::= SEQUENCE +SRSASN_CODE overheat_assist_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(overheat_assist_for_scg_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE overheat_assist_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(overheat_assist_for_scg_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void overheat_assist_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("overheatingAssistanceForSCG-r16", overheat_assist_for_scg_r16.to_string()); j.end_obj(); } @@ -1556,18 +2313,74 @@ void traffic_pattern_info_v1530_s::to_json(json_writer& j) const j.end_obj(); } -// UEInformationResponse-v1530-IEs ::= SEQUENCE -SRSASN_CODE ue_info_resp_v1530_ies_s::pack(bit_ref& bref) const +// UEAssistanceInformation-v1700-IEs ::= SEQUENCE +SRSASN_CODE ueassist_info_v1700_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(meas_result_list_idle_r15_present, 1)); - HANDLE_CODE(bref.pack(flight_path_info_report_r15_present, 1)); + HANDLE_CODE(bref.pack(ul_data_r17_present, 1)); + HANDLE_CODE(bref.pack(scg_deactivation_pref_r17_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (meas_result_list_idle_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_list_idle_r15, 1, 3)); + if (scg_deactivation_pref_r17_present) { + HANDLE_CODE(scg_deactivation_pref_r17.pack(bref)); } - if (flight_path_info_report_r15_present) { - HANDLE_CODE(flight_path_info_report_r15.pack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueassist_info_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ul_data_r17_present, 1)); + HANDLE_CODE(bref.unpack(scg_deactivation_pref_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (scg_deactivation_pref_r17_present) { + HANDLE_CODE(scg_deactivation_pref_r17.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueassist_info_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ul_data_r17_present) { + j.write_str("uplinkData-r17", "true"); + } + if (scg_deactivation_pref_r17_present) { + j.write_str("scg-DeactivationPreference-r17", scg_deactivation_pref_r17.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +const char* ueassist_info_v1700_ies_s::scg_deactivation_pref_r17_opts::to_string() const +{ + static const char* options[] = {"scgDeactivationPreferred", "noPreference"}; + return convert_enum_idx(options, 2, value, "ueassist_info_v1700_ies_s::scg_deactivation_pref_r17_e_"); +} + +// UEInformationResponse-v1530-IEs ::= SEQUENCE +SRSASN_CODE ue_info_resp_v1530_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(meas_result_list_idle_r15_present, 1)); + HANDLE_CODE(bref.pack(flight_path_info_report_r15_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (meas_result_list_idle_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_list_idle_r15, 1, 3)); + } + if (flight_path_info_report_r15_present) { + HANDLE_CODE(flight_path_info_report_r15.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); } return SRSASN_SUCCESS; @@ -1584,6 +2397,9 @@ SRSASN_CODE ue_info_resp_v1530_ies_s::unpack(cbit_ref& bref) if (flight_path_info_report_r15_present) { HANDLE_CODE(flight_path_info_report_r15.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -1603,8 +2419,7 @@ void ue_info_resp_v1530_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -1690,6 +2505,9 @@ SRSASN_CODE conn_est_fail_report_r11_s::pack(bit_ref& bref) const group_flags[1] |= meas_result_failed_cell_v1360_present; group_flags[2] |= log_meas_result_list_bt_r15.is_present(); group_flags[2] |= log_meas_result_list_wlan_r15.is_present(); + group_flags[3] |= meas_result_list_nr_r16.is_present(); + group_flags[4] |= meas_result_list_nr_v1640.is_present(); + group_flags[4] |= meas_result_list_ext_nr_r16.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -1728,6 +2546,27 @@ SRSASN_CODE conn_est_fail_report_r11_s::pack(bit_ref& bref) const HANDLE_CODE(pack_dyn_seq_of(bref, *log_meas_result_list_wlan_r15, 1, 32)); } } + if (group_flags[3]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(meas_result_list_nr_r16.is_present(), 1)); + if (meas_result_list_nr_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *meas_result_list_nr_r16, 1, 8)); + } + } + if (group_flags[4]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(meas_result_list_nr_v1640.is_present(), 1)); + HANDLE_CODE(bref.pack(meas_result_list_ext_nr_r16.is_present(), 1)); + if (meas_result_list_nr_v1640.is_present()) { + HANDLE_CODE( + pack_integer(bref, meas_result_list_nr_v1640->carrier_freq_nr_r16, (uint32_t)0u, (uint32_t)3279165u)); + } + if (meas_result_list_ext_nr_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *meas_result_list_ext_nr_r16, 1, 7)); + } + } } return SRSASN_SUCCESS; } @@ -1774,7 +2613,7 @@ SRSASN_CODE conn_est_fail_report_r11_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(3); + ext_groups_unpacker_guard group_flags(5); group_flags.unpack(bref); if (group_flags[0]) { @@ -1821,6 +2660,33 @@ SRSASN_CODE conn_est_fail_report_r11_s::unpack(cbit_ref& bref) HANDLE_CODE(unpack_dyn_seq_of(*log_meas_result_list_wlan_r15, bref, 1, 32)); } } + if (group_flags[3]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool meas_result_list_nr_r16_present; + HANDLE_CODE(bref.unpack(meas_result_list_nr_r16_present, 1)); + meas_result_list_nr_r16.set_present(meas_result_list_nr_r16_present); + if (meas_result_list_nr_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*meas_result_list_nr_r16, bref, 1, 8)); + } + } + if (group_flags[4]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool meas_result_list_nr_v1640_present; + HANDLE_CODE(bref.unpack(meas_result_list_nr_v1640_present, 1)); + meas_result_list_nr_v1640.set_present(meas_result_list_nr_v1640_present); + bool meas_result_list_ext_nr_r16_present; + HANDLE_CODE(bref.unpack(meas_result_list_ext_nr_r16_present, 1)); + meas_result_list_ext_nr_r16.set_present(meas_result_list_ext_nr_r16_present); + if (meas_result_list_nr_v1640.is_present()) { + HANDLE_CODE( + unpack_integer(meas_result_list_nr_v1640->carrier_freq_nr_r16, bref, (uint32_t)0u, (uint32_t)3279165u)); + } + if (meas_result_list_ext_nr_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*meas_result_list_ext_nr_r16, bref, 1, 7)); + } + } } return SRSASN_SUCCESS; } @@ -1916,6 +2782,26 @@ void conn_est_fail_report_r11_s::to_json(json_writer& j) const } j.end_array(); } + if (meas_result_list_nr_r16.is_present()) { + j.start_array("measResultListNR-r16"); + for (const auto& e1 : *meas_result_list_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (meas_result_list_nr_v1640.is_present()) { + j.write_fieldname("measResultListNR-v1640"); + j.start_obj(); + j.write_int("carrierFreqNR-r16", meas_result_list_nr_v1640->carrier_freq_nr_r16); + j.end_obj(); + } + if (meas_result_list_ext_nr_r16.is_present()) { + j.start_array("measResultListExtNR-r16"); + for (const auto& e1 : *meas_result_list_ext_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } } j.end_obj(); } @@ -1955,6 +2841,9 @@ SRSASN_CODE in_dev_coex_ind_v1530_ies_s::pack(bit_ref& bref) const if (mrdc_assist_info_r15_present) { HANDLE_CODE(mrdc_assist_info_r15.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -1966,6 +2855,9 @@ SRSASN_CODE in_dev_coex_ind_v1530_ies_s::unpack(cbit_ref& bref) if (mrdc_assist_info_r15_present) { HANDLE_CODE(mrdc_assist_info_r15.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -1978,12 +2870,64 @@ void in_dev_coex_ind_v1530_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } +// MBMS-ROM-Info-r16 ::= SEQUENCE +SRSASN_CODE mbms_rom_info_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, mbms_rom_freq_r16, (uint32_t)0u, (uint32_t)262143u)); + HANDLE_CODE(mbms_rom_subcarrier_spacing_r16.pack(bref)); + HANDLE_CODE(mbms_bw_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mbms_rom_info_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(mbms_rom_freq_r16, bref, (uint32_t)0u, (uint32_t)262143u)); + HANDLE_CODE(mbms_rom_subcarrier_spacing_r16.unpack(bref)); + HANDLE_CODE(mbms_bw_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void mbms_rom_info_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("mbms-ROM-Freq-r16", mbms_rom_freq_r16); + j.write_str("mbms-ROM-SubcarrierSpacing-r16", mbms_rom_subcarrier_spacing_r16.to_string()); + j.write_str("mbms-Bandwidth-r16", mbms_bw_r16.to_string()); + j.end_obj(); +} + +const char* mbms_rom_info_r16_s::mbms_rom_subcarrier_spacing_r16_opts::to_string() const +{ + static const char* options[] = {"kHz2dot5", "kHz0dot37"}; + return convert_enum_idx(options, 2, value, "mbms_rom_info_r16_s::mbms_rom_subcarrier_spacing_r16_e_"); +} +float mbms_rom_info_r16_s::mbms_rom_subcarrier_spacing_r16_opts::to_number() const +{ + static const float options[] = {2.5, 0.37}; + return map_enum_number(options, 2, value, "mbms_rom_info_r16_s::mbms_rom_subcarrier_spacing_r16_e_"); +} +const char* mbms_rom_info_r16_s::mbms_rom_subcarrier_spacing_r16_opts::to_number_string() const +{ + static const char* options[] = {"2.5", "0.37"}; + return convert_enum_idx(options, 2, value, "mbms_rom_info_r16_s::mbms_rom_subcarrier_spacing_r16_e_"); +} + +const char* mbms_rom_info_r16_s::mbms_bw_r16_opts::to_string() const +{ + static const char* options[] = {"n6", "n15", "n25", "n50", "n75", "n100"}; + return convert_enum_idx(options, 6, value, "mbms_rom_info_r16_s::mbms_bw_r16_e_"); +} +uint8_t mbms_rom_info_r16_s::mbms_bw_r16_opts::to_number() const +{ + static const uint8_t options[] = {6, 15, 25, 50, 75, 100}; + return map_enum_number(options, 6, value, "mbms_rom_info_r16_s::mbms_bw_r16_e_"); +} + // RRCConnectionReconfigurationComplete-v1250-IEs ::= SEQUENCE SRSASN_CODE rrc_conn_recfg_complete_v1250_ies_s::pack(bit_ref& bref) const { @@ -2170,6 +3114,49 @@ void sl_v2x_comm_tx_res_req_r14_s::to_json(json_writer& j) const j.end_obj(); } +// UEAssistanceInformation-v1610-IEs ::= SEQUENCE +SRSASN_CODE ueassist_info_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(overheat_assist_v1610_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (overheat_assist_v1610_present) { + HANDLE_CODE(overheat_assist_v1610.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ueassist_info_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(overheat_assist_v1610_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (overheat_assist_v1610_present) { + HANDLE_CODE(overheat_assist_v1610.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ueassist_info_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (overheat_assist_v1610_present) { + j.write_fieldname("overheatingAssistance-v1610"); + overheat_assist_v1610.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + // UEInformationResponse-v1250-IEs ::= SEQUENCE SRSASN_CODE ue_info_resp_v1250_ies_s::pack(bit_ref& bref) const { @@ -2610,38 +3597,91 @@ void mbms_service_info_r13_s::to_json(json_writer& j) const j.end_obj(); } -// MeasResultFreqFailNR-r15 ::= SEQUENCE -SRSASN_CODE meas_result_freq_fail_nr_r15_s::pack(bit_ref& bref) const +// MBMSInterestIndication-v1610-IEs ::= SEQUENCE +SRSASN_CODE mbms_interest_ind_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(mbms_rom_info_list_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (mbms_rom_info_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, mbms_rom_info_list_r16, 1, 15)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE mbms_interest_ind_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(mbms_rom_info_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (mbms_rom_info_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(mbms_rom_info_list_r16, bref, 1, 15)); + } + + return SRSASN_SUCCESS; +} +void mbms_interest_ind_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (mbms_rom_info_list_r16_present) { + j.start_array("mbms-ROM-InfoList-r16"); + for (const auto& e1 : mbms_rom_info_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// MeasResult3EUTRA-r15 ::= SEQUENCE +SRSASN_CODE meas_result3_eutra_r15_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(meas_result_cell_list_r15_present, 1)); + HANDLE_CODE(bref.pack(meas_result_serving_cell_r15_present, 1)); + HANDLE_CODE(bref.pack(meas_result_neigh_cell_list_r15_present, 1)); - HANDLE_CODE(pack_integer(bref, carrier_freq_r15, (uint32_t)0u, (uint32_t)3279165u)); - if (meas_result_cell_list_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_cell_list_r15, 1, 8)); + HANDLE_CODE(pack_integer(bref, carrier_freq_r15, (uint32_t)0u, (uint32_t)262143u)); + if (meas_result_serving_cell_r15_present) { + HANDLE_CODE(meas_result_serving_cell_r15.pack(bref)); + } + if (meas_result_neigh_cell_list_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_neigh_cell_list_r15, 1, 8)); } return SRSASN_SUCCESS; } -SRSASN_CODE meas_result_freq_fail_nr_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE meas_result3_eutra_r15_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(meas_result_cell_list_r15_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_serving_cell_r15_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_neigh_cell_list_r15_present, 1)); - HANDLE_CODE(unpack_integer(carrier_freq_r15, bref, (uint32_t)0u, (uint32_t)3279165u)); - if (meas_result_cell_list_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(meas_result_cell_list_r15, bref, 1, 8)); + HANDLE_CODE(unpack_integer(carrier_freq_r15, bref, (uint32_t)0u, (uint32_t)262143u)); + if (meas_result_serving_cell_r15_present) { + HANDLE_CODE(meas_result_serving_cell_r15.unpack(bref)); + } + if (meas_result_neigh_cell_list_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_neigh_cell_list_r15, bref, 1, 8)); } return SRSASN_SUCCESS; } -void meas_result_freq_fail_nr_r15_s::to_json(json_writer& j) const +void meas_result3_eutra_r15_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("carrierFreq-r15", carrier_freq_r15); - if (meas_result_cell_list_r15_present) { - j.start_array("measResultCellList-r15"); - for (const auto& e1 : meas_result_cell_list_r15) { + if (meas_result_serving_cell_r15_present) { + j.write_fieldname("measResultServingCell-r15"); + meas_result_serving_cell_r15.to_json(j); + } + if (meas_result_neigh_cell_list_r15_present) { + j.start_array("measResultNeighCellList-r15"); + for (const auto& e1 : meas_result_neigh_cell_list_r15) { e1.to_json(j); } j.end_array(); @@ -2774,6 +3814,43 @@ void rrc_conn_reest_complete_v1020_ies_s::to_json(json_writer& j) const j.end_obj(); } +// RRCConnectionResumeComplete-v1710-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_complete_v1710_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_resume_complete_v1710_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_resume_complete_v1710_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (gnss_validity_dur_r17_present) { + j.write_str("gnss-ValidityDuration-r17", gnss_validity_dur_r17.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // RRCConnectionSetupComplete-v1130-IEs ::= SEQUENCE SRSASN_CODE rrc_conn_setup_complete_v1130_ies_s::pack(bit_ref& bref) const { @@ -3304,6 +4381,9 @@ SRSASN_CODE ueassist_info_v1530_ies_s::pack(bit_ref& bref) const if (sps_assist_info_v1530_present) { HANDLE_CODE(pack_dyn_seq_of(bref, sps_assist_info_v1530.traffic_pattern_info_list_sl_v1530, 1, 8)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -3315,6 +4395,9 @@ SRSASN_CODE ueassist_info_v1530_ies_s::unpack(cbit_ref& bref) if (sps_assist_info_v1530_present) { HANDLE_CODE(unpack_dyn_seq_of(sps_assist_info_v1530.traffic_pattern_info_list_sl_v1530, bref, 1, 8)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -3333,8 +4416,7 @@ void ueassist_info_v1530_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -3484,6 +4566,43 @@ const char* bw_pref_r14_s::ul_pref_r14_opts::to_number_string() const return convert_enum_idx(options, 2, value, "bw_pref_r14_s::ul_pref_r14_e_"); } +// CellGlobalIdNR-r16 ::= SEQUENCE +SRSASN_CODE cell_global_id_nr_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(tac_r16_present, 1)); + + HANDLE_CODE(plmn_id_r16.pack(bref)); + HANDLE_CODE(cell_id_r16.pack(bref)); + if (tac_r16_present) { + HANDLE_CODE(tac_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE cell_global_id_nr_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(tac_r16_present, 1)); + + HANDLE_CODE(plmn_id_r16.unpack(bref)); + HANDLE_CODE(cell_id_r16.unpack(bref)); + if (tac_r16_present) { + HANDLE_CODE(tac_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void cell_global_id_nr_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("plmn-Identity-r16"); + plmn_id_r16.to_json(j); + j.write_str("cellIdentity-r16", cell_id_r16.to_string()); + if (tac_r16_present) { + j.write_str("trackingAreaCode-r16", tac_r16.to_string()); + } + j.end_obj(); +} + // CounterCheckResponse-v1530-IEs ::= SEQUENCE SRSASN_CODE counter_check_resp_v1530_ies_s::pack(bit_ref& bref) const { @@ -3788,6 +4907,9 @@ SRSASN_CODE mbms_interest_ind_v1540_ies_s::pack(bit_ref& bref) const if (mbms_rom_info_list_r15_present) { HANDLE_CODE(pack_dyn_seq_of(bref, mbms_rom_info_list_r15, 1, 15)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -3799,6 +4921,9 @@ SRSASN_CODE mbms_interest_ind_v1540_ies_s::unpack(cbit_ref& bref) if (mbms_rom_info_list_r15_present) { HANDLE_CODE(unpack_dyn_seq_of(mbms_rom_info_list_r15, bref, 1, 15)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -3814,8 +4939,7 @@ void mbms_interest_ind_v1540_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -3903,20 +5027,111 @@ void rrc_conn_reest_complete_v8a0_ies_s::to_json(json_writer& j) const j.end_obj(); } -// RRCConnectionSetupComplete-v1020-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_setup_complete_v1020_ies_s::pack(bit_ref& bref) const +// RRCConnectionResumeComplete-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_complete_v1610_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(gummei_type_r10_present, 1)); - HANDLE_CODE(bref.pack(rlf_info_available_r10_present, 1)); - HANDLE_CODE(bref.pack(log_meas_available_r10_present, 1)); - HANDLE_CODE(bref.pack(rn_sf_cfg_req_r10_present, 1)); + HANDLE_CODE(bref.pack(meas_result_list_idle_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_result_list_ext_idle_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_result_list_idle_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(scg_cfg_resp_nr_r16_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (gummei_type_r10_present) { - HANDLE_CODE(gummei_type_r10.pack(bref)); + if (meas_result_list_idle_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_list_idle_r16, 1, 3)); } - if (rn_sf_cfg_req_r10_present) { - HANDLE_CODE(rn_sf_cfg_req_r10.pack(bref)); + if (meas_result_list_ext_idle_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_list_ext_idle_r16, 1, 5, SeqOfPacker(1, 8, Packer()))); + } + if (meas_result_list_idle_nr_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_list_idle_nr_r16, 1, 8)); + } + if (scg_cfg_resp_nr_r16_present) { + HANDLE_CODE(scg_cfg_resp_nr_r16.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_resume_complete_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(meas_result_list_idle_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_list_ext_idle_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_list_idle_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(scg_cfg_resp_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (meas_result_list_idle_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_list_idle_r16, bref, 1, 3)); + } + if (meas_result_list_ext_idle_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_list_ext_idle_r16, bref, 1, 5, SeqOfPacker(1, 8, Packer()))); + } + if (meas_result_list_idle_nr_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_list_idle_nr_r16, bref, 1, 8)); + } + if (scg_cfg_resp_nr_r16_present) { + HANDLE_CODE(scg_cfg_resp_nr_r16.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_resume_complete_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (meas_result_list_idle_r16_present) { + j.start_array("measResultListIdle-r16"); + for (const auto& e1 : meas_result_list_idle_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (meas_result_list_ext_idle_r16_present) { + j.start_array("measResultListExtIdle-r16"); + for (const auto& e1 : meas_result_list_ext_idle_r16) { + j.start_array(); + for (const auto& e2 : e1) { + e2.to_json(j); + } + j.end_array(); + } + j.end_array(); + } + if (meas_result_list_idle_nr_r16_present) { + j.start_array("measResultListIdleNR-r16"); + for (const auto& e1 : meas_result_list_idle_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (scg_cfg_resp_nr_r16_present) { + j.write_str("scg-ConfigResponseNR-r16", scg_cfg_resp_nr_r16.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// RRCConnectionSetupComplete-v1020-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_complete_v1020_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(gummei_type_r10_present, 1)); + HANDLE_CODE(bref.pack(rlf_info_available_r10_present, 1)); + HANDLE_CODE(bref.pack(log_meas_available_r10_present, 1)); + HANDLE_CODE(bref.pack(rn_sf_cfg_req_r10_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (gummei_type_r10_present) { + HANDLE_CODE(gummei_type_r10.pack(bref)); + } + if (rn_sf_cfg_req_r10_present) { + HANDLE_CODE(rn_sf_cfg_req_r10.pack(bref)); } if (non_crit_ext_present) { HANDLE_CODE(non_crit_ext.pack(bref)); @@ -4818,6 +6033,182 @@ void counter_check_resp_v8a0_ies_s::to_json(json_writer& j) const j.end_obj(); } +// FailedLogicalChannelIdentity-r16 ::= SEQUENCE +SRSASN_CODE failed_lc_ch_id_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(lc_ch_id_r16_present, 1)); + HANDLE_CODE(bref.pack(lc_ch_id_ext_r16_present, 1)); + + HANDLE_CODE(cell_group_ind_r16.pack(bref)); + if (lc_ch_id_r16_present) { + HANDLE_CODE(pack_integer(bref, lc_ch_id_r16, (uint8_t)1u, (uint8_t)10u)); + } + if (lc_ch_id_ext_r16_present) { + HANDLE_CODE(pack_integer(bref, lc_ch_id_ext_r16, (uint8_t)32u, (uint8_t)38u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE failed_lc_ch_id_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(lc_ch_id_r16_present, 1)); + HANDLE_CODE(bref.unpack(lc_ch_id_ext_r16_present, 1)); + + HANDLE_CODE(cell_group_ind_r16.unpack(bref)); + if (lc_ch_id_r16_present) { + HANDLE_CODE(unpack_integer(lc_ch_id_r16, bref, (uint8_t)1u, (uint8_t)10u)); + } + if (lc_ch_id_ext_r16_present) { + HANDLE_CODE(unpack_integer(lc_ch_id_ext_r16, bref, (uint8_t)32u, (uint8_t)38u)); + } + + return SRSASN_SUCCESS; +} +void failed_lc_ch_id_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("cellGroupIndication-r16", cell_group_ind_r16.to_string()); + if (lc_ch_id_r16_present) { + j.write_int("logicalChannelIdentity-r16", lc_ch_id_r16); + } + if (lc_ch_id_ext_r16_present) { + j.write_int("logicalChannelIdentityExt-r16", lc_ch_id_ext_r16); + } + j.end_obj(); +} + +const char* failed_lc_ch_id_r16_s::cell_group_ind_r16_opts::to_string() const +{ + static const char* options[] = {"mn", "sn"}; + return convert_enum_idx(options, 2, value, "failed_lc_ch_id_r16_s::cell_group_ind_r16_e_"); +} + +// FailureReportMCG-r16 ::= SEQUENCE +SRSASN_CODE fail_report_mcg_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(fail_type_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_result_freq_list_eutra_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_result_freq_list_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_result_freq_list_geran_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_result_freq_list_utra_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_result_scg_r16_present, 1)); + + if (fail_type_r16_present) { + HANDLE_CODE(fail_type_r16.pack(bref)); + } + if (meas_result_freq_list_eutra_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_freq_list_eutra_r16, 1, 8)); + } + if (meas_result_freq_list_nr_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_freq_list_nr_r16, 1, 5)); + } + if (meas_result_freq_list_geran_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_freq_list_geran_r16, 1, 3, SeqOfPacker(1, 8, Packer()))); + } + if (meas_result_freq_list_utra_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_freq_list_utra_r16, 1, 8)); + } + if (meas_result_scg_r16_present) { + HANDLE_CODE(meas_result_scg_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE fail_report_mcg_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(fail_type_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_freq_list_eutra_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_freq_list_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_freq_list_geran_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_freq_list_utra_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_scg_r16_present, 1)); + + if (fail_type_r16_present) { + HANDLE_CODE(fail_type_r16.unpack(bref)); + } + if (meas_result_freq_list_eutra_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_freq_list_eutra_r16, bref, 1, 8)); + } + if (meas_result_freq_list_nr_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_freq_list_nr_r16, bref, 1, 5)); + } + if (meas_result_freq_list_geran_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_freq_list_geran_r16, bref, 1, 3, SeqOfPacker(1, 8, Packer()))); + } + if (meas_result_freq_list_utra_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(meas_result_freq_list_utra_r16, bref, 1, 8)); + } + if (meas_result_scg_r16_present) { + HANDLE_CODE(meas_result_scg_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void fail_report_mcg_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (fail_type_r16_present) { + j.write_str("failureType-r16", fail_type_r16.to_string()); + } + if (meas_result_freq_list_eutra_r16_present) { + j.start_array("measResultFreqListEUTRA-r16"); + for (const auto& e1 : meas_result_freq_list_eutra_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (meas_result_freq_list_nr_r16_present) { + j.start_array("measResultFreqListNR-r16"); + for (const auto& e1 : meas_result_freq_list_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (meas_result_freq_list_geran_r16_present) { + j.start_array("measResultFreqListGERAN-r16"); + for (const auto& e1 : meas_result_freq_list_geran_r16) { + j.start_array(); + for (const auto& e2 : e1) { + e2.to_json(j); + } + j.end_array(); + } + j.end_array(); + } + if (meas_result_freq_list_utra_r16_present) { + j.start_array("measResultFreqListUTRA-r16"); + for (const auto& e1 : meas_result_freq_list_utra_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (meas_result_scg_r16_present) { + j.write_str("measResultSCG-r16", meas_result_scg_r16.to_string()); + } + j.end_obj(); +} + +const char* fail_report_mcg_r16_s::fail_type_r16_opts::to_string() const +{ + static const char* options[] = { + "t310-Expiry", "randomAccessProblem", "rlc-MaxNumRetx", "t312-Expiry", "spare4", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 8, value, "fail_report_mcg_r16_s::fail_type_r16_e_"); +} +uint16_t fail_report_mcg_r16_s::fail_type_r16_opts::to_number() const +{ + switch (value) { + case t310_expiry: + return 310; + case t312_expiry: + return 312; + default: + invalid_enum_number(value, "fail_report_mcg_r16_s::fail_type_r16_e_"); + } + return 0; +} + // FailureReportSCG-NR-r15 ::= SEQUENCE SRSASN_CODE fail_report_scg_nr_r15_s::pack(bit_ref& bref) const { @@ -4833,6 +6224,35 @@ SRSASN_CODE fail_report_scg_nr_r15_s::pack(bit_ref& bref) const HANDLE_CODE(meas_result_scg_r15.pack(bref)); } + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= location_info_r16.is_present(); + group_flags[0] |= log_meas_result_list_bt_r16.is_present(); + group_flags[0] |= log_meas_result_list_wlan_r16.is_present(); + group_flags[0] |= fail_type_v1610_present; + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(location_info_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(log_meas_result_list_bt_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(log_meas_result_list_wlan_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(fail_type_v1610_present, 1)); + if (location_info_r16.is_present()) { + HANDLE_CODE(location_info_r16->pack(bref)); + } + if (log_meas_result_list_bt_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *log_meas_result_list_bt_r16, 1, 32)); + } + if (log_meas_result_list_wlan_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *log_meas_result_list_wlan_r16, 1, 32)); + } + if (fail_type_v1610_present) { + HANDLE_CODE(fail_type_v1610.pack(bref)); + } + } + } return SRSASN_SUCCESS; } SRSASN_CODE fail_report_scg_nr_r15_s::unpack(cbit_ref& bref) @@ -4849,6 +6269,37 @@ SRSASN_CODE fail_report_scg_nr_r15_s::unpack(cbit_ref& bref) HANDLE_CODE(meas_result_scg_r15.unpack(bref)); } + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool location_info_r16_present; + HANDLE_CODE(bref.unpack(location_info_r16_present, 1)); + location_info_r16.set_present(location_info_r16_present); + bool log_meas_result_list_bt_r16_present; + HANDLE_CODE(bref.unpack(log_meas_result_list_bt_r16_present, 1)); + log_meas_result_list_bt_r16.set_present(log_meas_result_list_bt_r16_present); + bool log_meas_result_list_wlan_r16_present; + HANDLE_CODE(bref.unpack(log_meas_result_list_wlan_r16_present, 1)); + log_meas_result_list_wlan_r16.set_present(log_meas_result_list_wlan_r16_present); + HANDLE_CODE(bref.unpack(fail_type_v1610_present, 1)); + if (location_info_r16.is_present()) { + HANDLE_CODE(location_info_r16->unpack(bref)); + } + if (log_meas_result_list_bt_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*log_meas_result_list_bt_r16, bref, 1, 32)); + } + if (log_meas_result_list_wlan_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*log_meas_result_list_wlan_r16, bref, 1, 32)); + } + if (fail_type_v1610_present) { + HANDLE_CODE(fail_type_v1610.unpack(bref)); + } + } + } return SRSASN_SUCCESS; } void fail_report_scg_nr_r15_s::to_json(json_writer& j) const @@ -4865,6 +6316,29 @@ void fail_report_scg_nr_r15_s::to_json(json_writer& j) const if (meas_result_scg_r15_present) { j.write_str("measResultSCG-r15", meas_result_scg_r15.to_string()); } + if (ext) { + if (location_info_r16.is_present()) { + j.write_fieldname("locationInfo-r16"); + location_info_r16->to_json(j); + } + if (log_meas_result_list_bt_r16.is_present()) { + j.start_array("logMeasResultListBT-r16"); + for (const auto& e1 : *log_meas_result_list_bt_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (log_meas_result_list_wlan_r16.is_present()) { + j.start_array("logMeasResultListWLAN-r16"); + for (const auto& e1 : *log_meas_result_list_wlan_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (fail_type_v1610_present) { + j.write_str("failureType-v1610", fail_type_v1610.to_string()); + } + } j.end_obj(); } @@ -4875,8 +6349,9 @@ const char* fail_report_scg_nr_r15_s::fail_type_r15_opts::to_string() const "rlc-MaxNumRetx", "synchReconfigFailureSCG", "scg-reconfigFailure", - "srb3-IntegrityFailure"}; - return convert_enum_idx(options, 6, value, "fail_report_scg_nr_r15_s::fail_type_r15_e_"); + "srb3-IntegrityFailure", + "dummy"}; + return convert_enum_idx(options, 7, value, "fail_report_scg_nr_r15_s::fail_type_r15_e_"); } uint16_t fail_report_scg_nr_r15_s::fail_type_r15_opts::to_number() const { @@ -4891,6 +6366,24 @@ uint16_t fail_report_scg_nr_r15_s::fail_type_r15_opts::to_number() const return 0; } +const char* fail_report_scg_nr_r15_s::fail_type_v1610_opts::to_string() const +{ + static const char* options[] = {"t312-Expiry", + "scg-lbtFailure", + "beamFailureRecoveryFailure", + "bh-RLF-r16", + "beamFailure-r17", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 8, value, "fail_report_scg_nr_r15_s::fail_type_v1610_e_"); +} +uint16_t fail_report_scg_nr_r15_s::fail_type_v1610_opts::to_number() const +{ + static const uint16_t options[] = {312}; + return map_enum_number(options, 1, value, "fail_report_scg_nr_r15_s::fail_type_v1610_e_"); +} + // FailureReportSCG-r12 ::= SEQUENCE SRSASN_CODE fail_report_scg_r12_s::pack(bit_ref& bref) const { @@ -5201,6 +6694,29 @@ void proximity_ind_v930_ies_s::to_json(json_writer& j) const j.end_obj(); } +// RACH-Report-r16 ::= SEQUENCE +SRSASN_CODE rach_report_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, nof_preambs_sent_r16, (uint8_t)1u, (uint8_t)200u)); + HANDLE_CODE(bref.pack(contention_detected_r16, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rach_report_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(nof_preambs_sent_r16, bref, (uint8_t)1u, (uint8_t)200u)); + HANDLE_CODE(bref.unpack(contention_detected_r16, 1)); + + return SRSASN_SUCCESS; +} +void rach_report_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("numberOfPreamblesSent-r16", nof_preambs_sent_r16); + j.write_bool("contentionDetected-r16", contention_detected_r16); + j.end_obj(); +} + // RLF-Report-r9 ::= SEQUENCE SRSASN_CODE rlf_report_r9_s::pack(bit_ref& bref) const { @@ -5251,6 +6767,13 @@ SRSASN_CODE rlf_report_r9_s::pack(bit_ref& bref) const group_flags[5] |= meas_result_last_serv_cell_v1360_present; group_flags[6] |= log_meas_result_list_bt_r15.is_present(); group_flags[6] |= log_meas_result_list_wlan_r15.is_present(); + group_flags[7] |= meas_result_list_nr_r16.is_present(); + group_flags[7] |= prev_nr_pcell_id_r16.is_present(); + group_flags[7] |= failed_nr_pcell_id_r16.is_present(); + group_flags[7] |= reconnect_cell_id_r16.is_present(); + group_flags[7] |= time_until_reconn_r16_present; + group_flags[8] |= meas_result_list_nr_v1640.is_present(); + group_flags[8] |= meas_result_list_ext_nr_r16.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -5358,6 +6881,43 @@ SRSASN_CODE rlf_report_r9_s::pack(bit_ref& bref) const HANDLE_CODE(pack_dyn_seq_of(bref, *log_meas_result_list_wlan_r15, 1, 32)); } } + if (group_flags[7]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(meas_result_list_nr_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(prev_nr_pcell_id_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(failed_nr_pcell_id_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(reconnect_cell_id_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(time_until_reconn_r16_present, 1)); + if (meas_result_list_nr_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *meas_result_list_nr_r16, 1, 8)); + } + if (prev_nr_pcell_id_r16.is_present()) { + HANDLE_CODE(prev_nr_pcell_id_r16->pack(bref)); + } + if (failed_nr_pcell_id_r16.is_present()) { + HANDLE_CODE(failed_nr_pcell_id_r16->pack(bref)); + } + if (reconnect_cell_id_r16.is_present()) { + HANDLE_CODE(reconnect_cell_id_r16->pack(bref)); + } + if (time_until_reconn_r16_present) { + HANDLE_CODE(pack_integer(bref, time_until_reconn_r16, (uint32_t)0u, (uint32_t)172800u)); + } + } + if (group_flags[8]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(meas_result_list_nr_v1640.is_present(), 1)); + HANDLE_CODE(bref.pack(meas_result_list_ext_nr_r16.is_present(), 1)); + if (meas_result_list_nr_v1640.is_present()) { + HANDLE_CODE( + pack_integer(bref, meas_result_list_nr_v1640->carrier_freq_nr_r16, (uint32_t)0u, (uint32_t)3279165u)); + } + if (meas_result_list_ext_nr_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *meas_result_list_ext_nr_r16, 1, 7)); + } + } } return SRSASN_SUCCESS; } @@ -5391,7 +6951,7 @@ SRSASN_CODE rlf_report_r9_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(7); + ext_groups_unpacker_guard group_flags(9); group_flags.unpack(bref); if (group_flags[0]) { @@ -5526,6 +7086,55 @@ SRSASN_CODE rlf_report_r9_s::unpack(cbit_ref& bref) HANDLE_CODE(unpack_dyn_seq_of(*log_meas_result_list_wlan_r15, bref, 1, 32)); } } + if (group_flags[7]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool meas_result_list_nr_r16_present; + HANDLE_CODE(bref.unpack(meas_result_list_nr_r16_present, 1)); + meas_result_list_nr_r16.set_present(meas_result_list_nr_r16_present); + bool prev_nr_pcell_id_r16_present; + HANDLE_CODE(bref.unpack(prev_nr_pcell_id_r16_present, 1)); + prev_nr_pcell_id_r16.set_present(prev_nr_pcell_id_r16_present); + bool failed_nr_pcell_id_r16_present; + HANDLE_CODE(bref.unpack(failed_nr_pcell_id_r16_present, 1)); + failed_nr_pcell_id_r16.set_present(failed_nr_pcell_id_r16_present); + bool reconnect_cell_id_r16_present; + HANDLE_CODE(bref.unpack(reconnect_cell_id_r16_present, 1)); + reconnect_cell_id_r16.set_present(reconnect_cell_id_r16_present); + HANDLE_CODE(bref.unpack(time_until_reconn_r16_present, 1)); + if (meas_result_list_nr_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*meas_result_list_nr_r16, bref, 1, 8)); + } + if (prev_nr_pcell_id_r16.is_present()) { + HANDLE_CODE(prev_nr_pcell_id_r16->unpack(bref)); + } + if (failed_nr_pcell_id_r16.is_present()) { + HANDLE_CODE(failed_nr_pcell_id_r16->unpack(bref)); + } + if (reconnect_cell_id_r16.is_present()) { + HANDLE_CODE(reconnect_cell_id_r16->unpack(bref)); + } + if (time_until_reconn_r16_present) { + HANDLE_CODE(unpack_integer(time_until_reconn_r16, bref, (uint32_t)0u, (uint32_t)172800u)); + } + } + if (group_flags[8]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool meas_result_list_nr_v1640_present; + HANDLE_CODE(bref.unpack(meas_result_list_nr_v1640_present, 1)); + meas_result_list_nr_v1640.set_present(meas_result_list_nr_v1640_present); + bool meas_result_list_ext_nr_r16_present; + HANDLE_CODE(bref.unpack(meas_result_list_ext_nr_r16_present, 1)); + meas_result_list_ext_nr_r16.set_present(meas_result_list_ext_nr_r16_present); + if (meas_result_list_nr_v1640.is_present()) { + HANDLE_CODE( + unpack_integer(meas_result_list_nr_v1640->carrier_freq_nr_r16, bref, (uint32_t)0u, (uint32_t)3279165u)); + } + if (meas_result_list_ext_nr_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*meas_result_list_ext_nr_r16, bref, 1, 7)); + } + } } return SRSASN_SUCCESS; } @@ -5669,6 +7278,41 @@ void rlf_report_r9_s::to_json(json_writer& j) const } j.end_array(); } + if (meas_result_list_nr_r16.is_present()) { + j.start_array("measResultListNR-r16"); + for (const auto& e1 : *meas_result_list_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (prev_nr_pcell_id_r16.is_present()) { + j.write_fieldname("previousNR-PCellId-r16"); + prev_nr_pcell_id_r16->to_json(j); + } + if (failed_nr_pcell_id_r16.is_present()) { + j.write_fieldname("failedNR-PCellId-r16"); + failed_nr_pcell_id_r16->to_json(j); + } + if (reconnect_cell_id_r16.is_present()) { + j.write_fieldname("reconnectCellId-r16"); + reconnect_cell_id_r16->to_json(j); + } + if (time_until_reconn_r16_present) { + j.write_int("timeUntilReconnection-r16", time_until_reconn_r16); + } + if (meas_result_list_nr_v1640.is_present()) { + j.write_fieldname("measResultListNR-v1640"); + j.start_obj(); + j.write_int("carrierFreqNR-r16", meas_result_list_nr_v1640->carrier_freq_nr_r16); + j.end_obj(); + } + if (meas_result_list_ext_nr_r16.is_present()) { + j.start_array("measResultListExtNR-r16"); + for (const auto& e1 : *meas_result_list_ext_nr_r16) { + e1.to_json(j); + } + j.end_array(); + } } j.end_obj(); } @@ -5814,229 +7458,522 @@ const char* rlf_report_r9_s::conn_fail_type_r10_opts::to_string() const return convert_enum_idx(options, 2, value, "rlf_report_r9_s::conn_fail_type_r10_e_"); } -const char* rlf_report_r9_s::basic_fields_r11_s_::rlf_cause_r11_opts::to_string() const -{ - static const char* options[] = {"t310-Expiry", "randomAccessProblem", "rlc-MaxNumRetx", "t312-Expiry-r12"}; - return convert_enum_idx(options, 4, value, "rlf_report_r9_s::basic_fields_r11_s_::rlf_cause_r11_e_"); -} -uint16_t rlf_report_r9_s::basic_fields_r11_s_::rlf_cause_r11_opts::to_number() const +const char* rlf_report_r9_s::basic_fields_r11_s_::rlf_cause_r11_opts::to_string() const +{ + static const char* options[] = {"t310-Expiry", "randomAccessProblem", "rlc-MaxNumRetx", "t312-Expiry-r12"}; + return convert_enum_idx(options, 4, value, "rlf_report_r9_s::basic_fields_r11_s_::rlf_cause_r11_e_"); +} +uint16_t rlf_report_r9_s::basic_fields_r11_s_::rlf_cause_r11_opts::to_number() const +{ + switch (value) { + case t310_expiry: + return 310; + case t312_expiry_r12: + return 312; + default: + invalid_enum_number(value, "rlf_report_r9_s::basic_fields_r11_s_::rlf_cause_r11_e_"); + } + return 0; +} + +void rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::destroy_() {} +void rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::pci_r11_c_( + const rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::fdd_r11: + c.init(other.c.get()); + break; + case types::tdd_r11: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_"); + } +} +rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_& rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::operator=( + const rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::fdd_r11: + c.set(other.c.get()); + break; + case types::tdd_r11: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_"); + } + + return *this; +} +uint16_t& rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::set_fdd_r11() +{ + set(types::fdd_r11); + return c.get(); +} +uint8_t& rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::set_tdd_r11() +{ + set(types::tdd_r11); + return c.get(); +} +void rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::fdd_r11: + j.write_int("fdd-r11", c.get()); + break; + case types::tdd_r11: + j.write_int("tdd-r11", c.get()); + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_"); + } + j.end_obj(); +} +SRSASN_CODE rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::fdd_r11: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)511u)); + break; + case types::tdd_r11: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::fdd_r11: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)511u)); + break; + case types::tdd_r11: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +void rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::destroy_() {} +void rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::pci_r11_c_( + const rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::fdd_r11: + c.init(other.c.get()); + break; + case types::tdd_r11: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_"); + } +} +rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_& rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::operator=( + const rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::fdd_r11: + c.set(other.c.get()); + break; + case types::tdd_r11: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_"); + } + + return *this; +} +uint16_t& rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::set_fdd_r11() +{ + set(types::fdd_r11); + return c.get(); +} +uint8_t& rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::set_tdd_r11() +{ + set(types::tdd_r11); + return c.get(); +} +void rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::fdd_r11: + j.write_int("fdd-r11", c.get()); + break; + case types::tdd_r11: + j.write_int("tdd-r11", c.get()); + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_"); + } + j.end_obj(); +} +SRSASN_CODE rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::fdd_r11: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)511u)); + break; + case types::tdd_r11: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::fdd_r11: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)511u)); + break; + case types::tdd_r11: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +void rlf_report_r9_s::failed_nr_pcell_id_r16_c_::destroy_() { - switch (value) { - case t310_expiry: - return 310; - case t312_expiry_r12: - return 312; + switch (type_) { + case types::cell_global_id: + c.destroy(); + break; + case types::pci_arfcn: + c.destroy(); + break; default: - invalid_enum_number(value, "rlf_report_r9_s::basic_fields_r11_s_::rlf_cause_r11_e_"); + break; } - return 0; } - -void rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::destroy_() {} -void rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::set(types::options e) +void rlf_report_r9_s::failed_nr_pcell_id_r16_c_::set(types::options e) { destroy_(); type_ = e; + switch (type_) { + case types::cell_global_id: + c.init(); + break; + case types::pci_arfcn: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::failed_nr_pcell_id_r16_c_"); + } } -rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::pci_r11_c_( - const rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_& other) +rlf_report_r9_s::failed_nr_pcell_id_r16_c_::failed_nr_pcell_id_r16_c_( + const rlf_report_r9_s::failed_nr_pcell_id_r16_c_& other) { type_ = other.type(); switch (type_) { - case types::fdd_r11: - c.init(other.c.get()); + case types::cell_global_id: + c.init(other.c.get()); break; - case types::tdd_r11: - c.init(other.c.get()); + case types::pci_arfcn: + c.init(other.c.get()); break; case types::nulltype: break; default: - log_invalid_choice_id(type_, "rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_"); + log_invalid_choice_id(type_, "rlf_report_r9_s::failed_nr_pcell_id_r16_c_"); } } -rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_& rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::operator=( - const rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_& other) +rlf_report_r9_s::failed_nr_pcell_id_r16_c_& +rlf_report_r9_s::failed_nr_pcell_id_r16_c_::operator=(const rlf_report_r9_s::failed_nr_pcell_id_r16_c_& other) { if (this == &other) { return *this; } set(other.type()); switch (type_) { - case types::fdd_r11: - c.set(other.c.get()); + case types::cell_global_id: + c.set(other.c.get()); break; - case types::tdd_r11: - c.set(other.c.get()); + case types::pci_arfcn: + c.set(other.c.get()); break; case types::nulltype: break; default: - log_invalid_choice_id(type_, "rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_"); + log_invalid_choice_id(type_, "rlf_report_r9_s::failed_nr_pcell_id_r16_c_"); } return *this; } -uint16_t& rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::set_fdd_r11() +cell_global_id_nr_r16_s& rlf_report_r9_s::failed_nr_pcell_id_r16_c_::set_cell_global_id() { - set(types::fdd_r11); - return c.get(); + set(types::cell_global_id); + return c.get(); } -uint8_t& rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::set_tdd_r11() +rlf_report_r9_s::failed_nr_pcell_id_r16_c_::pci_arfcn_s_& rlf_report_r9_s::failed_nr_pcell_id_r16_c_::set_pci_arfcn() { - set(types::tdd_r11); - return c.get(); + set(types::pci_arfcn); + return c.get(); } -void rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::to_json(json_writer& j) const +void rlf_report_r9_s::failed_nr_pcell_id_r16_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::fdd_r11: - j.write_int("fdd-r11", c.get()); + case types::cell_global_id: + j.write_fieldname("cellGlobalId"); + c.get().to_json(j); break; - case types::tdd_r11: - j.write_int("tdd-r11", c.get()); + case types::pci_arfcn: + j.write_fieldname("pci-arfcn"); + j.start_obj(); + j.write_int("physCellId-r16", c.get().pci_r16); + j.write_int("carrierFreq-r16", c.get().carrier_freq_r16); + j.end_obj(); break; default: - log_invalid_choice_id(type_, "rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_"); + log_invalid_choice_id(type_, "rlf_report_r9_s::failed_nr_pcell_id_r16_c_"); } j.end_obj(); } -SRSASN_CODE rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::pack(bit_ref& bref) const +SRSASN_CODE rlf_report_r9_s::failed_nr_pcell_id_r16_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::fdd_r11: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)511u)); + case types::cell_global_id: + HANDLE_CODE(c.get().pack(bref)); break; - case types::tdd_r11: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + case types::pci_arfcn: + HANDLE_CODE(pack_integer(bref, c.get().pci_r16, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(pack_integer(bref, c.get().carrier_freq_r16, (uint32_t)0u, (uint32_t)3279165u)); break; default: - log_invalid_choice_id(type_, "rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_"); + log_invalid_choice_id(type_, "rlf_report_r9_s::failed_nr_pcell_id_r16_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_::unpack(cbit_ref& bref) +SRSASN_CODE rlf_report_r9_s::failed_nr_pcell_id_r16_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::fdd_r11: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)511u)); + case types::cell_global_id: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::tdd_r11: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + case types::pci_arfcn: + HANDLE_CODE(unpack_integer(c.get().pci_r16, bref, (uint16_t)0u, (uint16_t)1007u)); + HANDLE_CODE(unpack_integer(c.get().carrier_freq_r16, bref, (uint32_t)0u, (uint32_t)3279165u)); break; default: - log_invalid_choice_id(type_, "rlf_report_r9_s::prev_utra_cell_id_r11_s_::pci_r11_c_"); + log_invalid_choice_id(type_, "rlf_report_r9_s::failed_nr_pcell_id_r16_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::destroy_() {} -void rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::set(types::options e) +void rlf_report_r9_s::reconnect_cell_id_r16_c_::destroy_() +{ + switch (type_) { + case types::nr_reconnect_cell_id: + c.destroy(); + break; + case types::eutra_reconnect_cell_id: + c.destroy(); + break; + default: + break; + } +} +void rlf_report_r9_s::reconnect_cell_id_r16_c_::set(types::options e) { destroy_(); type_ = e; + switch (type_) { + case types::nr_reconnect_cell_id: + c.init(); + break; + case types::eutra_reconnect_cell_id: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rlf_report_r9_s::reconnect_cell_id_r16_c_"); + } } -rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::pci_r11_c_( - const rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_& other) +rlf_report_r9_s::reconnect_cell_id_r16_c_::reconnect_cell_id_r16_c_( + const rlf_report_r9_s::reconnect_cell_id_r16_c_& other) { type_ = other.type(); switch (type_) { - case types::fdd_r11: - c.init(other.c.get()); + case types::nr_reconnect_cell_id: + c.init(other.c.get()); break; - case types::tdd_r11: - c.init(other.c.get()); + case types::eutra_reconnect_cell_id: + c.init(other.c.get()); break; case types::nulltype: break; default: - log_invalid_choice_id(type_, "rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_"); + log_invalid_choice_id(type_, "rlf_report_r9_s::reconnect_cell_id_r16_c_"); } } -rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_& rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::operator=( - const rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_& other) +rlf_report_r9_s::reconnect_cell_id_r16_c_& +rlf_report_r9_s::reconnect_cell_id_r16_c_::operator=(const rlf_report_r9_s::reconnect_cell_id_r16_c_& other) { if (this == &other) { return *this; } set(other.type()); switch (type_) { - case types::fdd_r11: - c.set(other.c.get()); + case types::nr_reconnect_cell_id: + c.set(other.c.get()); break; - case types::tdd_r11: - c.set(other.c.get()); + case types::eutra_reconnect_cell_id: + c.set(other.c.get()); break; case types::nulltype: break; default: - log_invalid_choice_id(type_, "rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_"); + log_invalid_choice_id(type_, "rlf_report_r9_s::reconnect_cell_id_r16_c_"); } return *this; } -uint16_t& rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::set_fdd_r11() +cell_global_id_nr_r16_s& rlf_report_r9_s::reconnect_cell_id_r16_c_::set_nr_reconnect_cell_id() { - set(types::fdd_r11); - return c.get(); + set(types::nr_reconnect_cell_id); + return c.get(); } -uint8_t& rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::set_tdd_r11() +rlf_report_r9_s::reconnect_cell_id_r16_c_::eutra_reconnect_cell_id_s_& +rlf_report_r9_s::reconnect_cell_id_r16_c_::set_eutra_reconnect_cell_id() { - set(types::tdd_r11); - return c.get(); + set(types::eutra_reconnect_cell_id); + return c.get(); } -void rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::to_json(json_writer& j) const +void rlf_report_r9_s::reconnect_cell_id_r16_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::fdd_r11: - j.write_int("fdd-r11", c.get()); + case types::nr_reconnect_cell_id: + j.write_fieldname("nrReconnectCellId"); + c.get().to_json(j); break; - case types::tdd_r11: - j.write_int("tdd-r11", c.get()); + case types::eutra_reconnect_cell_id: + j.write_fieldname("eutraReconnectCellId"); + j.start_obj(); + j.write_fieldname("cellGlobalId-r16"); + c.get().cell_global_id_r16.to_json(j); + if (c.get().tac_epc_r16_present) { + j.write_str("trackingAreaCode-EPC-r16", c.get().tac_epc_r16.to_string()); + } + if (c.get().tac_minus5_gc_r16_present) { + j.write_str("trackingAreaCode-5GC-r16", c.get().tac_minus5_gc_r16.to_string()); + } + j.end_obj(); break; default: - log_invalid_choice_id(type_, "rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_"); + log_invalid_choice_id(type_, "rlf_report_r9_s::reconnect_cell_id_r16_c_"); } j.end_obj(); } -SRSASN_CODE rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::pack(bit_ref& bref) const +SRSASN_CODE rlf_report_r9_s::reconnect_cell_id_r16_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::fdd_r11: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)511u)); + case types::nr_reconnect_cell_id: + HANDLE_CODE(c.get().pack(bref)); break; - case types::tdd_r11: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + case types::eutra_reconnect_cell_id: + HANDLE_CODE(bref.pack(c.get().tac_epc_r16_present, 1)); + HANDLE_CODE(bref.pack(c.get().tac_minus5_gc_r16_present, 1)); + HANDLE_CODE(c.get().cell_global_id_r16.pack(bref)); + if (c.get().tac_epc_r16_present) { + HANDLE_CODE(c.get().tac_epc_r16.pack(bref)); + } + if (c.get().tac_minus5_gc_r16_present) { + HANDLE_CODE(c.get().tac_minus5_gc_r16.pack(bref)); + } break; default: - log_invalid_choice_id(type_, "rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_"); + log_invalid_choice_id(type_, "rlf_report_r9_s::reconnect_cell_id_r16_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_::unpack(cbit_ref& bref) +SRSASN_CODE rlf_report_r9_s::reconnect_cell_id_r16_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::fdd_r11: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)511u)); + case types::nr_reconnect_cell_id: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::tdd_r11: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + case types::eutra_reconnect_cell_id: + HANDLE_CODE(bref.unpack(c.get().tac_epc_r16_present, 1)); + HANDLE_CODE(bref.unpack(c.get().tac_minus5_gc_r16_present, 1)); + HANDLE_CODE(c.get().cell_global_id_r16.unpack(bref)); + if (c.get().tac_epc_r16_present) { + HANDLE_CODE(c.get().tac_epc_r16.unpack(bref)); + } + if (c.get().tac_minus5_gc_r16_present) { + HANDLE_CODE(c.get().tac_minus5_gc_r16.unpack(bref)); + } break; default: - log_invalid_choice_id(type_, "rlf_report_r9_s::sel_utra_cell_id_r11_s_::pci_r11_c_"); + log_invalid_choice_id(type_, "rlf_report_r9_s::reconnect_cell_id_r16_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; @@ -6129,6 +8066,10 @@ SRSASN_CODE rrc_conn_resume_complete_v1530_ies_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(flight_path_info_available_r15_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + return SRSASN_SUCCESS; } SRSASN_CODE rrc_conn_resume_complete_v1530_ies_s::unpack(cbit_ref& bref) @@ -6139,6 +8080,10 @@ SRSASN_CODE rrc_conn_resume_complete_v1530_ies_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(flight_path_info_available_r15_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + return SRSASN_SUCCESS; } void rrc_conn_resume_complete_v1530_ies_s::to_json(json_writer& j) const @@ -6158,8 +8103,7 @@ void rrc_conn_resume_complete_v1530_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -7090,6 +9034,61 @@ const char* failed_lc_ch_info_r15_s::fail_type_opts::to_string() const return convert_enum_idx(options, 4, value, "failed_lc_ch_info_r15_s::fail_type_e_"); } +// FailureInformation-r16-IEs ::= SEQUENCE +SRSASN_CODE fail_info_r16_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(failed_lc_ch_id_r16_present, 1)); + HANDLE_CODE(bref.pack(fail_type_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (failed_lc_ch_id_r16_present) { + HANDLE_CODE(failed_lc_ch_id_r16.pack(bref)); + } + if (fail_type_r16_present) { + HANDLE_CODE(fail_type_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE fail_info_r16_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(failed_lc_ch_id_r16_present, 1)); + HANDLE_CODE(bref.unpack(fail_type_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (failed_lc_ch_id_r16_present) { + HANDLE_CODE(failed_lc_ch_id_r16.unpack(bref)); + } + if (fail_type_r16_present) { + HANDLE_CODE(fail_type_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void fail_info_r16_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (failed_lc_ch_id_r16_present) { + j.write_fieldname("failedLogicalChannelIdentity-r16"); + failed_lc_ch_id_r16.to_json(j); + } + if (fail_type_r16_present) { + j.write_str("failureType-r16", fail_type_r16.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +const char* fail_info_r16_ies_s::fail_type_r16_opts::to_string() const +{ + static const char* options[] = {"duplication", "dapsHO-failure", "spare2", "spare1"}; + return convert_enum_idx(options, 4, value, "fail_info_r16_ies_s::fail_type_r16_e_"); +} + // InDeviceCoexIndication-r11-IEs ::= SEQUENCE SRSASN_CODE in_dev_coex_ind_r11_ies_s::pack(bit_ref& bref) const { @@ -7393,6 +9392,55 @@ void mbms_interest_ind_r11_ies_s::to_json(json_writer& j) const j.end_obj(); } +// MCGFailureInformation-r16-IEs ::= SEQUENCE +SRSASN_CODE mcg_fail_info_r16_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(fail_report_mcg_r16_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (fail_report_mcg_r16_present) { + HANDLE_CODE(fail_report_mcg_r16.pack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE mcg_fail_info_r16_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(fail_report_mcg_r16_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (fail_report_mcg_r16_present) { + HANDLE_CODE(fail_report_mcg_r16.unpack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void mcg_fail_info_r16_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (fail_report_mcg_r16_present) { + j.write_fieldname("failureReportMCG-r16"); + fail_report_mcg_r16.to_json(j); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // MeasReportAppLayer-r15-IEs ::= SEQUENCE SRSASN_CODE meas_report_app_layer_r15_ies_s::pack(bit_ref& bref) const { @@ -7406,50 +9454,237 @@ SRSASN_CODE meas_report_app_layer_r15_ies_s::pack(bit_ref& bref) const if (service_type_r15_present) { HANDLE_CODE(service_type_r15.pack(bref)); } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_report_app_layer_r15_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(meas_report_app_layer_container_r15_present, 1)); + HANDLE_CODE(bref.unpack(service_type_r15_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (meas_report_app_layer_container_r15_present) { + HANDLE_CODE(meas_report_app_layer_container_r15.unpack(bref)); + } + if (service_type_r15_present) { + HANDLE_CODE(service_type_r15.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void meas_report_app_layer_r15_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (meas_report_app_layer_container_r15_present) { + j.write_str("measReportAppLayerContainer-r15", meas_report_app_layer_container_r15.to_string()); + } + if (service_type_r15_present) { + j.write_str("serviceType-r15", service_type_r15.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +const char* meas_report_app_layer_r15_ies_s::service_type_r15_opts::to_string() const +{ + static const char* options[] = {"qoe", "qoemtsi", "spare6", "spare5", "spare4", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 8, value, "meas_report_app_layer_r15_ies_s::service_type_r15_e_"); +} + +// PURConfigurationRequest-r16-IEs ::= SEQUENCE +SRSASN_CODE pur_cfg_request_r16_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pur_cfg_request_r16_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (pur_cfg_request_r16_present) { + HANDLE_CODE(pur_cfg_request_r16.pack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE meas_report_app_layer_r15_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE pur_cfg_request_r16_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(meas_report_app_layer_container_r15_present, 1)); - HANDLE_CODE(bref.unpack(service_type_r15_present, 1)); + HANDLE_CODE(bref.unpack(pur_cfg_request_r16_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - if (meas_report_app_layer_container_r15_present) { - HANDLE_CODE(meas_report_app_layer_container_r15.unpack(bref)); - } - if (service_type_r15_present) { - HANDLE_CODE(service_type_r15.unpack(bref)); + if (pur_cfg_request_r16_present) { + HANDLE_CODE(pur_cfg_request_r16.unpack(bref)); } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); } return SRSASN_SUCCESS; } -void meas_report_app_layer_r15_ies_s::to_json(json_writer& j) const +void pur_cfg_request_r16_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (meas_report_app_layer_container_r15_present) { - j.write_str("measReportAppLayerContainer-r15", meas_report_app_layer_container_r15.to_string()); + if (pur_cfg_request_r16_present) { + j.write_fieldname("pur-ConfigRequest-r16"); + pur_cfg_request_r16.to_json(j); } - if (service_type_r15_present) { - j.write_str("serviceType-r15", service_type_r15.to_string()); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); + j.start_obj(); + j.end_obj(); } j.end_obj(); } -const char* meas_report_app_layer_r15_ies_s::service_type_r15_opts::to_string() const +void pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::set(types::options e) { - static const char* options[] = {"qoe", "qoemtsi", "spare6", "spare5", "spare4", "spare3", "spare2", "spare1"}; - return convert_enum_idx(options, 8, value, "meas_report_app_layer_r15_ies_s::service_type_r15_e_"); + type_ = e; +} +void pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::set_pur_release_request() +{ + set(types::pur_release_request); +} +pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::pur_setup_request_s_& +pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::set_pur_setup_request() +{ + set(types::pur_setup_request); + return c; +} +void pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::pur_release_request: + break; + case types::pur_setup_request: + j.write_fieldname("pur-SetupRequest"); + j.start_obj(); + j.write_str("requestedNumOccasions-r16", c.requested_num_occasions_r16.to_string()); + if (c.requested_periodicity_and_offset_r16_present) { + j.write_fieldname("requestedPeriodicityAndOffset-r16"); + c.requested_periodicity_and_offset_r16.to_json(j); + } + j.write_str("requestedTBS-r16", c.requested_tbs_r16.to_string()); + if (c.rrc_ack_r16_present) { + j.write_str("rrc-ACK-r16", "true"); + } + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_"); + } + j.end_obj(); +} +SRSASN_CODE pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::pur_release_request: + break; + case types::pur_setup_request: + HANDLE_CODE(bref.pack(c.requested_periodicity_and_offset_r16_present, 1)); + HANDLE_CODE(bref.pack(c.rrc_ack_r16_present, 1)); + HANDLE_CODE(c.requested_num_occasions_r16.pack(bref)); + if (c.requested_periodicity_and_offset_r16_present) { + HANDLE_CODE(c.requested_periodicity_and_offset_r16.pack(bref)); + } + HANDLE_CODE(c.requested_tbs_r16.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::pur_release_request: + break; + case types::pur_setup_request: + HANDLE_CODE(bref.unpack(c.requested_periodicity_and_offset_r16_present, 1)); + HANDLE_CODE(bref.unpack(c.rrc_ack_r16_present, 1)); + HANDLE_CODE(c.requested_num_occasions_r16.unpack(bref)); + if (c.requested_periodicity_and_offset_r16_present) { + HANDLE_CODE(c.requested_periodicity_and_offset_r16.unpack(bref)); + } + HANDLE_CODE(c.requested_tbs_r16.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* +pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::pur_setup_request_s_::requested_num_occasions_r16_opts::to_string() + const +{ + static const char* options[] = {"one", "infinite"}; + return convert_enum_idx( + options, + 2, + value, + "pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::pur_setup_request_s_::requested_num_occasions_r16_e_"); +} +uint8_t +pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::pur_setup_request_s_::requested_num_occasions_r16_opts::to_number() + const +{ + static const uint8_t options[] = {1}; + return map_enum_number( + options, + 1, + value, + "pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::pur_setup_request_s_::requested_num_occasions_r16_e_"); +} + +const char* +pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::pur_setup_request_s_::requested_tbs_r16_opts::to_string() const +{ + static const char* options[] = { + "b328", "b344", "b376", "b392", "b408", "b424", "b440", "b456", "b472", "b488", "b504", + "b536", "b568", "b584", "b616", "b648", "b680", "b712", "b744", "b776", "b808", "b840", + "b872", "b904", "b936", "b968", "b1000", "b1032", "b1064", "b1096", "b1128", "b1160", "b1192", + "b1224", "b1256", "b1288", "b1320", "b1352", "b1384", "b1416", "b1480", "b1544", "b1608", "b1672", + "b1736", "b1800", "b1864", "b1928", "b1992", "b2024", "b2088", "b2152", "b2216", "b2280", "b2344", + "b2408", "b2472", "b2536", "b2600", "b2664", "b2728", "b2792", "b2856", "b2984"}; + return convert_enum_idx( + options, + 64, + value, + "pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::pur_setup_request_s_::requested_tbs_r16_e_"); +} +uint16_t +pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::pur_setup_request_s_::requested_tbs_r16_opts::to_number() const +{ + static const uint16_t options[] = {328, 344, 376, 392, 408, 424, 440, 456, 472, 488, 504, 536, 568, + 584, 616, 648, 680, 712, 744, 776, 808, 840, 872, 904, 936, 968, + 1000, 1032, 1064, 1096, 1128, 1160, 1192, 1224, 1256, 1288, 1320, 1352, 1384, + 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 1992, 2024, 2088, 2152, + 2216, 2280, 2344, 2408, 2472, 2536, 2600, 2664, 2728, 2792, 2856, 2984}; + return map_enum_number( + options, + 64, + value, + "pur_cfg_request_r16_ies_s::pur_cfg_request_r16_c_::pur_setup_request_s_::requested_tbs_r16_e_"); } // ProximityIndication-r9-IEs ::= SEQUENCE @@ -8110,8 +10345,7 @@ SRSASN_CODE ue_info_resp_r9_ies_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (rach_report_r9_present) { - HANDLE_CODE(pack_integer(bref, rach_report_r9.nof_preambs_sent_r9, (uint8_t)1u, (uint8_t)200u)); - HANDLE_CODE(bref.pack(rach_report_r9.contention_detected_r9, 1)); + HANDLE_CODE(rach_report_r9.pack(bref)); } if (rlf_report_r9_present) { HANDLE_CODE(rlf_report_r9.pack(bref)); @@ -8129,8 +10363,7 @@ SRSASN_CODE ue_info_resp_r9_ies_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); if (rach_report_r9_present) { - HANDLE_CODE(unpack_integer(rach_report_r9.nof_preambs_sent_r9, bref, (uint8_t)1u, (uint8_t)200u)); - HANDLE_CODE(bref.unpack(rach_report_r9.contention_detected_r9, 1)); + HANDLE_CODE(rach_report_r9.unpack(bref)); } if (rlf_report_r9_present) { HANDLE_CODE(rlf_report_r9.unpack(bref)); @@ -8146,10 +10379,7 @@ void ue_info_resp_r9_ies_s::to_json(json_writer& j) const j.start_obj(); if (rach_report_r9_present) { j.write_fieldname("rach-Report-r9"); - j.start_obj(); - j.write_int("numberOfPreamblesSent-r9", rach_report_r9.nof_preambs_sent_r9); - j.write_bool("contentionDetected-r9", rach_report_r9.contention_detected_r9); - j.end_obj(); + rach_report_r9.to_json(j); } if (rlf_report_r9_present) { j.write_fieldname("rlf-Report-r9"); @@ -8162,6 +10392,58 @@ void ue_info_resp_r9_ies_s::to_json(json_writer& j) const j.end_obj(); } +// ULDedicatedMessageSegment-r16-IEs ::= SEQUENCE +SRSASN_CODE ul_ded_msg_segment_r16_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(pack_integer(bref, segment_num_r16, (uint8_t)0u, (uint8_t)15u)); + HANDLE_CODE(rrc_msg_segment_container_r16.pack(bref)); + HANDLE_CODE(rrc_msg_segment_type_r16.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ul_ded_msg_segment_r16_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(unpack_integer(segment_num_r16, bref, (uint8_t)0u, (uint8_t)15u)); + HANDLE_CODE(rrc_msg_segment_container_r16.unpack(bref)); + HANDLE_CODE(rrc_msg_segment_type_r16.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ul_ded_msg_segment_r16_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("segmentNumber-r16", segment_num_r16); + j.write_str("rrc-MessageSegmentContainer-r16", rrc_msg_segment_container_r16.to_string()); + j.write_str("rrc-MessageSegmentType-r16", rrc_msg_segment_type_r16.to_string()); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +const char* ul_ded_msg_segment_r16_ies_s::rrc_msg_segment_type_r16_opts::to_string() const +{ + static const char* options[] = {"notLastSegment", "lastSegment"}; + return convert_enum_idx(options, 2, value, "ul_ded_msg_segment_r16_ies_s::rrc_msg_segment_type_r16_e_"); +} + // ULHandoverPreparationTransfer-r8-IEs ::= SEQUENCE SRSASN_CODE ul_ho_prep_transfer_r8_ies_s::pack(bit_ref& bref) const { @@ -8207,7 +10489,216 @@ void ul_ho_prep_transfer_r8_ies_s::to_json(json_writer& j) const j.write_fieldname("nonCriticalExtension"); non_crit_ext.to_json(j); } - j.end_obj(); + j.end_obj(); +} + +// ULInformationTransfer-r16-IEs ::= SEQUENCE +SRSASN_CODE ul_info_transfer_r16_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ded_info_type_r16_present, 1)); + HANDLE_CODE(bref.pack(ded_info_f1c_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (ded_info_type_r16_present) { + HANDLE_CODE(ded_info_type_r16.pack(bref)); + } + if (ded_info_f1c_r16_present) { + HANDLE_CODE(ded_info_f1c_r16.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ul_info_transfer_r16_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ded_info_type_r16_present, 1)); + HANDLE_CODE(bref.unpack(ded_info_f1c_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (ded_info_type_r16_present) { + HANDLE_CODE(ded_info_type_r16.unpack(bref)); + } + if (ded_info_f1c_r16_present) { + HANDLE_CODE(ded_info_f1c_r16.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ul_info_transfer_r16_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ded_info_type_r16_present) { + j.write_fieldname("dedicatedInfoType-r16"); + ded_info_type_r16.to_json(j); + } + if (ded_info_f1c_r16_present) { + j.write_str("dedicatedInfoF1c-r16", ded_info_f1c_r16.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +void ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::destroy_() +{ + switch (type_) { + case types::ded_info_nas_r16: + c.destroy(); + break; + case types::ded_info_cdma2000_minus1_xrtt_r16: + c.destroy(); + break; + case types::ded_info_cdma2000_hrpd_r16: + c.destroy(); + break; + default: + break; + } +} +void ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ded_info_nas_r16: + c.init(); + break; + case types::ded_info_cdma2000_minus1_xrtt_r16: + c.init(); + break; + case types::ded_info_cdma2000_hrpd_r16: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ul_info_transfer_r16_ies_s::ded_info_type_r16_c_"); + } +} +ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::ded_info_type_r16_c_( + const ul_info_transfer_r16_ies_s::ded_info_type_r16_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::ded_info_nas_r16: + c.init(other.c.get()); + break; + case types::ded_info_cdma2000_minus1_xrtt_r16: + c.init(other.c.get()); + break; + case types::ded_info_cdma2000_hrpd_r16: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ul_info_transfer_r16_ies_s::ded_info_type_r16_c_"); + } +} +ul_info_transfer_r16_ies_s::ded_info_type_r16_c_& ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::operator=( + const ul_info_transfer_r16_ies_s::ded_info_type_r16_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ded_info_nas_r16: + c.set(other.c.get()); + break; + case types::ded_info_cdma2000_minus1_xrtt_r16: + c.set(other.c.get()); + break; + case types::ded_info_cdma2000_hrpd_r16: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ul_info_transfer_r16_ies_s::ded_info_type_r16_c_"); + } + + return *this; +} +dyn_octstring& ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::set_ded_info_nas_r16() +{ + set(types::ded_info_nas_r16); + return c.get(); +} +dyn_octstring& ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::set_ded_info_cdma2000_minus1_xrtt_r16() +{ + set(types::ded_info_cdma2000_minus1_xrtt_r16); + return c.get(); +} +dyn_octstring& ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::set_ded_info_cdma2000_hrpd_r16() +{ + set(types::ded_info_cdma2000_hrpd_r16); + return c.get(); +} +void ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ded_info_nas_r16: + j.write_str("dedicatedInfoNAS-r16", c.get().to_string()); + break; + case types::ded_info_cdma2000_minus1_xrtt_r16: + j.write_str("dedicatedInfoCDMA2000-1XRTT-r16", c.get().to_string()); + break; + case types::ded_info_cdma2000_hrpd_r16: + j.write_str("dedicatedInfoCDMA2000-HRPD-r16", c.get().to_string()); + break; + default: + log_invalid_choice_id(type_, "ul_info_transfer_r16_ies_s::ded_info_type_r16_c_"); + } + j.end_obj(); +} +SRSASN_CODE ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ded_info_nas_r16: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ded_info_cdma2000_minus1_xrtt_r16: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ded_info_cdma2000_hrpd_r16: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "ul_info_transfer_r16_ies_s::ded_info_type_r16_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ul_info_transfer_r16_ies_s::ded_info_type_r16_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ded_info_nas_r16: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ded_info_cdma2000_minus1_xrtt_r16: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ded_info_cdma2000_hrpd_r16: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "ul_info_transfer_r16_ies_s::ded_info_type_r16_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; } // ULInformationTransfer-r8-IEs ::= SEQUENCE @@ -8399,6 +10890,54 @@ SRSASN_CODE ul_info_transfer_r8_ies_s::ded_info_type_c_::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +// ULInformationTransferIRAT-r16-IEs ::= SEQUENCE +SRSASN_CODE ul_info_transfer_irat_r16_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ul_dcch_msg_nr_r16_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (ul_dcch_msg_nr_r16_present) { + HANDLE_CODE(ul_dcch_msg_nr_r16.pack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ul_info_transfer_irat_r16_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ul_dcch_msg_nr_r16_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (ul_dcch_msg_nr_r16_present) { + HANDLE_CODE(ul_dcch_msg_nr_r16.unpack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ul_info_transfer_irat_r16_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ul_dcch_msg_nr_r16_present) { + j.write_str("ul-DCCH-MessageNR-r16", ul_dcch_msg_nr_r16.to_string()); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // ULInformationTransferMRDC-r15-IEs ::= SEQUENCE SRSASN_CODE ul_info_transfer_mrdc_r15_ies_s::pack(bit_ref& bref) const { @@ -8691,6 +11230,88 @@ void fail_info_r15_s::to_json(json_writer& j) const j.end_obj(); } +// FailureInformation-r16 ::= SEQUENCE +SRSASN_CODE fail_info_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE fail_info_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void fail_info_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void fail_info_r16_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +fail_info_r16_ies_s& fail_info_r16_s::crit_exts_c_::set_fail_info_r16() +{ + set(types::fail_info_r16); + return c; +} +void fail_info_r16_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void fail_info_r16_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::fail_info_r16: + j.write_fieldname("failureInformation-r16"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "fail_info_r16_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE fail_info_r16_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::fail_info_r16: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "fail_info_r16_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE fail_info_r16_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::fail_info_r16: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "fail_info_r16_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + // InDeviceCoexIndication-r11 ::= SEQUENCE SRSASN_CODE in_dev_coex_ind_r11_s::pack(bit_ref& bref) const { @@ -9344,6 +11965,88 @@ SRSASN_CODE mbms_interest_ind_r11_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } +// MCGFailureInformation-r16 ::= SEQUENCE +SRSASN_CODE mcg_fail_info_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mcg_fail_info_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void mcg_fail_info_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void mcg_fail_info_r16_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +mcg_fail_info_r16_ies_s& mcg_fail_info_r16_s::crit_exts_c_::set_mcg_fail_info() +{ + set(types::mcg_fail_info); + return c; +} +void mcg_fail_info_r16_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void mcg_fail_info_r16_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::mcg_fail_info: + j.write_fieldname("mcgFailureInformation"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "mcg_fail_info_r16_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE mcg_fail_info_r16_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::mcg_fail_info: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "mcg_fail_info_r16_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE mcg_fail_info_r16_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::mcg_fail_info: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "mcg_fail_info_r16_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + // MeasReportAppLayer-r15 ::= SEQUENCE SRSASN_CODE meas_report_app_layer_r15_s::pack(bit_ref& bref) const { @@ -9365,62 +12068,144 @@ void meas_report_app_layer_r15_s::to_json(json_writer& j) const j.end_obj(); } -void meas_report_app_layer_r15_s::crit_exts_c_::set(types::options e) +void meas_report_app_layer_r15_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +meas_report_app_layer_r15_ies_s& meas_report_app_layer_r15_s::crit_exts_c_::set_meas_report_app_layer_r15() +{ + set(types::meas_report_app_layer_r15); + return c; +} +void meas_report_app_layer_r15_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void meas_report_app_layer_r15_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::meas_report_app_layer_r15: + j.write_fieldname("measReportAppLayer-r15"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "meas_report_app_layer_r15_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE meas_report_app_layer_r15_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::meas_report_app_layer_r15: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "meas_report_app_layer_r15_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_report_app_layer_r15_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::meas_report_app_layer_r15: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "meas_report_app_layer_r15_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +// PURConfigurationRequest-r16 ::= SEQUENCE +SRSASN_CODE pur_cfg_request_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE pur_cfg_request_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void pur_cfg_request_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void pur_cfg_request_r16_s::crit_exts_c_::set(types::options e) { type_ = e; } -meas_report_app_layer_r15_ies_s& meas_report_app_layer_r15_s::crit_exts_c_::set_meas_report_app_layer_r15() +pur_cfg_request_r16_ies_s& pur_cfg_request_r16_s::crit_exts_c_::set_pur_cfg_request() { - set(types::meas_report_app_layer_r15); + set(types::pur_cfg_request); return c; } -void meas_report_app_layer_r15_s::crit_exts_c_::set_crit_exts_future() +void pur_cfg_request_r16_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void meas_report_app_layer_r15_s::crit_exts_c_::to_json(json_writer& j) const +void pur_cfg_request_r16_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::meas_report_app_layer_r15: - j.write_fieldname("measReportAppLayer-r15"); + case types::pur_cfg_request: + j.write_fieldname("purConfigurationRequest"); c.to_json(j); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "meas_report_app_layer_r15_s::crit_exts_c_"); + log_invalid_choice_id(type_, "pur_cfg_request_r16_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE meas_report_app_layer_r15_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE pur_cfg_request_r16_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::meas_report_app_layer_r15: + case types::pur_cfg_request: HANDLE_CODE(c.pack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "meas_report_app_layer_r15_s::crit_exts_c_"); + log_invalid_choice_id(type_, "pur_cfg_request_r16_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE meas_report_app_layer_r15_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE pur_cfg_request_r16_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::meas_report_app_layer_r15: + case types::pur_cfg_request: HANDLE_CODE(c.unpack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "meas_report_app_layer_r15_s::crit_exts_c_"); + log_invalid_choice_id(type_, "pur_cfg_request_r16_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; @@ -10794,78 +13579,323 @@ SRSASN_CODE ueassist_info_r11_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const case types::ue_assist_info_r11: HANDLE_CODE(c.pack(bref)); break; - case types::spare3: - break; - case types::spare2: - break; - case types::spare1: + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "ueassist_info_r11_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ueassist_info_r11_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ue_assist_info_r11: + HANDLE_CODE(c.unpack(bref)); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "ueassist_info_r11_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +// UEInformationResponse-r9 ::= SEQUENCE +SRSASN_CODE ue_info_resp_r9_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_info_resp_r9_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ue_info_resp_r9_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void ue_info_resp_r9_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +ue_info_resp_r9_s::crit_exts_c_::c1_c_& ue_info_resp_r9_s::crit_exts_c_::set_c1() +{ + set(types::c1); + return c; +} +void ue_info_resp_r9_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void ue_info_resp_r9_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::c1: + j.write_fieldname("c1"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::c1: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::c1: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +void ue_info_resp_r9_s::crit_exts_c_::c1_c_::set(types::options e) +{ + type_ = e; +} +ue_info_resp_r9_ies_s& ue_info_resp_r9_s::crit_exts_c_::c1_c_::set_ue_info_resp_r9() +{ + set(types::ue_info_resp_r9); + return c; +} +void ue_info_resp_r9_s::crit_exts_c_::c1_c_::set_spare3() +{ + set(types::spare3); +} +void ue_info_resp_r9_s::crit_exts_c_::c1_c_::set_spare2() +{ + set(types::spare2); +} +void ue_info_resp_r9_s::crit_exts_c_::c1_c_::set_spare1() +{ + set(types::spare1); +} +void ue_info_resp_r9_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ue_info_resp_r9: + j.write_fieldname("ueInformationResponse-r9"); + c.to_json(j); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_::c1_c_"); + } + j.end_obj(); +} +SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ue_info_resp_r9: + HANDLE_CODE(c.pack(bref)); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ue_info_resp_r9: + HANDLE_CODE(c.unpack(bref)); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +// ULDedicatedMessageSegment-r16 ::= SEQUENCE +SRSASN_CODE ul_ded_msg_segment_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ul_ded_msg_segment_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ul_ded_msg_segment_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void ul_ded_msg_segment_r16_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +ul_ded_msg_segment_r16_ies_s& ul_ded_msg_segment_r16_s::crit_exts_c_::set_ul_ded_msg_segment_r16() +{ + set(types::ul_ded_msg_segment_r16); + return c; +} +void ul_ded_msg_segment_r16_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void ul_ded_msg_segment_r16_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ul_ded_msg_segment_r16: + j.write_fieldname("ulDedicatedMessageSegment-r16"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "ul_ded_msg_segment_r16_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE ul_ded_msg_segment_r16_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ul_ded_msg_segment_r16: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "ueassist_info_r11_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ul_ded_msg_segment_r16_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE ueassist_info_r11_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE ul_ded_msg_segment_r16_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::ue_assist_info_r11: + case types::ul_ded_msg_segment_r16: HANDLE_CODE(c.unpack(bref)); break; - case types::spare3: - break; - case types::spare2: - break; - case types::spare1: + case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "ueassist_info_r11_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ul_ded_msg_segment_r16_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -// UEInformationResponse-r9 ::= SEQUENCE -SRSASN_CODE ue_info_resp_r9_s::pack(bit_ref& bref) const +// ULHandoverPreparationTransfer ::= SEQUENCE +SRSASN_CODE ul_ho_prep_transfer_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE ue_info_resp_r9_s::unpack(cbit_ref& bref) +SRSASN_CODE ul_ho_prep_transfer_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void ue_info_resp_r9_s::to_json(json_writer& j) const +void ul_ho_prep_transfer_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); j.write_fieldname("criticalExtensions"); crit_exts.to_json(j); j.end_obj(); } -void ue_info_resp_r9_s::crit_exts_c_::set(types::options e) +void ul_ho_prep_transfer_s::crit_exts_c_::set(types::options e) { type_ = e; } -ue_info_resp_r9_s::crit_exts_c_::c1_c_& ue_info_resp_r9_s::crit_exts_c_::set_c1() +ul_ho_prep_transfer_s::crit_exts_c_::c1_c_& ul_ho_prep_transfer_s::crit_exts_c_::set_c1() { set(types::c1); return c; } -void ue_info_resp_r9_s::crit_exts_c_::set_crit_exts_future() +void ul_ho_prep_transfer_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void ue_info_resp_r9_s::crit_exts_c_::to_json(json_writer& j) const +void ul_ho_prep_transfer_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { @@ -10876,11 +13906,11 @@ void ue_info_resp_r9_s::crit_exts_c_::to_json(json_writer& j) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE ul_ho_prep_transfer_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { @@ -10890,12 +13920,12 @@ SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::pack(bit_ref& bref) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE ul_ho_prep_transfer_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -10907,39 +13937,39 @@ SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::unpack(cbit_ref& bref) case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void ue_info_resp_r9_s::crit_exts_c_::c1_c_::set(types::options e) +void ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::set(types::options e) { type_ = e; } -ue_info_resp_r9_ies_s& ue_info_resp_r9_s::crit_exts_c_::c1_c_::set_ue_info_resp_r9() +ul_ho_prep_transfer_r8_ies_s& ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::set_ul_ho_prep_transfer_r8() { - set(types::ue_info_resp_r9); + set(types::ul_ho_prep_transfer_r8); return c; } -void ue_info_resp_r9_s::crit_exts_c_::c1_c_::set_spare3() +void ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::set_spare3() { set(types::spare3); } -void ue_info_resp_r9_s::crit_exts_c_::c1_c_::set_spare2() +void ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::set_spare2() { set(types::spare2); } -void ue_info_resp_r9_s::crit_exts_c_::c1_c_::set_spare1() +void ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::set_spare1() { set(types::spare1); } -void ue_info_resp_r9_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +void ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::ue_info_resp_r9: - j.write_fieldname("ueInformationResponse-r9"); + case types::ul_ho_prep_transfer_r8: + j.write_fieldname("ulHandoverPreparationTransfer-r8"); c.to_json(j); break; case types::spare3: @@ -10949,15 +13979,15 @@ void ue_info_resp_r9_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const case types::spare1: break; default: - log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_::c1_c_"); } j.end_obj(); } -SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +SRSASN_CODE ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::ue_info_resp_r9: + case types::ul_ho_prep_transfer_r8: HANDLE_CODE(c.pack(bref)); break; case types::spare3: @@ -10967,18 +13997,18 @@ SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const case types::spare1: break; default: - log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::ue_info_resp_r9: + case types::ul_ho_prep_transfer_r8: HANDLE_CODE(c.unpack(bref)); break; case types::spare3: @@ -10988,26 +14018,26 @@ SRSASN_CODE ue_info_resp_r9_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) case types::spare1: break; default: - log_invalid_choice_id(type_, "ue_info_resp_r9_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -// ULHandoverPreparationTransfer ::= SEQUENCE -SRSASN_CODE ul_ho_prep_transfer_s::pack(bit_ref& bref) const +// ULInformationTransfer ::= SEQUENCE +SRSASN_CODE ul_info_transfer_s::pack(bit_ref& bref) const { HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE ul_ho_prep_transfer_s::unpack(cbit_ref& bref) +SRSASN_CODE ul_info_transfer_s::unpack(cbit_ref& bref) { HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void ul_ho_prep_transfer_s::to_json(json_writer& j) const +void ul_info_transfer_s::to_json(json_writer& j) const { j.start_obj(); j.write_fieldname("criticalExtensions"); @@ -11015,20 +14045,20 @@ void ul_ho_prep_transfer_s::to_json(json_writer& j) const j.end_obj(); } -void ul_ho_prep_transfer_s::crit_exts_c_::set(types::options e) +void ul_info_transfer_s::crit_exts_c_::set(types::options e) { type_ = e; } -ul_ho_prep_transfer_s::crit_exts_c_::c1_c_& ul_ho_prep_transfer_s::crit_exts_c_::set_c1() +ul_info_transfer_s::crit_exts_c_::c1_c_& ul_info_transfer_s::crit_exts_c_::set_c1() { set(types::c1); return c; } -void ul_ho_prep_transfer_s::crit_exts_c_::set_crit_exts_future() +void ul_info_transfer_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void ul_ho_prep_transfer_s::crit_exts_c_::to_json(json_writer& j) const +void ul_info_transfer_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { @@ -11039,11 +14069,11 @@ void ul_ho_prep_transfer_s::crit_exts_c_::to_json(json_writer& j) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE ul_ho_prep_transfer_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE ul_info_transfer_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { @@ -11053,12 +14083,12 @@ SRSASN_CODE ul_ho_prep_transfer_s::crit_exts_c_::pack(bit_ref& bref) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE ul_ho_prep_transfer_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE ul_info_transfer_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -11070,107 +14100,188 @@ SRSASN_CODE ul_ho_prep_transfer_s::crit_exts_c_::unpack(cbit_ref& bref) case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::set(types::options e) +void ul_info_transfer_s::crit_exts_c_::c1_c_::destroy_() +{ + switch (type_) { + case types::ul_info_transfer_r8: + c.destroy(); + break; + case types::ul_info_transfer_r16: + c.destroy(); + break; + default: + break; + } +} +void ul_info_transfer_s::crit_exts_c_::c1_c_::set(types::options e) { + destroy_(); type_ = e; + switch (type_) { + case types::ul_info_transfer_r8: + c.init(); + break; + case types::ul_info_transfer_r16: + c.init(); + break; + case types::spare2: + break; + case types::spare1: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_::c1_c_"); + } } -ul_ho_prep_transfer_r8_ies_s& ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::set_ul_ho_prep_transfer_r8() +ul_info_transfer_s::crit_exts_c_::c1_c_::c1_c_(const ul_info_transfer_s::crit_exts_c_::c1_c_& other) { - set(types::ul_ho_prep_transfer_r8); - return c; + type_ = other.type(); + switch (type_) { + case types::ul_info_transfer_r8: + c.init(other.c.get()); + break; + case types::ul_info_transfer_r16: + c.init(other.c.get()); + break; + case types::spare2: + break; + case types::spare1: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_::c1_c_"); + } } -void ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::set_spare3() +ul_info_transfer_s::crit_exts_c_::c1_c_& +ul_info_transfer_s::crit_exts_c_::c1_c_::operator=(const ul_info_transfer_s::crit_exts_c_::c1_c_& other) { - set(types::spare3); + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ul_info_transfer_r8: + c.set(other.c.get()); + break; + case types::ul_info_transfer_r16: + c.set(other.c.get()); + break; + case types::spare2: + break; + case types::spare1: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_::c1_c_"); + } + + return *this; } -void ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::set_spare2() +ul_info_transfer_r8_ies_s& ul_info_transfer_s::crit_exts_c_::c1_c_::set_ul_info_transfer_r8() +{ + set(types::ul_info_transfer_r8); + return c.get(); +} +ul_info_transfer_r16_ies_s& ul_info_transfer_s::crit_exts_c_::c1_c_::set_ul_info_transfer_r16() +{ + set(types::ul_info_transfer_r16); + return c.get(); +} +void ul_info_transfer_s::crit_exts_c_::c1_c_::set_spare2() { set(types::spare2); } -void ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::set_spare1() +void ul_info_transfer_s::crit_exts_c_::c1_c_::set_spare1() { set(types::spare1); } -void ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +void ul_info_transfer_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::ul_ho_prep_transfer_r8: - j.write_fieldname("ulHandoverPreparationTransfer-r8"); - c.to_json(j); + case types::ul_info_transfer_r8: + j.write_fieldname("ulInformationTransfer-r8"); + c.get().to_json(j); break; - case types::spare3: + case types::ul_info_transfer_r16: + j.write_fieldname("ulInformationTransfer-r16"); + c.get().to_json(j); break; case types::spare2: break; case types::spare1: break; default: - log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_::c1_c_"); } j.end_obj(); } -SRSASN_CODE ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +SRSASN_CODE ul_info_transfer_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::ul_ho_prep_transfer_r8: - HANDLE_CODE(c.pack(bref)); + case types::ul_info_transfer_r8: + HANDLE_CODE(c.get().pack(bref)); break; - case types::spare3: + case types::ul_info_transfer_r16: + HANDLE_CODE(c.get().pack(bref)); break; case types::spare2: break; case types::spare1: break; default: - log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE ul_ho_prep_transfer_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE ul_info_transfer_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::ul_ho_prep_transfer_r8: - HANDLE_CODE(c.unpack(bref)); + case types::ul_info_transfer_r8: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::spare3: + case types::ul_info_transfer_r16: + HANDLE_CODE(c.get().unpack(bref)); break; case types::spare2: break; case types::spare1: break; default: - log_invalid_choice_id(type_, "ul_ho_prep_transfer_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -// ULInformationTransfer ::= SEQUENCE -SRSASN_CODE ul_info_transfer_s::pack(bit_ref& bref) const +// ULInformationTransferIRAT-r16 ::= SEQUENCE +SRSASN_CODE ul_info_transfer_irat_r16_s::pack(bit_ref& bref) const { HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE ul_info_transfer_s::unpack(cbit_ref& bref) +SRSASN_CODE ul_info_transfer_irat_r16_s::unpack(cbit_ref& bref) { HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void ul_info_transfer_s::to_json(json_writer& j) const +void ul_info_transfer_irat_r16_s::to_json(json_writer& j) const { j.start_obj(); j.write_fieldname("criticalExtensions"); @@ -11178,20 +14289,20 @@ void ul_info_transfer_s::to_json(json_writer& j) const j.end_obj(); } -void ul_info_transfer_s::crit_exts_c_::set(types::options e) +void ul_info_transfer_irat_r16_s::crit_exts_c_::set(types::options e) { type_ = e; } -ul_info_transfer_s::crit_exts_c_::c1_c_& ul_info_transfer_s::crit_exts_c_::set_c1() +ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_& ul_info_transfer_irat_r16_s::crit_exts_c_::set_c1() { set(types::c1); return c; } -void ul_info_transfer_s::crit_exts_c_::set_crit_exts_future() +void ul_info_transfer_irat_r16_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void ul_info_transfer_s::crit_exts_c_::to_json(json_writer& j) const +void ul_info_transfer_irat_r16_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { @@ -11202,11 +14313,11 @@ void ul_info_transfer_s::crit_exts_c_::to_json(json_writer& j) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_irat_r16_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE ul_info_transfer_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE ul_info_transfer_irat_r16_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { @@ -11216,12 +14327,12 @@ SRSASN_CODE ul_info_transfer_s::crit_exts_c_::pack(bit_ref& bref) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_irat_r16_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE ul_info_transfer_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE ul_info_transfer_irat_r16_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -11233,39 +14344,39 @@ SRSASN_CODE ul_info_transfer_s::crit_exts_c_::unpack(cbit_ref& bref) case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_irat_r16_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void ul_info_transfer_s::crit_exts_c_::c1_c_::set(types::options e) +void ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_::set(types::options e) { type_ = e; } -ul_info_transfer_r8_ies_s& ul_info_transfer_s::crit_exts_c_::c1_c_::set_ul_info_transfer_r8() +ul_info_transfer_irat_r16_ies_s& ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_::set_ul_info_transfer_irat_r16() { - set(types::ul_info_transfer_r8); + set(types::ul_info_transfer_irat_r16); return c; } -void ul_info_transfer_s::crit_exts_c_::c1_c_::set_spare3() +void ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_::set_spare3() { set(types::spare3); } -void ul_info_transfer_s::crit_exts_c_::c1_c_::set_spare2() +void ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_::set_spare2() { set(types::spare2); } -void ul_info_transfer_s::crit_exts_c_::c1_c_::set_spare1() +void ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_::set_spare1() { set(types::spare1); } -void ul_info_transfer_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +void ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::ul_info_transfer_r8: - j.write_fieldname("ulInformationTransfer-r8"); + case types::ul_info_transfer_irat_r16: + j.write_fieldname("ulInformationTransferIRAT-r16"); c.to_json(j); break; case types::spare3: @@ -11275,15 +14386,15 @@ void ul_info_transfer_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const case types::spare1: break; default: - log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_"); } j.end_obj(); } -SRSASN_CODE ul_info_transfer_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +SRSASN_CODE ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::ul_info_transfer_r8: + case types::ul_info_transfer_irat_r16: HANDLE_CODE(c.pack(bref)); break; case types::spare3: @@ -11293,18 +14404,18 @@ SRSASN_CODE ul_info_transfer_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const case types::spare1: break; default: - log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE ul_info_transfer_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::ul_info_transfer_r8: + case types::ul_info_transfer_irat_r16: HANDLE_CODE(c.unpack(bref)); break; case types::spare3: @@ -11314,7 +14425,7 @@ SRSASN_CODE ul_info_transfer_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) case types::spare1: break; default: - log_invalid_choice_id(type_, "ul_info_transfer_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ul_info_transfer_irat_r16_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; @@ -12380,6 +15491,21 @@ void ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::destroy_() case types::fail_info_r15: c.destroy(); break; + case types::ul_ded_msg_segment_r16: + c.destroy(); + break; + case types::pur_cfg_request_r16: + c.destroy(); + break; + case types::fail_info_r16: + c.destroy(); + break; + case types::mcg_fail_info_r16: + c.destroy(); + break; + case types::ul_info_transfer_irat_r16: + c.destroy(); + break; default: break; } @@ -12422,15 +15548,20 @@ void ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set(types::options e) case types::fail_info_r15: c.init(); break; - case types::spare5: + case types::ul_ded_msg_segment_r16: + c.init(); break; - case types::spare4: + case types::pur_cfg_request_r16: + c.init(); break; - case types::spare3: + case types::fail_info_r16: + c.init(); break; - case types::spare2: + case types::mcg_fail_info_r16: + c.init(); break; - case types::spare1: + case types::ul_info_transfer_irat_r16: + c.init(); break; case types::nulltype: break; @@ -12475,15 +15606,20 @@ ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::c2_c_(const ul_dcch_msg_type_c::msg case types::fail_info_r15: c.init(other.c.get()); break; - case types::spare5: + case types::ul_ded_msg_segment_r16: + c.init(other.c.get()); break; - case types::spare4: + case types::pur_cfg_request_r16: + c.init(other.c.get()); break; - case types::spare3: + case types::fail_info_r16: + c.init(other.c.get()); break; - case types::spare2: + case types::mcg_fail_info_r16: + c.init(other.c.get()); break; - case types::spare1: + case types::ul_info_transfer_irat_r16: + c.init(other.c.get()); break; case types::nulltype: break; @@ -12532,15 +15668,20 @@ ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::operator=(const ul_dcch_msg_type_c: case types::fail_info_r15: c.set(other.c.get()); break; - case types::spare5: + case types::ul_ded_msg_segment_r16: + c.set(other.c.get()); break; - case types::spare4: + case types::pur_cfg_request_r16: + c.set(other.c.get()); break; - case types::spare3: + case types::fail_info_r16: + c.set(other.c.get()); break; - case types::spare2: + case types::mcg_fail_info_r16: + c.set(other.c.get()); break; - case types::spare1: + case types::ul_info_transfer_irat_r16: + c.set(other.c.get()); break; case types::nulltype: break; @@ -12605,25 +15746,30 @@ fail_info_r15_s& ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set_fail_info_r15( set(types::fail_info_r15); return c.get(); } -void ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set_spare5() +ul_ded_msg_segment_r16_s& ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set_ul_ded_msg_segment_r16() { - set(types::spare5); + set(types::ul_ded_msg_segment_r16); + return c.get(); } -void ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set_spare4() +pur_cfg_request_r16_s& ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set_pur_cfg_request_r16() { - set(types::spare4); + set(types::pur_cfg_request_r16); + return c.get(); } -void ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set_spare3() +fail_info_r16_s& ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set_fail_info_r16() { - set(types::spare3); + set(types::fail_info_r16); + return c.get(); } -void ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set_spare2() +mcg_fail_info_r16_s& ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set_mcg_fail_info_r16() { - set(types::spare2); + set(types::mcg_fail_info_r16); + return c.get(); } -void ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set_spare1() +ul_info_transfer_irat_r16_s& ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::set_ul_info_transfer_irat_r16() { - set(types::spare1); + set(types::ul_info_transfer_irat_r16); + return c.get(); } void ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::to_json(json_writer& j) const { @@ -12673,15 +15819,25 @@ void ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::to_json(json_writer& j) const j.write_fieldname("failureInformation-r15"); c.get().to_json(j); break; - case types::spare5: + case types::ul_ded_msg_segment_r16: + j.write_fieldname("ulDedicatedMessageSegment-r16"); + c.get().to_json(j); break; - case types::spare4: + case types::pur_cfg_request_r16: + j.write_fieldname("purConfigurationRequest-r16"); + c.get().to_json(j); break; - case types::spare3: + case types::fail_info_r16: + j.write_fieldname("failureInformation-r16"); + c.get().to_json(j); break; - case types::spare2: + case types::mcg_fail_info_r16: + j.write_fieldname("mcgFailureInformation-r16"); + c.get().to_json(j); break; - case types::spare1: + case types::ul_info_transfer_irat_r16: + j.write_fieldname("ulInformationTransferIRAT-r16"); + c.get().to_json(j); break; default: log_invalid_choice_id(type_, "ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_"); @@ -12725,15 +15881,20 @@ SRSASN_CODE ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::pack(bit_ref& bref) con case types::fail_info_r15: HANDLE_CODE(c.get().pack(bref)); break; - case types::spare5: + case types::ul_ded_msg_segment_r16: + HANDLE_CODE(c.get().pack(bref)); break; - case types::spare4: + case types::pur_cfg_request_r16: + HANDLE_CODE(c.get().pack(bref)); break; - case types::spare3: + case types::fail_info_r16: + HANDLE_CODE(c.get().pack(bref)); break; - case types::spare2: + case types::mcg_fail_info_r16: + HANDLE_CODE(c.get().pack(bref)); break; - case types::spare1: + case types::ul_info_transfer_irat_r16: + HANDLE_CODE(c.get().pack(bref)); break; default: log_invalid_choice_id(type_, "ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_"); @@ -12780,15 +15941,20 @@ SRSASN_CODE ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_::unpack(cbit_ref& bref) case types::fail_info_r15: HANDLE_CODE(c.get().unpack(bref)); break; - case types::spare5: + case types::ul_ded_msg_segment_r16: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::spare4: + case types::pur_cfg_request_r16: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::spare3: + case types::fail_info_r16: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::spare2: + case types::mcg_fail_info_r16: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::spare1: + case types::ul_info_transfer_irat_r16: + HANDLE_CODE(c.get().unpack(bref)); break; default: log_invalid_choice_id(type_, "ul_dcch_msg_type_c::msg_class_ext_c_::c2_c_"); diff --git a/lib/src/asn1/rrc_nbiot.cc b/lib/src/asn1/rrc_nbiot.cc index cf36bbfe0a..a25238124d 100644 --- a/lib/src/asn1/rrc_nbiot.cc +++ b/lib/src/asn1/rrc_nbiot.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -99,32 +99,72 @@ void ab_cfg_plmn_nb_r13_s::to_json(json_writer& j) const j.end_obj(); } -// T-PollRetransmit-NB-r13 ::= ENUMERATED -const char* t_poll_retx_nb_r13_opts::to_string() const +// ANR-Carrier-NB-r16 ::= SEQUENCE +SRSASN_CODE anr_carrier_nb_r16_s::pack(bit_ref& bref) const { - static const char* options[] = {"ms250", - "ms500", - "ms1000", - "ms2000", - "ms3000", - "ms4000", - "ms6000", - "ms10000", - "ms15000", - "ms25000", - "ms40000", - "ms60000", - "ms90000", - "ms120000", - "ms180000", - "ms300000-v1530"}; - return convert_enum_idx(options, 16, value, "t_poll_retx_nb_r13_e"); + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(excluded_cell_list_r16_present, 1)); + + HANDLE_CODE(pack_integer(bref, carrier_freq_idx_r16, (uint8_t)1u, (uint8_t)8u)); + if (excluded_cell_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, excluded_cell_list_r16, 1, 16, integer_packer(0, 503))); + } + + return SRSASN_SUCCESS; } -uint32_t t_poll_retx_nb_r13_opts::to_number() const +SRSASN_CODE anr_carrier_nb_r16_s::unpack(cbit_ref& bref) { - static const uint32_t options[] = { - 250, 500, 1000, 2000, 3000, 4000, 6000, 10000, 15000, 25000, 40000, 60000, 90000, 120000, 180000, 300000}; - return map_enum_number(options, 16, value, "t_poll_retx_nb_r13_e"); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(excluded_cell_list_r16_present, 1)); + + HANDLE_CODE(unpack_integer(carrier_freq_idx_r16, bref, (uint8_t)1u, (uint8_t)8u)); + if (excluded_cell_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(excluded_cell_list_r16, bref, 1, 16, integer_packer(0, 503))); + } + + return SRSASN_SUCCESS; +} +void anr_carrier_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("carrierFreqIndex-r16", carrier_freq_idx_r16); + if (excluded_cell_list_r16_present) { + j.start_array("excludedCellList-r16"); + for (const auto& e1 : excluded_cell_list_r16) { + j.write_int(e1); + } + j.end_array(); + } + j.end_obj(); +} + +// ANR-MeasConfig-NB-r16 ::= SEQUENCE +SRSASN_CODE anr_meas_cfg_nb_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(pack_integer(bref, anr_quality_thres_r16, (uint8_t)0u, (uint8_t)113u)); + HANDLE_CODE(pack_dyn_seq_of(bref, anr_carrier_list_r16, 1, 2)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE anr_meas_cfg_nb_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(unpack_integer(anr_quality_thres_r16, bref, (uint8_t)0u, (uint8_t)113u)); + HANDLE_CODE(unpack_dyn_seq_of(anr_carrier_list_r16, bref, 1, 2)); + + return SRSASN_SUCCESS; +} +void anr_meas_cfg_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("anr-QualityThreshold-r16", anr_quality_thres_r16); + j.start_array("anr-CarrierList-r16"); + for (const auto& e1 : anr_carrier_list_r16) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); } // CarrierFreq-NB-r13 ::= SEQUENCE @@ -179,6 +219,186 @@ const char* carrier_freq_nb_r13_s::carrier_freq_offset_r13_opts::to_number_strin return convert_enum_idx(options, 21, value, "carrier_freq_nb_r13_s::carrier_freq_offset_r13_e_"); } +// MeasResultServCell-NB-r14 ::= SEQUENCE +SRSASN_CODE meas_result_serv_cell_nb_r14_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, nrsrp_result_r14, (uint8_t)0u, (uint8_t)113u)); + HANDLE_CODE(pack_integer(bref, nrsrq_result_r14, (int8_t)-30, (int8_t)46)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE meas_result_serv_cell_nb_r14_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(nrsrp_result_r14, bref, (uint8_t)0u, (uint8_t)113u)); + HANDLE_CODE(unpack_integer(nrsrq_result_r14, bref, (int8_t)-30, (int8_t)46)); + + return SRSASN_SUCCESS; +} +void meas_result_serv_cell_nb_r14_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("nrsrpResult-r14", nrsrp_result_r14); + j.write_int("nrsrqResult-r14", nrsrq_result_r14); + j.end_obj(); +} + +// ANR-MeasResult-NB-r16 ::= SEQUENCE +SRSASN_CODE anr_meas_result_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pci_r16_present, 1)); + HANDLE_CODE(bref.pack(meas_result_r16_present, 1)); + HANDLE_CODE(bref.pack(cgi_info_r16_present, 1)); + + HANDLE_CODE(carrier_freq_r16.pack(bref)); + if (pci_r16_present) { + HANDLE_CODE(pack_integer(bref, pci_r16, (uint16_t)0u, (uint16_t)503u)); + } + HANDLE_CODE(meas_result_last_serv_cell_r16.pack(bref)); + if (meas_result_r16_present) { + HANDLE_CODE(pack_integer(bref, meas_result_r16, (uint8_t)0u, (uint8_t)113u)); + } + if (cgi_info_r16_present) { + HANDLE_CODE(bref.pack(cgi_info_r16.plmn_id_list_r16_present, 1)); + HANDLE_CODE(cgi_info_r16.cell_global_id_r16.pack(bref)); + HANDLE_CODE(cgi_info_r16.tac_r16.pack(bref)); + if (cgi_info_r16.plmn_id_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, cgi_info_r16.plmn_id_list_r16, 1, 5)); + } + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE anr_meas_result_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(pci_r16_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_r16_present, 1)); + HANDLE_CODE(bref.unpack(cgi_info_r16_present, 1)); + + HANDLE_CODE(carrier_freq_r16.unpack(bref)); + if (pci_r16_present) { + HANDLE_CODE(unpack_integer(pci_r16, bref, (uint16_t)0u, (uint16_t)503u)); + } + HANDLE_CODE(meas_result_last_serv_cell_r16.unpack(bref)); + if (meas_result_r16_present) { + HANDLE_CODE(unpack_integer(meas_result_r16, bref, (uint8_t)0u, (uint8_t)113u)); + } + if (cgi_info_r16_present) { + HANDLE_CODE(bref.unpack(cgi_info_r16.plmn_id_list_r16_present, 1)); + HANDLE_CODE(cgi_info_r16.cell_global_id_r16.unpack(bref)); + HANDLE_CODE(cgi_info_r16.tac_r16.unpack(bref)); + if (cgi_info_r16.plmn_id_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(cgi_info_r16.plmn_id_list_r16, bref, 1, 5)); + } + } + + return SRSASN_SUCCESS; +} +void anr_meas_result_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("carrierFreq-r16"); + carrier_freq_r16.to_json(j); + if (pci_r16_present) { + j.write_int("physCellId-r16", pci_r16); + } + j.write_fieldname("measResultLastServCell-r16"); + meas_result_last_serv_cell_r16.to_json(j); + if (meas_result_r16_present) { + j.write_int("measResult-r16", meas_result_r16); + } + if (cgi_info_r16_present) { + j.write_fieldname("cgi-Info-r16"); + j.start_obj(); + j.write_fieldname("cellGlobalId-r16"); + cgi_info_r16.cell_global_id_r16.to_json(j); + j.write_str("trackingAreaCode-r16", cgi_info_r16.tac_r16.to_string()); + if (cgi_info_r16.plmn_id_list_r16_present) { + j.start_array("plmn-IdentityList-r16"); + for (const auto& e1 : cgi_info_r16.plmn_id_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); + } + j.end_obj(); +} + +// ANR-MeasReport-NB-r16 ::= SEQUENCE +SRSASN_CODE anr_meas_report_nb_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(serv_cell_id_r16_present, 1)); + + if (serv_cell_id_r16_present) { + HANDLE_CODE(serv_cell_id_r16.pack(bref)); + } + HANDLE_CODE(meas_result_serv_cell_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, relative_time_stamp_r16, (uint8_t)0u, (uint8_t)95u)); + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_list_r16, 1, 2)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE anr_meas_report_nb_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(serv_cell_id_r16_present, 1)); + + if (serv_cell_id_r16_present) { + HANDLE_CODE(serv_cell_id_r16.unpack(bref)); + } + HANDLE_CODE(meas_result_serv_cell_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(relative_time_stamp_r16, bref, (uint8_t)0u, (uint8_t)95u)); + HANDLE_CODE(unpack_dyn_seq_of(meas_result_list_r16, bref, 1, 2)); + + return SRSASN_SUCCESS; +} +void anr_meas_report_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (serv_cell_id_r16_present) { + j.write_fieldname("servCellIdentity-r16"); + serv_cell_id_r16.to_json(j); + } + j.write_fieldname("measResultServCell-r16"); + meas_result_serv_cell_r16.to_json(j); + j.write_int("relativeTimeStamp-r16", relative_time_stamp_r16); + j.start_array("measResultList-r16"); + for (const auto& e1 : meas_result_list_r16) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// T-PollRetransmit-NB-r13 ::= ENUMERATED +const char* t_poll_retx_nb_r13_opts::to_string() const +{ + static const char* options[] = {"ms250", + "ms500", + "ms1000", + "ms2000", + "ms3000", + "ms4000", + "ms6000", + "ms10000", + "ms15000", + "ms25000", + "ms40000", + "ms60000", + "ms90000", + "ms120000", + "ms180000", + "ms300000-v1530"}; + return convert_enum_idx(options, 16, value, "t_poll_retx_nb_r13_e"); +} +uint32_t t_poll_retx_nb_r13_opts::to_number() const +{ + static const uint32_t options[] = { + 250, 500, 1000, 2000, 3000, 4000, 6000, 10000, 15000, 25000, 40000, 60000, 90000, 120000, 180000, 300000}; + return map_enum_number(options, 16, value, "t_poll_retx_nb_r13_e"); +} + // CarrierFreq-NB-v1550 ::= SEQUENCE SRSASN_CODE carrier_freq_nb_v1550_s::pack(bit_ref& bref) const { @@ -1080,6 +1300,112 @@ void lc_ch_cfg_nb_r13_s::to_json(json_writer& j) const j.end_obj(); } +// NPDSCH-16QAM-Config-NB-r17 ::= SEQUENCE +SRSASN_CODE npdsch_minus16_qam_cfg_nb_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(nrs_pwr_ratio_r17_present, 1)); + HANDLE_CODE(bref.pack(nrs_pwr_ratio_with_crs_r17_present, 1)); + + if (nrs_pwr_ratio_r17_present) { + HANDLE_CODE(nrs_pwr_ratio_r17.pack(bref)); + } + if (nrs_pwr_ratio_with_crs_r17_present) { + HANDLE_CODE(nrs_pwr_ratio_with_crs_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE npdsch_minus16_qam_cfg_nb_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(nrs_pwr_ratio_r17_present, 1)); + HANDLE_CODE(bref.unpack(nrs_pwr_ratio_with_crs_r17_present, 1)); + + if (nrs_pwr_ratio_r17_present) { + HANDLE_CODE(nrs_pwr_ratio_r17.unpack(bref)); + } + if (nrs_pwr_ratio_with_crs_r17_present) { + HANDLE_CODE(nrs_pwr_ratio_with_crs_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void npdsch_minus16_qam_cfg_nb_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (nrs_pwr_ratio_r17_present) { + j.write_str("nrs-PowerRatio-r17", nrs_pwr_ratio_r17.to_string()); + } + if (nrs_pwr_ratio_with_crs_r17_present) { + j.write_str("nrs-PowerRatioWithCRS-r17", nrs_pwr_ratio_with_crs_r17.to_string()); + } + j.end_obj(); +} + +const char* npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_r17_opts::to_string() const +{ + static const char* options[] = {"dB-6", "dB-4dot77", "dB-3", "dB-1dot77", "dB0", "dB1", "dB2", "dB3"}; + return convert_enum_idx(options, 8, value, "npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_r17_e_"); +} +float npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_r17_opts::to_number() const +{ + static const float options[] = {-6.0, -4.77, -3.0, -1.77, 0.0, 1.0, 2.0, 3.0}; + return map_enum_number(options, 8, value, "npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_r17_e_"); +} +const char* npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_r17_opts::to_number_string() const +{ + static const char* options[] = {"-6", "-4.77", "-3", "-1.77", "0", "1", "2", "3"}; + return convert_enum_idx(options, 8, value, "npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_r17_e_"); +} + +const char* npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_with_crs_r17_opts::to_string() const +{ + static const char* options[] = {"dB-6", "dB-4dot77", "dB-3", "dB-1dot77", "dB0", "dB1", "dB2", "dB3"}; + return convert_enum_idx(options, 8, value, "npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_with_crs_r17_e_"); +} +float npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_with_crs_r17_opts::to_number() const +{ + static const float options[] = {-6.0, -4.77, -3.0, -1.77, 0.0, 1.0, 2.0, 3.0}; + return map_enum_number(options, 8, value, "npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_with_crs_r17_e_"); +} +const char* npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_with_crs_r17_opts::to_number_string() const +{ + static const char* options[] = {"-6", "-4.77", "-3", "-1.77", "0", "1", "2", "3"}; + return convert_enum_idx(options, 8, value, "npdsch_minus16_qam_cfg_nb_r17_s::nrs_pwr_ratio_with_crs_r17_e_"); +} + +// NPDSCH-MultiTB-Config-NB-r16 ::= SEQUENCE +SRSASN_CODE npdsch_multi_tb_cfg_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(harq_ack_bundling_r16_present, 1)); + + HANDLE_CODE(multi_tb_cfg_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE npdsch_multi_tb_cfg_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(harq_ack_bundling_r16_present, 1)); + + HANDLE_CODE(multi_tb_cfg_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void npdsch_multi_tb_cfg_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("multiTB-Config-r16", multi_tb_cfg_r16.to_string()); + if (harq_ack_bundling_r16_present) { + j.write_str("harq-AckBundling-r16", "true"); + } + j.end_obj(); +} + +const char* npdsch_multi_tb_cfg_nb_r16_s::multi_tb_cfg_r16_opts::to_string() const +{ + static const char* options[] = {"interleaved", "nonInterleaved"}; + return convert_enum_idx(options, 2, value, "npdsch_multi_tb_cfg_nb_r16_s::multi_tb_cfg_r16_e_"); +} + // PDCP-Config-NB-r13 ::= SEQUENCE SRSASN_CODE pdcp_cfg_nb_r13_s::pack(bit_ref& bref) const { @@ -1091,6 +1417,17 @@ SRSASN_CODE pdcp_cfg_nb_r13_s::pack(bit_ref& bref) const } HANDLE_CODE(hdr_compress_r13.pack(bref)); + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= ciphering_disabled_r16_present; + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ciphering_disabled_r16_present, 1)); + } + } return SRSASN_SUCCESS; } SRSASN_CODE pdcp_cfg_nb_r13_s::unpack(cbit_ref& bref) @@ -1103,6 +1440,16 @@ SRSASN_CODE pdcp_cfg_nb_r13_s::unpack(cbit_ref& bref) } HANDLE_CODE(hdr_compress_r13.unpack(bref)); + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(ciphering_disabled_r16_present, 1)); + } + } return SRSASN_SUCCESS; } void pdcp_cfg_nb_r13_s::to_json(json_writer& j) const @@ -1113,6 +1460,11 @@ void pdcp_cfg_nb_r13_s::to_json(json_writer& j) const } j.write_fieldname("headerCompression-r13"); hdr_compress_r13.to_json(j); + if (ext) { + if (ciphering_disabled_r16_present) { + j.write_str("cipheringDisabled-r16", "true"); + } + } j.end_obj(); } @@ -1356,6 +1708,27 @@ void rlc_cfg_nb_v1430_s::to_json(json_writer& j) const j.end_obj(); } +// RLC-Config-NB-v1700 ::= SEQUENCE +SRSASN_CODE rlc_cfg_nb_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(t_reordering_ext_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rlc_cfg_nb_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(t_reordering_ext_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void rlc_cfg_nb_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("t-ReorderingExt-r17"); + t_reordering_ext_r17.to_json(j); + j.end_obj(); +} + // SR-NPRACH-Resource-NB-r15 ::= SEQUENCE SRSASN_CODE sr_nprach_res_nb_r15_s::pack(bit_ref& bref) const { @@ -1521,10 +1894,22 @@ const char* sr_nprach_res_nb_r15_s::alpha_r15_opts::to_number_string() const return convert_enum_idx(options, 8, value, "sr_nprach_res_nb_r15_s::alpha_r15_e_"); } -// UL-CarrierConfigDedicated-NB-r13 ::= SEQUENCE -SRSASN_CODE ul_carrier_cfg_ded_nb_r13_s::pack(bit_ref& bref) const +// SR-ProhibitTimerOffset-NB-r17 ::= ENUMERATED +const char* sr_prohibit_timer_offset_nb_r17_opts::to_string() const { - bref.pack(ext, 1); + static const char* options[] = {"ms90", "ms180", "ms270", "ms360", "ms450", "ms540", "ms1080", "spare"}; + return convert_enum_idx(options, 8, value, "sr_prohibit_timer_offset_nb_r17_e"); +} +uint16_t sr_prohibit_timer_offset_nb_r17_opts::to_number() const +{ + static const uint16_t options[] = {90, 180, 270, 360, 450, 540, 1080}; + return map_enum_number(options, 7, value, "sr_prohibit_timer_offset_nb_r17_e"); +} + +// UL-CarrierConfigDedicated-NB-r13 ::= SEQUENCE +SRSASN_CODE ul_carrier_cfg_ded_nb_r13_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); HANDLE_CODE(bref.pack(ul_carrier_freq_r13_present, 1)); if (ul_carrier_freq_r13_present) { @@ -1641,6 +2026,8 @@ SRSASN_CODE drb_to_add_mod_nb_r13_s::pack(bit_ref& bref) const if (ext) { ext_groups_packer_guard group_flags; group_flags[0] |= rlc_cfg_v1430.is_present(); + group_flags[1] |= pdu_session_r16_present; + group_flags[2] |= rlc_cfg_v1700.is_present(); group_flags.pack(bref); if (group_flags[0]) { @@ -1651,6 +2038,22 @@ SRSASN_CODE drb_to_add_mod_nb_r13_s::pack(bit_ref& bref) const HANDLE_CODE(rlc_cfg_v1430->pack(bref)); } } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(pdu_session_r16_present, 1)); + if (pdu_session_r16_present) { + HANDLE_CODE(pack_integer(bref, pdu_session_r16, (uint16_t)0u, (uint16_t)255u)); + } + } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(rlc_cfg_v1700.is_present(), 1)); + if (rlc_cfg_v1700.is_present()) { + HANDLE_CODE(rlc_cfg_v1700->pack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -1681,7 +2084,7 @@ SRSASN_CODE drb_to_add_mod_nb_r13_s::unpack(cbit_ref& bref) } if (ext) { - ext_groups_unpacker_guard group_flags(1); + ext_groups_unpacker_guard group_flags(3); group_flags.unpack(bref); if (group_flags[0]) { @@ -1694,6 +2097,24 @@ SRSASN_CODE drb_to_add_mod_nb_r13_s::unpack(cbit_ref& bref) HANDLE_CODE(rlc_cfg_v1430->unpack(bref)); } } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(pdu_session_r16_present, 1)); + if (pdu_session_r16_present) { + HANDLE_CODE(unpack_integer(pdu_session_r16, bref, (uint16_t)0u, (uint16_t)255u)); + } + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool rlc_cfg_v1700_present; + HANDLE_CODE(bref.unpack(rlc_cfg_v1700_present, 1)); + rlc_cfg_v1700.set_present(rlc_cfg_v1700_present); + if (rlc_cfg_v1700.is_present()) { + HANDLE_CODE(rlc_cfg_v1700->unpack(bref)); + } + } } return SRSASN_SUCCESS; } @@ -1724,6 +2145,13 @@ void drb_to_add_mod_nb_r13_s::to_json(json_writer& j) const j.write_fieldname("rlc-Config-v1430"); rlc_cfg_v1430->to_json(j); } + if (pdu_session_r16_present) { + j.write_int("pdu-Session-r16", pdu_session_r16); + } + if (rlc_cfg_v1700.is_present()) { + j.write_fieldname("rlc-Config-v1700"); + rlc_cfg_v1700->to_json(j); + } } j.end_obj(); } @@ -2023,6 +2451,58 @@ uint8_t npdcch_cfg_ded_nb_v1530_s::npdcch_start_sf_uss_v1530_opts::to_number() c return map_enum_number(options, 2, value, "npdcch_cfg_ded_nb_v1530_s::npdcch_start_sf_uss_v1530_e_"); } +// NPDSCH-ConfigDedicated-NB-r16 ::= SEQUENCE +SRSASN_CODE npdsch_cfg_ded_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(npdsch_multi_tb_cfg_r16_present, 1)); + + if (npdsch_multi_tb_cfg_r16_present) { + HANDLE_CODE(npdsch_multi_tb_cfg_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE npdsch_cfg_ded_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(npdsch_multi_tb_cfg_r16_present, 1)); + + if (npdsch_multi_tb_cfg_r16_present) { + HANDLE_CODE(npdsch_multi_tb_cfg_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void npdsch_cfg_ded_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (npdsch_multi_tb_cfg_r16_present) { + j.write_fieldname("npdsch-MultiTB-Config-r16"); + npdsch_multi_tb_cfg_r16.to_json(j); + } + j.end_obj(); +} + +// NPDSCH-ConfigDedicated-NB-v1710 ::= SEQUENCE +SRSASN_CODE npdsch_cfg_ded_nb_v1710_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(npdsch_minus16_qam_cfg_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE npdsch_cfg_ded_nb_v1710_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(npdsch_minus16_qam_cfg_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void npdsch_cfg_ded_nb_v1710_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("npdsch-16QAM-Config-r17"); + npdsch_minus16_qam_cfg_r17.to_json(j); + j.end_obj(); +} + // NPUSCH-ConfigDedicated-NB-r13 ::= SEQUENCE SRSASN_CODE npusch_cfg_ded_nb_r13_s::pack(bit_ref& bref) const { @@ -2069,6 +2549,118 @@ void npusch_cfg_ded_nb_r13_s::to_json(json_writer& j) const j.end_obj(); } +// NPUSCH-ConfigDedicated-NB-v1610 ::= SEQUENCE +SRSASN_CODE npusch_cfg_ded_nb_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(npusch_multi_tb_cfg_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE npusch_cfg_ded_nb_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(npusch_multi_tb_cfg_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void npusch_cfg_ded_nb_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("npusch-MultiTB-Config-r16", npusch_multi_tb_cfg_r16.to_string()); + j.end_obj(); +} + +const char* npusch_cfg_ded_nb_v1610_s::npusch_multi_tb_cfg_r16_opts::to_string() const +{ + static const char* options[] = {"interleaved", "nonInterleaved"}; + return convert_enum_idx(options, 2, value, "npusch_cfg_ded_nb_v1610_s::npusch_multi_tb_cfg_r16_e_"); +} + +// NPUSCH-ConfigDedicated-NB-v1700 ::= SEQUENCE +SRSASN_CODE npusch_cfg_ded_nb_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(npusch_minus16_qam_cfg_r17_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE npusch_cfg_ded_nb_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(npusch_minus16_qam_cfg_r17_present, 1)); + + return SRSASN_SUCCESS; +} +void npusch_cfg_ded_nb_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (npusch_minus16_qam_cfg_r17_present) { + j.write_str("npusch-16QAM-Config-r17", "true"); + } + j.end_obj(); +} + +// NPUSCH-TxDuration-NB-r17 ::= SEQUENCE +SRSASN_CODE npusch_tx_dur_nb_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(npusch_tx_dur_r17.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE npusch_tx_dur_nb_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(npusch_tx_dur_r17.unpack(bref)); + + return SRSASN_SUCCESS; +} +void npusch_tx_dur_nb_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("npusch-TxDuration-r17", npusch_tx_dur_r17.to_string()); + j.end_obj(); +} + +const char* npusch_tx_dur_nb_r17_s::npusch_tx_dur_r17_opts::to_string() const +{ + static const char* options[] = {"ms2", "ms4", "ms8", "ms16", "ms32", "ms64", "ms128", "ms256"}; + return convert_enum_idx(options, 8, value, "npusch_tx_dur_nb_r17_s::npusch_tx_dur_r17_e_"); +} +uint16_t npusch_tx_dur_nb_r17_s::npusch_tx_dur_r17_opts::to_number() const +{ + static const uint16_t options[] = {2, 4, 8, 16, 32, 64, 128, 256}; + return map_enum_number(options, 8, value, "npusch_tx_dur_nb_r17_s::npusch_tx_dur_r17_e_"); +} + +// OffsetThresholdTA-NB-r17 ::= ENUMERATED +const char* offset_thres_ta_nb_r17_opts::to_string() const +{ + static const char* options[] = {"ms0dot5", + "ms1", + "ms2", + "ms3", + "ms4", + "ms5", + "ms6", + "ms7", + "ms8", + "ms9", + "ms10", + "ms11", + "ms12", + "ms13", + "ms14", + "ms15"}; + return convert_enum_idx(options, 16, value, "offset_thres_ta_nb_r17_e"); +} +float offset_thres_ta_nb_r17_opts::to_number() const +{ + static const float options[] = {0.5, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0}; + return map_enum_number(options, 16, value, "offset_thres_ta_nb_r17_e"); +} +const char* offset_thres_ta_nb_r17_opts::to_number_string() const +{ + static const char* options[] = { + "0.5", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"}; + return convert_enum_idx(options, 16, value, "offset_thres_ta_nb_r17_e"); +} + // PeriodicBSR-Timer-NB-r13 ::= ENUMERATED const char* periodic_bsr_timer_nb_r13_opts::to_string() const { @@ -2081,653 +2673,689 @@ int16_t periodic_bsr_timer_nb_r13_opts::to_number() const return map_enum_number(options, 7, value, "periodic_bsr_timer_nb_r13_e"); } -// RetxBSR-Timer-NB-r13 ::= ENUMERATED -const char* retx_bsr_timer_nb_r13_opts::to_string() const +// ResourceReservationConfig-NB-r16 ::= SEQUENCE +SRSASN_CODE res_reserv_cfg_nb_r16_s::pack(bit_ref& bref) const { - static const char* options[] = {"pp4", "pp16", "pp64", "pp128", "pp256", "pp512", "infinity", "spare"}; - return convert_enum_idx(options, 8, value, "retx_bsr_timer_nb_r13_e"); + bref.pack(ext, 1); + HANDLE_CODE(periodicity_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, start_position_r16, (uint8_t)0u, (uint8_t)15u)); + HANDLE_CODE(res_reserv_r16.pack(bref)); + + return SRSASN_SUCCESS; } -int16_t retx_bsr_timer_nb_r13_opts::to_number() const +SRSASN_CODE res_reserv_cfg_nb_r16_s::unpack(cbit_ref& bref) { - static const int16_t options[] = {4, 16, 64, 128, 256, 512, -1}; - return map_enum_number(options, 7, value, "retx_bsr_timer_nb_r13_e"); -} + bref.unpack(ext, 1); + HANDLE_CODE(periodicity_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(start_position_r16, bref, (uint8_t)0u, (uint8_t)15u)); + HANDLE_CODE(res_reserv_r16.unpack(bref)); -// SR-SPS-BSR-Config-NB-r15 ::= CHOICE -void sr_sps_bsr_cfg_nb_r15_c::set(types::options e) + return SRSASN_SUCCESS; +} +void res_reserv_cfg_nb_r16_s::to_json(json_writer& j) const { - type_ = e; + j.start_obj(); + j.write_str("periodicity-r16", periodicity_r16.to_string()); + j.write_int("startPosition-r16", start_position_r16); + j.write_fieldname("resourceReservation-r16"); + res_reserv_r16.to_json(j); + j.end_obj(); } -void sr_sps_bsr_cfg_nb_r15_c::set_release() + +const char* res_reserv_cfg_nb_r16_s::periodicity_r16_opts::to_string() const { - set(types::release); + static const char* options[] = {"ms10", "ms20", "ms40", "ms80", "ms160", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 8, value, "res_reserv_cfg_nb_r16_s::periodicity_r16_e_"); } -sr_sps_bsr_cfg_nb_r15_c::setup_s_& sr_sps_bsr_cfg_nb_r15_c::set_setup() +uint8_t res_reserv_cfg_nb_r16_s::periodicity_r16_opts::to_number() const { - set(types::setup); - return c; + static const uint8_t options[] = {10, 20, 40, 80, 160}; + return map_enum_number(options, 5, value, "res_reserv_cfg_nb_r16_s::periodicity_r16_e_"); } -void sr_sps_bsr_cfg_nb_r15_c::to_json(json_writer& j) const + +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::destroy_() { - j.start_obj(); switch (type_) { - case types::release: + case types::sf_bitmap_r16: + c.destroy(); break; - case types::setup: - j.write_fieldname("setup"); - j.start_obj(); - j.write_str("semiPersistSchedC-RNTI-r15", c.semi_persist_sched_c_rnti_r15.to_string()); - j.write_str("semiPersistSchedIntervalUL-r15", c.semi_persist_sched_interv_ul_r15.to_string()); - j.end_obj(); + case types::slot_cfg_r16: + c.destroy(); break; default: - log_invalid_choice_id(type_, "sr_sps_bsr_cfg_nb_r15_c"); + break; } - j.end_obj(); } -SRSASN_CODE sr_sps_bsr_cfg_nb_r15_c::pack(bit_ref& bref) const +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::set(types::options e) { - type_.pack(bref); + destroy_(); + type_ = e; switch (type_) { - case types::release: + case types::sf_bitmap_r16: + c.init(); break; - case types::setup: - HANDLE_CODE(c.semi_persist_sched_c_rnti_r15.pack(bref)); - HANDLE_CODE(c.semi_persist_sched_interv_ul_r15.pack(bref)); + case types::slot_cfg_r16: + c.init(); + break; + case types::nulltype: break; default: - log_invalid_choice_id(type_, "sr_sps_bsr_cfg_nb_r15_c"); - return SRSASN_ERROR_ENCODE_FAIL; + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_"); } - return SRSASN_SUCCESS; } -SRSASN_CODE sr_sps_bsr_cfg_nb_r15_c::unpack(cbit_ref& bref) +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::res_reserv_r16_c_(const res_reserv_cfg_nb_r16_s::res_reserv_r16_c_& other) { - types e; - e.unpack(bref); - set(e); + type_ = other.type(); switch (type_) { - case types::release: + case types::sf_bitmap_r16: + c.init(other.c.get()); break; - case types::setup: - HANDLE_CODE(c.semi_persist_sched_c_rnti_r15.unpack(bref)); - HANDLE_CODE(c.semi_persist_sched_interv_ul_r15.unpack(bref)); + case types::slot_cfg_r16: + c.init(other.c.get()); + break; + case types::nulltype: break; default: - log_invalid_choice_id(type_, "sr_sps_bsr_cfg_nb_r15_c"); - return SRSASN_ERROR_DECODE_FAIL; + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_"); } - return SRSASN_SUCCESS; } - -const char* sr_sps_bsr_cfg_nb_r15_c::setup_s_::semi_persist_sched_interv_ul_r15_opts::to_string() const -{ - static const char* options[] = {"sf128", "sf256", "sf512", "sf1024", "sf1280", "sf2048", "sf2560", "sf5120"}; - return convert_enum_idx(options, 8, value, "sr_sps_bsr_cfg_nb_r15_c::setup_s_::semi_persist_sched_interv_ul_r15_e_"); -} -uint16_t sr_sps_bsr_cfg_nb_r15_c::setup_s_::semi_persist_sched_interv_ul_r15_opts::to_number() const +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_& +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::operator=(const res_reserv_cfg_nb_r16_s::res_reserv_r16_c_& other) { - static const uint16_t options[] = {128, 256, 512, 1024, 1280, 2048, 2560, 5120}; - return map_enum_number(options, 8, value, "sr_sps_bsr_cfg_nb_r15_c::setup_s_::semi_persist_sched_interv_ul_r15_e_"); -} + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::sf_bitmap_r16: + c.set(other.c.get()); + break; + case types::slot_cfg_r16: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_"); + } -// SR-WithoutHARQ-ACK-Config-NB-r15 ::= CHOICE -void sr_without_harq_ack_cfg_nb_r15_c::set(types::options e) -{ - type_ = e; + return *this; } -void sr_without_harq_ack_cfg_nb_r15_c::set_release() +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_& +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::set_sf_bitmap_r16() { - set(types::release); + set(types::sf_bitmap_r16); + return c.get(); } -sr_without_harq_ack_cfg_nb_r15_c::setup_s_& sr_without_harq_ack_cfg_nb_r15_c::set_setup() +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_& +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::set_slot_cfg_r16() { - set(types::setup); - return c; + set(types::slot_cfg_r16); + return c.get(); } -void sr_without_harq_ack_cfg_nb_r15_c::to_json(json_writer& j) const +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::release: + case types::sf_bitmap_r16: + j.write_fieldname("subframeBitmap-r16"); + c.get().to_json(j); break; - case types::setup: - j.write_fieldname("setup"); + case types::slot_cfg_r16: + j.write_fieldname("slotConfig-r16"); j.start_obj(); - if (c.sr_prohibit_timer_r15_present) { - j.write_int("sr-ProhibitTimer-r15", c.sr_prohibit_timer_r15); - } - if (c.sr_nprach_res_r15_present) { - j.write_fieldname("sr-NPRACH-Resource-r15"); - c.sr_nprach_res_r15.to_json(j); - } + j.write_fieldname("slotBitmap-r16"); + c.get().slot_bitmap_r16.to_json(j); + j.write_fieldname("symbolBitmap-r16"); + c.get().symbol_bitmap_r16.to_json(j); j.end_obj(); break; default: - log_invalid_choice_id(type_, "sr_without_harq_ack_cfg_nb_r15_c"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_"); } j.end_obj(); } -SRSASN_CODE sr_without_harq_ack_cfg_nb_r15_c::pack(bit_ref& bref) const +SRSASN_CODE res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::release: + case types::sf_bitmap_r16: + HANDLE_CODE(c.get().pack(bref)); break; - case types::setup: - HANDLE_CODE(bref.pack(c.sr_prohibit_timer_r15_present, 1)); - HANDLE_CODE(bref.pack(c.sr_nprach_res_r15_present, 1)); - if (c.sr_prohibit_timer_r15_present) { - HANDLE_CODE(pack_integer(bref, c.sr_prohibit_timer_r15, (uint8_t)0u, (uint8_t)7u)); - } - if (c.sr_nprach_res_r15_present) { - HANDLE_CODE(c.sr_nprach_res_r15.pack(bref)); - } + case types::slot_cfg_r16: + HANDLE_CODE(c.get().slot_bitmap_r16.pack(bref)); + HANDLE_CODE(c.get().symbol_bitmap_r16.pack(bref)); break; default: - log_invalid_choice_id(type_, "sr_without_harq_ack_cfg_nb_r15_c"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE sr_without_harq_ack_cfg_nb_r15_c::unpack(cbit_ref& bref) +SRSASN_CODE res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::release: + case types::sf_bitmap_r16: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::setup: - HANDLE_CODE(bref.unpack(c.sr_prohibit_timer_r15_present, 1)); - HANDLE_CODE(bref.unpack(c.sr_nprach_res_r15_present, 1)); - if (c.sr_prohibit_timer_r15_present) { - HANDLE_CODE(unpack_integer(c.sr_prohibit_timer_r15, bref, (uint8_t)0u, (uint8_t)7u)); - } - if (c.sr_nprach_res_r15_present) { - HANDLE_CODE(c.sr_nprach_res_r15.unpack(bref)); - } + case types::slot_cfg_r16: + HANDLE_CODE(c.get().slot_bitmap_r16.unpack(bref)); + HANDLE_CODE(c.get().symbol_bitmap_r16.unpack(bref)); break; default: - log_invalid_choice_id(type_, "sr_without_harq_ack_cfg_nb_r15_c"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -// SRB-ToAddMod-NB-r13 ::= SEQUENCE -SRSASN_CODE srb_to_add_mod_nb_r13_s::pack(bit_ref& bref) const +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::destroy_() { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(rlc_cfg_r13_present, 1)); - HANDLE_CODE(bref.pack(lc_ch_cfg_r13_present, 1)); - - if (rlc_cfg_r13_present) { - HANDLE_CODE(rlc_cfg_r13.pack(bref)); - } - if (lc_ch_cfg_r13_present) { - HANDLE_CODE(lc_ch_cfg_r13.pack(bref)); - } - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= rlc_cfg_v1430.is_present(); - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(rlc_cfg_v1430.is_present(), 1)); - if (rlc_cfg_v1430.is_present()) { - HANDLE_CODE(rlc_cfg_v1430->pack(bref)); - } - } + switch (type_) { + case types::sf_pattern10ms: + c.destroy >(); + break; + case types::sf_pattern40ms: + c.destroy >(); + break; + default: + break; } - return SRSASN_SUCCESS; } -SRSASN_CODE srb_to_add_mod_nb_r13_s::unpack(cbit_ref& bref) +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::set(types::options e) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(rlc_cfg_r13_present, 1)); - HANDLE_CODE(bref.unpack(lc_ch_cfg_r13_present, 1)); - - if (rlc_cfg_r13_present) { - HANDLE_CODE(rlc_cfg_r13.unpack(bref)); - } - if (lc_ch_cfg_r13_present) { - HANDLE_CODE(lc_ch_cfg_r13.unpack(bref)); - } - - if (ext) { - ext_groups_unpacker_guard group_flags(1); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool rlc_cfg_v1430_present; - HANDLE_CODE(bref.unpack(rlc_cfg_v1430_present, 1)); - rlc_cfg_v1430.set_present(rlc_cfg_v1430_present); - if (rlc_cfg_v1430.is_present()) { - HANDLE_CODE(rlc_cfg_v1430->unpack(bref)); - } - } + destroy_(); + type_ = e; + switch (type_) { + case types::sf_pattern10ms: + c.init >(); + break; + case types::sf_pattern40ms: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_"); } - return SRSASN_SUCCESS; } -void srb_to_add_mod_nb_r13_s::to_json(json_writer& j) const +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::sf_bitmap_r16_c_( + const res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_& other) { - j.start_obj(); - if (rlc_cfg_r13_present) { - j.write_fieldname("rlc-Config-r13"); - rlc_cfg_r13.to_json(j); + type_ = other.type(); + switch (type_) { + case types::sf_pattern10ms: + c.init(other.c.get >()); + break; + case types::sf_pattern40ms: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_"); } - if (lc_ch_cfg_r13_present) { - j.write_fieldname("logicalChannelConfig-r13"); - lc_ch_cfg_r13.to_json(j); +} +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_& +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::operator=( + const res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_& other) +{ + if (this == &other) { + return *this; } - if (ext) { - if (rlc_cfg_v1430.is_present()) { - j.write_fieldname("rlc-Config-v1430"); - rlc_cfg_v1430->to_json(j); - } + set(other.type()); + switch (type_) { + case types::sf_pattern10ms: + c.set(other.c.get >()); + break; + case types::sf_pattern40ms: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_"); } - j.end_obj(); -} -void srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::set(types::options e) -{ - type_ = e; + return *this; } -rlc_cfg_nb_r13_c& srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::set_explicit_value() +fixed_bitstring<10>& res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::set_sf_pattern10ms() { - set(types::explicit_value); - return c; + set(types::sf_pattern10ms); + return c.get >(); } -void srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::set_default_value() +fixed_bitstring<40>& res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::set_sf_pattern40ms() { - set(types::default_value); + set(types::sf_pattern40ms); + return c.get >(); } -void srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::to_json(json_writer& j) const +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::explicit_value: - j.write_fieldname("explicitValue"); - c.to_json(j); + case types::sf_pattern10ms: + j.write_str("subframePattern10ms", c.get >().to_string()); break; - case types::default_value: + case types::sf_pattern40ms: + j.write_str("subframePattern40ms", c.get >().to_string()); break; default: - log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_"); } j.end_obj(); } -SRSASN_CODE srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::pack(bit_ref& bref) const +SRSASN_CODE res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::explicit_value: - HANDLE_CODE(c.pack(bref)); + case types::sf_pattern10ms: + HANDLE_CODE(c.get >().pack(bref)); break; - case types::default_value: + case types::sf_pattern40ms: + HANDLE_CODE(c.get >().pack(bref)); break; default: - log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::unpack(cbit_ref& bref) +SRSASN_CODE res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::explicit_value: - HANDLE_CODE(c.unpack(bref)); + case types::sf_pattern10ms: + HANDLE_CODE(c.get >().unpack(bref)); break; - case types::default_value: + case types::sf_pattern40ms: + HANDLE_CODE(c.get >().unpack(bref)); break; default: - log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::types_opts::to_string() const +const char* res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::types_opts::to_string() const { - static const char* options[] = {"explicitValue", "defaultValue"}; - return convert_enum_idx(options, 2, value, "srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::types"); + static const char* options[] = {"subframePattern10ms", "subframePattern40ms"}; + return convert_enum_idx(options, 2, value, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::types"); +} +uint8_t res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {10, 40}; + return map_enum_number(options, 2, value, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::sf_bitmap_r16_c_::types"); } -void srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::set(types::options e) +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::destroy_() +{ + switch (type_) { + case types::slot_pattern10ms: + c.destroy >(); + break; + case types::slot_pattern40ms: + c.destroy >(); + break; + default: + break; + } +} +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::set(types::options e) { + destroy_(); type_ = e; + switch (type_) { + case types::slot_pattern10ms: + c.init >(); + break; + case types::slot_pattern40ms: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_"); + } } -lc_ch_cfg_nb_r13_s& srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::set_explicit_value() +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::slot_bitmap_r16_c_( + const res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_& other) { - set(types::explicit_value); - return c; + type_ = other.type(); + switch (type_) { + case types::slot_pattern10ms: + c.init(other.c.get >()); + break; + case types::slot_pattern40ms: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_"); + } } -void srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::set_default_value() +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_& +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::operator=( + const res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_& other) { - set(types::default_value); + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::slot_pattern10ms: + c.set(other.c.get >()); + break; + case types::slot_pattern40ms: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_"); + } + + return *this; } -void srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::to_json(json_writer& j) const +fixed_bitstring<20>& +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::set_slot_pattern10ms() +{ + set(types::slot_pattern10ms); + return c.get >(); +} +fixed_bitstring<80>& +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::set_slot_pattern40ms() +{ + set(types::slot_pattern40ms); + return c.get >(); +} +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::explicit_value: - j.write_fieldname("explicitValue"); - c.to_json(j); + case types::slot_pattern10ms: + j.write_str("slotPattern10ms", c.get >().to_string()); break; - case types::default_value: + case types::slot_pattern40ms: + j.write_str("slotPattern40ms", c.get >().to_string()); break; default: - log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_"); } j.end_obj(); } -SRSASN_CODE srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::pack(bit_ref& bref) const +SRSASN_CODE res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::explicit_value: - HANDLE_CODE(c.pack(bref)); + case types::slot_pattern10ms: + HANDLE_CODE(c.get >().pack(bref)); break; - case types::default_value: + case types::slot_pattern40ms: + HANDLE_CODE(c.get >().pack(bref)); break; default: - log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::unpack(cbit_ref& bref) +SRSASN_CODE res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::explicit_value: - HANDLE_CODE(c.unpack(bref)); + case types::slot_pattern10ms: + HANDLE_CODE(c.get >().unpack(bref)); break; - case types::default_value: + case types::slot_pattern40ms: + HANDLE_CODE(c.get >().unpack(bref)); break; default: - log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::types_opts::to_string() const +const char* +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::types_opts::to_string() const { - static const char* options[] = {"explicitValue", "defaultValue"}; - return convert_enum_idx(options, 2, value, "srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::types"); + static const char* options[] = {"slotPattern10ms", "slotPattern40ms"}; + return convert_enum_idx( + options, 2, value, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::types"); } - -// UplinkPowerControlDedicated-NB-r13 ::= SEQUENCE -SRSASN_CODE ul_pwr_ctrl_ded_nb_r13_s::pack(bit_ref& bref) const +uint8_t res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::types_opts::to_number() const { - HANDLE_CODE(pack_integer(bref, p0_ue_npusch_r13, (int8_t)-8, (int8_t)7)); + static const uint8_t options[] = {10, 40}; + return map_enum_number( + options, 2, value, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::slot_bitmap_r16_c_::types"); +} - return SRSASN_SUCCESS; +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::destroy_() +{ + switch (type_) { + case types::symbol_bitmap_fdd_dl: + c.destroy(); + break; + case types::symbol_bitmap_fdd_ul_or_tdd: + c.destroy(); + break; + default: + break; + } } -SRSASN_CODE ul_pwr_ctrl_ded_nb_r13_s::unpack(cbit_ref& bref) +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::set(types::options e) { - HANDLE_CODE(unpack_integer(p0_ue_npusch_r13, bref, (int8_t)-8, (int8_t)7)); - - return SRSASN_SUCCESS; + destroy_(); + type_ = e; + switch (type_) { + case types::symbol_bitmap_fdd_dl: + c.init(); + break; + case types::symbol_bitmap_fdd_ul_or_tdd: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_"); + } } -void ul_pwr_ctrl_ded_nb_r13_s::to_json(json_writer& j) const +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::symbol_bitmap_r16_c_( + const res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_& other) { - j.start_obj(); - j.write_int("p0-UE-NPUSCH-r13", p0_ue_npusch_r13); - j.end_obj(); + type_ = other.type(); + switch (type_) { + case types::symbol_bitmap_fdd_dl: + c.init(other.c.get()); + break; + case types::symbol_bitmap_fdd_ul_or_tdd: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_"); + } } - -// MAC-MainConfig-NB-r13 ::= SEQUENCE -SRSASN_CODE mac_main_cfg_nb_r13_s::pack(bit_ref& bref) const +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_& +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::operator=( + const res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_& other) { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(ul_sch_cfg_r13_present, 1)); - HANDLE_CODE(bref.pack(drx_cfg_r13_present, 1)); - HANDLE_CODE(bref.pack(lc_ch_sr_cfg_r13_present, 1)); - - if (ul_sch_cfg_r13_present) { - HANDLE_CODE(bref.pack(ul_sch_cfg_r13.periodic_bsr_timer_r13_present, 1)); - if (ul_sch_cfg_r13.periodic_bsr_timer_r13_present) { - HANDLE_CODE(ul_sch_cfg_r13.periodic_bsr_timer_r13.pack(bref)); - } - HANDLE_CODE(ul_sch_cfg_r13.retx_bsr_timer_r13.pack(bref)); - } - if (drx_cfg_r13_present) { - HANDLE_CODE(drx_cfg_r13.pack(bref)); - } - HANDLE_CODE(time_align_timer_ded_r13.pack(bref)); - if (lc_ch_sr_cfg_r13_present) { - HANDLE_CODE(lc_ch_sr_cfg_r13.pack(bref)); - } - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= rai_activation_r14_present; - group_flags[0] |= data_inactivity_timer_cfg_r14.is_present(); - group_flags[1] |= drx_cycle_v1430_present; - group_flags[2] |= ra_cfra_cfg_r14_present; - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(rai_activation_r14_present, 1)); - HANDLE_CODE(bref.pack(data_inactivity_timer_cfg_r14.is_present(), 1)); - if (data_inactivity_timer_cfg_r14.is_present()) { - HANDLE_CODE(data_inactivity_timer_cfg_r14->pack(bref)); - } - } - if (group_flags[1]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(drx_cycle_v1430_present, 1)); - if (drx_cycle_v1430_present) { - HANDLE_CODE(drx_cycle_v1430.pack(bref)); - } - } - if (group_flags[2]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(ra_cfra_cfg_r14_present, 1)); - } - } - return SRSASN_SUCCESS; -} -SRSASN_CODE mac_main_cfg_nb_r13_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(ul_sch_cfg_r13_present, 1)); - HANDLE_CODE(bref.unpack(drx_cfg_r13_present, 1)); - HANDLE_CODE(bref.unpack(lc_ch_sr_cfg_r13_present, 1)); - - if (ul_sch_cfg_r13_present) { - HANDLE_CODE(bref.unpack(ul_sch_cfg_r13.periodic_bsr_timer_r13_present, 1)); - if (ul_sch_cfg_r13.periodic_bsr_timer_r13_present) { - HANDLE_CODE(ul_sch_cfg_r13.periodic_bsr_timer_r13.unpack(bref)); - } - HANDLE_CODE(ul_sch_cfg_r13.retx_bsr_timer_r13.unpack(bref)); - } - if (drx_cfg_r13_present) { - HANDLE_CODE(drx_cfg_r13.unpack(bref)); - } - HANDLE_CODE(time_align_timer_ded_r13.unpack(bref)); - if (lc_ch_sr_cfg_r13_present) { - HANDLE_CODE(lc_ch_sr_cfg_r13.unpack(bref)); - } - - if (ext) { - ext_groups_unpacker_guard group_flags(3); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.unpack(rai_activation_r14_present, 1)); - bool data_inactivity_timer_cfg_r14_present; - HANDLE_CODE(bref.unpack(data_inactivity_timer_cfg_r14_present, 1)); - data_inactivity_timer_cfg_r14.set_present(data_inactivity_timer_cfg_r14_present); - if (data_inactivity_timer_cfg_r14.is_present()) { - HANDLE_CODE(data_inactivity_timer_cfg_r14->unpack(bref)); - } - } - if (group_flags[1]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.unpack(drx_cycle_v1430_present, 1)); - if (drx_cycle_v1430_present) { - HANDLE_CODE(drx_cycle_v1430.unpack(bref)); - } - } - if (group_flags[2]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.unpack(ra_cfra_cfg_r14_present, 1)); - } - } - return SRSASN_SUCCESS; -} -void mac_main_cfg_nb_r13_s::to_json(json_writer& j) const -{ - j.start_obj(); - if (ul_sch_cfg_r13_present) { - j.write_fieldname("ul-SCH-Config-r13"); - j.start_obj(); - if (ul_sch_cfg_r13.periodic_bsr_timer_r13_present) { - j.write_str("periodicBSR-Timer-r13", ul_sch_cfg_r13.periodic_bsr_timer_r13.to_string()); - } - j.write_str("retxBSR-Timer-r13", ul_sch_cfg_r13.retx_bsr_timer_r13.to_string()); - j.end_obj(); - } - if (drx_cfg_r13_present) { - j.write_fieldname("drx-Config-r13"); - drx_cfg_r13.to_json(j); - } - j.write_str("timeAlignmentTimerDedicated-r13", time_align_timer_ded_r13.to_string()); - if (lc_ch_sr_cfg_r13_present) { - j.write_fieldname("logicalChannelSR-Config-r13"); - lc_ch_sr_cfg_r13.to_json(j); + if (this == &other) { + return *this; } - if (ext) { - if (rai_activation_r14_present) { - j.write_str("rai-Activation-r14", "true"); - } - if (data_inactivity_timer_cfg_r14.is_present()) { - j.write_fieldname("dataInactivityTimerConfig-r14"); - data_inactivity_timer_cfg_r14->to_json(j); - } - if (drx_cycle_v1430_present) { - j.write_str("drx-Cycle-v1430", drx_cycle_v1430.to_string()); - } - if (ra_cfra_cfg_r14_present) { - j.write_str("ra-CFRA-Config-r14", "true"); - } + set(other.type()); + switch (type_) { + case types::symbol_bitmap_fdd_dl: + c.set(other.c.get()); + break; + case types::symbol_bitmap_fdd_ul_or_tdd: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_"); } - j.end_obj(); -} -void mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::set(types::options e) -{ - type_ = e; + return *this; } -void mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::set_release() +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::symbol_bitmap_fdd_dl_s_& +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::set_symbol_bitmap_fdd_dl() { - set(types::release); + set(types::symbol_bitmap_fdd_dl); + return c.get(); } -mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::setup_s_& mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::set_setup() +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::symbol_bitmap_fdd_ul_or_tdd_s_& +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::set_symbol_bitmap_fdd_ul_or_tdd() { - set(types::setup); - return c; + set(types::symbol_bitmap_fdd_ul_or_tdd); + return c.get(); } -void mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::to_json(json_writer& j) const +void res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::release: + case types::symbol_bitmap_fdd_dl: + j.write_fieldname("symbolBitmapFddDl"); + j.start_obj(); + if (c.get().symbol_bitmap1_r16_present) { + j.write_str("symbolBitmap1-r16", c.get().symbol_bitmap1_r16.to_string()); + } + if (c.get().symbol_bitmap2_r16_present) { + j.write_str("symbolBitmap2-r16", c.get().symbol_bitmap2_r16.to_string()); + } + j.end_obj(); break; - case types::setup: - j.write_fieldname("setup"); + case types::symbol_bitmap_fdd_ul_or_tdd: + j.write_fieldname("symbolBitmapFddUlOrTdd"); j.start_obj(); - j.write_str("logicalChannelSR-ProhibitTimer-r13", c.lc_ch_sr_prohibit_timer_r13.to_string()); + if (c.get().symbol_bitmap1_r16_present) { + j.write_str("symbolBitmap1-r16", c.get().symbol_bitmap1_r16.to_string()); + } + if (c.get().symbol_bitmap2_r16_present) { + j.write_str("symbolBitmap2-r16", c.get().symbol_bitmap2_r16.to_string()); + } j.end_obj(); break; default: - log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_"); } j.end_obj(); } -SRSASN_CODE mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::pack(bit_ref& bref) const +SRSASN_CODE res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::release: + case types::symbol_bitmap_fdd_dl: + HANDLE_CODE(bref.pack(c.get().symbol_bitmap1_r16_present, 1)); + HANDLE_CODE(bref.pack(c.get().symbol_bitmap2_r16_present, 1)); + if (c.get().symbol_bitmap1_r16_present) { + HANDLE_CODE(c.get().symbol_bitmap1_r16.pack(bref)); + } + if (c.get().symbol_bitmap2_r16_present) { + HANDLE_CODE(c.get().symbol_bitmap2_r16.pack(bref)); + } break; - case types::setup: - HANDLE_CODE(c.lc_ch_sr_prohibit_timer_r13.pack(bref)); + case types::symbol_bitmap_fdd_ul_or_tdd: + HANDLE_CODE(bref.pack(c.get().symbol_bitmap1_r16_present, 1)); + HANDLE_CODE(bref.pack(c.get().symbol_bitmap2_r16_present, 1)); + if (c.get().symbol_bitmap1_r16_present) { + HANDLE_CODE(c.get().symbol_bitmap1_r16.pack(bref)); + } + if (c.get().symbol_bitmap2_r16_present) { + HANDLE_CODE(c.get().symbol_bitmap2_r16.pack(bref)); + } break; default: - log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::unpack(cbit_ref& bref) +SRSASN_CODE res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::release: + case types::symbol_bitmap_fdd_dl: + HANDLE_CODE(bref.unpack(c.get().symbol_bitmap1_r16_present, 1)); + HANDLE_CODE(bref.unpack(c.get().symbol_bitmap2_r16_present, 1)); + if (c.get().symbol_bitmap1_r16_present) { + HANDLE_CODE(c.get().symbol_bitmap1_r16.unpack(bref)); + } + if (c.get().symbol_bitmap2_r16_present) { + HANDLE_CODE(c.get().symbol_bitmap2_r16.unpack(bref)); + } break; - case types::setup: - HANDLE_CODE(c.lc_ch_sr_prohibit_timer_r13.unpack(bref)); + case types::symbol_bitmap_fdd_ul_or_tdd: + HANDLE_CODE(bref.unpack(c.get().symbol_bitmap1_r16_present, 1)); + HANDLE_CODE(bref.unpack(c.get().symbol_bitmap2_r16_present, 1)); + if (c.get().symbol_bitmap1_r16_present) { + HANDLE_CODE(c.get().symbol_bitmap1_r16.unpack(bref)); + } + if (c.get().symbol_bitmap2_r16_present) { + HANDLE_CODE(c.get().symbol_bitmap2_r16.unpack(bref)); + } break; default: - log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_"); + log_invalid_choice_id(type_, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::setup_s_::lc_ch_sr_prohibit_timer_r13_opts::to_string() const +const char* +res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::types_opts::to_string() const { - static const char* options[] = {"pp2", "pp8", "pp32", "pp128", "pp512", "pp1024", "pp2048", "spare"}; + static const char* options[] = {"symbolBitmapFddDl", "symbolBitmapFddUlOrTdd"}; return convert_enum_idx( - options, 8, value, "mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::setup_s_::lc_ch_sr_prohibit_timer_r13_e_"); + options, 2, value, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::slot_cfg_r16_s_::symbol_bitmap_r16_c_::types"); } -uint16_t mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::setup_s_::lc_ch_sr_prohibit_timer_r13_opts::to_number() const + +const char* res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::types_opts::to_string() const { - static const uint16_t options[] = {2, 8, 32, 128, 512, 1024, 2048}; - return map_enum_number( - options, 7, value, "mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::setup_s_::lc_ch_sr_prohibit_timer_r13_e_"); + static const char* options[] = {"subframeBitmap-r16", "slotConfig-r16"}; + return convert_enum_idx(options, 2, value, "res_reserv_cfg_nb_r16_s::res_reserv_r16_c_::types"); } -void mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::set(types::options e) +// RetxBSR-Timer-NB-r13 ::= ENUMERATED +const char* retx_bsr_timer_nb_r13_opts::to_string() const +{ + static const char* options[] = {"pp4", "pp16", "pp64", "pp128", "pp256", "pp512", "infinity", "spare"}; + return convert_enum_idx(options, 8, value, "retx_bsr_timer_nb_r13_e"); +} +int16_t retx_bsr_timer_nb_r13_opts::to_number() const +{ + static const int16_t options[] = {4, 16, 64, 128, 256, 512, -1}; + return map_enum_number(options, 7, value, "retx_bsr_timer_nb_r13_e"); +} + +// SR-SPS-BSR-Config-NB-r15 ::= CHOICE +void sr_sps_bsr_cfg_nb_r15_c::set(types::options e) { type_ = e; } -void mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::set_release() +void sr_sps_bsr_cfg_nb_r15_c::set_release() { set(types::release); } -mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::setup_s_& -mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::set_setup() +sr_sps_bsr_cfg_nb_r15_c::setup_s_& sr_sps_bsr_cfg_nb_r15_c::set_setup() { set(types::setup); return c; } -void mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::to_json(json_writer& j) const +void sr_sps_bsr_cfg_nb_r15_c::to_json(json_writer& j) const { j.start_obj(); switch (type_) { @@ -2736,30 +3364,32 @@ void mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::to_json(json_write case types::setup: j.write_fieldname("setup"); j.start_obj(); - j.write_str("dataInactivityTimer-r14", c.data_inactivity_timer_r14.to_string()); + j.write_str("semiPersistSchedC-RNTI-r15", c.semi_persist_sched_c_rnti_r15.to_string()); + j.write_str("semiPersistSchedIntervalUL-r15", c.semi_persist_sched_interv_ul_r15.to_string()); j.end_obj(); break; default: - log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_"); + log_invalid_choice_id(type_, "sr_sps_bsr_cfg_nb_r15_c"); } j.end_obj(); } -SRSASN_CODE mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::pack(bit_ref& bref) const +SRSASN_CODE sr_sps_bsr_cfg_nb_r15_c::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { case types::release: break; case types::setup: - HANDLE_CODE(c.data_inactivity_timer_r14.pack(bref)); + HANDLE_CODE(c.semi_persist_sched_c_rnti_r15.pack(bref)); + HANDLE_CODE(c.semi_persist_sched_interv_ul_r15.pack(bref)); break; default: - log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_"); + log_invalid_choice_id(type_, "sr_sps_bsr_cfg_nb_r15_c"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::unpack(cbit_ref& bref) +SRSASN_CODE sr_sps_bsr_cfg_nb_r15_c::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -2768,1899 +3398,2274 @@ SRSASN_CODE mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::unpack(cbit case types::release: break; case types::setup: - HANDLE_CODE(c.data_inactivity_timer_r14.unpack(bref)); + HANDLE_CODE(c.semi_persist_sched_c_rnti_r15.unpack(bref)); + HANDLE_CODE(c.semi_persist_sched_interv_ul_r15.unpack(bref)); break; default: - log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_"); + log_invalid_choice_id(type_, "sr_sps_bsr_cfg_nb_r15_c"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* mac_main_cfg_nb_r13_s::drx_cycle_v1430_opts::to_string() const +const char* sr_sps_bsr_cfg_nb_r15_c::setup_s_::semi_persist_sched_interv_ul_r15_opts::to_string() const { - static const char* options[] = {"sf1280", "sf2560", "sf5120", "sf10240"}; - return convert_enum_idx(options, 4, value, "mac_main_cfg_nb_r13_s::drx_cycle_v1430_e_"); + static const char* options[] = {"sf128", "sf256", "sf512", "sf1024", "sf1280", "sf2048", "sf2560", "sf5120"}; + return convert_enum_idx(options, 8, value, "sr_sps_bsr_cfg_nb_r15_c::setup_s_::semi_persist_sched_interv_ul_r15_e_"); } -uint16_t mac_main_cfg_nb_r13_s::drx_cycle_v1430_opts::to_number() const +uint16_t sr_sps_bsr_cfg_nb_r15_c::setup_s_::semi_persist_sched_interv_ul_r15_opts::to_number() const { - static const uint16_t options[] = {1280, 2560, 5120, 10240}; - return map_enum_number(options, 4, value, "mac_main_cfg_nb_r13_s::drx_cycle_v1430_e_"); + static const uint16_t options[] = {128, 256, 512, 1024, 1280, 2048, 2560, 5120}; + return map_enum_number(options, 8, value, "sr_sps_bsr_cfg_nb_r15_c::setup_s_::semi_persist_sched_interv_ul_r15_e_"); } -// PhysicalConfigDedicated-NB-r13 ::= SEQUENCE -SRSASN_CODE phys_cfg_ded_nb_r13_s::pack(bit_ref& bref) const +// SR-WithoutHARQ-ACK-Config-NB-r15 ::= CHOICE +void sr_without_harq_ack_cfg_nb_r15_c::set(types::options e) { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(carrier_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.pack(npdcch_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.pack(npusch_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.pack(ul_pwr_ctrl_ded_r13_present, 1)); + type_ = e; +} +void sr_without_harq_ack_cfg_nb_r15_c::set_release() +{ + set(types::release); +} +sr_without_harq_ack_cfg_nb_r15_c::setup_s_& sr_without_harq_ack_cfg_nb_r15_c::set_setup() +{ + set(types::setup); + return c; +} +void sr_without_harq_ack_cfg_nb_r15_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::release: + break; + case types::setup: + j.write_fieldname("setup"); + j.start_obj(); + if (c.sr_prohibit_timer_r15_present) { + j.write_int("sr-ProhibitTimer-r15", c.sr_prohibit_timer_r15); + } + if (c.sr_nprach_res_r15_present) { + j.write_fieldname("sr-NPRACH-Resource-r15"); + c.sr_nprach_res_r15.to_json(j); + } + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "sr_without_harq_ack_cfg_nb_r15_c"); + } + j.end_obj(); +} +SRSASN_CODE sr_without_harq_ack_cfg_nb_r15_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(bref.pack(c.sr_prohibit_timer_r15_present, 1)); + HANDLE_CODE(bref.pack(c.sr_nprach_res_r15_present, 1)); + if (c.sr_prohibit_timer_r15_present) { + HANDLE_CODE(pack_integer(bref, c.sr_prohibit_timer_r15, (uint8_t)0u, (uint8_t)7u)); + } + if (c.sr_nprach_res_r15_present) { + HANDLE_CODE(c.sr_nprach_res_r15.pack(bref)); + } + break; + default: + log_invalid_choice_id(type_, "sr_without_harq_ack_cfg_nb_r15_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sr_without_harq_ack_cfg_nb_r15_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(bref.unpack(c.sr_prohibit_timer_r15_present, 1)); + HANDLE_CODE(bref.unpack(c.sr_nprach_res_r15_present, 1)); + if (c.sr_prohibit_timer_r15_present) { + HANDLE_CODE(unpack_integer(c.sr_prohibit_timer_r15, bref, (uint8_t)0u, (uint8_t)7u)); + } + if (c.sr_nprach_res_r15_present) { + HANDLE_CODE(c.sr_nprach_res_r15.unpack(bref)); + } + break; + default: + log_invalid_choice_id(type_, "sr_without_harq_ack_cfg_nb_r15_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} - if (carrier_cfg_ded_r13_present) { - HANDLE_CODE(carrier_cfg_ded_r13.pack(bref)); +// SR-WithoutHARQ-ACK-Config-NB-v1700 ::= SEQUENCE +SRSASN_CODE sr_without_harq_ack_cfg_nb_v1700_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(sr_prohibit_timer_offset_r17_present, 1)); + + if (sr_prohibit_timer_offset_r17_present) { + HANDLE_CODE(sr_prohibit_timer_offset_r17.pack(bref)); } - if (npdcch_cfg_ded_r13_present) { - HANDLE_CODE(npdcch_cfg_ded_r13.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE sr_without_harq_ack_cfg_nb_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(sr_prohibit_timer_offset_r17_present, 1)); + + if (sr_prohibit_timer_offset_r17_present) { + HANDLE_CODE(sr_prohibit_timer_offset_r17.unpack(bref)); } - if (npusch_cfg_ded_r13_present) { - HANDLE_CODE(npusch_cfg_ded_r13.pack(bref)); + + return SRSASN_SUCCESS; +} +void sr_without_harq_ack_cfg_nb_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (sr_prohibit_timer_offset_r17_present) { + j.write_fieldname("sr-ProhibitTimerOffset-r17"); + sr_prohibit_timer_offset_r17.to_json(j); } - if (ul_pwr_ctrl_ded_r13_present) { - HANDLE_CODE(ul_pwr_ctrl_ded_r13.pack(bref)); + j.end_obj(); +} + +// SRB-ToAddMod-NB-r13 ::= SEQUENCE +SRSASN_CODE srb_to_add_mod_nb_r13_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(rlc_cfg_r13_present, 1)); + HANDLE_CODE(bref.pack(lc_ch_cfg_r13_present, 1)); + + if (rlc_cfg_r13_present) { + HANDLE_CODE(rlc_cfg_r13.pack(bref)); + } + if (lc_ch_cfg_r13_present) { + HANDLE_CODE(lc_ch_cfg_r13.pack(bref)); } if (ext) { ext_groups_packer_guard group_flags; - group_flags[0] |= two_harq_processes_cfg_r14_present; - group_flags[1] |= interference_randomisation_cfg_r14_present; - group_flags[2] |= npdcch_cfg_ded_v1530.is_present(); - group_flags[3] |= add_tx_sib1_cfg_v1540_present; + group_flags[0] |= rlc_cfg_v1430.is_present(); + group_flags[1] |= rlc_cfg_v1700.is_present(); group_flags.pack(bref); if (group_flags[0]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(two_harq_processes_cfg_r14_present, 1)); + HANDLE_CODE(bref.pack(rlc_cfg_v1430.is_present(), 1)); + if (rlc_cfg_v1430.is_present()) { + HANDLE_CODE(rlc_cfg_v1430->pack(bref)); + } } if (group_flags[1]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(interference_randomisation_cfg_r14_present, 1)); - } - if (group_flags[2]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(npdcch_cfg_ded_v1530.is_present(), 1)); - if (npdcch_cfg_ded_v1530.is_present()) { - HANDLE_CODE(npdcch_cfg_ded_v1530->pack(bref)); + HANDLE_CODE(bref.pack(rlc_cfg_v1700.is_present(), 1)); + if (rlc_cfg_v1700.is_present()) { + HANDLE_CODE(rlc_cfg_v1700->pack(bref)); } } - if (group_flags[3]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(add_tx_sib1_cfg_v1540_present, 1)); - } } return SRSASN_SUCCESS; } -SRSASN_CODE phys_cfg_ded_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE srb_to_add_mod_nb_r13_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(carrier_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.unpack(npdcch_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.unpack(npusch_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.unpack(ul_pwr_ctrl_ded_r13_present, 1)); + HANDLE_CODE(bref.unpack(rlc_cfg_r13_present, 1)); + HANDLE_CODE(bref.unpack(lc_ch_cfg_r13_present, 1)); - if (carrier_cfg_ded_r13_present) { - HANDLE_CODE(carrier_cfg_ded_r13.unpack(bref)); - } - if (npdcch_cfg_ded_r13_present) { - HANDLE_CODE(npdcch_cfg_ded_r13.unpack(bref)); - } - if (npusch_cfg_ded_r13_present) { - HANDLE_CODE(npusch_cfg_ded_r13.unpack(bref)); + if (rlc_cfg_r13_present) { + HANDLE_CODE(rlc_cfg_r13.unpack(bref)); } - if (ul_pwr_ctrl_ded_r13_present) { - HANDLE_CODE(ul_pwr_ctrl_ded_r13.unpack(bref)); + if (lc_ch_cfg_r13_present) { + HANDLE_CODE(lc_ch_cfg_r13.unpack(bref)); } if (ext) { - ext_groups_unpacker_guard group_flags(4); + ext_groups_unpacker_guard group_flags(2); group_flags.unpack(bref); if (group_flags[0]) { varlength_field_unpack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.unpack(two_harq_processes_cfg_r14_present, 1)); + bool rlc_cfg_v1430_present; + HANDLE_CODE(bref.unpack(rlc_cfg_v1430_present, 1)); + rlc_cfg_v1430.set_present(rlc_cfg_v1430_present); + if (rlc_cfg_v1430.is_present()) { + HANDLE_CODE(rlc_cfg_v1430->unpack(bref)); + } } if (group_flags[1]) { varlength_field_unpack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.unpack(interference_randomisation_cfg_r14_present, 1)); - } - if (group_flags[2]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool npdcch_cfg_ded_v1530_present; - HANDLE_CODE(bref.unpack(npdcch_cfg_ded_v1530_present, 1)); - npdcch_cfg_ded_v1530.set_present(npdcch_cfg_ded_v1530_present); - if (npdcch_cfg_ded_v1530.is_present()) { - HANDLE_CODE(npdcch_cfg_ded_v1530->unpack(bref)); + bool rlc_cfg_v1700_present; + HANDLE_CODE(bref.unpack(rlc_cfg_v1700_present, 1)); + rlc_cfg_v1700.set_present(rlc_cfg_v1700_present); + if (rlc_cfg_v1700.is_present()) { + HANDLE_CODE(rlc_cfg_v1700->unpack(bref)); } } - if (group_flags[3]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.unpack(add_tx_sib1_cfg_v1540_present, 1)); - } } return SRSASN_SUCCESS; } -void phys_cfg_ded_nb_r13_s::to_json(json_writer& j) const +void srb_to_add_mod_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - if (carrier_cfg_ded_r13_present) { - j.write_fieldname("carrierConfigDedicated-r13"); - carrier_cfg_ded_r13.to_json(j); - } - if (npdcch_cfg_ded_r13_present) { - j.write_fieldname("npdcch-ConfigDedicated-r13"); - npdcch_cfg_ded_r13.to_json(j); - } - if (npusch_cfg_ded_r13_present) { - j.write_fieldname("npusch-ConfigDedicated-r13"); - npusch_cfg_ded_r13.to_json(j); + if (rlc_cfg_r13_present) { + j.write_fieldname("rlc-Config-r13"); + rlc_cfg_r13.to_json(j); } - if (ul_pwr_ctrl_ded_r13_present) { - j.write_fieldname("uplinkPowerControlDedicated-r13"); - ul_pwr_ctrl_ded_r13.to_json(j); + if (lc_ch_cfg_r13_present) { + j.write_fieldname("logicalChannelConfig-r13"); + lc_ch_cfg_r13.to_json(j); } if (ext) { - if (two_harq_processes_cfg_r14_present) { - j.write_str("twoHARQ-ProcessesConfig-r14", "true"); - } - if (interference_randomisation_cfg_r14_present) { - j.write_str("interferenceRandomisationConfig-r14", "true"); - } - if (npdcch_cfg_ded_v1530.is_present()) { - j.write_fieldname("npdcch-ConfigDedicated-v1530"); - npdcch_cfg_ded_v1530->to_json(j); + if (rlc_cfg_v1430.is_present()) { + j.write_fieldname("rlc-Config-v1430"); + rlc_cfg_v1430->to_json(j); } - if (add_tx_sib1_cfg_v1540_present) { - j.write_str("additionalTxSIB1-Config-v1540", "true"); + if (rlc_cfg_v1700.is_present()) { + j.write_fieldname("rlc-Config-v1700"); + rlc_cfg_v1700->to_json(j); } } j.end_obj(); } -// RLF-TimersAndConstants-NB-r13 ::= CHOICE -void rlf_timers_and_consts_nb_r13_c::set(types::options e) +void srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::set(types::options e) { type_ = e; } -void rlf_timers_and_consts_nb_r13_c::set_release() +rlc_cfg_nb_r13_c& srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::set_explicit_value() { - set(types::release); + set(types::explicit_value); + return c; } -rlf_timers_and_consts_nb_r13_c::setup_s_& rlf_timers_and_consts_nb_r13_c::set_setup() +void srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::set_default_value() { - set(types::setup); - return c; + set(types::default_value); } -void rlf_timers_and_consts_nb_r13_c::to_json(json_writer& j) const +void srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::release: - break; - case types::setup: - j.write_fieldname("setup"); + case types::explicit_value: + j.write_fieldname("explicitValue"); c.to_json(j); break; + case types::default_value: + break; default: - log_invalid_choice_id(type_, "rlf_timers_and_consts_nb_r13_c"); + log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_"); } j.end_obj(); } -SRSASN_CODE rlf_timers_and_consts_nb_r13_c::pack(bit_ref& bref) const +SRSASN_CODE srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::release: - break; - case types::setup: + case types::explicit_value: HANDLE_CODE(c.pack(bref)); break; + case types::default_value: + break; default: - log_invalid_choice_id(type_, "rlf_timers_and_consts_nb_r13_c"); + log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rlf_timers_and_consts_nb_r13_c::unpack(cbit_ref& bref) +SRSASN_CODE srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::release: - break; - case types::setup: + case types::explicit_value: HANDLE_CODE(c.unpack(bref)); break; + case types::default_value: + break; default: - log_invalid_choice_id(type_, "rlf_timers_and_consts_nb_r13_c"); + log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rlf_timers_and_consts_nb_r13_c::setup_s_::pack(bit_ref& bref) const +const char* srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::types_opts::to_string() const { - bref.pack(ext, 1); - HANDLE_CODE(t301_r13.pack(bref)); - HANDLE_CODE(t310_r13.pack(bref)); - HANDLE_CODE(n310_r13.pack(bref)); - HANDLE_CODE(t311_r13.pack(bref)); - HANDLE_CODE(n311_r13.pack(bref)); - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= t311_v1350_present; - group_flags[1] |= t301_v1530_present; - group_flags[1] |= t311_v1530_present; - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(t311_v1350_present, 1)); - if (t311_v1350_present) { - HANDLE_CODE(t311_v1350.pack(bref)); - } - } - if (group_flags[1]) { - varlength_field_pack_guard varlen_scope(bref, false); + static const char* options[] = {"explicitValue", "defaultValue"}; + return convert_enum_idx(options, 2, value, "srb_to_add_mod_nb_r13_s::rlc_cfg_r13_c_::types"); +} - HANDLE_CODE(bref.pack(t301_v1530_present, 1)); - HANDLE_CODE(bref.pack(t311_v1530_present, 1)); - if (t301_v1530_present) { - HANDLE_CODE(t301_v1530.pack(bref)); - } - if (t311_v1530_present) { - HANDLE_CODE(t311_v1530.pack(bref)); - } - } - } - return SRSASN_SUCCESS; +void srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::set(types::options e) +{ + type_ = e; } -SRSASN_CODE rlf_timers_and_consts_nb_r13_c::setup_s_::unpack(cbit_ref& bref) +lc_ch_cfg_nb_r13_s& srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::set_explicit_value() { - bref.unpack(ext, 1); - HANDLE_CODE(t301_r13.unpack(bref)); - HANDLE_CODE(t310_r13.unpack(bref)); - HANDLE_CODE(n310_r13.unpack(bref)); - HANDLE_CODE(t311_r13.unpack(bref)); - HANDLE_CODE(n311_r13.unpack(bref)); - - if (ext) { - ext_groups_unpacker_guard group_flags(2); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.unpack(t311_v1350_present, 1)); - if (t311_v1350_present) { - HANDLE_CODE(t311_v1350.unpack(bref)); - } - } - if (group_flags[1]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.unpack(t301_v1530_present, 1)); - HANDLE_CODE(bref.unpack(t311_v1530_present, 1)); - if (t301_v1530_present) { - HANDLE_CODE(t301_v1530.unpack(bref)); - } - if (t311_v1530_present) { - HANDLE_CODE(t311_v1530.unpack(bref)); - } - } - } - return SRSASN_SUCCESS; + set(types::explicit_value); + return c; } -void rlf_timers_and_consts_nb_r13_c::setup_s_::to_json(json_writer& j) const +void srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::set_default_value() +{ + set(types::default_value); +} +void srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::to_json(json_writer& j) const { j.start_obj(); - j.write_str("t301-r13", t301_r13.to_string()); - j.write_str("t310-r13", t310_r13.to_string()); - j.write_str("n310-r13", n310_r13.to_string()); - j.write_str("t311-r13", t311_r13.to_string()); - j.write_str("n311-r13", n311_r13.to_string()); - if (ext) { - if (t311_v1350_present) { - j.write_str("t311-v1350", t311_v1350.to_string()); - } - if (t301_v1530_present) { - j.write_str("t301-v1530", t301_v1530.to_string()); - } - if (t311_v1530_present) { - j.write_str("t311-v1530", t311_v1530.to_string()); - } + switch (type_) { + case types::explicit_value: + j.write_fieldname("explicitValue"); + c.to_json(j); + break; + case types::default_value: + break; + default: + log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_"); } j.end_obj(); } - -const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t301_r13_opts::to_string() const +SRSASN_CODE srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::pack(bit_ref& bref) const { - static const char* options[] = {"ms2500", "ms4000", "ms6000", "ms10000", "ms15000", "ms25000", "ms40000", "ms60000"}; - return convert_enum_idx(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t301_r13_e_"); + type_.pack(bref); + switch (type_) { + case types::explicit_value: + HANDLE_CODE(c.pack(bref)); + break; + case types::default_value: + break; + default: + log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; } -uint16_t rlf_timers_and_consts_nb_r13_c::setup_s_::t301_r13_opts::to_number() const +SRSASN_CODE srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::unpack(cbit_ref& bref) { - static const uint16_t options[] = {2500, 4000, 6000, 10000, 15000, 25000, 40000, 60000}; - return map_enum_number(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t301_r13_e_"); + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::explicit_value: + HANDLE_CODE(c.unpack(bref)); + break; + case types::default_value: + break; + default: + log_invalid_choice_id(type_, "srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; } -const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t310_r13_opts::to_string() const -{ - static const char* options[] = {"ms0", "ms200", "ms500", "ms1000", "ms2000", "ms4000", "ms8000"}; - return convert_enum_idx(options, 7, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t310_r13_e_"); -} -uint16_t rlf_timers_and_consts_nb_r13_c::setup_s_::t310_r13_opts::to_number() const +const char* srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::types_opts::to_string() const { - static const uint16_t options[] = {0, 200, 500, 1000, 2000, 4000, 8000}; - return map_enum_number(options, 7, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t310_r13_e_"); + static const char* options[] = {"explicitValue", "defaultValue"}; + return convert_enum_idx(options, 2, value, "srb_to_add_mod_nb_r13_s::lc_ch_cfg_r13_c_::types"); } -const char* rlf_timers_and_consts_nb_r13_c::setup_s_::n310_r13_opts::to_string() const -{ - static const char* options[] = {"n1", "n2", "n3", "n4", "n6", "n8", "n10", "n20"}; - return convert_enum_idx(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::n310_r13_e_"); -} -uint8_t rlf_timers_and_consts_nb_r13_c::setup_s_::n310_r13_opts::to_number() const +// UplinkPowerControlDedicated-NB-r13 ::= SEQUENCE +SRSASN_CODE ul_pwr_ctrl_ded_nb_r13_s::pack(bit_ref& bref) const { - static const uint8_t options[] = {1, 2, 3, 4, 6, 8, 10, 20}; - return map_enum_number(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::n310_r13_e_"); -} + HANDLE_CODE(pack_integer(bref, p0_ue_npusch_r13, (int8_t)-8, (int8_t)7)); -const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t311_r13_opts::to_string() const -{ - static const char* options[] = {"ms1000", "ms3000", "ms5000", "ms10000", "ms15000", "ms20000", "ms30000"}; - return convert_enum_idx(options, 7, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_r13_e_"); + return SRSASN_SUCCESS; } -uint16_t rlf_timers_and_consts_nb_r13_c::setup_s_::t311_r13_opts::to_number() const +SRSASN_CODE ul_pwr_ctrl_ded_nb_r13_s::unpack(cbit_ref& bref) { - static const uint16_t options[] = {1000, 3000, 5000, 10000, 15000, 20000, 30000}; - return map_enum_number(options, 7, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_r13_e_"); -} + HANDLE_CODE(unpack_integer(p0_ue_npusch_r13, bref, (int8_t)-8, (int8_t)7)); -const char* rlf_timers_and_consts_nb_r13_c::setup_s_::n311_r13_opts::to_string() const -{ - static const char* options[] = {"n1", "n2", "n3", "n4", "n5", "n6", "n8", "n10"}; - return convert_enum_idx(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::n311_r13_e_"); + return SRSASN_SUCCESS; } -uint8_t rlf_timers_and_consts_nb_r13_c::setup_s_::n311_r13_opts::to_number() const +void ul_pwr_ctrl_ded_nb_r13_s::to_json(json_writer& j) const { - static const uint8_t options[] = {1, 2, 3, 4, 5, 6, 8, 10}; - return map_enum_number(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::n311_r13_e_"); + j.start_obj(); + j.write_int("p0-UE-NPUSCH-r13", p0_ue_npusch_r13); + j.end_obj(); } -const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1350_opts::to_string() const +// UplinkPowerControlDedicated-NB-v1700 ::= SEQUENCE +SRSASN_CODE ul_pwr_ctrl_ded_nb_v1700_s::pack(bit_ref& bref) const { - static const char* options[] = {"ms40000", "ms60000", "ms90000", "ms120000"}; - return convert_enum_idx(options, 4, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1350_e_"); + HANDLE_CODE(delta_mcs_enabled_r17.pack(bref)); + + return SRSASN_SUCCESS; } -uint32_t rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1350_opts::to_number() const +SRSASN_CODE ul_pwr_ctrl_ded_nb_v1700_s::unpack(cbit_ref& bref) { - static const uint32_t options[] = {40000, 60000, 90000, 120000}; - return map_enum_number(options, 4, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1350_e_"); -} + HANDLE_CODE(delta_mcs_enabled_r17.unpack(bref)); -const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t301_v1530_opts::to_string() const -{ - static const char* options[] = {"ms80000", "ms100000", "ms120000"}; - return convert_enum_idx(options, 3, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t301_v1530_e_"); + return SRSASN_SUCCESS; } -uint32_t rlf_timers_and_consts_nb_r13_c::setup_s_::t301_v1530_opts::to_number() const +void ul_pwr_ctrl_ded_nb_v1700_s::to_json(json_writer& j) const { - static const uint32_t options[] = {80000, 100000, 120000}; - return map_enum_number(options, 3, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t301_v1530_e_"); + j.start_obj(); + j.write_str("deltaMCS-Enabled-r17", delta_mcs_enabled_r17.to_string()); + j.end_obj(); } -const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1530_opts::to_string() const +const char* ul_pwr_ctrl_ded_nb_v1700_s::delta_mcs_enabled_r17_opts::to_string() const { - static const char* options[] = {"ms160000", "ms200000"}; - return convert_enum_idx(options, 2, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1530_e_"); + static const char* options[] = {"en0", "en1"}; + return convert_enum_idx(options, 2, value, "ul_pwr_ctrl_ded_nb_v1700_s::delta_mcs_enabled_r17_e_"); } -uint32_t rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1530_opts::to_number() const +uint8_t ul_pwr_ctrl_ded_nb_v1700_s::delta_mcs_enabled_r17_opts::to_number() const { - static const uint32_t options[] = {160000, 200000}; - return map_enum_number(options, 2, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1530_e_"); + static const uint8_t options[] = {0, 1}; + return map_enum_number(options, 2, value, "ul_pwr_ctrl_ded_nb_v1700_s::delta_mcs_enabled_r17_e_"); } -// SchedulingRequestConfig-NB-r15 ::= SEQUENCE -SRSASN_CODE sched_request_cfg_nb_r15_s::pack(bit_ref& bref) const +// MAC-MainConfig-NB-r13 ::= SEQUENCE +SRSASN_CODE mac_main_cfg_nb_r13_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(sr_with_harq_ack_cfg_r15_present, 1)); - HANDLE_CODE(bref.pack(sr_without_harq_ack_cfg_r15_present, 1)); - HANDLE_CODE(bref.pack(sr_sps_bsr_cfg_r15_present, 1)); + HANDLE_CODE(bref.pack(ul_sch_cfg_r13_present, 1)); + HANDLE_CODE(bref.pack(drx_cfg_r13_present, 1)); + HANDLE_CODE(bref.pack(lc_ch_sr_cfg_r13_present, 1)); - if (sr_without_harq_ack_cfg_r15_present) { - HANDLE_CODE(sr_without_harq_ack_cfg_r15.pack(bref)); + if (ul_sch_cfg_r13_present) { + HANDLE_CODE(bref.pack(ul_sch_cfg_r13.periodic_bsr_timer_r13_present, 1)); + if (ul_sch_cfg_r13.periodic_bsr_timer_r13_present) { + HANDLE_CODE(ul_sch_cfg_r13.periodic_bsr_timer_r13.pack(bref)); + } + HANDLE_CODE(ul_sch_cfg_r13.retx_bsr_timer_r13.pack(bref)); } - if (sr_sps_bsr_cfg_r15_present) { - HANDLE_CODE(sr_sps_bsr_cfg_r15.pack(bref)); - } - - return SRSASN_SUCCESS; -} -SRSASN_CODE sched_request_cfg_nb_r15_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(sr_with_harq_ack_cfg_r15_present, 1)); - HANDLE_CODE(bref.unpack(sr_without_harq_ack_cfg_r15_present, 1)); - HANDLE_CODE(bref.unpack(sr_sps_bsr_cfg_r15_present, 1)); - - if (sr_without_harq_ack_cfg_r15_present) { - HANDLE_CODE(sr_without_harq_ack_cfg_r15.unpack(bref)); - } - if (sr_sps_bsr_cfg_r15_present) { - HANDLE_CODE(sr_sps_bsr_cfg_r15.unpack(bref)); - } - - return SRSASN_SUCCESS; -} -void sched_request_cfg_nb_r15_s::to_json(json_writer& j) const -{ - j.start_obj(); - if (sr_with_harq_ack_cfg_r15_present) { - j.write_str("sr-WithHARQ-ACK-Config-r15", "true"); - } - if (sr_without_harq_ack_cfg_r15_present) { - j.write_fieldname("sr-WithoutHARQ-ACK-Config-r15"); - sr_without_harq_ack_cfg_r15.to_json(j); - } - if (sr_sps_bsr_cfg_r15_present) { - j.write_fieldname("sr-SPS-BSR-Config-r15"); - sr_sps_bsr_cfg_r15.to_json(j); - } - j.end_obj(); -} - -// RadioResourceConfigDedicated-NB-r13 ::= SEQUENCE -SRSASN_CODE rr_cfg_ded_nb_r13_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(srb_to_add_mod_list_r13_present, 1)); - HANDLE_CODE(bref.pack(drb_to_add_mod_list_r13_present, 1)); - HANDLE_CODE(bref.pack(drb_to_release_list_r13_present, 1)); - HANDLE_CODE(bref.pack(mac_main_cfg_r13_present, 1)); - HANDLE_CODE(bref.pack(phys_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.pack(rlf_timers_and_consts_r13_present, 1)); - - if (srb_to_add_mod_list_r13_present) { - HANDLE_CODE(pack_fixed_seq_of(bref, &(srb_to_add_mod_list_r13)[0], srb_to_add_mod_list_r13.size())); - } - if (drb_to_add_mod_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, drb_to_add_mod_list_r13, 1, 2)); - } - if (drb_to_release_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, drb_to_release_list_r13, 1, 2, integer_packer(1, 32))); - } - if (mac_main_cfg_r13_present) { - HANDLE_CODE(mac_main_cfg_r13.pack(bref)); - } - if (phys_cfg_ded_r13_present) { - HANDLE_CODE(phys_cfg_ded_r13.pack(bref)); - } - if (rlf_timers_and_consts_r13_present) { - HANDLE_CODE(rlf_timers_and_consts_r13.pack(bref)); + if (drx_cfg_r13_present) { + HANDLE_CODE(drx_cfg_r13.pack(bref)); + } + HANDLE_CODE(time_align_timer_ded_r13.pack(bref)); + if (lc_ch_sr_cfg_r13_present) { + HANDLE_CODE(lc_ch_sr_cfg_r13.pack(bref)); } if (ext) { ext_groups_packer_guard group_flags; - group_flags[0] |= sched_request_cfg_r15.is_present(); + group_flags[0] |= rai_activation_r14_present; + group_flags[0] |= data_inactivity_timer_cfg_r14.is_present(); + group_flags[1] |= drx_cycle_v1430_present; + group_flags[2] |= ra_cfra_cfg_r14_present; + group_flags[3] |= offset_thres_ta_r17.is_present(); group_flags.pack(bref); if (group_flags[0]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(sched_request_cfg_r15.is_present(), 1)); - if (sched_request_cfg_r15.is_present()) { - HANDLE_CODE(sched_request_cfg_r15->pack(bref)); + HANDLE_CODE(bref.pack(rai_activation_r14_present, 1)); + HANDLE_CODE(bref.pack(data_inactivity_timer_cfg_r14.is_present(), 1)); + if (data_inactivity_timer_cfg_r14.is_present()) { + HANDLE_CODE(data_inactivity_timer_cfg_r14->pack(bref)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(drx_cycle_v1430_present, 1)); + if (drx_cycle_v1430_present) { + HANDLE_CODE(drx_cycle_v1430.pack(bref)); + } + } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ra_cfra_cfg_r14_present, 1)); + } + if (group_flags[3]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(offset_thres_ta_r17.is_present(), 1)); + if (offset_thres_ta_r17.is_present()) { + HANDLE_CODE(offset_thres_ta_r17->pack(bref)); } } } return SRSASN_SUCCESS; } -SRSASN_CODE rr_cfg_ded_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE mac_main_cfg_nb_r13_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(srb_to_add_mod_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(drb_to_add_mod_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(drb_to_release_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(mac_main_cfg_r13_present, 1)); - HANDLE_CODE(bref.unpack(phys_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.unpack(rlf_timers_and_consts_r13_present, 1)); + HANDLE_CODE(bref.unpack(ul_sch_cfg_r13_present, 1)); + HANDLE_CODE(bref.unpack(drx_cfg_r13_present, 1)); + HANDLE_CODE(bref.unpack(lc_ch_sr_cfg_r13_present, 1)); - if (srb_to_add_mod_list_r13_present) { - HANDLE_CODE(unpack_fixed_seq_of(&(srb_to_add_mod_list_r13)[0], bref, srb_to_add_mod_list_r13.size())); - } - if (drb_to_add_mod_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(drb_to_add_mod_list_r13, bref, 1, 2)); - } - if (drb_to_release_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(drb_to_release_list_r13, bref, 1, 2, integer_packer(1, 32))); - } - if (mac_main_cfg_r13_present) { - HANDLE_CODE(mac_main_cfg_r13.unpack(bref)); + if (ul_sch_cfg_r13_present) { + HANDLE_CODE(bref.unpack(ul_sch_cfg_r13.periodic_bsr_timer_r13_present, 1)); + if (ul_sch_cfg_r13.periodic_bsr_timer_r13_present) { + HANDLE_CODE(ul_sch_cfg_r13.periodic_bsr_timer_r13.unpack(bref)); + } + HANDLE_CODE(ul_sch_cfg_r13.retx_bsr_timer_r13.unpack(bref)); } - if (phys_cfg_ded_r13_present) { - HANDLE_CODE(phys_cfg_ded_r13.unpack(bref)); + if (drx_cfg_r13_present) { + HANDLE_CODE(drx_cfg_r13.unpack(bref)); } - if (rlf_timers_and_consts_r13_present) { - HANDLE_CODE(rlf_timers_and_consts_r13.unpack(bref)); + HANDLE_CODE(time_align_timer_ded_r13.unpack(bref)); + if (lc_ch_sr_cfg_r13_present) { + HANDLE_CODE(lc_ch_sr_cfg_r13.unpack(bref)); } if (ext) { - ext_groups_unpacker_guard group_flags(1); + ext_groups_unpacker_guard group_flags(4); group_flags.unpack(bref); if (group_flags[0]) { varlength_field_unpack_guard varlen_scope(bref, false); - bool sched_request_cfg_r15_present; - HANDLE_CODE(bref.unpack(sched_request_cfg_r15_present, 1)); - sched_request_cfg_r15.set_present(sched_request_cfg_r15_present); - if (sched_request_cfg_r15.is_present()) { - HANDLE_CODE(sched_request_cfg_r15->unpack(bref)); + HANDLE_CODE(bref.unpack(rai_activation_r14_present, 1)); + bool data_inactivity_timer_cfg_r14_present; + HANDLE_CODE(bref.unpack(data_inactivity_timer_cfg_r14_present, 1)); + data_inactivity_timer_cfg_r14.set_present(data_inactivity_timer_cfg_r14_present); + if (data_inactivity_timer_cfg_r14.is_present()) { + HANDLE_CODE(data_inactivity_timer_cfg_r14->unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(drx_cycle_v1430_present, 1)); + if (drx_cycle_v1430_present) { + HANDLE_CODE(drx_cycle_v1430.unpack(bref)); + } + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(ra_cfra_cfg_r14_present, 1)); + } + if (group_flags[3]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool offset_thres_ta_r17_present; + HANDLE_CODE(bref.unpack(offset_thres_ta_r17_present, 1)); + offset_thres_ta_r17.set_present(offset_thres_ta_r17_present); + if (offset_thres_ta_r17.is_present()) { + HANDLE_CODE(offset_thres_ta_r17->unpack(bref)); } } } return SRSASN_SUCCESS; } -void rr_cfg_ded_nb_r13_s::to_json(json_writer& j) const +void mac_main_cfg_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - if (srb_to_add_mod_list_r13_present) { - j.start_array("srb-ToAddModList-r13"); - for (const auto& e1 : srb_to_add_mod_list_r13) { - e1.to_json(j); - } - j.end_array(); - } - if (drb_to_add_mod_list_r13_present) { - j.start_array("drb-ToAddModList-r13"); - for (const auto& e1 : drb_to_add_mod_list_r13) { - e1.to_json(j); - } - j.end_array(); - } - if (drb_to_release_list_r13_present) { - j.start_array("drb-ToReleaseList-r13"); - for (const auto& e1 : drb_to_release_list_r13) { - j.write_int(e1); + if (ul_sch_cfg_r13_present) { + j.write_fieldname("ul-SCH-Config-r13"); + j.start_obj(); + if (ul_sch_cfg_r13.periodic_bsr_timer_r13_present) { + j.write_str("periodicBSR-Timer-r13", ul_sch_cfg_r13.periodic_bsr_timer_r13.to_string()); } - j.end_array(); - } - if (mac_main_cfg_r13_present) { - j.write_fieldname("mac-MainConfig-r13"); - mac_main_cfg_r13.to_json(j); + j.write_str("retxBSR-Timer-r13", ul_sch_cfg_r13.retx_bsr_timer_r13.to_string()); + j.end_obj(); } - if (phys_cfg_ded_r13_present) { - j.write_fieldname("physicalConfigDedicated-r13"); - phys_cfg_ded_r13.to_json(j); + if (drx_cfg_r13_present) { + j.write_fieldname("drx-Config-r13"); + drx_cfg_r13.to_json(j); } - if (rlf_timers_and_consts_r13_present) { - j.write_fieldname("rlf-TimersAndConstants-r13"); - rlf_timers_and_consts_r13.to_json(j); + j.write_str("timeAlignmentTimerDedicated-r13", time_align_timer_ded_r13.to_string()); + if (lc_ch_sr_cfg_r13_present) { + j.write_fieldname("logicalChannelSR-Config-r13"); + lc_ch_sr_cfg_r13.to_json(j); } if (ext) { - if (sched_request_cfg_r15.is_present()) { - j.write_fieldname("schedulingRequestConfig-r15"); - sched_request_cfg_r15->to_json(j); + if (rai_activation_r14_present) { + j.write_str("rai-Activation-r14", "true"); + } + if (data_inactivity_timer_cfg_r14.is_present()) { + j.write_fieldname("dataInactivityTimerConfig-r14"); + data_inactivity_timer_cfg_r14->to_json(j); + } + if (drx_cycle_v1430_present) { + j.write_str("drx-Cycle-v1430", drx_cycle_v1430.to_string()); + } + if (ra_cfra_cfg_r14_present) { + j.write_str("ra-CFRA-Config-r14", "true"); + } + if (offset_thres_ta_r17.is_present()) { + j.write_fieldname("offsetThresholdTA-r17"); + offset_thres_ta_r17->to_json(j); } } j.end_obj(); } -void rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::set(types::options e) +void mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::set(types::options e) { type_ = e; } -mac_main_cfg_nb_r13_s& rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::set_explicit_value_r13() +void mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::set_release() { - set(types::explicit_value_r13); - return c; + set(types::release); } -void rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::set_default_value_r13() +mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::setup_s_& mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::set_setup() { - set(types::default_value_r13); + set(types::setup); + return c; } -void rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::to_json(json_writer& j) const +void mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::explicit_value_r13: - j.write_fieldname("explicitValue-r13"); - c.to_json(j); + case types::release: break; - case types::default_value_r13: + case types::setup: + j.write_fieldname("setup"); + j.start_obj(); + j.write_str("logicalChannelSR-ProhibitTimer-r13", c.lc_ch_sr_prohibit_timer_r13.to_string()); + j.end_obj(); break; default: - log_invalid_choice_id(type_, "rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_"); + log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_"); } j.end_obj(); } -SRSASN_CODE rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::pack(bit_ref& bref) const +SRSASN_CODE mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::explicit_value_r13: - HANDLE_CODE(c.pack(bref)); + case types::release: break; - case types::default_value_r13: + case types::setup: + HANDLE_CODE(c.lc_ch_sr_prohibit_timer_r13.pack(bref)); break; default: - log_invalid_choice_id(type_, "rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_"); + log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::unpack(cbit_ref& bref) +SRSASN_CODE mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::explicit_value_r13: - HANDLE_CODE(c.unpack(bref)); + case types::release: break; - case types::default_value_r13: + case types::setup: + HANDLE_CODE(c.lc_ch_sr_prohibit_timer_r13.unpack(bref)); break; default: - log_invalid_choice_id(type_, "rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_"); + log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::types_opts::to_string() const +const char* mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::setup_s_::lc_ch_sr_prohibit_timer_r13_opts::to_string() const { - static const char* options[] = {"explicitValue-r13", "defaultValue-r13"}; - return convert_enum_idx(options, 2, value, "rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::types"); + static const char* options[] = {"pp2", "pp8", "pp32", "pp128", "pp512", "pp1024", "pp2048", "spare"}; + return convert_enum_idx( + options, 8, value, "mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::setup_s_::lc_ch_sr_prohibit_timer_r13_e_"); } - -// AS-Config-NB ::= SEQUENCE -SRSASN_CODE as_cfg_nb_s::pack(bit_ref& bref) const +uint16_t mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::setup_s_::lc_ch_sr_prohibit_timer_r13_opts::to_number() const { - bref.pack(ext, 1); - HANDLE_CODE(source_rr_cfg_r13.pack(bref)); - HANDLE_CODE(source_security_algorithm_cfg_r13.pack(bref)); - HANDLE_CODE(source_ue_id_r13.pack(bref)); - HANDLE_CODE(source_dl_carrier_freq_r13.pack(bref)); - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= source_dl_carrier_freq_v1550.is_present(); - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(source_dl_carrier_freq_v1550.is_present(), 1)); - if (source_dl_carrier_freq_v1550.is_present()) { - HANDLE_CODE(source_dl_carrier_freq_v1550->pack(bref)); - } - } - } - return SRSASN_SUCCESS; + static const uint16_t options[] = {2, 8, 32, 128, 512, 1024, 2048}; + return map_enum_number( + options, 7, value, "mac_main_cfg_nb_r13_s::lc_ch_sr_cfg_r13_c_::setup_s_::lc_ch_sr_prohibit_timer_r13_e_"); } -SRSASN_CODE as_cfg_nb_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(source_rr_cfg_r13.unpack(bref)); - HANDLE_CODE(source_security_algorithm_cfg_r13.unpack(bref)); - HANDLE_CODE(source_ue_id_r13.unpack(bref)); - HANDLE_CODE(source_dl_carrier_freq_r13.unpack(bref)); - - if (ext) { - ext_groups_unpacker_guard group_flags(1); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); - bool source_dl_carrier_freq_v1550_present; - HANDLE_CODE(bref.unpack(source_dl_carrier_freq_v1550_present, 1)); - source_dl_carrier_freq_v1550.set_present(source_dl_carrier_freq_v1550_present); - if (source_dl_carrier_freq_v1550.is_present()) { - HANDLE_CODE(source_dl_carrier_freq_v1550->unpack(bref)); - } - } - } - return SRSASN_SUCCESS; -} -void as_cfg_nb_s::to_json(json_writer& j) const +void mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::set(types::options e) { - j.start_obj(); - j.write_fieldname("sourceRadioResourceConfig-r13"); - source_rr_cfg_r13.to_json(j); - j.write_fieldname("sourceSecurityAlgorithmConfig-r13"); - source_security_algorithm_cfg_r13.to_json(j); - j.write_str("sourceUE-Identity-r13", source_ue_id_r13.to_string()); - j.write_fieldname("sourceDl-CarrierFreq-r13"); - source_dl_carrier_freq_r13.to_json(j); - if (ext) { - if (source_dl_carrier_freq_v1550.is_present()) { - j.write_fieldname("sourceDL-CarrierFreq-v1550"); - source_dl_carrier_freq_v1550->to_json(j); - } - } - j.end_obj(); + type_ = e; } - -// ReestablishmentInfo-NB ::= SEQUENCE -SRSASN_CODE reest_info_nb_s::pack(bit_ref& bref) const +void mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::set_release() { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(add_reestab_info_list_r13_present, 1)); - - HANDLE_CODE(pack_integer(bref, source_pci_r13, (uint16_t)0u, (uint16_t)503u)); - HANDLE_CODE(target_cell_short_mac_i_r13.pack(bref)); - if (add_reestab_info_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, add_reestab_info_list_r13, 1, 32)); - } - - return SRSASN_SUCCESS; + set(types::release); } -SRSASN_CODE reest_info_nb_s::unpack(cbit_ref& bref) +mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::setup_s_& +mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::set_setup() { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(add_reestab_info_list_r13_present, 1)); - - HANDLE_CODE(unpack_integer(source_pci_r13, bref, (uint16_t)0u, (uint16_t)503u)); - HANDLE_CODE(target_cell_short_mac_i_r13.unpack(bref)); - if (add_reestab_info_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(add_reestab_info_list_r13, bref, 1, 32)); - } - - return SRSASN_SUCCESS; + set(types::setup); + return c; } -void reest_info_nb_s::to_json(json_writer& j) const +void mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::to_json(json_writer& j) const { j.start_obj(); - j.write_int("sourcePhysCellId-r13", source_pci_r13); - j.write_str("targetCellShortMAC-I-r13", target_cell_short_mac_i_r13.to_string()); - if (add_reestab_info_list_r13_present) { - j.start_array("additionalReestabInfoList-r13"); - for (const auto& e1 : add_reestab_info_list_r13) { - e1.to_json(j); - } - j.end_array(); + switch (type_) { + case types::release: + break; + case types::setup: + j.write_fieldname("setup"); + j.start_obj(); + j.write_str("dataInactivityTimer-r14", c.data_inactivity_timer_r14.to_string()); + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_"); } j.end_obj(); } - -// AS-Context-NB ::= SEQUENCE -SRSASN_CODE as_context_nb_s::pack(bit_ref& bref) const +SRSASN_CODE mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(reest_info_r13_present, 1)); - - if (reest_info_r13_present) { - HANDLE_CODE(reest_info_r13.pack(bref)); + type_.pack(bref); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(c.data_inactivity_timer_r14.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_"); + return SRSASN_ERROR_ENCODE_FAIL; } - return SRSASN_SUCCESS; } -SRSASN_CODE as_context_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(reest_info_r13_present, 1)); - - if (reest_info_r13_present) { - HANDLE_CODE(reest_info_r13.unpack(bref)); + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(c.data_inactivity_timer_r14.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "mac_main_cfg_nb_r13_s::data_inactivity_timer_cfg_r14_c_"); + return SRSASN_ERROR_DECODE_FAIL; } - return SRSASN_SUCCESS; } -void as_context_nb_s::to_json(json_writer& j) const -{ - j.start_obj(); - if (reest_info_r13_present) { - j.write_fieldname("reestablishmentInfo-r13"); - reest_info_r13.to_json(j); - } - j.end_obj(); -} -// ChannelRasterOffset-NB-r13 ::= ENUMERATED -const char* ch_raster_offset_nb_r13_opts::to_string() const -{ - static const char* options[] = {"khz-7dot5", "khz-2dot5", "khz2dot5", "khz7dot5"}; - return convert_enum_idx(options, 4, value, "ch_raster_offset_nb_r13_e"); -} -float ch_raster_offset_nb_r13_opts::to_number() const +const char* mac_main_cfg_nb_r13_s::drx_cycle_v1430_opts::to_string() const { - static const float options[] = {-7.5, -2.5, 2.5, 7.5}; - return map_enum_number(options, 4, value, "ch_raster_offset_nb_r13_e"); + static const char* options[] = {"sf1280", "sf2560", "sf5120", "sf10240"}; + return convert_enum_idx(options, 4, value, "mac_main_cfg_nb_r13_s::drx_cycle_v1430_e_"); } -const char* ch_raster_offset_nb_r13_opts::to_number_string() const +uint16_t mac_main_cfg_nb_r13_s::drx_cycle_v1430_opts::to_number() const { - static const char* options[] = {"-7.5", "-2.5", "2.5", "7.5"}; - return convert_enum_idx(options, 4, value, "ch_raster_offset_nb_r13_e"); + static const uint16_t options[] = {1280, 2560, 5120, 10240}; + return map_enum_number(options, 4, value, "mac_main_cfg_nb_r13_s::drx_cycle_v1430_e_"); } -// Guardband-NB-r13 ::= SEQUENCE -SRSASN_CODE guardband_nb_r13_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(raster_offset_r13.pack(bref)); - HANDLE_CODE(spare.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE guardband_nb_r13_s::unpack(cbit_ref& bref) +// PhysicalConfigDedicated-NB-r13 ::= SEQUENCE +SRSASN_CODE phys_cfg_ded_nb_r13_s::pack(bit_ref& bref) const { - HANDLE_CODE(raster_offset_r13.unpack(bref)); - HANDLE_CODE(spare.unpack(bref)); + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(carrier_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.pack(npdcch_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.pack(npusch_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.pack(ul_pwr_ctrl_ded_r13_present, 1)); - return SRSASN_SUCCESS; -} -void guardband_nb_r13_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_str("rasterOffset-r13", raster_offset_r13.to_string()); - j.write_str("spare", spare.to_string()); - j.end_obj(); -} + if (carrier_cfg_ded_r13_present) { + HANDLE_CODE(carrier_cfg_ded_r13.pack(bref)); + } + if (npdcch_cfg_ded_r13_present) { + HANDLE_CODE(npdcch_cfg_ded_r13.pack(bref)); + } + if (npusch_cfg_ded_r13_present) { + HANDLE_CODE(npusch_cfg_ded_r13.pack(bref)); + } + if (ul_pwr_ctrl_ded_r13_present) { + HANDLE_CODE(ul_pwr_ctrl_ded_r13.pack(bref)); + } -// Inband-DifferentPCI-NB-r13 ::= SEQUENCE -SRSASN_CODE inband_different_pci_nb_r13_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(eutra_num_crs_ports_r13.pack(bref)); - HANDLE_CODE(raster_offset_r13.pack(bref)); - HANDLE_CODE(spare.pack(bref)); + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= two_harq_processes_cfg_r14_present; + group_flags[1] |= interference_randomisation_cfg_r14_present; + group_flags[2] |= npdcch_cfg_ded_v1530.is_present(); + group_flags[3] |= add_tx_sib1_cfg_v1540_present; + group_flags[4] |= npusch_cfg_ded_v1610.is_present(); + group_flags[4] |= npdsch_cfg_ded_r16.is_present(); + group_flags[4] |= res_reserv_cfg_dl_r16.is_present(); + group_flags[4] |= res_reserv_cfg_ul_r16.is_present(); + group_flags[5] |= ntn_cfg_ded_r17.is_present(); + group_flags[5] |= npdsch_cfg_ded_v1700.is_present(); + group_flags[5] |= ul_pwr_ctrl_ded_v1700.is_present(); + group_flags[6] |= ul_segmented_precompensation_gap_r17_present; + group_flags[7] |= npusch_cfg_ded_v1740.is_present(); + group_flags.pack(bref); + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(two_harq_processes_cfg_r14_present, 1)); + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(interference_randomisation_cfg_r14_present, 1)); + } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(npdcch_cfg_ded_v1530.is_present(), 1)); + if (npdcch_cfg_ded_v1530.is_present()) { + HANDLE_CODE(npdcch_cfg_ded_v1530->pack(bref)); + } + } + if (group_flags[3]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(add_tx_sib1_cfg_v1540_present, 1)); + } + if (group_flags[4]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(npusch_cfg_ded_v1610.is_present(), 1)); + HANDLE_CODE(bref.pack(npdsch_cfg_ded_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(res_reserv_cfg_dl_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(res_reserv_cfg_ul_r16.is_present(), 1)); + if (npusch_cfg_ded_v1610.is_present()) { + HANDLE_CODE(npusch_cfg_ded_v1610->pack(bref)); + } + if (npdsch_cfg_ded_r16.is_present()) { + HANDLE_CODE(npdsch_cfg_ded_r16->pack(bref)); + } + if (res_reserv_cfg_dl_r16.is_present()) { + HANDLE_CODE(res_reserv_cfg_dl_r16->pack(bref)); + } + if (res_reserv_cfg_ul_r16.is_present()) { + HANDLE_CODE(res_reserv_cfg_ul_r16->pack(bref)); + } + } + if (group_flags[5]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ntn_cfg_ded_r17.is_present(), 1)); + HANDLE_CODE(bref.pack(npdsch_cfg_ded_v1700.is_present(), 1)); + HANDLE_CODE(bref.pack(ul_pwr_ctrl_ded_v1700.is_present(), 1)); + if (ntn_cfg_ded_r17.is_present()) { + HANDLE_CODE(ntn_cfg_ded_r17->npusch_tx_dur_r17.pack(bref)); + } + if (npdsch_cfg_ded_v1700.is_present()) { + HANDLE_CODE(npdsch_cfg_ded_v1700->pack(bref)); + } + if (ul_pwr_ctrl_ded_v1700.is_present()) { + HANDLE_CODE(ul_pwr_ctrl_ded_v1700->pack(bref)); + } + } + if (group_flags[6]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ul_segmented_precompensation_gap_r17_present, 1)); + if (ul_segmented_precompensation_gap_r17_present) { + HANDLE_CODE(ul_segmented_precompensation_gap_r17.pack(bref)); + } + } + if (group_flags[7]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(npusch_cfg_ded_v1740.is_present(), 1)); + if (npusch_cfg_ded_v1740.is_present()) { + HANDLE_CODE(npusch_cfg_ded_v1740->pack(bref)); + } + } + } return SRSASN_SUCCESS; } -SRSASN_CODE inband_different_pci_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE phys_cfg_ded_nb_r13_s::unpack(cbit_ref& bref) { - HANDLE_CODE(eutra_num_crs_ports_r13.unpack(bref)); - HANDLE_CODE(raster_offset_r13.unpack(bref)); - HANDLE_CODE(spare.unpack(bref)); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(carrier_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.unpack(npdcch_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.unpack(npusch_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.unpack(ul_pwr_ctrl_ded_r13_present, 1)); + + if (carrier_cfg_ded_r13_present) { + HANDLE_CODE(carrier_cfg_ded_r13.unpack(bref)); + } + if (npdcch_cfg_ded_r13_present) { + HANDLE_CODE(npdcch_cfg_ded_r13.unpack(bref)); + } + if (npusch_cfg_ded_r13_present) { + HANDLE_CODE(npusch_cfg_ded_r13.unpack(bref)); + } + if (ul_pwr_ctrl_ded_r13_present) { + HANDLE_CODE(ul_pwr_ctrl_ded_r13.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(8); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(two_harq_processes_cfg_r14_present, 1)); + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(interference_randomisation_cfg_r14_present, 1)); + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool npdcch_cfg_ded_v1530_present; + HANDLE_CODE(bref.unpack(npdcch_cfg_ded_v1530_present, 1)); + npdcch_cfg_ded_v1530.set_present(npdcch_cfg_ded_v1530_present); + if (npdcch_cfg_ded_v1530.is_present()) { + HANDLE_CODE(npdcch_cfg_ded_v1530->unpack(bref)); + } + } + if (group_flags[3]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(add_tx_sib1_cfg_v1540_present, 1)); + } + if (group_flags[4]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool npusch_cfg_ded_v1610_present; + HANDLE_CODE(bref.unpack(npusch_cfg_ded_v1610_present, 1)); + npusch_cfg_ded_v1610.set_present(npusch_cfg_ded_v1610_present); + bool npdsch_cfg_ded_r16_present; + HANDLE_CODE(bref.unpack(npdsch_cfg_ded_r16_present, 1)); + npdsch_cfg_ded_r16.set_present(npdsch_cfg_ded_r16_present); + bool res_reserv_cfg_dl_r16_present; + HANDLE_CODE(bref.unpack(res_reserv_cfg_dl_r16_present, 1)); + res_reserv_cfg_dl_r16.set_present(res_reserv_cfg_dl_r16_present); + bool res_reserv_cfg_ul_r16_present; + HANDLE_CODE(bref.unpack(res_reserv_cfg_ul_r16_present, 1)); + res_reserv_cfg_ul_r16.set_present(res_reserv_cfg_ul_r16_present); + if (npusch_cfg_ded_v1610.is_present()) { + HANDLE_CODE(npusch_cfg_ded_v1610->unpack(bref)); + } + if (npdsch_cfg_ded_r16.is_present()) { + HANDLE_CODE(npdsch_cfg_ded_r16->unpack(bref)); + } + if (res_reserv_cfg_dl_r16.is_present()) { + HANDLE_CODE(res_reserv_cfg_dl_r16->unpack(bref)); + } + if (res_reserv_cfg_ul_r16.is_present()) { + HANDLE_CODE(res_reserv_cfg_ul_r16->unpack(bref)); + } + } + if (group_flags[5]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool ntn_cfg_ded_r17_present; + HANDLE_CODE(bref.unpack(ntn_cfg_ded_r17_present, 1)); + ntn_cfg_ded_r17.set_present(ntn_cfg_ded_r17_present); + bool npdsch_cfg_ded_v1700_present; + HANDLE_CODE(bref.unpack(npdsch_cfg_ded_v1700_present, 1)); + npdsch_cfg_ded_v1700.set_present(npdsch_cfg_ded_v1700_present); + bool ul_pwr_ctrl_ded_v1700_present; + HANDLE_CODE(bref.unpack(ul_pwr_ctrl_ded_v1700_present, 1)); + ul_pwr_ctrl_ded_v1700.set_present(ul_pwr_ctrl_ded_v1700_present); + if (ntn_cfg_ded_r17.is_present()) { + HANDLE_CODE(ntn_cfg_ded_r17->npusch_tx_dur_r17.unpack(bref)); + } + if (npdsch_cfg_ded_v1700.is_present()) { + HANDLE_CODE(npdsch_cfg_ded_v1700->unpack(bref)); + } + if (ul_pwr_ctrl_ded_v1700.is_present()) { + HANDLE_CODE(ul_pwr_ctrl_ded_v1700->unpack(bref)); + } + } + if (group_flags[6]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(ul_segmented_precompensation_gap_r17_present, 1)); + if (ul_segmented_precompensation_gap_r17_present) { + HANDLE_CODE(ul_segmented_precompensation_gap_r17.unpack(bref)); + } + } + if (group_flags[7]) { + varlength_field_unpack_guard varlen_scope(bref, false); + bool npusch_cfg_ded_v1740_present; + HANDLE_CODE(bref.unpack(npusch_cfg_ded_v1740_present, 1)); + npusch_cfg_ded_v1740.set_present(npusch_cfg_ded_v1740_present); + if (npusch_cfg_ded_v1740.is_present()) { + HANDLE_CODE(npusch_cfg_ded_v1740->unpack(bref)); + } + } + } return SRSASN_SUCCESS; } -void inband_different_pci_nb_r13_s::to_json(json_writer& j) const +void phys_cfg_ded_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("eutra-NumCRS-Ports-r13", eutra_num_crs_ports_r13.to_string()); - j.write_str("rasterOffset-r13", raster_offset_r13.to_string()); - j.write_str("spare", spare.to_string()); + if (carrier_cfg_ded_r13_present) { + j.write_fieldname("carrierConfigDedicated-r13"); + carrier_cfg_ded_r13.to_json(j); + } + if (npdcch_cfg_ded_r13_present) { + j.write_fieldname("npdcch-ConfigDedicated-r13"); + npdcch_cfg_ded_r13.to_json(j); + } + if (npusch_cfg_ded_r13_present) { + j.write_fieldname("npusch-ConfigDedicated-r13"); + npusch_cfg_ded_r13.to_json(j); + } + if (ul_pwr_ctrl_ded_r13_present) { + j.write_fieldname("uplinkPowerControlDedicated-r13"); + ul_pwr_ctrl_ded_r13.to_json(j); + } + if (ext) { + if (two_harq_processes_cfg_r14_present) { + j.write_str("twoHARQ-ProcessesConfig-r14", "true"); + } + if (interference_randomisation_cfg_r14_present) { + j.write_str("interferenceRandomisationConfig-r14", "true"); + } + if (npdcch_cfg_ded_v1530.is_present()) { + j.write_fieldname("npdcch-ConfigDedicated-v1530"); + npdcch_cfg_ded_v1530->to_json(j); + } + if (add_tx_sib1_cfg_v1540_present) { + j.write_str("additionalTxSIB1-Config-v1540", "true"); + } + if (npusch_cfg_ded_v1610.is_present()) { + j.write_fieldname("npusch-ConfigDedicated-v1610"); + npusch_cfg_ded_v1610->to_json(j); + } + if (npdsch_cfg_ded_r16.is_present()) { + j.write_fieldname("npdsch-ConfigDedicated-r16"); + npdsch_cfg_ded_r16->to_json(j); + } + if (res_reserv_cfg_dl_r16.is_present()) { + j.write_fieldname("resourceReservationConfigDL-r16"); + res_reserv_cfg_dl_r16->to_json(j); + } + if (res_reserv_cfg_ul_r16.is_present()) { + j.write_fieldname("resourceReservationConfigUL-r16"); + res_reserv_cfg_ul_r16->to_json(j); + } + if (ntn_cfg_ded_r17.is_present()) { + j.write_fieldname("ntn-ConfigDedicated-r17"); + j.start_obj(); + j.write_fieldname("npusch-TxDuration-r17"); + ntn_cfg_ded_r17->npusch_tx_dur_r17.to_json(j); + j.end_obj(); + } + if (npdsch_cfg_ded_v1700.is_present()) { + j.write_fieldname("npdsch-ConfigDedicated-v1700"); + npdsch_cfg_ded_v1700->to_json(j); + } + if (ul_pwr_ctrl_ded_v1700.is_present()) { + j.write_fieldname("uplinkPowerControlDedicated-v1700"); + ul_pwr_ctrl_ded_v1700->to_json(j); + } + if (ul_segmented_precompensation_gap_r17_present) { + j.write_str("uplinkSegmentedPrecompensationGap-r17", ul_segmented_precompensation_gap_r17.to_string()); + } + if (npusch_cfg_ded_v1740.is_present()) { + j.write_fieldname("npusch-ConfigDedicated-v1740"); + npusch_cfg_ded_v1740->to_json(j); + } + } j.end_obj(); } -const char* inband_different_pci_nb_r13_s::eutra_num_crs_ports_r13_opts::to_string() const +const char* phys_cfg_ded_nb_r13_s::ul_segmented_precompensation_gap_r17_opts::to_string() const { - static const char* options[] = {"same", "four"}; - return convert_enum_idx(options, 2, value, "inband_different_pci_nb_r13_s::eutra_num_crs_ports_r13_e_"); + static const char* options[] = {"sym1", "sl1", "sl2"}; + return convert_enum_idx(options, 3, value, "phys_cfg_ded_nb_r13_s::ul_segmented_precompensation_gap_r17_e_"); } -uint8_t inband_different_pci_nb_r13_s::eutra_num_crs_ports_r13_opts::to_number() const + +// RLF-TimersAndConstants-NB-r13 ::= CHOICE +void rlf_timers_and_consts_nb_r13_c::set(types::options e) { - if (value == four) { - return 4; - } - invalid_enum_number(value, "inband_different_pci_nb_r13_s::eutra_num_crs_ports_r13_e_"); - return 0; + type_ = e; } - -// Inband-SamePCI-NB-r13 ::= SEQUENCE -SRSASN_CODE inband_same_pci_nb_r13_s::pack(bit_ref& bref) const +void rlf_timers_and_consts_nb_r13_c::set_release() { - HANDLE_CODE(pack_integer(bref, eutra_crs_seq_info_r13, (uint8_t)0u, (uint8_t)31u)); - - return SRSASN_SUCCESS; + set(types::release); } -SRSASN_CODE inband_same_pci_nb_r13_s::unpack(cbit_ref& bref) +rlf_timers_and_consts_nb_r13_c::setup_s_& rlf_timers_and_consts_nb_r13_c::set_setup() { - HANDLE_CODE(unpack_integer(eutra_crs_seq_info_r13, bref, (uint8_t)0u, (uint8_t)31u)); - - return SRSASN_SUCCESS; + set(types::setup); + return c; } -void inband_same_pci_nb_r13_s::to_json(json_writer& j) const +void rlf_timers_and_consts_nb_r13_c::to_json(json_writer& j) const { j.start_obj(); - j.write_int("eutra-CRS-SequenceInfo-r13", eutra_crs_seq_info_r13); + switch (type_) { + case types::release: + break; + case types::setup: + j.write_fieldname("setup"); + c.to_json(j); + break; + default: + log_invalid_choice_id(type_, "rlf_timers_and_consts_nb_r13_c"); + } j.end_obj(); } - -// Standalone-NB-r13 ::= SEQUENCE -SRSASN_CODE standalone_nb_r13_s::pack(bit_ref& bref) const +SRSASN_CODE rlf_timers_and_consts_nb_r13_c::pack(bit_ref& bref) const { - HANDLE_CODE(spare.pack(bref)); - + type_.pack(bref); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(c.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "rlf_timers_and_consts_nb_r13_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } return SRSASN_SUCCESS; } -SRSASN_CODE standalone_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE rlf_timers_and_consts_nb_r13_c::unpack(cbit_ref& bref) { - HANDLE_CODE(spare.unpack(bref)); - + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::release: + break; + case types::setup: + HANDLE_CODE(c.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "rlf_timers_and_consts_nb_r13_c"); + return SRSASN_ERROR_DECODE_FAIL; + } return SRSASN_SUCCESS; } -void standalone_nb_r13_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_str("spare", spare.to_string()); - j.end_obj(); -} -// MasterInformationBlock-NB ::= SEQUENCE -SRSASN_CODE mib_nb_s::pack(bit_ref& bref) const +SRSASN_CODE rlf_timers_and_consts_nb_r13_c::setup_s_::pack(bit_ref& bref) const { - HANDLE_CODE(sys_frame_num_msb_r13.pack(bref)); - HANDLE_CODE(hyper_sfn_lsb_r13.pack(bref)); - HANDLE_CODE(pack_integer(bref, sched_info_sib1_r13, (uint8_t)0u, (uint8_t)15u)); - HANDLE_CODE(pack_integer(bref, sys_info_value_tag_r13, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(bref.pack(ab_enabled_r13, 1)); - HANDLE_CODE(operation_mode_info_r13.pack(bref)); - HANDLE_CODE(bref.pack(add_tx_sib1_r15, 1)); - HANDLE_CODE(spare.pack(bref)); + bref.pack(ext, 1); + HANDLE_CODE(t301_r13.pack(bref)); + HANDLE_CODE(t310_r13.pack(bref)); + HANDLE_CODE(n310_r13.pack(bref)); + HANDLE_CODE(t311_r13.pack(bref)); + HANDLE_CODE(n311_r13.pack(bref)); + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= t311_v1350_present; + group_flags[1] |= t301_v1530_present; + group_flags[1] |= t311_v1530_present; + group_flags.pack(bref); + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(t311_v1350_present, 1)); + if (t311_v1350_present) { + HANDLE_CODE(t311_v1350.pack(bref)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(t301_v1530_present, 1)); + HANDLE_CODE(bref.pack(t311_v1530_present, 1)); + if (t301_v1530_present) { + HANDLE_CODE(t301_v1530.pack(bref)); + } + if (t311_v1530_present) { + HANDLE_CODE(t311_v1530.pack(bref)); + } + } + } return SRSASN_SUCCESS; } -SRSASN_CODE mib_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rlf_timers_and_consts_nb_r13_c::setup_s_::unpack(cbit_ref& bref) { - HANDLE_CODE(sys_frame_num_msb_r13.unpack(bref)); - HANDLE_CODE(hyper_sfn_lsb_r13.unpack(bref)); - HANDLE_CODE(unpack_integer(sched_info_sib1_r13, bref, (uint8_t)0u, (uint8_t)15u)); - HANDLE_CODE(unpack_integer(sys_info_value_tag_r13, bref, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(bref.unpack(ab_enabled_r13, 1)); - HANDLE_CODE(operation_mode_info_r13.unpack(bref)); - HANDLE_CODE(bref.unpack(add_tx_sib1_r15, 1)); - HANDLE_CODE(spare.unpack(bref)); + bref.unpack(ext, 1); + HANDLE_CODE(t301_r13.unpack(bref)); + HANDLE_CODE(t310_r13.unpack(bref)); + HANDLE_CODE(n310_r13.unpack(bref)); + HANDLE_CODE(t311_r13.unpack(bref)); + HANDLE_CODE(n311_r13.unpack(bref)); + + if (ext) { + ext_groups_unpacker_guard group_flags(2); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(t311_v1350_present, 1)); + if (t311_v1350_present) { + HANDLE_CODE(t311_v1350.unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(bref.unpack(t301_v1530_present, 1)); + HANDLE_CODE(bref.unpack(t311_v1530_present, 1)); + if (t301_v1530_present) { + HANDLE_CODE(t301_v1530.unpack(bref)); + } + if (t311_v1530_present) { + HANDLE_CODE(t311_v1530.unpack(bref)); + } + } + } return SRSASN_SUCCESS; } -void mib_nb_s::to_json(json_writer& j) const +void rlf_timers_and_consts_nb_r13_c::setup_s_::to_json(json_writer& j) const { j.start_obj(); - j.write_str("systemFrameNumber-MSB-r13", sys_frame_num_msb_r13.to_string()); - j.write_str("hyperSFN-LSB-r13", hyper_sfn_lsb_r13.to_string()); - j.write_int("schedulingInfoSIB1-r13", sched_info_sib1_r13); - j.write_int("systemInfoValueTag-r13", sys_info_value_tag_r13); - j.write_bool("ab-Enabled-r13", ab_enabled_r13); - j.write_fieldname("operationModeInfo-r13"); - operation_mode_info_r13.to_json(j); - j.write_bool("additionalTransmissionSIB1-r15", add_tx_sib1_r15); - j.write_str("spare", spare.to_string()); + j.write_str("t301-r13", t301_r13.to_string()); + j.write_str("t310-r13", t310_r13.to_string()); + j.write_str("n310-r13", n310_r13.to_string()); + j.write_str("t311-r13", t311_r13.to_string()); + j.write_str("n311-r13", n311_r13.to_string()); + if (ext) { + if (t311_v1350_present) { + j.write_str("t311-v1350", t311_v1350.to_string()); + } + if (t301_v1530_present) { + j.write_str("t301-v1530", t301_v1530.to_string()); + } + if (t311_v1530_present) { + j.write_str("t311-v1530", t311_v1530.to_string()); + } + } j.end_obj(); } -void mib_nb_s::operation_mode_info_r13_c_::destroy_() +const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t301_r13_opts::to_string() const { - switch (type_) { - case types::inband_same_pci_r13: - c.destroy(); - break; - case types::inband_different_pci_r13: - c.destroy(); - break; - case types::guardband_r13: - c.destroy(); - break; - case types::standalone_r13: - c.destroy(); - break; - default: - break; - } + static const char* options[] = {"ms2500", "ms4000", "ms6000", "ms10000", "ms15000", "ms25000", "ms40000", "ms60000"}; + return convert_enum_idx(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t301_r13_e_"); } -void mib_nb_s::operation_mode_info_r13_c_::set(types::options e) +uint16_t rlf_timers_and_consts_nb_r13_c::setup_s_::t301_r13_opts::to_number() const { - destroy_(); - type_ = e; - switch (type_) { - case types::inband_same_pci_r13: - c.init(); - break; - case types::inband_different_pci_r13: - c.init(); - break; - case types::guardband_r13: - c.init(); - break; - case types::standalone_r13: - c.init(); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); - } + static const uint16_t options[] = {2500, 4000, 6000, 10000, 15000, 25000, 40000, 60000}; + return map_enum_number(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t301_r13_e_"); } -mib_nb_s::operation_mode_info_r13_c_::operation_mode_info_r13_c_(const mib_nb_s::operation_mode_info_r13_c_& other) + +const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t310_r13_opts::to_string() const { - type_ = other.type(); - switch (type_) { - case types::inband_same_pci_r13: - c.init(other.c.get()); - break; - case types::inband_different_pci_r13: - c.init(other.c.get()); - break; - case types::guardband_r13: - c.init(other.c.get()); - break; - case types::standalone_r13: - c.init(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); - } + static const char* options[] = {"ms0", "ms200", "ms500", "ms1000", "ms2000", "ms4000", "ms8000"}; + return convert_enum_idx(options, 7, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t310_r13_e_"); } -mib_nb_s::operation_mode_info_r13_c_& -mib_nb_s::operation_mode_info_r13_c_::operator=(const mib_nb_s::operation_mode_info_r13_c_& other) +uint16_t rlf_timers_and_consts_nb_r13_c::setup_s_::t310_r13_opts::to_number() const { - if (this == &other) { - return *this; - } - set(other.type()); - switch (type_) { - case types::inband_same_pci_r13: - c.set(other.c.get()); - break; - case types::inband_different_pci_r13: - c.set(other.c.get()); - break; - case types::guardband_r13: - c.set(other.c.get()); - break; - case types::standalone_r13: - c.set(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); - } - - return *this; + static const uint16_t options[] = {0, 200, 500, 1000, 2000, 4000, 8000}; + return map_enum_number(options, 7, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t310_r13_e_"); } -inband_same_pci_nb_r13_s& mib_nb_s::operation_mode_info_r13_c_::set_inband_same_pci_r13() + +const char* rlf_timers_and_consts_nb_r13_c::setup_s_::n310_r13_opts::to_string() const { - set(types::inband_same_pci_r13); - return c.get(); + static const char* options[] = {"n1", "n2", "n3", "n4", "n6", "n8", "n10", "n20"}; + return convert_enum_idx(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::n310_r13_e_"); } -inband_different_pci_nb_r13_s& mib_nb_s::operation_mode_info_r13_c_::set_inband_different_pci_r13() +uint8_t rlf_timers_and_consts_nb_r13_c::setup_s_::n310_r13_opts::to_number() const { - set(types::inband_different_pci_r13); - return c.get(); + static const uint8_t options[] = {1, 2, 3, 4, 6, 8, 10, 20}; + return map_enum_number(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::n310_r13_e_"); } -guardband_nb_r13_s& mib_nb_s::operation_mode_info_r13_c_::set_guardband_r13() + +const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t311_r13_opts::to_string() const { - set(types::guardband_r13); - return c.get(); + static const char* options[] = {"ms1000", "ms3000", "ms5000", "ms10000", "ms15000", "ms20000", "ms30000"}; + return convert_enum_idx(options, 7, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_r13_e_"); } -standalone_nb_r13_s& mib_nb_s::operation_mode_info_r13_c_::set_standalone_r13() +uint16_t rlf_timers_and_consts_nb_r13_c::setup_s_::t311_r13_opts::to_number() const { - set(types::standalone_r13); - return c.get(); + static const uint16_t options[] = {1000, 3000, 5000, 10000, 15000, 20000, 30000}; + return map_enum_number(options, 7, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_r13_e_"); } -void mib_nb_s::operation_mode_info_r13_c_::to_json(json_writer& j) const + +const char* rlf_timers_and_consts_nb_r13_c::setup_s_::n311_r13_opts::to_string() const { - j.start_obj(); - switch (type_) { - case types::inband_same_pci_r13: - j.write_fieldname("inband-SamePCI-r13"); - c.get().to_json(j); - break; - case types::inband_different_pci_r13: - j.write_fieldname("inband-DifferentPCI-r13"); - c.get().to_json(j); - break; - case types::guardband_r13: - j.write_fieldname("guardband-r13"); - c.get().to_json(j); - break; - case types::standalone_r13: - j.write_fieldname("standalone-r13"); - c.get().to_json(j); - break; - default: - log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); - } - j.end_obj(); + static const char* options[] = {"n1", "n2", "n3", "n4", "n5", "n6", "n8", "n10"}; + return convert_enum_idx(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::n311_r13_e_"); } -SRSASN_CODE mib_nb_s::operation_mode_info_r13_c_::pack(bit_ref& bref) const -{ - type_.pack(bref); - switch (type_) { - case types::inband_same_pci_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::inband_different_pci_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::guardband_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::standalone_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - default: - log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); - return SRSASN_ERROR_ENCODE_FAIL; - } - return SRSASN_SUCCESS; -} -SRSASN_CODE mib_nb_s::operation_mode_info_r13_c_::unpack(cbit_ref& bref) +uint8_t rlf_timers_and_consts_nb_r13_c::setup_s_::n311_r13_opts::to_number() const { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::inband_same_pci_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::inband_different_pci_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::guardband_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::standalone_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - default: - log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; + static const uint8_t options[] = {1, 2, 3, 4, 5, 6, 8, 10}; + return map_enum_number(options, 8, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::n311_r13_e_"); } -const char* mib_nb_s::operation_mode_info_r13_c_::types_opts::to_string() const -{ - static const char* options[] = {"inband-SamePCI-r13", "inband-DifferentPCI-r13", "guardband-r13", "standalone-r13"}; - return convert_enum_idx(options, 4, value, "mib_nb_s::operation_mode_info_r13_c_::types"); -} -uint8_t mib_nb_s::operation_mode_info_r13_c_::types_opts::to_number() const +const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1350_opts::to_string() const { - if (value == standalone_r13) { - return 1; - } - invalid_enum_number(value, "mib_nb_s::operation_mode_info_r13_c_::types"); - return 0; + static const char* options[] = {"ms40000", "ms60000", "ms90000", "ms120000"}; + return convert_enum_idx(options, 4, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1350_e_"); } - -// BCCH-BCH-Message-NB ::= SEQUENCE -SRSASN_CODE bcch_bch_msg_nb_s::pack(bit_ref& bref) const +uint32_t rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1350_opts::to_number() const { - HANDLE_CODE(msg.pack(bref)); - - bref.align_bytes_zero(); - - return SRSASN_SUCCESS; + static const uint32_t options[] = {40000, 60000, 90000, 120000}; + return map_enum_number(options, 4, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1350_e_"); } -SRSASN_CODE bcch_bch_msg_nb_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(msg.unpack(bref)); - - bref.align_bytes(); - return SRSASN_SUCCESS; -} -void bcch_bch_msg_nb_s::to_json(json_writer& j) const +const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t301_v1530_opts::to_string() const { - j.start_array(); - j.start_obj(); - j.start_obj("BCCH-BCH-Message-NB"); - j.write_fieldname("message"); - msg.to_json(j); - j.end_obj(); - j.end_obj(); - j.end_array(); + static const char* options[] = {"ms80000", "ms100000", "ms120000"}; + return convert_enum_idx(options, 3, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t301_v1530_e_"); } - -// SIB-GuardbandAnchorTDD-NB-r15 ::= SEQUENCE -SRSASN_CODE sib_guardband_anchor_tdd_nb_r15_s::pack(bit_ref& bref) const +uint32_t rlf_timers_and_consts_nb_r13_c::setup_s_::t301_v1530_opts::to_number() const { - HANDLE_CODE(spare.pack(bref)); - - return SRSASN_SUCCESS; + static const uint32_t options[] = {80000, 100000, 120000}; + return map_enum_number(options, 3, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t301_v1530_e_"); } -SRSASN_CODE sib_guardband_anchor_tdd_nb_r15_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(spare.unpack(bref)); - return SRSASN_SUCCESS; -} -void sib_guardband_anchor_tdd_nb_r15_s::to_json(json_writer& j) const +const char* rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1530_opts::to_string() const { - j.start_obj(); - j.write_str("spare", spare.to_string()); - j.end_obj(); + static const char* options[] = {"ms160000", "ms200000"}; + return convert_enum_idx(options, 2, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1530_e_"); } - -// SIB-GuardbandGuardbandTDD-NB-r15 ::= SEQUENCE -SRSASN_CODE sib_guardband_guardband_tdd_nb_r15_s::pack(bit_ref& bref) const +uint32_t rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1530_opts::to_number() const { - HANDLE_CODE(sib_guardband_guardband_location_r15.pack(bref)); - - return SRSASN_SUCCESS; + static const uint32_t options[] = {160000, 200000}; + return map_enum_number(options, 2, value, "rlf_timers_and_consts_nb_r13_c::setup_s_::t311_v1530_e_"); } -SRSASN_CODE sib_guardband_guardband_tdd_nb_r15_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(sib_guardband_guardband_location_r15.unpack(bref)); - return SRSASN_SUCCESS; -} -void sib_guardband_guardband_tdd_nb_r15_s::to_json(json_writer& j) const +// SchedulingRequestConfig-NB-r15 ::= SEQUENCE +SRSASN_CODE sched_request_cfg_nb_r15_s::pack(bit_ref& bref) const { - j.start_obj(); - j.write_str("sib-GuardbandGuardbandLocation-r15", sib_guardband_guardband_location_r15.to_string()); - j.end_obj(); -} + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(sr_with_harq_ack_cfg_r15_present, 1)); + HANDLE_CODE(bref.pack(sr_without_harq_ack_cfg_r15_present, 1)); + HANDLE_CODE(bref.pack(sr_sps_bsr_cfg_r15_present, 1)); -const char* sib_guardband_guardband_tdd_nb_r15_s::sib_guardband_guardband_location_r15_opts::to_string() const -{ - static const char* options[] = {"same", "opposite"}; - return convert_enum_idx( - options, 2, value, "sib_guardband_guardband_tdd_nb_r15_s::sib_guardband_guardband_location_r15_e_"); -} + if (sr_without_harq_ack_cfg_r15_present) { + HANDLE_CODE(sr_without_harq_ack_cfg_r15.pack(bref)); + } + if (sr_sps_bsr_cfg_r15_present) { + HANDLE_CODE(sr_sps_bsr_cfg_r15.pack(bref)); + } -// SIB-GuardbandInbandDiffPCI-TDD-NB-r15 ::= SEQUENCE -SRSASN_CODE sib_guardband_inband_diff_pci_tdd_nb_r15_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(sib_eutra_num_crs_ports_r15.pack(bref)); + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= sr_without_harq_ack_cfg_v1700.is_present(); + group_flags.pack(bref); - return SRSASN_SUCCESS; -} -SRSASN_CODE sib_guardband_inband_diff_pci_tdd_nb_r15_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(sib_eutra_num_crs_ports_r15.unpack(bref)); + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(bref.pack(sr_without_harq_ack_cfg_v1700.is_present(), 1)); + if (sr_without_harq_ack_cfg_v1700.is_present()) { + HANDLE_CODE(sr_without_harq_ack_cfg_v1700->pack(bref)); + } + } + } return SRSASN_SUCCESS; } -void sib_guardband_inband_diff_pci_tdd_nb_r15_s::to_json(json_writer& j) const +SRSASN_CODE sched_request_cfg_nb_r15_s::unpack(cbit_ref& bref) { - j.start_obj(); - j.write_str("sib-EUTRA-NumCRS-Ports-r15", sib_eutra_num_crs_ports_r15.to_string()); - j.end_obj(); -} + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(sr_with_harq_ack_cfg_r15_present, 1)); + HANDLE_CODE(bref.unpack(sr_without_harq_ack_cfg_r15_present, 1)); + HANDLE_CODE(bref.unpack(sr_sps_bsr_cfg_r15_present, 1)); -const char* sib_guardband_inband_diff_pci_tdd_nb_r15_s::sib_eutra_num_crs_ports_r15_opts::to_string() const -{ - static const char* options[] = {"same", "four"}; - return convert_enum_idx( - options, 2, value, "sib_guardband_inband_diff_pci_tdd_nb_r15_s::sib_eutra_num_crs_ports_r15_e_"); -} -uint8_t sib_guardband_inband_diff_pci_tdd_nb_r15_s::sib_eutra_num_crs_ports_r15_opts::to_number() const -{ - if (value == four) { - return 4; + if (sr_without_harq_ack_cfg_r15_present) { + HANDLE_CODE(sr_without_harq_ack_cfg_r15.unpack(bref)); + } + if (sr_sps_bsr_cfg_r15_present) { + HANDLE_CODE(sr_sps_bsr_cfg_r15.unpack(bref)); } - invalid_enum_number(value, "sib_guardband_inband_diff_pci_tdd_nb_r15_s::sib_eutra_num_crs_ports_r15_e_"); - return 0; -} -// SIB-GuardbandInbandSamePCI-TDD-NB-r15 ::= SEQUENCE -SRSASN_CODE sib_guardband_inband_same_pci_tdd_nb_r15_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(spare.pack(bref)); + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); - return SRSASN_SUCCESS; -} -SRSASN_CODE sib_guardband_inband_same_pci_tdd_nb_r15_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(spare.unpack(bref)); + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + bool sr_without_harq_ack_cfg_v1700_present; + HANDLE_CODE(bref.unpack(sr_without_harq_ack_cfg_v1700_present, 1)); + sr_without_harq_ack_cfg_v1700.set_present(sr_without_harq_ack_cfg_v1700_present); + if (sr_without_harq_ack_cfg_v1700.is_present()) { + HANDLE_CODE(sr_without_harq_ack_cfg_v1700->unpack(bref)); + } + } + } return SRSASN_SUCCESS; } -void sib_guardband_inband_same_pci_tdd_nb_r15_s::to_json(json_writer& j) const +void sched_request_cfg_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("spare", spare.to_string()); + if (sr_with_harq_ack_cfg_r15_present) { + j.write_str("sr-WithHARQ-ACK-Config-r15", "true"); + } + if (sr_without_harq_ack_cfg_r15_present) { + j.write_fieldname("sr-WithoutHARQ-ACK-Config-r15"); + sr_without_harq_ack_cfg_r15.to_json(j); + } + if (sr_sps_bsr_cfg_r15_present) { + j.write_fieldname("sr-SPS-BSR-Config-r15"); + sr_sps_bsr_cfg_r15.to_json(j); + } + if (ext) { + if (sr_without_harq_ack_cfg_v1700.is_present()) { + j.write_fieldname("sr-WithoutHARQ-ACK-Config-v1700"); + sr_without_harq_ack_cfg_v1700->to_json(j); + } + } j.end_obj(); } -// GuardbandTDD-NB-r15 ::= SEQUENCE -SRSASN_CODE guardband_tdd_nb_r15_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(raster_offset_r15.pack(bref)); - HANDLE_CODE(sib_guardband_info_r15.pack(bref)); - HANDLE_CODE(eutra_bandwitdh_r15.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE guardband_tdd_nb_r15_s::unpack(cbit_ref& bref) +// RadioResourceConfigDedicated-NB-r13 ::= SEQUENCE +SRSASN_CODE rr_cfg_ded_nb_r13_s::pack(bit_ref& bref) const { - HANDLE_CODE(raster_offset_r15.unpack(bref)); - HANDLE_CODE(sib_guardband_info_r15.unpack(bref)); - HANDLE_CODE(eutra_bandwitdh_r15.unpack(bref)); + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(srb_to_add_mod_list_r13_present, 1)); + HANDLE_CODE(bref.pack(drb_to_add_mod_list_r13_present, 1)); + HANDLE_CODE(bref.pack(drb_to_release_list_r13_present, 1)); + HANDLE_CODE(bref.pack(mac_main_cfg_r13_present, 1)); + HANDLE_CODE(bref.pack(phys_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.pack(rlf_timers_and_consts_r13_present, 1)); - return SRSASN_SUCCESS; -} -void guardband_tdd_nb_r15_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_str("rasterOffset-r15", raster_offset_r15.to_string()); - j.write_fieldname("sib-GuardbandInfo-r15"); - sib_guardband_info_r15.to_json(j); - j.write_str("eutra-Bandwitdh-r15", eutra_bandwitdh_r15.to_string()); - j.end_obj(); + if (srb_to_add_mod_list_r13_present) { + HANDLE_CODE(pack_fixed_seq_of(bref, &(srb_to_add_mod_list_r13)[0], srb_to_add_mod_list_r13.size())); + } + if (drb_to_add_mod_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, drb_to_add_mod_list_r13, 1, 2)); + } + if (drb_to_release_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, drb_to_release_list_r13, 1, 2, integer_packer(1, 32))); + } + if (mac_main_cfg_r13_present) { + HANDLE_CODE(mac_main_cfg_r13.pack(bref)); + } + if (phys_cfg_ded_r13_present) { + HANDLE_CODE(phys_cfg_ded_r13.pack(bref)); + } + if (rlf_timers_and_consts_r13_present) { + HANDLE_CODE(rlf_timers_and_consts_r13.pack(bref)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= sched_request_cfg_r15.is_present(); + group_flags[1] |= new_ue_id_r16_present; + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(sched_request_cfg_r15.is_present(), 1)); + if (sched_request_cfg_r15.is_present()) { + HANDLE_CODE(sched_request_cfg_r15->pack(bref)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(new_ue_id_r16_present, 1)); + if (new_ue_id_r16_present) { + HANDLE_CODE(new_ue_id_r16.pack(bref)); + } + } + } + return SRSASN_SUCCESS; } +SRSASN_CODE rr_cfg_ded_nb_r13_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(srb_to_add_mod_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(drb_to_add_mod_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(drb_to_release_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(mac_main_cfg_r13_present, 1)); + HANDLE_CODE(bref.unpack(phys_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.unpack(rlf_timers_and_consts_r13_present, 1)); -void guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::destroy_() + if (srb_to_add_mod_list_r13_present) { + HANDLE_CODE(unpack_fixed_seq_of(&(srb_to_add_mod_list_r13)[0], bref, srb_to_add_mod_list_r13.size())); + } + if (drb_to_add_mod_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(drb_to_add_mod_list_r13, bref, 1, 2)); + } + if (drb_to_release_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(drb_to_release_list_r13, bref, 1, 2, integer_packer(1, 32))); + } + if (mac_main_cfg_r13_present) { + HANDLE_CODE(mac_main_cfg_r13.unpack(bref)); + } + if (phys_cfg_ded_r13_present) { + HANDLE_CODE(phys_cfg_ded_r13.unpack(bref)); + } + if (rlf_timers_and_consts_r13_present) { + HANDLE_CODE(rlf_timers_and_consts_r13.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(2); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool sched_request_cfg_r15_present; + HANDLE_CODE(bref.unpack(sched_request_cfg_r15_present, 1)); + sched_request_cfg_r15.set_present(sched_request_cfg_r15_present); + if (sched_request_cfg_r15.is_present()) { + HANDLE_CODE(sched_request_cfg_r15->unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(new_ue_id_r16_present, 1)); + if (new_ue_id_r16_present) { + HANDLE_CODE(new_ue_id_r16.unpack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +void rr_cfg_ded_nb_r13_s::to_json(json_writer& j) const { - switch (type_) { - case types::sib_guardband_anchor_r15: - c.destroy(); - break; - case types::sib_guardband_guardband_r15: - c.destroy(); - break; - case types::sib_guardband_inband_same_pci_r15: - c.destroy(); - break; - case types::sib_guardbandinband_diff_pci_r15: - c.destroy(); - break; - default: - break; + j.start_obj(); + if (srb_to_add_mod_list_r13_present) { + j.start_array("srb-ToAddModList-r13"); + for (const auto& e1 : srb_to_add_mod_list_r13) { + e1.to_json(j); + } + j.end_array(); + } + if (drb_to_add_mod_list_r13_present) { + j.start_array("drb-ToAddModList-r13"); + for (const auto& e1 : drb_to_add_mod_list_r13) { + e1.to_json(j); + } + j.end_array(); + } + if (drb_to_release_list_r13_present) { + j.start_array("drb-ToReleaseList-r13"); + for (const auto& e1 : drb_to_release_list_r13) { + j.write_int(e1); + } + j.end_array(); + } + if (mac_main_cfg_r13_present) { + j.write_fieldname("mac-MainConfig-r13"); + mac_main_cfg_r13.to_json(j); + } + if (phys_cfg_ded_r13_present) { + j.write_fieldname("physicalConfigDedicated-r13"); + phys_cfg_ded_r13.to_json(j); + } + if (rlf_timers_and_consts_r13_present) { + j.write_fieldname("rlf-TimersAndConstants-r13"); + rlf_timers_and_consts_r13.to_json(j); + } + if (ext) { + if (sched_request_cfg_r15.is_present()) { + j.write_fieldname("schedulingRequestConfig-r15"); + sched_request_cfg_r15->to_json(j); + } + if (new_ue_id_r16_present) { + j.write_str("newUE-Identity-r16", new_ue_id_r16.to_string()); + } } + j.end_obj(); } -void guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::set(types::options e) + +void rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::set(types::options e) { - destroy_(); type_ = e; +} +mac_main_cfg_nb_r13_s& rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::set_explicit_value_r13() +{ + set(types::explicit_value_r13); + return c; +} +void rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::set_default_value_r13() +{ + set(types::default_value_r13); +} +void rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::to_json(json_writer& j) const +{ + j.start_obj(); switch (type_) { - case types::sib_guardband_anchor_r15: - c.init(); - break; - case types::sib_guardband_guardband_r15: - c.init(); - break; - case types::sib_guardband_inband_same_pci_r15: - c.init(); - break; - case types::sib_guardbandinband_diff_pci_r15: - c.init(); + case types::explicit_value_r13: + j.write_fieldname("explicitValue-r13"); + c.to_json(j); break; - case types::nulltype: + case types::default_value_r13: break; default: - log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); + log_invalid_choice_id(type_, "rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_"); } + j.end_obj(); } -guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::sib_guardband_info_r15_c_( - const guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_& other) +SRSASN_CODE rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::pack(bit_ref& bref) const { - type_ = other.type(); + type_.pack(bref); switch (type_) { - case types::sib_guardband_anchor_r15: - c.init(other.c.get()); - break; - case types::sib_guardband_guardband_r15: - c.init(other.c.get()); - break; - case types::sib_guardband_inband_same_pci_r15: - c.init(other.c.get()); - break; - case types::sib_guardbandinband_diff_pci_r15: - c.init(other.c.get()); + case types::explicit_value_r13: + HANDLE_CODE(c.pack(bref)); break; - case types::nulltype: + case types::default_value_r13: break; default: - log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); + log_invalid_choice_id(type_, "rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_"); + return SRSASN_ERROR_ENCODE_FAIL; } + return SRSASN_SUCCESS; } -guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_& guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::operator=( - const guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_& other) +SRSASN_CODE rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::unpack(cbit_ref& bref) { - if (this == &other) { - return *this; - } - set(other.type()); + types e; + e.unpack(bref); + set(e); switch (type_) { - case types::sib_guardband_anchor_r15: - c.set(other.c.get()); - break; - case types::sib_guardband_guardband_r15: - c.set(other.c.get()); - break; - case types::sib_guardband_inband_same_pci_r15: - c.set(other.c.get()); - break; - case types::sib_guardbandinband_diff_pci_r15: - c.set(other.c.get()); + case types::explicit_value_r13: + HANDLE_CODE(c.unpack(bref)); break; - case types::nulltype: + case types::default_value_r13: break; default: - log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); + log_invalid_choice_id(type_, "rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_"); + return SRSASN_ERROR_DECODE_FAIL; } - - return *this; + return SRSASN_SUCCESS; } -sib_guardband_anchor_tdd_nb_r15_s& guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::set_sib_guardband_anchor_r15() + +const char* rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::types_opts::to_string() const { - set(types::sib_guardband_anchor_r15); - return c.get(); + static const char* options[] = {"explicitValue-r13", "defaultValue-r13"}; + return convert_enum_idx(options, 2, value, "rr_cfg_ded_nb_r13_s::mac_main_cfg_r13_c_::types"); } -sib_guardband_guardband_tdd_nb_r15_s& -guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::set_sib_guardband_guardband_r15() + +// AS-Config-NB ::= SEQUENCE +SRSASN_CODE as_cfg_nb_s::pack(bit_ref& bref) const { - set(types::sib_guardband_guardband_r15); - return c.get(); -} -sib_guardband_inband_same_pci_tdd_nb_r15_s& -guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::set_sib_guardband_inband_same_pci_r15() -{ - set(types::sib_guardband_inband_same_pci_r15); - return c.get(); + bref.pack(ext, 1); + HANDLE_CODE(source_rr_cfg_r13.pack(bref)); + HANDLE_CODE(source_security_algorithm_cfg_r13.pack(bref)); + HANDLE_CODE(source_ue_id_r13.pack(bref)); + HANDLE_CODE(source_dl_carrier_freq_r13.pack(bref)); + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= source_dl_carrier_freq_v1550.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(source_dl_carrier_freq_v1550.is_present(), 1)); + if (source_dl_carrier_freq_v1550.is_present()) { + HANDLE_CODE(source_dl_carrier_freq_v1550->pack(bref)); + } + } + } + return SRSASN_SUCCESS; } -sib_guardband_inband_diff_pci_tdd_nb_r15_s& -guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::set_sib_guardbandinband_diff_pci_r15() +SRSASN_CODE as_cfg_nb_s::unpack(cbit_ref& bref) { - set(types::sib_guardbandinband_diff_pci_r15); - return c.get(); + bref.unpack(ext, 1); + HANDLE_CODE(source_rr_cfg_r13.unpack(bref)); + HANDLE_CODE(source_security_algorithm_cfg_r13.unpack(bref)); + HANDLE_CODE(source_ue_id_r13.unpack(bref)); + HANDLE_CODE(source_dl_carrier_freq_r13.unpack(bref)); + + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool source_dl_carrier_freq_v1550_present; + HANDLE_CODE(bref.unpack(source_dl_carrier_freq_v1550_present, 1)); + source_dl_carrier_freq_v1550.set_present(source_dl_carrier_freq_v1550_present); + if (source_dl_carrier_freq_v1550.is_present()) { + HANDLE_CODE(source_dl_carrier_freq_v1550->unpack(bref)); + } + } + } + return SRSASN_SUCCESS; } -void guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::to_json(json_writer& j) const +void as_cfg_nb_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::sib_guardband_anchor_r15: - j.write_fieldname("sib-GuardbandAnchor-r15"); - c.get().to_json(j); - break; - case types::sib_guardband_guardband_r15: - j.write_fieldname("sib-GuardbandGuardband-r15"); - c.get().to_json(j); - break; - case types::sib_guardband_inband_same_pci_r15: - j.write_fieldname("sib-GuardbandInbandSamePCI-r15"); - c.get().to_json(j); - break; - case types::sib_guardbandinband_diff_pci_r15: - j.write_fieldname("sib-GuardbandinbandDiffPCI-r15"); - c.get().to_json(j); - break; - default: - log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); + j.write_fieldname("sourceRadioResourceConfig-r13"); + source_rr_cfg_r13.to_json(j); + j.write_fieldname("sourceSecurityAlgorithmConfig-r13"); + source_security_algorithm_cfg_r13.to_json(j); + j.write_str("sourceUE-Identity-r13", source_ue_id_r13.to_string()); + j.write_fieldname("sourceDl-CarrierFreq-r13"); + source_dl_carrier_freq_r13.to_json(j); + if (ext) { + if (source_dl_carrier_freq_v1550.is_present()) { + j.write_fieldname("sourceDL-CarrierFreq-v1550"); + source_dl_carrier_freq_v1550->to_json(j); + } } j.end_obj(); } -SRSASN_CODE guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::pack(bit_ref& bref) const + +// ReestablishmentInfo-NB ::= SEQUENCE +SRSASN_CODE reest_info_nb_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::sib_guardband_anchor_r15: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::sib_guardband_guardband_r15: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::sib_guardband_inband_same_pci_r15: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::sib_guardbandinband_diff_pci_r15: - HANDLE_CODE(c.get().pack(bref)); - break; - default: - log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); - return SRSASN_ERROR_ENCODE_FAIL; + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(add_reestab_info_list_r13_present, 1)); + + HANDLE_CODE(pack_integer(bref, source_pci_r13, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(target_cell_short_mac_i_r13.pack(bref)); + if (add_reestab_info_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, add_reestab_info_list_r13, 1, 32)); } + return SRSASN_SUCCESS; } -SRSASN_CODE guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::unpack(cbit_ref& bref) +SRSASN_CODE reest_info_nb_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::sib_guardband_anchor_r15: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::sib_guardband_guardband_r15: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::sib_guardband_inband_same_pci_r15: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::sib_guardbandinband_diff_pci_r15: - HANDLE_CODE(c.get().unpack(bref)); - break; - default: - log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); - return SRSASN_ERROR_DECODE_FAIL; + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(add_reestab_info_list_r13_present, 1)); + + HANDLE_CODE(unpack_integer(source_pci_r13, bref, (uint16_t)0u, (uint16_t)503u)); + HANDLE_CODE(target_cell_short_mac_i_r13.unpack(bref)); + if (add_reestab_info_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(add_reestab_info_list_r13, bref, 1, 32)); } + return SRSASN_SUCCESS; } - -const char* guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::types_opts::to_string() const +void reest_info_nb_s::to_json(json_writer& j) const { - static const char* options[] = {"sib-GuardbandAnchor-r15", - "sib-GuardbandGuardband-r15", - "sib-GuardbandInbandSamePCI-r15", - "sib-GuardbandinbandDiffPCI-r15"}; - return convert_enum_idx(options, 4, value, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::types"); + j.start_obj(); + j.write_int("sourcePhysCellId-r13", source_pci_r13); + j.write_str("targetCellShortMAC-I-r13", target_cell_short_mac_i_r13.to_string()); + if (add_reestab_info_list_r13_present) { + j.start_array("additionalReestabInfoList-r13"); + for (const auto& e1 : add_reestab_info_list_r13) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); } -const char* guardband_tdd_nb_r15_s::eutra_bandwitdh_r15_opts::to_string() const -{ - static const char* options[] = {"bw5or10", "bw15or20"}; - return convert_enum_idx(options, 2, value, "guardband_tdd_nb_r15_s::eutra_bandwitdh_r15_e_"); -} -uint8_t guardband_tdd_nb_r15_s::eutra_bandwitdh_r15_opts::to_number() const +// AS-Context-NB ::= SEQUENCE +SRSASN_CODE as_context_nb_s::pack(bit_ref& bref) const { - static const uint8_t options[] = {5, 15}; - return map_enum_number(options, 2, value, "guardband_tdd_nb_r15_s::eutra_bandwitdh_r15_e_"); -} + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(reest_info_r13_present, 1)); -// Inband-DifferentPCI-TDD-NB-r15 ::= SEQUENCE -SRSASN_CODE inband_different_pci_tdd_nb_r15_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(eutra_num_crs_ports_r15.pack(bref)); - HANDLE_CODE(raster_offset_r15.pack(bref)); - HANDLE_CODE(sib_inband_location_r15.pack(bref)); - HANDLE_CODE(spare.pack(bref)); + if (reest_info_r13_present) { + HANDLE_CODE(reest_info_r13.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE inband_different_pci_tdd_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE as_context_nb_s::unpack(cbit_ref& bref) { - HANDLE_CODE(eutra_num_crs_ports_r15.unpack(bref)); - HANDLE_CODE(raster_offset_r15.unpack(bref)); - HANDLE_CODE(sib_inband_location_r15.unpack(bref)); - HANDLE_CODE(spare.unpack(bref)); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(reest_info_r13_present, 1)); + + if (reest_info_r13_present) { + HANDLE_CODE(reest_info_r13.unpack(bref)); + } return SRSASN_SUCCESS; } -void inband_different_pci_tdd_nb_r15_s::to_json(json_writer& j) const +void as_context_nb_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("eutra-NumCRS-Ports-r15", eutra_num_crs_ports_r15.to_string()); - j.write_str("rasterOffset-r15", raster_offset_r15.to_string()); - j.write_str("sib-InbandLocation-r15", sib_inband_location_r15.to_string()); - j.write_str("spare", spare.to_string()); + if (reest_info_r13_present) { + j.write_fieldname("reestablishmentInfo-r13"); + reest_info_r13.to_json(j); + } j.end_obj(); } -const char* inband_different_pci_tdd_nb_r15_s::eutra_num_crs_ports_r15_opts::to_string() const +// ChannelRasterOffset-NB-r13 ::= ENUMERATED +const char* ch_raster_offset_nb_r13_opts::to_string() const { - static const char* options[] = {"same", "four"}; - return convert_enum_idx(options, 2, value, "inband_different_pci_tdd_nb_r15_s::eutra_num_crs_ports_r15_e_"); + static const char* options[] = {"khz-7dot5", "khz-2dot5", "khz2dot5", "khz7dot5"}; + return convert_enum_idx(options, 4, value, "ch_raster_offset_nb_r13_e"); } -uint8_t inband_different_pci_tdd_nb_r15_s::eutra_num_crs_ports_r15_opts::to_number() const +float ch_raster_offset_nb_r13_opts::to_number() const { - if (value == four) { - return 4; - } - invalid_enum_number(value, "inband_different_pci_tdd_nb_r15_s::eutra_num_crs_ports_r15_e_"); - return 0; + static const float options[] = {-7.5, -2.5, 2.5, 7.5}; + return map_enum_number(options, 4, value, "ch_raster_offset_nb_r13_e"); } - -const char* inband_different_pci_tdd_nb_r15_s::sib_inband_location_r15_opts::to_string() const +const char* ch_raster_offset_nb_r13_opts::to_number_string() const { - static const char* options[] = {"lower", "higher"}; - return convert_enum_idx(options, 2, value, "inband_different_pci_tdd_nb_r15_s::sib_inband_location_r15_e_"); + static const char* options[] = {"-7.5", "-2.5", "2.5", "7.5"}; + return convert_enum_idx(options, 4, value, "ch_raster_offset_nb_r13_e"); } -// Inband-SamePCI-TDD-NB-r15 ::= SEQUENCE -SRSASN_CODE inband_same_pci_tdd_nb_r15_s::pack(bit_ref& bref) const +// Guardband-NB-r13 ::= SEQUENCE +SRSASN_CODE guardband_nb_r13_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, eutra_crs_seq_info_r15, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(sib_inband_location_r15.pack(bref)); + HANDLE_CODE(raster_offset_r13.pack(bref)); + HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE inband_same_pci_tdd_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE guardband_nb_r13_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(eutra_crs_seq_info_r15, bref, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(sib_inband_location_r15.unpack(bref)); + HANDLE_CODE(raster_offset_r13.unpack(bref)); + HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void inband_same_pci_tdd_nb_r15_s::to_json(json_writer& j) const +void guardband_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("eutra-CRS-SequenceInfo-r15", eutra_crs_seq_info_r15); - j.write_str("sib-InbandLocation-r15", sib_inband_location_r15.to_string()); + j.write_str("rasterOffset-r13", raster_offset_r13.to_string()); + j.write_str("spare", spare.to_string()); j.end_obj(); } -const char* inband_same_pci_tdd_nb_r15_s::sib_inband_location_r15_opts::to_string() const +// Inband-DifferentPCI-NB-r13 ::= SEQUENCE +SRSASN_CODE inband_different_pci_nb_r13_s::pack(bit_ref& bref) const { - static const char* options[] = {"lower", "higher"}; - return convert_enum_idx(options, 2, value, "inband_same_pci_tdd_nb_r15_s::sib_inband_location_r15_e_"); -} - -// StandaloneTDD-NB-r15 ::= SEQUENCE -SRSASN_CODE standalone_tdd_nb_r15_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(sib_standalone_location_r15.pack(bref)); + HANDLE_CODE(eutra_num_crs_ports_r13.pack(bref)); + HANDLE_CODE(raster_offset_r13.pack(bref)); HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE standalone_tdd_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE inband_different_pci_nb_r13_s::unpack(cbit_ref& bref) { - HANDLE_CODE(sib_standalone_location_r15.unpack(bref)); + HANDLE_CODE(eutra_num_crs_ports_r13.unpack(bref)); + HANDLE_CODE(raster_offset_r13.unpack(bref)); HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void standalone_tdd_nb_r15_s::to_json(json_writer& j) const +void inband_different_pci_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("sib-StandaloneLocation-r15", sib_standalone_location_r15.to_string()); + j.write_str("eutra-NumCRS-Ports-r13", eutra_num_crs_ports_r13.to_string()); + j.write_str("rasterOffset-r13", raster_offset_r13.to_string()); j.write_str("spare", spare.to_string()); j.end_obj(); } -const char* standalone_tdd_nb_r15_s::sib_standalone_location_r15_opts::to_string() const +const char* inband_different_pci_nb_r13_s::eutra_num_crs_ports_r13_opts::to_string() const { - static const char* options[] = {"lower", "higher"}; - return convert_enum_idx(options, 2, value, "standalone_tdd_nb_r15_s::sib_standalone_location_r15_e_"); + static const char* options[] = {"same", "four"}; + return convert_enum_idx(options, 2, value, "inband_different_pci_nb_r13_s::eutra_num_crs_ports_r13_e_"); +} +uint8_t inband_different_pci_nb_r13_s::eutra_num_crs_ports_r13_opts::to_number() const +{ + if (value == four) { + return 4; + } + invalid_enum_number(value, "inband_different_pci_nb_r13_s::eutra_num_crs_ports_r13_e_"); + return 0; } -// MasterInformationBlock-TDD-NB-r15 ::= SEQUENCE -SRSASN_CODE mib_tdd_nb_r15_s::pack(bit_ref& bref) const +// Inband-SamePCI-NB-r13 ::= SEQUENCE +SRSASN_CODE inband_same_pci_nb_r13_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, eutra_crs_seq_info_r13, (uint8_t)0u, (uint8_t)31u)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE inband_same_pci_nb_r13_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(eutra_crs_seq_info_r13, bref, (uint8_t)0u, (uint8_t)31u)); + + return SRSASN_SUCCESS; +} +void inband_same_pci_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("eutra-CRS-SequenceInfo-r13", eutra_crs_seq_info_r13); + j.end_obj(); +} + +// Standalone-NB-r13 ::= SEQUENCE +SRSASN_CODE standalone_nb_r13_s::pack(bit_ref& bref) const { - HANDLE_CODE(sys_frame_num_msb_r15.pack(bref)); - HANDLE_CODE(hyper_sfn_lsb_r15.pack(bref)); - HANDLE_CODE(pack_integer(bref, sched_info_sib1_r15, (uint8_t)0u, (uint8_t)15u)); - HANDLE_CODE(pack_integer(bref, sys_info_value_tag_r15, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(bref.pack(ab_enabled_r15, 1)); - HANDLE_CODE(operation_mode_info_r15.pack(bref)); - HANDLE_CODE(sib1_carrier_info_r15.pack(bref)); HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE mib_tdd_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE standalone_nb_r13_s::unpack(cbit_ref& bref) { - HANDLE_CODE(sys_frame_num_msb_r15.unpack(bref)); - HANDLE_CODE(hyper_sfn_lsb_r15.unpack(bref)); - HANDLE_CODE(unpack_integer(sched_info_sib1_r15, bref, (uint8_t)0u, (uint8_t)15u)); - HANDLE_CODE(unpack_integer(sys_info_value_tag_r15, bref, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(bref.unpack(ab_enabled_r15, 1)); - HANDLE_CODE(operation_mode_info_r15.unpack(bref)); - HANDLE_CODE(sib1_carrier_info_r15.unpack(bref)); HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void mib_tdd_nb_r15_s::to_json(json_writer& j) const +void standalone_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("systemFrameNumber-MSB-r15", sys_frame_num_msb_r15.to_string()); - j.write_str("hyperSFN-LSB-r15", hyper_sfn_lsb_r15.to_string()); - j.write_int("schedulingInfoSIB1-r15", sched_info_sib1_r15); - j.write_int("systemInfoValueTag-r15", sys_info_value_tag_r15); - j.write_bool("ab-Enabled-r15", ab_enabled_r15); - j.write_fieldname("operationModeInfo-r15"); - operation_mode_info_r15.to_json(j); - j.write_str("sib1-CarrierInfo-r15", sib1_carrier_info_r15.to_string()); j.write_str("spare", spare.to_string()); j.end_obj(); } -void mib_tdd_nb_r15_s::operation_mode_info_r15_c_::destroy_() +// MasterInformationBlock-NB ::= SEQUENCE +SRSASN_CODE mib_nb_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(sys_frame_num_msb_r13.pack(bref)); + HANDLE_CODE(hyper_sfn_lsb_r13.pack(bref)); + HANDLE_CODE(pack_integer(bref, sched_info_sib1_r13, (uint8_t)0u, (uint8_t)15u)); + HANDLE_CODE(pack_integer(bref, sys_info_value_tag_r13, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(bref.pack(ab_enabled_r13, 1)); + HANDLE_CODE(operation_mode_info_r13.pack(bref)); + HANDLE_CODE(bref.pack(add_tx_sib1_r15, 1)); + HANDLE_CODE(bref.pack(ab_enabled_minus5_gc_r16, 1)); + HANDLE_CODE(part_earfcn_minus17.pack(bref)); + HANDLE_CODE(spare.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mib_nb_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(sys_frame_num_msb_r13.unpack(bref)); + HANDLE_CODE(hyper_sfn_lsb_r13.unpack(bref)); + HANDLE_CODE(unpack_integer(sched_info_sib1_r13, bref, (uint8_t)0u, (uint8_t)15u)); + HANDLE_CODE(unpack_integer(sys_info_value_tag_r13, bref, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(bref.unpack(ab_enabled_r13, 1)); + HANDLE_CODE(operation_mode_info_r13.unpack(bref)); + HANDLE_CODE(bref.unpack(add_tx_sib1_r15, 1)); + HANDLE_CODE(bref.unpack(ab_enabled_minus5_gc_r16, 1)); + HANDLE_CODE(part_earfcn_minus17.unpack(bref)); + HANDLE_CODE(spare.unpack(bref)); + + return SRSASN_SUCCESS; +} +void mib_nb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("systemFrameNumber-MSB-r13", sys_frame_num_msb_r13.to_string()); + j.write_str("hyperSFN-LSB-r13", hyper_sfn_lsb_r13.to_string()); + j.write_int("schedulingInfoSIB1-r13", sched_info_sib1_r13); + j.write_int("systemInfoValueTag-r13", sys_info_value_tag_r13); + j.write_bool("ab-Enabled-r13", ab_enabled_r13); + j.write_fieldname("operationModeInfo-r13"); + operation_mode_info_r13.to_json(j); + j.write_bool("additionalTransmissionSIB1-r15", add_tx_sib1_r15); + j.write_bool("ab-Enabled-5GC-r16", ab_enabled_minus5_gc_r16); + j.write_fieldname("partEARFCN-17"); + part_earfcn_minus17.to_json(j); + j.write_str("spare", spare.to_string()); + j.end_obj(); +} + +void mib_nb_s::operation_mode_info_r13_c_::destroy_() { switch (type_) { - case types::inband_same_pci_r15: - c.destroy(); + case types::inband_same_pci_r13: + c.destroy(); break; - case types::inband_different_pci_r15: - c.destroy(); + case types::inband_different_pci_r13: + c.destroy(); break; - case types::guardband_r15: - c.destroy(); + case types::guardband_r13: + c.destroy(); break; - case types::standalone_r15: - c.destroy(); + case types::standalone_r13: + c.destroy(); break; default: break; } } -void mib_tdd_nb_r15_s::operation_mode_info_r15_c_::set(types::options e) +void mib_nb_s::operation_mode_info_r13_c_::set(types::options e) { destroy_(); type_ = e; switch (type_) { - case types::inband_same_pci_r15: - c.init(); + case types::inband_same_pci_r13: + c.init(); break; - case types::inband_different_pci_r15: - c.init(); + case types::inband_different_pci_r13: + c.init(); break; - case types::guardband_r15: - c.init(); + case types::guardband_r13: + c.init(); break; - case types::standalone_r15: - c.init(); + case types::standalone_r13: + c.init(); break; case types::nulltype: break; default: - log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); } } -mib_tdd_nb_r15_s::operation_mode_info_r15_c_::operation_mode_info_r15_c_( - const mib_tdd_nb_r15_s::operation_mode_info_r15_c_& other) +mib_nb_s::operation_mode_info_r13_c_::operation_mode_info_r13_c_(const mib_nb_s::operation_mode_info_r13_c_& other) { type_ = other.type(); switch (type_) { - case types::inband_same_pci_r15: - c.init(other.c.get()); + case types::inband_same_pci_r13: + c.init(other.c.get()); break; - case types::inband_different_pci_r15: - c.init(other.c.get()); + case types::inband_different_pci_r13: + c.init(other.c.get()); break; - case types::guardband_r15: - c.init(other.c.get()); + case types::guardband_r13: + c.init(other.c.get()); break; - case types::standalone_r15: - c.init(other.c.get()); + case types::standalone_r13: + c.init(other.c.get()); break; case types::nulltype: break; default: - log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); } } -mib_tdd_nb_r15_s::operation_mode_info_r15_c_& -mib_tdd_nb_r15_s::operation_mode_info_r15_c_::operator=(const mib_tdd_nb_r15_s::operation_mode_info_r15_c_& other) +mib_nb_s::operation_mode_info_r13_c_& +mib_nb_s::operation_mode_info_r13_c_::operator=(const mib_nb_s::operation_mode_info_r13_c_& other) { if (this == &other) { return *this; } set(other.type()); switch (type_) { - case types::inband_same_pci_r15: - c.set(other.c.get()); + case types::inband_same_pci_r13: + c.set(other.c.get()); break; - case types::inband_different_pci_r15: - c.set(other.c.get()); + case types::inband_different_pci_r13: + c.set(other.c.get()); break; - case types::guardband_r15: - c.set(other.c.get()); + case types::guardband_r13: + c.set(other.c.get()); break; - case types::standalone_r15: - c.set(other.c.get()); + case types::standalone_r13: + c.set(other.c.get()); break; case types::nulltype: break; default: - log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); } return *this; } -inband_same_pci_tdd_nb_r15_s& mib_tdd_nb_r15_s::operation_mode_info_r15_c_::set_inband_same_pci_r15() +inband_same_pci_nb_r13_s& mib_nb_s::operation_mode_info_r13_c_::set_inband_same_pci_r13() { - set(types::inband_same_pci_r15); - return c.get(); + set(types::inband_same_pci_r13); + return c.get(); } -inband_different_pci_tdd_nb_r15_s& mib_tdd_nb_r15_s::operation_mode_info_r15_c_::set_inband_different_pci_r15() +inband_different_pci_nb_r13_s& mib_nb_s::operation_mode_info_r13_c_::set_inband_different_pci_r13() { - set(types::inband_different_pci_r15); - return c.get(); + set(types::inband_different_pci_r13); + return c.get(); } -guardband_tdd_nb_r15_s& mib_tdd_nb_r15_s::operation_mode_info_r15_c_::set_guardband_r15() +guardband_nb_r13_s& mib_nb_s::operation_mode_info_r13_c_::set_guardband_r13() { - set(types::guardband_r15); - return c.get(); + set(types::guardband_r13); + return c.get(); } -standalone_tdd_nb_r15_s& mib_tdd_nb_r15_s::operation_mode_info_r15_c_::set_standalone_r15() +standalone_nb_r13_s& mib_nb_s::operation_mode_info_r13_c_::set_standalone_r13() { - set(types::standalone_r15); - return c.get(); + set(types::standalone_r13); + return c.get(); } -void mib_tdd_nb_r15_s::operation_mode_info_r15_c_::to_json(json_writer& j) const +void mib_nb_s::operation_mode_info_r13_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::inband_same_pci_r15: - j.write_fieldname("inband-SamePCI-r15"); - c.get().to_json(j); + case types::inband_same_pci_r13: + j.write_fieldname("inband-SamePCI-r13"); + c.get().to_json(j); break; - case types::inband_different_pci_r15: - j.write_fieldname("inband-DifferentPCI-r15"); - c.get().to_json(j); + case types::inband_different_pci_r13: + j.write_fieldname("inband-DifferentPCI-r13"); + c.get().to_json(j); break; - case types::guardband_r15: - j.write_fieldname("guardband-r15"); - c.get().to_json(j); + case types::guardband_r13: + j.write_fieldname("guardband-r13"); + c.get().to_json(j); break; - case types::standalone_r15: - j.write_fieldname("standalone-r15"); - c.get().to_json(j); + case types::standalone_r13: + j.write_fieldname("standalone-r13"); + c.get().to_json(j); break; default: - log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); } j.end_obj(); } -SRSASN_CODE mib_tdd_nb_r15_s::operation_mode_info_r15_c_::pack(bit_ref& bref) const +SRSASN_CODE mib_nb_s::operation_mode_info_r13_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::inband_same_pci_r15: - HANDLE_CODE(c.get().pack(bref)); + case types::inband_same_pci_r13: + HANDLE_CODE(c.get().pack(bref)); break; - case types::inband_different_pci_r15: - HANDLE_CODE(c.get().pack(bref)); + case types::inband_different_pci_r13: + HANDLE_CODE(c.get().pack(bref)); break; - case types::guardband_r15: - HANDLE_CODE(c.get().pack(bref)); + case types::guardband_r13: + HANDLE_CODE(c.get().pack(bref)); break; - case types::standalone_r15: - HANDLE_CODE(c.get().pack(bref)); + case types::standalone_r13: + HANDLE_CODE(c.get().pack(bref)); break; default: - log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE mib_tdd_nb_r15_s::operation_mode_info_r15_c_::unpack(cbit_ref& bref) +SRSASN_CODE mib_nb_s::operation_mode_info_r13_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::inband_same_pci_r15: - HANDLE_CODE(c.get().unpack(bref)); + case types::inband_same_pci_r13: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::inband_different_pci_r15: - HANDLE_CODE(c.get().unpack(bref)); + case types::inband_different_pci_r13: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::guardband_r15: - HANDLE_CODE(c.get().unpack(bref)); + case types::guardband_r13: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::standalone_r15: - HANDLE_CODE(c.get().unpack(bref)); + case types::standalone_r13: + HANDLE_CODE(c.get().unpack(bref)); break; default: - log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + log_invalid_choice_id(type_, "mib_nb_s::operation_mode_info_r13_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* mib_tdd_nb_r15_s::operation_mode_info_r15_c_::types_opts::to_string() const +const char* mib_nb_s::operation_mode_info_r13_c_::types_opts::to_string() const { - static const char* options[] = {"inband-SamePCI-r15", "inband-DifferentPCI-r15", "guardband-r15", "standalone-r15"}; - return convert_enum_idx(options, 4, value, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_::types"); + static const char* options[] = {"inband-SamePCI-r13", "inband-DifferentPCI-r13", "guardband-r13", "standalone-r13"}; + return convert_enum_idx(options, 4, value, "mib_nb_s::operation_mode_info_r13_c_::types"); } -uint8_t mib_tdd_nb_r15_s::operation_mode_info_r15_c_::types_opts::to_number() const +uint8_t mib_nb_s::operation_mode_info_r13_c_::types_opts::to_number() const { - if (value == standalone_r15) { + if (value == standalone_r13) { return 1; } - invalid_enum_number(value, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_::types"); + invalid_enum_number(value, "mib_nb_s::operation_mode_info_r13_c_::types"); return 0; } -const char* mib_tdd_nb_r15_s::sib1_carrier_info_r15_opts::to_string() const +void mib_nb_s::part_earfcn_minus17_c_::destroy_() { - static const char* options[] = {"anchor", "non-anchor"}; - return convert_enum_idx(options, 2, value, "mib_tdd_nb_r15_s::sib1_carrier_info_r15_e_"); + switch (type_) { + case types::spare: + c.destroy >(); + break; + case types::earfcn_lsb: + c.destroy >(); + break; + default: + break; + } +} +void mib_nb_s::part_earfcn_minus17_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::spare: + c.init >(); + break; + case types::earfcn_lsb: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mib_nb_s::part_earfcn_minus17_c_"); + } +} +mib_nb_s::part_earfcn_minus17_c_::part_earfcn_minus17_c_(const mib_nb_s::part_earfcn_minus17_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::spare: + c.init(other.c.get >()); + break; + case types::earfcn_lsb: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mib_nb_s::part_earfcn_minus17_c_"); + } } +mib_nb_s::part_earfcn_minus17_c_& +mib_nb_s::part_earfcn_minus17_c_::operator=(const mib_nb_s::part_earfcn_minus17_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::spare: + c.set(other.c.get >()); + break; + case types::earfcn_lsb: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mib_nb_s::part_earfcn_minus17_c_"); + } -// BCCH-BCH-Message-TDD-NB ::= SEQUENCE -SRSASN_CODE bcch_bch_msg_tdd_nb_s::pack(bit_ref& bref) const + return *this; +} +fixed_bitstring<2>& mib_nb_s::part_earfcn_minus17_c_::set_spare() +{ + set(types::spare); + return c.get >(); +} +fixed_bitstring<2>& mib_nb_s::part_earfcn_minus17_c_::set_earfcn_lsb() +{ + set(types::earfcn_lsb); + return c.get >(); +} +void mib_nb_s::part_earfcn_minus17_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::spare: + j.write_str("spare", c.get >().to_string()); + break; + case types::earfcn_lsb: + j.write_str("earfcn-LSB", c.get >().to_string()); + break; + default: + log_invalid_choice_id(type_, "mib_nb_s::part_earfcn_minus17_c_"); + } + j.end_obj(); +} +SRSASN_CODE mib_nb_s::part_earfcn_minus17_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::spare: + HANDLE_CODE(c.get >().pack(bref)); + break; + case types::earfcn_lsb: + HANDLE_CODE(c.get >().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "mib_nb_s::part_earfcn_minus17_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE mib_nb_s::part_earfcn_minus17_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::spare: + HANDLE_CODE(c.get >().unpack(bref)); + break; + case types::earfcn_lsb: + HANDLE_CODE(c.get >().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "mib_nb_s::part_earfcn_minus17_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* mib_nb_s::part_earfcn_minus17_c_::types_opts::to_string() const +{ + static const char* options[] = {"spare", "earfcn-LSB"}; + return convert_enum_idx(options, 2, value, "mib_nb_s::part_earfcn_minus17_c_::types"); +} + +// BCCH-BCH-Message-NB ::= SEQUENCE +SRSASN_CODE bcch_bch_msg_nb_s::pack(bit_ref& bref) const { HANDLE_CODE(msg.pack(bref)); @@ -4668,7 +5673,7 @@ SRSASN_CODE bcch_bch_msg_tdd_nb_s::pack(bit_ref& bref) const return SRSASN_SUCCESS; } -SRSASN_CODE bcch_bch_msg_tdd_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE bcch_bch_msg_nb_s::unpack(cbit_ref& bref) { HANDLE_CODE(msg.unpack(bref)); @@ -4676,11 +5681,11 @@ SRSASN_CODE bcch_bch_msg_tdd_nb_s::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -void bcch_bch_msg_tdd_nb_s::to_json(json_writer& j) const +void bcch_bch_msg_nb_s::to_json(json_writer& j) const { j.start_array(); j.start_obj(); - j.start_obj("BCCH-BCH-Message-TDD-NB"); + j.start_obj("BCCH-BCH-Message-NB"); j.write_fieldname("message"); msg.to_json(j); j.end_obj(); @@ -4688,1274 +5693,1309 @@ void bcch_bch_msg_tdd_nb_s::to_json(json_writer& j) const j.end_array(); } -// NS-PmaxValue-NB-r13 ::= SEQUENCE -SRSASN_CODE ns_pmax_value_nb_r13_s::pack(bit_ref& bref) const +// SIB-GuardbandAnchorTDD-NB-r15 ::= SEQUENCE +SRSASN_CODE sib_guardband_anchor_tdd_nb_r15_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(add_pmax_r13_present, 1)); - - if (add_pmax_r13_present) { - HANDLE_CODE(pack_integer(bref, add_pmax_r13, (int8_t)-30, (int8_t)33)); - } - HANDLE_CODE(pack_integer(bref, add_spec_emission_r13, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE ns_pmax_value_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE sib_guardband_anchor_tdd_nb_r15_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(add_pmax_r13_present, 1)); - - if (add_pmax_r13_present) { - HANDLE_CODE(unpack_integer(add_pmax_r13, bref, (int8_t)-30, (int8_t)33)); - } - HANDLE_CODE(unpack_integer(add_spec_emission_r13, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void ns_pmax_value_nb_r13_s::to_json(json_writer& j) const +void sib_guardband_anchor_tdd_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - if (add_pmax_r13_present) { - j.write_int("additionalPmax-r13", add_pmax_r13); - } - j.write_int("additionalSpectrumEmission-r13", add_spec_emission_r13); + j.write_str("spare", spare.to_string()); j.end_obj(); } -// SIB-Type-NB-v1530 ::= ENUMERATED -const char* sib_type_nb_v1530_opts::to_string() const -{ - static const char* options[] = { - "sibType23-NB-r15", "spare7", "spare6", "spare5", "spare4", "spare3", "spare2", "spare1"}; - return convert_enum_idx(options, 8, value, "sib_type_nb_v1530_e"); -} -uint8_t sib_type_nb_v1530_opts::to_number() const -{ - static const uint8_t options[] = {23}; - return map_enum_number(options, 1, value, "sib_type_nb_v1530_e"); -} - -// NSSS-RRM-Config-NB-r15 ::= SEQUENCE -SRSASN_CODE nsss_rrm_cfg_nb_r15_s::pack(bit_ref& bref) const +// SIB-GuardbandGuardbandTDD-NB-r15 ::= SEQUENCE +SRSASN_CODE sib_guardband_guardband_tdd_nb_r15_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(nsss_num_occ_diff_precoders_r15_present, 1)); - - HANDLE_CODE(nsss_rrm_pwr_offset_r15.pack(bref)); - if (nsss_num_occ_diff_precoders_r15_present) { - HANDLE_CODE(nsss_num_occ_diff_precoders_r15.pack(bref)); - } + HANDLE_CODE(sib_guardband_guardband_location_r15.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE nsss_rrm_cfg_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE sib_guardband_guardband_tdd_nb_r15_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(nsss_num_occ_diff_precoders_r15_present, 1)); - - HANDLE_CODE(nsss_rrm_pwr_offset_r15.unpack(bref)); - if (nsss_num_occ_diff_precoders_r15_present) { - HANDLE_CODE(nsss_num_occ_diff_precoders_r15.unpack(bref)); - } + HANDLE_CODE(sib_guardband_guardband_location_r15.unpack(bref)); return SRSASN_SUCCESS; } -void nsss_rrm_cfg_nb_r15_s::to_json(json_writer& j) const +void sib_guardband_guardband_tdd_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("nsss-RRM-PowerOffset-r15", nsss_rrm_pwr_offset_r15.to_string()); - if (nsss_num_occ_diff_precoders_r15_present) { - j.write_str("nsss-NumOccDiffPrecoders-r15", nsss_num_occ_diff_precoders_r15.to_string()); - } + j.write_str("sib-GuardbandGuardbandLocation-r15", sib_guardband_guardband_location_r15.to_string()); j.end_obj(); } -const char* nsss_rrm_cfg_nb_r15_s::nsss_rrm_pwr_offset_r15_opts::to_string() const -{ - static const char* options[] = {"dB-3", "db0", "dB3"}; - return convert_enum_idx(options, 3, value, "nsss_rrm_cfg_nb_r15_s::nsss_rrm_pwr_offset_r15_e_"); -} -int8_t nsss_rrm_cfg_nb_r15_s::nsss_rrm_pwr_offset_r15_opts::to_number() const -{ - static const int8_t options[] = {-3, 0, 3}; - return map_enum_number(options, 3, value, "nsss_rrm_cfg_nb_r15_s::nsss_rrm_pwr_offset_r15_e_"); -} - -const char* nsss_rrm_cfg_nb_r15_s::nsss_num_occ_diff_precoders_r15_opts::to_string() const -{ - static const char* options[] = {"n1", "n2", "n4", "n8"}; - return convert_enum_idx(options, 4, value, "nsss_rrm_cfg_nb_r15_s::nsss_num_occ_diff_precoders_r15_e_"); -} -uint8_t nsss_rrm_cfg_nb_r15_s::nsss_num_occ_diff_precoders_r15_opts::to_number() const +const char* sib_guardband_guardband_tdd_nb_r15_s::sib_guardband_guardband_location_r15_opts::to_string() const { - static const uint8_t options[] = {1, 2, 4, 8}; - return map_enum_number(options, 4, value, "nsss_rrm_cfg_nb_r15_s::nsss_num_occ_diff_precoders_r15_e_"); + static const char* options[] = {"same", "opposite"}; + return convert_enum_idx( + options, 2, value, "sib_guardband_guardband_tdd_nb_r15_s::sib_guardband_guardband_location_r15_e_"); } -// EDT-TBS-NB-r15 ::= SEQUENCE -SRSASN_CODE edt_tbs_nb_r15_s::pack(bit_ref& bref) const +// SIB-GuardbandInbandDiffPCI-TDD-NB-r15 ::= SEQUENCE +SRSASN_CODE sib_guardband_inband_diff_pci_tdd_nb_r15_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(edt_small_tbs_enabled_r15, 1)); - HANDLE_CODE(edt_tbs_r15.pack(bref)); + HANDLE_CODE(sib_eutra_num_crs_ports_r15.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE edt_tbs_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE sib_guardband_inband_diff_pci_tdd_nb_r15_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(edt_small_tbs_enabled_r15, 1)); - HANDLE_CODE(edt_tbs_r15.unpack(bref)); + HANDLE_CODE(sib_eutra_num_crs_ports_r15.unpack(bref)); return SRSASN_SUCCESS; } -void edt_tbs_nb_r15_s::to_json(json_writer& j) const +void sib_guardband_inband_diff_pci_tdd_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - j.write_bool("edt-SmallTBS-Enabled-r15", edt_small_tbs_enabled_r15); - j.write_str("edt-TBS-r15", edt_tbs_r15.to_string()); + j.write_str("sib-EUTRA-NumCRS-Ports-r15", sib_eutra_num_crs_ports_r15.to_string()); j.end_obj(); } -const char* edt_tbs_nb_r15_s::edt_tbs_r15_opts::to_string() const +const char* sib_guardband_inband_diff_pci_tdd_nb_r15_s::sib_eutra_num_crs_ports_r15_opts::to_string() const { - static const char* options[] = {"b328", "b408", "b504", "b584", "b680", "b808", "b936", "b1000"}; - return convert_enum_idx(options, 8, value, "edt_tbs_nb_r15_s::edt_tbs_r15_e_"); + static const char* options[] = {"same", "four"}; + return convert_enum_idx( + options, 2, value, "sib_guardband_inband_diff_pci_tdd_nb_r15_s::sib_eutra_num_crs_ports_r15_e_"); } -uint16_t edt_tbs_nb_r15_s::edt_tbs_r15_opts::to_number() const +uint8_t sib_guardband_inband_diff_pci_tdd_nb_r15_s::sib_eutra_num_crs_ports_r15_opts::to_number() const { - static const uint16_t options[] = {328, 408, 504, 584, 680, 808, 936, 1000}; - return map_enum_number(options, 8, value, "edt_tbs_nb_r15_s::edt_tbs_r15_e_"); + if (value == four) { + return 4; + } + invalid_enum_number(value, "sib_guardband_inband_diff_pci_tdd_nb_r15_s::sib_eutra_num_crs_ports_r15_e_"); + return 0; } -// InterFreqNeighCellInfo-NB-v1530 ::= SEQUENCE -SRSASN_CODE inter_freq_neigh_cell_info_nb_v1530_s::pack(bit_ref& bref) const +// SIB-GuardbandInbandSamePCI-TDD-NB-r15 ::= SEQUENCE +SRSASN_CODE sib_guardband_inband_same_pci_tdd_nb_r15_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(nsss_rrm_cfg_r15_present, 1)); - - if (nsss_rrm_cfg_r15_present) { - HANDLE_CODE(nsss_rrm_cfg_r15.pack(bref)); - } + HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE inter_freq_neigh_cell_info_nb_v1530_s::unpack(cbit_ref& bref) +SRSASN_CODE sib_guardband_inband_same_pci_tdd_nb_r15_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(nsss_rrm_cfg_r15_present, 1)); - - if (nsss_rrm_cfg_r15_present) { - HANDLE_CODE(nsss_rrm_cfg_r15.unpack(bref)); - } + HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void inter_freq_neigh_cell_info_nb_v1530_s::to_json(json_writer& j) const +void sib_guardband_inband_same_pci_tdd_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - if (nsss_rrm_cfg_r15_present) { - j.write_fieldname("nsss-RRM-Config-r15"); - nsss_rrm_cfg_r15.to_json(j); - } + j.write_str("spare", spare.to_string()); j.end_obj(); } -// MultiBandInfo-NB-r13 ::= SEQUENCE -SRSASN_CODE multi_band_info_nb_r13_s::pack(bit_ref& bref) const +// GuardbandTDD-NB-r15 ::= SEQUENCE +SRSASN_CODE guardband_tdd_nb_r15_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(freq_band_ind_r13_present, 1)); - HANDLE_CODE(bref.pack(freq_band_info_r13_present, 1)); - - if (freq_band_ind_r13_present) { - HANDLE_CODE(pack_integer(bref, freq_band_ind_r13, (uint16_t)1u, (uint16_t)256u)); - } - if (freq_band_info_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_info_r13, 1, 4)); - } + HANDLE_CODE(raster_offset_r15.pack(bref)); + HANDLE_CODE(sib_guardband_info_r15.pack(bref)); + HANDLE_CODE(eutra_bandwitdh_r15.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE multi_band_info_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE guardband_tdd_nb_r15_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(freq_band_ind_r13_present, 1)); - HANDLE_CODE(bref.unpack(freq_band_info_r13_present, 1)); - - if (freq_band_ind_r13_present) { - HANDLE_CODE(unpack_integer(freq_band_ind_r13, bref, (uint16_t)1u, (uint16_t)256u)); - } - if (freq_band_info_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(freq_band_info_r13, bref, 1, 4)); - } + HANDLE_CODE(raster_offset_r15.unpack(bref)); + HANDLE_CODE(sib_guardband_info_r15.unpack(bref)); + HANDLE_CODE(eutra_bandwitdh_r15.unpack(bref)); return SRSASN_SUCCESS; } -void multi_band_info_nb_r13_s::to_json(json_writer& j) const +void guardband_tdd_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - if (freq_band_ind_r13_present) { - j.write_int("freqBandIndicator-r13", freq_band_ind_r13); - } - if (freq_band_info_r13_present) { - j.start_array("freqBandInfo-r13"); - for (const auto& e1 : freq_band_info_r13) { - e1.to_json(j); - } - j.end_array(); - } + j.write_str("rasterOffset-r15", raster_offset_r15.to_string()); + j.write_fieldname("sib-GuardbandInfo-r15"); + sib_guardband_info_r15.to_json(j); + j.write_str("eutra-Bandwitdh-r15", eutra_bandwitdh_r15.to_string()); j.end_obj(); } -// NPRACH-Parameters-NB-r13 ::= SEQUENCE -SRSASN_CODE nprach_params_nb_r13_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(nprach_periodicity_r13.pack(bref)); - HANDLE_CODE(nprach_start_time_r13.pack(bref)); - HANDLE_CODE(nprach_subcarrier_offset_r13.pack(bref)); - HANDLE_CODE(nprach_num_subcarriers_r13.pack(bref)); - HANDLE_CODE(nprach_subcarrier_msg3_range_start_r13.pack(bref)); - HANDLE_CODE(max_num_preamb_attempt_ce_r13.pack(bref)); - HANDLE_CODE(num_repeats_per_preamb_attempt_r13.pack(bref)); - HANDLE_CODE(npdcch_num_repeats_ra_r13.pack(bref)); - HANDLE_CODE(npdcch_start_sf_css_ra_r13.pack(bref)); - HANDLE_CODE(npdcch_offset_ra_r13.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE nprach_params_nb_r13_s::unpack(cbit_ref& bref) +void guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::destroy_() { - HANDLE_CODE(nprach_periodicity_r13.unpack(bref)); - HANDLE_CODE(nprach_start_time_r13.unpack(bref)); - HANDLE_CODE(nprach_subcarrier_offset_r13.unpack(bref)); - HANDLE_CODE(nprach_num_subcarriers_r13.unpack(bref)); - HANDLE_CODE(nprach_subcarrier_msg3_range_start_r13.unpack(bref)); - HANDLE_CODE(max_num_preamb_attempt_ce_r13.unpack(bref)); - HANDLE_CODE(num_repeats_per_preamb_attempt_r13.unpack(bref)); - HANDLE_CODE(npdcch_num_repeats_ra_r13.unpack(bref)); - HANDLE_CODE(npdcch_start_sf_css_ra_r13.unpack(bref)); - HANDLE_CODE(npdcch_offset_ra_r13.unpack(bref)); - - return SRSASN_SUCCESS; + switch (type_) { + case types::sib_guardband_anchor_r15: + c.destroy(); + break; + case types::sib_guardband_guardband_r15: + c.destroy(); + break; + case types::sib_guardband_inband_same_pci_r15: + c.destroy(); + break; + case types::sib_guardbandinband_diff_pci_r15: + c.destroy(); + break; + default: + break; + } } -void nprach_params_nb_r13_s::to_json(json_writer& j) const +void guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::set(types::options e) { - j.start_obj(); - j.write_str("nprach-Periodicity-r13", nprach_periodicity_r13.to_string()); - j.write_str("nprach-StartTime-r13", nprach_start_time_r13.to_string()); - j.write_str("nprach-SubcarrierOffset-r13", nprach_subcarrier_offset_r13.to_string()); - j.write_str("nprach-NumSubcarriers-r13", nprach_num_subcarriers_r13.to_string()); - j.write_str("nprach-SubcarrierMSG3-RangeStart-r13", nprach_subcarrier_msg3_range_start_r13.to_string()); - j.write_str("maxNumPreambleAttemptCE-r13", max_num_preamb_attempt_ce_r13.to_string()); - j.write_str("numRepetitionsPerPreambleAttempt-r13", num_repeats_per_preamb_attempt_r13.to_string()); - j.write_str("npdcch-NumRepetitions-RA-r13", npdcch_num_repeats_ra_r13.to_string()); - j.write_str("npdcch-StartSF-CSS-RA-r13", npdcch_start_sf_css_ra_r13.to_string()); - j.write_str("npdcch-Offset-RA-r13", npdcch_offset_ra_r13.to_string()); - j.end_obj(); + destroy_(); + type_ = e; + switch (type_) { + case types::sib_guardband_anchor_r15: + c.init(); + break; + case types::sib_guardband_guardband_r15: + c.init(); + break; + case types::sib_guardband_inband_same_pci_r15: + c.init(); + break; + case types::sib_guardbandinband_diff_pci_r15: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); + } } - -const char* nprach_params_nb_r13_s::nprach_periodicity_r13_opts::to_string() const +guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::sib_guardband_info_r15_c_( + const guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_& other) { - static const char* options[] = {"ms40", "ms80", "ms160", "ms240", "ms320", "ms640", "ms1280", "ms2560"}; - return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::nprach_periodicity_r13_e_"); + type_ = other.type(); + switch (type_) { + case types::sib_guardband_anchor_r15: + c.init(other.c.get()); + break; + case types::sib_guardband_guardband_r15: + c.init(other.c.get()); + break; + case types::sib_guardband_inband_same_pci_r15: + c.init(other.c.get()); + break; + case types::sib_guardbandinband_diff_pci_r15: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); + } } -uint16_t nprach_params_nb_r13_s::nprach_periodicity_r13_opts::to_number() const +guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_& guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::operator=( + const guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_& other) { - static const uint16_t options[] = {40, 80, 160, 240, 320, 640, 1280, 2560}; - return map_enum_number(options, 8, value, "nprach_params_nb_r13_s::nprach_periodicity_r13_e_"); -} + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::sib_guardband_anchor_r15: + c.set(other.c.get()); + break; + case types::sib_guardband_guardband_r15: + c.set(other.c.get()); + break; + case types::sib_guardband_inband_same_pci_r15: + c.set(other.c.get()); + break; + case types::sib_guardbandinband_diff_pci_r15: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); + } -const char* nprach_params_nb_r13_s::nprach_start_time_r13_opts::to_string() const -{ - static const char* options[] = {"ms8", "ms16", "ms32", "ms64", "ms128", "ms256", "ms512", "ms1024"}; - return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::nprach_start_time_r13_e_"); + return *this; } -uint16_t nprach_params_nb_r13_s::nprach_start_time_r13_opts::to_number() const +sib_guardband_anchor_tdd_nb_r15_s& guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::set_sib_guardband_anchor_r15() { - static const uint16_t options[] = {8, 16, 32, 64, 128, 256, 512, 1024}; - return map_enum_number(options, 8, value, "nprach_params_nb_r13_s::nprach_start_time_r13_e_"); + set(types::sib_guardband_anchor_r15); + return c.get(); } - -const char* nprach_params_nb_r13_s::nprach_subcarrier_offset_r13_opts::to_string() const +sib_guardband_guardband_tdd_nb_r15_s& +guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::set_sib_guardband_guardband_r15() { - static const char* options[] = {"n0", "n12", "n24", "n36", "n2", "n18", "n34", "spare1"}; - return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::nprach_subcarrier_offset_r13_e_"); + set(types::sib_guardband_guardband_r15); + return c.get(); } -uint8_t nprach_params_nb_r13_s::nprach_subcarrier_offset_r13_opts::to_number() const +sib_guardband_inband_same_pci_tdd_nb_r15_s& +guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::set_sib_guardband_inband_same_pci_r15() { - static const uint8_t options[] = {0, 12, 24, 36, 2, 18, 34}; - return map_enum_number(options, 7, value, "nprach_params_nb_r13_s::nprach_subcarrier_offset_r13_e_"); + set(types::sib_guardband_inband_same_pci_r15); + return c.get(); } - -const char* nprach_params_nb_r13_s::nprach_num_subcarriers_r13_opts::to_string() const +sib_guardband_inband_diff_pci_tdd_nb_r15_s& +guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::set_sib_guardbandinband_diff_pci_r15() { - static const char* options[] = {"n12", "n24", "n36", "n48"}; - return convert_enum_idx(options, 4, value, "nprach_params_nb_r13_s::nprach_num_subcarriers_r13_e_"); + set(types::sib_guardbandinband_diff_pci_r15); + return c.get(); } -uint8_t nprach_params_nb_r13_s::nprach_num_subcarriers_r13_opts::to_number() const +void guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::to_json(json_writer& j) const { - static const uint8_t options[] = {12, 24, 36, 48}; - return map_enum_number(options, 4, value, "nprach_params_nb_r13_s::nprach_num_subcarriers_r13_e_"); + j.start_obj(); + switch (type_) { + case types::sib_guardband_anchor_r15: + j.write_fieldname("sib-GuardbandAnchor-r15"); + c.get().to_json(j); + break; + case types::sib_guardband_guardband_r15: + j.write_fieldname("sib-GuardbandGuardband-r15"); + c.get().to_json(j); + break; + case types::sib_guardband_inband_same_pci_r15: + j.write_fieldname("sib-GuardbandInbandSamePCI-r15"); + c.get().to_json(j); + break; + case types::sib_guardbandinband_diff_pci_r15: + j.write_fieldname("sib-GuardbandinbandDiffPCI-r15"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); + } + j.end_obj(); } - -const char* nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_opts::to_string() const +SRSASN_CODE guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::pack(bit_ref& bref) const { - static const char* options[] = {"zero", "oneThird", "twoThird", "one"}; - return convert_enum_idx(options, 4, value, "nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_e_"); + type_.pack(bref); + switch (type_) { + case types::sib_guardband_anchor_r15: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::sib_guardband_guardband_r15: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::sib_guardband_inband_same_pci_r15: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::sib_guardbandinband_diff_pci_r15: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; } -float nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_opts::to_number() const +SRSASN_CODE guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::unpack(cbit_ref& bref) { - static const float options[] = {0.0, 0.3333333333333333, 0.6666666666666666, 1.0}; - return map_enum_number(options, 4, value, "nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_e_"); + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::sib_guardband_anchor_r15: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::sib_guardband_guardband_r15: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::sib_guardband_inband_same_pci_r15: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::sib_guardbandinband_diff_pci_r15: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; } -const char* nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_opts::to_number_string() const + +const char* guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::types_opts::to_string() const { - static const char* options[] = {"0", "1/3", "2/3", "1"}; - return convert_enum_idx(options, 4, value, "nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_e_"); + static const char* options[] = {"sib-GuardbandAnchor-r15", + "sib-GuardbandGuardband-r15", + "sib-GuardbandInbandSamePCI-r15", + "sib-GuardbandinbandDiffPCI-r15"}; + return convert_enum_idx(options, 4, value, "guardband_tdd_nb_r15_s::sib_guardband_info_r15_c_::types"); } -const char* nprach_params_nb_r13_s::max_num_preamb_attempt_ce_r13_opts::to_string() const +const char* guardband_tdd_nb_r15_s::eutra_bandwitdh_r15_opts::to_string() const { - static const char* options[] = {"n3", "n4", "n5", "n6", "n7", "n8", "n10", "spare1"}; - return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::max_num_preamb_attempt_ce_r13_e_"); + static const char* options[] = {"bw5or10", "bw15or20"}; + return convert_enum_idx(options, 2, value, "guardband_tdd_nb_r15_s::eutra_bandwitdh_r15_e_"); } -uint8_t nprach_params_nb_r13_s::max_num_preamb_attempt_ce_r13_opts::to_number() const +uint8_t guardband_tdd_nb_r15_s::eutra_bandwitdh_r15_opts::to_number() const { - static const uint8_t options[] = {3, 4, 5, 6, 7, 8, 10}; - return map_enum_number(options, 7, value, "nprach_params_nb_r13_s::max_num_preamb_attempt_ce_r13_e_"); + static const uint8_t options[] = {5, 15}; + return map_enum_number(options, 2, value, "guardband_tdd_nb_r15_s::eutra_bandwitdh_r15_e_"); } -const char* nprach_params_nb_r13_s::num_repeats_per_preamb_attempt_r13_opts::to_string() const +// Inband-DifferentPCI-TDD-NB-r15 ::= SEQUENCE +SRSASN_CODE inband_different_pci_tdd_nb_r15_s::pack(bit_ref& bref) const { - static const char* options[] = {"n1", "n2", "n4", "n8", "n16", "n32", "n64", "n128"}; - return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::num_repeats_per_preamb_attempt_r13_e_"); + HANDLE_CODE(eutra_num_crs_ports_r15.pack(bref)); + HANDLE_CODE(raster_offset_r15.pack(bref)); + HANDLE_CODE(sib_inband_location_r15.pack(bref)); + HANDLE_CODE(spare.pack(bref)); + + return SRSASN_SUCCESS; } -uint8_t nprach_params_nb_r13_s::num_repeats_per_preamb_attempt_r13_opts::to_number() const +SRSASN_CODE inband_different_pci_tdd_nb_r15_s::unpack(cbit_ref& bref) { - static const uint8_t options[] = {1, 2, 4, 8, 16, 32, 64, 128}; - return map_enum_number(options, 8, value, "nprach_params_nb_r13_s::num_repeats_per_preamb_attempt_r13_e_"); -} + HANDLE_CODE(eutra_num_crs_ports_r15.unpack(bref)); + HANDLE_CODE(raster_offset_r15.unpack(bref)); + HANDLE_CODE(sib_inband_location_r15.unpack(bref)); + HANDLE_CODE(spare.unpack(bref)); -const char* nprach_params_nb_r13_s::npdcch_num_repeats_ra_r13_opts::to_string() const -{ - static const char* options[] = {"r1", - "r2", - "r4", - "r8", - "r16", - "r32", - "r64", - "r128", - "r256", - "r512", - "r1024", - "r2048", - "spare4", - "spare3", - "spare2", - "spare1"}; - return convert_enum_idx(options, 16, value, "nprach_params_nb_r13_s::npdcch_num_repeats_ra_r13_e_"); + return SRSASN_SUCCESS; } -uint16_t nprach_params_nb_r13_s::npdcch_num_repeats_ra_r13_opts::to_number() const +void inband_different_pci_tdd_nb_r15_s::to_json(json_writer& j) const { - static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; - return map_enum_number(options, 12, value, "nprach_params_nb_r13_s::npdcch_num_repeats_ra_r13_e_"); + j.start_obj(); + j.write_str("eutra-NumCRS-Ports-r15", eutra_num_crs_ports_r15.to_string()); + j.write_str("rasterOffset-r15", raster_offset_r15.to_string()); + j.write_str("sib-InbandLocation-r15", sib_inband_location_r15.to_string()); + j.write_str("spare", spare.to_string()); + j.end_obj(); } -const char* nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_opts::to_string() const +const char* inband_different_pci_tdd_nb_r15_s::eutra_num_crs_ports_r15_opts::to_string() const { - static const char* options[] = {"v1dot5", "v2", "v4", "v8", "v16", "v32", "v48", "v64"}; - return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_e_"); + static const char* options[] = {"same", "four"}; + return convert_enum_idx(options, 2, value, "inband_different_pci_tdd_nb_r15_s::eutra_num_crs_ports_r15_e_"); } -float nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_opts::to_number() const +uint8_t inband_different_pci_tdd_nb_r15_s::eutra_num_crs_ports_r15_opts::to_number() const { - static const float options[] = {1.5, 2.0, 4.0, 8.0, 16.0, 32.0, 48.0, 64.0}; - return map_enum_number(options, 8, value, "nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_e_"); + if (value == four) { + return 4; + } + invalid_enum_number(value, "inband_different_pci_tdd_nb_r15_s::eutra_num_crs_ports_r15_e_"); + return 0; } -const char* nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_opts::to_number_string() const + +const char* inband_different_pci_tdd_nb_r15_s::sib_inband_location_r15_opts::to_string() const { - static const char* options[] = {"1.5", "2", "4", "8", "16", "32", "48", "64"}; - return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_e_"); + static const char* options[] = {"lower", "higher"}; + return convert_enum_idx(options, 2, value, "inband_different_pci_tdd_nb_r15_s::sib_inband_location_r15_e_"); } -const char* nprach_params_nb_r13_s::npdcch_offset_ra_r13_opts::to_string() const +// Inband-SamePCI-TDD-NB-r15 ::= SEQUENCE +SRSASN_CODE inband_same_pci_tdd_nb_r15_s::pack(bit_ref& bref) const { - static const char* options[] = {"zero", "oneEighth", "oneFourth", "threeEighth"}; - return convert_enum_idx(options, 4, value, "nprach_params_nb_r13_s::npdcch_offset_ra_r13_e_"); + HANDLE_CODE(pack_integer(bref, eutra_crs_seq_info_r15, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(sib_inband_location_r15.pack(bref)); + + return SRSASN_SUCCESS; } -float nprach_params_nb_r13_s::npdcch_offset_ra_r13_opts::to_number() const +SRSASN_CODE inband_same_pci_tdd_nb_r15_s::unpack(cbit_ref& bref) { - static const float options[] = {0.0, 0.125, 0.25, 0.375}; - return map_enum_number(options, 4, value, "nprach_params_nb_r13_s::npdcch_offset_ra_r13_e_"); + HANDLE_CODE(unpack_integer(eutra_crs_seq_info_r15, bref, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(sib_inband_location_r15.unpack(bref)); + + return SRSASN_SUCCESS; } -const char* nprach_params_nb_r13_s::npdcch_offset_ra_r13_opts::to_number_string() const +void inband_same_pci_tdd_nb_r15_s::to_json(json_writer& j) const { - static const char* options[] = {"0", "1/8", "1/4", "3/8"}; - return convert_enum_idx(options, 4, value, "nprach_params_nb_r13_s::npdcch_offset_ra_r13_e_"); + j.start_obj(); + j.write_int("eutra-CRS-SequenceInfo-r15", eutra_crs_seq_info_r15); + j.write_str("sib-InbandLocation-r15", sib_inband_location_r15.to_string()); + j.end_obj(); } -// NPRACH-Parameters-NB-r14 ::= SEQUENCE -SRSASN_CODE nprach_params_nb_r14_s::pack(bit_ref& bref) const +const char* inband_same_pci_tdd_nb_r15_s::sib_inband_location_r15_opts::to_string() const { - HANDLE_CODE(bref.pack(nprach_params_r14_present, 1)); + static const char* options[] = {"lower", "higher"}; + return convert_enum_idx(options, 2, value, "inband_same_pci_tdd_nb_r15_s::sib_inband_location_r15_e_"); +} - if (nprach_params_r14_present) { - bref.pack(nprach_params_r14.ext, 1); - HANDLE_CODE(bref.pack(nprach_params_r14.nprach_periodicity_r14_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r14.nprach_start_time_r14_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r14.nprach_subcarrier_offset_r14_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r14.nprach_num_subcarriers_r14_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r14.nprach_subcarrier_msg3_range_start_r14_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r14.npdcch_num_repeats_ra_r14_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r14.npdcch_start_sf_css_ra_r14_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r14.npdcch_offset_ra_r14_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r14.nprach_num_cbra_start_subcarriers_r14_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r14.npdcch_carrier_idx_r14_present, 1)); - if (nprach_params_r14.nprach_periodicity_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_periodicity_r14.pack(bref)); - } - if (nprach_params_r14.nprach_start_time_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_start_time_r14.pack(bref)); - } - if (nprach_params_r14.nprach_subcarrier_offset_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_subcarrier_offset_r14.pack(bref)); - } - if (nprach_params_r14.nprach_num_subcarriers_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_num_subcarriers_r14.pack(bref)); - } - if (nprach_params_r14.nprach_subcarrier_msg3_range_start_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_subcarrier_msg3_range_start_r14.pack(bref)); - } - if (nprach_params_r14.npdcch_num_repeats_ra_r14_present) { - HANDLE_CODE(nprach_params_r14.npdcch_num_repeats_ra_r14.pack(bref)); - } - if (nprach_params_r14.npdcch_start_sf_css_ra_r14_present) { - HANDLE_CODE(nprach_params_r14.npdcch_start_sf_css_ra_r14.pack(bref)); - } - if (nprach_params_r14.npdcch_offset_ra_r14_present) { - HANDLE_CODE(nprach_params_r14.npdcch_offset_ra_r14.pack(bref)); - } - if (nprach_params_r14.nprach_num_cbra_start_subcarriers_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_num_cbra_start_subcarriers_r14.pack(bref)); - } - if (nprach_params_r14.npdcch_carrier_idx_r14_present) { - HANDLE_CODE(pack_integer(bref, nprach_params_r14.npdcch_carrier_idx_r14, (uint8_t)1u, (uint8_t)15u)); - } - } +// StandaloneTDD-NB-r15 ::= SEQUENCE +SRSASN_CODE standalone_tdd_nb_r15_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(sib_standalone_location_r15.pack(bref)); + HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE nprach_params_nb_r14_s::unpack(cbit_ref& bref) +SRSASN_CODE standalone_tdd_nb_r15_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(nprach_params_r14_present, 1)); - - if (nprach_params_r14_present) { - bref.unpack(nprach_params_r14.ext, 1); - HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_periodicity_r14_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_start_time_r14_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_subcarrier_offset_r14_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_num_subcarriers_r14_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_subcarrier_msg3_range_start_r14_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r14.npdcch_num_repeats_ra_r14_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r14.npdcch_start_sf_css_ra_r14_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r14.npdcch_offset_ra_r14_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_num_cbra_start_subcarriers_r14_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r14.npdcch_carrier_idx_r14_present, 1)); - if (nprach_params_r14.nprach_periodicity_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_periodicity_r14.unpack(bref)); - } - if (nprach_params_r14.nprach_start_time_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_start_time_r14.unpack(bref)); - } - if (nprach_params_r14.nprach_subcarrier_offset_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_subcarrier_offset_r14.unpack(bref)); - } - if (nprach_params_r14.nprach_num_subcarriers_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_num_subcarriers_r14.unpack(bref)); - } - if (nprach_params_r14.nprach_subcarrier_msg3_range_start_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_subcarrier_msg3_range_start_r14.unpack(bref)); - } - if (nprach_params_r14.npdcch_num_repeats_ra_r14_present) { - HANDLE_CODE(nprach_params_r14.npdcch_num_repeats_ra_r14.unpack(bref)); - } - if (nprach_params_r14.npdcch_start_sf_css_ra_r14_present) { - HANDLE_CODE(nprach_params_r14.npdcch_start_sf_css_ra_r14.unpack(bref)); - } - if (nprach_params_r14.npdcch_offset_ra_r14_present) { - HANDLE_CODE(nprach_params_r14.npdcch_offset_ra_r14.unpack(bref)); - } - if (nprach_params_r14.nprach_num_cbra_start_subcarriers_r14_present) { - HANDLE_CODE(nprach_params_r14.nprach_num_cbra_start_subcarriers_r14.unpack(bref)); - } - if (nprach_params_r14.npdcch_carrier_idx_r14_present) { - HANDLE_CODE(unpack_integer(nprach_params_r14.npdcch_carrier_idx_r14, bref, (uint8_t)1u, (uint8_t)15u)); - } - } + HANDLE_CODE(sib_standalone_location_r15.unpack(bref)); + HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void nprach_params_nb_r14_s::to_json(json_writer& j) const +void standalone_tdd_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - if (nprach_params_r14_present) { - j.write_fieldname("nprach-Parameters-r14"); - j.start_obj(); - if (nprach_params_r14.nprach_periodicity_r14_present) { - j.write_str("nprach-Periodicity-r14", nprach_params_r14.nprach_periodicity_r14.to_string()); - } - if (nprach_params_r14.nprach_start_time_r14_present) { - j.write_str("nprach-StartTime-r14", nprach_params_r14.nprach_start_time_r14.to_string()); - } - if (nprach_params_r14.nprach_subcarrier_offset_r14_present) { - j.write_str("nprach-SubcarrierOffset-r14", nprach_params_r14.nprach_subcarrier_offset_r14.to_string()); - } - if (nprach_params_r14.nprach_num_subcarriers_r14_present) { - j.write_str("nprach-NumSubcarriers-r14", nprach_params_r14.nprach_num_subcarriers_r14.to_string()); - } - if (nprach_params_r14.nprach_subcarrier_msg3_range_start_r14_present) { - j.write_str("nprach-SubcarrierMSG3-RangeStart-r14", - nprach_params_r14.nprach_subcarrier_msg3_range_start_r14.to_string()); - } - if (nprach_params_r14.npdcch_num_repeats_ra_r14_present) { - j.write_str("npdcch-NumRepetitions-RA-r14", nprach_params_r14.npdcch_num_repeats_ra_r14.to_string()); - } - if (nprach_params_r14.npdcch_start_sf_css_ra_r14_present) { - j.write_str("npdcch-StartSF-CSS-RA-r14", nprach_params_r14.npdcch_start_sf_css_ra_r14.to_string()); - } - if (nprach_params_r14.npdcch_offset_ra_r14_present) { - j.write_str("npdcch-Offset-RA-r14", nprach_params_r14.npdcch_offset_ra_r14.to_string()); - } - if (nprach_params_r14.nprach_num_cbra_start_subcarriers_r14_present) { - j.write_str("nprach-NumCBRA-StartSubcarriers-r14", - nprach_params_r14.nprach_num_cbra_start_subcarriers_r14.to_string()); - } - if (nprach_params_r14.npdcch_carrier_idx_r14_present) { - j.write_int("npdcch-CarrierIndex-r14", nprach_params_r14.npdcch_carrier_idx_r14); - } - j.end_obj(); - } + j.write_str("sib-StandaloneLocation-r15", sib_standalone_location_r15.to_string()); + j.write_str("spare", spare.to_string()); j.end_obj(); } -const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_periodicity_r14_opts::to_string() const +const char* standalone_tdd_nb_r15_s::sib_standalone_location_r15_opts::to_string() const { - static const char* options[] = {"ms40", "ms80", "ms160", "ms240", "ms320", "ms640", "ms1280", "ms2560"}; - return convert_enum_idx(options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_periodicity_r14_e_"); + static const char* options[] = {"lower", "higher"}; + return convert_enum_idx(options, 2, value, "standalone_tdd_nb_r15_s::sib_standalone_location_r15_e_"); } -uint16_t nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_periodicity_r14_opts::to_number() const + +// MasterInformationBlock-TDD-NB-r15 ::= SEQUENCE +SRSASN_CODE mib_tdd_nb_r15_s::pack(bit_ref& bref) const { - static const uint16_t options[] = {40, 80, 160, 240, 320, 640, 1280, 2560}; - return map_enum_number(options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_periodicity_r14_e_"); -} + HANDLE_CODE(sys_frame_num_msb_r15.pack(bref)); + HANDLE_CODE(hyper_sfn_lsb_r15.pack(bref)); + HANDLE_CODE(pack_integer(bref, sched_info_sib1_r15, (uint8_t)0u, (uint8_t)15u)); + HANDLE_CODE(pack_integer(bref, sys_info_value_tag_r15, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(bref.pack(ab_enabled_r15, 1)); + HANDLE_CODE(operation_mode_info_r15.pack(bref)); + HANDLE_CODE(sib1_carrier_info_r15.pack(bref)); + HANDLE_CODE(bref.pack(ab_enabled_minus5_gc_r16, 1)); + HANDLE_CODE(spare.pack(bref)); -const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_start_time_r14_opts::to_string() const + return SRSASN_SUCCESS; +} +SRSASN_CODE mib_tdd_nb_r15_s::unpack(cbit_ref& bref) { - static const char* options[] = {"ms8", "ms16", "ms32", "ms64", "ms128", "ms256", "ms512", "ms1024"}; - return convert_enum_idx(options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_start_time_r14_e_"); + HANDLE_CODE(sys_frame_num_msb_r15.unpack(bref)); + HANDLE_CODE(hyper_sfn_lsb_r15.unpack(bref)); + HANDLE_CODE(unpack_integer(sched_info_sib1_r15, bref, (uint8_t)0u, (uint8_t)15u)); + HANDLE_CODE(unpack_integer(sys_info_value_tag_r15, bref, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(bref.unpack(ab_enabled_r15, 1)); + HANDLE_CODE(operation_mode_info_r15.unpack(bref)); + HANDLE_CODE(sib1_carrier_info_r15.unpack(bref)); + HANDLE_CODE(bref.unpack(ab_enabled_minus5_gc_r16, 1)); + HANDLE_CODE(spare.unpack(bref)); + + return SRSASN_SUCCESS; } -uint16_t nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_start_time_r14_opts::to_number() const +void mib_tdd_nb_r15_s::to_json(json_writer& j) const { - static const uint16_t options[] = {8, 16, 32, 64, 128, 256, 512, 1024}; - return map_enum_number(options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_start_time_r14_e_"); + j.start_obj(); + j.write_str("systemFrameNumber-MSB-r15", sys_frame_num_msb_r15.to_string()); + j.write_str("hyperSFN-LSB-r15", hyper_sfn_lsb_r15.to_string()); + j.write_int("schedulingInfoSIB1-r15", sched_info_sib1_r15); + j.write_int("systemInfoValueTag-r15", sys_info_value_tag_r15); + j.write_bool("ab-Enabled-r15", ab_enabled_r15); + j.write_fieldname("operationModeInfo-r15"); + operation_mode_info_r15.to_json(j); + j.write_str("sib1-CarrierInfo-r15", sib1_carrier_info_r15.to_string()); + j.write_bool("ab-Enabled-5GC-r16", ab_enabled_minus5_gc_r16); + j.write_str("spare", spare.to_string()); + j.end_obj(); } -const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_offset_r14_opts::to_string() const +void mib_tdd_nb_r15_s::operation_mode_info_r15_c_::destroy_() { - static const char* options[] = {"n0", "n12", "n24", "n36", "n2", "n18", "n34", "spare1"}; - return convert_enum_idx( - options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_offset_r14_e_"); + switch (type_) { + case types::inband_same_pci_r15: + c.destroy(); + break; + case types::inband_different_pci_r15: + c.destroy(); + break; + case types::guardband_r15: + c.destroy(); + break; + case types::standalone_r15: + c.destroy(); + break; + default: + break; + } } -uint8_t nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_offset_r14_opts::to_number() const +void mib_tdd_nb_r15_s::operation_mode_info_r15_c_::set(types::options e) { - static const uint8_t options[] = {0, 12, 24, 36, 2, 18, 34}; - return map_enum_number( - options, 7, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_offset_r14_e_"); + destroy_(); + type_ = e; + switch (type_) { + case types::inband_same_pci_r15: + c.init(); + break; + case types::inband_different_pci_r15: + c.init(); + break; + case types::guardband_r15: + c.init(); + break; + case types::standalone_r15: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + } } - -const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_subcarriers_r14_opts::to_string() const +mib_tdd_nb_r15_s::operation_mode_info_r15_c_::operation_mode_info_r15_c_( + const mib_tdd_nb_r15_s::operation_mode_info_r15_c_& other) { - static const char* options[] = {"n12", "n24", "n36", "n48"}; - return convert_enum_idx( - options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_subcarriers_r14_e_"); + type_ = other.type(); + switch (type_) { + case types::inband_same_pci_r15: + c.init(other.c.get()); + break; + case types::inband_different_pci_r15: + c.init(other.c.get()); + break; + case types::guardband_r15: + c.init(other.c.get()); + break; + case types::standalone_r15: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + } } -uint8_t nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_subcarriers_r14_opts::to_number() const +mib_tdd_nb_r15_s::operation_mode_info_r15_c_& +mib_tdd_nb_r15_s::operation_mode_info_r15_c_::operator=(const mib_tdd_nb_r15_s::operation_mode_info_r15_c_& other) { - static const uint8_t options[] = {12, 24, 36, 48}; - return map_enum_number( - options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_subcarriers_r14_e_"); -} + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::inband_same_pci_r15: + c.set(other.c.get()); + break; + case types::inband_different_pci_r15: + c.set(other.c.get()); + break; + case types::guardband_r15: + c.set(other.c.get()); + break; + case types::standalone_r15: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + } -const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_opts::to_string() const + return *this; +} +inband_same_pci_tdd_nb_r15_s& mib_tdd_nb_r15_s::operation_mode_info_r15_c_::set_inband_same_pci_r15() { - static const char* options[] = {"zero", "oneThird", "twoThird", "one"}; - return convert_enum_idx( - options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_e_"); + set(types::inband_same_pci_r15); + return c.get(); } -float nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_opts::to_number() const +inband_different_pci_tdd_nb_r15_s& mib_tdd_nb_r15_s::operation_mode_info_r15_c_::set_inband_different_pci_r15() { - static const float options[] = {0.0, 0.3333333333333333, 0.6666666666666666, 1.0}; - return map_enum_number( - options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_e_"); + set(types::inband_different_pci_r15); + return c.get(); } -const char* -nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_opts::to_number_string() const +guardband_tdd_nb_r15_s& mib_tdd_nb_r15_s::operation_mode_info_r15_c_::set_guardband_r15() { - static const char* options[] = {"0", "1/3", "2/3", "1"}; - return convert_enum_idx( - options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_e_"); + set(types::guardband_r15); + return c.get(); } - -const char* nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_num_repeats_ra_r14_opts::to_string() const +standalone_tdd_nb_r15_s& mib_tdd_nb_r15_s::operation_mode_info_r15_c_::set_standalone_r15() { - static const char* options[] = {"r1", - "r2", - "r4", - "r8", - "r16", - "r32", - "r64", - "r128", - "r256", - "r512", - "r1024", - "r2048", - "spare4", - "spare3", - "spare2", - "spare1"}; - return convert_enum_idx( - options, 16, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_num_repeats_ra_r14_e_"); + set(types::standalone_r15); + return c.get(); } -uint16_t nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_num_repeats_ra_r14_opts::to_number() const +void mib_tdd_nb_r15_s::operation_mode_info_r15_c_::to_json(json_writer& j) const { - static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; - return map_enum_number( - options, 12, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_num_repeats_ra_r14_e_"); + j.start_obj(); + switch (type_) { + case types::inband_same_pci_r15: + j.write_fieldname("inband-SamePCI-r15"); + c.get().to_json(j); + break; + case types::inband_different_pci_r15: + j.write_fieldname("inband-DifferentPCI-r15"); + c.get().to_json(j); + break; + case types::guardband_r15: + j.write_fieldname("guardband-r15"); + c.get().to_json(j); + break; + case types::standalone_r15: + j.write_fieldname("standalone-r15"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + } + j.end_obj(); +} +SRSASN_CODE mib_tdd_nb_r15_s::operation_mode_info_r15_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::inband_same_pci_r15: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::inband_different_pci_r15: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::guardband_r15: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::standalone_r15: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE mib_tdd_nb_r15_s::operation_mode_info_r15_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::inband_same_pci_r15: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::inband_different_pci_r15: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::guardband_r15: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::standalone_r15: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; } -const char* nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_opts::to_string() const +const char* mib_tdd_nb_r15_s::operation_mode_info_r15_c_::types_opts::to_string() const { - static const char* options[] = {"v1dot5", "v2", "v4", "v8", "v16", "v32", "v48", "v64"}; - return convert_enum_idx( - options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_e_"); + static const char* options[] = {"inband-SamePCI-r15", "inband-DifferentPCI-r15", "guardband-r15", "standalone-r15"}; + return convert_enum_idx(options, 4, value, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_::types"); } -float nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_opts::to_number() const +uint8_t mib_tdd_nb_r15_s::operation_mode_info_r15_c_::types_opts::to_number() const { - static const float options[] = {1.5, 2.0, 4.0, 8.0, 16.0, 32.0, 48.0, 64.0}; - return map_enum_number( - options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_e_"); + if (value == standalone_r15) { + return 1; + } + invalid_enum_number(value, "mib_tdd_nb_r15_s::operation_mode_info_r15_c_::types"); + return 0; } -const char* nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_opts::to_number_string() const + +const char* mib_tdd_nb_r15_s::sib1_carrier_info_r15_opts::to_string() const { - static const char* options[] = {"1.5", "2", "4", "8", "16", "32", "48", "64"}; - return convert_enum_idx( - options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_e_"); + static const char* options[] = {"anchor", "non-anchor"}; + return convert_enum_idx(options, 2, value, "mib_tdd_nb_r15_s::sib1_carrier_info_r15_e_"); } -const char* nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_opts::to_string() const +// BCCH-BCH-Message-TDD-NB ::= SEQUENCE +SRSASN_CODE bcch_bch_msg_tdd_nb_s::pack(bit_ref& bref) const { - static const char* options[] = {"zero", "oneEighth", "oneFourth", "threeEighth"}; - return convert_enum_idx(options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_e_"); + HANDLE_CODE(msg.pack(bref)); + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; } -float nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_opts::to_number() const +SRSASN_CODE bcch_bch_msg_tdd_nb_s::unpack(cbit_ref& bref) { - static const float options[] = {0.0, 0.125, 0.25, 0.375}; - return map_enum_number(options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_e_"); + HANDLE_CODE(msg.unpack(bref)); + + bref.align_bytes(); + + return SRSASN_SUCCESS; } -const char* nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_opts::to_number_string() const +void bcch_bch_msg_tdd_nb_s::to_json(json_writer& j) const { - static const char* options[] = {"0", "1/8", "1/4", "3/8"}; - return convert_enum_idx(options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_e_"); + j.start_array(); + j.start_obj(); + j.start_obj("BCCH-BCH-Message-TDD-NB"); + j.write_fieldname("message"); + msg.to_json(j); + j.end_obj(); + j.end_obj(); + j.end_array(); } -const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_cbra_start_subcarriers_r14_opts::to_string() const +// NS-PmaxValue-NB-r13 ::= SEQUENCE +SRSASN_CODE ns_pmax_value_nb_r13_s::pack(bit_ref& bref) const { - static const char* options[] = { - "n8", "n10", "n11", "n12", "n20", "n22", "n23", "n24", "n32", "n34", "n35", "n36", "n40", "n44", "n46", "n48"}; - return convert_enum_idx( - options, 16, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_cbra_start_subcarriers_r14_e_"); + HANDLE_CODE(bref.pack(add_pmax_r13_present, 1)); + + if (add_pmax_r13_present) { + HANDLE_CODE(pack_integer(bref, add_pmax_r13, (int8_t)-30, (int8_t)33)); + } + HANDLE_CODE(pack_integer(bref, add_spec_emission_r13, (uint8_t)1u, (uint8_t)32u)); + + return SRSASN_SUCCESS; } -uint8_t nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_cbra_start_subcarriers_r14_opts::to_number() const +SRSASN_CODE ns_pmax_value_nb_r13_s::unpack(cbit_ref& bref) { - static const uint8_t options[] = {8, 10, 11, 12, 20, 22, 23, 24, 32, 34, 35, 36, 40, 44, 46, 48}; - return map_enum_number( - options, 16, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_cbra_start_subcarriers_r14_e_"); + HANDLE_CODE(bref.unpack(add_pmax_r13_present, 1)); + + if (add_pmax_r13_present) { + HANDLE_CODE(unpack_integer(add_pmax_r13, bref, (int8_t)-30, (int8_t)33)); + } + HANDLE_CODE(unpack_integer(add_spec_emission_r13, bref, (uint8_t)1u, (uint8_t)32u)); + + return SRSASN_SUCCESS; +} +void ns_pmax_value_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (add_pmax_r13_present) { + j.write_int("additionalPmax-r13", add_pmax_r13); + } + j.write_int("additionalSpectrumEmission-r13", add_spec_emission_r13); + j.end_obj(); } -// NPRACH-Parameters-NB-v1330 ::= SEQUENCE -SRSASN_CODE nprach_params_nb_v1330_s::pack(bit_ref& bref) const +// PLMN-IdentityInfo-NB-v1700 ::= SEQUENCE +SRSASN_CODE plmn_id_info_nb_v1700_s::pack(bit_ref& bref) const { - HANDLE_CODE(nprach_num_cbra_start_subcarriers_r13.pack(bref)); + HANDLE_CODE(bref.pack(tracking_area_list_r17_present, 1)); + + if (tracking_area_list_r17_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, tracking_area_list_r17, 1, 12)); + } return SRSASN_SUCCESS; } -SRSASN_CODE nprach_params_nb_v1330_s::unpack(cbit_ref& bref) +SRSASN_CODE plmn_id_info_nb_v1700_s::unpack(cbit_ref& bref) { - HANDLE_CODE(nprach_num_cbra_start_subcarriers_r13.unpack(bref)); + HANDLE_CODE(bref.unpack(tracking_area_list_r17_present, 1)); + + if (tracking_area_list_r17_present) { + HANDLE_CODE(unpack_dyn_seq_of(tracking_area_list_r17, bref, 1, 12)); + } return SRSASN_SUCCESS; } -void nprach_params_nb_v1330_s::to_json(json_writer& j) const +void plmn_id_info_nb_v1700_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("nprach-NumCBRA-StartSubcarriers-r13", nprach_num_cbra_start_subcarriers_r13.to_string()); + if (tracking_area_list_r17_present) { + j.start_array("trackingAreaList-r17"); + for (const auto& e1 : tracking_area_list_r17) { + j.write_str(e1.to_string()); + } + j.end_array(); + } j.end_obj(); } -const char* nprach_params_nb_v1330_s::nprach_num_cbra_start_subcarriers_r13_opts::to_string() const +// SIB-Type-NB-v1530 ::= ENUMERATED +const char* sib_type_nb_v1530_opts::to_string() const { - static const char* options[] = { - "n8", "n10", "n11", "n12", "n20", "n22", "n23", "n24", "n32", "n34", "n35", "n36", "n40", "n44", "n46", "n48"}; - return convert_enum_idx(options, 16, value, "nprach_params_nb_v1330_s::nprach_num_cbra_start_subcarriers_r13_e_"); + static const char* options[] = {"sibType23-NB-r15", + "sibType27-NB-r16", + "sibType31-NB-r17", + "sibType32-NB-r17", + "spare4", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 8, value, "sib_type_nb_v1530_e"); } -uint8_t nprach_params_nb_v1330_s::nprach_num_cbra_start_subcarriers_r13_opts::to_number() const +uint8_t sib_type_nb_v1530_opts::to_number() const { - static const uint8_t options[] = {8, 10, 11, 12, 20, 22, 23, 24, 32, 34, 35, 36, 40, 44, 46, 48}; - return map_enum_number(options, 16, value, "nprach_params_nb_v1330_s::nprach_num_cbra_start_subcarriers_r13_e_"); + static const uint8_t options[] = {23, 27, 31, 32}; + return map_enum_number(options, 4, value, "sib_type_nb_v1530_e"); } -// NPRACH-ParametersFmt2-NB-r15 ::= SEQUENCE -SRSASN_CODE nprach_params_fmt2_nb_r15_s::pack(bit_ref& bref) const +// GWUS-NumGroups-NB-r16 ::= ENUMERATED +const char* gwus_num_groups_nb_r16_opts::to_string() const { - HANDLE_CODE(bref.pack(nprach_params_r15_present, 1)); + static const char* options[] = {"n1", "n2", "n4", "n8"}; + return convert_enum_idx(options, 4, value, "gwus_num_groups_nb_r16_e"); +} +uint8_t gwus_num_groups_nb_r16_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 4, 8}; + return map_enum_number(options, 4, value, "gwus_num_groups_nb_r16_e"); +} - if (nprach_params_r15_present) { - bref.pack(nprach_params_r15.ext, 1); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_periodicity_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_start_time_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_subcarrier_offset_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_num_subcarriers_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_num_repeats_ra_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_start_sf_css_ra_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_offset_ra_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_carrier_idx_r15_present, 1)); - if (nprach_params_r15.nprach_periodicity_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_periodicity_r15.pack(bref)); - } - if (nprach_params_r15.nprach_start_time_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_start_time_r15.pack(bref)); - } - if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_subcarrier_offset_r15.pack(bref)); - } - if (nprach_params_r15.nprach_num_subcarriers_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_num_subcarriers_r15.pack(bref)); - } - if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.pack(bref)); - } - if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_num_repeats_ra_r15.pack(bref)); - } - if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_start_sf_css_ra_r15.pack(bref)); - } - if (nprach_params_r15.npdcch_offset_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_offset_ra_r15.pack(bref)); - } - if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.pack(bref)); - } - if (nprach_params_r15.npdcch_carrier_idx_r15_present) { - HANDLE_CODE(pack_integer(bref, nprach_params_r15.npdcch_carrier_idx_r15, (uint8_t)1u, (uint8_t)15u)); - } +// NSSS-RRM-Config-NB-r15 ::= SEQUENCE +SRSASN_CODE nsss_rrm_cfg_nb_r15_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(nsss_num_occ_diff_precoders_r15_present, 1)); + + HANDLE_CODE(nsss_rrm_pwr_offset_r15.pack(bref)); + if (nsss_num_occ_diff_precoders_r15_present) { + HANDLE_CODE(nsss_num_occ_diff_precoders_r15.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE nprach_params_fmt2_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE nsss_rrm_cfg_nb_r15_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(nprach_params_r15_present, 1)); + HANDLE_CODE(bref.unpack(nsss_num_occ_diff_precoders_r15_present, 1)); - if (nprach_params_r15_present) { - bref.unpack(nprach_params_r15.ext, 1); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_periodicity_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_start_time_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_subcarrier_offset_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_num_subcarriers_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_num_repeats_ra_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_start_sf_css_ra_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_offset_ra_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_carrier_idx_r15_present, 1)); - if (nprach_params_r15.nprach_periodicity_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_periodicity_r15.unpack(bref)); - } - if (nprach_params_r15.nprach_start_time_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_start_time_r15.unpack(bref)); - } - if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_subcarrier_offset_r15.unpack(bref)); - } - if (nprach_params_r15.nprach_num_subcarriers_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_num_subcarriers_r15.unpack(bref)); - } - if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.unpack(bref)); - } - if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_num_repeats_ra_r15.unpack(bref)); - } - if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_start_sf_css_ra_r15.unpack(bref)); - } - if (nprach_params_r15.npdcch_offset_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_offset_ra_r15.unpack(bref)); - } - if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.unpack(bref)); - } - if (nprach_params_r15.npdcch_carrier_idx_r15_present) { - HANDLE_CODE(unpack_integer(nprach_params_r15.npdcch_carrier_idx_r15, bref, (uint8_t)1u, (uint8_t)15u)); - } + HANDLE_CODE(nsss_rrm_pwr_offset_r15.unpack(bref)); + if (nsss_num_occ_diff_precoders_r15_present) { + HANDLE_CODE(nsss_num_occ_diff_precoders_r15.unpack(bref)); } return SRSASN_SUCCESS; } -void nprach_params_fmt2_nb_r15_s::to_json(json_writer& j) const +void nsss_rrm_cfg_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - if (nprach_params_r15_present) { - j.write_fieldname("nprach-Parameters-r15"); - j.start_obj(); - if (nprach_params_r15.nprach_periodicity_r15_present) { - j.write_str("nprach-Periodicity-r15", nprach_params_r15.nprach_periodicity_r15.to_string()); - } - if (nprach_params_r15.nprach_start_time_r15_present) { - j.write_str("nprach-StartTime-r15", nprach_params_r15.nprach_start_time_r15.to_string()); - } - if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { - j.write_str("nprach-SubcarrierOffset-r15", nprach_params_r15.nprach_subcarrier_offset_r15.to_string()); - } - if (nprach_params_r15.nprach_num_subcarriers_r15_present) { - j.write_str("nprach-NumSubcarriers-r15", nprach_params_r15.nprach_num_subcarriers_r15.to_string()); - } - if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { - j.write_str("nprach-SubcarrierMSG3-RangeStart-r15", - nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.to_string()); - } - if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { - j.write_str("npdcch-NumRepetitions-RA-r15", nprach_params_r15.npdcch_num_repeats_ra_r15.to_string()); - } - if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { - j.write_str("npdcch-StartSF-CSS-RA-r15", nprach_params_r15.npdcch_start_sf_css_ra_r15.to_string()); - } - if (nprach_params_r15.npdcch_offset_ra_r15_present) { - j.write_str("npdcch-Offset-RA-r15", nprach_params_r15.npdcch_offset_ra_r15.to_string()); - } - if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { - j.write_str("nprach-NumCBRA-StartSubcarriers-r15", - nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.to_string()); - } - if (nprach_params_r15.npdcch_carrier_idx_r15_present) { - j.write_int("npdcch-CarrierIndex-r15", nprach_params_r15.npdcch_carrier_idx_r15); - } - j.end_obj(); + j.write_str("nsss-RRM-PowerOffset-r15", nsss_rrm_pwr_offset_r15.to_string()); + if (nsss_num_occ_diff_precoders_r15_present) { + j.write_str("nsss-NumOccDiffPrecoders-r15", nsss_num_occ_diff_precoders_r15.to_string()); } j.end_obj(); } -const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_opts::to_string() const +const char* nsss_rrm_cfg_nb_r15_s::nsss_rrm_pwr_offset_r15_opts::to_string() const { - static const char* options[] = {"ms40", "ms80", "ms160", "ms320", "ms640", "ms1280", "ms2560", "ms5120"}; - return convert_enum_idx( - options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_e_"); + static const char* options[] = {"dB-3", "db0", "dB3"}; + return convert_enum_idx(options, 3, value, "nsss_rrm_cfg_nb_r15_s::nsss_rrm_pwr_offset_r15_e_"); } -uint16_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_opts::to_number() const +int8_t nsss_rrm_cfg_nb_r15_s::nsss_rrm_pwr_offset_r15_opts::to_number() const { - static const uint16_t options[] = {40, 80, 160, 320, 640, 1280, 2560, 5120}; - return map_enum_number( - options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_e_"); + static const int8_t options[] = {-3, 0, 3}; + return map_enum_number(options, 3, value, "nsss_rrm_cfg_nb_r15_s::nsss_rrm_pwr_offset_r15_e_"); } -const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_opts::to_string() const +const char* nsss_rrm_cfg_nb_r15_s::nsss_num_occ_diff_precoders_r15_opts::to_string() const { - static const char* options[] = {"ms8", "ms16", "ms32", "ms64", "ms128", "ms256", "ms512", "ms1024"}; - return convert_enum_idx( - options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_e_"); + static const char* options[] = {"n1", "n2", "n4", "n8"}; + return convert_enum_idx(options, 4, value, "nsss_rrm_cfg_nb_r15_s::nsss_num_occ_diff_precoders_r15_e_"); } -uint16_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_opts::to_number() const +uint8_t nsss_rrm_cfg_nb_r15_s::nsss_num_occ_diff_precoders_r15_opts::to_number() const { - static const uint16_t options[] = {8, 16, 32, 64, 128, 256, 512, 1024}; - return map_enum_number( - options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_e_"); + static const uint8_t options[] = {1, 2, 4, 8}; + return map_enum_number(options, 4, value, "nsss_rrm_cfg_nb_r15_s::nsss_num_occ_diff_precoders_r15_e_"); } -const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_opts::to_string() const +// PLMN-IdentityInfo-5GC-NB-r16 ::= SEQUENCE +SRSASN_CODE plmn_id_info_minus5_gc_nb_r16_s::pack(bit_ref& bref) const { - static const char* options[] = { - "n0", "n36", "n72", "n108", "n6", "n54", "n102", "n42", "n78", "n90", "n12", "n24", "n48", "n84", "n60", "n18"}; - return convert_enum_idx( - options, 16, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_e_"); + HANDLE_CODE(bref.pack(ng_u_data_transfer_r16_present, 1)); + HANDLE_CODE(bref.pack(up_cio_t_minus5_gs_optim_r16_present, 1)); + + HANDLE_CODE(plmn_id_minus5_gc_r16.pack(bref)); + HANDLE_CODE(cell_reserved_for_oper_r16.pack(bref)); + + return SRSASN_SUCCESS; } -uint8_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_opts::to_number() const +SRSASN_CODE plmn_id_info_minus5_gc_nb_r16_s::unpack(cbit_ref& bref) { - static const uint8_t options[] = {0, 36, 72, 108, 6, 54, 102, 42, 78, 90, 12, 24, 48, 84, 60, 18}; - return map_enum_number( - options, 16, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_e_"); -} + HANDLE_CODE(bref.unpack(ng_u_data_transfer_r16_present, 1)); + HANDLE_CODE(bref.unpack(up_cio_t_minus5_gs_optim_r16_present, 1)); -const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_opts::to_string() const -{ - static const char* options[] = {"n36", "n72", "n108", "n144"}; - return convert_enum_idx( - options, 4, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_e_"); + HANDLE_CODE(plmn_id_minus5_gc_r16.unpack(bref)); + HANDLE_CODE(cell_reserved_for_oper_r16.unpack(bref)); + + return SRSASN_SUCCESS; } -uint8_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_opts::to_number() const +void plmn_id_info_minus5_gc_nb_r16_s::to_json(json_writer& j) const { - static const uint8_t options[] = {36, 72, 108, 144}; - return map_enum_number( - options, 4, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_e_"); + j.start_obj(); + j.write_fieldname("plmn-Identity-5GC-r16"); + plmn_id_minus5_gc_r16.to_json(j); + j.write_str("cellReservedForOperatorUse-r16", cell_reserved_for_oper_r16.to_string()); + if (ng_u_data_transfer_r16_present) { + j.write_str("ng-U-DataTransfer-r16", "true"); + } + if (up_cio_t_minus5_gs_optim_r16_present) { + j.write_str("up-CIoT-5GS-Optimisation-r16", "true"); + } + j.end_obj(); } -const char* -nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_string() const +void plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_::destroy_() { - static const char* options[] = {"zero", "oneThird", "twoThird", "one"}; - return convert_enum_idx( - options, - 4, - value, - "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); + switch (type_) { + case types::plmn_id_r16: + c.destroy(); + break; + default: + break; + } } -float nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_number() const +void plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_::set(types::options e) { - static const float options[] = {0.0, 0.3333333333333333, 0.6666666666666666, 1.0}; - return map_enum_number( - options, - 4, - value, - "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); + destroy_(); + type_ = e; + switch (type_) { + case types::plmn_id_r16: + c.init(); + break; + case types::plmn_idx_r16: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_"); + } } -const char* -nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_number_string() const +plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_::plmn_id_minus5_gc_r16_c_( + const plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_& other) { - static const char* options[] = {"0", "1/3", "2/3", "1"}; - return convert_enum_idx( - options, - 4, - value, - "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); + type_ = other.type(); + switch (type_) { + case types::plmn_id_r16: + c.init(other.c.get()); + break; + case types::plmn_idx_r16: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_"); + } } +plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_& +plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_::operator=( + const plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::plmn_id_r16: + c.set(other.c.get()); + break; + case types::plmn_idx_r16: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_"); + } -const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_opts::to_string() const + return *this; +} +plmn_id_s& plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_::set_plmn_id_r16() { - static const char* options[] = {"r1", - "r2", - "r4", - "r8", - "r16", - "r32", - "r64", - "r128", - "r256", - "r512", - "r1024", - "r2048", - "spare4", - "spare3", - "spare2", - "spare1"}; - return convert_enum_idx( - options, 16, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_e_"); + set(types::plmn_id_r16); + return c.get(); } -uint16_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_opts::to_number() const +uint8_t& plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_::set_plmn_idx_r16() { - static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; - return map_enum_number( - options, 12, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_e_"); + set(types::plmn_idx_r16); + return c.get(); +} +void plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::plmn_id_r16: + j.write_fieldname("plmn-Identity-r16"); + c.get().to_json(j); + break; + case types::plmn_idx_r16: + j.write_int("plmn-Index-r16", c.get()); + break; + default: + log_invalid_choice_id(type_, "plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_"); + } + j.end_obj(); +} +SRSASN_CODE plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::plmn_id_r16: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::plmn_idx_r16: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)1u, (uint8_t)6u)); + break; + default: + log_invalid_choice_id(type_, "plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::plmn_id_r16: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::plmn_idx_r16: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)1u, (uint8_t)6u)); + break; + default: + log_invalid_choice_id(type_, "plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; } -const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_opts::to_string() const +const char* plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_::types_opts::to_string() const { - static const char* options[] = {"v1dot5", "v2", "v4", "v8", "v16", "v32", "v48", "v64"}; - return convert_enum_idx( - options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_e_"); + static const char* options[] = {"plmn-Identity-r16", "plmn-Index-r16"}; + return convert_enum_idx(options, 2, value, "plmn_id_info_minus5_gc_nb_r16_s::plmn_id_minus5_gc_r16_c_::types"); } -float nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_opts::to_number() const + +const char* plmn_id_info_minus5_gc_nb_r16_s::cell_reserved_for_oper_r16_opts::to_string() const { - static const float options[] = {1.5, 2.0, 4.0, 8.0, 16.0, 32.0, 48.0, 64.0}; - return map_enum_number( - options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_e_"); + static const char* options[] = {"reserved", "notReserved"}; + return convert_enum_idx(options, 2, value, "plmn_id_info_minus5_gc_nb_r16_s::cell_reserved_for_oper_r16_e_"); } -const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_opts::to_number_string() const + +// EDT-TBS-NB-r15 ::= SEQUENCE +SRSASN_CODE edt_tbs_nb_r15_s::pack(bit_ref& bref) const { - static const char* options[] = {"1.5", "2", "4", "8", "16", "32", "48", "64"}; - return convert_enum_idx( - options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_e_"); + HANDLE_CODE(bref.pack(edt_small_tbs_enabled_r15, 1)); + HANDLE_CODE(edt_tbs_r15.pack(bref)); + + return SRSASN_SUCCESS; } +SRSASN_CODE edt_tbs_nb_r15_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(edt_small_tbs_enabled_r15, 1)); + HANDLE_CODE(edt_tbs_r15.unpack(bref)); -const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_string() const + return SRSASN_SUCCESS; +} +void edt_tbs_nb_r15_s::to_json(json_writer& j) const { - static const char* options[] = {"zero", "oneEighth", "oneFourth", "threeEighth"}; - return convert_enum_idx( - options, 4, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); + j.start_obj(); + j.write_bool("edt-SmallTBS-Enabled-r15", edt_small_tbs_enabled_r15); + j.write_str("edt-TBS-r15", edt_tbs_r15.to_string()); + j.end_obj(); } -float nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_number() const + +const char* edt_tbs_nb_r15_s::edt_tbs_r15_opts::to_string() const { - static const float options[] = {0.0, 0.125, 0.25, 0.375}; - return map_enum_number( - options, 4, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); + static const char* options[] = {"b328", "b408", "b504", "b584", "b680", "b808", "b936", "b1000"}; + return convert_enum_idx(options, 8, value, "edt_tbs_nb_r15_s::edt_tbs_r15_e_"); } -const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_number_string() const +uint16_t edt_tbs_nb_r15_s::edt_tbs_r15_opts::to_number() const { - static const char* options[] = {"0", "1/8", "1/4", "3/8"}; - return convert_enum_idx( - options, 4, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); + static const uint16_t options[] = {328, 408, 504, 584, 680, 808, 936, 1000}; + return map_enum_number(options, 8, value, "edt_tbs_nb_r15_s::edt_tbs_r15_e_"); } -const char* -nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_opts::to_string() const +// GWUS-Paging-ProbThresh-NB-r16 ::= ENUMERATED +const char* gwus_paging_prob_thresh_nb_r16_opts::to_string() const { - static const char* options[] = {"n24", - "n30", - "n33", - "n36", - "n60", - "n66", - "n69", - "n72", - "n96", - "n102", - "n105", - "n108", - "n120", - "n132", - "n138", - "n144"}; - return convert_enum_idx( - options, - 16, - value, - "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_e_"); + static const char* options[] = {"p20", "p30", "p40", "p50", "p60", "p70", "p80", "p90"}; + return convert_enum_idx(options, 8, value, "gwus_paging_prob_thresh_nb_r16_e"); } -uint8_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_opts::to_number() const +uint8_t gwus_paging_prob_thresh_nb_r16_opts::to_number() const { - static const uint8_t options[] = {24, 30, 33, 36, 60, 66, 69, 72, 96, 102, 105, 108, 120, 132, 138, 144}; - return map_enum_number(options, - 16, - value, - "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_e_"); + static const uint8_t options[] = {20, 30, 40, 50, 60, 70, 80, 90}; + return map_enum_number(options, 8, value, "gwus_paging_prob_thresh_nb_r16_e"); } -// NPRACH-ParametersTDD-NB-r15 ::= SEQUENCE -SRSASN_CODE nprach_params_tdd_nb_r15_s::pack(bit_ref& bref) const +// InterFreqNeighCellInfo-NB-v1530 ::= SEQUENCE +SRSASN_CODE inter_freq_neigh_cell_info_nb_v1530_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(nprach_params_r15_present, 1)); + HANDLE_CODE(bref.pack(nsss_rrm_cfg_r15_present, 1)); - if (nprach_params_r15_present) { - bref.pack(nprach_params_r15.ext, 1); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_periodicity_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_start_time_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_subcarrier_offset_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_num_subcarriers_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_num_repeats_ra_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_start_sf_css_ra_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_offset_ra_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present, 1)); - if (nprach_params_r15.nprach_periodicity_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_periodicity_r15.pack(bref)); - } - if (nprach_params_r15.nprach_start_time_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_start_time_r15.pack(bref)); - } - if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_subcarrier_offset_r15.pack(bref)); - } - if (nprach_params_r15.nprach_num_subcarriers_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_num_subcarriers_r15.pack(bref)); - } - if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.pack(bref)); - } - if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_num_repeats_ra_r15.pack(bref)); - } - if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_start_sf_css_ra_r15.pack(bref)); - } - if (nprach_params_r15.npdcch_offset_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_offset_ra_r15.pack(bref)); - } - if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.pack(bref)); - } + if (nsss_rrm_cfg_r15_present) { + HANDLE_CODE(nsss_rrm_cfg_r15.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE nprach_params_tdd_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE inter_freq_neigh_cell_info_nb_v1530_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(nprach_params_r15_present, 1)); + HANDLE_CODE(bref.unpack(nsss_rrm_cfg_r15_present, 1)); - if (nprach_params_r15_present) { - bref.unpack(nprach_params_r15.ext, 1); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_periodicity_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_start_time_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_subcarrier_offset_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_num_subcarriers_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_num_repeats_ra_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_start_sf_css_ra_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_offset_ra_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present, 1)); - if (nprach_params_r15.nprach_periodicity_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_periodicity_r15.unpack(bref)); - } - if (nprach_params_r15.nprach_start_time_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_start_time_r15.unpack(bref)); - } - if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_subcarrier_offset_r15.unpack(bref)); - } - if (nprach_params_r15.nprach_num_subcarriers_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_num_subcarriers_r15.unpack(bref)); - } - if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.unpack(bref)); - } - if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_num_repeats_ra_r15.unpack(bref)); - } - if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_start_sf_css_ra_r15.unpack(bref)); - } - if (nprach_params_r15.npdcch_offset_ra_r15_present) { - HANDLE_CODE(nprach_params_r15.npdcch_offset_ra_r15.unpack(bref)); - } - if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { - HANDLE_CODE(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.unpack(bref)); - } + if (nsss_rrm_cfg_r15_present) { + HANDLE_CODE(nsss_rrm_cfg_r15.unpack(bref)); } return SRSASN_SUCCESS; } -void nprach_params_tdd_nb_r15_s::to_json(json_writer& j) const +void inter_freq_neigh_cell_info_nb_v1530_s::to_json(json_writer& j) const { j.start_obj(); - if (nprach_params_r15_present) { - j.write_fieldname("nprach-Parameters-r15"); - j.start_obj(); - if (nprach_params_r15.nprach_periodicity_r15_present) { - j.write_str("nprach-Periodicity-r15", nprach_params_r15.nprach_periodicity_r15.to_string()); - } - if (nprach_params_r15.nprach_start_time_r15_present) { - j.write_str("nprach-StartTime-r15", nprach_params_r15.nprach_start_time_r15.to_string()); - } - if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { - j.write_str("nprach-SubcarrierOffset-r15", nprach_params_r15.nprach_subcarrier_offset_r15.to_string()); - } - if (nprach_params_r15.nprach_num_subcarriers_r15_present) { - j.write_str("nprach-NumSubcarriers-r15", nprach_params_r15.nprach_num_subcarriers_r15.to_string()); - } - if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { - j.write_str("nprach-SubcarrierMSG3-RangeStart-r15", - nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.to_string()); - } - if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { - j.write_str("npdcch-NumRepetitions-RA-r15", nprach_params_r15.npdcch_num_repeats_ra_r15.to_string()); - } - if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { - j.write_str("npdcch-StartSF-CSS-RA-r15", nprach_params_r15.npdcch_start_sf_css_ra_r15.to_string()); - } - if (nprach_params_r15.npdcch_offset_ra_r15_present) { - j.write_str("npdcch-Offset-RA-r15", nprach_params_r15.npdcch_offset_ra_r15.to_string()); - } - if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { - j.write_str("nprach-NumCBRA-StartSubcarriers-r15", - nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.to_string()); - } - j.end_obj(); + if (nsss_rrm_cfg_r15_present) { + j.write_fieldname("nsss-RRM-Config-r15"); + nsss_rrm_cfg_r15.to_json(j); } j.end_obj(); } -const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_opts::to_string() const -{ - static const char* options[] = {"ms80", "ms160", "ms320", "ms640", "ms1280", "ms2560", "ms5120", "ms10240"}; - return convert_enum_idx( - options, 8, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_e_"); -} -uint16_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_opts::to_number() const +// MultiBandInfo-NB-r13 ::= SEQUENCE +SRSASN_CODE multi_band_info_nb_r13_s::pack(bit_ref& bref) const { - static const uint16_t options[] = {80, 160, 320, 640, 1280, 2560, 5120, 10240}; - return map_enum_number( - options, 8, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_e_"); -} + HANDLE_CODE(bref.pack(freq_band_ind_r13_present, 1)); + HANDLE_CODE(bref.pack(freq_band_info_r13_present, 1)); -const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_opts::to_string() const -{ - static const char* options[] = {"ms10", - "ms20", - "ms40", - "ms80", - "ms160", - "ms320", - "ms640", - "ms1280", - "ms2560", - "ms5120", - "spare6", - "spare5", - "spare4", - "spare3", - "spare2", - "spare1"}; - return convert_enum_idx( - options, 16, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_e_"); + if (freq_band_ind_r13_present) { + HANDLE_CODE(pack_integer(bref, freq_band_ind_r13, (uint16_t)1u, (uint16_t)256u)); + } + if (freq_band_info_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_info_r13, 1, 4)); + } + + return SRSASN_SUCCESS; } -uint16_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_opts::to_number() const +SRSASN_CODE multi_band_info_nb_r13_s::unpack(cbit_ref& bref) { - static const uint16_t options[] = {10, 20, 40, 80, 160, 320, 640, 1280, 2560, 5120}; - return map_enum_number( - options, 10, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_e_"); + HANDLE_CODE(bref.unpack(freq_band_ind_r13_present, 1)); + HANDLE_CODE(bref.unpack(freq_band_info_r13_present, 1)); + + if (freq_band_ind_r13_present) { + HANDLE_CODE(unpack_integer(freq_band_ind_r13, bref, (uint16_t)1u, (uint16_t)256u)); + } + if (freq_band_info_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(freq_band_info_r13, bref, 1, 4)); + } + + return SRSASN_SUCCESS; +} +void multi_band_info_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (freq_band_ind_r13_present) { + j.write_int("freqBandIndicator-r13", freq_band_ind_r13); + } + if (freq_band_info_r13_present) { + j.start_array("freqBandInfo-r13"); + for (const auto& e1 : freq_band_info_r13) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); } -const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_opts::to_string() const +// NPRACH-Parameters-NB-r13 ::= SEQUENCE +SRSASN_CODE nprach_params_nb_r13_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(nprach_periodicity_r13.pack(bref)); + HANDLE_CODE(nprach_start_time_r13.pack(bref)); + HANDLE_CODE(nprach_subcarrier_offset_r13.pack(bref)); + HANDLE_CODE(nprach_num_subcarriers_r13.pack(bref)); + HANDLE_CODE(nprach_subcarrier_msg3_range_start_r13.pack(bref)); + HANDLE_CODE(max_num_preamb_attempt_ce_r13.pack(bref)); + HANDLE_CODE(num_repeats_per_preamb_attempt_r13.pack(bref)); + HANDLE_CODE(npdcch_num_repeats_ra_r13.pack(bref)); + HANDLE_CODE(npdcch_start_sf_css_ra_r13.pack(bref)); + HANDLE_CODE(npdcch_offset_ra_r13.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nprach_params_nb_r13_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(nprach_periodicity_r13.unpack(bref)); + HANDLE_CODE(nprach_start_time_r13.unpack(bref)); + HANDLE_CODE(nprach_subcarrier_offset_r13.unpack(bref)); + HANDLE_CODE(nprach_num_subcarriers_r13.unpack(bref)); + HANDLE_CODE(nprach_subcarrier_msg3_range_start_r13.unpack(bref)); + HANDLE_CODE(max_num_preamb_attempt_ce_r13.unpack(bref)); + HANDLE_CODE(num_repeats_per_preamb_attempt_r13.unpack(bref)); + HANDLE_CODE(npdcch_num_repeats_ra_r13.unpack(bref)); + HANDLE_CODE(npdcch_start_sf_css_ra_r13.unpack(bref)); + HANDLE_CODE(npdcch_offset_ra_r13.unpack(bref)); + + return SRSASN_SUCCESS; +} +void nprach_params_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("nprach-Periodicity-r13", nprach_periodicity_r13.to_string()); + j.write_str("nprach-StartTime-r13", nprach_start_time_r13.to_string()); + j.write_str("nprach-SubcarrierOffset-r13", nprach_subcarrier_offset_r13.to_string()); + j.write_str("nprach-NumSubcarriers-r13", nprach_num_subcarriers_r13.to_string()); + j.write_str("nprach-SubcarrierMSG3-RangeStart-r13", nprach_subcarrier_msg3_range_start_r13.to_string()); + j.write_str("maxNumPreambleAttemptCE-r13", max_num_preamb_attempt_ce_r13.to_string()); + j.write_str("numRepetitionsPerPreambleAttempt-r13", num_repeats_per_preamb_attempt_r13.to_string()); + j.write_str("npdcch-NumRepetitions-RA-r13", npdcch_num_repeats_ra_r13.to_string()); + j.write_str("npdcch-StartSF-CSS-RA-r13", npdcch_start_sf_css_ra_r13.to_string()); + j.write_str("npdcch-Offset-RA-r13", npdcch_offset_ra_r13.to_string()); + j.end_obj(); +} + +const char* nprach_params_nb_r13_s::nprach_periodicity_r13_opts::to_string() const +{ + static const char* options[] = {"ms40", "ms80", "ms160", "ms240", "ms320", "ms640", "ms1280", "ms2560"}; + return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::nprach_periodicity_r13_e_"); +} +uint16_t nprach_params_nb_r13_s::nprach_periodicity_r13_opts::to_number() const +{ + static const uint16_t options[] = {40, 80, 160, 240, 320, 640, 1280, 2560}; + return map_enum_number(options, 8, value, "nprach_params_nb_r13_s::nprach_periodicity_r13_e_"); +} + +const char* nprach_params_nb_r13_s::nprach_start_time_r13_opts::to_string() const +{ + static const char* options[] = {"ms8", "ms16", "ms32", "ms64", "ms128", "ms256", "ms512", "ms1024"}; + return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::nprach_start_time_r13_e_"); +} +uint16_t nprach_params_nb_r13_s::nprach_start_time_r13_opts::to_number() const +{ + static const uint16_t options[] = {8, 16, 32, 64, 128, 256, 512, 1024}; + return map_enum_number(options, 8, value, "nprach_params_nb_r13_s::nprach_start_time_r13_e_"); +} + +const char* nprach_params_nb_r13_s::nprach_subcarrier_offset_r13_opts::to_string() const { static const char* options[] = {"n0", "n12", "n24", "n36", "n2", "n18", "n34", "spare1"}; - return convert_enum_idx( - options, 8, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_e_"); + return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::nprach_subcarrier_offset_r13_e_"); } -uint8_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_opts::to_number() const +uint8_t nprach_params_nb_r13_s::nprach_subcarrier_offset_r13_opts::to_number() const { static const uint8_t options[] = {0, 12, 24, 36, 2, 18, 34}; - return map_enum_number( - options, 7, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_e_"); + return map_enum_number(options, 7, value, "nprach_params_nb_r13_s::nprach_subcarrier_offset_r13_e_"); } -const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_opts::to_string() const +const char* nprach_params_nb_r13_s::nprach_num_subcarriers_r13_opts::to_string() const { static const char* options[] = {"n12", "n24", "n36", "n48"}; - return convert_enum_idx( - options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_e_"); + return convert_enum_idx(options, 4, value, "nprach_params_nb_r13_s::nprach_num_subcarriers_r13_e_"); } -uint8_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_opts::to_number() const +uint8_t nprach_params_nb_r13_s::nprach_num_subcarriers_r13_opts::to_number() const { static const uint8_t options[] = {12, 24, 36, 48}; - return map_enum_number( - options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_e_"); + return map_enum_number(options, 4, value, "nprach_params_nb_r13_s::nprach_num_subcarriers_r13_e_"); } -const char* -nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_string() const +const char* nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_opts::to_string() const { static const char* options[] = {"zero", "oneThird", "twoThird", "one"}; - return convert_enum_idx( - options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); + return convert_enum_idx(options, 4, value, "nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_e_"); } -float nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_number() const +float nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_opts::to_number() const { static const float options[] = {0.0, 0.3333333333333333, 0.6666666666666666, 1.0}; - return map_enum_number( - options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); + return map_enum_number(options, 4, value, "nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_e_"); } -const char* -nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_number_string() const +const char* nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_opts::to_number_string() const { static const char* options[] = {"0", "1/3", "2/3", "1"}; - return convert_enum_idx( - options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); + return convert_enum_idx(options, 4, value, "nprach_params_nb_r13_s::nprach_subcarrier_msg3_range_start_r13_e_"); } -const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_opts::to_string() const +const char* nprach_params_nb_r13_s::max_num_preamb_attempt_ce_r13_opts::to_string() const +{ + static const char* options[] = {"n3", "n4", "n5", "n6", "n7", "n8", "n10", "spare1"}; + return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::max_num_preamb_attempt_ce_r13_e_"); +} +uint8_t nprach_params_nb_r13_s::max_num_preamb_attempt_ce_r13_opts::to_number() const +{ + static const uint8_t options[] = {3, 4, 5, 6, 7, 8, 10}; + return map_enum_number(options, 7, value, "nprach_params_nb_r13_s::max_num_preamb_attempt_ce_r13_e_"); +} + +const char* nprach_params_nb_r13_s::num_repeats_per_preamb_attempt_r13_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n4", "n8", "n16", "n32", "n64", "n128"}; + return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::num_repeats_per_preamb_attempt_r13_e_"); +} +uint8_t nprach_params_nb_r13_s::num_repeats_per_preamb_attempt_r13_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 4, 8, 16, 32, 64, 128}; + return map_enum_number(options, 8, value, "nprach_params_nb_r13_s::num_repeats_per_preamb_attempt_r13_e_"); +} + +const char* nprach_params_nb_r13_s::npdcch_num_repeats_ra_r13_opts::to_string() const { static const char* options[] = {"r1", "r2", @@ -5973,767 +7013,916 @@ const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats "spare3", "spare2", "spare1"}; - return convert_enum_idx( - options, 16, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_e_"); + return convert_enum_idx(options, 16, value, "nprach_params_nb_r13_s::npdcch_num_repeats_ra_r13_e_"); } -uint16_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_opts::to_number() const +uint16_t nprach_params_nb_r13_s::npdcch_num_repeats_ra_r13_opts::to_number() const { static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; - return map_enum_number( - options, 12, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_e_"); + return map_enum_number(options, 12, value, "nprach_params_nb_r13_s::npdcch_num_repeats_ra_r13_e_"); } -const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_opts::to_string() const +const char* nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_opts::to_string() const { - static const char* options[] = {"v4", "v8", "v16", "v32", "v48", "v64", "v96", "v128"}; - return convert_enum_idx( - options, 8, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_e_"); + static const char* options[] = {"v1dot5", "v2", "v4", "v8", "v16", "v32", "v48", "v64"}; + return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_e_"); } -uint8_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_opts::to_number() const +float nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_opts::to_number() const { - static const uint8_t options[] = {4, 8, 16, 32, 48, 64, 96, 128}; - return map_enum_number( - options, 8, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_e_"); + static const float options[] = {1.5, 2.0, 4.0, 8.0, 16.0, 32.0, 48.0, 64.0}; + return map_enum_number(options, 8, value, "nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_e_"); +} +const char* nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_opts::to_number_string() const +{ + static const char* options[] = {"1.5", "2", "4", "8", "16", "32", "48", "64"}; + return convert_enum_idx(options, 8, value, "nprach_params_nb_r13_s::npdcch_start_sf_css_ra_r13_e_"); } -const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_string() const +const char* nprach_params_nb_r13_s::npdcch_offset_ra_r13_opts::to_string() const { static const char* options[] = {"zero", "oneEighth", "oneFourth", "threeEighth"}; - return convert_enum_idx( - options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); + return convert_enum_idx(options, 4, value, "nprach_params_nb_r13_s::npdcch_offset_ra_r13_e_"); } -float nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_number() const +float nprach_params_nb_r13_s::npdcch_offset_ra_r13_opts::to_number() const { static const float options[] = {0.0, 0.125, 0.25, 0.375}; - return map_enum_number( - options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); + return map_enum_number(options, 4, value, "nprach_params_nb_r13_s::npdcch_offset_ra_r13_e_"); } -const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_number_string() const +const char* nprach_params_nb_r13_s::npdcch_offset_ra_r13_opts::to_number_string() const { static const char* options[] = {"0", "1/8", "1/4", "3/8"}; - return convert_enum_idx( - options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); -} - -const char* -nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_opts::to_string() const -{ - static const char* options[] = { - "n8", "n10", "n11", "n12", "n20", "n22", "n23", "n24", "n32", "n34", "n35", "n36", "n40", "n44", "n46", "n48"}; - return convert_enum_idx( - options, 16, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_e_"); -} -uint8_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_opts::to_number() const -{ - static const uint8_t options[] = {8, 10, 11, 12, 20, 22, 23, 24, 32, 34, 35, 36, 40, 44, 46, 48}; - return map_enum_number( - options, 16, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_e_"); + return convert_enum_idx(options, 4, value, "nprach_params_nb_r13_s::npdcch_offset_ra_r13_e_"); } -// NPRACH-ParametersTDD-NB-v1550 ::= SEQUENCE -SRSASN_CODE nprach_params_tdd_nb_v1550_s::pack(bit_ref& bref) const +// NPRACH-Parameters-NB-r14 ::= SEQUENCE +SRSASN_CODE nprach_params_nb_r14_s::pack(bit_ref& bref) const { - HANDLE_CODE(max_num_preamb_attempt_ce_v1550.pack(bref)); - HANDLE_CODE(num_repeats_per_preamb_attempt_v1550.pack(bref)); + HANDLE_CODE(bref.pack(nprach_params_r14_present, 1)); - return SRSASN_SUCCESS; -} -SRSASN_CODE nprach_params_tdd_nb_v1550_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(max_num_preamb_attempt_ce_v1550.unpack(bref)); - HANDLE_CODE(num_repeats_per_preamb_attempt_v1550.unpack(bref)); + if (nprach_params_r14_present) { + bref.pack(nprach_params_r14.ext, 1); + HANDLE_CODE(bref.pack(nprach_params_r14.nprach_periodicity_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r14.nprach_start_time_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r14.nprach_subcarrier_offset_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r14.nprach_num_subcarriers_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r14.nprach_subcarrier_msg3_range_start_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r14.npdcch_num_repeats_ra_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r14.npdcch_start_sf_css_ra_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r14.npdcch_offset_ra_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r14.nprach_num_cbra_start_subcarriers_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r14.npdcch_carrier_idx_r14_present, 1)); + if (nprach_params_r14.nprach_periodicity_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_periodicity_r14.pack(bref)); + } + if (nprach_params_r14.nprach_start_time_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_start_time_r14.pack(bref)); + } + if (nprach_params_r14.nprach_subcarrier_offset_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_subcarrier_offset_r14.pack(bref)); + } + if (nprach_params_r14.nprach_num_subcarriers_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_num_subcarriers_r14.pack(bref)); + } + if (nprach_params_r14.nprach_subcarrier_msg3_range_start_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_subcarrier_msg3_range_start_r14.pack(bref)); + } + if (nprach_params_r14.npdcch_num_repeats_ra_r14_present) { + HANDLE_CODE(nprach_params_r14.npdcch_num_repeats_ra_r14.pack(bref)); + } + if (nprach_params_r14.npdcch_start_sf_css_ra_r14_present) { + HANDLE_CODE(nprach_params_r14.npdcch_start_sf_css_ra_r14.pack(bref)); + } + if (nprach_params_r14.npdcch_offset_ra_r14_present) { + HANDLE_CODE(nprach_params_r14.npdcch_offset_ra_r14.pack(bref)); + } + if (nprach_params_r14.nprach_num_cbra_start_subcarriers_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_num_cbra_start_subcarriers_r14.pack(bref)); + } + if (nprach_params_r14.npdcch_carrier_idx_r14_present) { + HANDLE_CODE(pack_integer(bref, nprach_params_r14.npdcch_carrier_idx_r14, (uint8_t)1u, (uint8_t)15u)); + } + } return SRSASN_SUCCESS; } -void nprach_params_tdd_nb_v1550_s::to_json(json_writer& j) const +SRSASN_CODE nprach_params_nb_r14_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(nprach_params_r14_present, 1)); + + if (nprach_params_r14_present) { + bref.unpack(nprach_params_r14.ext, 1); + HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_periodicity_r14_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_start_time_r14_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_subcarrier_offset_r14_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_num_subcarriers_r14_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_subcarrier_msg3_range_start_r14_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r14.npdcch_num_repeats_ra_r14_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r14.npdcch_start_sf_css_ra_r14_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r14.npdcch_offset_ra_r14_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r14.nprach_num_cbra_start_subcarriers_r14_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r14.npdcch_carrier_idx_r14_present, 1)); + if (nprach_params_r14.nprach_periodicity_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_periodicity_r14.unpack(bref)); + } + if (nprach_params_r14.nprach_start_time_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_start_time_r14.unpack(bref)); + } + if (nprach_params_r14.nprach_subcarrier_offset_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_subcarrier_offset_r14.unpack(bref)); + } + if (nprach_params_r14.nprach_num_subcarriers_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_num_subcarriers_r14.unpack(bref)); + } + if (nprach_params_r14.nprach_subcarrier_msg3_range_start_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_subcarrier_msg3_range_start_r14.unpack(bref)); + } + if (nprach_params_r14.npdcch_num_repeats_ra_r14_present) { + HANDLE_CODE(nprach_params_r14.npdcch_num_repeats_ra_r14.unpack(bref)); + } + if (nprach_params_r14.npdcch_start_sf_css_ra_r14_present) { + HANDLE_CODE(nprach_params_r14.npdcch_start_sf_css_ra_r14.unpack(bref)); + } + if (nprach_params_r14.npdcch_offset_ra_r14_present) { + HANDLE_CODE(nprach_params_r14.npdcch_offset_ra_r14.unpack(bref)); + } + if (nprach_params_r14.nprach_num_cbra_start_subcarriers_r14_present) { + HANDLE_CODE(nprach_params_r14.nprach_num_cbra_start_subcarriers_r14.unpack(bref)); + } + if (nprach_params_r14.npdcch_carrier_idx_r14_present) { + HANDLE_CODE(unpack_integer(nprach_params_r14.npdcch_carrier_idx_r14, bref, (uint8_t)1u, (uint8_t)15u)); + } + } + + return SRSASN_SUCCESS; +} +void nprach_params_nb_r14_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("maxNumPreambleAttemptCE-v1550", max_num_preamb_attempt_ce_v1550.to_string()); - j.write_str("numRepetitionsPerPreambleAttempt-v1550", num_repeats_per_preamb_attempt_v1550.to_string()); + if (nprach_params_r14_present) { + j.write_fieldname("nprach-Parameters-r14"); + j.start_obj(); + if (nprach_params_r14.nprach_periodicity_r14_present) { + j.write_str("nprach-Periodicity-r14", nprach_params_r14.nprach_periodicity_r14.to_string()); + } + if (nprach_params_r14.nprach_start_time_r14_present) { + j.write_str("nprach-StartTime-r14", nprach_params_r14.nprach_start_time_r14.to_string()); + } + if (nprach_params_r14.nprach_subcarrier_offset_r14_present) { + j.write_str("nprach-SubcarrierOffset-r14", nprach_params_r14.nprach_subcarrier_offset_r14.to_string()); + } + if (nprach_params_r14.nprach_num_subcarriers_r14_present) { + j.write_str("nprach-NumSubcarriers-r14", nprach_params_r14.nprach_num_subcarriers_r14.to_string()); + } + if (nprach_params_r14.nprach_subcarrier_msg3_range_start_r14_present) { + j.write_str("nprach-SubcarrierMSG3-RangeStart-r14", + nprach_params_r14.nprach_subcarrier_msg3_range_start_r14.to_string()); + } + if (nprach_params_r14.npdcch_num_repeats_ra_r14_present) { + j.write_str("npdcch-NumRepetitions-RA-r14", nprach_params_r14.npdcch_num_repeats_ra_r14.to_string()); + } + if (nprach_params_r14.npdcch_start_sf_css_ra_r14_present) { + j.write_str("npdcch-StartSF-CSS-RA-r14", nprach_params_r14.npdcch_start_sf_css_ra_r14.to_string()); + } + if (nprach_params_r14.npdcch_offset_ra_r14_present) { + j.write_str("npdcch-Offset-RA-r14", nprach_params_r14.npdcch_offset_ra_r14.to_string()); + } + if (nprach_params_r14.nprach_num_cbra_start_subcarriers_r14_present) { + j.write_str("nprach-NumCBRA-StartSubcarriers-r14", + nprach_params_r14.nprach_num_cbra_start_subcarriers_r14.to_string()); + } + if (nprach_params_r14.npdcch_carrier_idx_r14_present) { + j.write_int("npdcch-CarrierIndex-r14", nprach_params_r14.npdcch_carrier_idx_r14); + } + j.end_obj(); + } j.end_obj(); } -const char* nprach_params_tdd_nb_v1550_s::max_num_preamb_attempt_ce_v1550_opts::to_string() const +const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_periodicity_r14_opts::to_string() const { - static const char* options[] = {"n3", "n4", "n5", "n6", "n7", "n8", "n10", "spare1"}; - return convert_enum_idx(options, 8, value, "nprach_params_tdd_nb_v1550_s::max_num_preamb_attempt_ce_v1550_e_"); + static const char* options[] = {"ms40", "ms80", "ms160", "ms240", "ms320", "ms640", "ms1280", "ms2560"}; + return convert_enum_idx(options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_periodicity_r14_e_"); } -uint8_t nprach_params_tdd_nb_v1550_s::max_num_preamb_attempt_ce_v1550_opts::to_number() const +uint16_t nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_periodicity_r14_opts::to_number() const { - static const uint8_t options[] = {3, 4, 5, 6, 7, 8, 10}; - return map_enum_number(options, 7, value, "nprach_params_tdd_nb_v1550_s::max_num_preamb_attempt_ce_v1550_e_"); + static const uint16_t options[] = {40, 80, 160, 240, 320, 640, 1280, 2560}; + return map_enum_number(options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_periodicity_r14_e_"); } -const char* nprach_params_tdd_nb_v1550_s::num_repeats_per_preamb_attempt_v1550_opts::to_string() const +const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_start_time_r14_opts::to_string() const { - static const char* options[] = {"n1", "n2", "n4", "n8", "n16", "n32", "n64", "n128", "n256", "n512", "n1024"}; - return convert_enum_idx(options, 11, value, "nprach_params_tdd_nb_v1550_s::num_repeats_per_preamb_attempt_v1550_e_"); + static const char* options[] = {"ms8", "ms16", "ms32", "ms64", "ms128", "ms256", "ms512", "ms1024"}; + return convert_enum_idx(options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_start_time_r14_e_"); } -uint16_t nprach_params_tdd_nb_v1550_s::num_repeats_per_preamb_attempt_v1550_opts::to_number() const +uint16_t nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_start_time_r14_opts::to_number() const { - static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}; - return map_enum_number(options, 11, value, "nprach_params_tdd_nb_v1550_s::num_repeats_per_preamb_attempt_v1550_e_"); + static const uint16_t options[] = {8, 16, 32, 64, 128, 256, 512, 1024}; + return map_enum_number(options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_start_time_r14_e_"); } -// PagingWeight-NB-r14 ::= ENUMERATED -const char* paging_weight_nb_r14_opts::to_string() const +const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_offset_r14_opts::to_string() const { - static const char* options[] = { - "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15", "w16"}; - return convert_enum_idx(options, 16, value, "paging_weight_nb_r14_e"); + static const char* options[] = {"n0", "n12", "n24", "n36", "n2", "n18", "n34", "spare1"}; + return convert_enum_idx( + options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_offset_r14_e_"); } -uint8_t paging_weight_nb_r14_opts::to_number() const +uint8_t nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_offset_r14_opts::to_number() const { - static const uint8_t options[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - return map_enum_number(options, 16, value, "paging_weight_nb_r14_e"); + static const uint8_t options[] = {0, 12, 24, 36, 2, 18, 34}; + return map_enum_number( + options, 7, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_offset_r14_e_"); } -// RACH-Info-NB-r13 ::= SEQUENCE -SRSASN_CODE rach_info_nb_r13_s::pack(bit_ref& bref) const +const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_subcarriers_r14_opts::to_string() const { - HANDLE_CODE(ra_resp_win_size_r13.pack(bref)); - HANDLE_CODE(mac_contention_resolution_timer_r13.pack(bref)); - - return SRSASN_SUCCESS; + static const char* options[] = {"n12", "n24", "n36", "n48"}; + return convert_enum_idx( + options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_subcarriers_r14_e_"); } -SRSASN_CODE rach_info_nb_r13_s::unpack(cbit_ref& bref) +uint8_t nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_subcarriers_r14_opts::to_number() const { - HANDLE_CODE(ra_resp_win_size_r13.unpack(bref)); - HANDLE_CODE(mac_contention_resolution_timer_r13.unpack(bref)); - - return SRSASN_SUCCESS; + static const uint8_t options[] = {12, 24, 36, 48}; + return map_enum_number( + options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_subcarriers_r14_e_"); } -void rach_info_nb_r13_s::to_json(json_writer& j) const + +const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_opts::to_string() const { - j.start_obj(); - j.write_str("ra-ResponseWindowSize-r13", ra_resp_win_size_r13.to_string()); - j.write_str("mac-ContentionResolutionTimer-r13", mac_contention_resolution_timer_r13.to_string()); - j.end_obj(); + static const char* options[] = {"zero", "oneThird", "twoThird", "one"}; + return convert_enum_idx( + options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_e_"); } - -const char* rach_info_nb_r13_s::ra_resp_win_size_r13_opts::to_string() const +float nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_opts::to_number() const { - static const char* options[] = {"pp2", "pp3", "pp4", "pp5", "pp6", "pp7", "pp8", "pp10"}; - return convert_enum_idx(options, 8, value, "rach_info_nb_r13_s::ra_resp_win_size_r13_e_"); + static const float options[] = {0.0, 0.3333333333333333, 0.6666666666666666, 1.0}; + return map_enum_number( + options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_e_"); } -uint8_t rach_info_nb_r13_s::ra_resp_win_size_r13_opts::to_number() const +const char* +nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_opts::to_number_string() const { - static const uint8_t options[] = {2, 3, 4, 5, 6, 7, 8, 10}; - return map_enum_number(options, 8, value, "rach_info_nb_r13_s::ra_resp_win_size_r13_e_"); + static const char* options[] = {"0", "1/3", "2/3", "1"}; + return convert_enum_idx( + options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_subcarrier_msg3_range_start_r14_e_"); } -const char* rach_info_nb_r13_s::mac_contention_resolution_timer_r13_opts::to_string() const +const char* nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_num_repeats_ra_r14_opts::to_string() const { - static const char* options[] = {"pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32", "pp64"}; - return convert_enum_idx(options, 8, value, "rach_info_nb_r13_s::mac_contention_resolution_timer_r13_e_"); + static const char* options[] = {"r1", + "r2", + "r4", + "r8", + "r16", + "r32", + "r64", + "r128", + "r256", + "r512", + "r1024", + "r2048", + "spare4", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx( + options, 16, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_num_repeats_ra_r14_e_"); } -uint8_t rach_info_nb_r13_s::mac_contention_resolution_timer_r13_opts::to_number() const +uint16_t nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_num_repeats_ra_r14_opts::to_number() const { - static const uint8_t options[] = {1, 2, 3, 4, 8, 16, 32, 64}; - return map_enum_number(options, 8, value, "rach_info_nb_r13_s::mac_contention_resolution_timer_r13_e_"); + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; + return map_enum_number( + options, 12, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_num_repeats_ra_r14_e_"); } -// RACH-Info-NB-v1530 ::= SEQUENCE -SRSASN_CODE rach_info_nb_v1530_s::pack(bit_ref& bref) const +const char* nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_opts::to_string() const { - HANDLE_CODE(mac_contention_resolution_timer_r15.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE rach_info_nb_v1530_s::unpack(cbit_ref& bref) + static const char* options[] = {"v1dot5", "v2", "v4", "v8", "v16", "v32", "v48", "v64"}; + return convert_enum_idx( + options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_e_"); +} +float nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_opts::to_number() const { - HANDLE_CODE(mac_contention_resolution_timer_r15.unpack(bref)); - - return SRSASN_SUCCESS; + static const float options[] = {1.5, 2.0, 4.0, 8.0, 16.0, 32.0, 48.0, 64.0}; + return map_enum_number( + options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_e_"); } -void rach_info_nb_v1530_s::to_json(json_writer& j) const +const char* nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_opts::to_number_string() const { - j.start_obj(); - j.write_str("mac-ContentionResolutionTimer-r15", mac_contention_resolution_timer_r15.to_string()); - j.end_obj(); + static const char* options[] = {"1.5", "2", "4", "8", "16", "32", "48", "64"}; + return convert_enum_idx( + options, 8, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_start_sf_css_ra_r14_e_"); } -const char* rach_info_nb_v1530_s::mac_contention_resolution_timer_r15_opts::to_string() const +const char* nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_opts::to_string() const { - static const char* options[] = {"pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32", "pp64"}; - return convert_enum_idx(options, 8, value, "rach_info_nb_v1530_s::mac_contention_resolution_timer_r15_e_"); + static const char* options[] = {"zero", "oneEighth", "oneFourth", "threeEighth"}; + return convert_enum_idx(options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_e_"); } -uint8_t rach_info_nb_v1530_s::mac_contention_resolution_timer_r15_opts::to_number() const +float nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_opts::to_number() const { - static const uint8_t options[] = {1, 2, 3, 4, 8, 16, 32, 64}; - return map_enum_number(options, 8, value, "rach_info_nb_v1530_s::mac_contention_resolution_timer_r15_e_"); + static const float options[] = {0.0, 0.125, 0.25, 0.375}; + return map_enum_number(options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_e_"); +} +const char* nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_opts::to_number_string() const +{ + static const char* options[] = {"0", "1/8", "1/4", "3/8"}; + return convert_enum_idx(options, 4, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::npdcch_offset_ra_r14_e_"); } -// SchedulingInfo-NB-v1530 ::= SEQUENCE -SRSASN_CODE sched_info_nb_v1530_s::pack(bit_ref& bref) const +const char* nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_cbra_start_subcarriers_r14_opts::to_string() const { - HANDLE_CODE(bref.pack(sib_map_info_v1530_present, 1)); + static const char* options[] = { + "n8", "n10", "n11", "n12", "n20", "n22", "n23", "n24", "n32", "n34", "n35", "n36", "n40", "n44", "n46", "n48"}; + return convert_enum_idx( + options, 16, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_cbra_start_subcarriers_r14_e_"); +} +uint8_t nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_cbra_start_subcarriers_r14_opts::to_number() const +{ + static const uint8_t options[] = {8, 10, 11, 12, 20, 22, 23, 24, 32, 34, 35, 36, 40, 44, 46, 48}; + return map_enum_number( + options, 16, value, "nprach_params_nb_r14_s::nprach_params_r14_s_::nprach_num_cbra_start_subcarriers_r14_e_"); +} - if (sib_map_info_v1530_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, sib_map_info_v1530, 1, 8)); - } +// NPRACH-Parameters-NB-v1330 ::= SEQUENCE +SRSASN_CODE nprach_params_nb_v1330_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(nprach_num_cbra_start_subcarriers_r13.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE sched_info_nb_v1530_s::unpack(cbit_ref& bref) +SRSASN_CODE nprach_params_nb_v1330_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(sib_map_info_v1530_present, 1)); - - if (sib_map_info_v1530_present) { - HANDLE_CODE(unpack_dyn_seq_of(sib_map_info_v1530, bref, 1, 8)); - } + HANDLE_CODE(nprach_num_cbra_start_subcarriers_r13.unpack(bref)); return SRSASN_SUCCESS; } -void sched_info_nb_v1530_s::to_json(json_writer& j) const +void nprach_params_nb_v1330_s::to_json(json_writer& j) const { j.start_obj(); - if (sib_map_info_v1530_present) { - j.start_array("sib-MappingInfo-v1530"); - for (const auto& e1 : sib_map_info_v1530) { - j.write_str(e1.to_string()); - } - j.end_array(); - } + j.write_str("nprach-NumCBRA-StartSubcarriers-r13", nprach_num_cbra_start_subcarriers_r13.to_string()); j.end_obj(); } -// WUS-MaxDurationFactor-NB-r15 ::= ENUMERATED -const char* wus_max_dur_factor_nb_r15_opts::to_string() const -{ - static const char* options[] = {"one128th", "one64th", "one32th", "one16th", "oneEighth", "oneQuarter", "oneHalf"}; - return convert_enum_idx(options, 7, value, "wus_max_dur_factor_nb_r15_e"); -} -float wus_max_dur_factor_nb_r15_opts::to_number() const +const char* nprach_params_nb_v1330_s::nprach_num_cbra_start_subcarriers_r13_opts::to_string() const { - static const float options[] = {128.0, 64.0, 32.0, 16.0, 0.125, 0.25, 0.5}; - return map_enum_number(options, 7, value, "wus_max_dur_factor_nb_r15_e"); + static const char* options[] = { + "n8", "n10", "n11", "n12", "n20", "n22", "n23", "n24", "n32", "n34", "n35", "n36", "n40", "n44", "n46", "n48"}; + return convert_enum_idx(options, 16, value, "nprach_params_nb_v1330_s::nprach_num_cbra_start_subcarriers_r13_e_"); } -const char* wus_max_dur_factor_nb_r15_opts::to_number_string() const +uint8_t nprach_params_nb_v1330_s::nprach_num_cbra_start_subcarriers_r13_opts::to_number() const { - static const char* options[] = {"128", "64", "32", "16", "1/8", "1/4", "1/2"}; - return convert_enum_idx(options, 7, value, "wus_max_dur_factor_nb_r15_e"); + static const uint8_t options[] = {8, 10, 11, 12, 20, 22, 23, 24, 32, 34, 35, 36, 40, 44, 46, 48}; + return map_enum_number(options, 16, value, "nprach_params_nb_v1330_s::nprach_num_cbra_start_subcarriers_r13_e_"); } -// DL-CarrierConfigCommon-NB-r14 ::= SEQUENCE -SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::pack(bit_ref& bref) const +// NPRACH-ParametersFmt2-NB-r15 ::= SEQUENCE +SRSASN_CODE nprach_params_fmt2_nb_r15_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(inband_carrier_info_r14_present, 1)); - HANDLE_CODE(bref.pack(nrs_pwr_offset_non_anchor_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15_present, 1)); - HANDLE_CODE(dl_carrier_freq_r14.pack(bref)); - HANDLE_CODE(dl_bitmap_non_anchor_r14.pack(bref)); - HANDLE_CODE(dl_gap_non_anchor_r14.pack(bref)); - if (inband_carrier_info_r14_present) { - HANDLE_CODE(bref.pack(inband_carrier_info_r14.same_pci_ind_r14_present, 1)); - if (inband_carrier_info_r14.same_pci_ind_r14_present) { - HANDLE_CODE(inband_carrier_info_r14.same_pci_ind_r14.pack(bref)); + if (nprach_params_r15_present) { + bref.pack(nprach_params_r15.ext, 1); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_periodicity_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_start_time_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_subcarrier_offset_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_num_subcarriers_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_num_repeats_ra_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_start_sf_css_ra_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_offset_ra_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_carrier_idx_r15_present, 1)); + if (nprach_params_r15.nprach_periodicity_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_periodicity_r15.pack(bref)); } - HANDLE_CODE(inband_carrier_info_r14.eutra_ctrl_region_size_r14.pack(bref)); - } - if (nrs_pwr_offset_non_anchor_r14_present) { - HANDLE_CODE(nrs_pwr_offset_non_anchor_r14.pack(bref)); - } - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= dl_gap_non_anchor_v1530.is_present(); - group_flags[1] |= dl_carrier_freq_v1550.is_present(); - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(dl_gap_non_anchor_v1530.is_present(), 1)); - if (dl_gap_non_anchor_v1530.is_present()) { - HANDLE_CODE(dl_gap_non_anchor_v1530->pack(bref)); - } + if (nprach_params_r15.nprach_start_time_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_start_time_r15.pack(bref)); } - if (group_flags[1]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(dl_carrier_freq_v1550.is_present(), 1)); - if (dl_carrier_freq_v1550.is_present()) { - HANDLE_CODE(dl_carrier_freq_v1550->pack(bref)); - } + if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_subcarrier_offset_r15.pack(bref)); } - } - return SRSASN_SUCCESS; -} -SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(inband_carrier_info_r14_present, 1)); - HANDLE_CODE(bref.unpack(nrs_pwr_offset_non_anchor_r14_present, 1)); - - HANDLE_CODE(dl_carrier_freq_r14.unpack(bref)); - HANDLE_CODE(dl_bitmap_non_anchor_r14.unpack(bref)); - HANDLE_CODE(dl_gap_non_anchor_r14.unpack(bref)); - if (inband_carrier_info_r14_present) { - HANDLE_CODE(bref.unpack(inband_carrier_info_r14.same_pci_ind_r14_present, 1)); - if (inband_carrier_info_r14.same_pci_ind_r14_present) { - HANDLE_CODE(inband_carrier_info_r14.same_pci_ind_r14.unpack(bref)); + if (nprach_params_r15.nprach_num_subcarriers_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_num_subcarriers_r15.pack(bref)); } - HANDLE_CODE(inband_carrier_info_r14.eutra_ctrl_region_size_r14.unpack(bref)); - } - if (nrs_pwr_offset_non_anchor_r14_present) { - HANDLE_CODE(nrs_pwr_offset_non_anchor_r14.unpack(bref)); - } - - if (ext) { - ext_groups_unpacker_guard group_flags(2); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool dl_gap_non_anchor_v1530_present; - HANDLE_CODE(bref.unpack(dl_gap_non_anchor_v1530_present, 1)); - dl_gap_non_anchor_v1530.set_present(dl_gap_non_anchor_v1530_present); - if (dl_gap_non_anchor_v1530.is_present()) { - HANDLE_CODE(dl_gap_non_anchor_v1530->unpack(bref)); - } + if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.pack(bref)); } - if (group_flags[1]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool dl_carrier_freq_v1550_present; - HANDLE_CODE(bref.unpack(dl_carrier_freq_v1550_present, 1)); - dl_carrier_freq_v1550.set_present(dl_carrier_freq_v1550_present); - if (dl_carrier_freq_v1550.is_present()) { - HANDLE_CODE(dl_carrier_freq_v1550->unpack(bref)); - } + if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_num_repeats_ra_r15.pack(bref)); } - } - return SRSASN_SUCCESS; -} -void dl_carrier_cfg_common_nb_r14_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("dl-CarrierFreq-r14"); - dl_carrier_freq_r14.to_json(j); - j.write_fieldname("downlinkBitmapNonAnchor-r14"); - dl_bitmap_non_anchor_r14.to_json(j); - j.write_fieldname("dl-GapNonAnchor-r14"); - dl_gap_non_anchor_r14.to_json(j); - if (inband_carrier_info_r14_present) { - j.write_fieldname("inbandCarrierInfo-r14"); - j.start_obj(); - if (inband_carrier_info_r14.same_pci_ind_r14_present) { - j.write_fieldname("samePCI-Indicator-r14"); - inband_carrier_info_r14.same_pci_ind_r14.to_json(j); + if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_start_sf_css_ra_r15.pack(bref)); } - j.write_str("eutraControlRegionSize-r14", inband_carrier_info_r14.eutra_ctrl_region_size_r14.to_string()); - j.end_obj(); - } - if (nrs_pwr_offset_non_anchor_r14_present) { - j.write_str("nrs-PowerOffsetNonAnchor-r14", nrs_pwr_offset_non_anchor_r14.to_string()); - } - if (ext) { - if (dl_gap_non_anchor_v1530.is_present()) { - j.write_fieldname("dl-GapNonAnchor-v1530"); - dl_gap_non_anchor_v1530->to_json(j); + if (nprach_params_r15.npdcch_offset_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_offset_ra_r15.pack(bref)); } - if (dl_carrier_freq_v1550.is_present()) { - j.write_fieldname("dl-CarrierFreq-v1550"); - dl_carrier_freq_v1550->to_json(j); + if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.pack(bref)); + } + if (nprach_params_r15.npdcch_carrier_idx_r15_present) { + HANDLE_CODE(pack_integer(bref, nprach_params_r15.npdcch_carrier_idx_r15, (uint8_t)1u, (uint8_t)15u)); } } - j.end_obj(); -} -void dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::set(types::options e) -{ - type_ = e; + return SRSASN_SUCCESS; } -void dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::set_use_no_bitmap_r14() +SRSASN_CODE nprach_params_fmt2_nb_r15_s::unpack(cbit_ref& bref) { - set(types::use_no_bitmap_r14); -} -void dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::set_use_anchor_bitmap_r14() -{ - set(types::use_anchor_bitmap_r14); -} -dl_bitmap_nb_r13_c& dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::set_explicit_bitmap_cfg_r14() -{ - set(types::explicit_bitmap_cfg_r14); - return c; + HANDLE_CODE(bref.unpack(nprach_params_r15_present, 1)); + + if (nprach_params_r15_present) { + bref.unpack(nprach_params_r15.ext, 1); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_periodicity_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_start_time_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_subcarrier_offset_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_num_subcarriers_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_num_repeats_ra_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_start_sf_css_ra_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_offset_ra_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_carrier_idx_r15_present, 1)); + if (nprach_params_r15.nprach_periodicity_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_periodicity_r15.unpack(bref)); + } + if (nprach_params_r15.nprach_start_time_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_start_time_r15.unpack(bref)); + } + if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_subcarrier_offset_r15.unpack(bref)); + } + if (nprach_params_r15.nprach_num_subcarriers_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_num_subcarriers_r15.unpack(bref)); + } + if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.unpack(bref)); + } + if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_num_repeats_ra_r15.unpack(bref)); + } + if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_start_sf_css_ra_r15.unpack(bref)); + } + if (nprach_params_r15.npdcch_offset_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_offset_ra_r15.unpack(bref)); + } + if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.unpack(bref)); + } + if (nprach_params_r15.npdcch_carrier_idx_r15_present) { + HANDLE_CODE(unpack_integer(nprach_params_r15.npdcch_carrier_idx_r15, bref, (uint8_t)1u, (uint8_t)15u)); + } + } + + return SRSASN_SUCCESS; } -void dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::to_json(json_writer& j) const +void nprach_params_fmt2_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::use_no_bitmap_r14: - break; - case types::use_anchor_bitmap_r14: - break; - case types::explicit_bitmap_cfg_r14: - j.write_fieldname("explicitBitmapConfiguration-r14"); - c.to_json(j); - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_"); + if (nprach_params_r15_present) { + j.write_fieldname("nprach-Parameters-r15"); + j.start_obj(); + if (nprach_params_r15.nprach_periodicity_r15_present) { + j.write_str("nprach-Periodicity-r15", nprach_params_r15.nprach_periodicity_r15.to_string()); + } + if (nprach_params_r15.nprach_start_time_r15_present) { + j.write_str("nprach-StartTime-r15", nprach_params_r15.nprach_start_time_r15.to_string()); + } + if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { + j.write_str("nprach-SubcarrierOffset-r15", nprach_params_r15.nprach_subcarrier_offset_r15.to_string()); + } + if (nprach_params_r15.nprach_num_subcarriers_r15_present) { + j.write_str("nprach-NumSubcarriers-r15", nprach_params_r15.nprach_num_subcarriers_r15.to_string()); + } + if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { + j.write_str("nprach-SubcarrierMSG3-RangeStart-r15", + nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.to_string()); + } + if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { + j.write_str("npdcch-NumRepetitions-RA-r15", nprach_params_r15.npdcch_num_repeats_ra_r15.to_string()); + } + if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { + j.write_str("npdcch-StartSF-CSS-RA-r15", nprach_params_r15.npdcch_start_sf_css_ra_r15.to_string()); + } + if (nprach_params_r15.npdcch_offset_ra_r15_present) { + j.write_str("npdcch-Offset-RA-r15", nprach_params_r15.npdcch_offset_ra_r15.to_string()); + } + if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { + j.write_str("nprach-NumCBRA-StartSubcarriers-r15", + nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.to_string()); + } + if (nprach_params_r15.npdcch_carrier_idx_r15_present) { + j.write_int("npdcch-CarrierIndex-r15", nprach_params_r15.npdcch_carrier_idx_r15); + } + j.end_obj(); } j.end_obj(); } -SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::pack(bit_ref& bref) const + +const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_opts::to_string() const { - type_.pack(bref); - switch (type_) { - case types::use_no_bitmap_r14: - break; - case types::use_anchor_bitmap_r14: - break; - case types::explicit_bitmap_cfg_r14: - HANDLE_CODE(c.pack(bref)); - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_"); - return SRSASN_ERROR_ENCODE_FAIL; - } - return SRSASN_SUCCESS; + static const char* options[] = {"ms40", "ms80", "ms160", "ms320", "ms640", "ms1280", "ms2560", "ms5120"}; + return convert_enum_idx( + options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_e_"); } -SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::unpack(cbit_ref& bref) +uint16_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_opts::to_number() const { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::use_no_bitmap_r14: - break; - case types::use_anchor_bitmap_r14: - break; - case types::explicit_bitmap_cfg_r14: - HANDLE_CODE(c.unpack(bref)); - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_"); - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; + static const uint16_t options[] = {40, 80, 160, 320, 640, 1280, 2560, 5120}; + return map_enum_number( + options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_e_"); } -const char* dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::types_opts::to_string() const +const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_opts::to_string() const { - static const char* options[] = {"useNoBitmap-r14", "useAnchorBitmap-r14", "explicitBitmapConfiguration-r14"}; - return convert_enum_idx(options, 3, value, "dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::types"); + static const char* options[] = {"ms8", "ms16", "ms32", "ms64", "ms128", "ms256", "ms512", "ms1024"}; + return convert_enum_idx( + options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_e_"); +} +uint16_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_opts::to_number() const +{ + static const uint16_t options[] = {8, 16, 32, 64, 128, 256, 512, 1024}; + return map_enum_number( + options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_e_"); } -void dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::set(types::options e) +const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_opts::to_string() const { - type_ = e; + static const char* options[] = { + "n0", "n36", "n72", "n108", "n6", "n54", "n102", "n42", "n78", "n90", "n12", "n24", "n48", "n84", "n60", "n18"}; + return convert_enum_idx( + options, 16, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_e_"); } -void dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::set_use_no_gap_r14() +uint8_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_opts::to_number() const { - set(types::use_no_gap_r14); + static const uint8_t options[] = {0, 36, 72, 108, 6, 54, 102, 42, 78, 90, 12, 24, 48, 84, 60, 18}; + return map_enum_number( + options, 16, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_e_"); } -void dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::set_use_anchor_gap_cfg_r14() + +const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_opts::to_string() const { - set(types::use_anchor_gap_cfg_r14); + static const char* options[] = {"n36", "n72", "n108", "n144"}; + return convert_enum_idx( + options, 4, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_e_"); } -dl_gap_cfg_nb_r13_s& dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::set_explicit_gap_cfg_r14() +uint8_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_opts::to_number() const { - set(types::explicit_gap_cfg_r14); - return c; + static const uint8_t options[] = {36, 72, 108, 144}; + return map_enum_number( + options, 4, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_e_"); } -void dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::to_json(json_writer& j) const + +const char* +nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_string() const { - j.start_obj(); - switch (type_) { - case types::use_no_gap_r14: - break; - case types::use_anchor_gap_cfg_r14: - break; - case types::explicit_gap_cfg_r14: - j.write_fieldname("explicitGapConfiguration-r14"); - c.to_json(j); - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_"); - } - j.end_obj(); + static const char* options[] = {"zero", "oneThird", "twoThird", "one"}; + return convert_enum_idx( + options, + 4, + value, + "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); } -SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::pack(bit_ref& bref) const +float nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_number() const { - type_.pack(bref); - switch (type_) { - case types::use_no_gap_r14: - break; - case types::use_anchor_gap_cfg_r14: - break; - case types::explicit_gap_cfg_r14: - HANDLE_CODE(c.pack(bref)); - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_"); - return SRSASN_ERROR_ENCODE_FAIL; - } - return SRSASN_SUCCESS; + static const float options[] = {0.0, 0.3333333333333333, 0.6666666666666666, 1.0}; + return map_enum_number( + options, + 4, + value, + "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); } -SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::unpack(cbit_ref& bref) +const char* +nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_number_string() const { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::use_no_gap_r14: - break; - case types::use_anchor_gap_cfg_r14: - break; - case types::explicit_gap_cfg_r14: - HANDLE_CODE(c.unpack(bref)); - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_"); - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; + static const char* options[] = {"0", "1/3", "2/3", "1"}; + return convert_enum_idx( + options, + 4, + value, + "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); } -const char* dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::types_opts::to_string() const -{ - static const char* options[] = {"useNoGap-r14", "useAnchorGapConfig-r14", "explicitGapConfiguration-r14"}; - return convert_enum_idx(options, 3, value, "dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::types"); -} - -void dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::destroy_() -{ - switch (type_) { - case types::same_pci_r14: - c.destroy(); - break; - case types::different_pci_r14: - c.destroy(); - break; - default: - break; - } -} -void dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::set(types::options e) +const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_opts::to_string() const { - destroy_(); - type_ = e; - switch (type_) { - case types::same_pci_r14: - c.init(); - break; - case types::different_pci_r14: - c.init(); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); - } + static const char* options[] = {"r1", + "r2", + "r4", + "r8", + "r16", + "r32", + "r64", + "r128", + "r256", + "r512", + "r1024", + "r2048", + "spare4", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx( + options, 16, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_e_"); } -dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::same_pci_ind_r14_c_( - const dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_& other) +uint16_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_opts::to_number() const { - type_ = other.type(); - switch (type_) { - case types::same_pci_r14: - c.init(other.c.get()); - break; - case types::different_pci_r14: - c.init(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); - } + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; + return map_enum_number( + options, 12, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_e_"); } -dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_& -dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::operator=( - const dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_& other) -{ - if (this == &other) { - return *this; - } - set(other.type()); - switch (type_) { - case types::same_pci_r14: - c.set(other.c.get()); - break; - case types::different_pci_r14: - c.set(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); - } - return *this; -} -dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::same_pci_r14_s_& -dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::set_same_pci_r14() -{ - set(types::same_pci_r14); - return c.get(); -} -dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::different_pci_r14_s_& -dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::set_different_pci_r14() -{ - set(types::different_pci_r14); - return c.get(); -} -void dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::to_json(json_writer& j) const +const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_opts::to_string() const { - j.start_obj(); - switch (type_) { - case types::same_pci_r14: - j.write_fieldname("samePCI-r14"); - j.start_obj(); - j.write_int("indexToMidPRB-r14", c.get().idx_to_mid_prb_r14); - j.end_obj(); - break; - case types::different_pci_r14: - j.write_fieldname("differentPCI-r14"); - j.start_obj(); - j.write_str("eutra-NumCRS-Ports-r14", c.get().eutra_num_crs_ports_r14.to_string()); - j.end_obj(); - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); - } - j.end_obj(); + static const char* options[] = {"v1dot5", "v2", "v4", "v8", "v16", "v32", "v48", "v64"}; + return convert_enum_idx( + options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_e_"); } -SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::pack(bit_ref& bref) const +float nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_opts::to_number() const { - type_.pack(bref); - switch (type_) { - case types::same_pci_r14: - HANDLE_CODE(pack_integer(bref, c.get().idx_to_mid_prb_r14, (int8_t)-55, (int8_t)54)); - break; - case types::different_pci_r14: - HANDLE_CODE(c.get().eutra_num_crs_ports_r14.pack(bref)); - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); - return SRSASN_ERROR_ENCODE_FAIL; - } - return SRSASN_SUCCESS; + static const float options[] = {1.5, 2.0, 4.0, 8.0, 16.0, 32.0, 48.0, 64.0}; + return map_enum_number( + options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_e_"); } -SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::unpack(cbit_ref& bref) +const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_opts::to_number_string() const { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::same_pci_r14: - HANDLE_CODE(unpack_integer(c.get().idx_to_mid_prb_r14, bref, (int8_t)-55, (int8_t)54)); - break; - case types::different_pci_r14: - HANDLE_CODE(c.get().eutra_num_crs_ports_r14.unpack(bref)); - break; - default: - log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; + static const char* options[] = {"1.5", "2", "4", "8", "16", "32", "48", "64"}; + return convert_enum_idx( + options, 8, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_e_"); } -const char* dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::different_pci_r14_s_:: - eutra_num_crs_ports_r14_opts::to_string() const +const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_string() const { - static const char* options[] = {"same", "four"}; - return convert_enum_idx(options, - 2, - value, - "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::different_" - "pci_r14_s_::eutra_num_crs_ports_r14_e_"); + static const char* options[] = {"zero", "oneEighth", "oneFourth", "threeEighth"}; + return convert_enum_idx( + options, 4, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); } -uint8_t dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::different_pci_r14_s_:: - eutra_num_crs_ports_r14_opts::to_number() const +float nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_number() const { - if (value == four) { - return 4; - } - invalid_enum_number(value, - "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::different_pci_" - "r14_s_::eutra_num_crs_ports_r14_e_"); - return 0; + static const float options[] = {0.0, 0.125, 0.25, 0.375}; + return map_enum_number( + options, 4, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); } - -const char* -dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::types_opts::to_string() const +const char* nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_number_string() const { - static const char* options[] = {"samePCI-r14", "differentPCI-r14"}; + static const char* options[] = {"0", "1/8", "1/4", "3/8"}; return convert_enum_idx( - options, 2, value, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::types"); + options, 4, value, "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); } const char* -dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::eutra_ctrl_region_size_r14_opts::to_string() const +nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_opts::to_string() const { - static const char* options[] = {"n1", "n2", "n3"}; + static const char* options[] = {"n24", + "n30", + "n33", + "n36", + "n60", + "n66", + "n69", + "n72", + "n96", + "n102", + "n105", + "n108", + "n120", + "n132", + "n138", + "n144"}; return convert_enum_idx( - options, 3, value, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::eutra_ctrl_region_size_r14_e_"); -} -uint8_t dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::eutra_ctrl_region_size_r14_opts::to_number() const -{ - static const uint8_t options[] = {1, 2, 3}; - return map_enum_number( - options, 3, value, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::eutra_ctrl_region_size_r14_e_"); -} - -const char* dl_carrier_cfg_common_nb_r14_s::nrs_pwr_offset_non_anchor_r14_opts::to_string() const -{ - static const char* options[] = {"dB-12", "dB-10", "dB-8", "dB-6", "dB-4", "dB-2", "dB0", "dB3"}; - return convert_enum_idx(options, 8, value, "dl_carrier_cfg_common_nb_r14_s::nrs_pwr_offset_non_anchor_r14_e_"); + options, + 16, + value, + "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_e_"); } -int8_t dl_carrier_cfg_common_nb_r14_s::nrs_pwr_offset_non_anchor_r14_opts::to_number() const +uint8_t nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_opts::to_number() const { - static const int8_t options[] = {-12, -10, -8, -6, -4, -2, 0, 3}; - return map_enum_number(options, 8, value, "dl_carrier_cfg_common_nb_r14_s::nrs_pwr_offset_non_anchor_r14_e_"); + static const uint8_t options[] = {24, 30, 33, 36, 60, 66, 69, 72, 96, 102, 105, 108, 120, 132, 138, 144}; + return map_enum_number(options, + 16, + value, + "nprach_params_fmt2_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_e_"); } -// PCCH-Config-NB-r14 ::= SEQUENCE -SRSASN_CODE pcch_cfg_nb_r14_s::pack(bit_ref& bref) const +// NPRACH-ParametersTDD-NB-r15 ::= SEQUENCE +SRSASN_CODE nprach_params_tdd_nb_r15_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(npdcch_num_repeat_paging_r14_present, 1)); - HANDLE_CODE(bref.pack(paging_weight_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15_present, 1)); - if (npdcch_num_repeat_paging_r14_present) { - HANDLE_CODE(npdcch_num_repeat_paging_r14.pack(bref)); - } - if (paging_weight_r14_present) { - HANDLE_CODE(paging_weight_r14.pack(bref)); + if (nprach_params_r15_present) { + bref.pack(nprach_params_r15.ext, 1); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_periodicity_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_start_time_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_subcarrier_offset_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_num_subcarriers_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_num_repeats_ra_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_start_sf_css_ra_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.npdcch_offset_ra_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present, 1)); + if (nprach_params_r15.nprach_periodicity_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_periodicity_r15.pack(bref)); + } + if (nprach_params_r15.nprach_start_time_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_start_time_r15.pack(bref)); + } + if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_subcarrier_offset_r15.pack(bref)); + } + if (nprach_params_r15.nprach_num_subcarriers_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_num_subcarriers_r15.pack(bref)); + } + if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.pack(bref)); + } + if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_num_repeats_ra_r15.pack(bref)); + } + if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_start_sf_css_ra_r15.pack(bref)); + } + if (nprach_params_r15.npdcch_offset_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_offset_ra_r15.pack(bref)); + } + if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.pack(bref)); + } } return SRSASN_SUCCESS; } -SRSASN_CODE pcch_cfg_nb_r14_s::unpack(cbit_ref& bref) +SRSASN_CODE nprach_params_tdd_nb_r15_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(npdcch_num_repeat_paging_r14_present, 1)); - HANDLE_CODE(bref.unpack(paging_weight_r14_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15_present, 1)); - if (npdcch_num_repeat_paging_r14_present) { - HANDLE_CODE(npdcch_num_repeat_paging_r14.unpack(bref)); - } - if (paging_weight_r14_present) { - HANDLE_CODE(paging_weight_r14.unpack(bref)); + if (nprach_params_r15_present) { + bref.unpack(nprach_params_r15.ext, 1); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_periodicity_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_start_time_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_subcarrier_offset_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_num_subcarriers_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_num_repeats_ra_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_start_sf_css_ra_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.npdcch_offset_ra_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present, 1)); + if (nprach_params_r15.nprach_periodicity_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_periodicity_r15.unpack(bref)); + } + if (nprach_params_r15.nprach_start_time_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_start_time_r15.unpack(bref)); + } + if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_subcarrier_offset_r15.unpack(bref)); + } + if (nprach_params_r15.nprach_num_subcarriers_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_num_subcarriers_r15.unpack(bref)); + } + if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.unpack(bref)); + } + if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_num_repeats_ra_r15.unpack(bref)); + } + if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_start_sf_css_ra_r15.unpack(bref)); + } + if (nprach_params_r15.npdcch_offset_ra_r15_present) { + HANDLE_CODE(nprach_params_r15.npdcch_offset_ra_r15.unpack(bref)); + } + if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { + HANDLE_CODE(nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.unpack(bref)); + } } return SRSASN_SUCCESS; } -void pcch_cfg_nb_r14_s::to_json(json_writer& j) const +void nprach_params_tdd_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - if (npdcch_num_repeat_paging_r14_present) { - j.write_str("npdcch-NumRepetitionPaging-r14", npdcch_num_repeat_paging_r14.to_string()); - } - if (paging_weight_r14_present) { - j.write_str("pagingWeight-r14", paging_weight_r14.to_string()); + if (nprach_params_r15_present) { + j.write_fieldname("nprach-Parameters-r15"); + j.start_obj(); + if (nprach_params_r15.nprach_periodicity_r15_present) { + j.write_str("nprach-Periodicity-r15", nprach_params_r15.nprach_periodicity_r15.to_string()); + } + if (nprach_params_r15.nprach_start_time_r15_present) { + j.write_str("nprach-StartTime-r15", nprach_params_r15.nprach_start_time_r15.to_string()); + } + if (nprach_params_r15.nprach_subcarrier_offset_r15_present) { + j.write_str("nprach-SubcarrierOffset-r15", nprach_params_r15.nprach_subcarrier_offset_r15.to_string()); + } + if (nprach_params_r15.nprach_num_subcarriers_r15_present) { + j.write_str("nprach-NumSubcarriers-r15", nprach_params_r15.nprach_num_subcarriers_r15.to_string()); + } + if (nprach_params_r15.nprach_subcarrier_msg3_range_start_r15_present) { + j.write_str("nprach-SubcarrierMSG3-RangeStart-r15", + nprach_params_r15.nprach_subcarrier_msg3_range_start_r15.to_string()); + } + if (nprach_params_r15.npdcch_num_repeats_ra_r15_present) { + j.write_str("npdcch-NumRepetitions-RA-r15", nprach_params_r15.npdcch_num_repeats_ra_r15.to_string()); + } + if (nprach_params_r15.npdcch_start_sf_css_ra_r15_present) { + j.write_str("npdcch-StartSF-CSS-RA-r15", nprach_params_r15.npdcch_start_sf_css_ra_r15.to_string()); + } + if (nprach_params_r15.npdcch_offset_ra_r15_present) { + j.write_str("npdcch-Offset-RA-r15", nprach_params_r15.npdcch_offset_ra_r15.to_string()); + } + if (nprach_params_r15.nprach_num_cbra_start_subcarriers_r15_present) { + j.write_str("nprach-NumCBRA-StartSubcarriers-r15", + nprach_params_r15.nprach_num_cbra_start_subcarriers_r15.to_string()); + } + j.end_obj(); } j.end_obj(); } -const char* pcch_cfg_nb_r14_s::npdcch_num_repeat_paging_r14_opts::to_string() const +const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_opts::to_string() const +{ + static const char* options[] = {"ms80", "ms160", "ms320", "ms640", "ms1280", "ms2560", "ms5120", "ms10240"}; + return convert_enum_idx( + options, 8, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_e_"); +} +uint16_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_opts::to_number() const +{ + static const uint16_t options[] = {80, 160, 320, 640, 1280, 2560, 5120, 10240}; + return map_enum_number( + options, 8, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_periodicity_r15_e_"); +} + +const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_opts::to_string() const +{ + static const char* options[] = {"ms10", + "ms20", + "ms40", + "ms80", + "ms160", + "ms320", + "ms640", + "ms1280", + "ms2560", + "ms5120", + "spare6", + "spare5", + "spare4", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx( + options, 16, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_e_"); +} +uint16_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_opts::to_number() const +{ + static const uint16_t options[] = {10, 20, 40, 80, 160, 320, 640, 1280, 2560, 5120}; + return map_enum_number( + options, 10, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_start_time_r15_e_"); +} + +const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_opts::to_string() const +{ + static const char* options[] = {"n0", "n12", "n24", "n36", "n2", "n18", "n34", "spare1"}; + return convert_enum_idx( + options, 8, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_e_"); +} +uint8_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_opts::to_number() const +{ + static const uint8_t options[] = {0, 12, 24, 36, 2, 18, 34}; + return map_enum_number( + options, 7, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_offset_r15_e_"); +} + +const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_opts::to_string() const +{ + static const char* options[] = {"n12", "n24", "n36", "n48"}; + return convert_enum_idx( + options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_e_"); +} +uint8_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_opts::to_number() const +{ + static const uint8_t options[] = {12, 24, 36, 48}; + return map_enum_number( + options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_subcarriers_r15_e_"); +} + +const char* +nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_string() const +{ + static const char* options[] = {"zero", "oneThird", "twoThird", "one"}; + return convert_enum_idx( + options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); +} +float nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_number() const +{ + static const float options[] = {0.0, 0.3333333333333333, 0.6666666666666666, 1.0}; + return map_enum_number( + options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); +} +const char* +nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_opts::to_number_string() const +{ + static const char* options[] = {"0", "1/3", "2/3", "1"}; + return convert_enum_idx( + options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_subcarrier_msg3_range_start_r15_e_"); +} + +const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_opts::to_string() const { static const char* options[] = {"r1", "r2", @@ -6751,376 +7940,403 @@ const char* pcch_cfg_nb_r14_s::npdcch_num_repeat_paging_r14_opts::to_string() co "spare3", "spare2", "spare1"}; - return convert_enum_idx(options, 16, value, "pcch_cfg_nb_r14_s::npdcch_num_repeat_paging_r14_e_"); + return convert_enum_idx( + options, 16, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_e_"); } -uint16_t pcch_cfg_nb_r14_s::npdcch_num_repeat_paging_r14_opts::to_number() const +uint16_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_opts::to_number() const { static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; - return map_enum_number(options, 12, value, "pcch_cfg_nb_r14_s::npdcch_num_repeat_paging_r14_e_"); + return map_enum_number( + options, 12, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_num_repeats_ra_r15_e_"); } -// PowerRampingParameters-NB-v1450 ::= SEQUENCE -SRSASN_CODE pwr_ramp_params_nb_v1450_s::pack(bit_ref& bref) const +const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_opts::to_string() const { - HANDLE_CODE(bref.pack(preamb_init_rx_target_pwr_v1450_present, 1)); - HANDLE_CODE(bref.pack(pwr_ramp_params_ce1_r14_present, 1)); - - if (preamb_init_rx_target_pwr_v1450_present) { - HANDLE_CODE(preamb_init_rx_target_pwr_v1450.pack(bref)); - } - if (pwr_ramp_params_ce1_r14_present) { - HANDLE_CODE(pwr_ramp_params_ce1_r14.pwr_ramp_step_ce1_r14.pack(bref)); - HANDLE_CODE(pwr_ramp_params_ce1_r14.preamb_init_rx_target_pwr_ce1_r14.pack(bref)); - } - - return SRSASN_SUCCESS; + static const char* options[] = {"v4", "v8", "v16", "v32", "v48", "v64", "v96", "v128"}; + return convert_enum_idx( + options, 8, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_e_"); } -SRSASN_CODE pwr_ramp_params_nb_v1450_s::unpack(cbit_ref& bref) +uint8_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_opts::to_number() const { - HANDLE_CODE(bref.unpack(preamb_init_rx_target_pwr_v1450_present, 1)); - HANDLE_CODE(bref.unpack(pwr_ramp_params_ce1_r14_present, 1)); + static const uint8_t options[] = {4, 8, 16, 32, 48, 64, 96, 128}; + return map_enum_number( + options, 8, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_start_sf_css_ra_r15_e_"); +} - if (preamb_init_rx_target_pwr_v1450_present) { - HANDLE_CODE(preamb_init_rx_target_pwr_v1450.unpack(bref)); - } - if (pwr_ramp_params_ce1_r14_present) { - HANDLE_CODE(pwr_ramp_params_ce1_r14.pwr_ramp_step_ce1_r14.unpack(bref)); - HANDLE_CODE(pwr_ramp_params_ce1_r14.preamb_init_rx_target_pwr_ce1_r14.unpack(bref)); - } - - return SRSASN_SUCCESS; -} -void pwr_ramp_params_nb_v1450_s::to_json(json_writer& j) const -{ - j.start_obj(); - if (preamb_init_rx_target_pwr_v1450_present) { - j.write_str("preambleInitialReceivedTargetPower-v1450", preamb_init_rx_target_pwr_v1450.to_string()); - } - if (pwr_ramp_params_ce1_r14_present) { - j.write_fieldname("powerRampingParametersCE1-r14"); - j.start_obj(); - j.write_str("powerRampingStepCE1-r14", pwr_ramp_params_ce1_r14.pwr_ramp_step_ce1_r14.to_string()); - j.write_str("preambleInitialReceivedTargetPowerCE1-r14", - pwr_ramp_params_ce1_r14.preamb_init_rx_target_pwr_ce1_r14.to_string()); - j.end_obj(); - } - j.end_obj(); -} - -const char* pwr_ramp_params_nb_v1450_s::preamb_init_rx_target_pwr_v1450_opts::to_string() const +const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_string() const { - static const char* options[] = { - "dBm-130", "dBm-128", "dBm-126", "dBm-124", "dBm-122", "dBm-88", "dBm-86", "dBm-84", "dBm-82", "dBm-80"}; - return convert_enum_idx(options, 10, value, "pwr_ramp_params_nb_v1450_s::preamb_init_rx_target_pwr_v1450_e_"); + static const char* options[] = {"zero", "oneEighth", "oneFourth", "threeEighth"}; + return convert_enum_idx( + options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); } -int16_t pwr_ramp_params_nb_v1450_s::preamb_init_rx_target_pwr_v1450_opts::to_number() const +float nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_number() const { - static const int16_t options[] = {-130, -128, -126, -124, -122, -88, -86, -84, -82, -80}; - return map_enum_number(options, 10, value, "pwr_ramp_params_nb_v1450_s::preamb_init_rx_target_pwr_v1450_e_"); + static const float options[] = {0.0, 0.125, 0.25, 0.375}; + return map_enum_number( + options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); } - -const char* pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::pwr_ramp_step_ce1_r14_opts::to_string() const +const char* nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_opts::to_number_string() const { - static const char* options[] = {"dB0", "dB2", "dB4", "dB6"}; + static const char* options[] = {"0", "1/8", "1/4", "3/8"}; return convert_enum_idx( - options, 4, value, "pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::pwr_ramp_step_ce1_r14_e_"); -} -uint8_t pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::pwr_ramp_step_ce1_r14_opts::to_number() const -{ - static const uint8_t options[] = {0, 2, 4, 6}; - return map_enum_number( - options, 4, value, "pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::pwr_ramp_step_ce1_r14_e_"); + options, 4, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::npdcch_offset_ra_r15_e_"); } const char* -pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::preamb_init_rx_target_pwr_ce1_r14_opts::to_string() const +nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_opts::to_string() const { - static const char* options[] = {"dBm-130", "dBm-128", "dBm-126", "dBm-124", "dBm-122", "dBm-120", "dBm-118", - "dBm-116", "dBm-114", "dBm-112", "dBm-110", "dBm-108", "dBm-106", "dBm-104", - "dBm-102", "dBm-100", "dBm-98", "dBm-96", "dBm-94", "dBm-92", "dBm-90", - "dBm-88", "dBm-86", "dBm-84", "dBm-82", "dBm-80"}; + static const char* options[] = { + "n8", "n10", "n11", "n12", "n20", "n22", "n23", "n24", "n32", "n34", "n35", "n36", "n40", "n44", "n46", "n48"}; return convert_enum_idx( - options, - 26, - value, - "pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::preamb_init_rx_target_pwr_ce1_r14_e_"); + options, 16, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_e_"); } -int16_t -pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::preamb_init_rx_target_pwr_ce1_r14_opts::to_number() const +uint8_t nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_opts::to_number() const { - static const int16_t options[] = {-130, -128, -126, -124, -122, -120, -118, -116, -114, -112, -110, -108, -106, - -104, -102, -100, -98, -96, -94, -92, -90, -88, -86, -84, -82, -80}; + static const uint8_t options[] = {8, 10, 11, 12, 20, 22, 23, 24, 32, 34, 35, 36, 40, 44, 46, 48}; return map_enum_number( - options, - 26, - value, - "pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::preamb_init_rx_target_pwr_ce1_r14_e_"); + options, 16, value, "nprach_params_tdd_nb_r15_s::nprach_params_r15_s_::nprach_num_cbra_start_subcarriers_r15_e_"); } -// TDD-Config-NB-r15 ::= SEQUENCE -SRSASN_CODE tdd_cfg_nb_r15_s::pack(bit_ref& bref) const +// NPRACH-ParametersTDD-NB-v1550 ::= SEQUENCE +SRSASN_CODE nprach_params_tdd_nb_v1550_s::pack(bit_ref& bref) const { - HANDLE_CODE(sf_assign_r15.pack(bref)); - HANDLE_CODE(special_sf_patterns_r15.pack(bref)); + HANDLE_CODE(max_num_preamb_attempt_ce_v1550.pack(bref)); + HANDLE_CODE(num_repeats_per_preamb_attempt_v1550.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE tdd_cfg_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE nprach_params_tdd_nb_v1550_s::unpack(cbit_ref& bref) { - HANDLE_CODE(sf_assign_r15.unpack(bref)); - HANDLE_CODE(special_sf_patterns_r15.unpack(bref)); + HANDLE_CODE(max_num_preamb_attempt_ce_v1550.unpack(bref)); + HANDLE_CODE(num_repeats_per_preamb_attempt_v1550.unpack(bref)); return SRSASN_SUCCESS; } -void tdd_cfg_nb_r15_s::to_json(json_writer& j) const +void nprach_params_tdd_nb_v1550_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("subframeAssignment-r15", sf_assign_r15.to_string()); - j.write_str("specialSubframePatterns-r15", special_sf_patterns_r15.to_string()); + j.write_str("maxNumPreambleAttemptCE-v1550", max_num_preamb_attempt_ce_v1550.to_string()); + j.write_str("numRepetitionsPerPreambleAttempt-v1550", num_repeats_per_preamb_attempt_v1550.to_string()); j.end_obj(); } -const char* tdd_cfg_nb_r15_s::sf_assign_r15_opts::to_string() const +const char* nprach_params_tdd_nb_v1550_s::max_num_preamb_attempt_ce_v1550_opts::to_string() const { - static const char* options[] = {"sa1", "sa2", "sa3", "sa4", "sa5"}; - return convert_enum_idx(options, 5, value, "tdd_cfg_nb_r15_s::sf_assign_r15_e_"); + static const char* options[] = {"n3", "n4", "n5", "n6", "n7", "n8", "n10", "spare1"}; + return convert_enum_idx(options, 8, value, "nprach_params_tdd_nb_v1550_s::max_num_preamb_attempt_ce_v1550_e_"); } -uint8_t tdd_cfg_nb_r15_s::sf_assign_r15_opts::to_number() const +uint8_t nprach_params_tdd_nb_v1550_s::max_num_preamb_attempt_ce_v1550_opts::to_number() const { - static const uint8_t options[] = {1, 2, 3, 4, 5}; - return map_enum_number(options, 5, value, "tdd_cfg_nb_r15_s::sf_assign_r15_e_"); + static const uint8_t options[] = {3, 4, 5, 6, 7, 8, 10}; + return map_enum_number(options, 7, value, "nprach_params_tdd_nb_v1550_s::max_num_preamb_attempt_ce_v1550_e_"); } -const char* tdd_cfg_nb_r15_s::special_sf_patterns_r15_opts::to_string() const +const char* nprach_params_tdd_nb_v1550_s::num_repeats_per_preamb_attempt_v1550_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n4", "n8", "n16", "n32", "n64", "n128", "n256", "n512", "n1024"}; + return convert_enum_idx(options, 11, value, "nprach_params_tdd_nb_v1550_s::num_repeats_per_preamb_attempt_v1550_e_"); +} +uint16_t nprach_params_tdd_nb_v1550_s::num_repeats_per_preamb_attempt_v1550_opts::to_number() const +{ + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}; + return map_enum_number(options, 11, value, "nprach_params_tdd_nb_v1550_s::num_repeats_per_preamb_attempt_v1550_e_"); +} + +// PagingWeight-NB-r14 ::= ENUMERATED +const char* paging_weight_nb_r14_opts::to_string() const { static const char* options[] = { - "ssp0", "ssp1", "ssp2", "ssp3", "ssp4", "ssp5", "ssp6", "ssp7", "ssp8", "ssp9", "ssp10", "ssp10-CRS-LessDwPTS"}; - return convert_enum_idx(options, 12, value, "tdd_cfg_nb_r15_s::special_sf_patterns_r15_e_"); + "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15", "w16"}; + return convert_enum_idx(options, 16, value, "paging_weight_nb_r14_e"); +} +uint8_t paging_weight_nb_r14_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + return map_enum_number(options, 16, value, "paging_weight_nb_r14_e"); } -// UL-ReferenceSignalsNPUSCH-NB-r13 ::= SEQUENCE -SRSASN_CODE ul_ref_sigs_npusch_nb_r13_s::pack(bit_ref& bref) const +// RACH-Info-NB-r13 ::= SEQUENCE +SRSASN_CODE rach_info_nb_r13_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(group_hop_enabled_r13, 1)); - HANDLE_CODE(pack_integer(bref, group_assign_npusch_r13, (uint8_t)0u, (uint8_t)29u)); + HANDLE_CODE(ra_resp_win_size_r13.pack(bref)); + HANDLE_CODE(mac_contention_resolution_timer_r13.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE ul_ref_sigs_npusch_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE rach_info_nb_r13_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(group_hop_enabled_r13, 1)); - HANDLE_CODE(unpack_integer(group_assign_npusch_r13, bref, (uint8_t)0u, (uint8_t)29u)); + HANDLE_CODE(ra_resp_win_size_r13.unpack(bref)); + HANDLE_CODE(mac_contention_resolution_timer_r13.unpack(bref)); return SRSASN_SUCCESS; } -void ul_ref_sigs_npusch_nb_r13_s::to_json(json_writer& j) const +void rach_info_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - j.write_bool("groupHoppingEnabled-r13", group_hop_enabled_r13); - j.write_int("groupAssignmentNPUSCH-r13", group_assign_npusch_r13); + j.write_str("ra-ResponseWindowSize-r13", ra_resp_win_size_r13.to_string()); + j.write_str("mac-ContentionResolutionTimer-r13", mac_contention_resolution_timer_r13.to_string()); j.end_obj(); } -// WUS-ConfigPerCarrier-NB-r15 ::= SEQUENCE -SRSASN_CODE wus_cfg_per_carrier_nb_r15_s::pack(bit_ref& bref) const +const char* rach_info_nb_r13_s::ra_resp_win_size_r13_opts::to_string() const { - HANDLE_CODE(max_dur_factor_r15.pack(bref)); - - return SRSASN_SUCCESS; + static const char* options[] = {"pp2", "pp3", "pp4", "pp5", "pp6", "pp7", "pp8", "pp10"}; + return convert_enum_idx(options, 8, value, "rach_info_nb_r13_s::ra_resp_win_size_r13_e_"); } -SRSASN_CODE wus_cfg_per_carrier_nb_r15_s::unpack(cbit_ref& bref) +uint8_t rach_info_nb_r13_s::ra_resp_win_size_r13_opts::to_number() const { - HANDLE_CODE(max_dur_factor_r15.unpack(bref)); + static const uint8_t options[] = {2, 3, 4, 5, 6, 7, 8, 10}; + return map_enum_number(options, 8, value, "rach_info_nb_r13_s::ra_resp_win_size_r13_e_"); +} - return SRSASN_SUCCESS; +const char* rach_info_nb_r13_s::mac_contention_resolution_timer_r13_opts::to_string() const +{ + static const char* options[] = {"pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32", "pp64"}; + return convert_enum_idx(options, 8, value, "rach_info_nb_r13_s::mac_contention_resolution_timer_r13_e_"); } -void wus_cfg_per_carrier_nb_r15_s::to_json(json_writer& j) const +uint8_t rach_info_nb_r13_s::mac_contention_resolution_timer_r13_opts::to_number() const { - j.start_obj(); - j.write_str("maxDurationFactor-r15", max_dur_factor_r15.to_string()); - j.end_obj(); + static const uint8_t options[] = {1, 2, 3, 4, 8, 16, 32, 64}; + return map_enum_number(options, 8, value, "rach_info_nb_r13_s::mac_contention_resolution_timer_r13_e_"); } -// BCCH-Config-NB-r13 ::= SEQUENCE -SRSASN_CODE bcch_cfg_nb_r13_s::pack(bit_ref& bref) const +// RACH-Info-NB-v1530 ::= SEQUENCE +SRSASN_CODE rach_info_nb_v1530_s::pack(bit_ref& bref) const { - HANDLE_CODE(mod_period_coeff_r13.pack(bref)); + HANDLE_CODE(mac_contention_resolution_timer_r15.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE bcch_cfg_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE rach_info_nb_v1530_s::unpack(cbit_ref& bref) { - HANDLE_CODE(mod_period_coeff_r13.unpack(bref)); + HANDLE_CODE(mac_contention_resolution_timer_r15.unpack(bref)); return SRSASN_SUCCESS; } -void bcch_cfg_nb_r13_s::to_json(json_writer& j) const +void rach_info_nb_v1530_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("modificationPeriodCoeff-r13", mod_period_coeff_r13.to_string()); + j.write_str("mac-ContentionResolutionTimer-r15", mac_contention_resolution_timer_r15.to_string()); j.end_obj(); } -const char* bcch_cfg_nb_r13_s::mod_period_coeff_r13_opts::to_string() const +const char* rach_info_nb_v1530_s::mac_contention_resolution_timer_r15_opts::to_string() const { - static const char* options[] = {"n16", "n32", "n64", "n128"}; - return convert_enum_idx(options, 4, value, "bcch_cfg_nb_r13_s::mod_period_coeff_r13_e_"); + static const char* options[] = {"pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32", "pp64"}; + return convert_enum_idx(options, 8, value, "rach_info_nb_v1530_s::mac_contention_resolution_timer_r15_e_"); } -uint8_t bcch_cfg_nb_r13_s::mod_period_coeff_r13_opts::to_number() const +uint8_t rach_info_nb_v1530_s::mac_contention_resolution_timer_r15_opts::to_number() const { - static const uint8_t options[] = {16, 32, 64, 128}; - return map_enum_number(options, 4, value, "bcch_cfg_nb_r13_s::mod_period_coeff_r13_e_"); + static const uint8_t options[] = {1, 2, 3, 4, 8, 16, 32, 64}; + return map_enum_number(options, 8, value, "rach_info_nb_v1530_s::mac_contention_resolution_timer_r15_e_"); } -// DL-ConfigCommon-NB-r14 ::= SEQUENCE -SRSASN_CODE dl_cfg_common_nb_r14_s::pack(bit_ref& bref) const +// SchedulingInfo-NB-v1530 ::= SEQUENCE +SRSASN_CODE sched_info_nb_v1530_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(pcch_cfg_r14_present, 1)); + HANDLE_CODE(bref.pack(sib_map_info_v1530_present, 1)); - HANDLE_CODE(dl_carrier_cfg_r14.pack(bref)); - if (pcch_cfg_r14_present) { - HANDLE_CODE(pcch_cfg_r14.pack(bref)); + if (sib_map_info_v1530_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, sib_map_info_v1530, 1, 8)); } - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= wus_cfg_r15.is_present(); - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(wus_cfg_r15.is_present(), 1)); - if (wus_cfg_r15.is_present()) { - HANDLE_CODE(wus_cfg_r15->pack(bref)); - } - } - } return SRSASN_SUCCESS; } -SRSASN_CODE dl_cfg_common_nb_r14_s::unpack(cbit_ref& bref) +SRSASN_CODE sched_info_nb_v1530_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(pcch_cfg_r14_present, 1)); + HANDLE_CODE(bref.unpack(sib_map_info_v1530_present, 1)); - HANDLE_CODE(dl_carrier_cfg_r14.unpack(bref)); - if (pcch_cfg_r14_present) { - HANDLE_CODE(pcch_cfg_r14.unpack(bref)); + if (sib_map_info_v1530_present) { + HANDLE_CODE(unpack_dyn_seq_of(sib_map_info_v1530, bref, 1, 8)); } - if (ext) { - ext_groups_unpacker_guard group_flags(1); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool wus_cfg_r15_present; - HANDLE_CODE(bref.unpack(wus_cfg_r15_present, 1)); - wus_cfg_r15.set_present(wus_cfg_r15_present); - if (wus_cfg_r15.is_present()) { - HANDLE_CODE(wus_cfg_r15->unpack(bref)); - } - } - } return SRSASN_SUCCESS; } -void dl_cfg_common_nb_r14_s::to_json(json_writer& j) const +void sched_info_nb_v1530_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("dl-CarrierConfig-r14"); - dl_carrier_cfg_r14.to_json(j); - if (pcch_cfg_r14_present) { - j.write_fieldname("pcch-Config-r14"); - pcch_cfg_r14.to_json(j); - } - if (ext) { - if (wus_cfg_r15.is_present()) { - j.write_fieldname("wus-Config-r15"); - wus_cfg_r15->to_json(j); + if (sib_map_info_v1530_present) { + j.start_array("sib-MappingInfo-v1530"); + for (const auto& e1 : sib_map_info_v1530) { + j.write_str(e1.to_string()); } + j.end_array(); } j.end_obj(); } -// InterFreqCarrierFreqInfo-NB-r13 ::= SEQUENCE -SRSASN_CODE inter_freq_carrier_freq_info_nb_r13_s::pack(bit_ref& bref) const +// SystemInformationBlockType1-NB-v1700 ::= SEQUENCE +SRSASN_CODE sib_type1_nb_v1700_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(q_qual_min_r13_present, 1)); - HANDLE_CODE(bref.pack(p_max_r13_present, 1)); - HANDLE_CODE(bref.pack(q_offset_freq_r13_present, 1)); - HANDLE_CODE(bref.pack(inter_freq_neigh_cell_list_r13_present, 1)); - HANDLE_CODE(bref.pack(inter_freq_black_cell_list_r13_present, 1)); - HANDLE_CODE(bref.pack(multi_band_info_list_r13_present, 1)); + HANDLE_CODE(bref.pack(cell_access_related_info_ntn_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - HANDLE_CODE(dl_carrier_freq_r13.pack(bref)); - HANDLE_CODE(pack_integer(bref, q_rx_lev_min_r13, (int8_t)-70, (int8_t)-22)); - if (q_qual_min_r13_present) { - HANDLE_CODE(pack_integer(bref, q_qual_min_r13, (int8_t)-34, (int8_t)-3)); + if (cell_access_related_info_ntn_r17_present) { + HANDLE_CODE(bref.pack(cell_access_related_info_ntn_r17.plmn_id_list_v1700_present, 1)); + HANDLE_CODE(cell_access_related_info_ntn_r17.cell_barred_ntn_r17.pack(bref)); + if (cell_access_related_info_ntn_r17.plmn_id_list_v1700_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, cell_access_related_info_ntn_r17.plmn_id_list_v1700, 1, 6)); + } } - if (p_max_r13_present) { - HANDLE_CODE(pack_integer(bref, p_max_r13, (int8_t)-30, (int8_t)33)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type1_nb_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(cell_access_related_info_ntn_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (cell_access_related_info_ntn_r17_present) { + HANDLE_CODE(bref.unpack(cell_access_related_info_ntn_r17.plmn_id_list_v1700_present, 1)); + HANDLE_CODE(cell_access_related_info_ntn_r17.cell_barred_ntn_r17.unpack(bref)); + if (cell_access_related_info_ntn_r17.plmn_id_list_v1700_present) { + HANDLE_CODE(unpack_dyn_seq_of(cell_access_related_info_ntn_r17.plmn_id_list_v1700, bref, 1, 6)); + } } - if (q_offset_freq_r13_present) { - HANDLE_CODE(q_offset_freq_r13.pack(bref)); + + return SRSASN_SUCCESS; +} +void sib_type1_nb_v1700_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (cell_access_related_info_ntn_r17_present) { + j.write_fieldname("cellAccessRelatedInfo-NTN-r17"); + j.start_obj(); + j.write_str("cellBarred-NTN-r17", cell_access_related_info_ntn_r17.cell_barred_ntn_r17.to_string()); + if (cell_access_related_info_ntn_r17.plmn_id_list_v1700_present) { + j.start_array("plmn-IdentityList-v1700"); + for (const auto& e1 : cell_access_related_info_ntn_r17.plmn_id_list_v1700) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); } - if (inter_freq_neigh_cell_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_neigh_cell_list_r13, 1, 16, integer_packer(0, 503))); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); } - if (inter_freq_black_cell_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_black_cell_list_r13, 1, 16, integer_packer(0, 503))); + j.end_obj(); +} + +const char* sib_type1_nb_v1700_s::cell_access_related_info_ntn_r17_s_::cell_barred_ntn_r17_opts::to_string() const +{ + static const char* options[] = {"barred", "notBarred"}; + return convert_enum_idx( + options, 2, value, "sib_type1_nb_v1700_s::cell_access_related_info_ntn_r17_s_::cell_barred_ntn_r17_e_"); +} + +// UAC-BarringPerCat-NB-r16 ::= SEQUENCE +SRSASN_CODE uac_barr_per_cat_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, uac_access_category_r16, (uint8_t)1u, (uint8_t)63u)); + HANDLE_CODE(uac_barr_factor_r16.pack(bref)); + HANDLE_CODE(uac_barr_time_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE uac_barr_per_cat_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(uac_access_category_r16, bref, (uint8_t)1u, (uint8_t)63u)); + HANDLE_CODE(uac_barr_factor_r16.unpack(bref)); + HANDLE_CODE(uac_barr_time_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void uac_barr_per_cat_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("uac-accessCategory-r16", uac_access_category_r16); + j.write_str("uac-BarringFactor-r16", uac_barr_factor_r16.to_string()); + j.write_str("uac-BarringTime-r16", uac_barr_time_r16.to_string()); + j.end_obj(); +} + +const char* uac_barr_per_cat_nb_r16_s::uac_barr_factor_r16_opts::to_string() const +{ + static const char* options[] = { + "p00", "p05", "p10", "p15", "p20", "p25", "p30", "p40", "p50", "p60", "p70", "p75", "p80", "p85", "p90", "p95"}; + return convert_enum_idx(options, 16, value, "uac_barr_per_cat_nb_r16_s::uac_barr_factor_r16_e_"); +} +float uac_barr_per_cat_nb_r16_s::uac_barr_factor_r16_opts::to_number() const +{ + static const float options[] = {0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5}; + return map_enum_number(options, 16, value, "uac_barr_per_cat_nb_r16_s::uac_barr_factor_r16_e_"); +} +const char* uac_barr_per_cat_nb_r16_s::uac_barr_factor_r16_opts::to_number_string() const +{ + static const char* options[] = { + "0.0", "0.5", "1.0", "1.5", "2.0", "2.5", "3.0", "4.0", "5.0", "6.0", "7.0", "7.5", "8.0", "8.5", "9.0", "9.5"}; + return convert_enum_idx(options, 16, value, "uac_barr_per_cat_nb_r16_s::uac_barr_factor_r16_e_"); +} + +const char* uac_barr_per_cat_nb_r16_s::uac_barr_time_r16_opts::to_string() const +{ + static const char* options[] = {"s4", "s8", "s16", "s32", "s64", "s128", "s256", "s512"}; + return convert_enum_idx(options, 8, value, "uac_barr_per_cat_nb_r16_s::uac_barr_time_r16_e_"); +} +uint16_t uac_barr_per_cat_nb_r16_s::uac_barr_time_r16_opts::to_number() const +{ + static const uint16_t options[] = {4, 8, 16, 32, 64, 128, 256, 512}; + return map_enum_number(options, 8, value, "uac_barr_per_cat_nb_r16_s::uac_barr_time_r16_e_"); +} + +// WUS-MaxDurationFactor-NB-r15 ::= ENUMERATED +const char* wus_max_dur_factor_nb_r15_opts::to_string() const +{ + static const char* options[] = {"one128th", "one64th", "one32th", "one16th", "oneEighth", "oneQuarter", "oneHalf"}; + return convert_enum_idx(options, 7, value, "wus_max_dur_factor_nb_r15_e"); +} +float wus_max_dur_factor_nb_r15_opts::to_number() const +{ + static const float options[] = {128.0, 64.0, 32.0, 16.0, 0.125, 0.25, 0.5}; + return map_enum_number(options, 7, value, "wus_max_dur_factor_nb_r15_e"); +} +const char* wus_max_dur_factor_nb_r15_opts::to_number_string() const +{ + static const char* options[] = {"128", "64", "32", "16", "1/8", "1/4", "1/2"}; + return convert_enum_idx(options, 7, value, "wus_max_dur_factor_nb_r15_e"); +} + +// DL-CarrierConfigCommon-NB-r14 ::= SEQUENCE +SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(inband_carrier_info_r14_present, 1)); + HANDLE_CODE(bref.pack(nrs_pwr_offset_non_anchor_r14_present, 1)); + + HANDLE_CODE(dl_carrier_freq_r14.pack(bref)); + HANDLE_CODE(dl_bitmap_non_anchor_r14.pack(bref)); + HANDLE_CODE(dl_gap_non_anchor_r14.pack(bref)); + if (inband_carrier_info_r14_present) { + HANDLE_CODE(bref.pack(inband_carrier_info_r14.same_pci_ind_r14_present, 1)); + if (inband_carrier_info_r14.same_pci_ind_r14_present) { + HANDLE_CODE(inband_carrier_info_r14.same_pci_ind_r14.pack(bref)); + } + HANDLE_CODE(inband_carrier_info_r14.eutra_ctrl_region_size_r14.pack(bref)); } - if (multi_band_info_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, multi_band_info_list_r13, 1, 8)); + if (nrs_pwr_offset_non_anchor_r14_present) { + HANDLE_CODE(nrs_pwr_offset_non_anchor_r14.pack(bref)); } if (ext) { ext_groups_packer_guard group_flags; - group_flags[0] |= delta_rx_lev_min_v1350_present; - group_flags[1] |= pwr_class14dbm_offset_r14_present; - group_flags[1] |= ce_authorisation_offset_r14_present; - group_flags[2] |= nsss_rrm_cfg_r15.is_present(); - group_flags[2] |= inter_freq_neigh_cell_list_v1530.is_present(); - group_flags[3] |= dl_carrier_freq_v1550.is_present(); + group_flags[0] |= dl_gap_non_anchor_v1530.is_present(); + group_flags[1] |= dl_carrier_freq_v1550.is_present(); group_flags.pack(bref); if (group_flags[0]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(delta_rx_lev_min_v1350_present, 1)); - if (delta_rx_lev_min_v1350_present) { - HANDLE_CODE(pack_integer(bref, delta_rx_lev_min_v1350, (int8_t)-8, (int8_t)-1)); + HANDLE_CODE(bref.pack(dl_gap_non_anchor_v1530.is_present(), 1)); + if (dl_gap_non_anchor_v1530.is_present()) { + HANDLE_CODE(dl_gap_non_anchor_v1530->pack(bref)); } } if (group_flags[1]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(pwr_class14dbm_offset_r14_present, 1)); - HANDLE_CODE(bref.pack(ce_authorisation_offset_r14_present, 1)); - if (pwr_class14dbm_offset_r14_present) { - HANDLE_CODE(pwr_class14dbm_offset_r14.pack(bref)); - } - if (ce_authorisation_offset_r14_present) { - HANDLE_CODE(ce_authorisation_offset_r14.pack(bref)); - } - } - if (group_flags[2]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(nsss_rrm_cfg_r15.is_present(), 1)); - HANDLE_CODE(bref.pack(inter_freq_neigh_cell_list_v1530.is_present(), 1)); - if (nsss_rrm_cfg_r15.is_present()) { - HANDLE_CODE(nsss_rrm_cfg_r15->pack(bref)); - } - if (inter_freq_neigh_cell_list_v1530.is_present()) { - HANDLE_CODE(pack_dyn_seq_of(bref, *inter_freq_neigh_cell_list_v1530, 1, 16)); - } - } - if (group_flags[3]) { - varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(dl_carrier_freq_v1550.is_present(), 1)); if (dl_carrier_freq_v1550.is_present()) { HANDLE_CODE(dl_carrier_freq_v1550->pack(bref)); @@ -7129,80 +8345,43 @@ SRSASN_CODE inter_freq_carrier_freq_info_nb_r13_s::pack(bit_ref& bref) const } return SRSASN_SUCCESS; } -SRSASN_CODE inter_freq_carrier_freq_info_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(q_qual_min_r13_present, 1)); - HANDLE_CODE(bref.unpack(p_max_r13_present, 1)); - HANDLE_CODE(bref.unpack(q_offset_freq_r13_present, 1)); - HANDLE_CODE(bref.unpack(inter_freq_neigh_cell_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(inter_freq_black_cell_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(multi_band_info_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(inband_carrier_info_r14_present, 1)); + HANDLE_CODE(bref.unpack(nrs_pwr_offset_non_anchor_r14_present, 1)); - HANDLE_CODE(dl_carrier_freq_r13.unpack(bref)); - HANDLE_CODE(unpack_integer(q_rx_lev_min_r13, bref, (int8_t)-70, (int8_t)-22)); - if (q_qual_min_r13_present) { - HANDLE_CODE(unpack_integer(q_qual_min_r13, bref, (int8_t)-34, (int8_t)-3)); - } - if (p_max_r13_present) { - HANDLE_CODE(unpack_integer(p_max_r13, bref, (int8_t)-30, (int8_t)33)); - } - if (q_offset_freq_r13_present) { - HANDLE_CODE(q_offset_freq_r13.unpack(bref)); - } - if (inter_freq_neigh_cell_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(inter_freq_neigh_cell_list_r13, bref, 1, 16, integer_packer(0, 503))); - } - if (inter_freq_black_cell_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(inter_freq_black_cell_list_r13, bref, 1, 16, integer_packer(0, 503))); + HANDLE_CODE(dl_carrier_freq_r14.unpack(bref)); + HANDLE_CODE(dl_bitmap_non_anchor_r14.unpack(bref)); + HANDLE_CODE(dl_gap_non_anchor_r14.unpack(bref)); + if (inband_carrier_info_r14_present) { + HANDLE_CODE(bref.unpack(inband_carrier_info_r14.same_pci_ind_r14_present, 1)); + if (inband_carrier_info_r14.same_pci_ind_r14_present) { + HANDLE_CODE(inband_carrier_info_r14.same_pci_ind_r14.unpack(bref)); + } + HANDLE_CODE(inband_carrier_info_r14.eutra_ctrl_region_size_r14.unpack(bref)); } - if (multi_band_info_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r13, bref, 1, 8)); + if (nrs_pwr_offset_non_anchor_r14_present) { + HANDLE_CODE(nrs_pwr_offset_non_anchor_r14.unpack(bref)); } if (ext) { - ext_groups_unpacker_guard group_flags(4); + ext_groups_unpacker_guard group_flags(2); group_flags.unpack(bref); if (group_flags[0]) { varlength_field_unpack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.unpack(delta_rx_lev_min_v1350_present, 1)); - if (delta_rx_lev_min_v1350_present) { - HANDLE_CODE(unpack_integer(delta_rx_lev_min_v1350, bref, (int8_t)-8, (int8_t)-1)); + bool dl_gap_non_anchor_v1530_present; + HANDLE_CODE(bref.unpack(dl_gap_non_anchor_v1530_present, 1)); + dl_gap_non_anchor_v1530.set_present(dl_gap_non_anchor_v1530_present); + if (dl_gap_non_anchor_v1530.is_present()) { + HANDLE_CODE(dl_gap_non_anchor_v1530->unpack(bref)); } } if (group_flags[1]) { varlength_field_unpack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.unpack(pwr_class14dbm_offset_r14_present, 1)); - HANDLE_CODE(bref.unpack(ce_authorisation_offset_r14_present, 1)); - if (pwr_class14dbm_offset_r14_present) { - HANDLE_CODE(pwr_class14dbm_offset_r14.unpack(bref)); - } - if (ce_authorisation_offset_r14_present) { - HANDLE_CODE(ce_authorisation_offset_r14.unpack(bref)); - } - } - if (group_flags[2]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool nsss_rrm_cfg_r15_present; - HANDLE_CODE(bref.unpack(nsss_rrm_cfg_r15_present, 1)); - nsss_rrm_cfg_r15.set_present(nsss_rrm_cfg_r15_present); - bool inter_freq_neigh_cell_list_v1530_present; - HANDLE_CODE(bref.unpack(inter_freq_neigh_cell_list_v1530_present, 1)); - inter_freq_neigh_cell_list_v1530.set_present(inter_freq_neigh_cell_list_v1530_present); - if (nsss_rrm_cfg_r15.is_present()) { - HANDLE_CODE(nsss_rrm_cfg_r15->unpack(bref)); - } - if (inter_freq_neigh_cell_list_v1530.is_present()) { - HANDLE_CODE(unpack_dyn_seq_of(*inter_freq_neigh_cell_list_v1530, bref, 1, 16)); - } - } - if (group_flags[3]) { - varlength_field_unpack_guard varlen_scope(bref, false); - bool dl_carrier_freq_v1550_present; HANDLE_CODE(bref.unpack(dl_carrier_freq_v1550_present, 1)); dl_carrier_freq_v1550.set_present(dl_carrier_freq_v1550_present); @@ -7213,62 +8392,32 @@ SRSASN_CODE inter_freq_carrier_freq_info_nb_r13_s::unpack(cbit_ref& bref) } return SRSASN_SUCCESS; } -void inter_freq_carrier_freq_info_nb_r13_s::to_json(json_writer& j) const +void dl_carrier_cfg_common_nb_r14_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("dl-CarrierFreq-r13"); - dl_carrier_freq_r13.to_json(j); - j.write_int("q-RxLevMin-r13", q_rx_lev_min_r13); - if (q_qual_min_r13_present) { - j.write_int("q-QualMin-r13", q_qual_min_r13); - } - if (p_max_r13_present) { - j.write_int("p-Max-r13", p_max_r13); - } - if (q_offset_freq_r13_present) { - j.write_str("q-OffsetFreq-r13", q_offset_freq_r13.to_string()); - } - if (inter_freq_neigh_cell_list_r13_present) { - j.start_array("interFreqNeighCellList-r13"); - for (const auto& e1 : inter_freq_neigh_cell_list_r13) { - j.write_int(e1); - } - j.end_array(); - } - if (inter_freq_black_cell_list_r13_present) { - j.start_array("interFreqBlackCellList-r13"); - for (const auto& e1 : inter_freq_black_cell_list_r13) { - j.write_int(e1); + j.write_fieldname("dl-CarrierFreq-r14"); + dl_carrier_freq_r14.to_json(j); + j.write_fieldname("downlinkBitmapNonAnchor-r14"); + dl_bitmap_non_anchor_r14.to_json(j); + j.write_fieldname("dl-GapNonAnchor-r14"); + dl_gap_non_anchor_r14.to_json(j); + if (inband_carrier_info_r14_present) { + j.write_fieldname("inbandCarrierInfo-r14"); + j.start_obj(); + if (inband_carrier_info_r14.same_pci_ind_r14_present) { + j.write_fieldname("samePCI-Indicator-r14"); + inband_carrier_info_r14.same_pci_ind_r14.to_json(j); } - j.end_array(); + j.write_str("eutraControlRegionSize-r14", inband_carrier_info_r14.eutra_ctrl_region_size_r14.to_string()); + j.end_obj(); } - if (multi_band_info_list_r13_present) { - j.start_array("multiBandInfoList-r13"); - for (const auto& e1 : multi_band_info_list_r13) { - e1.to_json(j); - } - j.end_array(); + if (nrs_pwr_offset_non_anchor_r14_present) { + j.write_str("nrs-PowerOffsetNonAnchor-r14", nrs_pwr_offset_non_anchor_r14.to_string()); } if (ext) { - if (delta_rx_lev_min_v1350_present) { - j.write_int("delta-RxLevMin-v1350", delta_rx_lev_min_v1350); - } - if (pwr_class14dbm_offset_r14_present) { - j.write_str("powerClass14dBm-Offset-r14", pwr_class14dbm_offset_r14.to_string()); - } - if (ce_authorisation_offset_r14_present) { - j.write_str("ce-AuthorisationOffset-r14", ce_authorisation_offset_r14.to_string()); - } - if (nsss_rrm_cfg_r15.is_present()) { - j.write_fieldname("nsss-RRM-Config-r15"); - nsss_rrm_cfg_r15->to_json(j); - } - if (inter_freq_neigh_cell_list_v1530.is_present()) { - j.start_array("interFreqNeighCellList-v1530"); - for (const auto& e1 : *inter_freq_neigh_cell_list_v1530) { - e1.to_json(j); - } - j.end_array(); + if (dl_gap_non_anchor_v1530.is_present()) { + j.write_fieldname("dl-GapNonAnchor-v1530"); + dl_gap_non_anchor_v1530->to_json(j); } if (dl_carrier_freq_v1550.is_present()) { j.write_fieldname("dl-CarrierFreq-v1550"); @@ -7278,1584 +8427,1420 @@ void inter_freq_carrier_freq_info_nb_r13_s::to_json(json_writer& j) const j.end_obj(); } -const char* inter_freq_carrier_freq_info_nb_r13_s::pwr_class14dbm_offset_r14_opts::to_string() const +void dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::set(types::options e) { - static const char* options[] = {"dB-6", "dB-3", "dB3", "dB6", "dB9", "dB12"}; - return convert_enum_idx(options, 6, value, "inter_freq_carrier_freq_info_nb_r13_s::pwr_class14dbm_offset_r14_e_"); + type_ = e; } -int8_t inter_freq_carrier_freq_info_nb_r13_s::pwr_class14dbm_offset_r14_opts::to_number() const +void dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::set_use_no_bitmap_r14() { - static const int8_t options[] = {-6, -3, 3, 6, 9, 12}; - return map_enum_number(options, 6, value, "inter_freq_carrier_freq_info_nb_r13_s::pwr_class14dbm_offset_r14_e_"); + set(types::use_no_bitmap_r14); } - -const char* inter_freq_carrier_freq_info_nb_r13_s::ce_authorisation_offset_r14_opts::to_string() const +void dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::set_use_anchor_bitmap_r14() { - static const char* options[] = {"dB5", "dB10", "dB15", "dB20", "dB25", "dB30", "dB35"}; - return convert_enum_idx(options, 7, value, "inter_freq_carrier_freq_info_nb_r13_s::ce_authorisation_offset_r14_e_"); + set(types::use_anchor_bitmap_r14); } -uint8_t inter_freq_carrier_freq_info_nb_r13_s::ce_authorisation_offset_r14_opts::to_number() const +dl_bitmap_nb_r13_c& dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::set_explicit_bitmap_cfg_r14() { - static const uint8_t options[] = {5, 10, 15, 20, 25, 30, 35}; - return map_enum_number(options, 7, value, "inter_freq_carrier_freq_info_nb_r13_s::ce_authorisation_offset_r14_e_"); + set(types::explicit_bitmap_cfg_r14); + return c; } - -// IntraFreqNeighCellInfo-NB-v1530 ::= SEQUENCE -SRSASN_CODE intra_freq_neigh_cell_info_nb_v1530_s::pack(bit_ref& bref) const +void dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::to_json(json_writer& j) const { - HANDLE_CODE(bref.pack(nsss_rrm_cfg_r15_present, 1)); - - if (nsss_rrm_cfg_r15_present) { - HANDLE_CODE(nsss_rrm_cfg_r15.pack(bref)); + j.start_obj(); + switch (type_) { + case types::use_no_bitmap_r14: + break; + case types::use_anchor_bitmap_r14: + break; + case types::explicit_bitmap_cfg_r14: + j.write_fieldname("explicitBitmapConfiguration-r14"); + c.to_json(j); + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_"); } - - return SRSASN_SUCCESS; + j.end_obj(); } -SRSASN_CODE intra_freq_neigh_cell_info_nb_v1530_s::unpack(cbit_ref& bref) +SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::pack(bit_ref& bref) const { - HANDLE_CODE(bref.unpack(nsss_rrm_cfg_r15_present, 1)); - - if (nsss_rrm_cfg_r15_present) { - HANDLE_CODE(nsss_rrm_cfg_r15.unpack(bref)); + type_.pack(bref); + switch (type_) { + case types::use_no_bitmap_r14: + break; + case types::use_anchor_bitmap_r14: + break; + case types::explicit_bitmap_cfg_r14: + HANDLE_CODE(c.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_"); + return SRSASN_ERROR_ENCODE_FAIL; } - return SRSASN_SUCCESS; } -void intra_freq_neigh_cell_info_nb_v1530_s::to_json(json_writer& j) const +SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::unpack(cbit_ref& bref) { - j.start_obj(); - if (nsss_rrm_cfg_r15_present) { - j.write_fieldname("nsss-RRM-Config-r15"); - nsss_rrm_cfg_r15.to_json(j); + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::use_no_bitmap_r14: + break; + case types::use_anchor_bitmap_r14: + break; + case types::explicit_bitmap_cfg_r14: + HANDLE_CODE(c.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_"); + return SRSASN_ERROR_DECODE_FAIL; } - j.end_obj(); + return SRSASN_SUCCESS; } -// MBMS-SAI-InterFreq-NB-r14 ::= SEQUENCE -SRSASN_CODE mbms_sai_inter_freq_nb_r14_s::pack(bit_ref& bref) const +const char* dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::types_opts::to_string() const { - HANDLE_CODE(bref.pack(multi_band_info_list_r14_present, 1)); - - HANDLE_CODE(dl_carrier_freq_r14.pack(bref)); - HANDLE_CODE(pack_dyn_seq_of(bref, mbms_sai_list_r14, 1, 64, integer_packer(0, 65535))); - if (multi_band_info_list_r14_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, multi_band_info_list_r14, 1, 8, integer_packer(1, 256))); - } - - return SRSASN_SUCCESS; + static const char* options[] = {"useNoBitmap-r14", "useAnchorBitmap-r14", "explicitBitmapConfiguration-r14"}; + return convert_enum_idx(options, 3, value, "dl_carrier_cfg_common_nb_r14_s::dl_bitmap_non_anchor_r14_c_::types"); } -SRSASN_CODE mbms_sai_inter_freq_nb_r14_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(bref.unpack(multi_band_info_list_r14_present, 1)); - - HANDLE_CODE(dl_carrier_freq_r14.unpack(bref)); - HANDLE_CODE(unpack_dyn_seq_of(mbms_sai_list_r14, bref, 1, 64, integer_packer(0, 65535))); - if (multi_band_info_list_r14_present) { - HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r14, bref, 1, 8, integer_packer(1, 256))); - } - return SRSASN_SUCCESS; +void dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::set(types::options e) +{ + type_ = e; } -void mbms_sai_inter_freq_nb_r14_s::to_json(json_writer& j) const +void dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::set_use_no_gap_r14() { - j.start_obj(); - j.write_fieldname("dl-CarrierFreq-r14"); - dl_carrier_freq_r14.to_json(j); - j.start_array("mbms-SAI-List-r14"); - for (const auto& e1 : mbms_sai_list_r14) { - j.write_int(e1); - } - j.end_array(); - if (multi_band_info_list_r14_present) { - j.start_array("multiBandInfoList-r14"); - for (const auto& e1 : multi_band_info_list_r14) { - j.write_int(e1); - } - j.end_array(); - } - j.end_obj(); + set(types::use_no_gap_r14); } - -// NPDSCH-ConfigCommon-NB-r13 ::= SEQUENCE -SRSASN_CODE npdsch_cfg_common_nb_r13_s::pack(bit_ref& bref) const +void dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::set_use_anchor_gap_cfg_r14() { - HANDLE_CODE(pack_integer(bref, nrs_pwr_r13, (int8_t)-60, (int8_t)50)); - - return SRSASN_SUCCESS; + set(types::use_anchor_gap_cfg_r14); } -SRSASN_CODE npdsch_cfg_common_nb_r13_s::unpack(cbit_ref& bref) +dl_gap_cfg_nb_r13_s& dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::set_explicit_gap_cfg_r14() { - HANDLE_CODE(unpack_integer(nrs_pwr_r13, bref, (int8_t)-60, (int8_t)50)); - - return SRSASN_SUCCESS; + set(types::explicit_gap_cfg_r14); + return c; } -void npdsch_cfg_common_nb_r13_s::to_json(json_writer& j) const +void dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::to_json(json_writer& j) const { j.start_obj(); - j.write_int("nrs-Power-r13", nrs_pwr_r13); + switch (type_) { + case types::use_no_gap_r14: + break; + case types::use_anchor_gap_cfg_r14: + break; + case types::explicit_gap_cfg_r14: + j.write_fieldname("explicitGapConfiguration-r14"); + c.to_json(j); + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_"); + } j.end_obj(); } - -// NPRACH-ConfigSIB-NB-r13 ::= SEQUENCE -SRSASN_CODE nprach_cfg_sib_nb_r13_s::pack(bit_ref& bref) const +SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(rsrp_thress_prach_info_list_r13_present, 1)); - - HANDLE_CODE(nprach_cp_len_r13.pack(bref)); - if (rsrp_thress_prach_info_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, rsrp_thress_prach_info_list_r13, 1, 2, integer_packer(0, 97))); + type_.pack(bref); + switch (type_) { + case types::use_no_gap_r14: + break; + case types::use_anchor_gap_cfg_r14: + break; + case types::explicit_gap_cfg_r14: + HANDLE_CODE(c.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_"); + return SRSASN_ERROR_ENCODE_FAIL; } - HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_r13, 1, 3)); - return SRSASN_SUCCESS; } -SRSASN_CODE nprach_cfg_sib_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(rsrp_thress_prach_info_list_r13_present, 1)); + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::use_no_gap_r14: + break; + case types::use_anchor_gap_cfg_r14: + break; + case types::explicit_gap_cfg_r14: + HANDLE_CODE(c.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} - HANDLE_CODE(nprach_cp_len_r13.unpack(bref)); - if (rsrp_thress_prach_info_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(rsrp_thress_prach_info_list_r13, bref, 1, 2, integer_packer(0, 97))); - } - HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_r13, bref, 1, 3)); +const char* dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::types_opts::to_string() const +{ + static const char* options[] = {"useNoGap-r14", "useAnchorGapConfig-r14", "explicitGapConfiguration-r14"}; + return convert_enum_idx(options, 3, value, "dl_carrier_cfg_common_nb_r14_s::dl_gap_non_anchor_r14_c_::types"); +} - return SRSASN_SUCCESS; +void dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::destroy_() +{ + switch (type_) { + case types::same_pci_r14: + c.destroy(); + break; + case types::different_pci_r14: + c.destroy(); + break; + default: + break; + } } -void nprach_cfg_sib_nb_r13_s::to_json(json_writer& j) const +void dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::set(types::options e) { - j.start_obj(); - j.write_str("nprach-CP-Length-r13", nprach_cp_len_r13.to_string()); - if (rsrp_thress_prach_info_list_r13_present) { - j.start_array("rsrp-ThresholdsPrachInfoList-r13"); - for (const auto& e1 : rsrp_thress_prach_info_list_r13) { - j.write_int(e1); - } - j.end_array(); + destroy_(); + type_ = e; + switch (type_) { + case types::same_pci_r14: + c.init(); + break; + case types::different_pci_r14: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); } - j.start_array("nprach-ParametersList-r13"); - for (const auto& e1 : nprach_params_list_r13) { - e1.to_json(j); +} +dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::same_pci_ind_r14_c_( + const dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::same_pci_r14: + c.init(other.c.get()); + break; + case types::different_pci_r14: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); } - j.end_array(); - j.end_obj(); } +dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_& +dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::operator=( + const dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::same_pci_r14: + c.set(other.c.get()); + break; + case types::different_pci_r14: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); + } -const char* nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_opts::to_string() const + return *this; +} +dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::same_pci_r14_s_& +dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::set_same_pci_r14() { - static const char* options[] = {"us66dot7", "us266dot7"}; - return convert_enum_idx(options, 2, value, "nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_e_"); + set(types::same_pci_r14); + return c.get(); } -float nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_opts::to_number() const +dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::different_pci_r14_s_& +dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::set_different_pci_r14() { - static const float options[] = {66.7, 266.7}; - return map_enum_number(options, 2, value, "nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_e_"); + set(types::different_pci_r14); + return c.get(); } -const char* nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_opts::to_number_string() const +void dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::to_json(json_writer& j) const { - static const char* options[] = {"66.7", "266.7"}; - return convert_enum_idx(options, 2, value, "nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_e_"); + j.start_obj(); + switch (type_) { + case types::same_pci_r14: + j.write_fieldname("samePCI-r14"); + j.start_obj(); + j.write_int("indexToMidPRB-r14", c.get().idx_to_mid_prb_r14); + j.end_obj(); + break; + case types::different_pci_r14: + j.write_fieldname("differentPCI-r14"); + j.start_obj(); + j.write_str("eutra-NumCRS-Ports-r14", c.get().eutra_num_crs_ports_r14.to_string()); + j.end_obj(); + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); + } + j.end_obj(); } - -// NPRACH-ConfigSIB-NB-v1330 ::= SEQUENCE -SRSASN_CODE nprach_cfg_sib_nb_v1330_s::pack(bit_ref& bref) const +SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::pack(bit_ref& bref) const { - HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_v1330, 1, 3)); - + type_.pack(bref); + switch (type_) { + case types::same_pci_r14: + HANDLE_CODE(pack_integer(bref, c.get().idx_to_mid_prb_r14, (int8_t)-55, (int8_t)54)); + break; + case types::different_pci_r14: + HANDLE_CODE(c.get().eutra_num_crs_ports_r14.pack(bref)); + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } return SRSASN_SUCCESS; } -SRSASN_CODE nprach_cfg_sib_nb_v1330_s::unpack(cbit_ref& bref) +SRSASN_CODE dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_v1330, bref, 1, 3)); - + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::same_pci_r14: + HANDLE_CODE(unpack_integer(c.get().idx_to_mid_prb_r14, bref, (int8_t)-55, (int8_t)54)); + break; + case types::different_pci_r14: + HANDLE_CODE(c.get().eutra_num_crs_ports_r14.unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } return SRSASN_SUCCESS; } -void nprach_cfg_sib_nb_v1330_s::to_json(json_writer& j) const + +const char* dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::different_pci_r14_s_:: + eutra_num_crs_ports_r14_opts::to_string() const { - j.start_obj(); - j.start_array("nprach-ParametersList-v1330"); - for (const auto& e1 : nprach_params_list_v1330) { - e1.to_json(j); + static const char* options[] = {"same", "four"}; + return convert_enum_idx(options, + 2, + value, + "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::different_" + "pci_r14_s_::eutra_num_crs_ports_r14_e_"); +} +uint8_t dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::different_pci_r14_s_:: + eutra_num_crs_ports_r14_opts::to_number() const +{ + if (value == four) { + return 4; } - j.end_array(); - j.end_obj(); + invalid_enum_number(value, + "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::different_pci_" + "r14_s_::eutra_num_crs_ports_r14_e_"); + return 0; } -// NPRACH-ConfigSIB-NB-v1450 ::= SEQUENCE -SRSASN_CODE nprach_cfg_sib_nb_v1450_s::pack(bit_ref& bref) const +const char* +dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::types_opts::to_string() const { - HANDLE_CODE(max_num_preamb_attempt_ce_r14.pack(bref)); - - return SRSASN_SUCCESS; + static const char* options[] = {"samePCI-r14", "differentPCI-r14"}; + return convert_enum_idx( + options, 2, value, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::same_pci_ind_r14_c_::types"); } -SRSASN_CODE nprach_cfg_sib_nb_v1450_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(max_num_preamb_attempt_ce_r14.unpack(bref)); - return SRSASN_SUCCESS; +const char* +dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::eutra_ctrl_region_size_r14_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n3"}; + return convert_enum_idx( + options, 3, value, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::eutra_ctrl_region_size_r14_e_"); } -void nprach_cfg_sib_nb_v1450_s::to_json(json_writer& j) const +uint8_t dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::eutra_ctrl_region_size_r14_opts::to_number() const { - j.start_obj(); - j.write_str("maxNumPreambleAttemptCE-r14", max_num_preamb_attempt_ce_r14.to_string()); - j.end_obj(); + static const uint8_t options[] = {1, 2, 3}; + return map_enum_number( + options, 3, value, "dl_carrier_cfg_common_nb_r14_s::inband_carrier_info_r14_s_::eutra_ctrl_region_size_r14_e_"); } -const char* nprach_cfg_sib_nb_v1450_s::max_num_preamb_attempt_ce_r14_opts::to_string() const +const char* dl_carrier_cfg_common_nb_r14_s::nrs_pwr_offset_non_anchor_r14_opts::to_string() const { - static const char* options[] = {"n3", "n4", "n5", "n6", "n7", "n8", "n10", "spare1"}; - return convert_enum_idx(options, 8, value, "nprach_cfg_sib_nb_v1450_s::max_num_preamb_attempt_ce_r14_e_"); + static const char* options[] = {"dB-12", "dB-10", "dB-8", "dB-6", "dB-4", "dB-2", "dB0", "dB3"}; + return convert_enum_idx(options, 8, value, "dl_carrier_cfg_common_nb_r14_s::nrs_pwr_offset_non_anchor_r14_e_"); } -uint8_t nprach_cfg_sib_nb_v1450_s::max_num_preamb_attempt_ce_r14_opts::to_number() const +int8_t dl_carrier_cfg_common_nb_r14_s::nrs_pwr_offset_non_anchor_r14_opts::to_number() const { - static const uint8_t options[] = {3, 4, 5, 6, 7, 8, 10}; - return map_enum_number(options, 7, value, "nprach_cfg_sib_nb_v1450_s::max_num_preamb_attempt_ce_r14_e_"); + static const int8_t options[] = {-12, -10, -8, -6, -4, -2, 0, 3}; + return map_enum_number(options, 8, value, "dl_carrier_cfg_common_nb_r14_s::nrs_pwr_offset_non_anchor_r14_e_"); } -// NPRACH-ConfigSIB-NB-v1530 ::= SEQUENCE -SRSASN_CODE nprach_cfg_sib_nb_v1530_s::pack(bit_ref& bref) const +// GWUS-ResourceConfig-NB-r16 ::= SEQUENCE +SRSASN_CODE gwus_res_cfg_nb_r16_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(tdd_params_r15_present, 1)); - HANDLE_CODE(bref.pack(fmt2_params_r15_present, 1)); - HANDLE_CODE(bref.pack(edt_params_r15_present, 1)); + HANDLE_CODE(bref.pack(num_groups_list_r16_present, 1)); + HANDLE_CODE(bref.pack(groups_for_service_list_r16_present, 1)); - if (tdd_params_r15_present) { - HANDLE_CODE(tdd_params_r15.nprach_preamb_format_r15.pack(bref)); - HANDLE_CODE(tdd_params_r15.dummy.pack(bref)); - HANDLE_CODE(pack_dyn_seq_of(bref, tdd_params_r15.nprach_params_list_tdd_r15, 1, 3)); - } - if (fmt2_params_r15_present) { - HANDLE_CODE(bref.pack(fmt2_params_r15.nprach_params_list_fmt2_r15_present, 1)); - HANDLE_CODE(bref.pack(fmt2_params_r15.nprach_params_list_fmt2_edt_r15_present, 1)); - if (fmt2_params_r15.nprach_params_list_fmt2_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, fmt2_params_r15.nprach_params_list_fmt2_r15, 1, 3)); - } - if (fmt2_params_r15.nprach_params_list_fmt2_edt_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, fmt2_params_r15.nprach_params_list_fmt2_edt_r15, 1, 3)); - } + HANDLE_CODE(res_position_r16.pack(bref)); + if (num_groups_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, num_groups_list_r16, 1, 2)); } - if (edt_params_r15_present) { - HANDLE_CODE(bref.pack(edt_params_r15.edt_small_tbs_subset_r15_present, 1)); - HANDLE_CODE(bref.pack(edt_params_r15.nprach_params_list_edt_r15_present, 1)); - HANDLE_CODE(pack_dyn_seq_of(bref, edt_params_r15.edt_tbs_info_list_r15, 1, 3)); - if (edt_params_r15.nprach_params_list_edt_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, edt_params_r15.nprach_params_list_edt_r15, 1, 3)); - } + if (groups_for_service_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, groups_for_service_list_r16, 1, 3, integer_packer(1, 15))); } return SRSASN_SUCCESS; } -SRSASN_CODE nprach_cfg_sib_nb_v1530_s::unpack(cbit_ref& bref) +SRSASN_CODE gwus_res_cfg_nb_r16_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(tdd_params_r15_present, 1)); - HANDLE_CODE(bref.unpack(fmt2_params_r15_present, 1)); - HANDLE_CODE(bref.unpack(edt_params_r15_present, 1)); + HANDLE_CODE(bref.unpack(num_groups_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(groups_for_service_list_r16_present, 1)); - if (tdd_params_r15_present) { - HANDLE_CODE(tdd_params_r15.nprach_preamb_format_r15.unpack(bref)); - HANDLE_CODE(tdd_params_r15.dummy.unpack(bref)); - HANDLE_CODE(unpack_dyn_seq_of(tdd_params_r15.nprach_params_list_tdd_r15, bref, 1, 3)); - } - if (fmt2_params_r15_present) { - HANDLE_CODE(bref.unpack(fmt2_params_r15.nprach_params_list_fmt2_r15_present, 1)); - HANDLE_CODE(bref.unpack(fmt2_params_r15.nprach_params_list_fmt2_edt_r15_present, 1)); - if (fmt2_params_r15.nprach_params_list_fmt2_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(fmt2_params_r15.nprach_params_list_fmt2_r15, bref, 1, 3)); - } - if (fmt2_params_r15.nprach_params_list_fmt2_edt_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(fmt2_params_r15.nprach_params_list_fmt2_edt_r15, bref, 1, 3)); - } + HANDLE_CODE(res_position_r16.unpack(bref)); + if (num_groups_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(num_groups_list_r16, bref, 1, 2)); } - if (edt_params_r15_present) { - HANDLE_CODE(bref.unpack(edt_params_r15.edt_small_tbs_subset_r15_present, 1)); - HANDLE_CODE(bref.unpack(edt_params_r15.nprach_params_list_edt_r15_present, 1)); - HANDLE_CODE(unpack_dyn_seq_of(edt_params_r15.edt_tbs_info_list_r15, bref, 1, 3)); - if (edt_params_r15.nprach_params_list_edt_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(edt_params_r15.nprach_params_list_edt_r15, bref, 1, 3)); - } + if (groups_for_service_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(groups_for_service_list_r16, bref, 1, 3, integer_packer(1, 15))); } return SRSASN_SUCCESS; } -void nprach_cfg_sib_nb_v1530_s::to_json(json_writer& j) const +void gwus_res_cfg_nb_r16_s::to_json(json_writer& j) const { j.start_obj(); - if (tdd_params_r15_present) { - j.write_fieldname("tdd-Parameters-r15"); - j.start_obj(); - j.write_str("nprach-PreambleFormat-r15", tdd_params_r15.nprach_preamb_format_r15.to_string()); - j.write_str("dummy", tdd_params_r15.dummy.to_string()); - j.start_array("nprach-ParametersListTDD-r15"); - for (const auto& e1 : tdd_params_r15.nprach_params_list_tdd_r15) { - e1.to_json(j); + j.write_str("resourcePosition-r16", res_position_r16.to_string()); + if (num_groups_list_r16_present) { + j.start_array("numGroupsList-r16"); + for (const auto& e1 : num_groups_list_r16) { + j.write_str(e1.to_string()); } j.end_array(); - j.end_obj(); - } - if (fmt2_params_r15_present) { - j.write_fieldname("fmt2-Parameters-r15"); - j.start_obj(); - if (fmt2_params_r15.nprach_params_list_fmt2_r15_present) { - j.start_array("nprach-ParametersListFmt2-r15"); - for (const auto& e1 : fmt2_params_r15.nprach_params_list_fmt2_r15) { - e1.to_json(j); - } - j.end_array(); - } - if (fmt2_params_r15.nprach_params_list_fmt2_edt_r15_present) { - j.start_array("nprach-ParametersListFmt2EDT-r15"); - for (const auto& e1 : fmt2_params_r15.nprach_params_list_fmt2_edt_r15) { - e1.to_json(j); - } - j.end_array(); - } - j.end_obj(); } - if (edt_params_r15_present) { - j.write_fieldname("edt-Parameters-r15"); - j.start_obj(); - if (edt_params_r15.edt_small_tbs_subset_r15_present) { - j.write_str("edt-SmallTBS-Subset-r15", "true"); - } - j.start_array("edt-TBS-InfoList-r15"); - for (const auto& e1 : edt_params_r15.edt_tbs_info_list_r15) { - e1.to_json(j); + if (groups_for_service_list_r16_present) { + j.start_array("groupsForServiceList-r16"); + for (const auto& e1 : groups_for_service_list_r16) { + j.write_int(e1); } j.end_array(); - if (edt_params_r15.nprach_params_list_edt_r15_present) { - j.start_array("nprach-ParametersListEDT-r15"); - for (const auto& e1 : edt_params_r15.nprach_params_list_edt_r15) { - e1.to_json(j); - } - j.end_array(); - } - j.end_obj(); } j.end_obj(); } -const char* nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::nprach_preamb_format_r15_opts::to_string() const +const char* gwus_res_cfg_nb_r16_s::res_position_r16_opts::to_string() const { - static const char* options[] = {"fmt0", "fmt1", "fmt2", "fmt0-a", "fmt1-a"}; - return convert_enum_idx( - options, 5, value, "nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::nprach_preamb_format_r15_e_"); + static const char* options[] = {"primary", "secondary"}; + return convert_enum_idx(options, 2, value, "gwus_res_cfg_nb_r16_s::res_position_r16_e_"); } -const char* nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::dummy_opts::to_string() const -{ - static const char* options[] = {"n1", "n2", "n4", "n8", "n16", "n32", "n64", "n128", "n256", "n512", "n1024"}; - return convert_enum_idx(options, 11, value, "nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::dummy_e_"); -} -uint16_t nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::dummy_opts::to_number() const +// PCCH-Config-NB-r14 ::= SEQUENCE +SRSASN_CODE pcch_cfg_nb_r14_s::pack(bit_ref& bref) const { - static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}; - return map_enum_number(options, 11, value, "nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::dummy_e_"); -} + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(npdcch_num_repeat_paging_r14_present, 1)); + HANDLE_CODE(bref.pack(paging_weight_r14_present, 1)); -// NPRACH-ConfigSIB-NB-v1550 ::= SEQUENCE -SRSASN_CODE nprach_cfg_sib_nb_v1550_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_dyn_seq_of(bref, tdd_params_v1550.nprach_params_list_tdd_v1550, 1, 3)); + if (npdcch_num_repeat_paging_r14_present) { + HANDLE_CODE(npdcch_num_repeat_paging_r14.pack(bref)); + } + if (paging_weight_r14_present) { + HANDLE_CODE(paging_weight_r14.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE nprach_cfg_sib_nb_v1550_s::unpack(cbit_ref& bref) +SRSASN_CODE pcch_cfg_nb_r14_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_dyn_seq_of(tdd_params_v1550.nprach_params_list_tdd_v1550, bref, 1, 3)); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(npdcch_num_repeat_paging_r14_present, 1)); + HANDLE_CODE(bref.unpack(paging_weight_r14_present, 1)); + + if (npdcch_num_repeat_paging_r14_present) { + HANDLE_CODE(npdcch_num_repeat_paging_r14.unpack(bref)); + } + if (paging_weight_r14_present) { + HANDLE_CODE(paging_weight_r14.unpack(bref)); + } return SRSASN_SUCCESS; } -void nprach_cfg_sib_nb_v1550_s::to_json(json_writer& j) const +void pcch_cfg_nb_r14_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("tdd-Parameters-v1550"); - j.start_obj(); - j.start_array("nprach-ParametersListTDD-v1550"); - for (const auto& e1 : tdd_params_v1550.nprach_params_list_tdd_v1550) { - e1.to_json(j); + if (npdcch_num_repeat_paging_r14_present) { + j.write_str("npdcch-NumRepetitionPaging-r14", npdcch_num_repeat_paging_r14.to_string()); + } + if (paging_weight_r14_present) { + j.write_str("pagingWeight-r14", paging_weight_r14.to_string()); } - j.end_array(); - j.end_obj(); j.end_obj(); } -// NPRACH-ProbabilityAnchor-NB-r14 ::= SEQUENCE -SRSASN_CODE nprach_probability_anchor_nb_r14_s::pack(bit_ref& bref) const +const char* pcch_cfg_nb_r14_s::npdcch_num_repeat_paging_r14_opts::to_string() const { - HANDLE_CODE(bref.pack(nprach_probability_anchor_r14_present, 1)); + static const char* options[] = {"r1", + "r2", + "r4", + "r8", + "r16", + "r32", + "r64", + "r128", + "r256", + "r512", + "r1024", + "r2048", + "spare4", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 16, value, "pcch_cfg_nb_r14_s::npdcch_num_repeat_paging_r14_e_"); +} +uint16_t pcch_cfg_nb_r14_s::npdcch_num_repeat_paging_r14_opts::to_number() const +{ + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; + return map_enum_number(options, 12, value, "pcch_cfg_nb_r14_s::npdcch_num_repeat_paging_r14_e_"); +} - if (nprach_probability_anchor_r14_present) { - HANDLE_CODE(nprach_probability_anchor_r14.pack(bref)); +// PCCH-Config-NB-r17 ::= SEQUENCE +SRSASN_CODE pcch_cfg_nb_r17_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(paging_weight_r17_present, 1)); + + HANDLE_CODE(pack_integer(bref, cbp_idx_r17, (uint8_t)1u, (uint8_t)2u)); + HANDLE_CODE(npdcch_num_repeat_paging_r17.pack(bref)); + if (paging_weight_r17_present) { + HANDLE_CODE(paging_weight_r17.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE nprach_probability_anchor_nb_r14_s::unpack(cbit_ref& bref) +SRSASN_CODE pcch_cfg_nb_r17_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(nprach_probability_anchor_r14_present, 1)); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(paging_weight_r17_present, 1)); - if (nprach_probability_anchor_r14_present) { - HANDLE_CODE(nprach_probability_anchor_r14.unpack(bref)); + HANDLE_CODE(unpack_integer(cbp_idx_r17, bref, (uint8_t)1u, (uint8_t)2u)); + HANDLE_CODE(npdcch_num_repeat_paging_r17.unpack(bref)); + if (paging_weight_r17_present) { + HANDLE_CODE(paging_weight_r17.unpack(bref)); } return SRSASN_SUCCESS; } -void nprach_probability_anchor_nb_r14_s::to_json(json_writer& j) const +void pcch_cfg_nb_r17_s::to_json(json_writer& j) const { j.start_obj(); - if (nprach_probability_anchor_r14_present) { - j.write_str("nprach-ProbabilityAnchor-r14", nprach_probability_anchor_r14.to_string()); + j.write_int("cbp-Index-r17", cbp_idx_r17); + j.write_str("npdcch-NumRepetitionPaging-r17", npdcch_num_repeat_paging_r17.to_string()); + if (paging_weight_r17_present) { + j.write_str("pagingWeight-r17", paging_weight_r17.to_string()); } j.end_obj(); } -const char* nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_opts::to_string() const -{ - static const char* options[] = {"zero", - "oneSixteenth", - "oneFifteenth", - "oneFourteenth", - "oneThirteenth", - "oneTwelfth", - "oneEleventh", - "oneTenth", - "oneNinth", - "oneEighth", - "oneSeventh", - "oneSixth", - "oneFifth", - "oneFourth", - "oneThird", - "oneHalf"}; - return convert_enum_idx(options, 16, value, "nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_e_"); -} -float nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_opts::to_number() const +const char* pcch_cfg_nb_r17_s::npdcch_num_repeat_paging_r17_opts::to_string() const { - static const float options[] = {0.0, - 0.0625, - 0.06666666666666667, - 0.07142857142857142, - 0.07692307692307693, - 0.08333333333333333, - 0.09090909090909091, - 0.1, - 0.1111111111111111, - 0.125, - 0.14285714285714285, - 0.16666666666666666, - 0.2, - 0.25, - 0.3333333333333333, - 0.5}; - return map_enum_number(options, 16, value, "nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_e_"); + static const char* options[] = {"r1", "r2", "r4", "r8", "r16", "r32", "r64", "r128"}; + return convert_enum_idx(options, 8, value, "pcch_cfg_nb_r17_s::npdcch_num_repeat_paging_r17_e_"); } -const char* nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_opts::to_number_string() const +uint8_t pcch_cfg_nb_r17_s::npdcch_num_repeat_paging_r17_opts::to_number() const { - static const char* options[] = {"0", - "1/16", - "1/15", - "1/14", - "1/13", - "1/12", - "1/11", - "1/10", - "1/9", - "1/8", - "1/7", - "1/6", - "1/5", - "1/4", - "1/3", - "1/2"}; - return convert_enum_idx(options, 16, value, "nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_e_"); + static const uint8_t options[] = {1, 2, 4, 8, 16, 32, 64, 128}; + return map_enum_number(options, 8, value, "pcch_cfg_nb_r17_s::npdcch_num_repeat_paging_r17_e_"); } -// NPUSCH-ConfigCommon-NB-r13 ::= SEQUENCE -SRSASN_CODE npusch_cfg_common_nb_r13_s::pack(bit_ref& bref) const +// PowerRampingParameters-NB-v1450 ::= SEQUENCE +SRSASN_CODE pwr_ramp_params_nb_v1450_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(srs_sf_cfg_r13_present, 1)); - HANDLE_CODE(bref.pack(dmrs_cfg_r13_present, 1)); + HANDLE_CODE(bref.pack(preamb_init_rx_target_pwr_v1450_present, 1)); + HANDLE_CODE(bref.pack(pwr_ramp_params_ce1_r14_present, 1)); - HANDLE_CODE(pack_dyn_seq_of(bref, ack_nack_num_repeats_msg4_r13, 1, 3)); - if (srs_sf_cfg_r13_present) { - HANDLE_CODE(srs_sf_cfg_r13.pack(bref)); + if (preamb_init_rx_target_pwr_v1450_present) { + HANDLE_CODE(preamb_init_rx_target_pwr_v1450.pack(bref)); } - if (dmrs_cfg_r13_present) { - HANDLE_CODE(bref.pack(dmrs_cfg_r13.three_tone_base_seq_r13_present, 1)); - HANDLE_CODE(bref.pack(dmrs_cfg_r13.six_tone_base_seq_r13_present, 1)); - HANDLE_CODE(bref.pack(dmrs_cfg_r13.twelve_tone_base_seq_r13_present, 1)); - if (dmrs_cfg_r13.three_tone_base_seq_r13_present) { - HANDLE_CODE(pack_integer(bref, dmrs_cfg_r13.three_tone_base_seq_r13, (uint8_t)0u, (uint8_t)12u)); - } - HANDLE_CODE(pack_integer(bref, dmrs_cfg_r13.three_tone_cyclic_shift_r13, (uint8_t)0u, (uint8_t)2u)); - if (dmrs_cfg_r13.six_tone_base_seq_r13_present) { - HANDLE_CODE(pack_integer(bref, dmrs_cfg_r13.six_tone_base_seq_r13, (uint8_t)0u, (uint8_t)14u)); - } - HANDLE_CODE(pack_integer(bref, dmrs_cfg_r13.six_tone_cyclic_shift_r13, (uint8_t)0u, (uint8_t)3u)); - if (dmrs_cfg_r13.twelve_tone_base_seq_r13_present) { - HANDLE_CODE(pack_integer(bref, dmrs_cfg_r13.twelve_tone_base_seq_r13, (uint8_t)0u, (uint8_t)30u)); - } + if (pwr_ramp_params_ce1_r14_present) { + HANDLE_CODE(pwr_ramp_params_ce1_r14.pwr_ramp_step_ce1_r14.pack(bref)); + HANDLE_CODE(pwr_ramp_params_ce1_r14.preamb_init_rx_target_pwr_ce1_r14.pack(bref)); } - HANDLE_CODE(ul_ref_sigs_npusch_r13.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE npusch_cfg_common_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE pwr_ramp_params_nb_v1450_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(srs_sf_cfg_r13_present, 1)); - HANDLE_CODE(bref.unpack(dmrs_cfg_r13_present, 1)); + HANDLE_CODE(bref.unpack(preamb_init_rx_target_pwr_v1450_present, 1)); + HANDLE_CODE(bref.unpack(pwr_ramp_params_ce1_r14_present, 1)); - HANDLE_CODE(unpack_dyn_seq_of(ack_nack_num_repeats_msg4_r13, bref, 1, 3)); - if (srs_sf_cfg_r13_present) { - HANDLE_CODE(srs_sf_cfg_r13.unpack(bref)); + if (preamb_init_rx_target_pwr_v1450_present) { + HANDLE_CODE(preamb_init_rx_target_pwr_v1450.unpack(bref)); } - if (dmrs_cfg_r13_present) { - HANDLE_CODE(bref.unpack(dmrs_cfg_r13.three_tone_base_seq_r13_present, 1)); - HANDLE_CODE(bref.unpack(dmrs_cfg_r13.six_tone_base_seq_r13_present, 1)); - HANDLE_CODE(bref.unpack(dmrs_cfg_r13.twelve_tone_base_seq_r13_present, 1)); - if (dmrs_cfg_r13.three_tone_base_seq_r13_present) { - HANDLE_CODE(unpack_integer(dmrs_cfg_r13.three_tone_base_seq_r13, bref, (uint8_t)0u, (uint8_t)12u)); - } - HANDLE_CODE(unpack_integer(dmrs_cfg_r13.three_tone_cyclic_shift_r13, bref, (uint8_t)0u, (uint8_t)2u)); - if (dmrs_cfg_r13.six_tone_base_seq_r13_present) { - HANDLE_CODE(unpack_integer(dmrs_cfg_r13.six_tone_base_seq_r13, bref, (uint8_t)0u, (uint8_t)14u)); - } - HANDLE_CODE(unpack_integer(dmrs_cfg_r13.six_tone_cyclic_shift_r13, bref, (uint8_t)0u, (uint8_t)3u)); - if (dmrs_cfg_r13.twelve_tone_base_seq_r13_present) { - HANDLE_CODE(unpack_integer(dmrs_cfg_r13.twelve_tone_base_seq_r13, bref, (uint8_t)0u, (uint8_t)30u)); - } + if (pwr_ramp_params_ce1_r14_present) { + HANDLE_CODE(pwr_ramp_params_ce1_r14.pwr_ramp_step_ce1_r14.unpack(bref)); + HANDLE_CODE(pwr_ramp_params_ce1_r14.preamb_init_rx_target_pwr_ce1_r14.unpack(bref)); } - HANDLE_CODE(ul_ref_sigs_npusch_r13.unpack(bref)); return SRSASN_SUCCESS; } -void npusch_cfg_common_nb_r13_s::to_json(json_writer& j) const +void pwr_ramp_params_nb_v1450_s::to_json(json_writer& j) const { j.start_obj(); - j.start_array("ack-NACK-NumRepetitions-Msg4-r13"); - for (const auto& e1 : ack_nack_num_repeats_msg4_r13) { - j.write_str(e1.to_string()); - } - j.end_array(); - if (srs_sf_cfg_r13_present) { - j.write_str("srs-SubframeConfig-r13", srs_sf_cfg_r13.to_string()); + if (preamb_init_rx_target_pwr_v1450_present) { + j.write_str("preambleInitialReceivedTargetPower-v1450", preamb_init_rx_target_pwr_v1450.to_string()); } - if (dmrs_cfg_r13_present) { - j.write_fieldname("dmrs-Config-r13"); + if (pwr_ramp_params_ce1_r14_present) { + j.write_fieldname("powerRampingParametersCE1-r14"); j.start_obj(); - if (dmrs_cfg_r13.three_tone_base_seq_r13_present) { - j.write_int("threeTone-BaseSequence-r13", dmrs_cfg_r13.three_tone_base_seq_r13); - } - j.write_int("threeTone-CyclicShift-r13", dmrs_cfg_r13.three_tone_cyclic_shift_r13); - if (dmrs_cfg_r13.six_tone_base_seq_r13_present) { - j.write_int("sixTone-BaseSequence-r13", dmrs_cfg_r13.six_tone_base_seq_r13); - } - j.write_int("sixTone-CyclicShift-r13", dmrs_cfg_r13.six_tone_cyclic_shift_r13); - if (dmrs_cfg_r13.twelve_tone_base_seq_r13_present) { - j.write_int("twelveTone-BaseSequence-r13", dmrs_cfg_r13.twelve_tone_base_seq_r13); - } + j.write_str("powerRampingStepCE1-r14", pwr_ramp_params_ce1_r14.pwr_ramp_step_ce1_r14.to_string()); + j.write_str("preambleInitialReceivedTargetPowerCE1-r14", + pwr_ramp_params_ce1_r14.preamb_init_rx_target_pwr_ce1_r14.to_string()); j.end_obj(); } - j.write_fieldname("ul-ReferenceSignalsNPUSCH-r13"); - ul_ref_sigs_npusch_r13.to_json(j); j.end_obj(); } -const char* npusch_cfg_common_nb_r13_s::srs_sf_cfg_r13_opts::to_string() const +const char* pwr_ramp_params_nb_v1450_s::preamb_init_rx_target_pwr_v1450_opts::to_string() const { - static const char* options[] = {"sc0", - "sc1", - "sc2", - "sc3", - "sc4", - "sc5", - "sc6", - "sc7", - "sc8", - "sc9", - "sc10", - "sc11", - "sc12", - "sc13", - "sc14", - "sc15"}; - return convert_enum_idx(options, 16, value, "npusch_cfg_common_nb_r13_s::srs_sf_cfg_r13_e_"); + static const char* options[] = { + "dBm-130", "dBm-128", "dBm-126", "dBm-124", "dBm-122", "dBm-88", "dBm-86", "dBm-84", "dBm-82", "dBm-80"}; + return convert_enum_idx(options, 10, value, "pwr_ramp_params_nb_v1450_s::preamb_init_rx_target_pwr_v1450_e_"); } -uint8_t npusch_cfg_common_nb_r13_s::srs_sf_cfg_r13_opts::to_number() const +int16_t pwr_ramp_params_nb_v1450_s::preamb_init_rx_target_pwr_v1450_opts::to_number() const { - static const uint8_t options[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - return map_enum_number(options, 16, value, "npusch_cfg_common_nb_r13_s::srs_sf_cfg_r13_e_"); + static const int16_t options[] = {-130, -128, -126, -124, -122, -88, -86, -84, -82, -80}; + return map_enum_number(options, 10, value, "pwr_ramp_params_nb_v1450_s::preamb_init_rx_target_pwr_v1450_e_"); } -// PCCH-Config-NB-r13 ::= SEQUENCE -SRSASN_CODE pcch_cfg_nb_r13_s::pack(bit_ref& bref) const +const char* pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::pwr_ramp_step_ce1_r14_opts::to_string() const { - HANDLE_CODE(default_paging_cycle_r13.pack(bref)); - HANDLE_CODE(nb_r13.pack(bref)); - HANDLE_CODE(npdcch_num_repeat_paging_r13.pack(bref)); + static const char* options[] = {"dB0", "dB2", "dB4", "dB6"}; + return convert_enum_idx( + options, 4, value, "pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::pwr_ramp_step_ce1_r14_e_"); +} +uint8_t pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::pwr_ramp_step_ce1_r14_opts::to_number() const +{ + static const uint8_t options[] = {0, 2, 4, 6}; + return map_enum_number( + options, 4, value, "pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::pwr_ramp_step_ce1_r14_e_"); +} + +const char* +pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::preamb_init_rx_target_pwr_ce1_r14_opts::to_string() const +{ + static const char* options[] = {"dBm-130", "dBm-128", "dBm-126", "dBm-124", "dBm-122", "dBm-120", "dBm-118", + "dBm-116", "dBm-114", "dBm-112", "dBm-110", "dBm-108", "dBm-106", "dBm-104", + "dBm-102", "dBm-100", "dBm-98", "dBm-96", "dBm-94", "dBm-92", "dBm-90", + "dBm-88", "dBm-86", "dBm-84", "dBm-82", "dBm-80"}; + return convert_enum_idx( + options, + 26, + value, + "pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::preamb_init_rx_target_pwr_ce1_r14_e_"); +} +int16_t +pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::preamb_init_rx_target_pwr_ce1_r14_opts::to_number() const +{ + static const int16_t options[] = {-130, -128, -126, -124, -122, -120, -118, -116, -114, -112, -110, -108, -106, + -104, -102, -100, -98, -96, -94, -92, -90, -88, -86, -84, -82, -80}; + return map_enum_number( + options, + 26, + value, + "pwr_ramp_params_nb_v1450_s::pwr_ramp_params_ce1_r14_s_::preamb_init_rx_target_pwr_ce1_r14_e_"); +} + +// SystemInformationBlockType1-NB-v1610 ::= SEQUENCE +SRSASN_CODE sib_type1_nb_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(cell_access_related_info_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (cell_access_related_info_minus5_gc_r16_present) { + HANDLE_CODE(bref.pack(cell_access_related_info_minus5_gc_r16.cell_id_r16_present, 1)); + HANDLE_CODE(pack_dyn_seq_of(bref, cell_access_related_info_minus5_gc_r16.plmn_id_list_r16, 1, 6)); + HANDLE_CODE(cell_access_related_info_minus5_gc_r16.tac_minus5_gc_r16.pack(bref)); + if (cell_access_related_info_minus5_gc_r16.cell_id_r16_present) { + HANDLE_CODE(cell_access_related_info_minus5_gc_r16.cell_id_r16.pack(bref)); + } + HANDLE_CODE(cell_access_related_info_minus5_gc_r16.cell_barred_minus5_gc_r16.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE pcch_cfg_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE sib_type1_nb_v1610_s::unpack(cbit_ref& bref) { - HANDLE_CODE(default_paging_cycle_r13.unpack(bref)); - HANDLE_CODE(nb_r13.unpack(bref)); - HANDLE_CODE(npdcch_num_repeat_paging_r13.unpack(bref)); + HANDLE_CODE(bref.unpack(cell_access_related_info_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (cell_access_related_info_minus5_gc_r16_present) { + HANDLE_CODE(bref.unpack(cell_access_related_info_minus5_gc_r16.cell_id_r16_present, 1)); + HANDLE_CODE(unpack_dyn_seq_of(cell_access_related_info_minus5_gc_r16.plmn_id_list_r16, bref, 1, 6)); + HANDLE_CODE(cell_access_related_info_minus5_gc_r16.tac_minus5_gc_r16.unpack(bref)); + if (cell_access_related_info_minus5_gc_r16.cell_id_r16_present) { + HANDLE_CODE(cell_access_related_info_minus5_gc_r16.cell_id_r16.unpack(bref)); + } + HANDLE_CODE(cell_access_related_info_minus5_gc_r16.cell_barred_minus5_gc_r16.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } -void pcch_cfg_nb_r13_s::to_json(json_writer& j) const +void sib_type1_nb_v1610_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("defaultPagingCycle-r13", default_paging_cycle_r13.to_string()); - j.write_str("nB-r13", nb_r13.to_string()); - j.write_str("npdcch-NumRepetitionPaging-r13", npdcch_num_repeat_paging_r13.to_string()); + if (cell_access_related_info_minus5_gc_r16_present) { + j.write_fieldname("cellAccessRelatedInfo-5GC-r16"); + j.start_obj(); + j.start_array("plmn-IdentityList-r16"); + for (const auto& e1 : cell_access_related_info_minus5_gc_r16.plmn_id_list_r16) { + e1.to_json(j); + } + j.end_array(); + j.write_str("trackingAreaCode-5GC-r16", cell_access_related_info_minus5_gc_r16.tac_minus5_gc_r16.to_string()); + if (cell_access_related_info_minus5_gc_r16.cell_id_r16_present) { + j.write_str("cellIdentity-r16", cell_access_related_info_minus5_gc_r16.cell_id_r16.to_string()); + } + j.write_str("cellBarred-5GC-r16", cell_access_related_info_minus5_gc_r16.cell_barred_minus5_gc_r16.to_string()); + j.end_obj(); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } j.end_obj(); } -const char* pcch_cfg_nb_r13_s::default_paging_cycle_r13_opts::to_string() const -{ - static const char* options[] = {"rf128", "rf256", "rf512", "rf1024"}; - return convert_enum_idx(options, 4, value, "pcch_cfg_nb_r13_s::default_paging_cycle_r13_e_"); -} -uint16_t pcch_cfg_nb_r13_s::default_paging_cycle_r13_opts::to_number() const +const char* +sib_type1_nb_v1610_s::cell_access_related_info_minus5_gc_r16_s_::cell_barred_minus5_gc_r16_opts::to_string() const { - static const uint16_t options[] = {128, 256, 512, 1024}; - return map_enum_number(options, 4, value, "pcch_cfg_nb_r13_s::default_paging_cycle_r13_e_"); + static const char* options[] = {"barred", "notBarred"}; + return convert_enum_idx( + options, + 2, + value, + "sib_type1_nb_v1610_s::cell_access_related_info_minus5_gc_r16_s_::cell_barred_minus5_gc_r16_e_"); } -const char* pcch_cfg_nb_r13_s::nb_r13_opts::to_string() const +// TDD-Config-NB-r15 ::= SEQUENCE +SRSASN_CODE tdd_cfg_nb_r15_s::pack(bit_ref& bref) const { - static const char* options[] = {"fourT", - "twoT", - "oneT", - "halfT", - "quarterT", - "one8thT", - "one16thT", - "one32ndT", - "one64thT", - "one128thT", - "one256thT", - "one512thT", - "one1024thT", - "spare3", - "spare2", - "spare1"}; - return convert_enum_idx(options, 16, value, "pcch_cfg_nb_r13_s::nb_r13_e_"); + HANDLE_CODE(sf_assign_r15.pack(bref)); + HANDLE_CODE(special_sf_patterns_r15.pack(bref)); + + return SRSASN_SUCCESS; } -float pcch_cfg_nb_r13_s::nb_r13_opts::to_number() const +SRSASN_CODE tdd_cfg_nb_r15_s::unpack(cbit_ref& bref) { - static const float options[] = {4.0, 2.0, 1.0, 0.5, 0.25, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0}; - return map_enum_number(options, 13, value, "pcch_cfg_nb_r13_s::nb_r13_e_"); + HANDLE_CODE(sf_assign_r15.unpack(bref)); + HANDLE_CODE(special_sf_patterns_r15.unpack(bref)); + + return SRSASN_SUCCESS; } -const char* pcch_cfg_nb_r13_s::nb_r13_opts::to_number_string() const +void tdd_cfg_nb_r15_s::to_json(json_writer& j) const { - static const char* options[] = {"4", "2", "1", "0.5", "0.25", "8", "16", "32", "64", "128", "256", "512", "1024"}; - return convert_enum_idx(options, 16, value, "pcch_cfg_nb_r13_s::nb_r13_e_"); + j.start_obj(); + j.write_str("subframeAssignment-r15", sf_assign_r15.to_string()); + j.write_str("specialSubframePatterns-r15", special_sf_patterns_r15.to_string()); + j.end_obj(); } -const char* pcch_cfg_nb_r13_s::npdcch_num_repeat_paging_r13_opts::to_string() const +const char* tdd_cfg_nb_r15_s::sf_assign_r15_opts::to_string() const { - static const char* options[] = {"r1", - "r2", - "r4", - "r8", - "r16", - "r32", - "r64", - "r128", - "r256", - "r512", - "r1024", - "r2048", - "spare4", - "spare3", - "spare2", - "spare1"}; - return convert_enum_idx(options, 16, value, "pcch_cfg_nb_r13_s::npdcch_num_repeat_paging_r13_e_"); + static const char* options[] = {"sa1", "sa2", "sa3", "sa4", "sa5"}; + return convert_enum_idx(options, 5, value, "tdd_cfg_nb_r15_s::sf_assign_r15_e_"); } -uint16_t pcch_cfg_nb_r13_s::npdcch_num_repeat_paging_r13_opts::to_number() const +uint8_t tdd_cfg_nb_r15_s::sf_assign_r15_opts::to_number() const { - static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; - return map_enum_number(options, 12, value, "pcch_cfg_nb_r13_s::npdcch_num_repeat_paging_r13_e_"); + static const uint8_t options[] = {1, 2, 3, 4, 5}; + return map_enum_number(options, 5, value, "tdd_cfg_nb_r15_s::sf_assign_r15_e_"); } -// RACH-ConfigCommon-NB-r13 ::= SEQUENCE -SRSASN_CODE rach_cfg_common_nb_r13_s::pack(bit_ref& bref) const +const char* tdd_cfg_nb_r15_s::special_sf_patterns_r15_opts::to_string() const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(conn_est_fail_offset_r13_present, 1)); + static const char* options[] = { + "ssp0", "ssp1", "ssp2", "ssp3", "ssp4", "ssp5", "ssp6", "ssp7", "ssp8", "ssp9", "ssp10", "ssp10-CRS-LessDwPTS"}; + return convert_enum_idx(options, 12, value, "tdd_cfg_nb_r15_s::special_sf_patterns_r15_e_"); +} - HANDLE_CODE(preamb_trans_max_ce_r13.pack(bref)); - HANDLE_CODE(pwr_ramp_params_r13.pack(bref)); - HANDLE_CODE(pack_dyn_seq_of(bref, rach_info_list_r13, 1, 3)); - if (conn_est_fail_offset_r13_present) { - HANDLE_CODE(pack_integer(bref, conn_est_fail_offset_r13, (uint8_t)0u, (uint8_t)15u)); - } - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= pwr_ramp_params_v1450.is_present(); - group_flags[1] |= rach_info_list_v1530.is_present(); - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(pwr_ramp_params_v1450.is_present(), 1)); - if (pwr_ramp_params_v1450.is_present()) { - HANDLE_CODE(pwr_ramp_params_v1450->pack(bref)); - } - } - if (group_flags[1]) { - varlength_field_pack_guard varlen_scope(bref, false); +// UL-ReferenceSignalsNPUSCH-NB-r13 ::= SEQUENCE +SRSASN_CODE ul_ref_sigs_npusch_nb_r13_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(group_hop_enabled_r13, 1)); + HANDLE_CODE(pack_integer(bref, group_assign_npusch_r13, (uint8_t)0u, (uint8_t)29u)); - HANDLE_CODE(bref.pack(rach_info_list_v1530.is_present(), 1)); - if (rach_info_list_v1530.is_present()) { - HANDLE_CODE(pack_dyn_seq_of(bref, *rach_info_list_v1530, 1, 3)); - } - } - } return SRSASN_SUCCESS; } -SRSASN_CODE rach_cfg_common_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE ul_ref_sigs_npusch_nb_r13_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(conn_est_fail_offset_r13_present, 1)); - - HANDLE_CODE(preamb_trans_max_ce_r13.unpack(bref)); - HANDLE_CODE(pwr_ramp_params_r13.unpack(bref)); - HANDLE_CODE(unpack_dyn_seq_of(rach_info_list_r13, bref, 1, 3)); - if (conn_est_fail_offset_r13_present) { - HANDLE_CODE(unpack_integer(conn_est_fail_offset_r13, bref, (uint8_t)0u, (uint8_t)15u)); - } - - if (ext) { - ext_groups_unpacker_guard group_flags(2); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool pwr_ramp_params_v1450_present; - HANDLE_CODE(bref.unpack(pwr_ramp_params_v1450_present, 1)); - pwr_ramp_params_v1450.set_present(pwr_ramp_params_v1450_present); - if (pwr_ramp_params_v1450.is_present()) { - HANDLE_CODE(pwr_ramp_params_v1450->unpack(bref)); - } - } - if (group_flags[1]) { - varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(bref.unpack(group_hop_enabled_r13, 1)); + HANDLE_CODE(unpack_integer(group_assign_npusch_r13, bref, (uint8_t)0u, (uint8_t)29u)); - bool rach_info_list_v1530_present; - HANDLE_CODE(bref.unpack(rach_info_list_v1530_present, 1)); - rach_info_list_v1530.set_present(rach_info_list_v1530_present); - if (rach_info_list_v1530.is_present()) { - HANDLE_CODE(unpack_dyn_seq_of(*rach_info_list_v1530, bref, 1, 3)); - } - } - } return SRSASN_SUCCESS; } -void rach_cfg_common_nb_r13_s::to_json(json_writer& j) const +void ul_ref_sigs_npusch_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("preambleTransMax-CE-r13", preamb_trans_max_ce_r13.to_string()); - j.write_fieldname("powerRampingParameters-r13"); - pwr_ramp_params_r13.to_json(j); - j.start_array("rach-InfoList-r13"); - for (const auto& e1 : rach_info_list_r13) { - e1.to_json(j); - } - j.end_array(); - if (conn_est_fail_offset_r13_present) { - j.write_int("connEstFailOffset-r13", conn_est_fail_offset_r13); - } - if (ext) { - if (pwr_ramp_params_v1450.is_present()) { - j.write_fieldname("powerRampingParameters-v1450"); - pwr_ramp_params_v1450->to_json(j); - } - if (rach_info_list_v1530.is_present()) { - j.start_array("rach-InfoList-v1530"); - for (const auto& e1 : *rach_info_list_v1530) { - e1.to_json(j); - } - j.end_array(); - } - } + j.write_bool("groupHoppingEnabled-r13", group_hop_enabled_r13); + j.write_int("groupAssignmentNPUSCH-r13", group_assign_npusch_r13); j.end_obj(); } -// SIB-Type-NB-r13 ::= ENUMERATED -const char* sib_type_nb_r13_opts::to_string() const -{ - static const char* options[] = {"sibType3-NB-r13", - "sibType4-NB-r13", - "sibType5-NB-r13", - "sibType14-NB-r13", - "sibType16-NB-r13", - "sibType15-NB-r14", - "sibType20-NB-r14", - "sibType22-NB-r14"}; - return convert_enum_idx(options, 8, value, "sib_type_nb_r13_e"); -} -uint8_t sib_type_nb_r13_opts::to_number() const -{ - static const uint8_t options[] = {3, 4, 5, 14, 16, 15, 20, 22}; - return map_enum_number(options, 8, value, "sib_type_nb_r13_e"); -} - -// SystemInformationBlockType1-NB-v1530 ::= SEQUENCE -SRSASN_CODE sib_type1_nb_v1530_s::pack(bit_ref& bref) const +// WUS-Config-NB-r15 ::= SEQUENCE +SRSASN_CODE wus_cfg_nb_r15_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(tdd_params_r15_present, 1)); - HANDLE_CODE(bref.pack(sched_info_list_v1530_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(num_pos_r15_present, 1)); + HANDLE_CODE(bref.pack(time_offset_e_drx_long_r15_present, 1)); - if (tdd_params_r15_present) { - HANDLE_CODE(bref.pack(tdd_params_r15.tdd_si_sfs_bitmap_r15_present, 1)); - HANDLE_CODE(tdd_params_r15.tdd_cfg_r15.pack(bref)); - HANDLE_CODE(tdd_params_r15.tdd_si_carrier_info_r15.pack(bref)); - if (tdd_params_r15.tdd_si_sfs_bitmap_r15_present) { - HANDLE_CODE(tdd_params_r15.tdd_si_sfs_bitmap_r15.pack(bref)); - } + HANDLE_CODE(max_dur_factor_r15.pack(bref)); + if (num_pos_r15_present) { + HANDLE_CODE(num_pos_r15.pack(bref)); } - if (sched_info_list_v1530_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, sched_info_list_v1530, 1, 8)); + HANDLE_CODE(num_drx_cycles_relaxed_r15.pack(bref)); + HANDLE_CODE(time_offset_drx_r15.pack(bref)); + HANDLE_CODE(time_offset_e_drx_short_r15.pack(bref)); + if (time_offset_e_drx_long_r15_present) { + HANDLE_CODE(time_offset_e_drx_long_r15.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE sib_type1_nb_v1530_s::unpack(cbit_ref& bref) +SRSASN_CODE wus_cfg_nb_r15_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(tdd_params_r15_present, 1)); - HANDLE_CODE(bref.unpack(sched_info_list_v1530_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(num_pos_r15_present, 1)); + HANDLE_CODE(bref.unpack(time_offset_e_drx_long_r15_present, 1)); - if (tdd_params_r15_present) { - HANDLE_CODE(bref.unpack(tdd_params_r15.tdd_si_sfs_bitmap_r15_present, 1)); - HANDLE_CODE(tdd_params_r15.tdd_cfg_r15.unpack(bref)); - HANDLE_CODE(tdd_params_r15.tdd_si_carrier_info_r15.unpack(bref)); - if (tdd_params_r15.tdd_si_sfs_bitmap_r15_present) { - HANDLE_CODE(tdd_params_r15.tdd_si_sfs_bitmap_r15.unpack(bref)); - } + HANDLE_CODE(max_dur_factor_r15.unpack(bref)); + if (num_pos_r15_present) { + HANDLE_CODE(num_pos_r15.unpack(bref)); } - if (sched_info_list_v1530_present) { - HANDLE_CODE(unpack_dyn_seq_of(sched_info_list_v1530, bref, 1, 8)); + HANDLE_CODE(num_drx_cycles_relaxed_r15.unpack(bref)); + HANDLE_CODE(time_offset_drx_r15.unpack(bref)); + HANDLE_CODE(time_offset_e_drx_short_r15.unpack(bref)); + if (time_offset_e_drx_long_r15_present) { + HANDLE_CODE(time_offset_e_drx_long_r15.unpack(bref)); } return SRSASN_SUCCESS; } -void sib_type1_nb_v1530_s::to_json(json_writer& j) const +void wus_cfg_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - if (tdd_params_r15_present) { - j.write_fieldname("tdd-Parameters-r15"); - j.start_obj(); - j.write_fieldname("tdd-Config-r15"); - tdd_params_r15.tdd_cfg_r15.to_json(j); - j.write_str("tdd-SI-CarrierInfo-r15", tdd_params_r15.tdd_si_carrier_info_r15.to_string()); - if (tdd_params_r15.tdd_si_sfs_bitmap_r15_present) { - j.write_fieldname("tdd-SI-SubframesBitmap-r15"); - tdd_params_r15.tdd_si_sfs_bitmap_r15.to_json(j); - } - j.end_obj(); - } - if (sched_info_list_v1530_present) { - j.start_array("schedulingInfoList-v1530"); - for (const auto& e1 : sched_info_list_v1530) { - e1.to_json(j); - } - j.end_array(); + j.write_str("maxDurationFactor-r15", max_dur_factor_r15.to_string()); + if (num_pos_r15_present) { + j.write_str("numPOs-r15", num_pos_r15.to_string()); } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + j.write_str("numDRX-CyclesRelaxed-r15", num_drx_cycles_relaxed_r15.to_string()); + j.write_str("timeOffsetDRX-r15", time_offset_drx_r15.to_string()); + j.write_str("timeOffset-eDRX-Short-r15", time_offset_e_drx_short_r15.to_string()); + if (time_offset_e_drx_long_r15_present) { + j.write_str("timeOffset-eDRX-Long-r15", time_offset_e_drx_long_r15.to_string()); } j.end_obj(); } -const char* sib_type1_nb_v1530_s::tdd_params_r15_s_::tdd_si_carrier_info_r15_opts::to_string() const +const char* wus_cfg_nb_r15_s::num_pos_r15_opts::to_string() const { - static const char* options[] = {"anchor", "non-anchor"}; - return convert_enum_idx(options, 2, value, "sib_type1_nb_v1530_s::tdd_params_r15_s_::tdd_si_carrier_info_r15_e_"); + static const char* options[] = {"n1", "n2", "n4"}; + return convert_enum_idx(options, 3, value, "wus_cfg_nb_r15_s::num_pos_r15_e_"); } - -// UL-ConfigCommon-NB-r14 ::= SEQUENCE -SRSASN_CODE ul_cfg_common_nb_r14_s::pack(bit_ref& bref) const +uint8_t wus_cfg_nb_r15_s::num_pos_r15_opts::to_number() const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(nprach_params_list_r14_present, 1)); - - HANDLE_CODE(ul_carrier_freq_r14.pack(bref)); - if (nprach_params_list_r14_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_r14, 1, 3)); - } - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= nprach_params_list_edt_r15.is_present(); - group_flags.pack(bref); + static const uint8_t options[] = {1, 2, 4}; + return map_enum_number(options, 3, value, "wus_cfg_nb_r15_s::num_pos_r15_e_"); +} - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); +const char* wus_cfg_nb_r15_s::num_drx_cycles_relaxed_r15_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n4", "n8"}; + return convert_enum_idx(options, 4, value, "wus_cfg_nb_r15_s::num_drx_cycles_relaxed_r15_e_"); +} +uint8_t wus_cfg_nb_r15_s::num_drx_cycles_relaxed_r15_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 4, 8}; + return map_enum_number(options, 4, value, "wus_cfg_nb_r15_s::num_drx_cycles_relaxed_r15_e_"); +} - HANDLE_CODE(bref.pack(nprach_params_list_edt_r15.is_present(), 1)); - if (nprach_params_list_edt_r15.is_present()) { - HANDLE_CODE(pack_dyn_seq_of(bref, *nprach_params_list_edt_r15, 1, 3)); - } - } - } - return SRSASN_SUCCESS; +const char* wus_cfg_nb_r15_s::time_offset_drx_r15_opts::to_string() const +{ + static const char* options[] = {"ms40", "ms80", "ms160", "ms240"}; + return convert_enum_idx(options, 4, value, "wus_cfg_nb_r15_s::time_offset_drx_r15_e_"); } -SRSASN_CODE ul_cfg_common_nb_r14_s::unpack(cbit_ref& bref) +uint8_t wus_cfg_nb_r15_s::time_offset_drx_r15_opts::to_number() const { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(nprach_params_list_r14_present, 1)); + static const uint8_t options[] = {40, 80, 160, 240}; + return map_enum_number(options, 4, value, "wus_cfg_nb_r15_s::time_offset_drx_r15_e_"); +} - HANDLE_CODE(ul_carrier_freq_r14.unpack(bref)); - if (nprach_params_list_r14_present) { - HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_r14, bref, 1, 3)); - } +const char* wus_cfg_nb_r15_s::time_offset_e_drx_short_r15_opts::to_string() const +{ + static const char* options[] = {"ms40", "ms80", "ms160", "ms240"}; + return convert_enum_idx(options, 4, value, "wus_cfg_nb_r15_s::time_offset_e_drx_short_r15_e_"); +} +uint8_t wus_cfg_nb_r15_s::time_offset_e_drx_short_r15_opts::to_number() const +{ + static const uint8_t options[] = {40, 80, 160, 240}; + return map_enum_number(options, 4, value, "wus_cfg_nb_r15_s::time_offset_e_drx_short_r15_e_"); +} - if (ext) { - ext_groups_unpacker_guard group_flags(1); - group_flags.unpack(bref); +const char* wus_cfg_nb_r15_s::time_offset_e_drx_long_r15_opts::to_string() const +{ + static const char* options[] = {"ms1000", "ms2000"}; + return convert_enum_idx(options, 2, value, "wus_cfg_nb_r15_s::time_offset_e_drx_long_r15_e_"); +} +uint16_t wus_cfg_nb_r15_s::time_offset_e_drx_long_r15_opts::to_number() const +{ + static const uint16_t options[] = {1000, 2000}; + return map_enum_number(options, 2, value, "wus_cfg_nb_r15_s::time_offset_e_drx_long_r15_e_"); +} - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); +// WUS-ConfigPerCarrier-NB-r15 ::= SEQUENCE +SRSASN_CODE wus_cfg_per_carrier_nb_r15_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(max_dur_factor_r15.pack(bref)); - bool nprach_params_list_edt_r15_present; - HANDLE_CODE(bref.unpack(nprach_params_list_edt_r15_present, 1)); - nprach_params_list_edt_r15.set_present(nprach_params_list_edt_r15_present); - if (nprach_params_list_edt_r15.is_present()) { - HANDLE_CODE(unpack_dyn_seq_of(*nprach_params_list_edt_r15, bref, 1, 3)); - } - } - } return SRSASN_SUCCESS; } -void ul_cfg_common_nb_r14_s::to_json(json_writer& j) const +SRSASN_CODE wus_cfg_per_carrier_nb_r15_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(max_dur_factor_r15.unpack(bref)); + + return SRSASN_SUCCESS; +} +void wus_cfg_per_carrier_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("ul-CarrierFreq-r14"); - ul_carrier_freq_r14.to_json(j); - if (nprach_params_list_r14_present) { - j.start_array("nprach-ParametersList-r14"); - for (const auto& e1 : nprach_params_list_r14) { - e1.to_json(j); - } - j.end_array(); - } - if (ext) { - if (nprach_params_list_edt_r15.is_present()) { - j.start_array("nprach-ParametersListEDT-r15"); - for (const auto& e1 : *nprach_params_list_edt_r15) { - e1.to_json(j); - } - j.end_array(); - } - } + j.write_str("maxDurationFactor-r15", max_dur_factor_r15.to_string()); j.end_obj(); } -// UL-ConfigCommon-NB-v1530 ::= SEQUENCE -SRSASN_CODE ul_cfg_common_nb_v1530_s::pack(bit_ref& bref) const +// BCCH-Config-NB-r13 ::= SEQUENCE +SRSASN_CODE bcch_cfg_nb_r13_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(nprach_params_list_fmt2_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_params_list_fmt2_edt_r15_present, 1)); - - if (nprach_params_list_fmt2_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_fmt2_r15, 1, 3)); - } - if (nprach_params_list_fmt2_edt_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_fmt2_edt_r15, 1, 3)); - } + HANDLE_CODE(mod_period_coeff_r13.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE ul_cfg_common_nb_v1530_s::unpack(cbit_ref& bref) +SRSASN_CODE bcch_cfg_nb_r13_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(nprach_params_list_fmt2_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_params_list_fmt2_edt_r15_present, 1)); - - if (nprach_params_list_fmt2_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_fmt2_r15, bref, 1, 3)); - } - if (nprach_params_list_fmt2_edt_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_fmt2_edt_r15, bref, 1, 3)); - } + HANDLE_CODE(mod_period_coeff_r13.unpack(bref)); return SRSASN_SUCCESS; } -void ul_cfg_common_nb_v1530_s::to_json(json_writer& j) const +void bcch_cfg_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - if (nprach_params_list_fmt2_r15_present) { - j.start_array("nprach-ParametersListFmt2-r15"); - for (const auto& e1 : nprach_params_list_fmt2_r15) { - e1.to_json(j); - } - j.end_array(); - } - if (nprach_params_list_fmt2_edt_r15_present) { - j.start_array("nprach-ParametersListFmt2EDT-r15"); - for (const auto& e1 : nprach_params_list_fmt2_edt_r15) { - e1.to_json(j); - } - j.end_array(); - } + j.write_str("modificationPeriodCoeff-r13", mod_period_coeff_r13.to_string()); j.end_obj(); } -// UL-ConfigCommonTDD-NB-r15 ::= SEQUENCE -SRSASN_CODE ul_cfg_common_tdd_nb_r15_s::pack(bit_ref& bref) const +const char* bcch_cfg_nb_r13_s::mod_period_coeff_r13_opts::to_string() const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(nprach_params_list_tdd_r15_present, 1)); + static const char* options[] = {"n16", "n32", "n64", "n128"}; + return convert_enum_idx(options, 4, value, "bcch_cfg_nb_r13_s::mod_period_coeff_r13_e_"); +} +uint8_t bcch_cfg_nb_r13_s::mod_period_coeff_r13_opts::to_number() const +{ + static const uint8_t options[] = {16, 32, 64, 128}; + return map_enum_number(options, 4, value, "bcch_cfg_nb_r13_s::mod_period_coeff_r13_e_"); +} - HANDLE_CODE(tdd_ul_dl_align_offset_r15.pack(bref)); - if (nprach_params_list_tdd_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_tdd_r15, 1, 3)); +// CBP-Config-NB-r17 ::= SEQUENCE +SRSASN_CODE cbp_cfg_nb_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(nb_r17_present, 1)); + HANDLE_CODE(bref.pack(ue_specific_drx_cycle_min_r17_present, 1)); + + HANDLE_CODE(pack_integer(bref, nrsrp_min_r17, (uint8_t)0u, (uint8_t)97u)); + if (nb_r17_present) { + HANDLE_CODE(nb_r17.pack(bref)); + } + if (ue_specific_drx_cycle_min_r17_present) { + HANDLE_CODE(ue_specific_drx_cycle_min_r17.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE ul_cfg_common_tdd_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE cbp_cfg_nb_r17_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(nprach_params_list_tdd_r15_present, 1)); + HANDLE_CODE(bref.unpack(nb_r17_present, 1)); + HANDLE_CODE(bref.unpack(ue_specific_drx_cycle_min_r17_present, 1)); - HANDLE_CODE(tdd_ul_dl_align_offset_r15.unpack(bref)); - if (nprach_params_list_tdd_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_tdd_r15, bref, 1, 3)); + HANDLE_CODE(unpack_integer(nrsrp_min_r17, bref, (uint8_t)0u, (uint8_t)97u)); + if (nb_r17_present) { + HANDLE_CODE(nb_r17.unpack(bref)); + } + if (ue_specific_drx_cycle_min_r17_present) { + HANDLE_CODE(ue_specific_drx_cycle_min_r17.unpack(bref)); } return SRSASN_SUCCESS; } -void ul_cfg_common_tdd_nb_r15_s::to_json(json_writer& j) const +void cbp_cfg_nb_r17_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("tdd-UL-DL-AlignmentOffset-r15", tdd_ul_dl_align_offset_r15.to_string()); - if (nprach_params_list_tdd_r15_present) { - j.start_array("nprach-ParametersListTDD-r15"); - for (const auto& e1 : nprach_params_list_tdd_r15) { - e1.to_json(j); - } - j.end_array(); + j.write_int("nrsrpMin-r17", nrsrp_min_r17); + if (nb_r17_present) { + j.write_str("nB-r17", nb_r17.to_string()); + } + if (ue_specific_drx_cycle_min_r17_present) { + j.write_str("ue-SpecificDRX-CycleMin-r17", ue_specific_drx_cycle_min_r17.to_string()); } j.end_obj(); } -// UplinkPowerControlCommon-NB-r13 ::= SEQUENCE -SRSASN_CODE ul_pwr_ctrl_common_nb_r13_s::pack(bit_ref& bref) const +const char* cbp_cfg_nb_r17_s::nb_r17_opts::to_string() const { - HANDLE_CODE(pack_integer(bref, p0_nominal_npusch_r13, (int8_t)-126, (int8_t)24)); - HANDLE_CODE(alpha_r13.pack(bref)); - HANDLE_CODE(pack_integer(bref, delta_preamb_msg3_r13, (int8_t)-1, (int8_t)6)); - - return SRSASN_SUCCESS; + static const char* options[] = {"fourT", + "twoT", + "oneT", + "halfT", + "quarterT", + "one8thT", + "one16thT", + "one32ndT", + "one64thT", + "one128thT", + "one256thT", + "one512thT", + "one1024thT", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 16, value, "cbp_cfg_nb_r17_s::nb_r17_e_"); } -SRSASN_CODE ul_pwr_ctrl_common_nb_r13_s::unpack(cbit_ref& bref) +float cbp_cfg_nb_r17_s::nb_r17_opts::to_number() const { - HANDLE_CODE(unpack_integer(p0_nominal_npusch_r13, bref, (int8_t)-126, (int8_t)24)); - HANDLE_CODE(alpha_r13.unpack(bref)); - HANDLE_CODE(unpack_integer(delta_preamb_msg3_r13, bref, (int8_t)-1, (int8_t)6)); - - return SRSASN_SUCCESS; + static const float options[] = {4.0, 2.0, 1.0, 0.5, 0.25, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0}; + return map_enum_number(options, 13, value, "cbp_cfg_nb_r17_s::nb_r17_e_"); } -void ul_pwr_ctrl_common_nb_r13_s::to_json(json_writer& j) const +const char* cbp_cfg_nb_r17_s::nb_r17_opts::to_number_string() const { - j.start_obj(); - j.write_int("p0-NominalNPUSCH-r13", p0_nominal_npusch_r13); - j.write_str("alpha-r13", alpha_r13.to_string()); - j.write_int("deltaPreambleMsg3-r13", delta_preamb_msg3_r13); - j.end_obj(); + static const char* options[] = {"4", "2", "1", "0.5", "0.25", "8", "16", "32", "64", "128", "256", "512", "1024"}; + return convert_enum_idx(options, 16, value, "cbp_cfg_nb_r17_s::nb_r17_e_"); } -const char* ul_pwr_ctrl_common_nb_r13_s::alpha_r13_opts::to_string() const -{ - static const char* options[] = {"al0", "al04", "al05", "al06", "al07", "al08", "al09", "al1"}; - return convert_enum_idx(options, 8, value, "ul_pwr_ctrl_common_nb_r13_s::alpha_r13_e_"); -} -float ul_pwr_ctrl_common_nb_r13_s::alpha_r13_opts::to_number() const +const char* cbp_cfg_nb_r17_s::ue_specific_drx_cycle_min_r17_opts::to_string() const { - static const float options[] = {0.0, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; - return map_enum_number(options, 8, value, "ul_pwr_ctrl_common_nb_r13_s::alpha_r13_e_"); + static const char* options[] = {"rf32", "rf64", "rf128", "rf256"}; + return convert_enum_idx(options, 4, value, "cbp_cfg_nb_r17_s::ue_specific_drx_cycle_min_r17_e_"); } -const char* ul_pwr_ctrl_common_nb_r13_s::alpha_r13_opts::to_number_string() const +uint16_t cbp_cfg_nb_r17_s::ue_specific_drx_cycle_min_r17_opts::to_number() const { - static const char* options[] = {"0", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1"}; - return convert_enum_idx(options, 8, value, "ul_pwr_ctrl_common_nb_r13_s::alpha_r13_e_"); + static const uint16_t options[] = {32, 64, 128, 256}; + return map_enum_number(options, 4, value, "cbp_cfg_nb_r17_s::ue_specific_drx_cycle_min_r17_e_"); } -// WUS-Config-NB-r15 ::= SEQUENCE -SRSASN_CODE wus_cfg_nb_r15_s::pack(bit_ref& bref) const +// CarrierFreqEUTRA-NB-r16 ::= SEQUENCE +SRSASN_CODE carrier_freq_eutra_nb_r16_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(num_pos_r15_present, 1)); - HANDLE_CODE(bref.pack(time_offset_e_drx_long_r15_present, 1)); + HANDLE_CODE(bref.pack(sib1_r16_present, 1)); + HANDLE_CODE(bref.pack(sib1_br_r16_present, 1)); - HANDLE_CODE(max_dur_factor_r15.pack(bref)); - if (num_pos_r15_present) { - HANDLE_CODE(num_pos_r15.pack(bref)); - } - HANDLE_CODE(num_drx_cycles_relaxed_r15.pack(bref)); - HANDLE_CODE(time_offset_drx_r15.pack(bref)); - HANDLE_CODE(time_offset_e_drx_short_r15.pack(bref)); - if (time_offset_e_drx_long_r15_present) { - HANDLE_CODE(time_offset_e_drx_long_r15.pack(bref)); - } + HANDLE_CODE(pack_integer(bref, carrier_freq_r16, (uint32_t)0u, (uint32_t)262143u)); return SRSASN_SUCCESS; } -SRSASN_CODE wus_cfg_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE carrier_freq_eutra_nb_r16_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(num_pos_r15_present, 1)); - HANDLE_CODE(bref.unpack(time_offset_e_drx_long_r15_present, 1)); + HANDLE_CODE(bref.unpack(sib1_r16_present, 1)); + HANDLE_CODE(bref.unpack(sib1_br_r16_present, 1)); - HANDLE_CODE(max_dur_factor_r15.unpack(bref)); - if (num_pos_r15_present) { - HANDLE_CODE(num_pos_r15.unpack(bref)); - } - HANDLE_CODE(num_drx_cycles_relaxed_r15.unpack(bref)); - HANDLE_CODE(time_offset_drx_r15.unpack(bref)); - HANDLE_CODE(time_offset_e_drx_short_r15.unpack(bref)); - if (time_offset_e_drx_long_r15_present) { - HANDLE_CODE(time_offset_e_drx_long_r15.unpack(bref)); - } + HANDLE_CODE(unpack_integer(carrier_freq_r16, bref, (uint32_t)0u, (uint32_t)262143u)); return SRSASN_SUCCESS; } -void wus_cfg_nb_r15_s::to_json(json_writer& j) const +void carrier_freq_eutra_nb_r16_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("maxDurationFactor-r15", max_dur_factor_r15.to_string()); - if (num_pos_r15_present) { - j.write_str("numPOs-r15", num_pos_r15.to_string()); + j.write_int("carrierFreq-r16", carrier_freq_r16); + if (sib1_r16_present) { + j.write_str("sib1-r16", "supported"); } - j.write_str("numDRX-CyclesRelaxed-r15", num_drx_cycles_relaxed_r15.to_string()); - j.write_str("timeOffsetDRX-r15", time_offset_drx_r15.to_string()); - j.write_str("timeOffset-eDRX-Short-r15", time_offset_e_drx_short_r15.to_string()); - if (time_offset_e_drx_long_r15_present) { - j.write_str("timeOffset-eDRX-Long-r15", time_offset_e_drx_long_r15.to_string()); + if (sib1_br_r16_present) { + j.write_str("sib1-BR-r16", "supported"); } j.end_obj(); } -const char* wus_cfg_nb_r15_s::num_pos_r15_opts::to_string() const +// CarrierFreqsGERAN-NB-r16 ::= SEQUENCE +SRSASN_CODE carrier_freqs_geran_nb_r16_s::pack(bit_ref& bref) const { - static const char* options[] = {"n1", "n2", "n4"}; - return convert_enum_idx(options, 3, value, "wus_cfg_nb_r15_s::num_pos_r15_e_"); + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ec_gsm_iot_r16_present, 1)); + HANDLE_CODE(bref.pack(peo_r16_present, 1)); + + HANDLE_CODE(carrier_freqs_r16.pack(bref)); + + return SRSASN_SUCCESS; } -uint8_t wus_cfg_nb_r15_s::num_pos_r15_opts::to_number() const +SRSASN_CODE carrier_freqs_geran_nb_r16_s::unpack(cbit_ref& bref) { - static const uint8_t options[] = {1, 2, 4}; - return map_enum_number(options, 3, value, "wus_cfg_nb_r15_s::num_pos_r15_e_"); -} + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ec_gsm_iot_r16_present, 1)); + HANDLE_CODE(bref.unpack(peo_r16_present, 1)); -const char* wus_cfg_nb_r15_s::num_drx_cycles_relaxed_r15_opts::to_string() const -{ - static const char* options[] = {"n1", "n2", "n4", "n8"}; - return convert_enum_idx(options, 4, value, "wus_cfg_nb_r15_s::num_drx_cycles_relaxed_r15_e_"); + HANDLE_CODE(carrier_freqs_r16.unpack(bref)); + + return SRSASN_SUCCESS; } -uint8_t wus_cfg_nb_r15_s::num_drx_cycles_relaxed_r15_opts::to_number() const -{ - static const uint8_t options[] = {1, 2, 4, 8}; - return map_enum_number(options, 4, value, "wus_cfg_nb_r15_s::num_drx_cycles_relaxed_r15_e_"); -} - -const char* wus_cfg_nb_r15_s::time_offset_drx_r15_opts::to_string() const -{ - static const char* options[] = {"ms40", "ms80", "ms160", "ms240"}; - return convert_enum_idx(options, 4, value, "wus_cfg_nb_r15_s::time_offset_drx_r15_e_"); -} -uint8_t wus_cfg_nb_r15_s::time_offset_drx_r15_opts::to_number() const -{ - static const uint8_t options[] = {40, 80, 160, 240}; - return map_enum_number(options, 4, value, "wus_cfg_nb_r15_s::time_offset_drx_r15_e_"); -} - -const char* wus_cfg_nb_r15_s::time_offset_e_drx_short_r15_opts::to_string() const -{ - static const char* options[] = {"ms40", "ms80", "ms160", "ms240"}; - return convert_enum_idx(options, 4, value, "wus_cfg_nb_r15_s::time_offset_e_drx_short_r15_e_"); -} -uint8_t wus_cfg_nb_r15_s::time_offset_e_drx_short_r15_opts::to_number() const -{ - static const uint8_t options[] = {40, 80, 160, 240}; - return map_enum_number(options, 4, value, "wus_cfg_nb_r15_s::time_offset_e_drx_short_r15_e_"); -} - -const char* wus_cfg_nb_r15_s::time_offset_e_drx_long_r15_opts::to_string() const -{ - static const char* options[] = {"ms1000", "ms2000"}; - return convert_enum_idx(options, 2, value, "wus_cfg_nb_r15_s::time_offset_e_drx_long_r15_e_"); -} -uint16_t wus_cfg_nb_r15_s::time_offset_e_drx_long_r15_opts::to_number() const -{ - static const uint16_t options[] = {1000, 2000}; - return map_enum_number(options, 2, value, "wus_cfg_nb_r15_s::time_offset_e_drx_long_r15_e_"); -} - -// CellReselectionInfoCommon-NB-v1450 ::= SEQUENCE -SRSASN_CODE cell_resel_info_common_nb_v1450_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(s_search_delta_p_r14.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE cell_resel_info_common_nb_v1450_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(s_search_delta_p_r14.unpack(bref)); - - return SRSASN_SUCCESS; -} -void cell_resel_info_common_nb_v1450_s::to_json(json_writer& j) const +void carrier_freqs_geran_nb_r16_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("s-SearchDeltaP-r14", s_search_delta_p_r14.to_string()); + j.write_fieldname("carrierFreqs-r16"); + carrier_freqs_r16.to_json(j); + if (ec_gsm_iot_r16_present) { + j.write_str("ec-GSM-IOT-r16", "supported"); + } + if (peo_r16_present) { + j.write_str("peo-r16", "supported"); + } j.end_obj(); } -const char* cell_resel_info_common_nb_v1450_s::s_search_delta_p_r14_opts::to_string() const -{ - static const char* options[] = {"dB6", "dB9", "dB12", "dB15"}; - return convert_enum_idx(options, 4, value, "cell_resel_info_common_nb_v1450_s::s_search_delta_p_r14_e_"); -} -uint8_t cell_resel_info_common_nb_v1450_s::s_search_delta_p_r14_opts::to_number() const -{ - static const uint8_t options[] = {6, 9, 12, 15}; - return map_enum_number(options, 4, value, "cell_resel_info_common_nb_v1450_s::s_search_delta_p_r14_e_"); -} - -// CellSelectionInfo-NB-v1430 ::= SEQUENCE -SRSASN_CODE cell_sel_info_nb_v1430_s::pack(bit_ref& bref) const +// DL-ConfigCommon-NB-r14 ::= SEQUENCE +SRSASN_CODE dl_cfg_common_nb_r14_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(pwr_class14dbm_offset_r14_present, 1)); - HANDLE_CODE(bref.pack(ce_authorisation_offset_r14_present, 1)); + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(pcch_cfg_r14_present, 1)); - if (pwr_class14dbm_offset_r14_present) { - HANDLE_CODE(pwr_class14dbm_offset_r14.pack(bref)); - } - if (ce_authorisation_offset_r14_present) { - HANDLE_CODE(ce_authorisation_offset_r14.pack(bref)); + HANDLE_CODE(dl_carrier_cfg_r14.pack(bref)); + if (pcch_cfg_r14_present) { + HANDLE_CODE(pcch_cfg_r14.pack(bref)); } - return SRSASN_SUCCESS; -} -SRSASN_CODE cell_sel_info_nb_v1430_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(bref.unpack(pwr_class14dbm_offset_r14_present, 1)); - HANDLE_CODE(bref.unpack(ce_authorisation_offset_r14_present, 1)); + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= wus_cfg_r15.is_present(); + group_flags[1] |= gwus_cfg_r16.is_present(); + group_flags[2] |= pcch_cfg_r17.is_present(); + group_flags.pack(bref); - if (pwr_class14dbm_offset_r14_present) { - HANDLE_CODE(pwr_class14dbm_offset_r14.unpack(bref)); - } - if (ce_authorisation_offset_r14_present) { - HANDLE_CODE(ce_authorisation_offset_r14.unpack(bref)); - } + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); - return SRSASN_SUCCESS; -} -void cell_sel_info_nb_v1430_s::to_json(json_writer& j) const -{ - j.start_obj(); - if (pwr_class14dbm_offset_r14_present) { - j.write_str("powerClass14dBm-Offset-r14", pwr_class14dbm_offset_r14.to_string()); - } - if (ce_authorisation_offset_r14_present) { - j.write_str("ce-authorisationOffset-r14", ce_authorisation_offset_r14.to_string()); - } - j.end_obj(); -} + HANDLE_CODE(bref.pack(wus_cfg_r15.is_present(), 1)); + if (wus_cfg_r15.is_present()) { + HANDLE_CODE(wus_cfg_r15->pack(bref)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); -const char* cell_sel_info_nb_v1430_s::pwr_class14dbm_offset_r14_opts::to_string() const -{ - static const char* options[] = {"dB-6", "dB-3", "dB3", "dB6", "dB9", "dB12"}; - return convert_enum_idx(options, 6, value, "cell_sel_info_nb_v1430_s::pwr_class14dbm_offset_r14_e_"); -} -int8_t cell_sel_info_nb_v1430_s::pwr_class14dbm_offset_r14_opts::to_number() const -{ - static const int8_t options[] = {-6, -3, 3, 6, 9, 12}; - return map_enum_number(options, 6, value, "cell_sel_info_nb_v1430_s::pwr_class14dbm_offset_r14_e_"); -} + HANDLE_CODE(bref.pack(gwus_cfg_r16.is_present(), 1)); + if (gwus_cfg_r16.is_present()) { + HANDLE_CODE(gwus_cfg_r16->pack(bref)); + } + } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); -const char* cell_sel_info_nb_v1430_s::ce_authorisation_offset_r14_opts::to_string() const -{ - static const char* options[] = {"dB5", "dB10", "dB15", "dB20", "dB25", "dB30", "dB35"}; - return convert_enum_idx(options, 7, value, "cell_sel_info_nb_v1430_s::ce_authorisation_offset_r14_e_"); + HANDLE_CODE(bref.pack(pcch_cfg_r17.is_present(), 1)); + if (pcch_cfg_r17.is_present()) { + HANDLE_CODE(pcch_cfg_r17->pack(bref)); + } + } + } + return SRSASN_SUCCESS; } -uint8_t cell_sel_info_nb_v1430_s::ce_authorisation_offset_r14_opts::to_number() const +SRSASN_CODE dl_cfg_common_nb_r14_s::unpack(cbit_ref& bref) { - static const uint8_t options[] = {5, 10, 15, 20, 25, 30, 35}; - return map_enum_number(options, 7, value, "cell_sel_info_nb_v1430_s::ce_authorisation_offset_r14_e_"); -} + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(pcch_cfg_r14_present, 1)); -// IntraFreqCellReselectionInfo-NB-v1350 ::= SEQUENCE -SRSASN_CODE intra_freq_cell_resel_info_nb_v1350_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, delta_rx_lev_min_v1350, (int8_t)-8, (int8_t)-1)); + HANDLE_CODE(dl_carrier_cfg_r14.unpack(bref)); + if (pcch_cfg_r14_present) { + HANDLE_CODE(pcch_cfg_r14.unpack(bref)); + } - return SRSASN_SUCCESS; -} -SRSASN_CODE intra_freq_cell_resel_info_nb_v1350_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(delta_rx_lev_min_v1350, bref, (int8_t)-8, (int8_t)-1)); + if (ext) { + ext_groups_unpacker_guard group_flags(3); + group_flags.unpack(bref); - return SRSASN_SUCCESS; -} -void intra_freq_cell_resel_info_nb_v1350_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("delta-RxLevMin-v1350", delta_rx_lev_min_v1350); - j.end_obj(); -} + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); -// IntraFreqCellReselectionInfo-NB-v1360 ::= SEQUENCE -SRSASN_CODE intra_freq_cell_resel_info_nb_v1360_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, s_intra_search_p_v1360, (uint8_t)32u, (uint8_t)63u)); + bool wus_cfg_r15_present; + HANDLE_CODE(bref.unpack(wus_cfg_r15_present, 1)); + wus_cfg_r15.set_present(wus_cfg_r15_present); + if (wus_cfg_r15.is_present()) { + HANDLE_CODE(wus_cfg_r15->unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); - return SRSASN_SUCCESS; -} -SRSASN_CODE intra_freq_cell_resel_info_nb_v1360_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(s_intra_search_p_v1360, bref, (uint8_t)32u, (uint8_t)63u)); + bool gwus_cfg_r16_present; + HANDLE_CODE(bref.unpack(gwus_cfg_r16_present, 1)); + gwus_cfg_r16.set_present(gwus_cfg_r16_present); + if (gwus_cfg_r16.is_present()) { + HANDLE_CODE(gwus_cfg_r16->unpack(bref)); + } + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + bool pcch_cfg_r17_present; + HANDLE_CODE(bref.unpack(pcch_cfg_r17_present, 1)); + pcch_cfg_r17.set_present(pcch_cfg_r17_present); + if (pcch_cfg_r17.is_present()) { + HANDLE_CODE(pcch_cfg_r17->unpack(bref)); + } + } + } return SRSASN_SUCCESS; } -void intra_freq_cell_resel_info_nb_v1360_s::to_json(json_writer& j) const +void dl_cfg_common_nb_r14_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("s-IntraSearchP-v1360", s_intra_search_p_v1360); + j.write_fieldname("dl-CarrierConfig-r14"); + dl_carrier_cfg_r14.to_json(j); + if (pcch_cfg_r14_present) { + j.write_fieldname("pcch-Config-r14"); + pcch_cfg_r14.to_json(j); + } + if (ext) { + if (wus_cfg_r15.is_present()) { + j.write_fieldname("wus-Config-r15"); + wus_cfg_r15->to_json(j); + } + if (gwus_cfg_r16.is_present()) { + j.write_fieldname("gwus-Config-r16"); + gwus_cfg_r16->to_json(j); + } + if (pcch_cfg_r17.is_present()) { + j.write_fieldname("pcch-Config-r17"); + pcch_cfg_r17->to_json(j); + } + } j.end_obj(); } -// IntraFreqCellReselectionInfo-NB-v1430 ::= SEQUENCE -SRSASN_CODE intra_freq_cell_resel_info_nb_v1430_s::pack(bit_ref& bref) const +// GWUS-Config-NB-r16 ::= SEQUENCE +SRSASN_CODE gwus_cfg_nb_r16_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(pwr_class14dbm_offset_r14_present, 1)); - HANDLE_CODE(bref.pack(ce_authorisation_offset_r14_present, 1)); + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(group_alternation_r16_present, 1)); + HANDLE_CODE(bref.pack(common_seq_r16_present, 1)); + HANDLE_CODE(bref.pack(time_params_r16_present, 1)); + HANDLE_CODE(bref.pack(res_cfg_e_drx_short_r16_present, 1)); + HANDLE_CODE(bref.pack(res_cfg_e_drx_long_r16_present, 1)); + HANDLE_CODE(bref.pack(prob_thresh_list_r16_present, 1)); - if (pwr_class14dbm_offset_r14_present) { - HANDLE_CODE(pwr_class14dbm_offset_r14.pack(bref)); + if (common_seq_r16_present) { + HANDLE_CODE(common_seq_r16.pack(bref)); } - if (ce_authorisation_offset_r14_present) { - HANDLE_CODE(ce_authorisation_offset_r14.pack(bref)); + if (time_params_r16_present) { + HANDLE_CODE(time_params_r16.pack(bref)); + } + HANDLE_CODE(res_cfg_drx_r16.pack(bref)); + if (res_cfg_e_drx_short_r16_present) { + HANDLE_CODE(res_cfg_e_drx_short_r16.pack(bref)); + } + if (res_cfg_e_drx_long_r16_present) { + HANDLE_CODE(res_cfg_e_drx_long_r16.pack(bref)); + } + if (prob_thresh_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, prob_thresh_list_r16, 1, 3)); } return SRSASN_SUCCESS; } -SRSASN_CODE intra_freq_cell_resel_info_nb_v1430_s::unpack(cbit_ref& bref) +SRSASN_CODE gwus_cfg_nb_r16_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(pwr_class14dbm_offset_r14_present, 1)); - HANDLE_CODE(bref.unpack(ce_authorisation_offset_r14_present, 1)); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(group_alternation_r16_present, 1)); + HANDLE_CODE(bref.unpack(common_seq_r16_present, 1)); + HANDLE_CODE(bref.unpack(time_params_r16_present, 1)); + HANDLE_CODE(bref.unpack(res_cfg_e_drx_short_r16_present, 1)); + HANDLE_CODE(bref.unpack(res_cfg_e_drx_long_r16_present, 1)); + HANDLE_CODE(bref.unpack(prob_thresh_list_r16_present, 1)); - if (pwr_class14dbm_offset_r14_present) { - HANDLE_CODE(pwr_class14dbm_offset_r14.unpack(bref)); + if (common_seq_r16_present) { + HANDLE_CODE(common_seq_r16.unpack(bref)); } - if (ce_authorisation_offset_r14_present) { - HANDLE_CODE(ce_authorisation_offset_r14.unpack(bref)); + if (time_params_r16_present) { + HANDLE_CODE(time_params_r16.unpack(bref)); + } + HANDLE_CODE(res_cfg_drx_r16.unpack(bref)); + if (res_cfg_e_drx_short_r16_present) { + HANDLE_CODE(res_cfg_e_drx_short_r16.unpack(bref)); + } + if (res_cfg_e_drx_long_r16_present) { + HANDLE_CODE(res_cfg_e_drx_long_r16.unpack(bref)); + } + if (prob_thresh_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(prob_thresh_list_r16, bref, 1, 3)); } return SRSASN_SUCCESS; } -void intra_freq_cell_resel_info_nb_v1430_s::to_json(json_writer& j) const +void gwus_cfg_nb_r16_s::to_json(json_writer& j) const { j.start_obj(); - if (pwr_class14dbm_offset_r14_present) { - j.write_str("powerClass14dBm-Offset-r14", pwr_class14dbm_offset_r14.to_string()); + if (group_alternation_r16_present) { + j.write_str("groupAlternation-r16", "true"); } - if (ce_authorisation_offset_r14_present) { - j.write_str("ce-AuthorisationOffset-r14", ce_authorisation_offset_r14.to_string()); + if (common_seq_r16_present) { + j.write_str("commonSequence-r16", common_seq_r16.to_string()); + } + if (time_params_r16_present) { + j.write_fieldname("timeParameters-r16"); + time_params_r16.to_json(j); + } + j.write_fieldname("resourceConfigDRX-r16"); + res_cfg_drx_r16.to_json(j); + if (res_cfg_e_drx_short_r16_present) { + j.write_fieldname("resourceConfig-eDRX-Short-r16"); + res_cfg_e_drx_short_r16.to_json(j); + } + if (res_cfg_e_drx_long_r16_present) { + j.write_fieldname("resourceConfig-eDRX-Long-r16"); + res_cfg_e_drx_long_r16.to_json(j); + } + if (prob_thresh_list_r16_present) { + j.start_array("probThreshList-r16"); + for (const auto& e1 : prob_thresh_list_r16) { + j.write_str(e1.to_string()); + } + j.end_array(); } j.end_obj(); } -const char* intra_freq_cell_resel_info_nb_v1430_s::pwr_class14dbm_offset_r14_opts::to_string() const +const char* gwus_cfg_nb_r16_s::common_seq_r16_opts::to_string() const { - static const char* options[] = {"dB-6", "dB-3", "dB3", "dB6", "dB9", "dB12"}; - return convert_enum_idx(options, 6, value, "intra_freq_cell_resel_info_nb_v1430_s::pwr_class14dbm_offset_r14_e_"); + static const char* options[] = {"g0", "g126"}; + return convert_enum_idx(options, 2, value, "gwus_cfg_nb_r16_s::common_seq_r16_e_"); } -int8_t intra_freq_cell_resel_info_nb_v1430_s::pwr_class14dbm_offset_r14_opts::to_number() const +uint8_t gwus_cfg_nb_r16_s::common_seq_r16_opts::to_number() const { - static const int8_t options[] = {-6, -3, 3, 6, 9, 12}; - return map_enum_number(options, 6, value, "intra_freq_cell_resel_info_nb_v1430_s::pwr_class14dbm_offset_r14_e_"); + static const uint8_t options[] = {0, 126}; + return map_enum_number(options, 2, value, "gwus_cfg_nb_r16_s::common_seq_r16_e_"); } -const char* intra_freq_cell_resel_info_nb_v1430_s::ce_authorisation_offset_r14_opts::to_string() const -{ - static const char* options[] = {"dB5", "dB10", "dB15", "dB20", "dB25", "dB30", "dB35"}; - return convert_enum_idx(options, 7, value, "intra_freq_cell_resel_info_nb_v1430_s::ce_authorisation_offset_r14_e_"); -} -uint8_t intra_freq_cell_resel_info_nb_v1430_s::ce_authorisation_offset_r14_opts::to_number() const -{ - static const uint8_t options[] = {5, 10, 15, 20, 25, 30, 35}; - return map_enum_number(options, 7, value, "intra_freq_cell_resel_info_nb_v1430_s::ce_authorisation_offset_r14_e_"); -} - -// NPDCCH-SC-MCCH-Config-NB-r14 ::= SEQUENCE -SRSASN_CODE npdcch_sc_mcch_cfg_nb_r14_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(npdcch_num_repeats_sc_mcch_r14.pack(bref)); - HANDLE_CODE(npdcch_start_sf_sc_mcch_r14.pack(bref)); - HANDLE_CODE(npdcch_offset_sc_mcch_r14.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE npdcch_sc_mcch_cfg_nb_r14_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(npdcch_num_repeats_sc_mcch_r14.unpack(bref)); - HANDLE_CODE(npdcch_start_sf_sc_mcch_r14.unpack(bref)); - HANDLE_CODE(npdcch_offset_sc_mcch_r14.unpack(bref)); - - return SRSASN_SUCCESS; -} -void npdcch_sc_mcch_cfg_nb_r14_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_str("npdcch-NumRepetitions-SC-MCCH-r14", npdcch_num_repeats_sc_mcch_r14.to_string()); - j.write_str("npdcch-StartSF-SC-MCCH-r14", npdcch_start_sf_sc_mcch_r14.to_string()); - j.write_str("npdcch-Offset-SC-MCCH-r14", npdcch_offset_sc_mcch_r14.to_string()); - j.end_obj(); -} - -const char* npdcch_sc_mcch_cfg_nb_r14_s::npdcch_num_repeats_sc_mcch_r14_opts::to_string() const -{ - static const char* options[] = { - "r1", "r2", "r4", "r8", "r16", "r32", "r64", "r128", "r256", "r512", "r1024", "r2048"}; - return convert_enum_idx(options, 12, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_num_repeats_sc_mcch_r14_e_"); -} -uint16_t npdcch_sc_mcch_cfg_nb_r14_s::npdcch_num_repeats_sc_mcch_r14_opts::to_number() const -{ - static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; - return map_enum_number(options, 12, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_num_repeats_sc_mcch_r14_e_"); -} - -const char* npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_opts::to_string() const -{ - static const char* options[] = {"v1dot5", "v2", "v4", "v8", "v16", "v32", "v48", "v64"}; - return convert_enum_idx(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_e_"); -} -float npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_opts::to_number() const -{ - static const float options[] = {1.5, 2.0, 4.0, 8.0, 16.0, 32.0, 48.0, 64.0}; - return map_enum_number(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_e_"); -} -const char* npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_opts::to_number_string() const -{ - static const char* options[] = {"1.5", "2", "4", "8", "16", "32", "48", "64"}; - return convert_enum_idx(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_e_"); -} - -const char* npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_opts::to_string() const -{ - static const char* options[] = { - "zero", "oneEighth", "oneQuarter", "threeEighth", "oneHalf", "fiveEighth", "threeQuarter", "sevenEighth"}; - return convert_enum_idx(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_e_"); -} -float npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_opts::to_number() const -{ - static const float options[] = {0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875}; - return map_enum_number(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_e_"); -} -const char* npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_opts::to_number_string() const -{ - static const char* options[] = {"0", "1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "7/8"}; - return convert_enum_idx(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_e_"); -} - -// RadioResourceConfigCommonSIB-NB-r13 ::= SEQUENCE -SRSASN_CODE rr_cfg_common_sib_nb_r13_s::pack(bit_ref& bref) const +// InterFreqCarrierFreqInfo-NB-r13 ::= SEQUENCE +SRSASN_CODE inter_freq_carrier_freq_info_nb_r13_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(dl_gap_r13_present, 1)); + HANDLE_CODE(bref.pack(q_qual_min_r13_present, 1)); + HANDLE_CODE(bref.pack(p_max_r13_present, 1)); + HANDLE_CODE(bref.pack(q_offset_freq_r13_present, 1)); + HANDLE_CODE(bref.pack(inter_freq_neigh_cell_list_r13_present, 1)); + HANDLE_CODE(bref.pack(inter_freq_excluded_cell_list_r13_present, 1)); + HANDLE_CODE(bref.pack(multi_band_info_list_r13_present, 1)); - HANDLE_CODE(rach_cfg_common_r13.pack(bref)); - HANDLE_CODE(bcch_cfg_r13.pack(bref)); - HANDLE_CODE(pcch_cfg_r13.pack(bref)); - HANDLE_CODE(nprach_cfg_r13.pack(bref)); - HANDLE_CODE(npdsch_cfg_common_r13.pack(bref)); - HANDLE_CODE(npusch_cfg_common_r13.pack(bref)); - if (dl_gap_r13_present) { - HANDLE_CODE(dl_gap_r13.pack(bref)); + HANDLE_CODE(dl_carrier_freq_r13.pack(bref)); + HANDLE_CODE(pack_integer(bref, q_rx_lev_min_r13, (int8_t)-70, (int8_t)-22)); + if (q_qual_min_r13_present) { + HANDLE_CODE(pack_integer(bref, q_qual_min_r13, (int8_t)-34, (int8_t)-3)); + } + if (p_max_r13_present) { + HANDLE_CODE(pack_integer(bref, p_max_r13, (int8_t)-30, (int8_t)33)); + } + if (q_offset_freq_r13_present) { + HANDLE_CODE(q_offset_freq_r13.pack(bref)); + } + if (inter_freq_neigh_cell_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_neigh_cell_list_r13, 1, 16, integer_packer(0, 503))); + } + if (inter_freq_excluded_cell_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_excluded_cell_list_r13, 1, 16, integer_packer(0, 503))); + } + if (multi_band_info_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, multi_band_info_list_r13, 1, 8)); } - HANDLE_CODE(ul_pwr_ctrl_common_r13.pack(bref)); if (ext) { ext_groups_packer_guard group_flags; - group_flags[0] |= nprach_cfg_v1330.is_present(); - group_flags[1] |= nprach_cfg_v1450.is_present(); - group_flags[2] |= nprach_cfg_v1530.is_present(); - group_flags[2] |= dl_gap_v1530.is_present(); - group_flags[2] |= wus_cfg_r15.is_present(); - group_flags[3] |= nprach_cfg_v1550.is_present(); + group_flags[0] |= delta_rx_lev_min_v1350_present; + group_flags[1] |= pwr_class14dbm_offset_r14_present; + group_flags[1] |= ce_authorisation_offset_r14_present; + group_flags[2] |= nsss_rrm_cfg_r15.is_present(); + group_flags[2] |= inter_freq_neigh_cell_list_v1530.is_present(); + group_flags[3] |= dl_carrier_freq_v1550.is_present(); group_flags.pack(bref); if (group_flags[0]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(nprach_cfg_v1330.is_present(), 1)); - if (nprach_cfg_v1330.is_present()) { - HANDLE_CODE(nprach_cfg_v1330->pack(bref)); + HANDLE_CODE(bref.pack(delta_rx_lev_min_v1350_present, 1)); + if (delta_rx_lev_min_v1350_present) { + HANDLE_CODE(pack_integer(bref, delta_rx_lev_min_v1350, (int8_t)-8, (int8_t)-1)); } } if (group_flags[1]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(nprach_cfg_v1450.is_present(), 1)); - if (nprach_cfg_v1450.is_present()) { - HANDLE_CODE(nprach_cfg_v1450->pack(bref)); + HANDLE_CODE(bref.pack(pwr_class14dbm_offset_r14_present, 1)); + HANDLE_CODE(bref.pack(ce_authorisation_offset_r14_present, 1)); + if (pwr_class14dbm_offset_r14_present) { + HANDLE_CODE(pwr_class14dbm_offset_r14.pack(bref)); + } + if (ce_authorisation_offset_r14_present) { + HANDLE_CODE(ce_authorisation_offset_r14.pack(bref)); } } if (group_flags[2]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(nprach_cfg_v1530.is_present(), 1)); - HANDLE_CODE(bref.pack(dl_gap_v1530.is_present(), 1)); - HANDLE_CODE(bref.pack(wus_cfg_r15.is_present(), 1)); - if (nprach_cfg_v1530.is_present()) { - HANDLE_CODE(nprach_cfg_v1530->pack(bref)); - } - if (dl_gap_v1530.is_present()) { - HANDLE_CODE(dl_gap_v1530->pack(bref)); + HANDLE_CODE(bref.pack(nsss_rrm_cfg_r15.is_present(), 1)); + HANDLE_CODE(bref.pack(inter_freq_neigh_cell_list_v1530.is_present(), 1)); + if (nsss_rrm_cfg_r15.is_present()) { + HANDLE_CODE(nsss_rrm_cfg_r15->pack(bref)); } - if (wus_cfg_r15.is_present()) { - HANDLE_CODE(wus_cfg_r15->pack(bref)); + if (inter_freq_neigh_cell_list_v1530.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *inter_freq_neigh_cell_list_v1530, 1, 16)); } } if (group_flags[3]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(nprach_cfg_v1550.is_present(), 1)); - if (nprach_cfg_v1550.is_present()) { - HANDLE_CODE(nprach_cfg_v1550->pack(bref)); + HANDLE_CODE(bref.pack(dl_carrier_freq_v1550.is_present(), 1)); + if (dl_carrier_freq_v1550.is_present()) { + HANDLE_CODE(dl_carrier_freq_v1550->pack(bref)); } } } return SRSASN_SUCCESS; } -SRSASN_CODE rr_cfg_common_sib_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE inter_freq_carrier_freq_info_nb_r13_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(dl_gap_r13_present, 1)); + HANDLE_CODE(bref.unpack(q_qual_min_r13_present, 1)); + HANDLE_CODE(bref.unpack(p_max_r13_present, 1)); + HANDLE_CODE(bref.unpack(q_offset_freq_r13_present, 1)); + HANDLE_CODE(bref.unpack(inter_freq_neigh_cell_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(inter_freq_excluded_cell_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(multi_band_info_list_r13_present, 1)); - HANDLE_CODE(rach_cfg_common_r13.unpack(bref)); - HANDLE_CODE(bcch_cfg_r13.unpack(bref)); - HANDLE_CODE(pcch_cfg_r13.unpack(bref)); - HANDLE_CODE(nprach_cfg_r13.unpack(bref)); - HANDLE_CODE(npdsch_cfg_common_r13.unpack(bref)); - HANDLE_CODE(npusch_cfg_common_r13.unpack(bref)); - if (dl_gap_r13_present) { - HANDLE_CODE(dl_gap_r13.unpack(bref)); + HANDLE_CODE(dl_carrier_freq_r13.unpack(bref)); + HANDLE_CODE(unpack_integer(q_rx_lev_min_r13, bref, (int8_t)-70, (int8_t)-22)); + if (q_qual_min_r13_present) { + HANDLE_CODE(unpack_integer(q_qual_min_r13, bref, (int8_t)-34, (int8_t)-3)); + } + if (p_max_r13_present) { + HANDLE_CODE(unpack_integer(p_max_r13, bref, (int8_t)-30, (int8_t)33)); + } + if (q_offset_freq_r13_present) { + HANDLE_CODE(q_offset_freq_r13.unpack(bref)); + } + if (inter_freq_neigh_cell_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(inter_freq_neigh_cell_list_r13, bref, 1, 16, integer_packer(0, 503))); + } + if (inter_freq_excluded_cell_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(inter_freq_excluded_cell_list_r13, bref, 1, 16, integer_packer(0, 503))); + } + if (multi_band_info_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r13, bref, 1, 8)); } - HANDLE_CODE(ul_pwr_ctrl_common_r13.unpack(bref)); if (ext) { ext_groups_unpacker_guard group_flags(4); @@ -8864,1038 +9849,1024 @@ SRSASN_CODE rr_cfg_common_sib_nb_r13_s::unpack(cbit_ref& bref) if (group_flags[0]) { varlength_field_unpack_guard varlen_scope(bref, false); - bool nprach_cfg_v1330_present; - HANDLE_CODE(bref.unpack(nprach_cfg_v1330_present, 1)); - nprach_cfg_v1330.set_present(nprach_cfg_v1330_present); - if (nprach_cfg_v1330.is_present()) { - HANDLE_CODE(nprach_cfg_v1330->unpack(bref)); + HANDLE_CODE(bref.unpack(delta_rx_lev_min_v1350_present, 1)); + if (delta_rx_lev_min_v1350_present) { + HANDLE_CODE(unpack_integer(delta_rx_lev_min_v1350, bref, (int8_t)-8, (int8_t)-1)); } } if (group_flags[1]) { varlength_field_unpack_guard varlen_scope(bref, false); - bool nprach_cfg_v1450_present; - HANDLE_CODE(bref.unpack(nprach_cfg_v1450_present, 1)); - nprach_cfg_v1450.set_present(nprach_cfg_v1450_present); - if (nprach_cfg_v1450.is_present()) { - HANDLE_CODE(nprach_cfg_v1450->unpack(bref)); + HANDLE_CODE(bref.unpack(pwr_class14dbm_offset_r14_present, 1)); + HANDLE_CODE(bref.unpack(ce_authorisation_offset_r14_present, 1)); + if (pwr_class14dbm_offset_r14_present) { + HANDLE_CODE(pwr_class14dbm_offset_r14.unpack(bref)); + } + if (ce_authorisation_offset_r14_present) { + HANDLE_CODE(ce_authorisation_offset_r14.unpack(bref)); } } if (group_flags[2]) { varlength_field_unpack_guard varlen_scope(bref, false); - bool nprach_cfg_v1530_present; - HANDLE_CODE(bref.unpack(nprach_cfg_v1530_present, 1)); - nprach_cfg_v1530.set_present(nprach_cfg_v1530_present); - bool dl_gap_v1530_present; - HANDLE_CODE(bref.unpack(dl_gap_v1530_present, 1)); - dl_gap_v1530.set_present(dl_gap_v1530_present); - bool wus_cfg_r15_present; - HANDLE_CODE(bref.unpack(wus_cfg_r15_present, 1)); - wus_cfg_r15.set_present(wus_cfg_r15_present); - if (nprach_cfg_v1530.is_present()) { - HANDLE_CODE(nprach_cfg_v1530->unpack(bref)); - } - if (dl_gap_v1530.is_present()) { - HANDLE_CODE(dl_gap_v1530->unpack(bref)); + bool nsss_rrm_cfg_r15_present; + HANDLE_CODE(bref.unpack(nsss_rrm_cfg_r15_present, 1)); + nsss_rrm_cfg_r15.set_present(nsss_rrm_cfg_r15_present); + bool inter_freq_neigh_cell_list_v1530_present; + HANDLE_CODE(bref.unpack(inter_freq_neigh_cell_list_v1530_present, 1)); + inter_freq_neigh_cell_list_v1530.set_present(inter_freq_neigh_cell_list_v1530_present); + if (nsss_rrm_cfg_r15.is_present()) { + HANDLE_CODE(nsss_rrm_cfg_r15->unpack(bref)); } - if (wus_cfg_r15.is_present()) { - HANDLE_CODE(wus_cfg_r15->unpack(bref)); + if (inter_freq_neigh_cell_list_v1530.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*inter_freq_neigh_cell_list_v1530, bref, 1, 16)); } } if (group_flags[3]) { varlength_field_unpack_guard varlen_scope(bref, false); - bool nprach_cfg_v1550_present; - HANDLE_CODE(bref.unpack(nprach_cfg_v1550_present, 1)); - nprach_cfg_v1550.set_present(nprach_cfg_v1550_present); - if (nprach_cfg_v1550.is_present()) { - HANDLE_CODE(nprach_cfg_v1550->unpack(bref)); + bool dl_carrier_freq_v1550_present; + HANDLE_CODE(bref.unpack(dl_carrier_freq_v1550_present, 1)); + dl_carrier_freq_v1550.set_present(dl_carrier_freq_v1550_present); + if (dl_carrier_freq_v1550.is_present()) { + HANDLE_CODE(dl_carrier_freq_v1550->unpack(bref)); } } } return SRSASN_SUCCESS; } -void rr_cfg_common_sib_nb_r13_s::to_json(json_writer& j) const +void inter_freq_carrier_freq_info_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("rach-ConfigCommon-r13"); - rach_cfg_common_r13.to_json(j); - j.write_fieldname("bcch-Config-r13"); - bcch_cfg_r13.to_json(j); - j.write_fieldname("pcch-Config-r13"); - pcch_cfg_r13.to_json(j); - j.write_fieldname("nprach-Config-r13"); - nprach_cfg_r13.to_json(j); - j.write_fieldname("npdsch-ConfigCommon-r13"); - npdsch_cfg_common_r13.to_json(j); - j.write_fieldname("npusch-ConfigCommon-r13"); - npusch_cfg_common_r13.to_json(j); - if (dl_gap_r13_present) { - j.write_fieldname("dl-Gap-r13"); - dl_gap_r13.to_json(j); + j.write_fieldname("dl-CarrierFreq-r13"); + dl_carrier_freq_r13.to_json(j); + j.write_int("q-RxLevMin-r13", q_rx_lev_min_r13); + if (q_qual_min_r13_present) { + j.write_int("q-QualMin-r13", q_qual_min_r13); + } + if (p_max_r13_present) { + j.write_int("p-Max-r13", p_max_r13); + } + if (q_offset_freq_r13_present) { + j.write_str("q-OffsetFreq-r13", q_offset_freq_r13.to_string()); + } + if (inter_freq_neigh_cell_list_r13_present) { + j.start_array("interFreqNeighCellList-r13"); + for (const auto& e1 : inter_freq_neigh_cell_list_r13) { + j.write_int(e1); + } + j.end_array(); + } + if (inter_freq_excluded_cell_list_r13_present) { + j.start_array("interFreqExcludedCellList-r13"); + for (const auto& e1 : inter_freq_excluded_cell_list_r13) { + j.write_int(e1); + } + j.end_array(); + } + if (multi_band_info_list_r13_present) { + j.start_array("multiBandInfoList-r13"); + for (const auto& e1 : multi_band_info_list_r13) { + e1.to_json(j); + } + j.end_array(); } - j.write_fieldname("uplinkPowerControlCommon-r13"); - ul_pwr_ctrl_common_r13.to_json(j); if (ext) { - if (nprach_cfg_v1330.is_present()) { - j.write_fieldname("nprach-Config-v1330"); - nprach_cfg_v1330->to_json(j); + if (delta_rx_lev_min_v1350_present) { + j.write_int("delta-RxLevMin-v1350", delta_rx_lev_min_v1350); } - if (nprach_cfg_v1450.is_present()) { - j.write_fieldname("nprach-Config-v1450"); - nprach_cfg_v1450->to_json(j); + if (pwr_class14dbm_offset_r14_present) { + j.write_str("powerClass14dBm-Offset-r14", pwr_class14dbm_offset_r14.to_string()); } - if (nprach_cfg_v1530.is_present()) { - j.write_fieldname("nprach-Config-v1530"); - nprach_cfg_v1530->to_json(j); + if (ce_authorisation_offset_r14_present) { + j.write_str("ce-AuthorisationOffset-r14", ce_authorisation_offset_r14.to_string()); } - if (dl_gap_v1530.is_present()) { - j.write_fieldname("dl-Gap-v1530"); - dl_gap_v1530->to_json(j); + if (nsss_rrm_cfg_r15.is_present()) { + j.write_fieldname("nsss-RRM-Config-r15"); + nsss_rrm_cfg_r15->to_json(j); } - if (wus_cfg_r15.is_present()) { - j.write_fieldname("wus-Config-r15"); - wus_cfg_r15->to_json(j); + if (inter_freq_neigh_cell_list_v1530.is_present()) { + j.start_array("interFreqNeighCellList-v1530"); + for (const auto& e1 : *inter_freq_neigh_cell_list_v1530) { + e1.to_json(j); + } + j.end_array(); } - if (nprach_cfg_v1550.is_present()) { - j.write_fieldname("nprach-Config-v1550"); - nprach_cfg_v1550->to_json(j); + if (dl_carrier_freq_v1550.is_present()) { + j.write_fieldname("dl-CarrierFreq-v1550"); + dl_carrier_freq_v1550->to_json(j); } } j.end_obj(); } -// SC-MCCH-SchedulingInfo-NB-r14 ::= SEQUENCE -SRSASN_CODE sc_mcch_sched_info_nb_r14_s::pack(bit_ref& bref) const +const char* inter_freq_carrier_freq_info_nb_r13_s::pwr_class14dbm_offset_r14_opts::to_string() const { - bref.pack(ext, 1); - HANDLE_CODE(on_dur_timer_scptm_r14.pack(bref)); - HANDLE_CODE(drx_inactivity_timer_scptm_r14.pack(bref)); - HANDLE_CODE(sched_period_start_offset_scptm_r14.pack(bref)); + static const char* options[] = {"dB-6", "dB-3", "dB3", "dB6", "dB9", "dB12"}; + return convert_enum_idx(options, 6, value, "inter_freq_carrier_freq_info_nb_r13_s::pwr_class14dbm_offset_r14_e_"); +} +int8_t inter_freq_carrier_freq_info_nb_r13_s::pwr_class14dbm_offset_r14_opts::to_number() const +{ + static const int8_t options[] = {-6, -3, 3, 6, 9, 12}; + return map_enum_number(options, 6, value, "inter_freq_carrier_freq_info_nb_r13_s::pwr_class14dbm_offset_r14_e_"); +} + +const char* inter_freq_carrier_freq_info_nb_r13_s::ce_authorisation_offset_r14_opts::to_string() const +{ + static const char* options[] = {"dB5", "dB10", "dB15", "dB20", "dB25", "dB30", "dB35"}; + return convert_enum_idx(options, 7, value, "inter_freq_carrier_freq_info_nb_r13_s::ce_authorisation_offset_r14_e_"); +} +uint8_t inter_freq_carrier_freq_info_nb_r13_s::ce_authorisation_offset_r14_opts::to_number() const +{ + static const uint8_t options[] = {5, 10, 15, 20, 25, 30, 35}; + return map_enum_number(options, 7, value, "inter_freq_carrier_freq_info_nb_r13_s::ce_authorisation_offset_r14_e_"); +} + +// IntraFreqNeighCellInfo-NB-v1530 ::= SEQUENCE +SRSASN_CODE intra_freq_neigh_cell_info_nb_v1530_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(nsss_rrm_cfg_r15_present, 1)); + + if (nsss_rrm_cfg_r15_present) { + HANDLE_CODE(nsss_rrm_cfg_r15.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE sc_mcch_sched_info_nb_r14_s::unpack(cbit_ref& bref) +SRSASN_CODE intra_freq_neigh_cell_info_nb_v1530_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(on_dur_timer_scptm_r14.unpack(bref)); - HANDLE_CODE(drx_inactivity_timer_scptm_r14.unpack(bref)); - HANDLE_CODE(sched_period_start_offset_scptm_r14.unpack(bref)); + HANDLE_CODE(bref.unpack(nsss_rrm_cfg_r15_present, 1)); + + if (nsss_rrm_cfg_r15_present) { + HANDLE_CODE(nsss_rrm_cfg_r15.unpack(bref)); + } return SRSASN_SUCCESS; } -void sc_mcch_sched_info_nb_r14_s::to_json(json_writer& j) const +void intra_freq_neigh_cell_info_nb_v1530_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("onDurationTimerSCPTM-r14", on_dur_timer_scptm_r14.to_string()); - j.write_str("drx-InactivityTimerSCPTM-r14", drx_inactivity_timer_scptm_r14.to_string()); - j.write_fieldname("schedulingPeriodStartOffsetSCPTM-r14"); - sched_period_start_offset_scptm_r14.to_json(j); + if (nsss_rrm_cfg_r15_present) { + j.write_fieldname("nsss-RRM-Config-r15"); + nsss_rrm_cfg_r15.to_json(j); + } j.end_obj(); } -const char* sc_mcch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_opts::to_string() const +// MBMS-SAI-InterFreq-NB-r14 ::= SEQUENCE +SRSASN_CODE mbms_sai_inter_freq_nb_r14_s::pack(bit_ref& bref) const { - static const char* options[] = {"pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32", "spare"}; - return convert_enum_idx(options, 8, value, "sc_mcch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_e_"); + HANDLE_CODE(bref.pack(multi_band_info_list_r14_present, 1)); + + HANDLE_CODE(dl_carrier_freq_r14.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, mbms_sai_list_r14, 1, 64, integer_packer(0, 65535))); + if (multi_band_info_list_r14_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, multi_band_info_list_r14, 1, 8, integer_packer(1, 256))); + } + + return SRSASN_SUCCESS; } -uint8_t sc_mcch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_opts::to_number() const +SRSASN_CODE mbms_sai_inter_freq_nb_r14_s::unpack(cbit_ref& bref) { - static const uint8_t options[] = {1, 2, 3, 4, 8, 16, 32}; - return map_enum_number(options, 7, value, "sc_mcch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_e_"); + HANDLE_CODE(bref.unpack(multi_band_info_list_r14_present, 1)); + + HANDLE_CODE(dl_carrier_freq_r14.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(mbms_sai_list_r14, bref, 1, 64, integer_packer(0, 65535))); + if (multi_band_info_list_r14_present) { + HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r14, bref, 1, 8, integer_packer(1, 256))); + } + + return SRSASN_SUCCESS; +} +void mbms_sai_inter_freq_nb_r14_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("dl-CarrierFreq-r14"); + dl_carrier_freq_r14.to_json(j); + j.start_array("mbms-SAI-List-r14"); + for (const auto& e1 : mbms_sai_list_r14) { + j.write_int(e1); + } + j.end_array(); + if (multi_band_info_list_r14_present) { + j.start_array("multiBandInfoList-r14"); + for (const auto& e1 : multi_band_info_list_r14) { + j.write_int(e1); + } + j.end_array(); + } + j.end_obj(); } -const char* sc_mcch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_opts::to_string() const +// NPDSCH-ConfigCommon-NB-r13 ::= SEQUENCE +SRSASN_CODE npdsch_cfg_common_nb_r13_s::pack(bit_ref& bref) const { - static const char* options[] = {"pp0", "pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32"}; - return convert_enum_idx(options, 8, value, "sc_mcch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_e_"); + HANDLE_CODE(pack_integer(bref, nrs_pwr_r13, (int8_t)-60, (int8_t)50)); + + return SRSASN_SUCCESS; } -uint8_t sc_mcch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_opts::to_number() const +SRSASN_CODE npdsch_cfg_common_nb_r13_s::unpack(cbit_ref& bref) { - static const uint8_t options[] = {0, 1, 2, 3, 4, 8, 16, 32}; - return map_enum_number(options, 8, value, "sc_mcch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_e_"); + HANDLE_CODE(unpack_integer(nrs_pwr_r13, bref, (int8_t)-60, (int8_t)50)); + + return SRSASN_SUCCESS; +} +void npdsch_cfg_common_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("nrs-Power-r13", nrs_pwr_r13); + j.end_obj(); } -void sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::destroy_() {} -void sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set(types::options e) +// NPRACH-ConfigSIB-NB-r13 ::= SEQUENCE +SRSASN_CODE nprach_cfg_sib_nb_r13_s::pack(bit_ref& bref) const { - destroy_(); - type_ = e; + HANDLE_CODE(bref.pack(rsrp_thress_prach_info_list_r13_present, 1)); + + HANDLE_CODE(nprach_cp_len_r13.pack(bref)); + if (rsrp_thress_prach_info_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, rsrp_thress_prach_info_list_r13, 1, 2, integer_packer(0, 97))); + } + HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_r13, 1, 3)); + + return SRSASN_SUCCESS; } -sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::sched_period_start_offset_scptm_r14_c_( - const sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& other) +SRSASN_CODE nprach_cfg_sib_nb_r13_s::unpack(cbit_ref& bref) { - type_ = other.type(); - switch (type_) { - case types::sf10: - c.init(other.c.get()); - break; - case types::sf20: - c.init(other.c.get()); - break; - case types::sf32: - c.init(other.c.get()); - break; - case types::sf40: - c.init(other.c.get()); - break; - case types::sf64: - c.init(other.c.get()); - break; - case types::sf80: - c.init(other.c.get()); - break; - case types::sf128: - c.init(other.c.get()); - break; - case types::sf160: - c.init(other.c.get()); - break; - case types::sf256: - c.init(other.c.get()); - break; - case types::sf320: - c.init(other.c.get()); - break; - case types::sf512: - c.init(other.c.get()); - break; - case types::sf640: - c.init(other.c.get()); - break; - case types::sf1024: - c.init(other.c.get()); - break; - case types::sf2048: - c.init(other.c.get()); - break; - case types::sf4096: - c.init(other.c.get()); - break; - case types::sf8192: - c.init(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + HANDLE_CODE(bref.unpack(rsrp_thress_prach_info_list_r13_present, 1)); + + HANDLE_CODE(nprach_cp_len_r13.unpack(bref)); + if (rsrp_thress_prach_info_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(rsrp_thress_prach_info_list_r13, bref, 1, 2, integer_packer(0, 97))); } + HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_r13, bref, 1, 3)); + + return SRSASN_SUCCESS; } -sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& -sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::operator=( - const sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& other) +void nprach_cfg_sib_nb_r13_s::to_json(json_writer& j) const { - if (this == &other) { - return *this; + j.start_obj(); + j.write_str("nprach-CP-Length-r13", nprach_cp_len_r13.to_string()); + if (rsrp_thress_prach_info_list_r13_present) { + j.start_array("rsrp-ThresholdsPrachInfoList-r13"); + for (const auto& e1 : rsrp_thress_prach_info_list_r13) { + j.write_int(e1); + } + j.end_array(); } - set(other.type()); - switch (type_) { - case types::sf10: - c.set(other.c.get()); - break; - case types::sf20: - c.set(other.c.get()); - break; - case types::sf32: - c.set(other.c.get()); - break; - case types::sf40: - c.set(other.c.get()); - break; - case types::sf64: - c.set(other.c.get()); - break; - case types::sf80: - c.set(other.c.get()); - break; - case types::sf128: - c.set(other.c.get()); - break; - case types::sf160: - c.set(other.c.get()); - break; - case types::sf256: - c.set(other.c.get()); - break; - case types::sf320: - c.set(other.c.get()); - break; - case types::sf512: - c.set(other.c.get()); - break; - case types::sf640: - c.set(other.c.get()); - break; - case types::sf1024: - c.set(other.c.get()); - break; - case types::sf2048: - c.set(other.c.get()); - break; - case types::sf4096: - c.set(other.c.get()); - break; - case types::sf8192: - c.set(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + j.start_array("nprach-ParametersList-r13"); + for (const auto& e1 : nprach_params_list_r13) { + e1.to_json(j); } - - return *this; + j.end_array(); + j.end_obj(); } -uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf10() + +const char* nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_opts::to_string() const { - set(types::sf10); - return c.get(); + static const char* options[] = {"us66dot7", "us266dot7"}; + return convert_enum_idx(options, 2, value, "nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_e_"); } -uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf20() +float nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_opts::to_number() const { - set(types::sf20); - return c.get(); + static const float options[] = {66.7, 266.7}; + return map_enum_number(options, 2, value, "nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_e_"); } -uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf32() +const char* nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_opts::to_number_string() const { - set(types::sf32); - return c.get(); + static const char* options[] = {"66.7", "266.7"}; + return convert_enum_idx(options, 2, value, "nprach_cfg_sib_nb_r13_s::nprach_cp_len_r13_e_"); } -uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf40() + +// NPRACH-ConfigSIB-NB-v1330 ::= SEQUENCE +SRSASN_CODE nprach_cfg_sib_nb_v1330_s::pack(bit_ref& bref) const { - set(types::sf40); - return c.get(); + HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_v1330, 1, 3)); + + return SRSASN_SUCCESS; } -uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf64() +SRSASN_CODE nprach_cfg_sib_nb_v1330_s::unpack(cbit_ref& bref) { - set(types::sf64); - return c.get(); + HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_v1330, bref, 1, 3)); + + return SRSASN_SUCCESS; } -uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf80() +void nprach_cfg_sib_nb_v1330_s::to_json(json_writer& j) const { - set(types::sf80); - return c.get(); + j.start_obj(); + j.start_array("nprach-ParametersList-v1330"); + for (const auto& e1 : nprach_params_list_v1330) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); } -uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf128() + +// NPRACH-ConfigSIB-NB-v1450 ::= SEQUENCE +SRSASN_CODE nprach_cfg_sib_nb_v1450_s::pack(bit_ref& bref) const { - set(types::sf128); - return c.get(); + HANDLE_CODE(max_num_preamb_attempt_ce_r14.pack(bref)); + + return SRSASN_SUCCESS; } -uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf160() +SRSASN_CODE nprach_cfg_sib_nb_v1450_s::unpack(cbit_ref& bref) { - set(types::sf160); - return c.get(); + HANDLE_CODE(max_num_preamb_attempt_ce_r14.unpack(bref)); + + return SRSASN_SUCCESS; } -uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf256() +void nprach_cfg_sib_nb_v1450_s::to_json(json_writer& j) const { - set(types::sf256); - return c.get(); + j.start_obj(); + j.write_str("maxNumPreambleAttemptCE-r14", max_num_preamb_attempt_ce_r14.to_string()); + j.end_obj(); } -uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf320() + +const char* nprach_cfg_sib_nb_v1450_s::max_num_preamb_attempt_ce_r14_opts::to_string() const { - set(types::sf320); - return c.get(); + static const char* options[] = {"n3", "n4", "n5", "n6", "n7", "n8", "n10", "spare1"}; + return convert_enum_idx(options, 8, value, "nprach_cfg_sib_nb_v1450_s::max_num_preamb_attempt_ce_r14_e_"); } -uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf512() +uint8_t nprach_cfg_sib_nb_v1450_s::max_num_preamb_attempt_ce_r14_opts::to_number() const { - set(types::sf512); - return c.get(); + static const uint8_t options[] = {3, 4, 5, 6, 7, 8, 10}; + return map_enum_number(options, 7, value, "nprach_cfg_sib_nb_v1450_s::max_num_preamb_attempt_ce_r14_e_"); } -uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf640() + +// NPRACH-ConfigSIB-NB-v1530 ::= SEQUENCE +SRSASN_CODE nprach_cfg_sib_nb_v1530_s::pack(bit_ref& bref) const { - set(types::sf640); - return c.get(); + HANDLE_CODE(bref.pack(tdd_params_r15_present, 1)); + HANDLE_CODE(bref.pack(fmt2_params_r15_present, 1)); + HANDLE_CODE(bref.pack(edt_params_r15_present, 1)); + + if (tdd_params_r15_present) { + HANDLE_CODE(tdd_params_r15.nprach_preamb_format_r15.pack(bref)); + HANDLE_CODE(tdd_params_r15.dummy.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, tdd_params_r15.nprach_params_list_tdd_r15, 1, 3)); + } + if (fmt2_params_r15_present) { + HANDLE_CODE(bref.pack(fmt2_params_r15.nprach_params_list_fmt2_r15_present, 1)); + HANDLE_CODE(bref.pack(fmt2_params_r15.nprach_params_list_fmt2_edt_r15_present, 1)); + if (fmt2_params_r15.nprach_params_list_fmt2_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, fmt2_params_r15.nprach_params_list_fmt2_r15, 1, 3)); + } + if (fmt2_params_r15.nprach_params_list_fmt2_edt_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, fmt2_params_r15.nprach_params_list_fmt2_edt_r15, 1, 3)); + } + } + if (edt_params_r15_present) { + HANDLE_CODE(bref.pack(edt_params_r15.edt_small_tbs_subset_r15_present, 1)); + HANDLE_CODE(bref.pack(edt_params_r15.nprach_params_list_edt_r15_present, 1)); + HANDLE_CODE(pack_dyn_seq_of(bref, edt_params_r15.edt_tbs_info_list_r15, 1, 3)); + if (edt_params_r15.nprach_params_list_edt_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, edt_params_r15.nprach_params_list_edt_r15, 1, 3)); + } + } + + return SRSASN_SUCCESS; } -uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf1024() +SRSASN_CODE nprach_cfg_sib_nb_v1530_s::unpack(cbit_ref& bref) { - set(types::sf1024); - return c.get(); + HANDLE_CODE(bref.unpack(tdd_params_r15_present, 1)); + HANDLE_CODE(bref.unpack(fmt2_params_r15_present, 1)); + HANDLE_CODE(bref.unpack(edt_params_r15_present, 1)); + + if (tdd_params_r15_present) { + HANDLE_CODE(tdd_params_r15.nprach_preamb_format_r15.unpack(bref)); + HANDLE_CODE(tdd_params_r15.dummy.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(tdd_params_r15.nprach_params_list_tdd_r15, bref, 1, 3)); + } + if (fmt2_params_r15_present) { + HANDLE_CODE(bref.unpack(fmt2_params_r15.nprach_params_list_fmt2_r15_present, 1)); + HANDLE_CODE(bref.unpack(fmt2_params_r15.nprach_params_list_fmt2_edt_r15_present, 1)); + if (fmt2_params_r15.nprach_params_list_fmt2_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(fmt2_params_r15.nprach_params_list_fmt2_r15, bref, 1, 3)); + } + if (fmt2_params_r15.nprach_params_list_fmt2_edt_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(fmt2_params_r15.nprach_params_list_fmt2_edt_r15, bref, 1, 3)); + } + } + if (edt_params_r15_present) { + HANDLE_CODE(bref.unpack(edt_params_r15.edt_small_tbs_subset_r15_present, 1)); + HANDLE_CODE(bref.unpack(edt_params_r15.nprach_params_list_edt_r15_present, 1)); + HANDLE_CODE(unpack_dyn_seq_of(edt_params_r15.edt_tbs_info_list_r15, bref, 1, 3)); + if (edt_params_r15.nprach_params_list_edt_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(edt_params_r15.nprach_params_list_edt_r15, bref, 1, 3)); + } + } + + return SRSASN_SUCCESS; } -uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf2048() +void nprach_cfg_sib_nb_v1530_s::to_json(json_writer& j) const { - set(types::sf2048); - return c.get(); + j.start_obj(); + if (tdd_params_r15_present) { + j.write_fieldname("tdd-Parameters-r15"); + j.start_obj(); + j.write_str("nprach-PreambleFormat-r15", tdd_params_r15.nprach_preamb_format_r15.to_string()); + j.write_str("dummy", tdd_params_r15.dummy.to_string()); + j.start_array("nprach-ParametersListTDD-r15"); + for (const auto& e1 : tdd_params_r15.nprach_params_list_tdd_r15) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); + } + if (fmt2_params_r15_present) { + j.write_fieldname("fmt2-Parameters-r15"); + j.start_obj(); + if (fmt2_params_r15.nprach_params_list_fmt2_r15_present) { + j.start_array("nprach-ParametersListFmt2-r15"); + for (const auto& e1 : fmt2_params_r15.nprach_params_list_fmt2_r15) { + e1.to_json(j); + } + j.end_array(); + } + if (fmt2_params_r15.nprach_params_list_fmt2_edt_r15_present) { + j.start_array("nprach-ParametersListFmt2EDT-r15"); + for (const auto& e1 : fmt2_params_r15.nprach_params_list_fmt2_edt_r15) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); + } + if (edt_params_r15_present) { + j.write_fieldname("edt-Parameters-r15"); + j.start_obj(); + if (edt_params_r15.edt_small_tbs_subset_r15_present) { + j.write_str("edt-SmallTBS-Subset-r15", "true"); + } + j.start_array("edt-TBS-InfoList-r15"); + for (const auto& e1 : edt_params_r15.edt_tbs_info_list_r15) { + e1.to_json(j); + } + j.end_array(); + if (edt_params_r15.nprach_params_list_edt_r15_present) { + j.start_array("nprach-ParametersListEDT-r15"); + for (const auto& e1 : edt_params_r15.nprach_params_list_edt_r15) { + e1.to_json(j); + } + j.end_array(); + } + j.end_obj(); + } + j.end_obj(); } -uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf4096() + +const char* nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::nprach_preamb_format_r15_opts::to_string() const { - set(types::sf4096); - return c.get(); + static const char* options[] = {"fmt0", "fmt1", "fmt2", "fmt0-a", "fmt1-a"}; + return convert_enum_idx( + options, 5, value, "nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::nprach_preamb_format_r15_e_"); } -uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf8192() + +const char* nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::dummy_opts::to_string() const { - set(types::sf8192); - return c.get(); + static const char* options[] = {"n1", "n2", "n4", "n8", "n16", "n32", "n64", "n128", "n256", "n512", "n1024"}; + return convert_enum_idx(options, 11, value, "nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::dummy_e_"); } -void sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::to_json(json_writer& j) const +uint16_t nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::dummy_opts::to_number() const +{ + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}; + return map_enum_number(options, 11, value, "nprach_cfg_sib_nb_v1530_s::tdd_params_r15_s_::dummy_e_"); +} + +// NPRACH-ConfigSIB-NB-v1550 ::= SEQUENCE +SRSASN_CODE nprach_cfg_sib_nb_v1550_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_dyn_seq_of(bref, tdd_params_v1550.nprach_params_list_tdd_v1550, 1, 3)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE nprach_cfg_sib_nb_v1550_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_dyn_seq_of(tdd_params_v1550.nprach_params_list_tdd_v1550, bref, 1, 3)); + + return SRSASN_SUCCESS; +} +void nprach_cfg_sib_nb_v1550_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::sf10: - j.write_int("sf10", c.get()); - break; - case types::sf20: - j.write_int("sf20", c.get()); - break; - case types::sf32: - j.write_int("sf32", c.get()); - break; - case types::sf40: - j.write_int("sf40", c.get()); - break; - case types::sf64: - j.write_int("sf64", c.get()); - break; - case types::sf80: - j.write_int("sf80", c.get()); - break; - case types::sf128: - j.write_int("sf128", c.get()); - break; - case types::sf160: - j.write_int("sf160", c.get()); - break; - case types::sf256: - j.write_int("sf256", c.get()); - break; - case types::sf320: - j.write_int("sf320", c.get()); - break; - case types::sf512: - j.write_int("sf512", c.get()); - break; - case types::sf640: - j.write_int("sf640", c.get()); - break; - case types::sf1024: - j.write_int("sf1024", c.get()); - break; - case types::sf2048: - j.write_int("sf2048", c.get()); - break; - case types::sf4096: - j.write_int("sf4096", c.get()); - break; - case types::sf8192: - j.write_int("sf8192", c.get()); - break; - default: - log_invalid_choice_id(type_, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + j.write_fieldname("tdd-Parameters-v1550"); + j.start_obj(); + j.start_array("nprach-ParametersListTDD-v1550"); + for (const auto& e1 : tdd_params_v1550.nprach_params_list_tdd_v1550) { + e1.to_json(j); } + j.end_array(); + j.end_obj(); j.end_obj(); } -SRSASN_CODE sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::pack(bit_ref& bref) const + +// NPRACH-ProbabilityAnchor-NB-r14 ::= SEQUENCE +SRSASN_CODE nprach_probability_anchor_nb_r14_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::sf10: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)9u)); - break; - case types::sf20: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)19u)); - break; - case types::sf32: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)31u)); - break; - case types::sf40: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)39u)); - break; - case types::sf64: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)63u)); - break; - case types::sf80: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)79u)); - break; - case types::sf128: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); - break; - case types::sf160: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)159u)); - break; - case types::sf256: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u)); - break; - case types::sf320: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)319u)); - break; - case types::sf512: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)511u)); - break; - case types::sf640: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)639u)); - break; - case types::sf1024: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1023u)); - break; - case types::sf2048: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)2047u)); - break; - case types::sf4096: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u)); - break; - case types::sf8192: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)8191u)); - break; - default: - log_invalid_choice_id(type_, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); - return SRSASN_ERROR_ENCODE_FAIL; + HANDLE_CODE(bref.pack(nprach_probability_anchor_r14_present, 1)); + + if (nprach_probability_anchor_r14_present) { + HANDLE_CODE(nprach_probability_anchor_r14.pack(bref)); } + return SRSASN_SUCCESS; } -SRSASN_CODE sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::unpack(cbit_ref& bref) +SRSASN_CODE nprach_probability_anchor_nb_r14_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::sf10: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)9u)); - break; - case types::sf20: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)19u)); - break; - case types::sf32: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)31u)); - break; - case types::sf40: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)39u)); - break; - case types::sf64: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)63u)); - break; - case types::sf80: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)79u)); - break; - case types::sf128: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); - break; - case types::sf160: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)159u)); - break; - case types::sf256: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u)); - break; - case types::sf320: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)319u)); - break; - case types::sf512: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)511u)); - break; - case types::sf640: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)639u)); - break; - case types::sf1024: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1023u)); - break; - case types::sf2048: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)2047u)); - break; - case types::sf4096: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u)); - break; - case types::sf8192: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)8191u)); - break; - default: - log_invalid_choice_id(type_, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); - return SRSASN_ERROR_DECODE_FAIL; + HANDLE_CODE(bref.unpack(nprach_probability_anchor_r14_present, 1)); + + if (nprach_probability_anchor_r14_present) { + HANDLE_CODE(nprach_probability_anchor_r14.unpack(bref)); } + return SRSASN_SUCCESS; } +void nprach_probability_anchor_nb_r14_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (nprach_probability_anchor_r14_present) { + j.write_str("nprach-ProbabilityAnchor-r14", nprach_probability_anchor_r14.to_string()); + } + j.end_obj(); +} -const char* sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types_opts::to_string() const +const char* nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_opts::to_string() const { - static const char* options[] = {"sf10", - "sf20", - "sf32", - "sf40", - "sf64", - "sf80", - "sf128", - "sf160", - "sf256", - "sf320", - "sf512", - "sf640", - "sf1024", - "sf2048", - "sf4096", - "sf8192"}; - return convert_enum_idx( - options, 16, value, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types"); + static const char* options[] = {"zero", + "oneSixteenth", + "oneFifteenth", + "oneFourteenth", + "oneThirteenth", + "oneTwelfth", + "oneEleventh", + "oneTenth", + "oneNinth", + "oneEighth", + "oneSeventh", + "oneSixth", + "oneFifth", + "oneFourth", + "oneThird", + "oneHalf"}; + return convert_enum_idx(options, 16, value, "nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_e_"); } -uint16_t sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types_opts::to_number() const +float nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_opts::to_number() const { - static const uint16_t options[] = {10, 20, 32, 40, 64, 80, 128, 160, 256, 320, 512, 640, 1024, 2048, 4096, 8192}; - return map_enum_number( - options, 16, value, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types"); + static const float options[] = {0.0, + 0.0625, + 0.06666666666666667, + 0.07142857142857142, + 0.07692307692307693, + 0.08333333333333333, + 0.09090909090909091, + 0.1, + 0.1111111111111111, + 0.125, + 0.14285714285714285, + 0.16666666666666666, + 0.2, + 0.25, + 0.3333333333333333, + 0.5}; + return map_enum_number(options, 16, value, "nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_e_"); } - -// SystemInformationBlockType1-NB-v1450 ::= SEQUENCE -SRSASN_CODE sib_type1_nb_v1450_s::pack(bit_ref& bref) const +const char* nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_opts::to_number_string() const { - HANDLE_CODE(bref.pack(nrs_crs_pwr_offset_v1450_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + static const char* options[] = {"0", + "1/16", + "1/15", + "1/14", + "1/13", + "1/12", + "1/11", + "1/10", + "1/9", + "1/8", + "1/7", + "1/6", + "1/5", + "1/4", + "1/3", + "1/2"}; + return convert_enum_idx(options, 16, value, "nprach_probability_anchor_nb_r14_s::nprach_probability_anchor_r14_e_"); +} - if (nrs_crs_pwr_offset_v1450_present) { - HANDLE_CODE(nrs_crs_pwr_offset_v1450.pack(bref)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); - } +// NPRACH-TxDurationFmt01-NB-r17 ::= SEQUENCE +SRSASN_CODE nprach_tx_dur_fmt01_nb_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(nprach_tx_dur_fmt01_r17.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE sib_type1_nb_v1450_s::unpack(cbit_ref& bref) +SRSASN_CODE nprach_tx_dur_fmt01_nb_r17_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(nrs_crs_pwr_offset_v1450_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - if (nrs_crs_pwr_offset_v1450_present) { - HANDLE_CODE(nrs_crs_pwr_offset_v1450.unpack(bref)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); - } + HANDLE_CODE(nprach_tx_dur_fmt01_r17.unpack(bref)); return SRSASN_SUCCESS; } -void sib_type1_nb_v1450_s::to_json(json_writer& j) const +void nprach_tx_dur_fmt01_nb_r17_s::to_json(json_writer& j) const { j.start_obj(); - if (nrs_crs_pwr_offset_v1450_present) { - j.write_str("nrs-CRS-PowerOffset-v1450", nrs_crs_pwr_offset_v1450.to_string()); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); - } + j.write_str("nprach-TxDurationFmt01-r17", nprach_tx_dur_fmt01_r17.to_string()); j.end_obj(); } -const char* sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_opts::to_string() const +const char* nprach_tx_dur_fmt01_nb_r17_s::nprach_tx_dur_fmt01_r17_opts::to_string() const { - static const char* options[] = {"dB-6", - "dB-4dot77", - "dB-3", - "dB-1dot77", - "dB0", - "dB1", - "dB1dot23", - "dB2", - "dB3", - "dB4", - "dB4dot23", - "dB5", - "dB6", - "dB7", - "dB8", - "dB9"}; - return convert_enum_idx(options, 16, value, "sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_e_"); + static const char* options[] = {"n2", "n4", "n8", "n16", "n32", "n64"}; + return convert_enum_idx(options, 6, value, "nprach_tx_dur_fmt01_nb_r17_s::nprach_tx_dur_fmt01_r17_e_"); } -float sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_opts::to_number() const +uint8_t nprach_tx_dur_fmt01_nb_r17_s::nprach_tx_dur_fmt01_r17_opts::to_number() const { - static const float options[] = { - -6.0, -4.77, -3.0, -1.77, 0.0, 1.0, 1.23, 2.0, 3.0, 4.0, 4.23, 5.0, 6.0, 7.0, 8.0, 9.0}; - return map_enum_number(options, 16, value, "sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_e_"); + static const uint8_t options[] = {2, 4, 8, 16, 32, 64}; + return map_enum_number(options, 6, value, "nprach_tx_dur_fmt01_nb_r17_s::nprach_tx_dur_fmt01_r17_e_"); } -const char* sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_opts::to_number_string() const + +// NPRACH-TxDurationFmt2-NB-r17 ::= SEQUENCE +SRSASN_CODE nprach_tx_dur_fmt2_nb_r17_s::pack(bit_ref& bref) const { - static const char* options[] = { - "-6", "-4.77", "-3", "-1.77", "0", "1", "1.23", "2", "3", "4", "4.23", "5", "6", "7", "8", "9"}; - return convert_enum_idx(options, 16, value, "sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_e_"); -} + HANDLE_CODE(nprach_tx_dur_fmt2_r17.pack(bref)); -// T-Reselection-NB-r13 ::= ENUMERATED -const char* t_resel_nb_r13_opts::to_string() const + return SRSASN_SUCCESS; +} +SRSASN_CODE nprach_tx_dur_fmt2_nb_r17_s::unpack(cbit_ref& bref) { - static const char* options[] = {"s0", "s3", "s6", "s9", "s12", "s15", "s18", "s21"}; - return convert_enum_idx(options, 8, value, "t_resel_nb_r13_e"); + HANDLE_CODE(nprach_tx_dur_fmt2_r17.unpack(bref)); + + return SRSASN_SUCCESS; } -uint8_t t_resel_nb_r13_opts::to_number() const +void nprach_tx_dur_fmt2_nb_r17_s::to_json(json_writer& j) const { - static const uint8_t options[] = {0, 3, 6, 9, 12, 15, 18, 21}; - return map_enum_number(options, 8, value, "t_resel_nb_r13_e"); + j.start_obj(); + j.write_str("nprach-TxDurationFmt2-r17", nprach_tx_dur_fmt2_r17.to_string()); + j.end_obj(); } -// UE-TimersAndConstants-NB-r13 ::= SEQUENCE -SRSASN_CODE ue_timers_and_consts_nb_r13_s::pack(bit_ref& bref) const +const char* nprach_tx_dur_fmt2_nb_r17_s::nprach_tx_dur_fmt2_r17_opts::to_string() const { - bref.pack(ext, 1); - HANDLE_CODE(t300_r13.pack(bref)); - HANDLE_CODE(t301_r13.pack(bref)); - HANDLE_CODE(t310_r13.pack(bref)); - HANDLE_CODE(n310_r13.pack(bref)); - HANDLE_CODE(t311_r13.pack(bref)); - HANDLE_CODE(n311_r13.pack(bref)); - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= t311_v1350_present; - group_flags[1] |= t300_v1530_present; - group_flags[1] |= t301_v1530_present; - group_flags[1] |= t311_v1530_present; - group_flags[1] |= t300_r15_present; - group_flags.pack(bref); + static const char* options[] = {"n1", "n2", "n4", "n8", "n16"}; + return convert_enum_idx(options, 5, value, "nprach_tx_dur_fmt2_nb_r17_s::nprach_tx_dur_fmt2_r17_e_"); +} +uint8_t nprach_tx_dur_fmt2_nb_r17_s::nprach_tx_dur_fmt2_r17_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 4, 8, 16}; + return map_enum_number(options, 5, value, "nprach_tx_dur_fmt2_nb_r17_s::nprach_tx_dur_fmt2_r17_e_"); +} - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); +// NPUSCH-ConfigCommon-NB-r13 ::= SEQUENCE +SRSASN_CODE npusch_cfg_common_nb_r13_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(srs_sf_cfg_r13_present, 1)); + HANDLE_CODE(bref.pack(dmrs_cfg_r13_present, 1)); - HANDLE_CODE(bref.pack(t311_v1350_present, 1)); - if (t311_v1350_present) { - HANDLE_CODE(t311_v1350.pack(bref)); - } + HANDLE_CODE(pack_dyn_seq_of(bref, ack_nack_num_repeats_msg4_r13, 1, 3)); + if (srs_sf_cfg_r13_present) { + HANDLE_CODE(srs_sf_cfg_r13.pack(bref)); + } + if (dmrs_cfg_r13_present) { + HANDLE_CODE(bref.pack(dmrs_cfg_r13.three_tone_base_seq_r13_present, 1)); + HANDLE_CODE(bref.pack(dmrs_cfg_r13.six_tone_base_seq_r13_present, 1)); + HANDLE_CODE(bref.pack(dmrs_cfg_r13.twelve_tone_base_seq_r13_present, 1)); + if (dmrs_cfg_r13.three_tone_base_seq_r13_present) { + HANDLE_CODE(pack_integer(bref, dmrs_cfg_r13.three_tone_base_seq_r13, (uint8_t)0u, (uint8_t)12u)); } - if (group_flags[1]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(t300_v1530_present, 1)); - HANDLE_CODE(bref.pack(t301_v1530_present, 1)); - HANDLE_CODE(bref.pack(t311_v1530_present, 1)); - HANDLE_CODE(bref.pack(t300_r15_present, 1)); - if (t300_v1530_present) { - HANDLE_CODE(t300_v1530.pack(bref)); - } - if (t301_v1530_present) { - HANDLE_CODE(t301_v1530.pack(bref)); - } - if (t311_v1530_present) { - HANDLE_CODE(t311_v1530.pack(bref)); - } - if (t300_r15_present) { - HANDLE_CODE(t300_r15.pack(bref)); - } + HANDLE_CODE(pack_integer(bref, dmrs_cfg_r13.three_tone_cyclic_shift_r13, (uint8_t)0u, (uint8_t)2u)); + if (dmrs_cfg_r13.six_tone_base_seq_r13_present) { + HANDLE_CODE(pack_integer(bref, dmrs_cfg_r13.six_tone_base_seq_r13, (uint8_t)0u, (uint8_t)14u)); + } + HANDLE_CODE(pack_integer(bref, dmrs_cfg_r13.six_tone_cyclic_shift_r13, (uint8_t)0u, (uint8_t)3u)); + if (dmrs_cfg_r13.twelve_tone_base_seq_r13_present) { + HANDLE_CODE(pack_integer(bref, dmrs_cfg_r13.twelve_tone_base_seq_r13, (uint8_t)0u, (uint8_t)30u)); } } + HANDLE_CODE(ul_ref_sigs_npusch_r13.pack(bref)); + return SRSASN_SUCCESS; } -SRSASN_CODE ue_timers_and_consts_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE npusch_cfg_common_nb_r13_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(t300_r13.unpack(bref)); - HANDLE_CODE(t301_r13.unpack(bref)); - HANDLE_CODE(t310_r13.unpack(bref)); - HANDLE_CODE(n310_r13.unpack(bref)); - HANDLE_CODE(t311_r13.unpack(bref)); - HANDLE_CODE(n311_r13.unpack(bref)); + HANDLE_CODE(bref.unpack(srs_sf_cfg_r13_present, 1)); + HANDLE_CODE(bref.unpack(dmrs_cfg_r13_present, 1)); - if (ext) { - ext_groups_unpacker_guard group_flags(2); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.unpack(t311_v1350_present, 1)); - if (t311_v1350_present) { - HANDLE_CODE(t311_v1350.unpack(bref)); - } + HANDLE_CODE(unpack_dyn_seq_of(ack_nack_num_repeats_msg4_r13, bref, 1, 3)); + if (srs_sf_cfg_r13_present) { + HANDLE_CODE(srs_sf_cfg_r13.unpack(bref)); + } + if (dmrs_cfg_r13_present) { + HANDLE_CODE(bref.unpack(dmrs_cfg_r13.three_tone_base_seq_r13_present, 1)); + HANDLE_CODE(bref.unpack(dmrs_cfg_r13.six_tone_base_seq_r13_present, 1)); + HANDLE_CODE(bref.unpack(dmrs_cfg_r13.twelve_tone_base_seq_r13_present, 1)); + if (dmrs_cfg_r13.three_tone_base_seq_r13_present) { + HANDLE_CODE(unpack_integer(dmrs_cfg_r13.three_tone_base_seq_r13, bref, (uint8_t)0u, (uint8_t)12u)); } - if (group_flags[1]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.unpack(t300_v1530_present, 1)); - HANDLE_CODE(bref.unpack(t301_v1530_present, 1)); - HANDLE_CODE(bref.unpack(t311_v1530_present, 1)); - HANDLE_CODE(bref.unpack(t300_r15_present, 1)); - if (t300_v1530_present) { - HANDLE_CODE(t300_v1530.unpack(bref)); - } - if (t301_v1530_present) { - HANDLE_CODE(t301_v1530.unpack(bref)); - } - if (t311_v1530_present) { - HANDLE_CODE(t311_v1530.unpack(bref)); - } - if (t300_r15_present) { - HANDLE_CODE(t300_r15.unpack(bref)); - } + HANDLE_CODE(unpack_integer(dmrs_cfg_r13.three_tone_cyclic_shift_r13, bref, (uint8_t)0u, (uint8_t)2u)); + if (dmrs_cfg_r13.six_tone_base_seq_r13_present) { + HANDLE_CODE(unpack_integer(dmrs_cfg_r13.six_tone_base_seq_r13, bref, (uint8_t)0u, (uint8_t)14u)); + } + HANDLE_CODE(unpack_integer(dmrs_cfg_r13.six_tone_cyclic_shift_r13, bref, (uint8_t)0u, (uint8_t)3u)); + if (dmrs_cfg_r13.twelve_tone_base_seq_r13_present) { + HANDLE_CODE(unpack_integer(dmrs_cfg_r13.twelve_tone_base_seq_r13, bref, (uint8_t)0u, (uint8_t)30u)); } } + HANDLE_CODE(ul_ref_sigs_npusch_r13.unpack(bref)); + return SRSASN_SUCCESS; } -void ue_timers_and_consts_nb_r13_s::to_json(json_writer& j) const +void npusch_cfg_common_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("t300-r13", t300_r13.to_string()); - j.write_str("t301-r13", t301_r13.to_string()); - j.write_str("t310-r13", t310_r13.to_string()); - j.write_str("n310-r13", n310_r13.to_string()); - j.write_str("t311-r13", t311_r13.to_string()); - j.write_str("n311-r13", n311_r13.to_string()); - if (ext) { - if (t311_v1350_present) { - j.write_str("t311-v1350", t311_v1350.to_string()); - } - if (t300_v1530_present) { - j.write_str("t300-v1530", t300_v1530.to_string()); - } - if (t301_v1530_present) { - j.write_str("t301-v1530", t301_v1530.to_string()); + j.start_array("ack-NACK-NumRepetitions-Msg4-r13"); + for (const auto& e1 : ack_nack_num_repeats_msg4_r13) { + j.write_str(e1.to_string()); + } + j.end_array(); + if (srs_sf_cfg_r13_present) { + j.write_str("srs-SubframeConfig-r13", srs_sf_cfg_r13.to_string()); + } + if (dmrs_cfg_r13_present) { + j.write_fieldname("dmrs-Config-r13"); + j.start_obj(); + if (dmrs_cfg_r13.three_tone_base_seq_r13_present) { + j.write_int("threeTone-BaseSequence-r13", dmrs_cfg_r13.three_tone_base_seq_r13); } - if (t311_v1530_present) { - j.write_str("t311-v1530", t311_v1530.to_string()); + j.write_int("threeTone-CyclicShift-r13", dmrs_cfg_r13.three_tone_cyclic_shift_r13); + if (dmrs_cfg_r13.six_tone_base_seq_r13_present) { + j.write_int("sixTone-BaseSequence-r13", dmrs_cfg_r13.six_tone_base_seq_r13); } - if (t300_r15_present) { - j.write_str("t300-r15", t300_r15.to_string()); + j.write_int("sixTone-CyclicShift-r13", dmrs_cfg_r13.six_tone_cyclic_shift_r13); + if (dmrs_cfg_r13.twelve_tone_base_seq_r13_present) { + j.write_int("twelveTone-BaseSequence-r13", dmrs_cfg_r13.twelve_tone_base_seq_r13); } + j.end_obj(); } + j.write_fieldname("ul-ReferenceSignalsNPUSCH-r13"); + ul_ref_sigs_npusch_r13.to_json(j); j.end_obj(); } -const char* ue_timers_and_consts_nb_r13_s::t300_r13_opts::to_string() const +const char* npusch_cfg_common_nb_r13_s::srs_sf_cfg_r13_opts::to_string() const { - static const char* options[] = {"ms2500", "ms4000", "ms6000", "ms10000", "ms15000", "ms25000", "ms40000", "ms60000"}; - return convert_enum_idx(options, 8, value, "ue_timers_and_consts_nb_r13_s::t300_r13_e_"); + static const char* options[] = {"sc0", + "sc1", + "sc2", + "sc3", + "sc4", + "sc5", + "sc6", + "sc7", + "sc8", + "sc9", + "sc10", + "sc11", + "sc12", + "sc13", + "sc14", + "sc15"}; + return convert_enum_idx(options, 16, value, "npusch_cfg_common_nb_r13_s::srs_sf_cfg_r13_e_"); } -uint16_t ue_timers_and_consts_nb_r13_s::t300_r13_opts::to_number() const +uint8_t npusch_cfg_common_nb_r13_s::srs_sf_cfg_r13_opts::to_number() const { - static const uint16_t options[] = {2500, 4000, 6000, 10000, 15000, 25000, 40000, 60000}; - return map_enum_number(options, 8, value, "ue_timers_and_consts_nb_r13_s::t300_r13_e_"); + static const uint8_t options[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + return map_enum_number(options, 16, value, "npusch_cfg_common_nb_r13_s::srs_sf_cfg_r13_e_"); } -const char* ue_timers_and_consts_nb_r13_s::t301_r13_opts::to_string() const -{ - static const char* options[] = {"ms2500", "ms4000", "ms6000", "ms10000", "ms15000", "ms25000", "ms40000", "ms60000"}; - return convert_enum_idx(options, 8, value, "ue_timers_and_consts_nb_r13_s::t301_r13_e_"); -} -uint16_t ue_timers_and_consts_nb_r13_s::t301_r13_opts::to_number() const +// PCCH-Config-NB-r13 ::= SEQUENCE +SRSASN_CODE pcch_cfg_nb_r13_s::pack(bit_ref& bref) const { - static const uint16_t options[] = {2500, 4000, 6000, 10000, 15000, 25000, 40000, 60000}; - return map_enum_number(options, 8, value, "ue_timers_and_consts_nb_r13_s::t301_r13_e_"); -} + HANDLE_CODE(default_paging_cycle_r13.pack(bref)); + HANDLE_CODE(nb_r13.pack(bref)); + HANDLE_CODE(npdcch_num_repeat_paging_r13.pack(bref)); -const char* ue_timers_and_consts_nb_r13_s::t310_r13_opts::to_string() const -{ - static const char* options[] = {"ms0", "ms200", "ms500", "ms1000", "ms2000", "ms4000", "ms8000"}; - return convert_enum_idx(options, 7, value, "ue_timers_and_consts_nb_r13_s::t310_r13_e_"); + return SRSASN_SUCCESS; } -uint16_t ue_timers_and_consts_nb_r13_s::t310_r13_opts::to_number() const +SRSASN_CODE pcch_cfg_nb_r13_s::unpack(cbit_ref& bref) { - static const uint16_t options[] = {0, 200, 500, 1000, 2000, 4000, 8000}; - return map_enum_number(options, 7, value, "ue_timers_and_consts_nb_r13_s::t310_r13_e_"); -} + HANDLE_CODE(default_paging_cycle_r13.unpack(bref)); + HANDLE_CODE(nb_r13.unpack(bref)); + HANDLE_CODE(npdcch_num_repeat_paging_r13.unpack(bref)); -const char* ue_timers_and_consts_nb_r13_s::n310_r13_opts::to_string() const -{ - static const char* options[] = {"n1", "n2", "n3", "n4", "n6", "n8", "n10", "n20"}; - return convert_enum_idx(options, 8, value, "ue_timers_and_consts_nb_r13_s::n310_r13_e_"); + return SRSASN_SUCCESS; } -uint8_t ue_timers_and_consts_nb_r13_s::n310_r13_opts::to_number() const +void pcch_cfg_nb_r13_s::to_json(json_writer& j) const { - static const uint8_t options[] = {1, 2, 3, 4, 6, 8, 10, 20}; - return map_enum_number(options, 8, value, "ue_timers_and_consts_nb_r13_s::n310_r13_e_"); + j.start_obj(); + j.write_str("defaultPagingCycle-r13", default_paging_cycle_r13.to_string()); + j.write_str("nB-r13", nb_r13.to_string()); + j.write_str("npdcch-NumRepetitionPaging-r13", npdcch_num_repeat_paging_r13.to_string()); + j.end_obj(); } -const char* ue_timers_and_consts_nb_r13_s::t311_r13_opts::to_string() const +const char* pcch_cfg_nb_r13_s::default_paging_cycle_r13_opts::to_string() const { - static const char* options[] = {"ms1000", "ms3000", "ms5000", "ms10000", "ms15000", "ms20000", "ms30000"}; - return convert_enum_idx(options, 7, value, "ue_timers_and_consts_nb_r13_s::t311_r13_e_"); + static const char* options[] = {"rf128", "rf256", "rf512", "rf1024"}; + return convert_enum_idx(options, 4, value, "pcch_cfg_nb_r13_s::default_paging_cycle_r13_e_"); } -uint16_t ue_timers_and_consts_nb_r13_s::t311_r13_opts::to_number() const +uint16_t pcch_cfg_nb_r13_s::default_paging_cycle_r13_opts::to_number() const { - static const uint16_t options[] = {1000, 3000, 5000, 10000, 15000, 20000, 30000}; - return map_enum_number(options, 7, value, "ue_timers_and_consts_nb_r13_s::t311_r13_e_"); + static const uint16_t options[] = {128, 256, 512, 1024}; + return map_enum_number(options, 4, value, "pcch_cfg_nb_r13_s::default_paging_cycle_r13_e_"); } -const char* ue_timers_and_consts_nb_r13_s::n311_r13_opts::to_string() const -{ - static const char* options[] = {"n1", "n2", "n3", "n4", "n5", "n6", "n8", "n10"}; - return convert_enum_idx(options, 8, value, "ue_timers_and_consts_nb_r13_s::n311_r13_e_"); -} -uint8_t ue_timers_and_consts_nb_r13_s::n311_r13_opts::to_number() const +const char* pcch_cfg_nb_r13_s::nb_r13_opts::to_string() const { - static const uint8_t options[] = {1, 2, 3, 4, 5, 6, 8, 10}; - return map_enum_number(options, 8, value, "ue_timers_and_consts_nb_r13_s::n311_r13_e_"); + static const char* options[] = {"fourT", + "twoT", + "oneT", + "halfT", + "quarterT", + "one8thT", + "one16thT", + "one32ndT", + "one64thT", + "one128thT", + "one256thT", + "one512thT", + "one1024thT", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 16, value, "pcch_cfg_nb_r13_s::nb_r13_e_"); } - -const char* ue_timers_and_consts_nb_r13_s::t311_v1350_opts::to_string() const +float pcch_cfg_nb_r13_s::nb_r13_opts::to_number() const { - static const char* options[] = {"ms40000", "ms60000", "ms90000", "ms120000"}; - return convert_enum_idx(options, 4, value, "ue_timers_and_consts_nb_r13_s::t311_v1350_e_"); + static const float options[] = {4.0, 2.0, 1.0, 0.5, 0.25, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0}; + return map_enum_number(options, 13, value, "pcch_cfg_nb_r13_s::nb_r13_e_"); } -uint32_t ue_timers_and_consts_nb_r13_s::t311_v1350_opts::to_number() const +const char* pcch_cfg_nb_r13_s::nb_r13_opts::to_number_string() const { - static const uint32_t options[] = {40000, 60000, 90000, 120000}; - return map_enum_number(options, 4, value, "ue_timers_and_consts_nb_r13_s::t311_v1350_e_"); + static const char* options[] = {"4", "2", "1", "0.5", "0.25", "8", "16", "32", "64", "128", "256", "512", "1024"}; + return convert_enum_idx(options, 16, value, "pcch_cfg_nb_r13_s::nb_r13_e_"); } -const char* ue_timers_and_consts_nb_r13_s::t300_v1530_opts::to_string() const +const char* pcch_cfg_nb_r13_s::npdcch_num_repeat_paging_r13_opts::to_string() const { - static const char* options[] = {"ms80000", "ms100000", "ms120000"}; - return convert_enum_idx(options, 3, value, "ue_timers_and_consts_nb_r13_s::t300_v1530_e_"); + static const char* options[] = {"r1", + "r2", + "r4", + "r8", + "r16", + "r32", + "r64", + "r128", + "r256", + "r512", + "r1024", + "r2048", + "spare4", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 16, value, "pcch_cfg_nb_r13_s::npdcch_num_repeat_paging_r13_e_"); } -uint32_t ue_timers_and_consts_nb_r13_s::t300_v1530_opts::to_number() const +uint16_t pcch_cfg_nb_r13_s::npdcch_num_repeat_paging_r13_opts::to_number() const { - static const uint32_t options[] = {80000, 100000, 120000}; - return map_enum_number(options, 3, value, "ue_timers_and_consts_nb_r13_s::t300_v1530_e_"); + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; + return map_enum_number(options, 12, value, "pcch_cfg_nb_r13_s::npdcch_num_repeat_paging_r13_e_"); } -const char* ue_timers_and_consts_nb_r13_s::t301_v1530_opts::to_string() const -{ - static const char* options[] = {"ms80000", "ms100000", "ms120000"}; - return convert_enum_idx(options, 3, value, "ue_timers_and_consts_nb_r13_s::t301_v1530_e_"); -} -uint32_t ue_timers_and_consts_nb_r13_s::t301_v1530_opts::to_number() const +// RACH-ConfigCommon-NB-r13 ::= SEQUENCE +SRSASN_CODE rach_cfg_common_nb_r13_s::pack(bit_ref& bref) const { - static const uint32_t options[] = {80000, 100000, 120000}; - return map_enum_number(options, 3, value, "ue_timers_and_consts_nb_r13_s::t301_v1530_e_"); -} + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(conn_est_fail_offset_r13_present, 1)); -const char* ue_timers_and_consts_nb_r13_s::t311_v1530_opts::to_string() const -{ - static const char* options[] = {"ms160000", "ms200000"}; - return convert_enum_idx(options, 2, value, "ue_timers_and_consts_nb_r13_s::t311_v1530_e_"); -} -uint32_t ue_timers_and_consts_nb_r13_s::t311_v1530_opts::to_number() const -{ - static const uint32_t options[] = {160000, 200000}; - return map_enum_number(options, 2, value, "ue_timers_and_consts_nb_r13_s::t311_v1530_e_"); -} - -const char* ue_timers_and_consts_nb_r13_s::t300_r15_opts::to_string() const -{ - static const char* options[] = { - "ms6000", "ms10000", "ms15000", "ms25000", "ms40000", "ms60000", "ms80000", "ms120000"}; - return convert_enum_idx(options, 8, value, "ue_timers_and_consts_nb_r13_s::t300_r15_e_"); -} -uint32_t ue_timers_and_consts_nb_r13_s::t300_r15_opts::to_number() const -{ - static const uint32_t options[] = {6000, 10000, 15000, 25000, 40000, 60000, 80000, 120000}; - return map_enum_number(options, 8, value, "ue_timers_and_consts_nb_r13_s::t300_r15_e_"); -} - -// CellSelectionInfo-NB-v1350 ::= SEQUENCE -SRSASN_CODE cell_sel_info_nb_v1350_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, delta_rx_lev_min_v1350, (int8_t)-8, (int8_t)-1)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE cell_sel_info_nb_v1350_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(delta_rx_lev_min_v1350, bref, (int8_t)-8, (int8_t)-1)); + HANDLE_CODE(preamb_trans_max_ce_r13.pack(bref)); + HANDLE_CODE(pwr_ramp_params_r13.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, rach_info_list_r13, 1, 3)); + if (conn_est_fail_offset_r13_present) { + HANDLE_CODE(pack_integer(bref, conn_est_fail_offset_r13, (uint8_t)0u, (uint8_t)15u)); + } - return SRSASN_SUCCESS; -} -void cell_sel_info_nb_v1350_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("delta-RxLevMin-v1350", delta_rx_lev_min_v1350); - j.end_obj(); -} + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= pwr_ramp_params_v1450.is_present(); + group_flags[1] |= rach_info_list_v1530.is_present(); + group_flags.pack(bref); -// PLMN-IdentityInfo-NB-r13 ::= SEQUENCE -SRSASN_CODE plmn_id_info_nb_r13_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(bref.pack(attach_without_pdn_connect_r13_present, 1)); + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(plmn_id_r13.pack(bref)); - HANDLE_CODE(cell_reserved_for_oper_r13.pack(bref)); + HANDLE_CODE(bref.pack(pwr_ramp_params_v1450.is_present(), 1)); + if (pwr_ramp_params_v1450.is_present()) { + HANDLE_CODE(pwr_ramp_params_v1450->pack(bref)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(bref.pack(rach_info_list_v1530.is_present(), 1)); + if (rach_info_list_v1530.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *rach_info_list_v1530, 1, 3)); + } + } + } return SRSASN_SUCCESS; } -SRSASN_CODE plmn_id_info_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE rach_cfg_common_nb_r13_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(attach_without_pdn_connect_r13_present, 1)); - - HANDLE_CODE(plmn_id_r13.unpack(bref)); - HANDLE_CODE(cell_reserved_for_oper_r13.unpack(bref)); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(conn_est_fail_offset_r13_present, 1)); - return SRSASN_SUCCESS; -} -void plmn_id_info_nb_r13_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("plmn-Identity-r13"); - plmn_id_r13.to_json(j); - j.write_str("cellReservedForOperatorUse-r13", cell_reserved_for_oper_r13.to_string()); - if (attach_without_pdn_connect_r13_present) { - j.write_str("attachWithoutPDN-Connectivity-r13", "true"); + HANDLE_CODE(preamb_trans_max_ce_r13.unpack(bref)); + HANDLE_CODE(pwr_ramp_params_r13.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(rach_info_list_r13, bref, 1, 3)); + if (conn_est_fail_offset_r13_present) { + HANDLE_CODE(unpack_integer(conn_est_fail_offset_r13, bref, (uint8_t)0u, (uint8_t)15u)); } - j.end_obj(); -} -const char* plmn_id_info_nb_r13_s::cell_reserved_for_oper_r13_opts::to_string() const -{ - static const char* options[] = {"reserved", "notReserved"}; - return convert_enum_idx(options, 2, value, "plmn_id_info_nb_r13_s::cell_reserved_for_oper_r13_e_"); -} + if (ext) { + ext_groups_unpacker_guard group_flags(2); + group_flags.unpack(bref); -// SchedulingInfo-NB-r13 ::= SEQUENCE -SRSASN_CODE sched_info_nb_r13_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(si_periodicity_r13.pack(bref)); - HANDLE_CODE(si_repeat_pattern_r13.pack(bref)); - HANDLE_CODE(pack_dyn_seq_of(bref, sib_map_info_r13, 0, 31)); - HANDLE_CODE(si_tb_r13.pack(bref)); + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); - return SRSASN_SUCCESS; -} -SRSASN_CODE sched_info_nb_r13_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(si_periodicity_r13.unpack(bref)); - HANDLE_CODE(si_repeat_pattern_r13.unpack(bref)); - HANDLE_CODE(unpack_dyn_seq_of(sib_map_info_r13, bref, 0, 31)); - HANDLE_CODE(si_tb_r13.unpack(bref)); + bool pwr_ramp_params_v1450_present; + HANDLE_CODE(bref.unpack(pwr_ramp_params_v1450_present, 1)); + pwr_ramp_params_v1450.set_present(pwr_ramp_params_v1450_present); + if (pwr_ramp_params_v1450.is_present()) { + HANDLE_CODE(pwr_ramp_params_v1450->unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + bool rach_info_list_v1530_present; + HANDLE_CODE(bref.unpack(rach_info_list_v1530_present, 1)); + rach_info_list_v1530.set_present(rach_info_list_v1530_present); + if (rach_info_list_v1530.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*rach_info_list_v1530, bref, 1, 3)); + } + } + } return SRSASN_SUCCESS; } -void sched_info_nb_r13_s::to_json(json_writer& j) const +void rach_cfg_common_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("si-Periodicity-r13", si_periodicity_r13.to_string()); - j.write_str("si-RepetitionPattern-r13", si_repeat_pattern_r13.to_string()); - j.start_array("sib-MappingInfo-r13"); - for (const auto& e1 : sib_map_info_r13) { - j.write_str(e1.to_string()); + j.write_str("preambleTransMax-CE-r13", preamb_trans_max_ce_r13.to_string()); + j.write_fieldname("powerRampingParameters-r13"); + pwr_ramp_params_r13.to_json(j); + j.start_array("rach-InfoList-r13"); + for (const auto& e1 : rach_info_list_r13) { + e1.to_json(j); } j.end_array(); - j.write_str("si-TB-r13", si_tb_r13.to_string()); + if (conn_est_fail_offset_r13_present) { + j.write_int("connEstFailOffset-r13", conn_est_fail_offset_r13); + } + if (ext) { + if (pwr_ramp_params_v1450.is_present()) { + j.write_fieldname("powerRampingParameters-v1450"); + pwr_ramp_params_v1450->to_json(j); + } + if (rach_info_list_v1530.is_present()) { + j.start_array("rach-InfoList-v1530"); + for (const auto& e1 : *rach_info_list_v1530) { + e1.to_json(j); + } + j.end_array(); + } + } j.end_obj(); } -const char* sched_info_nb_r13_s::si_periodicity_r13_opts::to_string() const -{ - static const char* options[] = {"rf64", "rf128", "rf256", "rf512", "rf1024", "rf2048", "rf4096", "spare"}; - return convert_enum_idx(options, 8, value, "sched_info_nb_r13_s::si_periodicity_r13_e_"); -} -uint16_t sched_info_nb_r13_s::si_periodicity_r13_opts::to_number() const -{ - static const uint16_t options[] = {64, 128, 256, 512, 1024, 2048, 4096}; - return map_enum_number(options, 7, value, "sched_info_nb_r13_s::si_periodicity_r13_e_"); -} - -const char* sched_info_nb_r13_s::si_repeat_pattern_r13_opts::to_string() const -{ - static const char* options[] = {"every2ndRF", "every4thRF", "every8thRF", "every16thRF"}; - return convert_enum_idx(options, 4, value, "sched_info_nb_r13_s::si_repeat_pattern_r13_e_"); -} -uint8_t sched_info_nb_r13_s::si_repeat_pattern_r13_opts::to_number() const -{ - static const uint8_t options[] = {2, 4, 8, 16}; - return map_enum_number(options, 4, value, "sched_info_nb_r13_s::si_repeat_pattern_r13_e_"); -} - -const char* sched_info_nb_r13_s::si_tb_r13_opts::to_string() const +// SIB-Type-NB-r13 ::= ENUMERATED +const char* sib_type_nb_r13_opts::to_string() const { - static const char* options[] = {"b56", "b120", "b208", "b256", "b328", "b440", "b552", "b680"}; - return convert_enum_idx(options, 8, value, "sched_info_nb_r13_s::si_tb_r13_e_"); + static const char* options[] = {"sibType3-NB-r13", + "sibType4-NB-r13", + "sibType5-NB-r13", + "sibType14-NB-r13", + "sibType16-NB-r13", + "sibType15-NB-r14", + "sibType20-NB-r14", + "sibType22-NB-r14"}; + return convert_enum_idx(options, 8, value, "sib_type_nb_r13_e"); } -uint16_t sched_info_nb_r13_s::si_tb_r13_opts::to_number() const +uint8_t sib_type_nb_r13_opts::to_number() const { - static const uint16_t options[] = {56, 120, 208, 256, 328, 440, 552, 680}; - return map_enum_number(options, 8, value, "sched_info_nb_r13_s::si_tb_r13_e_"); + static const uint8_t options[] = {3, 4, 5, 14, 16, 15, 20, 22}; + return map_enum_number(options, 8, value, "sib_type_nb_r13_e"); } -// SystemInformationBlockType1-NB-v1430 ::= SEQUENCE -SRSASN_CODE sib_type1_nb_v1430_s::pack(bit_ref& bref) const +// SystemInformationBlockType1-NB-v1530 ::= SEQUENCE +SRSASN_CODE sib_type1_nb_v1530_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(cell_sel_info_v1430_present, 1)); + HANDLE_CODE(bref.pack(tdd_params_r15_present, 1)); + HANDLE_CODE(bref.pack(sched_info_list_v1530_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (cell_sel_info_v1430_present) { - HANDLE_CODE(cell_sel_info_v1430.pack(bref)); + if (tdd_params_r15_present) { + HANDLE_CODE(bref.pack(tdd_params_r15.tdd_si_sfs_bitmap_r15_present, 1)); + HANDLE_CODE(tdd_params_r15.tdd_cfg_r15.pack(bref)); + HANDLE_CODE(tdd_params_r15.tdd_si_carrier_info_r15.pack(bref)); + if (tdd_params_r15.tdd_si_sfs_bitmap_r15_present) { + HANDLE_CODE(tdd_params_r15.tdd_si_sfs_bitmap_r15.pack(bref)); + } + } + if (sched_info_list_v1530_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, sched_info_list_v1530, 1, 8)); } if (non_crit_ext_present) { HANDLE_CODE(non_crit_ext.pack(bref)); @@ -9903,13 +10874,22 @@ SRSASN_CODE sib_type1_nb_v1430_s::pack(bit_ref& bref) const return SRSASN_SUCCESS; } -SRSASN_CODE sib_type1_nb_v1430_s::unpack(cbit_ref& bref) +SRSASN_CODE sib_type1_nb_v1530_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(cell_sel_info_v1430_present, 1)); + HANDLE_CODE(bref.unpack(tdd_params_r15_present, 1)); + HANDLE_CODE(bref.unpack(sched_info_list_v1530_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - if (cell_sel_info_v1430_present) { - HANDLE_CODE(cell_sel_info_v1430.unpack(bref)); + if (tdd_params_r15_present) { + HANDLE_CODE(bref.unpack(tdd_params_r15.tdd_si_sfs_bitmap_r15_present, 1)); + HANDLE_CODE(tdd_params_r15.tdd_cfg_r15.unpack(bref)); + HANDLE_CODE(tdd_params_r15.tdd_si_carrier_info_r15.unpack(bref)); + if (tdd_params_r15.tdd_si_sfs_bitmap_r15_present) { + HANDLE_CODE(tdd_params_r15.tdd_si_sfs_bitmap_r15.unpack(bref)); + } + } + if (sched_info_list_v1530_present) { + HANDLE_CODE(unpack_dyn_seq_of(sched_info_list_v1530, bref, 1, 8)); } if (non_crit_ext_present) { HANDLE_CODE(non_crit_ext.unpack(bref)); @@ -9917,2489 +10897,7639 @@ SRSASN_CODE sib_type1_nb_v1430_s::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -void sib_type1_nb_v1430_s::to_json(json_writer& j) const +void sib_type1_nb_v1530_s::to_json(json_writer& j) const { j.start_obj(); - if (cell_sel_info_v1430_present) { - j.write_fieldname("cellSelectionInfo-v1430"); - cell_sel_info_v1430.to_json(j); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); - } - j.end_obj(); -} - -// SystemInformationBlockType14-NB-r13 ::= SEQUENCE -SRSASN_CODE sib_type14_nb_r13_s::pack(bit_ref& bref) const + if (tdd_params_r15_present) { + j.write_fieldname("tdd-Parameters-r15"); + j.start_obj(); + j.write_fieldname("tdd-Config-r15"); + tdd_params_r15.tdd_cfg_r15.to_json(j); + j.write_str("tdd-SI-CarrierInfo-r15", tdd_params_r15.tdd_si_carrier_info_r15.to_string()); + if (tdd_params_r15.tdd_si_sfs_bitmap_r15_present) { + j.write_fieldname("tdd-SI-SubframesBitmap-r15"); + tdd_params_r15.tdd_si_sfs_bitmap_r15.to_json(j); + } + j.end_obj(); + } + if (sched_info_list_v1530_present) { + j.start_array("schedulingInfoList-v1530"); + for (const auto& e1 : sched_info_list_v1530) { + e1.to_json(j); + } + j.end_array(); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +const char* sib_type1_nb_v1530_s::tdd_params_r15_s_::tdd_si_carrier_info_r15_opts::to_string() const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(ab_param_r13_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + static const char* options[] = {"anchor", "non-anchor"}; + return convert_enum_idx(options, 2, value, "sib_type1_nb_v1530_s::tdd_params_r15_s_::tdd_si_carrier_info_r15_e_"); +} - if (ab_param_r13_present) { - HANDLE_CODE(ab_param_r13.pack(bref)); +// UAC-Barring-NB-r16 ::= SEQUENCE +SRSASN_CODE uac_barr_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(uac_barr_per_cat_list_r16_present, 1)); + HANDLE_CODE(bref.pack(uac_ac1_select_assist_info_r16_present, 1)); + + if (uac_barr_per_cat_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, uac_barr_per_cat_list_r16, 1, 63)); } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); + if (uac_ac1_select_assist_info_r16_present) { + HANDLE_CODE(uac_ac1_select_assist_info_r16.pack(bref)); + } + HANDLE_CODE(uac_barr_for_access_id_r16.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE uac_barr_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(uac_barr_per_cat_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(uac_ac1_select_assist_info_r16_present, 1)); + + if (uac_barr_per_cat_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(uac_barr_per_cat_list_r16, bref, 1, 63)); + } + if (uac_ac1_select_assist_info_r16_present) { + HANDLE_CODE(uac_ac1_select_assist_info_r16.unpack(bref)); + } + HANDLE_CODE(uac_barr_for_access_id_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void uac_barr_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (uac_barr_per_cat_list_r16_present) { + j.start_array("uac-BarringPerCatList-r16"); + for (const auto& e1 : uac_barr_per_cat_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (uac_ac1_select_assist_info_r16_present) { + j.write_str("uac-AC1-SelectAssistInfo-r16", uac_ac1_select_assist_info_r16.to_string()); + } + j.write_str("uac-BarringForAccessIdentity-r16", uac_barr_for_access_id_r16.to_string()); + j.end_obj(); +} + +// UL-ConfigCommon-NB-r14 ::= SEQUENCE +SRSASN_CODE ul_cfg_common_nb_r14_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(nprach_params_list_r14_present, 1)); + + HANDLE_CODE(ul_carrier_freq_r14.pack(bref)); + if (nprach_params_list_r14_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_r14, 1, 3)); } if (ext) { ext_groups_packer_guard group_flags; - group_flags[0] |= ab_per_nrsrp_r15_present; + group_flags[0] |= nprach_params_list_edt_r15.is_present(); + group_flags[1] |= rsrp_thress_prach_info_list_r16.is_present(); group_flags.pack(bref); if (group_flags[0]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(ab_per_nrsrp_r15_present, 1)); - if (ab_per_nrsrp_r15_present) { - HANDLE_CODE(ab_per_nrsrp_r15.pack(bref)); + HANDLE_CODE(bref.pack(nprach_params_list_edt_r15.is_present(), 1)); + if (nprach_params_list_edt_r15.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *nprach_params_list_edt_r15, 1, 3)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(rsrp_thress_prach_info_list_r16.is_present(), 1)); + if (rsrp_thress_prach_info_list_r16.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *rsrp_thress_prach_info_list_r16, 1, 2, integer_packer(0, 97))); } } } return SRSASN_SUCCESS; } -SRSASN_CODE sib_type14_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE ul_cfg_common_nb_r14_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(ab_param_r13_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_list_r14_present, 1)); - if (ab_param_r13_present) { - HANDLE_CODE(ab_param_r13.unpack(bref)); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + HANDLE_CODE(ul_carrier_freq_r14.unpack(bref)); + if (nprach_params_list_r14_present) { + HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_r14, bref, 1, 3)); } if (ext) { - ext_groups_unpacker_guard group_flags(1); + ext_groups_unpacker_guard group_flags(2); group_flags.unpack(bref); if (group_flags[0]) { varlength_field_unpack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.unpack(ab_per_nrsrp_r15_present, 1)); - if (ab_per_nrsrp_r15_present) { - HANDLE_CODE(ab_per_nrsrp_r15.unpack(bref)); + bool nprach_params_list_edt_r15_present; + HANDLE_CODE(bref.unpack(nprach_params_list_edt_r15_present, 1)); + nprach_params_list_edt_r15.set_present(nprach_params_list_edt_r15_present); + if (nprach_params_list_edt_r15.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*nprach_params_list_edt_r15, bref, 1, 3)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool rsrp_thress_prach_info_list_r16_present; + HANDLE_CODE(bref.unpack(rsrp_thress_prach_info_list_r16_present, 1)); + rsrp_thress_prach_info_list_r16.set_present(rsrp_thress_prach_info_list_r16_present); + if (rsrp_thress_prach_info_list_r16.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*rsrp_thress_prach_info_list_r16, bref, 1, 2, integer_packer(0, 97))); } } } return SRSASN_SUCCESS; } -void sib_type14_nb_r13_s::to_json(json_writer& j) const +void ul_cfg_common_nb_r14_s::to_json(json_writer& j) const { j.start_obj(); - if (ab_param_r13_present) { - j.write_fieldname("ab-Param-r13"); - ab_param_r13.to_json(j); - } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + j.write_fieldname("ul-CarrierFreq-r14"); + ul_carrier_freq_r14.to_json(j); + if (nprach_params_list_r14_present) { + j.start_array("nprach-ParametersList-r14"); + for (const auto& e1 : nprach_params_list_r14) { + e1.to_json(j); + } + j.end_array(); } if (ext) { - if (ab_per_nrsrp_r15_present) { - j.write_str("ab-PerNRSRP-r15", ab_per_nrsrp_r15.to_string()); + if (nprach_params_list_edt_r15.is_present()) { + j.start_array("nprach-ParametersListEDT-r15"); + for (const auto& e1 : *nprach_params_list_edt_r15) { + e1.to_json(j); + } + j.end_array(); + } + if (rsrp_thress_prach_info_list_r16.is_present()) { + j.start_array("rsrp-ThresholdsPrachInfoList-r16"); + for (const auto& e1 : *rsrp_thress_prach_info_list_r16) { + j.write_int(e1); + } + j.end_array(); } } j.end_obj(); } -void sib_type14_nb_r13_s::ab_param_r13_c_::destroy_() +// UL-ConfigCommon-NB-v1530 ::= SEQUENCE +SRSASN_CODE ul_cfg_common_nb_v1530_s::pack(bit_ref& bref) const { - switch (type_) { - case types::ab_common_r13: - c.destroy(); - break; - case types::ab_per_plmn_list_r13: - c.destroy(); - break; - default: - break; + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(nprach_params_list_fmt2_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_params_list_fmt2_edt_r15_present, 1)); + + if (nprach_params_list_fmt2_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_fmt2_r15, 1, 3)); } -} -void sib_type14_nb_r13_s::ab_param_r13_c_::set(types::options e) -{ - destroy_(); - type_ = e; - switch (type_) { - case types::ab_common_r13: - c.init(); - break; - case types::ab_per_plmn_list_r13: - c.init(); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); + if (nprach_params_list_fmt2_edt_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_fmt2_edt_r15, 1, 3)); } + + return SRSASN_SUCCESS; } -sib_type14_nb_r13_s::ab_param_r13_c_::ab_param_r13_c_(const sib_type14_nb_r13_s::ab_param_r13_c_& other) +SRSASN_CODE ul_cfg_common_nb_v1530_s::unpack(cbit_ref& bref) { - type_ = other.type(); - switch (type_) { - case types::ab_common_r13: - c.init(other.c.get()); - break; - case types::ab_per_plmn_list_r13: - c.init(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(nprach_params_list_fmt2_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_params_list_fmt2_edt_r15_present, 1)); + + if (nprach_params_list_fmt2_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_fmt2_r15, bref, 1, 3)); + } + if (nprach_params_list_fmt2_edt_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_fmt2_edt_r15, bref, 1, 3)); } + + return SRSASN_SUCCESS; } -sib_type14_nb_r13_s::ab_param_r13_c_& -sib_type14_nb_r13_s::ab_param_r13_c_::operator=(const sib_type14_nb_r13_s::ab_param_r13_c_& other) +void ul_cfg_common_nb_v1530_s::to_json(json_writer& j) const { - if (this == &other) { - return *this; + j.start_obj(); + if (nprach_params_list_fmt2_r15_present) { + j.start_array("nprach-ParametersListFmt2-r15"); + for (const auto& e1 : nprach_params_list_fmt2_r15) { + e1.to_json(j); + } + j.end_array(); } - set(other.type()); - switch (type_) { - case types::ab_common_r13: - c.set(other.c.get()); - break; - case types::ab_per_plmn_list_r13: - c.set(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); + if (nprach_params_list_fmt2_edt_r15_present) { + j.start_array("nprach-ParametersListFmt2EDT-r15"); + for (const auto& e1 : nprach_params_list_fmt2_edt_r15) { + e1.to_json(j); + } + j.end_array(); } - - return *this; + j.end_obj(); } -ab_cfg_nb_r13_s& sib_type14_nb_r13_s::ab_param_r13_c_::set_ab_common_r13() + +// UL-ConfigCommonTDD-NB-r15 ::= SEQUENCE +SRSASN_CODE ul_cfg_common_tdd_nb_r15_s::pack(bit_ref& bref) const { - set(types::ab_common_r13); - return c.get(); + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(nprach_params_list_tdd_r15_present, 1)); + + HANDLE_CODE(tdd_ul_dl_align_offset_r15.pack(bref)); + if (nprach_params_list_tdd_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, nprach_params_list_tdd_r15, 1, 3)); + } + + return SRSASN_SUCCESS; } -sib_type14_nb_r13_s::ab_param_r13_c_::ab_per_plmn_list_r13_l_& -sib_type14_nb_r13_s::ab_param_r13_c_::set_ab_per_plmn_list_r13() +SRSASN_CODE ul_cfg_common_tdd_nb_r15_s::unpack(cbit_ref& bref) { - set(types::ab_per_plmn_list_r13); - return c.get(); -} -void sib_type14_nb_r13_s::ab_param_r13_c_::to_json(json_writer& j) const + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(nprach_params_list_tdd_r15_present, 1)); + + HANDLE_CODE(tdd_ul_dl_align_offset_r15.unpack(bref)); + if (nprach_params_list_tdd_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(nprach_params_list_tdd_r15, bref, 1, 3)); + } + + return SRSASN_SUCCESS; +} +void ul_cfg_common_tdd_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::ab_common_r13: - j.write_fieldname("ab-Common-r13"); - c.get().to_json(j); - break; - case types::ab_per_plmn_list_r13: - j.start_array("ab-PerPLMN-List-r13"); - for (const auto& e1 : c.get()) { - e1.to_json(j); - } - j.end_array(); - break; - default: - log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); + j.write_str("tdd-UL-DL-AlignmentOffset-r15", tdd_ul_dl_align_offset_r15.to_string()); + if (nprach_params_list_tdd_r15_present) { + j.start_array("nprach-ParametersListTDD-r15"); + for (const auto& e1 : nprach_params_list_tdd_r15) { + e1.to_json(j); + } + j.end_array(); } j.end_obj(); } -SRSASN_CODE sib_type14_nb_r13_s::ab_param_r13_c_::pack(bit_ref& bref) const + +// UplinkPowerControlCommon-NB-r13 ::= SEQUENCE +SRSASN_CODE ul_pwr_ctrl_common_nb_r13_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::ab_common_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::ab_per_plmn_list_r13: - HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 6)); - break; - default: - log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); - return SRSASN_ERROR_ENCODE_FAIL; - } + HANDLE_CODE(pack_integer(bref, p0_nominal_npusch_r13, (int8_t)-126, (int8_t)24)); + HANDLE_CODE(alpha_r13.pack(bref)); + HANDLE_CODE(pack_integer(bref, delta_preamb_msg3_r13, (int8_t)-1, (int8_t)6)); + return SRSASN_SUCCESS; } -SRSASN_CODE sib_type14_nb_r13_s::ab_param_r13_c_::unpack(cbit_ref& bref) +SRSASN_CODE ul_pwr_ctrl_common_nb_r13_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::ab_common_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::ab_per_plmn_list_r13: - HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 6)); - break; - default: - log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); - return SRSASN_ERROR_DECODE_FAIL; - } + HANDLE_CODE(unpack_integer(p0_nominal_npusch_r13, bref, (int8_t)-126, (int8_t)24)); + HANDLE_CODE(alpha_r13.unpack(bref)); + HANDLE_CODE(unpack_integer(delta_preamb_msg3_r13, bref, (int8_t)-1, (int8_t)6)); + return SRSASN_SUCCESS; } +void ul_pwr_ctrl_common_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("p0-NominalNPUSCH-r13", p0_nominal_npusch_r13); + j.write_str("alpha-r13", alpha_r13.to_string()); + j.write_int("deltaPreambleMsg3-r13", delta_preamb_msg3_r13); + j.end_obj(); +} -const char* sib_type14_nb_r13_s::ab_param_r13_c_::types_opts::to_string() const +const char* ul_pwr_ctrl_common_nb_r13_s::alpha_r13_opts::to_string() const { - static const char* options[] = {"ab-Common-r13", "ab-PerPLMN-List-r13"}; - return convert_enum_idx(options, 2, value, "sib_type14_nb_r13_s::ab_param_r13_c_::types"); + static const char* options[] = {"al0", "al04", "al05", "al06", "al07", "al08", "al09", "al1"}; + return convert_enum_idx(options, 8, value, "ul_pwr_ctrl_common_nb_r13_s::alpha_r13_e_"); +} +float ul_pwr_ctrl_common_nb_r13_s::alpha_r13_opts::to_number() const +{ + static const float options[] = {0.0, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; + return map_enum_number(options, 8, value, "ul_pwr_ctrl_common_nb_r13_s::alpha_r13_e_"); +} +const char* ul_pwr_ctrl_common_nb_r13_s::alpha_r13_opts::to_number_string() const +{ + static const char* options[] = {"0", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1"}; + return convert_enum_idx(options, 8, value, "ul_pwr_ctrl_common_nb_r13_s::alpha_r13_e_"); } -const char* sib_type14_nb_r13_s::ab_per_nrsrp_r15_opts::to_string() const +// CellReselectionInfoCommon-NB-v1450 ::= SEQUENCE +SRSASN_CODE cell_resel_info_common_nb_v1450_s::pack(bit_ref& bref) const { - static const char* options[] = {"thresh1", "thresh2"}; - return convert_enum_idx(options, 2, value, "sib_type14_nb_r13_s::ab_per_nrsrp_r15_e_"); + HANDLE_CODE(s_search_delta_p_r14.pack(bref)); + + return SRSASN_SUCCESS; } -uint8_t sib_type14_nb_r13_s::ab_per_nrsrp_r15_opts::to_number() const +SRSASN_CODE cell_resel_info_common_nb_v1450_s::unpack(cbit_ref& bref) { - static const uint8_t options[] = {1, 2}; - return map_enum_number(options, 2, value, "sib_type14_nb_r13_s::ab_per_nrsrp_r15_e_"); + HANDLE_CODE(s_search_delta_p_r14.unpack(bref)); + + return SRSASN_SUCCESS; +} +void cell_resel_info_common_nb_v1450_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("s-SearchDeltaP-r14", s_search_delta_p_r14.to_string()); + j.end_obj(); } -// SystemInformationBlockType15-NB-r14 ::= SEQUENCE -SRSASN_CODE sib_type15_nb_r14_s::pack(bit_ref& bref) const +const char* cell_resel_info_common_nb_v1450_s::s_search_delta_p_r14_opts::to_string() const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(mbms_sai_intra_freq_r14_present, 1)); - HANDLE_CODE(bref.pack(mbms_sai_inter_freq_list_r14_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + static const char* options[] = {"dB6", "dB9", "dB12", "dB15"}; + return convert_enum_idx(options, 4, value, "cell_resel_info_common_nb_v1450_s::s_search_delta_p_r14_e_"); +} +uint8_t cell_resel_info_common_nb_v1450_s::s_search_delta_p_r14_opts::to_number() const +{ + static const uint8_t options[] = {6, 9, 12, 15}; + return map_enum_number(options, 4, value, "cell_resel_info_common_nb_v1450_s::s_search_delta_p_r14_e_"); +} - if (mbms_sai_intra_freq_r14_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, mbms_sai_intra_freq_r14, 1, 64, integer_packer(0, 65535))); - } - if (mbms_sai_inter_freq_list_r14_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, mbms_sai_inter_freq_list_r14, 1, 8)); +// CellSelectionInfo-NB-v1430 ::= SEQUENCE +SRSASN_CODE cell_sel_info_nb_v1430_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pwr_class14dbm_offset_r14_present, 1)); + HANDLE_CODE(bref.pack(ce_authorisation_offset_r14_present, 1)); + + if (pwr_class14dbm_offset_r14_present) { + HANDLE_CODE(pwr_class14dbm_offset_r14.pack(bref)); } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); + if (ce_authorisation_offset_r14_present) { + HANDLE_CODE(ce_authorisation_offset_r14.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE sib_type15_nb_r14_s::unpack(cbit_ref& bref) +SRSASN_CODE cell_sel_info_nb_v1430_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(mbms_sai_intra_freq_r14_present, 1)); - HANDLE_CODE(bref.unpack(mbms_sai_inter_freq_list_r14_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(pwr_class14dbm_offset_r14_present, 1)); + HANDLE_CODE(bref.unpack(ce_authorisation_offset_r14_present, 1)); - if (mbms_sai_intra_freq_r14_present) { - HANDLE_CODE(unpack_dyn_seq_of(mbms_sai_intra_freq_r14, bref, 1, 64, integer_packer(0, 65535))); - } - if (mbms_sai_inter_freq_list_r14_present) { - HANDLE_CODE(unpack_dyn_seq_of(mbms_sai_inter_freq_list_r14, bref, 1, 8)); + if (pwr_class14dbm_offset_r14_present) { + HANDLE_CODE(pwr_class14dbm_offset_r14.unpack(bref)); } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + if (ce_authorisation_offset_r14_present) { + HANDLE_CODE(ce_authorisation_offset_r14.unpack(bref)); } return SRSASN_SUCCESS; } -void sib_type15_nb_r14_s::to_json(json_writer& j) const +void cell_sel_info_nb_v1430_s::to_json(json_writer& j) const { j.start_obj(); - if (mbms_sai_intra_freq_r14_present) { - j.start_array("mbms-SAI-IntraFreq-r14"); - for (const auto& e1 : mbms_sai_intra_freq_r14) { - j.write_int(e1); - } - j.end_array(); - } - if (mbms_sai_inter_freq_list_r14_present) { - j.start_array("mbms-SAI-InterFreqList-r14"); - for (const auto& e1 : mbms_sai_inter_freq_list_r14) { - e1.to_json(j); - } - j.end_array(); + if (pwr_class14dbm_offset_r14_present) { + j.write_str("powerClass14dBm-Offset-r14", pwr_class14dbm_offset_r14.to_string()); } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + if (ce_authorisation_offset_r14_present) { + j.write_str("ce-authorisationOffset-r14", ce_authorisation_offset_r14.to_string()); } j.end_obj(); } -// SystemInformationBlockType2-NB-r13 ::= SEQUENCE -SRSASN_CODE sib_type2_nb_r13_s::pack(bit_ref& bref) const +const char* cell_sel_info_nb_v1430_s::pwr_class14dbm_offset_r14_opts::to_string() const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(multi_band_info_list_r13_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + static const char* options[] = {"dB-6", "dB-3", "dB3", "dB6", "dB9", "dB12"}; + return convert_enum_idx(options, 6, value, "cell_sel_info_nb_v1430_s::pwr_class14dbm_offset_r14_e_"); +} +int8_t cell_sel_info_nb_v1430_s::pwr_class14dbm_offset_r14_opts::to_number() const +{ + static const int8_t options[] = {-6, -3, 3, 6, 9, 12}; + return map_enum_number(options, 6, value, "cell_sel_info_nb_v1430_s::pwr_class14dbm_offset_r14_e_"); +} - HANDLE_CODE(rr_cfg_common_r13.pack(bref)); - HANDLE_CODE(ue_timers_and_consts_r13.pack(bref)); - HANDLE_CODE(bref.pack(freq_info_r13.ul_carrier_freq_r13_present, 1)); - if (freq_info_r13.ul_carrier_freq_r13_present) { - HANDLE_CODE(freq_info_r13.ul_carrier_freq_r13.pack(bref)); - } - HANDLE_CODE(pack_integer(bref, freq_info_r13.add_spec_emission_r13, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(time_align_timer_common_r13.pack(bref)); - if (multi_band_info_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, multi_band_info_list_r13, 1, 8, integer_packer(1, 32))); +const char* cell_sel_info_nb_v1430_s::ce_authorisation_offset_r14_opts::to_string() const +{ + static const char* options[] = {"dB5", "dB10", "dB15", "dB20", "dB25", "dB30", "dB35"}; + return convert_enum_idx(options, 7, value, "cell_sel_info_nb_v1430_s::ce_authorisation_offset_r14_e_"); +} +uint8_t cell_sel_info_nb_v1430_s::ce_authorisation_offset_r14_opts::to_number() const +{ + static const uint8_t options[] = {5, 10, 15, 20, 25, 30, 35}; + return map_enum_number(options, 7, value, "cell_sel_info_nb_v1430_s::ce_authorisation_offset_r14_e_"); +} + +// ConnMeasConfig-NB-r17 ::= SEQUENCE +SRSASN_CODE conn_meas_cfg_nb_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(s_measure_inter_r17_present, 1)); + HANDLE_CODE(bref.pack(neigh_cell_meas_criteria_r17_present, 1)); + + HANDLE_CODE(pack_integer(bref, s_measure_intra_r17, (uint8_t)0u, (uint8_t)113u)); + if (s_measure_inter_r17_present) { + HANDLE_CODE(pack_integer(bref, s_measure_inter_r17, (uint8_t)0u, (uint8_t)113u)); } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); + if (neigh_cell_meas_criteria_r17_present) { + HANDLE_CODE(neigh_cell_meas_criteria_r17.s_measure_delta_p_r17.pack(bref)); + HANDLE_CODE(neigh_cell_meas_criteria_r17.t_measure_delta_p_r17.pack(bref)); } - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= cp_reest_r14_present; - group_flags[1] |= serving_cell_meas_info_r14_present; - group_flags[1] |= cqi_report_r14_present; - group_flags[2] |= enhanced_phr_r15_present; - group_flags[2] |= freq_info_v1530.is_present(); - group_flags[2] |= cp_edt_r15_present; - group_flags[2] |= up_edt_r15_present; - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); + return SRSASN_SUCCESS; +} +SRSASN_CODE conn_meas_cfg_nb_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(s_measure_inter_r17_present, 1)); + HANDLE_CODE(bref.unpack(neigh_cell_meas_criteria_r17_present, 1)); - HANDLE_CODE(bref.pack(cp_reest_r14_present, 1)); - } - if (group_flags[1]) { - varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(unpack_integer(s_measure_intra_r17, bref, (uint8_t)0u, (uint8_t)113u)); + if (s_measure_inter_r17_present) { + HANDLE_CODE(unpack_integer(s_measure_inter_r17, bref, (uint8_t)0u, (uint8_t)113u)); + } + if (neigh_cell_meas_criteria_r17_present) { + HANDLE_CODE(neigh_cell_meas_criteria_r17.s_measure_delta_p_r17.unpack(bref)); + HANDLE_CODE(neigh_cell_meas_criteria_r17.t_measure_delta_p_r17.unpack(bref)); + } - HANDLE_CODE(bref.pack(serving_cell_meas_info_r14_present, 1)); - HANDLE_CODE(bref.pack(cqi_report_r14_present, 1)); - } - if (group_flags[2]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(enhanced_phr_r15_present, 1)); - HANDLE_CODE(bref.pack(freq_info_v1530.is_present(), 1)); - HANDLE_CODE(bref.pack(cp_edt_r15_present, 1)); - HANDLE_CODE(bref.pack(up_edt_r15_present, 1)); - if (freq_info_v1530.is_present()) { - HANDLE_CODE(freq_info_v1530->tdd_ul_dl_align_offset_r15.pack(bref)); - } - } - } return SRSASN_SUCCESS; } -SRSASN_CODE sib_type2_nb_r13_s::unpack(cbit_ref& bref) +void conn_meas_cfg_nb_r17_s::to_json(json_writer& j) const { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(multi_band_info_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - - HANDLE_CODE(rr_cfg_common_r13.unpack(bref)); - HANDLE_CODE(ue_timers_and_consts_r13.unpack(bref)); - HANDLE_CODE(bref.unpack(freq_info_r13.ul_carrier_freq_r13_present, 1)); - if (freq_info_r13.ul_carrier_freq_r13_present) { - HANDLE_CODE(freq_info_r13.ul_carrier_freq_r13.unpack(bref)); - } - HANDLE_CODE(unpack_integer(freq_info_r13.add_spec_emission_r13, bref, (uint8_t)1u, (uint8_t)32u)); - HANDLE_CODE(time_align_timer_common_r13.unpack(bref)); - if (multi_band_info_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r13, bref, 1, 8, integer_packer(1, 32))); + j.start_obj(); + j.write_int("s-MeasureIntra-r17", s_measure_intra_r17); + if (s_measure_inter_r17_present) { + j.write_int("s-MeasureInter-r17", s_measure_inter_r17); } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + if (neigh_cell_meas_criteria_r17_present) { + j.write_fieldname("neighCellMeasCriteria-r17"); + j.start_obj(); + j.write_str("s-MeasureDeltaP-r17", neigh_cell_meas_criteria_r17.s_measure_delta_p_r17.to_string()); + j.write_str("t-MeasureDeltaP-r17", neigh_cell_meas_criteria_r17.t_measure_delta_p_r17.to_string()); + j.end_obj(); } + j.end_obj(); +} - if (ext) { - ext_groups_unpacker_guard group_flags(3); - group_flags.unpack(bref); +const char* conn_meas_cfg_nb_r17_s::neigh_cell_meas_criteria_r17_s_::s_measure_delta_p_r17_opts::to_string() const +{ + static const char* options[] = {"dB6", "dB9", "dB12", "dB15"}; + return convert_enum_idx( + options, 4, value, "conn_meas_cfg_nb_r17_s::neigh_cell_meas_criteria_r17_s_::s_measure_delta_p_r17_e_"); +} +uint8_t conn_meas_cfg_nb_r17_s::neigh_cell_meas_criteria_r17_s_::s_measure_delta_p_r17_opts::to_number() const +{ + static const uint8_t options[] = {6, 9, 12, 15}; + return map_enum_number( + options, 4, value, "conn_meas_cfg_nb_r17_s::neigh_cell_meas_criteria_r17_s_::s_measure_delta_p_r17_e_"); +} - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); +const char* conn_meas_cfg_nb_r17_s::neigh_cell_meas_criteria_r17_s_::t_measure_delta_p_r17_opts::to_string() const +{ + static const char* options[] = {"s15", "s30", "s45", "s60"}; + return convert_enum_idx( + options, 4, value, "conn_meas_cfg_nb_r17_s::neigh_cell_meas_criteria_r17_s_::t_measure_delta_p_r17_e_"); +} +uint8_t conn_meas_cfg_nb_r17_s::neigh_cell_meas_criteria_r17_s_::t_measure_delta_p_r17_opts::to_number() const +{ + static const uint8_t options[] = {15, 30, 45, 60}; + return map_enum_number( + options, 4, value, "conn_meas_cfg_nb_r17_s::neigh_cell_meas_criteria_r17_s_::t_measure_delta_p_r17_e_"); +} - HANDLE_CODE(bref.unpack(cp_reest_r14_present, 1)); - } - if (group_flags[1]) { - varlength_field_unpack_guard varlen_scope(bref, false); +// CoverageBasedPagingConfig-NB-r17 ::= SEQUENCE +SRSASN_CODE coverage_based_paging_cfg_nb_r17_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(cbp_hyst_timer_r17.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, cbp_cfg_list_r17, 1, 2)); - HANDLE_CODE(bref.unpack(serving_cell_meas_info_r14_present, 1)); - HANDLE_CODE(bref.unpack(cqi_report_r14_present, 1)); - } - if (group_flags[2]) { - varlength_field_unpack_guard varlen_scope(bref, false); + return SRSASN_SUCCESS; +} +SRSASN_CODE coverage_based_paging_cfg_nb_r17_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(cbp_hyst_timer_r17.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(cbp_cfg_list_r17, bref, 1, 2)); - HANDLE_CODE(bref.unpack(enhanced_phr_r15_present, 1)); - bool freq_info_v1530_present; - HANDLE_CODE(bref.unpack(freq_info_v1530_present, 1)); - freq_info_v1530.set_present(freq_info_v1530_present); - HANDLE_CODE(bref.unpack(cp_edt_r15_present, 1)); - HANDLE_CODE(bref.unpack(up_edt_r15_present, 1)); - if (freq_info_v1530.is_present()) { - HANDLE_CODE(freq_info_v1530->tdd_ul_dl_align_offset_r15.unpack(bref)); - } - } - } return SRSASN_SUCCESS; } -void sib_type2_nb_r13_s::to_json(json_writer& j) const +void coverage_based_paging_cfg_nb_r17_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("radioResourceConfigCommon-r13"); - rr_cfg_common_r13.to_json(j); - j.write_fieldname("ue-TimersAndConstants-r13"); - ue_timers_and_consts_r13.to_json(j); - j.write_fieldname("freqInfo-r13"); - j.start_obj(); - if (freq_info_r13.ul_carrier_freq_r13_present) { - j.write_fieldname("ul-CarrierFreq-r13"); - freq_info_r13.ul_carrier_freq_r13.to_json(j); + j.write_str("cbp-HystTimer-r17", cbp_hyst_timer_r17.to_string()); + j.start_array("cbp-ConfigList-r17"); + for (const auto& e1 : cbp_cfg_list_r17) { + e1.to_json(j); } - j.write_int("additionalSpectrumEmission-r13", freq_info_r13.add_spec_emission_r13); + j.end_array(); j.end_obj(); - j.write_str("timeAlignmentTimerCommon-r13", time_align_timer_common_r13.to_string()); - if (multi_band_info_list_r13_present) { - j.start_array("multiBandInfoList-r13"); - for (const auto& e1 : multi_band_info_list_r13) { - j.write_int(e1); - } - j.end_array(); - } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (ext) { - if (cp_reest_r14_present) { - j.write_str("cp-Reestablishment-r14", "true"); - } - if (serving_cell_meas_info_r14_present) { - j.write_str("servingCellMeasInfo-r14", "true"); - } - if (cqi_report_r14_present) { - j.write_str("cqi-Reporting-r14", "true"); - } - if (enhanced_phr_r15_present) { - j.write_str("enhancedPHR-r15", "true"); - } - if (freq_info_v1530.is_present()) { - j.write_fieldname("freqInfo-v1530"); - j.start_obj(); - j.write_str("tdd-UL-DL-AlignmentOffset-r15", freq_info_v1530->tdd_ul_dl_align_offset_r15.to_string()); - j.end_obj(); - } - if (cp_edt_r15_present) { - j.write_str("cp-EDT-r15", "true"); - } - if (up_edt_r15_present) { - j.write_str("up-EDT-r15", "true"); - } - } +} + +const char* coverage_based_paging_cfg_nb_r17_s::cbp_hyst_timer_r17_opts::to_string() const +{ + static const char* options[] = {"ms2560", "ms7680", "ms12800", "ms17920", "ms23040", "ms28160", "ms33280", "ms40960"}; + return convert_enum_idx(options, 8, value, "coverage_based_paging_cfg_nb_r17_s::cbp_hyst_timer_r17_e_"); +} +uint16_t coverage_based_paging_cfg_nb_r17_s::cbp_hyst_timer_r17_opts::to_number() const +{ + static const uint16_t options[] = {2560, 7680, 12800, 17920, 23040, 28160, 33280, 40960}; + return map_enum_number(options, 8, value, "coverage_based_paging_cfg_nb_r17_s::cbp_hyst_timer_r17_e_"); +} + +// IntraFreqCellReselectionInfo-NB-v1350 ::= SEQUENCE +SRSASN_CODE intra_freq_cell_resel_info_nb_v1350_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, delta_rx_lev_min_v1350, (int8_t)-8, (int8_t)-1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE intra_freq_cell_resel_info_nb_v1350_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(delta_rx_lev_min_v1350, bref, (int8_t)-8, (int8_t)-1)); + + return SRSASN_SUCCESS; +} +void intra_freq_cell_resel_info_nb_v1350_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("delta-RxLevMin-v1350", delta_rx_lev_min_v1350); j.end_obj(); } -// SystemInformationBlockType20-NB-r14 ::= SEQUENCE -SRSASN_CODE sib_type20_nb_r14_s::pack(bit_ref& bref) const +// IntraFreqCellReselectionInfo-NB-v1360 ::= SEQUENCE +SRSASN_CODE intra_freq_cell_resel_info_nb_v1360_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(sc_mcch_sched_info_r14_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(pack_integer(bref, s_intra_search_p_v1360, (uint8_t)32u, (uint8_t)63u)); - HANDLE_CODE(npdcch_sc_mcch_cfg_r14.pack(bref)); - HANDLE_CODE(sc_mcch_carrier_cfg_r14.pack(bref)); - HANDLE_CODE(sc_mcch_repeat_period_r14.pack(bref)); - HANDLE_CODE(pack_integer(bref, sc_mcch_offset_r14, (uint8_t)0u, (uint8_t)10u)); - HANDLE_CODE(sc_mcch_mod_period_r14.pack(bref)); - if (sc_mcch_sched_info_r14_present) { - HANDLE_CODE(sc_mcch_sched_info_r14.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE intra_freq_cell_resel_info_nb_v1360_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(s_intra_search_p_v1360, bref, (uint8_t)32u, (uint8_t)63u)); + + return SRSASN_SUCCESS; +} +void intra_freq_cell_resel_info_nb_v1360_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("s-IntraSearchP-v1360", s_intra_search_p_v1360); + j.end_obj(); +} + +// IntraFreqCellReselectionInfo-NB-v1430 ::= SEQUENCE +SRSASN_CODE intra_freq_cell_resel_info_nb_v1430_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(pwr_class14dbm_offset_r14_present, 1)); + HANDLE_CODE(bref.pack(ce_authorisation_offset_r14_present, 1)); + + if (pwr_class14dbm_offset_r14_present) { + HANDLE_CODE(pwr_class14dbm_offset_r14.pack(bref)); } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); + if (ce_authorisation_offset_r14_present) { + HANDLE_CODE(ce_authorisation_offset_r14.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE sib_type20_nb_r14_s::unpack(cbit_ref& bref) +SRSASN_CODE intra_freq_cell_resel_info_nb_v1430_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(sc_mcch_sched_info_r14_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(pwr_class14dbm_offset_r14_present, 1)); + HANDLE_CODE(bref.unpack(ce_authorisation_offset_r14_present, 1)); - HANDLE_CODE(npdcch_sc_mcch_cfg_r14.unpack(bref)); - HANDLE_CODE(sc_mcch_carrier_cfg_r14.unpack(bref)); - HANDLE_CODE(sc_mcch_repeat_period_r14.unpack(bref)); - HANDLE_CODE(unpack_integer(sc_mcch_offset_r14, bref, (uint8_t)0u, (uint8_t)10u)); - HANDLE_CODE(sc_mcch_mod_period_r14.unpack(bref)); - if (sc_mcch_sched_info_r14_present) { - HANDLE_CODE(sc_mcch_sched_info_r14.unpack(bref)); + if (pwr_class14dbm_offset_r14_present) { + HANDLE_CODE(pwr_class14dbm_offset_r14.unpack(bref)); } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + if (ce_authorisation_offset_r14_present) { + HANDLE_CODE(ce_authorisation_offset_r14.unpack(bref)); } return SRSASN_SUCCESS; } -void sib_type20_nb_r14_s::to_json(json_writer& j) const +void intra_freq_cell_resel_info_nb_v1430_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("npdcch-SC-MCCH-Config-r14"); - npdcch_sc_mcch_cfg_r14.to_json(j); - j.write_fieldname("sc-mcch-CarrierConfig-r14"); - sc_mcch_carrier_cfg_r14.to_json(j); - j.write_str("sc-mcch-RepetitionPeriod-r14", sc_mcch_repeat_period_r14.to_string()); - j.write_int("sc-mcch-Offset-r14", sc_mcch_offset_r14); - j.write_str("sc-mcch-ModificationPeriod-r14", sc_mcch_mod_period_r14.to_string()); - if (sc_mcch_sched_info_r14_present) { - j.write_fieldname("sc-mcch-SchedulingInfo-r14"); - sc_mcch_sched_info_r14.to_json(j); + if (pwr_class14dbm_offset_r14_present) { + j.write_str("powerClass14dBm-Offset-r14", pwr_class14dbm_offset_r14.to_string()); } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + if (ce_authorisation_offset_r14_present) { + j.write_str("ce-AuthorisationOffset-r14", ce_authorisation_offset_r14.to_string()); } j.end_obj(); } -void sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::destroy_() +const char* intra_freq_cell_resel_info_nb_v1430_s::pwr_class14dbm_offset_r14_opts::to_string() const { - switch (type_) { - case types::dl_carrier_cfg_r14: - c.destroy(); - break; - default: - break; - } + static const char* options[] = {"dB-6", "dB-3", "dB3", "dB6", "dB9", "dB12"}; + return convert_enum_idx(options, 6, value, "intra_freq_cell_resel_info_nb_v1430_s::pwr_class14dbm_offset_r14_e_"); } -void sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::set(types::options e) +int8_t intra_freq_cell_resel_info_nb_v1430_s::pwr_class14dbm_offset_r14_opts::to_number() const { - destroy_(); - type_ = e; - switch (type_) { - case types::dl_carrier_cfg_r14: - c.init(); - break; - case types::dl_carrier_idx_r14: - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); - } -} -sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::sc_mcch_carrier_cfg_r14_c_( - const sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_& other) + static const int8_t options[] = {-6, -3, 3, 6, 9, 12}; + return map_enum_number(options, 6, value, "intra_freq_cell_resel_info_nb_v1430_s::pwr_class14dbm_offset_r14_e_"); +} + +const char* intra_freq_cell_resel_info_nb_v1430_s::ce_authorisation_offset_r14_opts::to_string() const { - type_ = other.type(); - switch (type_) { - case types::dl_carrier_cfg_r14: - c.init(other.c.get()); - break; - case types::dl_carrier_idx_r14: - c.init(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); - } + static const char* options[] = {"dB5", "dB10", "dB15", "dB20", "dB25", "dB30", "dB35"}; + return convert_enum_idx(options, 7, value, "intra_freq_cell_resel_info_nb_v1430_s::ce_authorisation_offset_r14_e_"); } -sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_& -sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::operator=(const sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_& other) +uint8_t intra_freq_cell_resel_info_nb_v1430_s::ce_authorisation_offset_r14_opts::to_number() const { - if (this == &other) { - return *this; - } - set(other.type()); - switch (type_) { - case types::dl_carrier_cfg_r14: - c.set(other.c.get()); - break; - case types::dl_carrier_idx_r14: - c.set(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); - } - - return *this; + static const uint8_t options[] = {5, 10, 15, 20, 25, 30, 35}; + return map_enum_number(options, 7, value, "intra_freq_cell_resel_info_nb_v1430_s::ce_authorisation_offset_r14_e_"); } -dl_carrier_cfg_common_nb_r14_s& sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::set_dl_carrier_cfg_r14() + +// NPDCCH-SC-MCCH-Config-NB-r14 ::= SEQUENCE +SRSASN_CODE npdcch_sc_mcch_cfg_nb_r14_s::pack(bit_ref& bref) const { - set(types::dl_carrier_cfg_r14); - return c.get(); + HANDLE_CODE(npdcch_num_repeats_sc_mcch_r14.pack(bref)); + HANDLE_CODE(npdcch_start_sf_sc_mcch_r14.pack(bref)); + HANDLE_CODE(npdcch_offset_sc_mcch_r14.pack(bref)); + + return SRSASN_SUCCESS; } -uint8_t& sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::set_dl_carrier_idx_r14() +SRSASN_CODE npdcch_sc_mcch_cfg_nb_r14_s::unpack(cbit_ref& bref) { - set(types::dl_carrier_idx_r14); - return c.get(); + HANDLE_CODE(npdcch_num_repeats_sc_mcch_r14.unpack(bref)); + HANDLE_CODE(npdcch_start_sf_sc_mcch_r14.unpack(bref)); + HANDLE_CODE(npdcch_offset_sc_mcch_r14.unpack(bref)); + + return SRSASN_SUCCESS; } -void sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::to_json(json_writer& j) const +void npdcch_sc_mcch_cfg_nb_r14_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::dl_carrier_cfg_r14: - j.write_fieldname("dl-CarrierConfig-r14"); - c.get().to_json(j); - break; - case types::dl_carrier_idx_r14: - j.write_int("dl-CarrierIndex-r14", c.get()); - break; - default: - log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); - } + j.write_str("npdcch-NumRepetitions-SC-MCCH-r14", npdcch_num_repeats_sc_mcch_r14.to_string()); + j.write_str("npdcch-StartSF-SC-MCCH-r14", npdcch_start_sf_sc_mcch_r14.to_string()); + j.write_str("npdcch-Offset-SC-MCCH-r14", npdcch_offset_sc_mcch_r14.to_string()); j.end_obj(); } -SRSASN_CODE sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::pack(bit_ref& bref) const + +const char* npdcch_sc_mcch_cfg_nb_r14_s::npdcch_num_repeats_sc_mcch_r14_opts::to_string() const { - type_.pack(bref); - switch (type_) { - case types::dl_carrier_cfg_r14: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::dl_carrier_idx_r14: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)15u)); - break; - default: - log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); - return SRSASN_ERROR_ENCODE_FAIL; - } - return SRSASN_SUCCESS; + static const char* options[] = { + "r1", "r2", "r4", "r8", "r16", "r32", "r64", "r128", "r256", "r512", "r1024", "r2048"}; + return convert_enum_idx(options, 12, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_num_repeats_sc_mcch_r14_e_"); } -SRSASN_CODE sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::unpack(cbit_ref& bref) +uint16_t npdcch_sc_mcch_cfg_nb_r14_s::npdcch_num_repeats_sc_mcch_r14_opts::to_number() const { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::dl_carrier_cfg_r14: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::dl_carrier_idx_r14: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)15u)); - break; - default: - log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; + return map_enum_number(options, 12, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_num_repeats_sc_mcch_r14_e_"); } -const char* sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::types_opts::to_string() const +const char* npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_opts::to_string() const { - static const char* options[] = {"dl-CarrierConfig-r14", "dl-CarrierIndex-r14"}; - return convert_enum_idx(options, 2, value, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::types"); + static const char* options[] = {"v1dot5", "v2", "v4", "v8", "v16", "v32", "v48", "v64"}; + return convert_enum_idx(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_e_"); } - -const char* sib_type20_nb_r14_s::sc_mcch_repeat_period_r14_opts::to_string() const +float npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_opts::to_number() const { - static const char* options[] = {"rf32", "rf128", "rf512", "rf1024", "rf2048", "rf4096", "rf8192", "rf16384"}; - return convert_enum_idx(options, 8, value, "sib_type20_nb_r14_s::sc_mcch_repeat_period_r14_e_"); + static const float options[] = {1.5, 2.0, 4.0, 8.0, 16.0, 32.0, 48.0, 64.0}; + return map_enum_number(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_e_"); } -uint16_t sib_type20_nb_r14_s::sc_mcch_repeat_period_r14_opts::to_number() const +const char* npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_opts::to_number_string() const { - static const uint16_t options[] = {32, 128, 512, 1024, 2048, 4096, 8192, 16384}; - return map_enum_number(options, 8, value, "sib_type20_nb_r14_s::sc_mcch_repeat_period_r14_e_"); + static const char* options[] = {"1.5", "2", "4", "8", "16", "32", "48", "64"}; + return convert_enum_idx(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_start_sf_sc_mcch_r14_e_"); } -const char* sib_type20_nb_r14_s::sc_mcch_mod_period_r14_opts::to_string() const +const char* npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_opts::to_string() const { - static const char* options[] = {"rf32", - "rf128", - "rf256", - "rf512", - "rf1024", - "rf2048", - "rf4096", - "rf8192", - "rf16384", - "rf32768", - "rf65536", - "rf131072", - "rf262144", - "rf524288", - "rf1048576", - "spare1"}; - return convert_enum_idx(options, 16, value, "sib_type20_nb_r14_s::sc_mcch_mod_period_r14_e_"); + static const char* options[] = { + "zero", "oneEighth", "oneQuarter", "threeEighth", "oneHalf", "fiveEighth", "threeQuarter", "sevenEighth"}; + return convert_enum_idx(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_e_"); } -uint32_t sib_type20_nb_r14_s::sc_mcch_mod_period_r14_opts::to_number() const +float npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_opts::to_number() const { - static const uint32_t options[] = { - 32, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576}; - return map_enum_number(options, 15, value, "sib_type20_nb_r14_s::sc_mcch_mod_period_r14_e_"); + static const float options[] = {0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875}; + return map_enum_number(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_e_"); +} +const char* npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_opts::to_number_string() const +{ + static const char* options[] = {"0", "1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "7/8"}; + return convert_enum_idx(options, 8, value, "npdcch_sc_mcch_cfg_nb_r14_s::npdcch_offset_sc_mcch_r14_e_"); } -// SystemInformationBlockType22-NB-r14 ::= SEQUENCE -SRSASN_CODE sib_type22_nb_r14_s::pack(bit_ref& bref) const +// RadioResourceConfigCommonSIB-NB-r13 ::= SEQUENCE +SRSASN_CODE rr_cfg_common_sib_nb_r13_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(dl_cfg_list_r14_present, 1)); - HANDLE_CODE(bref.pack(ul_cfg_list_r14_present, 1)); - HANDLE_CODE(bref.pack(paging_weight_anchor_r14_present, 1)); - HANDLE_CODE(bref.pack(nprach_probability_anchor_list_r14_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(dl_gap_r13_present, 1)); - if (dl_cfg_list_r14_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, dl_cfg_list_r14, 1, 15)); - } - if (ul_cfg_list_r14_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, ul_cfg_list_r14, 1, 15)); - } - if (paging_weight_anchor_r14_present) { - HANDLE_CODE(paging_weight_anchor_r14.pack(bref)); - } - if (nprach_probability_anchor_list_r14_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, nprach_probability_anchor_list_r14, 1, 3)); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); + HANDLE_CODE(rach_cfg_common_r13.pack(bref)); + HANDLE_CODE(bcch_cfg_r13.pack(bref)); + HANDLE_CODE(pcch_cfg_r13.pack(bref)); + HANDLE_CODE(nprach_cfg_r13.pack(bref)); + HANDLE_CODE(npdsch_cfg_common_r13.pack(bref)); + HANDLE_CODE(npusch_cfg_common_r13.pack(bref)); + if (dl_gap_r13_present) { + HANDLE_CODE(dl_gap_r13.pack(bref)); } + HANDLE_CODE(ul_pwr_ctrl_common_r13.pack(bref)); if (ext) { ext_groups_packer_guard group_flags; - group_flags[0] |= mixed_operation_mode_cfg_r15.is_present(); - group_flags[0] |= ul_cfg_list_r15.is_present(); + group_flags[0] |= nprach_cfg_v1330.is_present(); + group_flags[1] |= nprach_cfg_v1450.is_present(); + group_flags[2] |= nprach_cfg_v1530.is_present(); + group_flags[2] |= dl_gap_v1530.is_present(); + group_flags[2] |= wus_cfg_r15.is_present(); + group_flags[3] |= nprach_cfg_v1550.is_present(); + group_flags[4] |= gwus_cfg_r16.is_present(); + group_flags[4] |= nrs_non_anchor_cfg_r16_present; + group_flags[4] |= ue_specific_drx_cycle_min_r16_present; + group_flags[5] |= ntn_cfg_common_r17.is_present(); group_flags.pack(bref); if (group_flags[0]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(mixed_operation_mode_cfg_r15.is_present(), 1)); - HANDLE_CODE(bref.pack(ul_cfg_list_r15.is_present(), 1)); - if (mixed_operation_mode_cfg_r15.is_present()) { - HANDLE_CODE(bref.pack(mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15_present, 1)); - HANDLE_CODE(bref.pack(mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15_present, 1)); - HANDLE_CODE(bref.pack(mixed_operation_mode_cfg_r15->paging_distribution_r15_present, 1)); - HANDLE_CODE(bref.pack(mixed_operation_mode_cfg_r15->nprach_distribution_r15_present, 1)); - if (mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15, 1, 15)); - } - if (mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15, 1, 15)); - } + HANDLE_CODE(bref.pack(nprach_cfg_v1330.is_present(), 1)); + if (nprach_cfg_v1330.is_present()) { + HANDLE_CODE(nprach_cfg_v1330->pack(bref)); } - if (ul_cfg_list_r15.is_present()) { - HANDLE_CODE(pack_dyn_seq_of(bref, *ul_cfg_list_r15, 1, 15)); + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(nprach_cfg_v1450.is_present(), 1)); + if (nprach_cfg_v1450.is_present()) { + HANDLE_CODE(nprach_cfg_v1450->pack(bref)); } } - } - return SRSASN_SUCCESS; -} -SRSASN_CODE sib_type22_nb_r14_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(dl_cfg_list_r14_present, 1)); - HANDLE_CODE(bref.unpack(ul_cfg_list_r14_present, 1)); - HANDLE_CODE(bref.unpack(paging_weight_anchor_r14_present, 1)); - HANDLE_CODE(bref.unpack(nprach_probability_anchor_list_r14_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); - if (dl_cfg_list_r14_present) { - HANDLE_CODE(unpack_dyn_seq_of(dl_cfg_list_r14, bref, 1, 15)); - } - if (ul_cfg_list_r14_present) { - HANDLE_CODE(unpack_dyn_seq_of(ul_cfg_list_r14, bref, 1, 15)); - } - if (paging_weight_anchor_r14_present) { - HANDLE_CODE(paging_weight_anchor_r14.unpack(bref)); - } - if (nprach_probability_anchor_list_r14_present) { - HANDLE_CODE(unpack_dyn_seq_of(nprach_probability_anchor_list_r14, bref, 1, 3)); + HANDLE_CODE(bref.pack(nprach_cfg_v1530.is_present(), 1)); + HANDLE_CODE(bref.pack(dl_gap_v1530.is_present(), 1)); + HANDLE_CODE(bref.pack(wus_cfg_r15.is_present(), 1)); + if (nprach_cfg_v1530.is_present()) { + HANDLE_CODE(nprach_cfg_v1530->pack(bref)); + } + if (dl_gap_v1530.is_present()) { + HANDLE_CODE(dl_gap_v1530->pack(bref)); + } + if (wus_cfg_r15.is_present()) { + HANDLE_CODE(wus_cfg_r15->pack(bref)); + } + } + if (group_flags[3]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(nprach_cfg_v1550.is_present(), 1)); + if (nprach_cfg_v1550.is_present()) { + HANDLE_CODE(nprach_cfg_v1550->pack(bref)); + } + } + if (group_flags[4]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(gwus_cfg_r16.is_present(), 1)); + HANDLE_CODE(bref.pack(nrs_non_anchor_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(ue_specific_drx_cycle_min_r16_present, 1)); + if (gwus_cfg_r16.is_present()) { + HANDLE_CODE(gwus_cfg_r16->pack(bref)); + } + if (ue_specific_drx_cycle_min_r16_present) { + HANDLE_CODE(ue_specific_drx_cycle_min_r16.pack(bref)); + } + } + if (group_flags[5]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ntn_cfg_common_r17.is_present(), 1)); + if (ntn_cfg_common_r17.is_present()) { + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->ta_report_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->nprach_tx_dur_fmt01_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->nprach_tx_dur_fmt2_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_cfg_common_r17->npusch_tx_dur_r17_present, 1)); + HANDLE_CODE(ntn_cfg_common_r17->t318_r17.pack(bref)); + if (ntn_cfg_common_r17->nprach_tx_dur_fmt01_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->nprach_tx_dur_fmt01_r17.pack(bref)); + } + if (ntn_cfg_common_r17->nprach_tx_dur_fmt2_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->nprach_tx_dur_fmt2_r17.pack(bref)); + } + if (ntn_cfg_common_r17->npusch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->npusch_tx_dur_r17.pack(bref)); + } + } + } } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE rr_cfg_common_sib_nb_r13_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(dl_gap_r13_present, 1)); + + HANDLE_CODE(rach_cfg_common_r13.unpack(bref)); + HANDLE_CODE(bcch_cfg_r13.unpack(bref)); + HANDLE_CODE(pcch_cfg_r13.unpack(bref)); + HANDLE_CODE(nprach_cfg_r13.unpack(bref)); + HANDLE_CODE(npdsch_cfg_common_r13.unpack(bref)); + HANDLE_CODE(npusch_cfg_common_r13.unpack(bref)); + if (dl_gap_r13_present) { + HANDLE_CODE(dl_gap_r13.unpack(bref)); } + HANDLE_CODE(ul_pwr_ctrl_common_r13.unpack(bref)); if (ext) { - ext_groups_unpacker_guard group_flags(1); + ext_groups_unpacker_guard group_flags(6); group_flags.unpack(bref); if (group_flags[0]) { varlength_field_unpack_guard varlen_scope(bref, false); - bool mixed_operation_mode_cfg_r15_present; - HANDLE_CODE(bref.unpack(mixed_operation_mode_cfg_r15_present, 1)); - mixed_operation_mode_cfg_r15.set_present(mixed_operation_mode_cfg_r15_present); - bool ul_cfg_list_r15_present; - HANDLE_CODE(bref.unpack(ul_cfg_list_r15_present, 1)); - ul_cfg_list_r15.set_present(ul_cfg_list_r15_present); - if (mixed_operation_mode_cfg_r15.is_present()) { - HANDLE_CODE(bref.unpack(mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15_present, 1)); - HANDLE_CODE(bref.unpack(mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15_present, 1)); - HANDLE_CODE(bref.unpack(mixed_operation_mode_cfg_r15->paging_distribution_r15_present, 1)); - HANDLE_CODE(bref.unpack(mixed_operation_mode_cfg_r15->nprach_distribution_r15_present, 1)); - if (mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15, bref, 1, 15)); + bool nprach_cfg_v1330_present; + HANDLE_CODE(bref.unpack(nprach_cfg_v1330_present, 1)); + nprach_cfg_v1330.set_present(nprach_cfg_v1330_present); + if (nprach_cfg_v1330.is_present()) { + HANDLE_CODE(nprach_cfg_v1330->unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool nprach_cfg_v1450_present; + HANDLE_CODE(bref.unpack(nprach_cfg_v1450_present, 1)); + nprach_cfg_v1450.set_present(nprach_cfg_v1450_present); + if (nprach_cfg_v1450.is_present()) { + HANDLE_CODE(nprach_cfg_v1450->unpack(bref)); + } + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool nprach_cfg_v1530_present; + HANDLE_CODE(bref.unpack(nprach_cfg_v1530_present, 1)); + nprach_cfg_v1530.set_present(nprach_cfg_v1530_present); + bool dl_gap_v1530_present; + HANDLE_CODE(bref.unpack(dl_gap_v1530_present, 1)); + dl_gap_v1530.set_present(dl_gap_v1530_present); + bool wus_cfg_r15_present; + HANDLE_CODE(bref.unpack(wus_cfg_r15_present, 1)); + wus_cfg_r15.set_present(wus_cfg_r15_present); + if (nprach_cfg_v1530.is_present()) { + HANDLE_CODE(nprach_cfg_v1530->unpack(bref)); + } + if (dl_gap_v1530.is_present()) { + HANDLE_CODE(dl_gap_v1530->unpack(bref)); + } + if (wus_cfg_r15.is_present()) { + HANDLE_CODE(wus_cfg_r15->unpack(bref)); + } + } + if (group_flags[3]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool nprach_cfg_v1550_present; + HANDLE_CODE(bref.unpack(nprach_cfg_v1550_present, 1)); + nprach_cfg_v1550.set_present(nprach_cfg_v1550_present); + if (nprach_cfg_v1550.is_present()) { + HANDLE_CODE(nprach_cfg_v1550->unpack(bref)); + } + } + if (group_flags[4]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool gwus_cfg_r16_present; + HANDLE_CODE(bref.unpack(gwus_cfg_r16_present, 1)); + gwus_cfg_r16.set_present(gwus_cfg_r16_present); + HANDLE_CODE(bref.unpack(nrs_non_anchor_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(ue_specific_drx_cycle_min_r16_present, 1)); + if (gwus_cfg_r16.is_present()) { + HANDLE_CODE(gwus_cfg_r16->unpack(bref)); + } + if (ue_specific_drx_cycle_min_r16_present) { + HANDLE_CODE(ue_specific_drx_cycle_min_r16.unpack(bref)); + } + } + if (group_flags[5]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool ntn_cfg_common_r17_present; + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17_present, 1)); + ntn_cfg_common_r17.set_present(ntn_cfg_common_r17_present); + if (ntn_cfg_common_r17.is_present()) { + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->ta_report_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->nprach_tx_dur_fmt01_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->nprach_tx_dur_fmt2_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_cfg_common_r17->npusch_tx_dur_r17_present, 1)); + HANDLE_CODE(ntn_cfg_common_r17->t318_r17.unpack(bref)); + if (ntn_cfg_common_r17->nprach_tx_dur_fmt01_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->nprach_tx_dur_fmt01_r17.unpack(bref)); } - if (mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15_present) { - HANDLE_CODE(unpack_dyn_seq_of(mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15, bref, 1, 15)); + if (ntn_cfg_common_r17->nprach_tx_dur_fmt2_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->nprach_tx_dur_fmt2_r17.unpack(bref)); + } + if (ntn_cfg_common_r17->npusch_tx_dur_r17_present) { + HANDLE_CODE(ntn_cfg_common_r17->npusch_tx_dur_r17.unpack(bref)); } - } - if (ul_cfg_list_r15.is_present()) { - HANDLE_CODE(unpack_dyn_seq_of(*ul_cfg_list_r15, bref, 1, 15)); } } } return SRSASN_SUCCESS; } -void sib_type22_nb_r14_s::to_json(json_writer& j) const +void rr_cfg_common_sib_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - if (dl_cfg_list_r14_present) { - j.start_array("dl-ConfigList-r14"); - for (const auto& e1 : dl_cfg_list_r14) { - e1.to_json(j); - } - j.end_array(); + j.write_fieldname("rach-ConfigCommon-r13"); + rach_cfg_common_r13.to_json(j); + j.write_fieldname("bcch-Config-r13"); + bcch_cfg_r13.to_json(j); + j.write_fieldname("pcch-Config-r13"); + pcch_cfg_r13.to_json(j); + j.write_fieldname("nprach-Config-r13"); + nprach_cfg_r13.to_json(j); + j.write_fieldname("npdsch-ConfigCommon-r13"); + npdsch_cfg_common_r13.to_json(j); + j.write_fieldname("npusch-ConfigCommon-r13"); + npusch_cfg_common_r13.to_json(j); + if (dl_gap_r13_present) { + j.write_fieldname("dl-Gap-r13"); + dl_gap_r13.to_json(j); } - if (ul_cfg_list_r14_present) { - j.start_array("ul-ConfigList-r14"); - for (const auto& e1 : ul_cfg_list_r14) { - e1.to_json(j); + j.write_fieldname("uplinkPowerControlCommon-r13"); + ul_pwr_ctrl_common_r13.to_json(j); + if (ext) { + if (nprach_cfg_v1330.is_present()) { + j.write_fieldname("nprach-Config-v1330"); + nprach_cfg_v1330->to_json(j); } - j.end_array(); - } - if (paging_weight_anchor_r14_present) { - j.write_str("pagingWeightAnchor-r14", paging_weight_anchor_r14.to_string()); - } - if (nprach_probability_anchor_list_r14_present) { - j.start_array("nprach-ProbabilityAnchorList-r14"); - for (const auto& e1 : nprach_probability_anchor_list_r14) { - e1.to_json(j); + if (nprach_cfg_v1450.is_present()) { + j.write_fieldname("nprach-Config-v1450"); + nprach_cfg_v1450->to_json(j); } - j.end_array(); - } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (ext) { - if (mixed_operation_mode_cfg_r15.is_present()) { - j.write_fieldname("mixedOperationModeConfig-r15"); + if (nprach_cfg_v1530.is_present()) { + j.write_fieldname("nprach-Config-v1530"); + nprach_cfg_v1530->to_json(j); + } + if (dl_gap_v1530.is_present()) { + j.write_fieldname("dl-Gap-v1530"); + dl_gap_v1530->to_json(j); + } + if (wus_cfg_r15.is_present()) { + j.write_fieldname("wus-Config-r15"); + wus_cfg_r15->to_json(j); + } + if (nprach_cfg_v1550.is_present()) { + j.write_fieldname("nprach-Config-v1550"); + nprach_cfg_v1550->to_json(j); + } + if (gwus_cfg_r16.is_present()) { + j.write_fieldname("gwus-Config-r16"); + gwus_cfg_r16->to_json(j); + } + if (nrs_non_anchor_cfg_r16_present) { + j.write_str("nrs-NonAnchorConfig-r16", "true"); + } + if (ue_specific_drx_cycle_min_r16_present) { + j.write_str("ue-SpecificDRX-CycleMin-r16", ue_specific_drx_cycle_min_r16.to_string()); + } + if (ntn_cfg_common_r17.is_present()) { + j.write_fieldname("ntn-ConfigCommon-r17"); j.start_obj(); - if (mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15_present) { - j.start_array("dl-ConfigListMixed-r15"); - for (const auto& e1 : mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15) { - e1.to_json(j); - } - j.end_array(); + if (ntn_cfg_common_r17->ta_report_r17_present) { + j.write_str("ta-Report-r17", "enabled"); } - if (mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15_present) { - j.start_array("ul-ConfigListMixed-r15"); - for (const auto& e1 : mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15) { - e1.to_json(j); - } - j.end_array(); + j.write_str("t318-r17", ntn_cfg_common_r17->t318_r17.to_string()); + if (ntn_cfg_common_r17->nprach_tx_dur_fmt01_r17_present) { + j.write_fieldname("nprach-TxDurationFmt01-r17"); + ntn_cfg_common_r17->nprach_tx_dur_fmt01_r17.to_json(j); } - if (mixed_operation_mode_cfg_r15->paging_distribution_r15_present) { - j.write_str("pagingDistribution-r15", "true"); + if (ntn_cfg_common_r17->nprach_tx_dur_fmt2_r17_present) { + j.write_fieldname("nprach-TxDurationFmt2-r17"); + ntn_cfg_common_r17->nprach_tx_dur_fmt2_r17.to_json(j); } - if (mixed_operation_mode_cfg_r15->nprach_distribution_r15_present) { - j.write_str("nprach-Distribution-r15", "true"); + if (ntn_cfg_common_r17->npusch_tx_dur_r17_present) { + j.write_fieldname("npusch-TxDuration-r17"); + ntn_cfg_common_r17->npusch_tx_dur_r17.to_json(j); } j.end_obj(); } - if (ul_cfg_list_r15.is_present()) { - j.start_array("ul-ConfigList-r15"); - for (const auto& e1 : *ul_cfg_list_r15) { - e1.to_json(j); - } - j.end_array(); - } } j.end_obj(); } -// SystemInformationBlockType23-NB-r15 ::= SEQUENCE -SRSASN_CODE sib_type23_nb_r15_s::pack(bit_ref& bref) const +const char* rr_cfg_common_sib_nb_r13_s::ue_specific_drx_cycle_min_r16_opts::to_string() const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(ul_cfg_list_v1530_present, 1)); - HANDLE_CODE(bref.pack(ul_cfg_list_mixed_v1530_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - - if (ul_cfg_list_v1530_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, ul_cfg_list_v1530, 1, 15)); - } - if (ul_cfg_list_mixed_v1530_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, ul_cfg_list_mixed_v1530, 1, 15)); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); - } - - return SRSASN_SUCCESS; + static const char* options[] = {"rf32", "rf64", "rf128", "rf256", "rf512", "rf1024"}; + return convert_enum_idx(options, 6, value, "rr_cfg_common_sib_nb_r13_s::ue_specific_drx_cycle_min_r16_e_"); } -SRSASN_CODE sib_type23_nb_r15_s::unpack(cbit_ref& bref) +uint16_t rr_cfg_common_sib_nb_r13_s::ue_specific_drx_cycle_min_r16_opts::to_number() const { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(ul_cfg_list_v1530_present, 1)); - HANDLE_CODE(bref.unpack(ul_cfg_list_mixed_v1530_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + static const uint16_t options[] = {32, 64, 128, 256, 512, 1024}; + return map_enum_number(options, 6, value, "rr_cfg_common_sib_nb_r13_s::ue_specific_drx_cycle_min_r16_e_"); +} - if (ul_cfg_list_v1530_present) { - HANDLE_CODE(unpack_dyn_seq_of(ul_cfg_list_v1530, bref, 1, 15)); - } - if (ul_cfg_list_mixed_v1530_present) { - HANDLE_CODE(unpack_dyn_seq_of(ul_cfg_list_mixed_v1530, bref, 1, 15)); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); - } - - return SRSASN_SUCCESS; +const char* rr_cfg_common_sib_nb_r13_s::ntn_cfg_common_r17_s_::t318_r17_opts::to_string() const +{ + static const char* options[] = {"ms0", "ms200", "ms500", "ms1000", "ms2000", "ms4000", "ms8000"}; + return convert_enum_idx(options, 7, value, "rr_cfg_common_sib_nb_r13_s::ntn_cfg_common_r17_s_::t318_r17_e_"); } -void sib_type23_nb_r15_s::to_json(json_writer& j) const +uint16_t rr_cfg_common_sib_nb_r13_s::ntn_cfg_common_r17_s_::t318_r17_opts::to_number() const { - j.start_obj(); - if (ul_cfg_list_v1530_present) { - j.start_array("ul-ConfigList-v1530"); - for (const auto& e1 : ul_cfg_list_v1530) { - e1.to_json(j); - } - j.end_array(); - } - if (ul_cfg_list_mixed_v1530_present) { - j.start_array("ul-ConfigListMixed-v1530"); - for (const auto& e1 : ul_cfg_list_mixed_v1530) { - e1.to_json(j); - } - j.end_array(); - } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - j.end_obj(); + static const uint16_t options[] = {0, 200, 500, 1000, 2000, 4000, 8000}; + return map_enum_number(options, 7, value, "rr_cfg_common_sib_nb_r13_s::ntn_cfg_common_r17_s_::t318_r17_e_"); } -// SystemInformationBlockType3-NB-r13 ::= SEQUENCE -SRSASN_CODE sib_type3_nb_r13_s::pack(bit_ref& bref) const +// SC-MCCH-SchedulingInfo-NB-r14 ::= SEQUENCE +SRSASN_CODE sc_mcch_sched_info_nb_r14_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(freq_band_info_r13_present, 1)); - HANDLE_CODE(bref.pack(multi_band_info_list_r13_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - - HANDLE_CODE(cell_resel_info_common_r13.q_hyst_r13.pack(bref)); - HANDLE_CODE(pack_integer(bref, cell_resel_serving_freq_info_r13.s_non_intra_search_r13, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(bref.pack(intra_freq_cell_resel_info_r13.q_qual_min_r13_present, 1)); - HANDLE_CODE(bref.pack(intra_freq_cell_resel_info_r13.p_max_r13_present, 1)); - HANDLE_CODE(pack_integer(bref, intra_freq_cell_resel_info_r13.q_rx_lev_min_r13, (int8_t)-70, (int8_t)-22)); - if (intra_freq_cell_resel_info_r13.q_qual_min_r13_present) { - HANDLE_CODE(pack_integer(bref, intra_freq_cell_resel_info_r13.q_qual_min_r13, (int8_t)-34, (int8_t)-3)); - } - if (intra_freq_cell_resel_info_r13.p_max_r13_present) { - HANDLE_CODE(pack_integer(bref, intra_freq_cell_resel_info_r13.p_max_r13, (int8_t)-30, (int8_t)33)); - } - HANDLE_CODE(pack_integer(bref, intra_freq_cell_resel_info_r13.s_intra_search_p_r13, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(intra_freq_cell_resel_info_r13.t_resel_r13.pack(bref)); - if (freq_band_info_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_info_r13, 1, 4)); - } - if (multi_band_info_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, multi_band_info_list_r13, 1, 8, SeqOfPacker(1, 4, Packer()))); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); - } - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= intra_freq_cell_resel_info_v1350.is_present(); - group_flags[1] |= intra_freq_cell_resel_info_v1360.is_present(); - group_flags[2] |= intra_freq_cell_resel_info_v1430.is_present(); - group_flags[3] |= cell_resel_info_common_v1450.is_present(); - group_flags[4] |= nsss_rrm_cfg_r15.is_present(); - group_flags[4] |= npbch_rrm_cfg_r15_present; - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(intra_freq_cell_resel_info_v1350.is_present(), 1)); - if (intra_freq_cell_resel_info_v1350.is_present()) { - HANDLE_CODE(intra_freq_cell_resel_info_v1350->pack(bref)); - } - } - if (group_flags[1]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(intra_freq_cell_resel_info_v1360.is_present(), 1)); - if (intra_freq_cell_resel_info_v1360.is_present()) { - HANDLE_CODE(intra_freq_cell_resel_info_v1360->pack(bref)); - } - } - if (group_flags[2]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(intra_freq_cell_resel_info_v1430.is_present(), 1)); - if (intra_freq_cell_resel_info_v1430.is_present()) { - HANDLE_CODE(intra_freq_cell_resel_info_v1430->pack(bref)); - } - } - if (group_flags[3]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(cell_resel_info_common_v1450.is_present(), 1)); - if (cell_resel_info_common_v1450.is_present()) { - HANDLE_CODE(cell_resel_info_common_v1450->pack(bref)); - } - } - if (group_flags[4]) { - varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(on_dur_timer_scptm_r14.pack(bref)); + HANDLE_CODE(drx_inactivity_timer_scptm_r14.pack(bref)); + HANDLE_CODE(sched_period_start_offset_scptm_r14.pack(bref)); - HANDLE_CODE(bref.pack(nsss_rrm_cfg_r15.is_present(), 1)); - HANDLE_CODE(bref.pack(npbch_rrm_cfg_r15_present, 1)); - if (nsss_rrm_cfg_r15.is_present()) { - HANDLE_CODE(nsss_rrm_cfg_r15->pack(bref)); - } - } - } return SRSASN_SUCCESS; } -SRSASN_CODE sib_type3_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE sc_mcch_sched_info_nb_r14_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(freq_band_info_r13_present, 1)); - HANDLE_CODE(bref.unpack(multi_band_info_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - - HANDLE_CODE(cell_resel_info_common_r13.q_hyst_r13.unpack(bref)); - HANDLE_CODE(unpack_integer(cell_resel_serving_freq_info_r13.s_non_intra_search_r13, bref, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(bref.unpack(intra_freq_cell_resel_info_r13.q_qual_min_r13_present, 1)); - HANDLE_CODE(bref.unpack(intra_freq_cell_resel_info_r13.p_max_r13_present, 1)); - HANDLE_CODE(unpack_integer(intra_freq_cell_resel_info_r13.q_rx_lev_min_r13, bref, (int8_t)-70, (int8_t)-22)); - if (intra_freq_cell_resel_info_r13.q_qual_min_r13_present) { - HANDLE_CODE(unpack_integer(intra_freq_cell_resel_info_r13.q_qual_min_r13, bref, (int8_t)-34, (int8_t)-3)); - } - if (intra_freq_cell_resel_info_r13.p_max_r13_present) { - HANDLE_CODE(unpack_integer(intra_freq_cell_resel_info_r13.p_max_r13, bref, (int8_t)-30, (int8_t)33)); - } - HANDLE_CODE(unpack_integer(intra_freq_cell_resel_info_r13.s_intra_search_p_r13, bref, (uint8_t)0u, (uint8_t)31u)); - HANDLE_CODE(intra_freq_cell_resel_info_r13.t_resel_r13.unpack(bref)); - if (freq_band_info_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(freq_band_info_r13, bref, 1, 4)); - } - if (multi_band_info_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r13, bref, 1, 8, SeqOfPacker(1, 4, Packer()))); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); - } - - if (ext) { - ext_groups_unpacker_guard group_flags(5); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool intra_freq_cell_resel_info_v1350_present; - HANDLE_CODE(bref.unpack(intra_freq_cell_resel_info_v1350_present, 1)); - intra_freq_cell_resel_info_v1350.set_present(intra_freq_cell_resel_info_v1350_present); - if (intra_freq_cell_resel_info_v1350.is_present()) { - HANDLE_CODE(intra_freq_cell_resel_info_v1350->unpack(bref)); - } - } - if (group_flags[1]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool intra_freq_cell_resel_info_v1360_present; - HANDLE_CODE(bref.unpack(intra_freq_cell_resel_info_v1360_present, 1)); - intra_freq_cell_resel_info_v1360.set_present(intra_freq_cell_resel_info_v1360_present); - if (intra_freq_cell_resel_info_v1360.is_present()) { - HANDLE_CODE(intra_freq_cell_resel_info_v1360->unpack(bref)); - } - } - if (group_flags[2]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool intra_freq_cell_resel_info_v1430_present; - HANDLE_CODE(bref.unpack(intra_freq_cell_resel_info_v1430_present, 1)); - intra_freq_cell_resel_info_v1430.set_present(intra_freq_cell_resel_info_v1430_present); - if (intra_freq_cell_resel_info_v1430.is_present()) { - HANDLE_CODE(intra_freq_cell_resel_info_v1430->unpack(bref)); - } - } - if (group_flags[3]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool cell_resel_info_common_v1450_present; - HANDLE_CODE(bref.unpack(cell_resel_info_common_v1450_present, 1)); - cell_resel_info_common_v1450.set_present(cell_resel_info_common_v1450_present); - if (cell_resel_info_common_v1450.is_present()) { - HANDLE_CODE(cell_resel_info_common_v1450->unpack(bref)); - } - } - if (group_flags[4]) { - varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(on_dur_timer_scptm_r14.unpack(bref)); + HANDLE_CODE(drx_inactivity_timer_scptm_r14.unpack(bref)); + HANDLE_CODE(sched_period_start_offset_scptm_r14.unpack(bref)); - bool nsss_rrm_cfg_r15_present; - HANDLE_CODE(bref.unpack(nsss_rrm_cfg_r15_present, 1)); - nsss_rrm_cfg_r15.set_present(nsss_rrm_cfg_r15_present); - HANDLE_CODE(bref.unpack(npbch_rrm_cfg_r15_present, 1)); - if (nsss_rrm_cfg_r15.is_present()) { - HANDLE_CODE(nsss_rrm_cfg_r15->unpack(bref)); - } - } - } return SRSASN_SUCCESS; } -void sib_type3_nb_r13_s::to_json(json_writer& j) const +void sc_mcch_sched_info_nb_r14_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("cellReselectionInfoCommon-r13"); - j.start_obj(); - j.write_str("q-Hyst-r13", cell_resel_info_common_r13.q_hyst_r13.to_string()); - j.end_obj(); - j.write_fieldname("cellReselectionServingFreqInfo-r13"); - j.start_obj(); - j.write_int("s-NonIntraSearch-r13", cell_resel_serving_freq_info_r13.s_non_intra_search_r13); - j.end_obj(); - j.write_fieldname("intraFreqCellReselectionInfo-r13"); - j.start_obj(); - j.write_int("q-RxLevMin-r13", intra_freq_cell_resel_info_r13.q_rx_lev_min_r13); - if (intra_freq_cell_resel_info_r13.q_qual_min_r13_present) { - j.write_int("q-QualMin-r13", intra_freq_cell_resel_info_r13.q_qual_min_r13); - } - if (intra_freq_cell_resel_info_r13.p_max_r13_present) { - j.write_int("p-Max-r13", intra_freq_cell_resel_info_r13.p_max_r13); - } - j.write_int("s-IntraSearchP-r13", intra_freq_cell_resel_info_r13.s_intra_search_p_r13); - j.write_str("t-Reselection-r13", intra_freq_cell_resel_info_r13.t_resel_r13.to_string()); - j.end_obj(); - if (freq_band_info_r13_present) { - j.start_array("freqBandInfo-r13"); - for (const auto& e1 : freq_band_info_r13) { - e1.to_json(j); - } - j.end_array(); - } - if (multi_band_info_list_r13_present) { - j.start_array("multiBandInfoList-r13"); - for (const auto& e1 : multi_band_info_list_r13) { - j.start_array(); - for (const auto& e2 : e1) { - e2.to_json(j); - } - j.end_array(); - } - j.end_array(); - } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (ext) { - if (intra_freq_cell_resel_info_v1350.is_present()) { - j.write_fieldname("intraFreqCellReselectionInfo-v1350"); - intra_freq_cell_resel_info_v1350->to_json(j); - } - if (intra_freq_cell_resel_info_v1360.is_present()) { - j.write_fieldname("intraFreqCellReselectionInfo-v1360"); - intra_freq_cell_resel_info_v1360->to_json(j); - } - if (intra_freq_cell_resel_info_v1430.is_present()) { - j.write_fieldname("intraFreqCellReselectionInfo-v1430"); - intra_freq_cell_resel_info_v1430->to_json(j); - } - if (cell_resel_info_common_v1450.is_present()) { - j.write_fieldname("cellReselectionInfoCommon-v1450"); - cell_resel_info_common_v1450->to_json(j); - } - if (nsss_rrm_cfg_r15.is_present()) { - j.write_fieldname("nsss-RRM-Config-r15"); - nsss_rrm_cfg_r15->to_json(j); - } - if (npbch_rrm_cfg_r15_present) { - j.write_str("npbch-RRM-Config-r15", "enabled"); - } - } + j.write_str("onDurationTimerSCPTM-r14", on_dur_timer_scptm_r14.to_string()); + j.write_str("drx-InactivityTimerSCPTM-r14", drx_inactivity_timer_scptm_r14.to_string()); + j.write_fieldname("schedulingPeriodStartOffsetSCPTM-r14"); + sched_period_start_offset_scptm_r14.to_json(j); j.end_obj(); } -const char* sib_type3_nb_r13_s::cell_resel_info_common_r13_s_::q_hyst_r13_opts::to_string() const +const char* sc_mcch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_opts::to_string() const { - static const char* options[] = {"dB0", - "dB1", - "dB2", - "dB3", - "dB4", - "dB5", - "dB6", - "dB8", - "dB10", - "dB12", - "dB14", - "dB16", - "dB18", - "dB20", - "dB22", - "dB24"}; - return convert_enum_idx(options, 16, value, "sib_type3_nb_r13_s::cell_resel_info_common_r13_s_::q_hyst_r13_e_"); + static const char* options[] = {"pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32", "spare"}; + return convert_enum_idx(options, 8, value, "sc_mcch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_e_"); } -uint8_t sib_type3_nb_r13_s::cell_resel_info_common_r13_s_::q_hyst_r13_opts::to_number() const +uint8_t sc_mcch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_opts::to_number() const { - static const uint8_t options[] = {0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24}; - return map_enum_number(options, 16, value, "sib_type3_nb_r13_s::cell_resel_info_common_r13_s_::q_hyst_r13_e_"); + static const uint8_t options[] = {1, 2, 3, 4, 8, 16, 32}; + return map_enum_number(options, 7, value, "sc_mcch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_e_"); } -// SystemInformationBlockType4-NB-r13 ::= SEQUENCE -SRSASN_CODE sib_type4_nb_r13_s::pack(bit_ref& bref) const +const char* sc_mcch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_opts::to_string() const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(intra_freq_neigh_cell_list_r13_present, 1)); - HANDLE_CODE(bref.pack(intra_freq_black_cell_list_r13_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - - if (intra_freq_neigh_cell_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, intra_freq_neigh_cell_list_r13, 1, 16)); - } - if (intra_freq_black_cell_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, intra_freq_black_cell_list_r13, 1, 16)); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); - } - - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= nsss_rrm_cfg_r15.is_present(); - group_flags[0] |= intra_freq_neigh_cell_list_v1530.is_present(); - group_flags.pack(bref); - - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); - - HANDLE_CODE(bref.pack(nsss_rrm_cfg_r15.is_present(), 1)); - HANDLE_CODE(bref.pack(intra_freq_neigh_cell_list_v1530.is_present(), 1)); - if (nsss_rrm_cfg_r15.is_present()) { - HANDLE_CODE(nsss_rrm_cfg_r15->pack(bref)); - } - if (intra_freq_neigh_cell_list_v1530.is_present()) { - HANDLE_CODE(pack_dyn_seq_of(bref, *intra_freq_neigh_cell_list_v1530, 1, 16)); - } - } - } - return SRSASN_SUCCESS; + static const char* options[] = {"pp0", "pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32"}; + return convert_enum_idx(options, 8, value, "sc_mcch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_e_"); } -SRSASN_CODE sib_type4_nb_r13_s::unpack(cbit_ref& bref) +uint8_t sc_mcch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_opts::to_number() const { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(intra_freq_neigh_cell_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(intra_freq_black_cell_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + static const uint8_t options[] = {0, 1, 2, 3, 4, 8, 16, 32}; + return map_enum_number(options, 8, value, "sc_mcch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_e_"); +} - if (intra_freq_neigh_cell_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(intra_freq_neigh_cell_list_r13, bref, 1, 16)); +void sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::destroy_() {} +void sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::sched_period_start_offset_scptm_r14_c_( + const sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::sf10: + c.init(other.c.get()); + break; + case types::sf20: + c.init(other.c.get()); + break; + case types::sf32: + c.init(other.c.get()); + break; + case types::sf40: + c.init(other.c.get()); + break; + case types::sf64: + c.init(other.c.get()); + break; + case types::sf80: + c.init(other.c.get()); + break; + case types::sf128: + c.init(other.c.get()); + break; + case types::sf160: + c.init(other.c.get()); + break; + case types::sf256: + c.init(other.c.get()); + break; + case types::sf320: + c.init(other.c.get()); + break; + case types::sf512: + c.init(other.c.get()); + break; + case types::sf640: + c.init(other.c.get()); + break; + case types::sf1024: + c.init(other.c.get()); + break; + case types::sf2048: + c.init(other.c.get()); + break; + case types::sf4096: + c.init(other.c.get()); + break; + case types::sf8192: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); } - if (intra_freq_black_cell_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(intra_freq_black_cell_list_r13, bref, 1, 16)); +} +sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& +sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::operator=( + const sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& other) +{ + if (this == &other) { + return *this; } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + set(other.type()); + switch (type_) { + case types::sf10: + c.set(other.c.get()); + break; + case types::sf20: + c.set(other.c.get()); + break; + case types::sf32: + c.set(other.c.get()); + break; + case types::sf40: + c.set(other.c.get()); + break; + case types::sf64: + c.set(other.c.get()); + break; + case types::sf80: + c.set(other.c.get()); + break; + case types::sf128: + c.set(other.c.get()); + break; + case types::sf160: + c.set(other.c.get()); + break; + case types::sf256: + c.set(other.c.get()); + break; + case types::sf320: + c.set(other.c.get()); + break; + case types::sf512: + c.set(other.c.get()); + break; + case types::sf640: + c.set(other.c.get()); + break; + case types::sf1024: + c.set(other.c.get()); + break; + case types::sf2048: + c.set(other.c.get()); + break; + case types::sf4096: + c.set(other.c.get()); + break; + case types::sf8192: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); } - if (ext) { - ext_groups_unpacker_guard group_flags(1); - group_flags.unpack(bref); - - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); - - bool nsss_rrm_cfg_r15_present; - HANDLE_CODE(bref.unpack(nsss_rrm_cfg_r15_present, 1)); - nsss_rrm_cfg_r15.set_present(nsss_rrm_cfg_r15_present); - bool intra_freq_neigh_cell_list_v1530_present; - HANDLE_CODE(bref.unpack(intra_freq_neigh_cell_list_v1530_present, 1)); - intra_freq_neigh_cell_list_v1530.set_present(intra_freq_neigh_cell_list_v1530_present); - if (nsss_rrm_cfg_r15.is_present()) { - HANDLE_CODE(nsss_rrm_cfg_r15->unpack(bref)); - } - if (intra_freq_neigh_cell_list_v1530.is_present()) { - HANDLE_CODE(unpack_dyn_seq_of(*intra_freq_neigh_cell_list_v1530, bref, 1, 16)); - } - } + return *this; +} +uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf10() +{ + set(types::sf10); + return c.get(); +} +uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf20() +{ + set(types::sf20); + return c.get(); +} +uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf32() +{ + set(types::sf32); + return c.get(); +} +uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf40() +{ + set(types::sf40); + return c.get(); +} +uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf64() +{ + set(types::sf64); + return c.get(); +} +uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf80() +{ + set(types::sf80); + return c.get(); +} +uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf128() +{ + set(types::sf128); + return c.get(); +} +uint8_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf160() +{ + set(types::sf160); + return c.get(); +} +uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf256() +{ + set(types::sf256); + return c.get(); +} +uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf320() +{ + set(types::sf320); + return c.get(); +} +uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf512() +{ + set(types::sf512); + return c.get(); +} +uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf640() +{ + set(types::sf640); + return c.get(); +} +uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf1024() +{ + set(types::sf1024); + return c.get(); +} +uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf2048() +{ + set(types::sf2048); + return c.get(); +} +uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf4096() +{ + set(types::sf4096); + return c.get(); +} +uint16_t& sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf8192() +{ + set(types::sf8192); + return c.get(); +} +void sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::sf10: + j.write_int("sf10", c.get()); + break; + case types::sf20: + j.write_int("sf20", c.get()); + break; + case types::sf32: + j.write_int("sf32", c.get()); + break; + case types::sf40: + j.write_int("sf40", c.get()); + break; + case types::sf64: + j.write_int("sf64", c.get()); + break; + case types::sf80: + j.write_int("sf80", c.get()); + break; + case types::sf128: + j.write_int("sf128", c.get()); + break; + case types::sf160: + j.write_int("sf160", c.get()); + break; + case types::sf256: + j.write_int("sf256", c.get()); + break; + case types::sf320: + j.write_int("sf320", c.get()); + break; + case types::sf512: + j.write_int("sf512", c.get()); + break; + case types::sf640: + j.write_int("sf640", c.get()); + break; + case types::sf1024: + j.write_int("sf1024", c.get()); + break; + case types::sf2048: + j.write_int("sf2048", c.get()); + break; + case types::sf4096: + j.write_int("sf4096", c.get()); + break; + case types::sf8192: + j.write_int("sf8192", c.get()); + break; + default: + log_invalid_choice_id(type_, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + } + j.end_obj(); +} +SRSASN_CODE sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::sf10: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)9u)); + break; + case types::sf20: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)19u)); + break; + case types::sf32: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)31u)); + break; + case types::sf40: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)39u)); + break; + case types::sf64: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)63u)); + break; + case types::sf80: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)79u)); + break; + case types::sf128: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + break; + case types::sf160: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)159u)); + break; + case types::sf256: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u)); + break; + case types::sf320: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)319u)); + break; + case types::sf512: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)511u)); + break; + case types::sf640: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)639u)); + break; + case types::sf1024: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1023u)); + break; + case types::sf2048: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)2047u)); + break; + case types::sf4096: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u)); + break; + case types::sf8192: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)8191u)); + break; + default: + log_invalid_choice_id(type_, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::sf10: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)9u)); + break; + case types::sf20: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)19u)); + break; + case types::sf32: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)31u)); + break; + case types::sf40: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)39u)); + break; + case types::sf64: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)63u)); + break; + case types::sf80: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)79u)); + break; + case types::sf128: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + break; + case types::sf160: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)159u)); + break; + case types::sf256: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u)); + break; + case types::sf320: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)319u)); + break; + case types::sf512: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)511u)); + break; + case types::sf640: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)639u)); + break; + case types::sf1024: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1023u)); + break; + case types::sf2048: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)2047u)); + break; + case types::sf4096: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u)); + break; + case types::sf8192: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)8191u)); + break; + default: + log_invalid_choice_id(type_, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types_opts::to_string() const +{ + static const char* options[] = {"sf10", + "sf20", + "sf32", + "sf40", + "sf64", + "sf80", + "sf128", + "sf160", + "sf256", + "sf320", + "sf512", + "sf640", + "sf1024", + "sf2048", + "sf4096", + "sf8192"}; + return convert_enum_idx( + options, 16, value, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types"); +} +uint16_t sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types_opts::to_number() const +{ + static const uint16_t options[] = {10, 20, 32, 40, 64, 80, 128, 160, 256, 320, 512, 640, 1024, 2048, 4096, 8192}; + return map_enum_number( + options, 16, value, "sc_mcch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types"); +} + +// SystemInformationBlockType1-NB-v1450 ::= SEQUENCE +SRSASN_CODE sib_type1_nb_v1450_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(nrs_crs_pwr_offset_v1450_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (nrs_crs_pwr_offset_v1450_present) { + HANDLE_CODE(nrs_crs_pwr_offset_v1450.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type1_nb_v1450_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(nrs_crs_pwr_offset_v1450_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (nrs_crs_pwr_offset_v1450_present) { + HANDLE_CODE(nrs_crs_pwr_offset_v1450.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type1_nb_v1450_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (nrs_crs_pwr_offset_v1450_present) { + j.write_str("nrs-CRS-PowerOffset-v1450", nrs_crs_pwr_offset_v1450.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +const char* sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_opts::to_string() const +{ + static const char* options[] = {"dB-6", + "dB-4dot77", + "dB-3", + "dB-1dot77", + "dB0", + "dB1", + "dB1dot23", + "dB2", + "dB3", + "dB4", + "dB4dot23", + "dB5", + "dB6", + "dB7", + "dB8", + "dB9"}; + return convert_enum_idx(options, 16, value, "sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_e_"); +} +float sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_opts::to_number() const +{ + static const float options[] = { + -6.0, -4.77, -3.0, -1.77, 0.0, 1.0, 1.23, 2.0, 3.0, 4.0, 4.23, 5.0, 6.0, 7.0, 8.0, 9.0}; + return map_enum_number(options, 16, value, "sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_e_"); +} +const char* sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_opts::to_number_string() const +{ + static const char* options[] = { + "-6", "-4.77", "-3", "-1.77", "0", "1", "1.23", "2", "3", "4", "4.23", "5", "6", "7", "8", "9"}; + return convert_enum_idx(options, 16, value, "sib_type1_nb_v1450_s::nrs_crs_pwr_offset_v1450_e_"); +} + +// T-Reselection-NB-r13 ::= ENUMERATED +const char* t_resel_nb_r13_opts::to_string() const +{ + static const char* options[] = {"s0", "s3", "s6", "s9", "s12", "s15", "s18", "s21"}; + return convert_enum_idx(options, 8, value, "t_resel_nb_r13_e"); +} +uint8_t t_resel_nb_r13_opts::to_number() const +{ + static const uint8_t options[] = {0, 3, 6, 9, 12, 15, 18, 21}; + return map_enum_number(options, 8, value, "t_resel_nb_r13_e"); +} + +// UAC-Param-NB-r16 ::= CHOICE +void uac_param_nb_r16_c::destroy_() +{ + switch (type_) { + case types::uac_barr_common: + c.destroy(); + break; + case types::uac_barr_per_plmn_list: + c.destroy(); + break; + default: + break; + } +} +void uac_param_nb_r16_c::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::uac_barr_common: + c.init(); + break; + case types::uac_barr_per_plmn_list: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "uac_param_nb_r16_c"); + } +} +uac_param_nb_r16_c::uac_param_nb_r16_c(const uac_param_nb_r16_c& other) +{ + type_ = other.type(); + switch (type_) { + case types::uac_barr_common: + c.init(other.c.get()); + break; + case types::uac_barr_per_plmn_list: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "uac_param_nb_r16_c"); + } +} +uac_param_nb_r16_c& uac_param_nb_r16_c::operator=(const uac_param_nb_r16_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::uac_barr_common: + c.set(other.c.get()); + break; + case types::uac_barr_per_plmn_list: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "uac_param_nb_r16_c"); + } + + return *this; +} +uac_barr_nb_r16_s& uac_param_nb_r16_c::set_uac_barr_common() +{ + set(types::uac_barr_common); + return c.get(); +} +uac_param_nb_r16_c::uac_barr_per_plmn_list_l_& uac_param_nb_r16_c::set_uac_barr_per_plmn_list() +{ + set(types::uac_barr_per_plmn_list); + return c.get(); +} +void uac_param_nb_r16_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::uac_barr_common: + j.write_fieldname("uac-BarringCommon"); + c.get().to_json(j); + break; + case types::uac_barr_per_plmn_list: + j.start_array("uac-BarringPerPLMN-List"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "uac_param_nb_r16_c"); + } + j.end_obj(); +} +SRSASN_CODE uac_param_nb_r16_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::uac_barr_common: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::uac_barr_per_plmn_list: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 6)); + break; + default: + log_invalid_choice_id(type_, "uac_param_nb_r16_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE uac_param_nb_r16_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::uac_barr_common: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::uac_barr_per_plmn_list: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 6)); + break; + default: + log_invalid_choice_id(type_, "uac_param_nb_r16_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* uac_param_nb_r16_c::types_opts::to_string() const +{ + static const char* options[] = {"uac-BarringCommon", "uac-BarringPerPLMN-List"}; + return convert_enum_idx(options, 2, value, "uac_param_nb_r16_c::types"); +} + +// UE-TimersAndConstants-NB-r13 ::= SEQUENCE +SRSASN_CODE ue_timers_and_consts_nb_r13_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(t300_r13.pack(bref)); + HANDLE_CODE(t301_r13.pack(bref)); + HANDLE_CODE(t310_r13.pack(bref)); + HANDLE_CODE(n310_r13.pack(bref)); + HANDLE_CODE(t311_r13.pack(bref)); + HANDLE_CODE(n311_r13.pack(bref)); + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= t311_v1350_present; + group_flags[1] |= t300_v1530_present; + group_flags[1] |= t301_v1530_present; + group_flags[1] |= t311_v1530_present; + group_flags[1] |= t300_r15_present; + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(t311_v1350_present, 1)); + if (t311_v1350_present) { + HANDLE_CODE(t311_v1350.pack(bref)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(t300_v1530_present, 1)); + HANDLE_CODE(bref.pack(t301_v1530_present, 1)); + HANDLE_CODE(bref.pack(t311_v1530_present, 1)); + HANDLE_CODE(bref.pack(t300_r15_present, 1)); + if (t300_v1530_present) { + HANDLE_CODE(t300_v1530.pack(bref)); + } + if (t301_v1530_present) { + HANDLE_CODE(t301_v1530.pack(bref)); + } + if (t311_v1530_present) { + HANDLE_CODE(t311_v1530.pack(bref)); + } + if (t300_r15_present) { + HANDLE_CODE(t300_r15.pack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_timers_and_consts_nb_r13_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(t300_r13.unpack(bref)); + HANDLE_CODE(t301_r13.unpack(bref)); + HANDLE_CODE(t310_r13.unpack(bref)); + HANDLE_CODE(n310_r13.unpack(bref)); + HANDLE_CODE(t311_r13.unpack(bref)); + HANDLE_CODE(n311_r13.unpack(bref)); + + if (ext) { + ext_groups_unpacker_guard group_flags(2); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(t311_v1350_present, 1)); + if (t311_v1350_present) { + HANDLE_CODE(t311_v1350.unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(t300_v1530_present, 1)); + HANDLE_CODE(bref.unpack(t301_v1530_present, 1)); + HANDLE_CODE(bref.unpack(t311_v1530_present, 1)); + HANDLE_CODE(bref.unpack(t300_r15_present, 1)); + if (t300_v1530_present) { + HANDLE_CODE(t300_v1530.unpack(bref)); + } + if (t301_v1530_present) { + HANDLE_CODE(t301_v1530.unpack(bref)); + } + if (t311_v1530_present) { + HANDLE_CODE(t311_v1530.unpack(bref)); + } + if (t300_r15_present) { + HANDLE_CODE(t300_r15.unpack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +void ue_timers_and_consts_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("t300-r13", t300_r13.to_string()); + j.write_str("t301-r13", t301_r13.to_string()); + j.write_str("t310-r13", t310_r13.to_string()); + j.write_str("n310-r13", n310_r13.to_string()); + j.write_str("t311-r13", t311_r13.to_string()); + j.write_str("n311-r13", n311_r13.to_string()); + if (ext) { + if (t311_v1350_present) { + j.write_str("t311-v1350", t311_v1350.to_string()); + } + if (t300_v1530_present) { + j.write_str("t300-v1530", t300_v1530.to_string()); + } + if (t301_v1530_present) { + j.write_str("t301-v1530", t301_v1530.to_string()); + } + if (t311_v1530_present) { + j.write_str("t311-v1530", t311_v1530.to_string()); + } + if (t300_r15_present) { + j.write_str("t300-r15", t300_r15.to_string()); + } + } + j.end_obj(); +} + +const char* ue_timers_and_consts_nb_r13_s::t300_r13_opts::to_string() const +{ + static const char* options[] = {"ms2500", "ms4000", "ms6000", "ms10000", "ms15000", "ms25000", "ms40000", "ms60000"}; + return convert_enum_idx(options, 8, value, "ue_timers_and_consts_nb_r13_s::t300_r13_e_"); +} +uint16_t ue_timers_and_consts_nb_r13_s::t300_r13_opts::to_number() const +{ + static const uint16_t options[] = {2500, 4000, 6000, 10000, 15000, 25000, 40000, 60000}; + return map_enum_number(options, 8, value, "ue_timers_and_consts_nb_r13_s::t300_r13_e_"); +} + +const char* ue_timers_and_consts_nb_r13_s::t301_r13_opts::to_string() const +{ + static const char* options[] = {"ms2500", "ms4000", "ms6000", "ms10000", "ms15000", "ms25000", "ms40000", "ms60000"}; + return convert_enum_idx(options, 8, value, "ue_timers_and_consts_nb_r13_s::t301_r13_e_"); +} +uint16_t ue_timers_and_consts_nb_r13_s::t301_r13_opts::to_number() const +{ + static const uint16_t options[] = {2500, 4000, 6000, 10000, 15000, 25000, 40000, 60000}; + return map_enum_number(options, 8, value, "ue_timers_and_consts_nb_r13_s::t301_r13_e_"); +} + +const char* ue_timers_and_consts_nb_r13_s::t310_r13_opts::to_string() const +{ + static const char* options[] = {"ms0", "ms200", "ms500", "ms1000", "ms2000", "ms4000", "ms8000"}; + return convert_enum_idx(options, 7, value, "ue_timers_and_consts_nb_r13_s::t310_r13_e_"); +} +uint16_t ue_timers_and_consts_nb_r13_s::t310_r13_opts::to_number() const +{ + static const uint16_t options[] = {0, 200, 500, 1000, 2000, 4000, 8000}; + return map_enum_number(options, 7, value, "ue_timers_and_consts_nb_r13_s::t310_r13_e_"); +} + +const char* ue_timers_and_consts_nb_r13_s::n310_r13_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n3", "n4", "n6", "n8", "n10", "n20"}; + return convert_enum_idx(options, 8, value, "ue_timers_and_consts_nb_r13_s::n310_r13_e_"); +} +uint8_t ue_timers_and_consts_nb_r13_s::n310_r13_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3, 4, 6, 8, 10, 20}; + return map_enum_number(options, 8, value, "ue_timers_and_consts_nb_r13_s::n310_r13_e_"); +} + +const char* ue_timers_and_consts_nb_r13_s::t311_r13_opts::to_string() const +{ + static const char* options[] = {"ms1000", "ms3000", "ms5000", "ms10000", "ms15000", "ms20000", "ms30000"}; + return convert_enum_idx(options, 7, value, "ue_timers_and_consts_nb_r13_s::t311_r13_e_"); +} +uint16_t ue_timers_and_consts_nb_r13_s::t311_r13_opts::to_number() const +{ + static const uint16_t options[] = {1000, 3000, 5000, 10000, 15000, 20000, 30000}; + return map_enum_number(options, 7, value, "ue_timers_and_consts_nb_r13_s::t311_r13_e_"); +} + +const char* ue_timers_and_consts_nb_r13_s::n311_r13_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n3", "n4", "n5", "n6", "n8", "n10"}; + return convert_enum_idx(options, 8, value, "ue_timers_and_consts_nb_r13_s::n311_r13_e_"); +} +uint8_t ue_timers_and_consts_nb_r13_s::n311_r13_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3, 4, 5, 6, 8, 10}; + return map_enum_number(options, 8, value, "ue_timers_and_consts_nb_r13_s::n311_r13_e_"); +} + +const char* ue_timers_and_consts_nb_r13_s::t311_v1350_opts::to_string() const +{ + static const char* options[] = {"ms40000", "ms60000", "ms90000", "ms120000"}; + return convert_enum_idx(options, 4, value, "ue_timers_and_consts_nb_r13_s::t311_v1350_e_"); +} +uint32_t ue_timers_and_consts_nb_r13_s::t311_v1350_opts::to_number() const +{ + static const uint32_t options[] = {40000, 60000, 90000, 120000}; + return map_enum_number(options, 4, value, "ue_timers_and_consts_nb_r13_s::t311_v1350_e_"); +} + +const char* ue_timers_and_consts_nb_r13_s::t300_v1530_opts::to_string() const +{ + static const char* options[] = {"ms80000", "ms100000", "ms120000"}; + return convert_enum_idx(options, 3, value, "ue_timers_and_consts_nb_r13_s::t300_v1530_e_"); +} +uint32_t ue_timers_and_consts_nb_r13_s::t300_v1530_opts::to_number() const +{ + static const uint32_t options[] = {80000, 100000, 120000}; + return map_enum_number(options, 3, value, "ue_timers_and_consts_nb_r13_s::t300_v1530_e_"); +} + +const char* ue_timers_and_consts_nb_r13_s::t301_v1530_opts::to_string() const +{ + static const char* options[] = {"ms80000", "ms100000", "ms120000"}; + return convert_enum_idx(options, 3, value, "ue_timers_and_consts_nb_r13_s::t301_v1530_e_"); +} +uint32_t ue_timers_and_consts_nb_r13_s::t301_v1530_opts::to_number() const +{ + static const uint32_t options[] = {80000, 100000, 120000}; + return map_enum_number(options, 3, value, "ue_timers_and_consts_nb_r13_s::t301_v1530_e_"); +} + +const char* ue_timers_and_consts_nb_r13_s::t311_v1530_opts::to_string() const +{ + static const char* options[] = {"ms160000", "ms200000"}; + return convert_enum_idx(options, 2, value, "ue_timers_and_consts_nb_r13_s::t311_v1530_e_"); +} +uint32_t ue_timers_and_consts_nb_r13_s::t311_v1530_opts::to_number() const +{ + static const uint32_t options[] = {160000, 200000}; + return map_enum_number(options, 2, value, "ue_timers_and_consts_nb_r13_s::t311_v1530_e_"); +} + +const char* ue_timers_and_consts_nb_r13_s::t300_r15_opts::to_string() const +{ + static const char* options[] = { + "ms6000", "ms10000", "ms15000", "ms25000", "ms40000", "ms60000", "ms80000", "ms120000"}; + return convert_enum_idx(options, 8, value, "ue_timers_and_consts_nb_r13_s::t300_r15_e_"); +} +uint32_t ue_timers_and_consts_nb_r13_s::t300_r15_opts::to_number() const +{ + static const uint32_t options[] = {6000, 10000, 15000, 25000, 40000, 60000, 80000, 120000}; + return map_enum_number(options, 8, value, "ue_timers_and_consts_nb_r13_s::t300_r15_e_"); +} + +// CellSelectionInfo-NB-v1350 ::= SEQUENCE +SRSASN_CODE cell_sel_info_nb_v1350_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, delta_rx_lev_min_v1350, (int8_t)-8, (int8_t)-1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE cell_sel_info_nb_v1350_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(delta_rx_lev_min_v1350, bref, (int8_t)-8, (int8_t)-1)); + + return SRSASN_SUCCESS; +} +void cell_sel_info_nb_v1350_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("delta-RxLevMin-v1350", delta_rx_lev_min_v1350); + j.end_obj(); +} + +// PLMN-IdentityInfo-NB-r13 ::= SEQUENCE +SRSASN_CODE plmn_id_info_nb_r13_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(attach_without_pdn_connect_r13_present, 1)); + + HANDLE_CODE(plmn_id_r13.pack(bref)); + HANDLE_CODE(cell_reserved_for_oper_r13.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE plmn_id_info_nb_r13_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(attach_without_pdn_connect_r13_present, 1)); + + HANDLE_CODE(plmn_id_r13.unpack(bref)); + HANDLE_CODE(cell_reserved_for_oper_r13.unpack(bref)); + + return SRSASN_SUCCESS; +} +void plmn_id_info_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("plmn-Identity-r13"); + plmn_id_r13.to_json(j); + j.write_str("cellReservedForOperatorUse-r13", cell_reserved_for_oper_r13.to_string()); + if (attach_without_pdn_connect_r13_present) { + j.write_str("attachWithoutPDN-Connectivity-r13", "true"); + } + j.end_obj(); +} + +const char* plmn_id_info_nb_r13_s::cell_reserved_for_oper_r13_opts::to_string() const +{ + static const char* options[] = {"reserved", "notReserved"}; + return convert_enum_idx(options, 2, value, "plmn_id_info_nb_r13_s::cell_reserved_for_oper_r13_e_"); +} + +// SchedulingInfo-NB-r13 ::= SEQUENCE +SRSASN_CODE sched_info_nb_r13_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(si_periodicity_r13.pack(bref)); + HANDLE_CODE(si_repeat_pattern_r13.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, sib_map_info_r13, 0, 31)); + HANDLE_CODE(si_tb_r13.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE sched_info_nb_r13_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(si_periodicity_r13.unpack(bref)); + HANDLE_CODE(si_repeat_pattern_r13.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(sib_map_info_r13, bref, 0, 31)); + HANDLE_CODE(si_tb_r13.unpack(bref)); + + return SRSASN_SUCCESS; +} +void sched_info_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("si-Periodicity-r13", si_periodicity_r13.to_string()); + j.write_str("si-RepetitionPattern-r13", si_repeat_pattern_r13.to_string()); + j.start_array("sib-MappingInfo-r13"); + for (const auto& e1 : sib_map_info_r13) { + j.write_str(e1.to_string()); + } + j.end_array(); + j.write_str("si-TB-r13", si_tb_r13.to_string()); + j.end_obj(); +} + +const char* sched_info_nb_r13_s::si_periodicity_r13_opts::to_string() const +{ + static const char* options[] = {"rf64", "rf128", "rf256", "rf512", "rf1024", "rf2048", "rf4096", "spare"}; + return convert_enum_idx(options, 8, value, "sched_info_nb_r13_s::si_periodicity_r13_e_"); +} +uint16_t sched_info_nb_r13_s::si_periodicity_r13_opts::to_number() const +{ + static const uint16_t options[] = {64, 128, 256, 512, 1024, 2048, 4096}; + return map_enum_number(options, 7, value, "sched_info_nb_r13_s::si_periodicity_r13_e_"); +} + +const char* sched_info_nb_r13_s::si_repeat_pattern_r13_opts::to_string() const +{ + static const char* options[] = {"every2ndRF", "every4thRF", "every8thRF", "every16thRF"}; + return convert_enum_idx(options, 4, value, "sched_info_nb_r13_s::si_repeat_pattern_r13_e_"); +} +uint8_t sched_info_nb_r13_s::si_repeat_pattern_r13_opts::to_number() const +{ + static const uint8_t options[] = {2, 4, 8, 16}; + return map_enum_number(options, 4, value, "sched_info_nb_r13_s::si_repeat_pattern_r13_e_"); +} + +const char* sched_info_nb_r13_s::si_tb_r13_opts::to_string() const +{ + static const char* options[] = {"b56", "b120", "b208", "b256", "b328", "b440", "b552", "b680"}; + return convert_enum_idx(options, 8, value, "sched_info_nb_r13_s::si_tb_r13_e_"); +} +uint16_t sched_info_nb_r13_s::si_tb_r13_opts::to_number() const +{ + static const uint16_t options[] = {56, 120, 208, 256, 328, 440, 552, 680}; + return map_enum_number(options, 8, value, "sched_info_nb_r13_s::si_tb_r13_e_"); +} + +// SystemInformationBlockType1-NB-v1430 ::= SEQUENCE +SRSASN_CODE sib_type1_nb_v1430_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(cell_sel_info_v1430_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (cell_sel_info_v1430_present) { + HANDLE_CODE(cell_sel_info_v1430.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type1_nb_v1430_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(cell_sel_info_v1430_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (cell_sel_info_v1430_present) { + HANDLE_CODE(cell_sel_info_v1430.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type1_nb_v1430_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (cell_sel_info_v1430_present) { + j.write_fieldname("cellSelectionInfo-v1430"); + cell_sel_info_v1430.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// SystemInformationBlockType14-NB-r13 ::= SEQUENCE +SRSASN_CODE sib_type14_nb_r13_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ab_param_r13_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + if (ab_param_r13_present) { + HANDLE_CODE(ab_param_r13.pack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= ab_per_nrsrp_r15_present; + group_flags[1] |= uac_param_r16.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ab_per_nrsrp_r15_present, 1)); + if (ab_per_nrsrp_r15_present) { + HANDLE_CODE(ab_per_nrsrp_r15.pack(bref)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(uac_param_r16.is_present(), 1)); + if (uac_param_r16.is_present()) { + HANDLE_CODE(uac_param_r16->pack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type14_nb_r13_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ab_param_r13_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + if (ab_param_r13_present) { + HANDLE_CODE(ab_param_r13.unpack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(2); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(ab_per_nrsrp_r15_present, 1)); + if (ab_per_nrsrp_r15_present) { + HANDLE_CODE(ab_per_nrsrp_r15.unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool uac_param_r16_present; + HANDLE_CODE(bref.unpack(uac_param_r16_present, 1)); + uac_param_r16.set_present(uac_param_r16_present); + if (uac_param_r16.is_present()) { + HANDLE_CODE(uac_param_r16->unpack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +void sib_type14_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ab_param_r13_present) { + j.write_fieldname("ab-Param-r13"); + ab_param_r13.to_json(j); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (ext) { + if (ab_per_nrsrp_r15_present) { + j.write_str("ab-PerNRSRP-r15", ab_per_nrsrp_r15.to_string()); + } + if (uac_param_r16.is_present()) { + j.write_fieldname("uac-Param-r16"); + uac_param_r16->to_json(j); + } + } + j.end_obj(); +} + +void sib_type14_nb_r13_s::ab_param_r13_c_::destroy_() +{ + switch (type_) { + case types::ab_common_r13: + c.destroy(); + break; + case types::ab_per_plmn_list_r13: + c.destroy(); + break; + default: + break; + } +} +void sib_type14_nb_r13_s::ab_param_r13_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::ab_common_r13: + c.init(); + break; + case types::ab_per_plmn_list_r13: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); + } +} +sib_type14_nb_r13_s::ab_param_r13_c_::ab_param_r13_c_(const sib_type14_nb_r13_s::ab_param_r13_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::ab_common_r13: + c.init(other.c.get()); + break; + case types::ab_per_plmn_list_r13: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); + } +} +sib_type14_nb_r13_s::ab_param_r13_c_& +sib_type14_nb_r13_s::ab_param_r13_c_::operator=(const sib_type14_nb_r13_s::ab_param_r13_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ab_common_r13: + c.set(other.c.get()); + break; + case types::ab_per_plmn_list_r13: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); + } + + return *this; +} +ab_cfg_nb_r13_s& sib_type14_nb_r13_s::ab_param_r13_c_::set_ab_common_r13() +{ + set(types::ab_common_r13); + return c.get(); +} +sib_type14_nb_r13_s::ab_param_r13_c_::ab_per_plmn_list_r13_l_& +sib_type14_nb_r13_s::ab_param_r13_c_::set_ab_per_plmn_list_r13() +{ + set(types::ab_per_plmn_list_r13); + return c.get(); +} +void sib_type14_nb_r13_s::ab_param_r13_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ab_common_r13: + j.write_fieldname("ab-Common-r13"); + c.get().to_json(j); + break; + case types::ab_per_plmn_list_r13: + j.start_array("ab-PerPLMN-List-r13"); + for (const auto& e1 : c.get()) { + e1.to_json(j); + } + j.end_array(); + break; + default: + log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); + } + j.end_obj(); +} +SRSASN_CODE sib_type14_nb_r13_s::ab_param_r13_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ab_common_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ab_per_plmn_list_r13: + HANDLE_CODE(pack_dyn_seq_of(bref, c.get(), 1, 6)); + break; + default: + log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type14_nb_r13_s::ab_param_r13_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ab_common_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ab_per_plmn_list_r13: + HANDLE_CODE(unpack_dyn_seq_of(c.get(), bref, 1, 6)); + break; + default: + log_invalid_choice_id(type_, "sib_type14_nb_r13_s::ab_param_r13_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* sib_type14_nb_r13_s::ab_param_r13_c_::types_opts::to_string() const +{ + static const char* options[] = {"ab-Common-r13", "ab-PerPLMN-List-r13"}; + return convert_enum_idx(options, 2, value, "sib_type14_nb_r13_s::ab_param_r13_c_::types"); +} + +const char* sib_type14_nb_r13_s::ab_per_nrsrp_r15_opts::to_string() const +{ + static const char* options[] = {"thresh1", "thresh2"}; + return convert_enum_idx(options, 2, value, "sib_type14_nb_r13_s::ab_per_nrsrp_r15_e_"); +} +uint8_t sib_type14_nb_r13_s::ab_per_nrsrp_r15_opts::to_number() const +{ + static const uint8_t options[] = {1, 2}; + return map_enum_number(options, 2, value, "sib_type14_nb_r13_s::ab_per_nrsrp_r15_e_"); +} + +// SystemInformationBlockType15-NB-r14 ::= SEQUENCE +SRSASN_CODE sib_type15_nb_r14_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(mbms_sai_intra_freq_r14_present, 1)); + HANDLE_CODE(bref.pack(mbms_sai_inter_freq_list_r14_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + if (mbms_sai_intra_freq_r14_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, mbms_sai_intra_freq_r14, 1, 64, integer_packer(0, 65535))); + } + if (mbms_sai_inter_freq_list_r14_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, mbms_sai_inter_freq_list_r14, 1, 8)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type15_nb_r14_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(mbms_sai_intra_freq_r14_present, 1)); + HANDLE_CODE(bref.unpack(mbms_sai_inter_freq_list_r14_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + if (mbms_sai_intra_freq_r14_present) { + HANDLE_CODE(unpack_dyn_seq_of(mbms_sai_intra_freq_r14, bref, 1, 64, integer_packer(0, 65535))); + } + if (mbms_sai_inter_freq_list_r14_present) { + HANDLE_CODE(unpack_dyn_seq_of(mbms_sai_inter_freq_list_r14, bref, 1, 8)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type15_nb_r14_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (mbms_sai_intra_freq_r14_present) { + j.start_array("mbms-SAI-IntraFreq-r14"); + for (const auto& e1 : mbms_sai_intra_freq_r14) { + j.write_int(e1); + } + j.end_array(); + } + if (mbms_sai_inter_freq_list_r14_present) { + j.start_array("mbms-SAI-InterFreqList-r14"); + for (const auto& e1 : mbms_sai_inter_freq_list_r14) { + e1.to_json(j); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + +// SystemInformationBlockType2-NB-r13 ::= SEQUENCE +SRSASN_CODE sib_type2_nb_r13_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(multi_band_info_list_r13_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(rr_cfg_common_r13.pack(bref)); + HANDLE_CODE(ue_timers_and_consts_r13.pack(bref)); + HANDLE_CODE(bref.pack(freq_info_r13.ul_carrier_freq_r13_present, 1)); + if (freq_info_r13.ul_carrier_freq_r13_present) { + HANDLE_CODE(freq_info_r13.ul_carrier_freq_r13.pack(bref)); + } + HANDLE_CODE(pack_integer(bref, freq_info_r13.add_spec_emission_r13, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(time_align_timer_common_r13.pack(bref)); + if (multi_band_info_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, multi_band_info_list_r13, 1, 8, integer_packer(1, 32))); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= cp_reest_r14_present; + group_flags[1] |= serving_cell_meas_info_r14_present; + group_flags[1] |= cqi_report_r14_present; + group_flags[2] |= enhanced_phr_r15_present; + group_flags[2] |= freq_info_v1530.is_present(); + group_flags[2] |= cp_edt_r15_present; + group_flags[2] |= up_edt_r15_present; + group_flags[3] |= early_security_reactivation_r16_present; + group_flags[3] |= cp_edt_minus5_gc_r16_present; + group_flags[3] |= up_edt_minus5_gc_r16_present; + group_flags[3] |= cp_pur_epc_r16_present; + group_flags[3] |= up_pur_epc_r16_present; + group_flags[3] |= cp_pur_minus5_gc_r16_present; + group_flags[3] |= up_pur_minus5_gc_r16_present; + group_flags[3] |= rai_activation_enh_r16_present; + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(cp_reest_r14_present, 1)); + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(serving_cell_meas_info_r14_present, 1)); + HANDLE_CODE(bref.pack(cqi_report_r14_present, 1)); + } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(enhanced_phr_r15_present, 1)); + HANDLE_CODE(bref.pack(freq_info_v1530.is_present(), 1)); + HANDLE_CODE(bref.pack(cp_edt_r15_present, 1)); + HANDLE_CODE(bref.pack(up_edt_r15_present, 1)); + if (freq_info_v1530.is_present()) { + HANDLE_CODE(freq_info_v1530->tdd_ul_dl_align_offset_r15.pack(bref)); + } + } + if (group_flags[3]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(early_security_reactivation_r16_present, 1)); + HANDLE_CODE(bref.pack(cp_edt_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(up_edt_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(cp_pur_epc_r16_present, 1)); + HANDLE_CODE(bref.pack(up_pur_epc_r16_present, 1)); + HANDLE_CODE(bref.pack(cp_pur_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(up_pur_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(rai_activation_enh_r16_present, 1)); + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type2_nb_r13_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(multi_band_info_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(rr_cfg_common_r13.unpack(bref)); + HANDLE_CODE(ue_timers_and_consts_r13.unpack(bref)); + HANDLE_CODE(bref.unpack(freq_info_r13.ul_carrier_freq_r13_present, 1)); + if (freq_info_r13.ul_carrier_freq_r13_present) { + HANDLE_CODE(freq_info_r13.ul_carrier_freq_r13.unpack(bref)); + } + HANDLE_CODE(unpack_integer(freq_info_r13.add_spec_emission_r13, bref, (uint8_t)1u, (uint8_t)32u)); + HANDLE_CODE(time_align_timer_common_r13.unpack(bref)); + if (multi_band_info_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r13, bref, 1, 8, integer_packer(1, 32))); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(4); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(cp_reest_r14_present, 1)); + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(serving_cell_meas_info_r14_present, 1)); + HANDLE_CODE(bref.unpack(cqi_report_r14_present, 1)); + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(enhanced_phr_r15_present, 1)); + bool freq_info_v1530_present; + HANDLE_CODE(bref.unpack(freq_info_v1530_present, 1)); + freq_info_v1530.set_present(freq_info_v1530_present); + HANDLE_CODE(bref.unpack(cp_edt_r15_present, 1)); + HANDLE_CODE(bref.unpack(up_edt_r15_present, 1)); + if (freq_info_v1530.is_present()) { + HANDLE_CODE(freq_info_v1530->tdd_ul_dl_align_offset_r15.unpack(bref)); + } + } + if (group_flags[3]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(early_security_reactivation_r16_present, 1)); + HANDLE_CODE(bref.unpack(cp_edt_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(up_edt_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(cp_pur_epc_r16_present, 1)); + HANDLE_CODE(bref.unpack(up_pur_epc_r16_present, 1)); + HANDLE_CODE(bref.unpack(cp_pur_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(up_pur_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(rai_activation_enh_r16_present, 1)); + } + } + return SRSASN_SUCCESS; +} +void sib_type2_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("radioResourceConfigCommon-r13"); + rr_cfg_common_r13.to_json(j); + j.write_fieldname("ue-TimersAndConstants-r13"); + ue_timers_and_consts_r13.to_json(j); + j.write_fieldname("freqInfo-r13"); + j.start_obj(); + if (freq_info_r13.ul_carrier_freq_r13_present) { + j.write_fieldname("ul-CarrierFreq-r13"); + freq_info_r13.ul_carrier_freq_r13.to_json(j); + } + j.write_int("additionalSpectrumEmission-r13", freq_info_r13.add_spec_emission_r13); + j.end_obj(); + j.write_str("timeAlignmentTimerCommon-r13", time_align_timer_common_r13.to_string()); + if (multi_band_info_list_r13_present) { + j.start_array("multiBandInfoList-r13"); + for (const auto& e1 : multi_band_info_list_r13) { + j.write_int(e1); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (ext) { + if (cp_reest_r14_present) { + j.write_str("cp-Reestablishment-r14", "true"); + } + if (serving_cell_meas_info_r14_present) { + j.write_str("servingCellMeasInfo-r14", "true"); + } + if (cqi_report_r14_present) { + j.write_str("cqi-Reporting-r14", "true"); + } + if (enhanced_phr_r15_present) { + j.write_str("enhancedPHR-r15", "true"); + } + if (freq_info_v1530.is_present()) { + j.write_fieldname("freqInfo-v1530"); + j.start_obj(); + j.write_str("tdd-UL-DL-AlignmentOffset-r15", freq_info_v1530->tdd_ul_dl_align_offset_r15.to_string()); + j.end_obj(); + } + if (cp_edt_r15_present) { + j.write_str("cp-EDT-r15", "true"); + } + if (up_edt_r15_present) { + j.write_str("up-EDT-r15", "true"); + } + if (early_security_reactivation_r16_present) { + j.write_str("earlySecurityReactivation-r16", "true"); + } + if (cp_edt_minus5_gc_r16_present) { + j.write_str("cp-EDT-5GC-r16", "true"); + } + if (up_edt_minus5_gc_r16_present) { + j.write_str("up-EDT-5GC-r16", "true"); + } + if (cp_pur_epc_r16_present) { + j.write_str("cp-PUR-EPC-r16", "true"); + } + if (up_pur_epc_r16_present) { + j.write_str("up-PUR-EPC-r16", "true"); + } + if (cp_pur_minus5_gc_r16_present) { + j.write_str("cp-PUR-5GC-r16", "true"); + } + if (up_pur_minus5_gc_r16_present) { + j.write_str("up-PUR-5GC-r16", "true"); + } + if (rai_activation_enh_r16_present) { + j.write_str("rai-ActivationEnh-r16", "true"); + } + } + j.end_obj(); +} + +// SystemInformationBlockType20-NB-r14 ::= SEQUENCE +SRSASN_CODE sib_type20_nb_r14_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(sc_mcch_sched_info_r14_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(npdcch_sc_mcch_cfg_r14.pack(bref)); + HANDLE_CODE(sc_mcch_carrier_cfg_r14.pack(bref)); + HANDLE_CODE(sc_mcch_repeat_period_r14.pack(bref)); + HANDLE_CODE(pack_integer(bref, sc_mcch_offset_r14, (uint8_t)0u, (uint8_t)10u)); + HANDLE_CODE(sc_mcch_mod_period_r14.pack(bref)); + if (sc_mcch_sched_info_r14_present) { + HANDLE_CODE(sc_mcch_sched_info_r14.pack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type20_nb_r14_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(sc_mcch_sched_info_r14_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(npdcch_sc_mcch_cfg_r14.unpack(bref)); + HANDLE_CODE(sc_mcch_carrier_cfg_r14.unpack(bref)); + HANDLE_CODE(sc_mcch_repeat_period_r14.unpack(bref)); + HANDLE_CODE(unpack_integer(sc_mcch_offset_r14, bref, (uint8_t)0u, (uint8_t)10u)); + HANDLE_CODE(sc_mcch_mod_period_r14.unpack(bref)); + if (sc_mcch_sched_info_r14_present) { + HANDLE_CODE(sc_mcch_sched_info_r14.unpack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type20_nb_r14_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("npdcch-SC-MCCH-Config-r14"); + npdcch_sc_mcch_cfg_r14.to_json(j); + j.write_fieldname("sc-mcch-CarrierConfig-r14"); + sc_mcch_carrier_cfg_r14.to_json(j); + j.write_str("sc-mcch-RepetitionPeriod-r14", sc_mcch_repeat_period_r14.to_string()); + j.write_int("sc-mcch-Offset-r14", sc_mcch_offset_r14); + j.write_str("sc-mcch-ModificationPeriod-r14", sc_mcch_mod_period_r14.to_string()); + if (sc_mcch_sched_info_r14_present) { + j.write_fieldname("sc-mcch-SchedulingInfo-r14"); + sc_mcch_sched_info_r14.to_json(j); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + +void sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::destroy_() +{ + switch (type_) { + case types::dl_carrier_cfg_r14: + c.destroy(); + break; + default: + break; + } +} +void sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::dl_carrier_cfg_r14: + c.init(); + break; + case types::dl_carrier_idx_r14: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); + } +} +sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::sc_mcch_carrier_cfg_r14_c_( + const sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::dl_carrier_cfg_r14: + c.init(other.c.get()); + break; + case types::dl_carrier_idx_r14: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); + } +} +sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_& +sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::operator=(const sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::dl_carrier_cfg_r14: + c.set(other.c.get()); + break; + case types::dl_carrier_idx_r14: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); + } + + return *this; +} +dl_carrier_cfg_common_nb_r14_s& sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::set_dl_carrier_cfg_r14() +{ + set(types::dl_carrier_cfg_r14); + return c.get(); +} +uint8_t& sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::set_dl_carrier_idx_r14() +{ + set(types::dl_carrier_idx_r14); + return c.get(); +} +void sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::dl_carrier_cfg_r14: + j.write_fieldname("dl-CarrierConfig-r14"); + c.get().to_json(j); + break; + case types::dl_carrier_idx_r14: + j.write_int("dl-CarrierIndex-r14", c.get()); + break; + default: + log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); + } + j.end_obj(); +} +SRSASN_CODE sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::dl_carrier_cfg_r14: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::dl_carrier_idx_r14: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)15u)); + break; + default: + log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::dl_carrier_cfg_r14: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::dl_carrier_idx_r14: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)15u)); + break; + default: + log_invalid_choice_id(type_, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::types_opts::to_string() const +{ + static const char* options[] = {"dl-CarrierConfig-r14", "dl-CarrierIndex-r14"}; + return convert_enum_idx(options, 2, value, "sib_type20_nb_r14_s::sc_mcch_carrier_cfg_r14_c_::types"); +} + +const char* sib_type20_nb_r14_s::sc_mcch_repeat_period_r14_opts::to_string() const +{ + static const char* options[] = {"rf32", "rf128", "rf512", "rf1024", "rf2048", "rf4096", "rf8192", "rf16384"}; + return convert_enum_idx(options, 8, value, "sib_type20_nb_r14_s::sc_mcch_repeat_period_r14_e_"); +} +uint16_t sib_type20_nb_r14_s::sc_mcch_repeat_period_r14_opts::to_number() const +{ + static const uint16_t options[] = {32, 128, 512, 1024, 2048, 4096, 8192, 16384}; + return map_enum_number(options, 8, value, "sib_type20_nb_r14_s::sc_mcch_repeat_period_r14_e_"); +} + +const char* sib_type20_nb_r14_s::sc_mcch_mod_period_r14_opts::to_string() const +{ + static const char* options[] = {"rf32", + "rf128", + "rf256", + "rf512", + "rf1024", + "rf2048", + "rf4096", + "rf8192", + "rf16384", + "rf32768", + "rf65536", + "rf131072", + "rf262144", + "rf524288", + "rf1048576", + "spare1"}; + return convert_enum_idx(options, 16, value, "sib_type20_nb_r14_s::sc_mcch_mod_period_r14_e_"); +} +uint32_t sib_type20_nb_r14_s::sc_mcch_mod_period_r14_opts::to_number() const +{ + static const uint32_t options[] = { + 32, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576}; + return map_enum_number(options, 15, value, "sib_type20_nb_r14_s::sc_mcch_mod_period_r14_e_"); +} + +// SystemInformationBlockType22-NB-r14 ::= SEQUENCE +SRSASN_CODE sib_type22_nb_r14_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(dl_cfg_list_r14_present, 1)); + HANDLE_CODE(bref.pack(ul_cfg_list_r14_present, 1)); + HANDLE_CODE(bref.pack(paging_weight_anchor_r14_present, 1)); + HANDLE_CODE(bref.pack(nprach_probability_anchor_list_r14_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + if (dl_cfg_list_r14_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, dl_cfg_list_r14, 1, 15)); + } + if (ul_cfg_list_r14_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, ul_cfg_list_r14, 1, 15)); + } + if (paging_weight_anchor_r14_present) { + HANDLE_CODE(paging_weight_anchor_r14.pack(bref)); + } + if (nprach_probability_anchor_list_r14_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, nprach_probability_anchor_list_r14, 1, 3)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= mixed_operation_mode_cfg_r15.is_present(); + group_flags[0] |= ul_cfg_list_r15.is_present(); + group_flags[1] |= coverage_based_paging_cfg_r17.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(mixed_operation_mode_cfg_r15.is_present(), 1)); + HANDLE_CODE(bref.pack(ul_cfg_list_r15.is_present(), 1)); + if (mixed_operation_mode_cfg_r15.is_present()) { + HANDLE_CODE(bref.pack(mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15_present, 1)); + HANDLE_CODE(bref.pack(mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15_present, 1)); + HANDLE_CODE(bref.pack(mixed_operation_mode_cfg_r15->paging_distribution_r15_present, 1)); + HANDLE_CODE(bref.pack(mixed_operation_mode_cfg_r15->nprach_distribution_r15_present, 1)); + if (mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15, 1, 15)); + } + if (mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15, 1, 15)); + } + } + if (ul_cfg_list_r15.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *ul_cfg_list_r15, 1, 15)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(coverage_based_paging_cfg_r17.is_present(), 1)); + if (coverage_based_paging_cfg_r17.is_present()) { + HANDLE_CODE(coverage_based_paging_cfg_r17->pack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type22_nb_r14_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(dl_cfg_list_r14_present, 1)); + HANDLE_CODE(bref.unpack(ul_cfg_list_r14_present, 1)); + HANDLE_CODE(bref.unpack(paging_weight_anchor_r14_present, 1)); + HANDLE_CODE(bref.unpack(nprach_probability_anchor_list_r14_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + if (dl_cfg_list_r14_present) { + HANDLE_CODE(unpack_dyn_seq_of(dl_cfg_list_r14, bref, 1, 15)); + } + if (ul_cfg_list_r14_present) { + HANDLE_CODE(unpack_dyn_seq_of(ul_cfg_list_r14, bref, 1, 15)); + } + if (paging_weight_anchor_r14_present) { + HANDLE_CODE(paging_weight_anchor_r14.unpack(bref)); + } + if (nprach_probability_anchor_list_r14_present) { + HANDLE_CODE(unpack_dyn_seq_of(nprach_probability_anchor_list_r14, bref, 1, 3)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(2); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool mixed_operation_mode_cfg_r15_present; + HANDLE_CODE(bref.unpack(mixed_operation_mode_cfg_r15_present, 1)); + mixed_operation_mode_cfg_r15.set_present(mixed_operation_mode_cfg_r15_present); + bool ul_cfg_list_r15_present; + HANDLE_CODE(bref.unpack(ul_cfg_list_r15_present, 1)); + ul_cfg_list_r15.set_present(ul_cfg_list_r15_present); + if (mixed_operation_mode_cfg_r15.is_present()) { + HANDLE_CODE(bref.unpack(mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15_present, 1)); + HANDLE_CODE(bref.unpack(mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15_present, 1)); + HANDLE_CODE(bref.unpack(mixed_operation_mode_cfg_r15->paging_distribution_r15_present, 1)); + HANDLE_CODE(bref.unpack(mixed_operation_mode_cfg_r15->nprach_distribution_r15_present, 1)); + if (mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15, bref, 1, 15)); + } + if (mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15_present) { + HANDLE_CODE(unpack_dyn_seq_of(mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15, bref, 1, 15)); + } + } + if (ul_cfg_list_r15.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*ul_cfg_list_r15, bref, 1, 15)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool coverage_based_paging_cfg_r17_present; + HANDLE_CODE(bref.unpack(coverage_based_paging_cfg_r17_present, 1)); + coverage_based_paging_cfg_r17.set_present(coverage_based_paging_cfg_r17_present); + if (coverage_based_paging_cfg_r17.is_present()) { + HANDLE_CODE(coverage_based_paging_cfg_r17->unpack(bref)); + } + } + } + return SRSASN_SUCCESS; +} +void sib_type22_nb_r14_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (dl_cfg_list_r14_present) { + j.start_array("dl-ConfigList-r14"); + for (const auto& e1 : dl_cfg_list_r14) { + e1.to_json(j); + } + j.end_array(); + } + if (ul_cfg_list_r14_present) { + j.start_array("ul-ConfigList-r14"); + for (const auto& e1 : ul_cfg_list_r14) { + e1.to_json(j); + } + j.end_array(); + } + if (paging_weight_anchor_r14_present) { + j.write_str("pagingWeightAnchor-r14", paging_weight_anchor_r14.to_string()); + } + if (nprach_probability_anchor_list_r14_present) { + j.start_array("nprach-ProbabilityAnchorList-r14"); + for (const auto& e1 : nprach_probability_anchor_list_r14) { + e1.to_json(j); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (ext) { + if (mixed_operation_mode_cfg_r15.is_present()) { + j.write_fieldname("mixedOperationModeConfig-r15"); + j.start_obj(); + if (mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15_present) { + j.start_array("dl-ConfigListMixed-r15"); + for (const auto& e1 : mixed_operation_mode_cfg_r15->dl_cfg_list_mixed_r15) { + e1.to_json(j); + } + j.end_array(); + } + if (mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15_present) { + j.start_array("ul-ConfigListMixed-r15"); + for (const auto& e1 : mixed_operation_mode_cfg_r15->ul_cfg_list_mixed_r15) { + e1.to_json(j); + } + j.end_array(); + } + if (mixed_operation_mode_cfg_r15->paging_distribution_r15_present) { + j.write_str("pagingDistribution-r15", "true"); + } + if (mixed_operation_mode_cfg_r15->nprach_distribution_r15_present) { + j.write_str("nprach-Distribution-r15", "true"); + } + j.end_obj(); + } + if (ul_cfg_list_r15.is_present()) { + j.start_array("ul-ConfigList-r15"); + for (const auto& e1 : *ul_cfg_list_r15) { + e1.to_json(j); + } + j.end_array(); + } + if (coverage_based_paging_cfg_r17.is_present()) { + j.write_fieldname("coverageBasedPagingConfig-r17"); + coverage_based_paging_cfg_r17->to_json(j); + } + } + j.end_obj(); +} + +// SystemInformationBlockType23-NB-r15 ::= SEQUENCE +SRSASN_CODE sib_type23_nb_r15_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ul_cfg_list_v1530_present, 1)); + HANDLE_CODE(bref.pack(ul_cfg_list_mixed_v1530_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + if (ul_cfg_list_v1530_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, ul_cfg_list_v1530, 1, 15)); + } + if (ul_cfg_list_mixed_v1530_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, ul_cfg_list_mixed_v1530, 1, 15)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type23_nb_r15_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ul_cfg_list_v1530_present, 1)); + HANDLE_CODE(bref.unpack(ul_cfg_list_mixed_v1530_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + if (ul_cfg_list_v1530_present) { + HANDLE_CODE(unpack_dyn_seq_of(ul_cfg_list_v1530, bref, 1, 15)); + } + if (ul_cfg_list_mixed_v1530_present) { + HANDLE_CODE(unpack_dyn_seq_of(ul_cfg_list_mixed_v1530, bref, 1, 15)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type23_nb_r15_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ul_cfg_list_v1530_present) { + j.start_array("ul-ConfigList-v1530"); + for (const auto& e1 : ul_cfg_list_v1530) { + e1.to_json(j); + } + j.end_array(); + } + if (ul_cfg_list_mixed_v1530_present) { + j.start_array("ul-ConfigListMixed-v1530"); + for (const auto& e1 : ul_cfg_list_mixed_v1530) { + e1.to_json(j); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + +// SystemInformationBlockType27-NB-r16 ::= SEQUENCE +SRSASN_CODE sib_type27_nb_r16_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(carrier_freq_list_eutra_r16_present, 1)); + HANDLE_CODE(bref.pack(carrier_freqs_list_geran_r16_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + if (carrier_freq_list_eutra_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, carrier_freq_list_eutra_r16, 1, 8)); + } + if (carrier_freqs_list_geran_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, carrier_freqs_list_geran_r16, 1, 8)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type27_nb_r16_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(carrier_freq_list_eutra_r16_present, 1)); + HANDLE_CODE(bref.unpack(carrier_freqs_list_geran_r16_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + if (carrier_freq_list_eutra_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(carrier_freq_list_eutra_r16, bref, 1, 8)); + } + if (carrier_freqs_list_geran_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(carrier_freqs_list_geran_r16, bref, 1, 8)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type27_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (carrier_freq_list_eutra_r16_present) { + j.start_array("carrierFreqListEUTRA-r16"); + for (const auto& e1 : carrier_freq_list_eutra_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (carrier_freqs_list_geran_r16_present) { + j.start_array("carrierFreqsListGERAN-r16"); + for (const auto& e1 : carrier_freqs_list_geran_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + +// SystemInformationBlockType3-NB-r13 ::= SEQUENCE +SRSASN_CODE sib_type3_nb_r13_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(freq_band_info_r13_present, 1)); + HANDLE_CODE(bref.pack(multi_band_info_list_r13_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(cell_resel_info_common_r13.q_hyst_r13.pack(bref)); + HANDLE_CODE(pack_integer(bref, cell_resel_serving_freq_info_r13.s_non_intra_search_r13, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(bref.pack(intra_freq_cell_resel_info_r13.q_qual_min_r13_present, 1)); + HANDLE_CODE(bref.pack(intra_freq_cell_resel_info_r13.p_max_r13_present, 1)); + HANDLE_CODE(pack_integer(bref, intra_freq_cell_resel_info_r13.q_rx_lev_min_r13, (int8_t)-70, (int8_t)-22)); + if (intra_freq_cell_resel_info_r13.q_qual_min_r13_present) { + HANDLE_CODE(pack_integer(bref, intra_freq_cell_resel_info_r13.q_qual_min_r13, (int8_t)-34, (int8_t)-3)); + } + if (intra_freq_cell_resel_info_r13.p_max_r13_present) { + HANDLE_CODE(pack_integer(bref, intra_freq_cell_resel_info_r13.p_max_r13, (int8_t)-30, (int8_t)33)); + } + HANDLE_CODE(pack_integer(bref, intra_freq_cell_resel_info_r13.s_intra_search_p_r13, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(intra_freq_cell_resel_info_r13.t_resel_r13.pack(bref)); + if (freq_band_info_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_info_r13, 1, 4)); + } + if (multi_band_info_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, multi_band_info_list_r13, 1, 8, SeqOfPacker(1, 4, Packer()))); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= intra_freq_cell_resel_info_v1350.is_present(); + group_flags[1] |= intra_freq_cell_resel_info_v1360.is_present(); + group_flags[2] |= intra_freq_cell_resel_info_v1430.is_present(); + group_flags[3] |= cell_resel_info_common_v1450.is_present(); + group_flags[4] |= nsss_rrm_cfg_r15.is_present(); + group_flags[4] |= npbch_rrm_cfg_r15_present; + group_flags[5] |= conn_meas_cfg_r17.is_present(); + group_flags[5] |= t_service_r17_present; + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(intra_freq_cell_resel_info_v1350.is_present(), 1)); + if (intra_freq_cell_resel_info_v1350.is_present()) { + HANDLE_CODE(intra_freq_cell_resel_info_v1350->pack(bref)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(intra_freq_cell_resel_info_v1360.is_present(), 1)); + if (intra_freq_cell_resel_info_v1360.is_present()) { + HANDLE_CODE(intra_freq_cell_resel_info_v1360->pack(bref)); + } + } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(intra_freq_cell_resel_info_v1430.is_present(), 1)); + if (intra_freq_cell_resel_info_v1430.is_present()) { + HANDLE_CODE(intra_freq_cell_resel_info_v1430->pack(bref)); + } + } + if (group_flags[3]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(cell_resel_info_common_v1450.is_present(), 1)); + if (cell_resel_info_common_v1450.is_present()) { + HANDLE_CODE(cell_resel_info_common_v1450->pack(bref)); + } + } + if (group_flags[4]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(nsss_rrm_cfg_r15.is_present(), 1)); + HANDLE_CODE(bref.pack(npbch_rrm_cfg_r15_present, 1)); + if (nsss_rrm_cfg_r15.is_present()) { + HANDLE_CODE(nsss_rrm_cfg_r15->pack(bref)); + } + } + if (group_flags[5]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(conn_meas_cfg_r17.is_present(), 1)); + HANDLE_CODE(bref.pack(t_service_r17_present, 1)); + if (conn_meas_cfg_r17.is_present()) { + HANDLE_CODE(conn_meas_cfg_r17->pack(bref)); + } + if (t_service_r17_present) { + HANDLE_CODE(pack_integer(bref, t_service_r17, (uint32_t)0u, (uint32_t)1048575u)); + } + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type3_nb_r13_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(freq_band_info_r13_present, 1)); + HANDLE_CODE(bref.unpack(multi_band_info_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(cell_resel_info_common_r13.q_hyst_r13.unpack(bref)); + HANDLE_CODE(unpack_integer(cell_resel_serving_freq_info_r13.s_non_intra_search_r13, bref, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(bref.unpack(intra_freq_cell_resel_info_r13.q_qual_min_r13_present, 1)); + HANDLE_CODE(bref.unpack(intra_freq_cell_resel_info_r13.p_max_r13_present, 1)); + HANDLE_CODE(unpack_integer(intra_freq_cell_resel_info_r13.q_rx_lev_min_r13, bref, (int8_t)-70, (int8_t)-22)); + if (intra_freq_cell_resel_info_r13.q_qual_min_r13_present) { + HANDLE_CODE(unpack_integer(intra_freq_cell_resel_info_r13.q_qual_min_r13, bref, (int8_t)-34, (int8_t)-3)); + } + if (intra_freq_cell_resel_info_r13.p_max_r13_present) { + HANDLE_CODE(unpack_integer(intra_freq_cell_resel_info_r13.p_max_r13, bref, (int8_t)-30, (int8_t)33)); + } + HANDLE_CODE(unpack_integer(intra_freq_cell_resel_info_r13.s_intra_search_p_r13, bref, (uint8_t)0u, (uint8_t)31u)); + HANDLE_CODE(intra_freq_cell_resel_info_r13.t_resel_r13.unpack(bref)); + if (freq_band_info_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(freq_band_info_r13, bref, 1, 4)); + } + if (multi_band_info_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r13, bref, 1, 8, SeqOfPacker(1, 4, Packer()))); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(6); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool intra_freq_cell_resel_info_v1350_present; + HANDLE_CODE(bref.unpack(intra_freq_cell_resel_info_v1350_present, 1)); + intra_freq_cell_resel_info_v1350.set_present(intra_freq_cell_resel_info_v1350_present); + if (intra_freq_cell_resel_info_v1350.is_present()) { + HANDLE_CODE(intra_freq_cell_resel_info_v1350->unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool intra_freq_cell_resel_info_v1360_present; + HANDLE_CODE(bref.unpack(intra_freq_cell_resel_info_v1360_present, 1)); + intra_freq_cell_resel_info_v1360.set_present(intra_freq_cell_resel_info_v1360_present); + if (intra_freq_cell_resel_info_v1360.is_present()) { + HANDLE_CODE(intra_freq_cell_resel_info_v1360->unpack(bref)); + } + } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool intra_freq_cell_resel_info_v1430_present; + HANDLE_CODE(bref.unpack(intra_freq_cell_resel_info_v1430_present, 1)); + intra_freq_cell_resel_info_v1430.set_present(intra_freq_cell_resel_info_v1430_present); + if (intra_freq_cell_resel_info_v1430.is_present()) { + HANDLE_CODE(intra_freq_cell_resel_info_v1430->unpack(bref)); + } + } + if (group_flags[3]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool cell_resel_info_common_v1450_present; + HANDLE_CODE(bref.unpack(cell_resel_info_common_v1450_present, 1)); + cell_resel_info_common_v1450.set_present(cell_resel_info_common_v1450_present); + if (cell_resel_info_common_v1450.is_present()) { + HANDLE_CODE(cell_resel_info_common_v1450->unpack(bref)); + } + } + if (group_flags[4]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool nsss_rrm_cfg_r15_present; + HANDLE_CODE(bref.unpack(nsss_rrm_cfg_r15_present, 1)); + nsss_rrm_cfg_r15.set_present(nsss_rrm_cfg_r15_present); + HANDLE_CODE(bref.unpack(npbch_rrm_cfg_r15_present, 1)); + if (nsss_rrm_cfg_r15.is_present()) { + HANDLE_CODE(nsss_rrm_cfg_r15->unpack(bref)); + } + } + if (group_flags[5]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool conn_meas_cfg_r17_present; + HANDLE_CODE(bref.unpack(conn_meas_cfg_r17_present, 1)); + conn_meas_cfg_r17.set_present(conn_meas_cfg_r17_present); + HANDLE_CODE(bref.unpack(t_service_r17_present, 1)); + if (conn_meas_cfg_r17.is_present()) { + HANDLE_CODE(conn_meas_cfg_r17->unpack(bref)); + } + if (t_service_r17_present) { + HANDLE_CODE(unpack_integer(t_service_r17, bref, (uint32_t)0u, (uint32_t)1048575u)); + } + } + } + return SRSASN_SUCCESS; +} +void sib_type3_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("cellReselectionInfoCommon-r13"); + j.start_obj(); + j.write_str("q-Hyst-r13", cell_resel_info_common_r13.q_hyst_r13.to_string()); + j.end_obj(); + j.write_fieldname("cellReselectionServingFreqInfo-r13"); + j.start_obj(); + j.write_int("s-NonIntraSearch-r13", cell_resel_serving_freq_info_r13.s_non_intra_search_r13); + j.end_obj(); + j.write_fieldname("intraFreqCellReselectionInfo-r13"); + j.start_obj(); + j.write_int("q-RxLevMin-r13", intra_freq_cell_resel_info_r13.q_rx_lev_min_r13); + if (intra_freq_cell_resel_info_r13.q_qual_min_r13_present) { + j.write_int("q-QualMin-r13", intra_freq_cell_resel_info_r13.q_qual_min_r13); + } + if (intra_freq_cell_resel_info_r13.p_max_r13_present) { + j.write_int("p-Max-r13", intra_freq_cell_resel_info_r13.p_max_r13); + } + j.write_int("s-IntraSearchP-r13", intra_freq_cell_resel_info_r13.s_intra_search_p_r13); + j.write_str("t-Reselection-r13", intra_freq_cell_resel_info_r13.t_resel_r13.to_string()); + j.end_obj(); + if (freq_band_info_r13_present) { + j.start_array("freqBandInfo-r13"); + for (const auto& e1 : freq_band_info_r13) { + e1.to_json(j); + } + j.end_array(); + } + if (multi_band_info_list_r13_present) { + j.start_array("multiBandInfoList-r13"); + for (const auto& e1 : multi_band_info_list_r13) { + j.start_array(); + for (const auto& e2 : e1) { + e2.to_json(j); + } + j.end_array(); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (ext) { + if (intra_freq_cell_resel_info_v1350.is_present()) { + j.write_fieldname("intraFreqCellReselectionInfo-v1350"); + intra_freq_cell_resel_info_v1350->to_json(j); + } + if (intra_freq_cell_resel_info_v1360.is_present()) { + j.write_fieldname("intraFreqCellReselectionInfo-v1360"); + intra_freq_cell_resel_info_v1360->to_json(j); + } + if (intra_freq_cell_resel_info_v1430.is_present()) { + j.write_fieldname("intraFreqCellReselectionInfo-v1430"); + intra_freq_cell_resel_info_v1430->to_json(j); + } + if (cell_resel_info_common_v1450.is_present()) { + j.write_fieldname("cellReselectionInfoCommon-v1450"); + cell_resel_info_common_v1450->to_json(j); + } + if (nsss_rrm_cfg_r15.is_present()) { + j.write_fieldname("nsss-RRM-Config-r15"); + nsss_rrm_cfg_r15->to_json(j); + } + if (npbch_rrm_cfg_r15_present) { + j.write_str("npbch-RRM-Config-r15", "enabled"); + } + if (conn_meas_cfg_r17.is_present()) { + j.write_fieldname("connMeasConfig-r17"); + conn_meas_cfg_r17->to_json(j); + } + if (t_service_r17_present) { + j.write_int("t-Service-r17", t_service_r17); + } + } + j.end_obj(); +} + +const char* sib_type3_nb_r13_s::cell_resel_info_common_r13_s_::q_hyst_r13_opts::to_string() const +{ + static const char* options[] = {"dB0", + "dB1", + "dB2", + "dB3", + "dB4", + "dB5", + "dB6", + "dB8", + "dB10", + "dB12", + "dB14", + "dB16", + "dB18", + "dB20", + "dB22", + "dB24"}; + return convert_enum_idx(options, 16, value, "sib_type3_nb_r13_s::cell_resel_info_common_r13_s_::q_hyst_r13_e_"); +} +uint8_t sib_type3_nb_r13_s::cell_resel_info_common_r13_s_::q_hyst_r13_opts::to_number() const +{ + static const uint8_t options[] = {0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24}; + return map_enum_number(options, 16, value, "sib_type3_nb_r13_s::cell_resel_info_common_r13_s_::q_hyst_r13_e_"); +} + +// SystemInformationBlockType31-NB-r17 ::= SEQUENCE +SRSASN_CODE sib_type31_nb_r17_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(serving_satellite_info_r17.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type31_nb_r17_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(serving_satellite_info_r17.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type31_nb_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("servingSatelliteInfo-r17"); + serving_satellite_info_r17.to_json(j); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + +// SystemInformationBlockType32-NB-r17 ::= SEQUENCE +SRSASN_CODE sib_type32_nb_r17_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(satellite_info_list_r17_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + if (satellite_info_list_r17_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, satellite_info_list_r17, 1, 4)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type32_nb_r17_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(satellite_info_list_r17_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + if (satellite_info_list_r17_present) { + HANDLE_CODE(unpack_dyn_seq_of(satellite_info_list_r17, bref, 1, 4)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type32_nb_r17_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (satellite_info_list_r17_present) { + j.start_array("satelliteInfoList-r17"); + for (const auto& e1 : satellite_info_list_r17) { + e1.to_json(j); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + j.end_obj(); +} + +// SystemInformationBlockType4-NB-r13 ::= SEQUENCE +SRSASN_CODE sib_type4_nb_r13_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(intra_freq_neigh_cell_list_r13_present, 1)); + HANDLE_CODE(bref.pack(intra_freq_excluded_cell_list_r13_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + if (intra_freq_neigh_cell_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, intra_freq_neigh_cell_list_r13, 1, 16)); + } + if (intra_freq_excluded_cell_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, intra_freq_excluded_cell_list_r13, 1, 16)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= nsss_rrm_cfg_r15.is_present(); + group_flags[0] |= intra_freq_neigh_cell_list_v1530.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(nsss_rrm_cfg_r15.is_present(), 1)); + HANDLE_CODE(bref.pack(intra_freq_neigh_cell_list_v1530.is_present(), 1)); + if (nsss_rrm_cfg_r15.is_present()) { + HANDLE_CODE(nsss_rrm_cfg_r15->pack(bref)); + } + if (intra_freq_neigh_cell_list_v1530.is_present()) { + HANDLE_CODE(pack_dyn_seq_of(bref, *intra_freq_neigh_cell_list_v1530, 1, 16)); + } + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type4_nb_r13_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(intra_freq_neigh_cell_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(intra_freq_excluded_cell_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + if (intra_freq_neigh_cell_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(intra_freq_neigh_cell_list_r13, bref, 1, 16)); + } + if (intra_freq_excluded_cell_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(intra_freq_excluded_cell_list_r13, bref, 1, 16)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool nsss_rrm_cfg_r15_present; + HANDLE_CODE(bref.unpack(nsss_rrm_cfg_r15_present, 1)); + nsss_rrm_cfg_r15.set_present(nsss_rrm_cfg_r15_present); + bool intra_freq_neigh_cell_list_v1530_present; + HANDLE_CODE(bref.unpack(intra_freq_neigh_cell_list_v1530_present, 1)); + intra_freq_neigh_cell_list_v1530.set_present(intra_freq_neigh_cell_list_v1530_present); + if (nsss_rrm_cfg_r15.is_present()) { + HANDLE_CODE(nsss_rrm_cfg_r15->unpack(bref)); + } + if (intra_freq_neigh_cell_list_v1530.is_present()) { + HANDLE_CODE(unpack_dyn_seq_of(*intra_freq_neigh_cell_list_v1530, bref, 1, 16)); + } + } + } + return SRSASN_SUCCESS; +} +void sib_type4_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (intra_freq_neigh_cell_list_r13_present) { + j.start_array("intraFreqNeighCellList-r13"); + for (const auto& e1 : intra_freq_neigh_cell_list_r13) { + e1.to_json(j); + } + j.end_array(); + } + if (intra_freq_excluded_cell_list_r13_present) { + j.start_array("intraFreqExcludedCellList-r13"); + for (const auto& e1 : intra_freq_excluded_cell_list_r13) { + e1.to_json(j); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (ext) { + if (nsss_rrm_cfg_r15.is_present()) { + j.write_fieldname("nsss-RRM-Config-r15"); + nsss_rrm_cfg_r15->to_json(j); + } + if (intra_freq_neigh_cell_list_v1530.is_present()) { + j.start_array("intraFreqNeighCellList-v1530"); + for (const auto& e1 : *intra_freq_neigh_cell_list_v1530) { + e1.to_json(j); + } + j.end_array(); + } + } + j.end_obj(); +} + +// SystemInformationBlockType5-NB-r13 ::= SEQUENCE +SRSASN_CODE sib_type5_nb_r13_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_carrier_freq_list_r13, 1, 8)); + HANDLE_CODE(t_resel_r13.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= scptm_freq_offset_r14_present; + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(scptm_freq_offset_r14_present, 1)); + if (scptm_freq_offset_r14_present) { + HANDLE_CODE(pack_integer(bref, scptm_freq_offset_r14, (uint8_t)1u, (uint8_t)8u)); + } + } + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type5_nb_r13_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(inter_freq_carrier_freq_list_r13, bref, 1, 8)); + HANDLE_CODE(t_resel_r13.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(1); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(scptm_freq_offset_r14_present, 1)); + if (scptm_freq_offset_r14_present) { + HANDLE_CODE(unpack_integer(scptm_freq_offset_r14, bref, (uint8_t)1u, (uint8_t)8u)); + } + } + } + return SRSASN_SUCCESS; +} +void sib_type5_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("interFreqCarrierFreqList-r13"); + for (const auto& e1 : inter_freq_carrier_freq_list_r13) { + e1.to_json(j); + } + j.end_array(); + j.write_str("t-Reselection-r13", t_resel_r13.to_string()); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (ext) { + if (scptm_freq_offset_r14_present) { + j.write_int("scptm-FreqOffset-r14", scptm_freq_offset_r14); + } + } + j.end_obj(); +} + +// SystemInformation-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE sys_info_nb_r13_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, sib_type_and_info_r13, 1, 32)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sys_info_nb_r13_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(sib_type_and_info_r13, bref, 1, 32)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sys_info_nb_r13_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("sib-TypeAndInfo-r13"); + for (const auto& e1 : sib_type_and_info_r13) { + e1.to_json(j); + } + j.end_array(); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +void sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::destroy_() +{ + switch (type_) { + case types::sib2_r13: + c.destroy(); + break; + case types::sib3_r13: + c.destroy(); + break; + case types::sib4_r13: + c.destroy(); + break; + case types::sib5_r13: + c.destroy(); + break; + case types::sib14_r13: + c.destroy(); + break; + case types::sib16_r13: + c.destroy(); + break; + case types::sib15_v1430: + c.destroy(); + break; + case types::sib20_v1430: + c.destroy(); + break; + case types::sib22_v1430: + c.destroy(); + break; + case types::sib23_v1530: + c.destroy(); + break; + case types::sib27_v1610: + c.destroy(); + break; + case types::sib31_v1700: + c.destroy(); + break; + case types::sib32_v1700: + c.destroy(); + break; + default: + break; + } +} +void sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::sib2_r13: + c.init(); + break; + case types::sib3_r13: + c.init(); + break; + case types::sib4_r13: + c.init(); + break; + case types::sib5_r13: + c.init(); + break; + case types::sib14_r13: + c.init(); + break; + case types::sib16_r13: + c.init(); + break; + case types::sib15_v1430: + c.init(); + break; + case types::sib20_v1430: + c.init(); + break; + case types::sib22_v1430: + c.init(); + break; + case types::sib23_v1530: + c.init(); + break; + case types::sib27_v1610: + c.init(); + break; + case types::sib31_v1700: + c.init(); + break; + case types::sib32_v1700: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + } +} +sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::sib_type_and_info_r13_item_c_( + const sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::sib2_r13: + c.init(other.c.get()); + break; + case types::sib3_r13: + c.init(other.c.get()); + break; + case types::sib4_r13: + c.init(other.c.get()); + break; + case types::sib5_r13: + c.init(other.c.get()); + break; + case types::sib14_r13: + c.init(other.c.get()); + break; + case types::sib16_r13: + c.init(other.c.get()); + break; + case types::sib15_v1430: + c.init(other.c.get()); + break; + case types::sib20_v1430: + c.init(other.c.get()); + break; + case types::sib22_v1430: + c.init(other.c.get()); + break; + case types::sib23_v1530: + c.init(other.c.get()); + break; + case types::sib27_v1610: + c.init(other.c.get()); + break; + case types::sib31_v1700: + c.init(other.c.get()); + break; + case types::sib32_v1700: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + } +} +sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::operator=( + const sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::sib2_r13: + c.set(other.c.get()); + break; + case types::sib3_r13: + c.set(other.c.get()); + break; + case types::sib4_r13: + c.set(other.c.get()); + break; + case types::sib5_r13: + c.set(other.c.get()); + break; + case types::sib14_r13: + c.set(other.c.get()); + break; + case types::sib16_r13: + c.set(other.c.get()); + break; + case types::sib15_v1430: + c.set(other.c.get()); + break; + case types::sib20_v1430: + c.set(other.c.get()); + break; + case types::sib22_v1430: + c.set(other.c.get()); + break; + case types::sib23_v1530: + c.set(other.c.get()); + break; + case types::sib27_v1610: + c.set(other.c.get()); + break; + case types::sib31_v1700: + c.set(other.c.get()); + break; + case types::sib32_v1700: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + } + + return *this; +} +sib_type2_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib2_r13() +{ + set(types::sib2_r13); + return c.get(); +} +sib_type3_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib3_r13() +{ + set(types::sib3_r13); + return c.get(); +} +sib_type4_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib4_r13() +{ + set(types::sib4_r13); + return c.get(); +} +sib_type5_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib5_r13() +{ + set(types::sib5_r13); + return c.get(); +} +sib_type14_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib14_r13() +{ + set(types::sib14_r13); + return c.get(); +} +sib_type16_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib16_r13() +{ + set(types::sib16_r13); + return c.get(); +} +sib_type15_nb_r14_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib15_v1430() +{ + set(types::sib15_v1430); + return c.get(); +} +sib_type20_nb_r14_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib20_v1430() +{ + set(types::sib20_v1430); + return c.get(); +} +sib_type22_nb_r14_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib22_v1430() +{ + set(types::sib22_v1430); + return c.get(); +} +sib_type23_nb_r15_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib23_v1530() +{ + set(types::sib23_v1530); + return c.get(); +} +sib_type27_nb_r16_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib27_v1610() +{ + set(types::sib27_v1610); + return c.get(); +} +sib_type31_nb_r17_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib31_v1700() +{ + set(types::sib31_v1700); + return c.get(); +} +sib_type32_nb_r17_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib32_v1700() +{ + set(types::sib32_v1700); + return c.get(); +} +void sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::sib2_r13: + j.write_fieldname("sib2-r13"); + c.get().to_json(j); + break; + case types::sib3_r13: + j.write_fieldname("sib3-r13"); + c.get().to_json(j); + break; + case types::sib4_r13: + j.write_fieldname("sib4-r13"); + c.get().to_json(j); + break; + case types::sib5_r13: + j.write_fieldname("sib5-r13"); + c.get().to_json(j); + break; + case types::sib14_r13: + j.write_fieldname("sib14-r13"); + c.get().to_json(j); + break; + case types::sib16_r13: + j.write_fieldname("sib16-r13"); + c.get().to_json(j); + break; + case types::sib15_v1430: + j.write_fieldname("sib15-v1430"); + c.get().to_json(j); + break; + case types::sib20_v1430: + j.write_fieldname("sib20-v1430"); + c.get().to_json(j); + break; + case types::sib22_v1430: + j.write_fieldname("sib22-v1430"); + c.get().to_json(j); + break; + case types::sib23_v1530: + j.write_fieldname("sib23-v1530"); + c.get().to_json(j); + break; + case types::sib27_v1610: + j.write_fieldname("sib27-v1610"); + c.get().to_json(j); + break; + case types::sib31_v1700: + j.write_fieldname("sib31-v1700"); + c.get().to_json(j); + break; + case types::sib32_v1700: + j.write_fieldname("sib32-v1700"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + } + j.end_obj(); +} +SRSASN_CODE sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::sib2_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::sib3_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::sib4_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::sib5_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::sib14_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::sib16_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::sib15_v1430: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib20_v1430: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib22_v1430: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib23_v1530: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib27_v1610: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib31_v1700: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + case types::sib32_v1700: { + varlength_field_pack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().pack(bref)); + } break; + default: + log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::sib2_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::sib3_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::sib4_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::sib5_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::sib14_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::sib16_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::sib15_v1430: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib20_v1430: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib22_v1430: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib23_v1530: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib27_v1610: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib31_v1700: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + case types::sib32_v1700: { + varlength_field_unpack_guard varlen_scope(bref, false); + HANDLE_CODE(c.get().unpack(bref)); + } break; + default: + log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::types_opts::to_string() const +{ + static const char* options[] = {"sib2-r13", + "sib3-r13", + "sib4-r13", + "sib5-r13", + "sib14-r13", + "sib16-r13", + "sib15-v1430", + "sib20-v1430", + "sib22-v1430", + "sib23-v1530", + "sib27-v1610", + "sib31-v1700", + "sib32-v1700"}; + return convert_enum_idx(options, 13, value, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::types"); +} +uint8_t sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::types_opts::to_number() const +{ + static const uint8_t options[] = {2, 3, 4, 5, 14, 16, 15, 20, 22, 23, 27, 31, 32}; + return map_enum_number(options, 13, value, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::types"); +} + +// SystemInformationBlockType1-NB-v1350 ::= SEQUENCE +SRSASN_CODE sib_type1_nb_v1350_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(cell_sel_info_v1350_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (cell_sel_info_v1350_present) { + HANDLE_CODE(cell_sel_info_v1350.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type1_nb_v1350_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(cell_sel_info_v1350_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (cell_sel_info_v1350_present) { + HANDLE_CODE(cell_sel_info_v1350.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type1_nb_v1350_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (cell_sel_info_v1350_present) { + j.write_fieldname("cellSelectionInfo-v1350"); + cell_sel_info_v1350.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// SystemInformation-NB ::= SEQUENCE +SRSASN_CODE sys_info_nb_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE sys_info_nb_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void sys_info_nb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void sys_info_nb_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +sys_info_nb_r13_ies_s& sys_info_nb_s::crit_exts_c_::set_sys_info_r13() +{ + set(types::sys_info_r13); + return c; +} +void sys_info_nb_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void sys_info_nb_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::sys_info_r13: + j.write_fieldname("systemInformation-r13"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "sys_info_nb_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE sys_info_nb_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::sys_info_r13: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "sys_info_nb_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sys_info_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::sys_info_r13: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "sys_info_nb_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* sys_info_nb_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"systemInformation-r13", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "sys_info_nb_s::crit_exts_c_::types"); +} + +// SystemInformationBlockType1-NB ::= SEQUENCE +SRSASN_CODE sib_type1_nb_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(p_max_r13_present, 1)); + HANDLE_CODE(bref.pack(freq_band_info_r13_present, 1)); + HANDLE_CODE(bref.pack(multi_band_info_list_r13_present, 1)); + HANDLE_CODE(bref.pack(dl_bitmap_r13_present, 1)); + HANDLE_CODE(bref.pack(eutra_ctrl_region_size_r13_present, 1)); + HANDLE_CODE(bref.pack(nrs_crs_pwr_offset_r13_present, 1)); + HANDLE_CODE(bref.pack(si_radio_frame_offset_r13_present, 1)); + HANDLE_CODE(bref.pack(sys_info_value_tag_list_r13_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(hyper_sfn_msb_r13.pack(bref)); + HANDLE_CODE(pack_dyn_seq_of(bref, cell_access_related_info_r13.plmn_id_list_r13, 1, 6)); + HANDLE_CODE(cell_access_related_info_r13.tac_r13.pack(bref)); + HANDLE_CODE(cell_access_related_info_r13.cell_id_r13.pack(bref)); + HANDLE_CODE(cell_access_related_info_r13.cell_barred_r13.pack(bref)); + HANDLE_CODE(cell_access_related_info_r13.intra_freq_resel_r13.pack(bref)); + HANDLE_CODE(pack_integer(bref, cell_sel_info_r13.q_rx_lev_min_r13, (int8_t)-70, (int8_t)-22)); + HANDLE_CODE(pack_integer(bref, cell_sel_info_r13.q_qual_min_r13, (int8_t)-34, (int8_t)-3)); + if (p_max_r13_present) { + HANDLE_CODE(pack_integer(bref, p_max_r13, (int8_t)-30, (int8_t)33)); + } + HANDLE_CODE(pack_integer(bref, freq_band_ind_r13, (uint16_t)1u, (uint16_t)256u)); + if (freq_band_info_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_info_r13, 1, 4)); + } + if (multi_band_info_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, multi_band_info_list_r13, 1, 8)); + } + if (dl_bitmap_r13_present) { + HANDLE_CODE(dl_bitmap_r13.pack(bref)); + } + if (eutra_ctrl_region_size_r13_present) { + HANDLE_CODE(eutra_ctrl_region_size_r13.pack(bref)); + } + if (nrs_crs_pwr_offset_r13_present) { + HANDLE_CODE(nrs_crs_pwr_offset_r13.pack(bref)); + } + HANDLE_CODE(pack_dyn_seq_of(bref, sched_info_list_r13, 1, 8)); + HANDLE_CODE(si_win_len_r13.pack(bref)); + if (si_radio_frame_offset_r13_present) { + HANDLE_CODE(pack_integer(bref, si_radio_frame_offset_r13, (uint8_t)1u, (uint8_t)15u)); + } + if (sys_info_value_tag_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, sys_info_value_tag_list_r13, 1, 8, integer_packer(0, 3))); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE sib_type1_nb_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(p_max_r13_present, 1)); + HANDLE_CODE(bref.unpack(freq_band_info_r13_present, 1)); + HANDLE_CODE(bref.unpack(multi_band_info_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(dl_bitmap_r13_present, 1)); + HANDLE_CODE(bref.unpack(eutra_ctrl_region_size_r13_present, 1)); + HANDLE_CODE(bref.unpack(nrs_crs_pwr_offset_r13_present, 1)); + HANDLE_CODE(bref.unpack(si_radio_frame_offset_r13_present, 1)); + HANDLE_CODE(bref.unpack(sys_info_value_tag_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(hyper_sfn_msb_r13.unpack(bref)); + HANDLE_CODE(unpack_dyn_seq_of(cell_access_related_info_r13.plmn_id_list_r13, bref, 1, 6)); + HANDLE_CODE(cell_access_related_info_r13.tac_r13.unpack(bref)); + HANDLE_CODE(cell_access_related_info_r13.cell_id_r13.unpack(bref)); + HANDLE_CODE(cell_access_related_info_r13.cell_barred_r13.unpack(bref)); + HANDLE_CODE(cell_access_related_info_r13.intra_freq_resel_r13.unpack(bref)); + HANDLE_CODE(unpack_integer(cell_sel_info_r13.q_rx_lev_min_r13, bref, (int8_t)-70, (int8_t)-22)); + HANDLE_CODE(unpack_integer(cell_sel_info_r13.q_qual_min_r13, bref, (int8_t)-34, (int8_t)-3)); + if (p_max_r13_present) { + HANDLE_CODE(unpack_integer(p_max_r13, bref, (int8_t)-30, (int8_t)33)); + } + HANDLE_CODE(unpack_integer(freq_band_ind_r13, bref, (uint16_t)1u, (uint16_t)256u)); + if (freq_band_info_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(freq_band_info_r13, bref, 1, 4)); + } + if (multi_band_info_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r13, bref, 1, 8)); + } + if (dl_bitmap_r13_present) { + HANDLE_CODE(dl_bitmap_r13.unpack(bref)); + } + if (eutra_ctrl_region_size_r13_present) { + HANDLE_CODE(eutra_ctrl_region_size_r13.unpack(bref)); + } + if (nrs_crs_pwr_offset_r13_present) { + HANDLE_CODE(nrs_crs_pwr_offset_r13.unpack(bref)); + } + HANDLE_CODE(unpack_dyn_seq_of(sched_info_list_r13, bref, 1, 8)); + HANDLE_CODE(si_win_len_r13.unpack(bref)); + if (si_radio_frame_offset_r13_present) { + HANDLE_CODE(unpack_integer(si_radio_frame_offset_r13, bref, (uint8_t)1u, (uint8_t)15u)); + } + if (sys_info_value_tag_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(sys_info_value_tag_list_r13, bref, 1, 8, integer_packer(0, 3))); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void sib_type1_nb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("hyperSFN-MSB-r13", hyper_sfn_msb_r13.to_string()); + j.write_fieldname("cellAccessRelatedInfo-r13"); + j.start_obj(); + j.start_array("plmn-IdentityList-r13"); + for (const auto& e1 : cell_access_related_info_r13.plmn_id_list_r13) { + e1.to_json(j); + } + j.end_array(); + j.write_str("trackingAreaCode-r13", cell_access_related_info_r13.tac_r13.to_string()); + j.write_str("cellIdentity-r13", cell_access_related_info_r13.cell_id_r13.to_string()); + j.write_str("cellBarred-r13", cell_access_related_info_r13.cell_barred_r13.to_string()); + j.write_str("intraFreqReselection-r13", cell_access_related_info_r13.intra_freq_resel_r13.to_string()); + j.end_obj(); + j.write_fieldname("cellSelectionInfo-r13"); + j.start_obj(); + j.write_int("q-RxLevMin-r13", cell_sel_info_r13.q_rx_lev_min_r13); + j.write_int("q-QualMin-r13", cell_sel_info_r13.q_qual_min_r13); + j.end_obj(); + if (p_max_r13_present) { + j.write_int("p-Max-r13", p_max_r13); + } + j.write_int("freqBandIndicator-r13", freq_band_ind_r13); + if (freq_band_info_r13_present) { + j.start_array("freqBandInfo-r13"); + for (const auto& e1 : freq_band_info_r13) { + e1.to_json(j); + } + j.end_array(); + } + if (multi_band_info_list_r13_present) { + j.start_array("multiBandInfoList-r13"); + for (const auto& e1 : multi_band_info_list_r13) { + e1.to_json(j); + } + j.end_array(); + } + if (dl_bitmap_r13_present) { + j.write_fieldname("downlinkBitmap-r13"); + dl_bitmap_r13.to_json(j); + } + if (eutra_ctrl_region_size_r13_present) { + j.write_str("eutraControlRegionSize-r13", eutra_ctrl_region_size_r13.to_string()); + } + if (nrs_crs_pwr_offset_r13_present) { + j.write_str("nrs-CRS-PowerOffset-r13", nrs_crs_pwr_offset_r13.to_string()); + } + j.start_array("schedulingInfoList-r13"); + for (const auto& e1 : sched_info_list_r13) { + e1.to_json(j); + } + j.end_array(); + j.write_str("si-WindowLength-r13", si_win_len_r13.to_string()); + if (si_radio_frame_offset_r13_present) { + j.write_int("si-RadioFrameOffset-r13", si_radio_frame_offset_r13); + } + if (sys_info_value_tag_list_r13_present) { + j.start_array("systemInfoValueTagList-r13"); + for (const auto& e1 : sys_info_value_tag_list_r13) { + j.write_int(e1); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +const char* sib_type1_nb_s::cell_access_related_info_r13_s_::cell_barred_r13_opts::to_string() const +{ + static const char* options[] = {"barred", "notBarred"}; + return convert_enum_idx(options, 2, value, "sib_type1_nb_s::cell_access_related_info_r13_s_::cell_barred_r13_e_"); +} + +const char* sib_type1_nb_s::cell_access_related_info_r13_s_::intra_freq_resel_r13_opts::to_string() const +{ + static const char* options[] = {"allowed", "notAllowed"}; + return convert_enum_idx( + options, 2, value, "sib_type1_nb_s::cell_access_related_info_r13_s_::intra_freq_resel_r13_e_"); +} + +const char* sib_type1_nb_s::eutra_ctrl_region_size_r13_opts::to_string() const +{ + static const char* options[] = {"n1", "n2", "n3"}; + return convert_enum_idx(options, 3, value, "sib_type1_nb_s::eutra_ctrl_region_size_r13_e_"); +} +uint8_t sib_type1_nb_s::eutra_ctrl_region_size_r13_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3}; + return map_enum_number(options, 3, value, "sib_type1_nb_s::eutra_ctrl_region_size_r13_e_"); +} + +const char* sib_type1_nb_s::nrs_crs_pwr_offset_r13_opts::to_string() const +{ + static const char* options[] = {"dB-6", + "dB-4dot77", + "dB-3", + "dB-1dot77", + "dB0", + "dB1", + "dB1dot23", + "dB2", + "dB3", + "dB4", + "dB4dot23", + "dB5", + "dB6", + "dB7", + "dB8", + "dB9"}; + return convert_enum_idx(options, 16, value, "sib_type1_nb_s::nrs_crs_pwr_offset_r13_e_"); +} +float sib_type1_nb_s::nrs_crs_pwr_offset_r13_opts::to_number() const +{ + static const float options[] = { + -6.0, -4.77, -3.0, -1.77, 0.0, 1.0, 1.23, 2.0, 3.0, 4.0, 4.23, 5.0, 6.0, 7.0, 8.0, 9.0}; + return map_enum_number(options, 16, value, "sib_type1_nb_s::nrs_crs_pwr_offset_r13_e_"); +} +const char* sib_type1_nb_s::nrs_crs_pwr_offset_r13_opts::to_number_string() const +{ + static const char* options[] = { + "-6", "-4.77", "-3", "-1.77", "0", "1", "1.23", "2", "3", "4", "4.23", "5", "6", "7", "8", "9"}; + return convert_enum_idx(options, 16, value, "sib_type1_nb_s::nrs_crs_pwr_offset_r13_e_"); +} + +const char* sib_type1_nb_s::si_win_len_r13_opts::to_string() const +{ + static const char* options[] = {"ms160", "ms320", "ms480", "ms640", "ms960", "ms1280", "ms1600", "spare1"}; + return convert_enum_idx(options, 8, value, "sib_type1_nb_s::si_win_len_r13_e_"); +} +uint16_t sib_type1_nb_s::si_win_len_r13_opts::to_number() const +{ + static const uint16_t options[] = {160, 320, 480, 640, 960, 1280, 1600}; + return map_enum_number(options, 7, value, "sib_type1_nb_s::si_win_len_r13_e_"); +} + +// BCCH-DL-SCH-MessageType-NB ::= CHOICE +void bcch_dl_sch_msg_type_nb_c::set(types::options e) +{ + type_ = e; +} +bcch_dl_sch_msg_type_nb_c::c1_c_& bcch_dl_sch_msg_type_nb_c::set_c1() +{ + set(types::c1); + return c; +} +void bcch_dl_sch_msg_type_nb_c::set_msg_class_ext() +{ + set(types::msg_class_ext); +} +void bcch_dl_sch_msg_type_nb_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::c1: + j.write_fieldname("c1"); + c.to_json(j); + break; + case types::msg_class_ext: + break; + default: + log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c"); + } + j.end_obj(); +} +SRSASN_CODE bcch_dl_sch_msg_type_nb_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::c1: + HANDLE_CODE(c.pack(bref)); + break; + case types::msg_class_ext: + break; + default: + log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE bcch_dl_sch_msg_type_nb_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::c1: + HANDLE_CODE(c.unpack(bref)); + break; + case types::msg_class_ext: + break; + default: + log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +void bcch_dl_sch_msg_type_nb_c::c1_c_::destroy_() +{ + switch (type_) { + case types::sys_info_r13: + c.destroy(); + break; + case types::sib_type1_r13: + c.destroy(); + break; + default: + break; + } +} +void bcch_dl_sch_msg_type_nb_c::c1_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::sys_info_r13: + c.init(); + break; + case types::sib_type1_r13: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); + } +} +bcch_dl_sch_msg_type_nb_c::c1_c_::c1_c_(const bcch_dl_sch_msg_type_nb_c::c1_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::sys_info_r13: + c.init(other.c.get()); + break; + case types::sib_type1_r13: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); + } +} +bcch_dl_sch_msg_type_nb_c::c1_c_& +bcch_dl_sch_msg_type_nb_c::c1_c_::operator=(const bcch_dl_sch_msg_type_nb_c::c1_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::sys_info_r13: + c.set(other.c.get()); + break; + case types::sib_type1_r13: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); + } + + return *this; +} +sys_info_nb_s& bcch_dl_sch_msg_type_nb_c::c1_c_::set_sys_info_r13() +{ + set(types::sys_info_r13); + return c.get(); +} +sib_type1_nb_s& bcch_dl_sch_msg_type_nb_c::c1_c_::set_sib_type1_r13() +{ + set(types::sib_type1_r13); + return c.get(); +} +void bcch_dl_sch_msg_type_nb_c::c1_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::sys_info_r13: + j.write_fieldname("systemInformation-r13"); + c.get().to_json(j); + break; + case types::sib_type1_r13: + j.write_fieldname("systemInformationBlockType1-r13"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); + } + j.end_obj(); +} +SRSASN_CODE bcch_dl_sch_msg_type_nb_c::c1_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::sys_info_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::sib_type1_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE bcch_dl_sch_msg_type_nb_c::c1_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::sys_info_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::sib_type1_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* bcch_dl_sch_msg_type_nb_c::c1_c_::types_opts::to_string() const +{ + static const char* options[] = {"systemInformation-r13", "systemInformationBlockType1-r13"}; + return convert_enum_idx(options, 2, value, "bcch_dl_sch_msg_type_nb_c::c1_c_::types"); +} +uint8_t bcch_dl_sch_msg_type_nb_c::c1_c_::types_opts::to_number() const +{ + if (value == sib_type1_r13) { + return 1; + } + invalid_enum_number(value, "bcch_dl_sch_msg_type_nb_c::c1_c_::types"); + return 0; +} + +const char* bcch_dl_sch_msg_type_nb_c::types_opts::to_string() const +{ + static const char* options[] = {"c1", "messageClassExtension"}; + return convert_enum_idx(options, 2, value, "bcch_dl_sch_msg_type_nb_c::types"); +} +uint8_t bcch_dl_sch_msg_type_nb_c::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "bcch_dl_sch_msg_type_nb_c::types"); +} + +// BCCH-DL-SCH-Message-NB ::= SEQUENCE +SRSASN_CODE bcch_dl_sch_msg_nb_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(msg.pack(bref)); + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; +} +SRSASN_CODE bcch_dl_sch_msg_nb_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(msg.unpack(bref)); + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void bcch_dl_sch_msg_nb_s::to_json(json_writer& j) const +{ + j.start_array(); + j.start_obj(); + j.start_obj("BCCH-DL-SCH-Message-NB"); + j.write_fieldname("message"); + msg.to_json(j); + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +// RRCEarlyDataComplete-NB-v1700-IEs ::= SEQUENCE +SRSASN_CODE rrc_early_data_complete_nb_v1700_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(cbp_idx_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (cbp_idx_r17_present) { + HANDLE_CODE(pack_integer(bref, cbp_idx_r17, (uint8_t)1u, (uint8_t)2u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_early_data_complete_nb_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(cbp_idx_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (cbp_idx_r17_present) { + HANDLE_CODE(unpack_integer(cbp_idx_r17, bref, (uint8_t)1u, (uint8_t)2u)); + } + + return SRSASN_SUCCESS; +} +void rrc_early_data_complete_nb_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (cbp_idx_r17_present) { + j.write_int("cbp-Index-r17", cbp_idx_r17); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// RRCConnectionReestablishment-NB-v1430-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_nb_v1430_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(dl_nas_mac_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (dl_nas_mac_present) { + HANDLE_CODE(dl_nas_mac.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reest_nb_v1430_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(dl_nas_mac_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (dl_nas_mac_present) { + HANDLE_CODE(dl_nas_mac.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_reest_nb_v1430_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (dl_nas_mac_present) { + j.write_str("dl-NAS-MAC", dl_nas_mac.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// RRCConnectionSetup-NB-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_nb_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ded_info_nas_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (ded_info_nas_r16_present) { + HANDLE_CODE(ded_info_nas_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_setup_nb_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ded_info_nas_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (ded_info_nas_r16_present) { + HANDLE_CODE(ded_info_nas_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_setup_nb_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ded_info_nas_r16_present) { + j.write_str("dedicatedInfoNAS-r16", ded_info_nas_r16.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// RRCEarlyDataComplete-NB-v1590-IEs ::= SEQUENCE +SRSASN_CODE rrc_early_data_complete_nb_v1590_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_early_data_complete_nb_v1590_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_early_data_complete_nb_v1590_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// RedirectedCarrierInfo-NB-v1430 ::= SEQUENCE +SRSASN_CODE redirected_carrier_info_nb_v1430_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(redirected_carrier_offset_ded_r14.pack(bref)); + HANDLE_CODE(t322_r14.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE redirected_carrier_info_nb_v1430_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(redirected_carrier_offset_ded_r14.unpack(bref)); + HANDLE_CODE(t322_r14.unpack(bref)); + + return SRSASN_SUCCESS; +} +void redirected_carrier_info_nb_v1430_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("redirectedCarrierOffsetDedicated-r14", redirected_carrier_offset_ded_r14.to_string()); + j.write_str("t322-r14", t322_r14.to_string()); + j.end_obj(); +} + +const char* redirected_carrier_info_nb_v1430_s::redirected_carrier_offset_ded_r14_opts::to_string() const +{ + static const char* options[] = {"dB1", + "dB2", + "dB3", + "dB4", + "dB5", + "dB6", + "dB8", + "dB10", + "dB12", + "dB14", + "dB16", + "dB18", + "dB20", + "dB22", + "dB24", + "dB26"}; + return convert_enum_idx( + options, 16, value, "redirected_carrier_info_nb_v1430_s::redirected_carrier_offset_ded_r14_e_"); +} +uint8_t redirected_carrier_info_nb_v1430_s::redirected_carrier_offset_ded_r14_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26}; + return map_enum_number( + options, 16, value, "redirected_carrier_info_nb_v1430_s::redirected_carrier_offset_ded_r14_e_"); +} + +const char* redirected_carrier_info_nb_v1430_s::t322_r14_opts::to_string() const +{ + static const char* options[] = {"min5", "min10", "min20", "min30", "min60", "min120", "min180", "spare1"}; + return convert_enum_idx(options, 8, value, "redirected_carrier_info_nb_v1430_s::t322_r14_e_"); +} +uint8_t redirected_carrier_info_nb_v1430_s::t322_r14_opts::to_number() const +{ + static const uint8_t options[] = {5, 10, 20, 30, 60, 120, 180}; + return map_enum_number(options, 7, value, "redirected_carrier_info_nb_v1430_s::t322_r14_e_"); +} + +// RRCConnectionReestablishment-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_nb_r13_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(rr_cfg_ded_r13.pack(bref)); + HANDLE_CODE(pack_integer(bref, next_hop_chaining_count_r13, (uint8_t)0u, (uint8_t)7u)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reest_nb_r13_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(rr_cfg_ded_r13.unpack(bref)); + HANDLE_CODE(unpack_integer(next_hop_chaining_count_r13, bref, (uint8_t)0u, (uint8_t)7u)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_reest_nb_r13_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("radioResourceConfigDedicated-r13"); + rr_cfg_ded_r13.to_json(j); + j.write_int("nextHopChainingCount-r13", next_hop_chaining_count_r13); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// RRCConnectionReject-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_reject_nb_r13_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(rrc_suspend_ind_r13_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(pack_integer(bref, extended_wait_time_r13, (uint16_t)1u, (uint16_t)1800u)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reject_nb_r13_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(rrc_suspend_ind_r13_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(unpack_integer(extended_wait_time_r13, bref, (uint16_t)1u, (uint16_t)1800u)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_reject_nb_r13_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("extendedWaitTime-r13", extended_wait_time_r13); + if (rrc_suspend_ind_r13_present) { + j.write_str("rrc-SuspendIndication-r13", "true"); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// RRCConnectionSetup-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_nb_r13_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(rr_cfg_ded_r13.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_setup_nb_r13_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(rr_cfg_ded_r13.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_setup_nb_r13_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("radioResourceConfigDedicated-r13"); + rr_cfg_ded_r13.to_json(j); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// RRCEarlyDataComplete-NB-r15-IEs ::= SEQUENCE +SRSASN_CODE rrc_early_data_complete_nb_r15_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(ded_info_nas_r15_present, 1)); + HANDLE_CODE(bref.pack(extended_wait_time_r15_present, 1)); + HANDLE_CODE(bref.pack(redirected_carrier_info_r15_present, 1)); + HANDLE_CODE(bref.pack(redirected_carrier_info_ext_r15_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (ded_info_nas_r15_present) { + HANDLE_CODE(ded_info_nas_r15.pack(bref)); + } + if (extended_wait_time_r15_present) { + HANDLE_CODE(pack_integer(bref, extended_wait_time_r15, (uint16_t)1u, (uint16_t)1800u)); + } + if (redirected_carrier_info_r15_present) { + HANDLE_CODE(redirected_carrier_info_r15.pack(bref)); + } + if (redirected_carrier_info_ext_r15_present) { + HANDLE_CODE(redirected_carrier_info_ext_r15.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_early_data_complete_nb_r15_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ded_info_nas_r15_present, 1)); + HANDLE_CODE(bref.unpack(extended_wait_time_r15_present, 1)); + HANDLE_CODE(bref.unpack(redirected_carrier_info_r15_present, 1)); + HANDLE_CODE(bref.unpack(redirected_carrier_info_ext_r15_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (ded_info_nas_r15_present) { + HANDLE_CODE(ded_info_nas_r15.unpack(bref)); + } + if (extended_wait_time_r15_present) { + HANDLE_CODE(unpack_integer(extended_wait_time_r15, bref, (uint16_t)1u, (uint16_t)1800u)); + } + if (redirected_carrier_info_r15_present) { + HANDLE_CODE(redirected_carrier_info_r15.unpack(bref)); + } + if (redirected_carrier_info_ext_r15_present) { + HANDLE_CODE(redirected_carrier_info_ext_r15.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_early_data_complete_nb_r15_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (ded_info_nas_r15_present) { + j.write_str("dedicatedInfoNAS-r15", ded_info_nas_r15.to_string()); + } + if (extended_wait_time_r15_present) { + j.write_int("extendedWaitTime-r15", extended_wait_time_r15); + } + if (redirected_carrier_info_r15_present) { + j.write_fieldname("redirectedCarrierInfo-r15"); + redirected_carrier_info_r15.to_json(j); + } + if (redirected_carrier_info_ext_r15_present) { + j.write_fieldname("redirectedCarrierInfoExt-r15"); + redirected_carrier_info_ext_r15.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// RRCConnectionReestablishment-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_nb_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reest_nb_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void rrc_conn_reest_nb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void rrc_conn_reest_nb_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +rrc_conn_reest_nb_s::crit_exts_c_::c1_c_& rrc_conn_reest_nb_s::crit_exts_c_::set_c1() +{ + set(types::c1); + return c; +} +void rrc_conn_reest_nb_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void rrc_conn_reest_nb_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::c1: + j.write_fieldname("c1"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_conn_reest_nb_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::c1: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reest_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::c1: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +void rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::set(types::options e) +{ + type_ = e; +} +rrc_conn_reest_nb_r13_ies_s& rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_reest_r13() +{ + set(types::rrc_conn_reest_r13); + return c; +} +void rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::set_spare1() +{ + set(types::spare1); +} +void rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::rrc_conn_reest_r13: + j.write_fieldname("rrcConnectionReestablishment-r13"); + c.to_json(j); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_::c1_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::rrc_conn_reest_r13: + HANDLE_CODE(c.pack(bref)); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rrc_conn_reest_r13: + HANDLE_CODE(c.unpack(bref)); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const +{ + static const char* options[] = {"rrcConnectionReestablishment-r13", "spare1"}; + return convert_enum_idx(options, 2, value, "rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::types"); +} + +// RRCConnectionReject-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_reject_nb_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reject_nb_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void rrc_conn_reject_nb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void rrc_conn_reject_nb_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +rrc_conn_reject_nb_s::crit_exts_c_::c1_c_& rrc_conn_reject_nb_s::crit_exts_c_::set_c1() +{ + set(types::c1); + return c; +} +void rrc_conn_reject_nb_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void rrc_conn_reject_nb_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::c1: + j.write_fieldname("c1"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_conn_reject_nb_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::c1: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reject_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::c1: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +void rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::set(types::options e) +{ + type_ = e; +} +rrc_conn_reject_nb_r13_ies_s& rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_reject_r13() +{ + set(types::rrc_conn_reject_r13); + return c; +} +void rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::set_spare1() +{ + set(types::spare1); +} +void rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::rrc_conn_reject_r13: + j.write_fieldname("rrcConnectionReject-r13"); + c.to_json(j); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_::c1_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::rrc_conn_reject_r13: + HANDLE_CODE(c.pack(bref)); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rrc_conn_reject_r13: + HANDLE_CODE(c.unpack(bref)); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const +{ + static const char* options[] = {"rrcConnectionReject-r13", "spare1"}; + return convert_enum_idx(options, 2, value, "rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::types"); +} + +// RRCConnectionSetup-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_nb_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_setup_nb_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void rrc_conn_setup_nb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void rrc_conn_setup_nb_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +rrc_conn_setup_nb_s::crit_exts_c_::c1_c_& rrc_conn_setup_nb_s::crit_exts_c_::set_c1() +{ + set(types::c1); + return c; +} +void rrc_conn_setup_nb_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void rrc_conn_setup_nb_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::c1: + j.write_fieldname("c1"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_conn_setup_nb_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::c1: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_setup_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::c1: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +void rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::set(types::options e) +{ + type_ = e; +} +rrc_conn_setup_nb_r13_ies_s& rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_setup_r13() +{ + set(types::rrc_conn_setup_r13); + return c; +} +void rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::set_spare1() +{ + set(types::spare1); +} +void rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::rrc_conn_setup_r13: + j.write_fieldname("rrcConnectionSetup-r13"); + c.to_json(j); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_::c1_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::rrc_conn_setup_r13: + HANDLE_CODE(c.pack(bref)); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rrc_conn_setup_r13: + HANDLE_CODE(c.unpack(bref)); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const +{ + static const char* options[] = {"rrcConnectionSetup-r13", "spare1"}; + return convert_enum_idx(options, 2, value, "rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::types"); +} + +// RRCEarlyDataComplete-NB-r15 ::= SEQUENCE +SRSASN_CODE rrc_early_data_complete_nb_r15_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_early_data_complete_nb_r15_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void rrc_early_data_complete_nb_r15_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void rrc_early_data_complete_nb_r15_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +rrc_early_data_complete_nb_r15_ies_s& rrc_early_data_complete_nb_r15_s::crit_exts_c_::set_rrc_early_data_complete_r15() +{ + set(types::rrc_early_data_complete_r15); + return c; +} +void rrc_early_data_complete_nb_r15_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void rrc_early_data_complete_nb_r15_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::rrc_early_data_complete_r15: + j.write_fieldname("rrcEarlyDataComplete-r15"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_complete_nb_r15_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_early_data_complete_nb_r15_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::rrc_early_data_complete_r15: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_complete_nb_r15_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_early_data_complete_nb_r15_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rrc_early_data_complete_r15: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_complete_nb_r15_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_early_data_complete_nb_r15_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"rrcEarlyDataComplete-r15", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "rrc_early_data_complete_nb_r15_s::crit_exts_c_::types"); +} + +// DL-CCCH-MessageType-NB ::= CHOICE +void dl_ccch_msg_type_nb_c::set(types::options e) +{ + type_ = e; +} +dl_ccch_msg_type_nb_c::c1_c_& dl_ccch_msg_type_nb_c::set_c1() +{ + set(types::c1); + return c; +} +void dl_ccch_msg_type_nb_c::set_msg_class_ext() +{ + set(types::msg_class_ext); +} +void dl_ccch_msg_type_nb_c::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::c1: + j.write_fieldname("c1"); + c.to_json(j); + break; + case types::msg_class_ext: + break; + default: + log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c"); + } + j.end_obj(); +} +SRSASN_CODE dl_ccch_msg_type_nb_c::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::c1: + HANDLE_CODE(c.pack(bref)); + break; + case types::msg_class_ext: + break; + default: + log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE dl_ccch_msg_type_nb_c::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::c1: + HANDLE_CODE(c.unpack(bref)); + break; + case types::msg_class_ext: + break; + default: + log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +void dl_ccch_msg_type_nb_c::c1_c_::destroy_() +{ + switch (type_) { + case types::rrc_conn_reest_r13: + c.destroy(); + break; + case types::rrc_conn_reest_reject_r13: + c.destroy(); + break; + case types::rrc_conn_reject_r13: + c.destroy(); + break; + case types::rrc_conn_setup_r13: + c.destroy(); + break; + case types::rrc_early_data_complete_r15: + c.destroy(); + break; + default: + break; + } +} +void dl_ccch_msg_type_nb_c::c1_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::rrc_conn_reest_r13: + c.init(); + break; + case types::rrc_conn_reest_reject_r13: + c.init(); + break; + case types::rrc_conn_reject_r13: + c.init(); + break; + case types::rrc_conn_setup_r13: + c.init(); + break; + case types::rrc_early_data_complete_r15: + c.init(); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); + } +} +dl_ccch_msg_type_nb_c::c1_c_::c1_c_(const dl_ccch_msg_type_nb_c::c1_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::rrc_conn_reest_r13: + c.init(other.c.get()); + break; + case types::rrc_conn_reest_reject_r13: + c.init(other.c.get()); + break; + case types::rrc_conn_reject_r13: + c.init(other.c.get()); + break; + case types::rrc_conn_setup_r13: + c.init(other.c.get()); + break; + case types::rrc_early_data_complete_r15: + c.init(other.c.get()); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); + } +} +dl_ccch_msg_type_nb_c::c1_c_& dl_ccch_msg_type_nb_c::c1_c_::operator=(const dl_ccch_msg_type_nb_c::c1_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::rrc_conn_reest_r13: + c.set(other.c.get()); + break; + case types::rrc_conn_reest_reject_r13: + c.set(other.c.get()); + break; + case types::rrc_conn_reject_r13: + c.set(other.c.get()); + break; + case types::rrc_conn_setup_r13: + c.set(other.c.get()); + break; + case types::rrc_early_data_complete_r15: + c.set(other.c.get()); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); + } + + return *this; +} +rrc_conn_reest_nb_s& dl_ccch_msg_type_nb_c::c1_c_::set_rrc_conn_reest_r13() +{ + set(types::rrc_conn_reest_r13); + return c.get(); +} +rrc_conn_reest_reject_s& dl_ccch_msg_type_nb_c::c1_c_::set_rrc_conn_reest_reject_r13() +{ + set(types::rrc_conn_reest_reject_r13); + return c.get(); +} +rrc_conn_reject_nb_s& dl_ccch_msg_type_nb_c::c1_c_::set_rrc_conn_reject_r13() +{ + set(types::rrc_conn_reject_r13); + return c.get(); +} +rrc_conn_setup_nb_s& dl_ccch_msg_type_nb_c::c1_c_::set_rrc_conn_setup_r13() +{ + set(types::rrc_conn_setup_r13); + return c.get(); +} +rrc_early_data_complete_nb_r15_s& dl_ccch_msg_type_nb_c::c1_c_::set_rrc_early_data_complete_r15() +{ + set(types::rrc_early_data_complete_r15); + return c.get(); +} +void dl_ccch_msg_type_nb_c::c1_c_::set_spare3() +{ + set(types::spare3); +} +void dl_ccch_msg_type_nb_c::c1_c_::set_spare2() +{ + set(types::spare2); +} +void dl_ccch_msg_type_nb_c::c1_c_::set_spare1() +{ + set(types::spare1); +} +void dl_ccch_msg_type_nb_c::c1_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::rrc_conn_reest_r13: + j.write_fieldname("rrcConnectionReestablishment-r13"); + c.get().to_json(j); + break; + case types::rrc_conn_reest_reject_r13: + j.write_fieldname("rrcConnectionReestablishmentReject-r13"); + c.get().to_json(j); + break; + case types::rrc_conn_reject_r13: + j.write_fieldname("rrcConnectionReject-r13"); + c.get().to_json(j); + break; + case types::rrc_conn_setup_r13: + j.write_fieldname("rrcConnectionSetup-r13"); + c.get().to_json(j); + break; + case types::rrc_early_data_complete_r15: + j.write_fieldname("rrcEarlyDataComplete-r15"); + c.get().to_json(j); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); + } + j.end_obj(); +} +SRSASN_CODE dl_ccch_msg_type_nb_c::c1_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::rrc_conn_reest_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::rrc_conn_reest_reject_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::rrc_conn_reject_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::rrc_conn_setup_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::rrc_early_data_complete_r15: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); + return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -void sib_type4_nb_r13_s::to_json(json_writer& j) const +SRSASN_CODE dl_ccch_msg_type_nb_c::c1_c_::unpack(cbit_ref& bref) { - j.start_obj(); - if (intra_freq_neigh_cell_list_r13_present) { - j.start_array("intraFreqNeighCellList-r13"); - for (const auto& e1 : intra_freq_neigh_cell_list_r13) { - e1.to_json(j); - } - j.end_array(); - } - if (intra_freq_black_cell_list_r13_present) { - j.start_array("intraFreqBlackCellList-r13"); - for (const auto& e1 : intra_freq_black_cell_list_r13) { - e1.to_json(j); - } - j.end_array(); - } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (ext) { - if (nsss_rrm_cfg_r15.is_present()) { - j.write_fieldname("nsss-RRM-Config-r15"); - nsss_rrm_cfg_r15->to_json(j); - } - if (intra_freq_neigh_cell_list_v1530.is_present()) { - j.start_array("intraFreqNeighCellList-v1530"); - for (const auto& e1 : *intra_freq_neigh_cell_list_v1530) { - e1.to_json(j); - } - j.end_array(); - } + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rrc_conn_reest_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::rrc_conn_reest_reject_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::rrc_conn_reject_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::rrc_conn_setup_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::rrc_early_data_complete_r15: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::spare3: + break; + case types::spare2: + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); + return SRSASN_ERROR_DECODE_FAIL; } - j.end_obj(); + return SRSASN_SUCCESS; } -// SystemInformationBlockType5-NB-r13 ::= SEQUENCE -SRSASN_CODE sib_type5_nb_r13_s::pack(bit_ref& bref) const +const char* dl_ccch_msg_type_nb_c::c1_c_::types_opts::to_string() const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + static const char* options[] = {"rrcConnectionReestablishment-r13", + "rrcConnectionReestablishmentReject-r13", + "rrcConnectionReject-r13", + "rrcConnectionSetup-r13", + "rrcEarlyDataComplete-r15", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 8, value, "dl_ccch_msg_type_nb_c::c1_c_::types"); +} - HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_carrier_freq_list_r13, 1, 8)); - HANDLE_CODE(t_resel_r13.pack(bref)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); - } +const char* dl_ccch_msg_type_nb_c::types_opts::to_string() const +{ + static const char* options[] = {"c1", "messageClassExtension"}; + return convert_enum_idx(options, 2, value, "dl_ccch_msg_type_nb_c::types"); +} +uint8_t dl_ccch_msg_type_nb_c::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "dl_ccch_msg_type_nb_c::types"); +} - if (ext) { - ext_groups_packer_guard group_flags; - group_flags[0] |= scptm_freq_offset_r14_present; - group_flags.pack(bref); +// DL-CCCH-Message-NB ::= SEQUENCE +SRSASN_CODE dl_ccch_msg_nb_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(msg.pack(bref)); - if (group_flags[0]) { - varlength_field_pack_guard varlen_scope(bref, false); + bref.align_bytes_zero(); - HANDLE_CODE(bref.pack(scptm_freq_offset_r14_present, 1)); - if (scptm_freq_offset_r14_present) { - HANDLE_CODE(pack_integer(bref, scptm_freq_offset_r14, (uint8_t)1u, (uint8_t)8u)); - } - } - } return SRSASN_SUCCESS; } -SRSASN_CODE sib_type5_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE dl_ccch_msg_nb_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - - HANDLE_CODE(unpack_dyn_seq_of(inter_freq_carrier_freq_list_r13, bref, 1, 8)); - HANDLE_CODE(t_resel_r13.unpack(bref)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); - } - - if (ext) { - ext_groups_unpacker_guard group_flags(1); - group_flags.unpack(bref); + HANDLE_CODE(msg.unpack(bref)); - if (group_flags[0]) { - varlength_field_unpack_guard varlen_scope(bref, false); + bref.align_bytes(); - HANDLE_CODE(bref.unpack(scptm_freq_offset_r14_present, 1)); - if (scptm_freq_offset_r14_present) { - HANDLE_CODE(unpack_integer(scptm_freq_offset_r14, bref, (uint8_t)1u, (uint8_t)8u)); - } - } - } return SRSASN_SUCCESS; } -void sib_type5_nb_r13_s::to_json(json_writer& j) const +void dl_ccch_msg_nb_s::to_json(json_writer& j) const { + j.start_array(); j.start_obj(); - j.start_array("interFreqCarrierFreqList-r13"); - for (const auto& e1 : inter_freq_carrier_freq_list_r13) { - e1.to_json(j); - } - j.end_array(); - j.write_str("t-Reselection-r13", t_resel_r13.to_string()); - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (ext) { - if (scptm_freq_offset_r14_present) { - j.write_int("scptm-FreqOffset-r14", scptm_freq_offset_r14); - } - } + j.start_obj("DL-CCCH-Message-NB"); + j.write_fieldname("message"); + msg.to_json(j); + j.end_obj(); j.end_obj(); + j.end_array(); } -// SystemInformation-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE sys_info_nb_r13_ies_s::pack(bit_ref& bref) const +// NRSRP-ChangeThresh-NB-r16 ::= ENUMERATED +const char* nrsrp_change_thresh_nb_r16_opts::to_string() const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + static const char* options[] = {"dB4", + "dB6", + "dB8", + "dB10", + "dB14", + "dB18", + "dB22", + "dB26", + "dB30", + "dB34", + "spare6", + "spare5", + "spare4", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 16, value, "nrsrp_change_thresh_nb_r16_e"); +} +uint8_t nrsrp_change_thresh_nb_r16_opts::to_number() const +{ + static const uint8_t options[] = {4, 6, 8, 10, 14, 18, 22, 26, 30, 34}; + return map_enum_number(options, 10, value, "nrsrp_change_thresh_nb_r16_e"); +} - HANDLE_CODE(pack_dyn_seq_of(bref, sib_type_and_info_r13, 1, 32)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); +// PUR-NRSRP-ChangeThreshold-NB-r16 ::= SEQUENCE +SRSASN_CODE pur_nrsrp_change_thres_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(decrease_thresh_r16_present, 1)); + + HANDLE_CODE(increase_thresh_r16.pack(bref)); + if (decrease_thresh_r16_present) { + HANDLE_CODE(decrease_thresh_r16.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE sys_info_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE pur_nrsrp_change_thres_nb_r16_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(decrease_thresh_r16_present, 1)); - HANDLE_CODE(unpack_dyn_seq_of(sib_type_and_info_r13, bref, 1, 32)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + HANDLE_CODE(increase_thresh_r16.unpack(bref)); + if (decrease_thresh_r16_present) { + HANDLE_CODE(decrease_thresh_r16.unpack(bref)); } return SRSASN_SUCCESS; } -void sys_info_nb_r13_ies_s::to_json(json_writer& j) const +void pur_nrsrp_change_thres_nb_r16_s::to_json(json_writer& j) const { j.start_obj(); - j.start_array("sib-TypeAndInfo-r13"); - for (const auto& e1 : sib_type_and_info_r13) { - e1.to_json(j); - } - j.end_array(); - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + j.write_str("increaseThresh-r16", increase_thresh_r16.to_string()); + if (decrease_thresh_r16_present) { + j.write_str("decreaseThresh-r16", decrease_thresh_r16.to_string()); } j.end_obj(); } -void sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::destroy_() +// PUR-PeriodicityAndOffset-NB-r16 ::= CHOICE +void pur_periodicity_and_offset_nb_r16_c::destroy_() {} +void pur_periodicity_and_offset_nb_r16_c::set(types::options e) +{ + destroy_(); + type_ = e; +} +pur_periodicity_and_offset_nb_r16_c::pur_periodicity_and_offset_nb_r16_c( + const pur_periodicity_and_offset_nb_r16_c& other) { + type_ = other.type(); switch (type_) { - case types::sib2_r13: - c.destroy(); + case types::periodicity8: + c.init(other.c.get()); + break; + case types::periodicity16: + c.init(other.c.get()); + break; + case types::periodicity32: + c.init(other.c.get()); + break; + case types::periodicity64: + c.init(other.c.get()); + break; + case types::periodicity128: + c.init(other.c.get()); + break; + case types::periodicity256: + c.init(other.c.get()); + break; + case types::periodicity512: + c.init(other.c.get()); + break; + case types::periodicity1024: + c.init(other.c.get()); + break; + case types::periodicity2048: + c.init(other.c.get()); + break; + case types::periodicity4096: + c.init(other.c.get()); + break; + case types::periodicity8192: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pur_periodicity_and_offset_nb_r16_c"); + } +} +pur_periodicity_and_offset_nb_r16_c& +pur_periodicity_and_offset_nb_r16_c::operator=(const pur_periodicity_and_offset_nb_r16_c& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::periodicity8: + c.set(other.c.get()); + break; + case types::periodicity16: + c.set(other.c.get()); + break; + case types::periodicity32: + c.set(other.c.get()); break; - case types::sib3_r13: - c.destroy(); + case types::periodicity64: + c.set(other.c.get()); break; - case types::sib4_r13: - c.destroy(); + case types::periodicity128: + c.set(other.c.get()); break; - case types::sib5_r13: - c.destroy(); + case types::periodicity256: + c.set(other.c.get()); break; - case types::sib14_r13: - c.destroy(); + case types::periodicity512: + c.set(other.c.get()); break; - case types::sib16_r13: - c.destroy(); + case types::periodicity1024: + c.set(other.c.get()); break; - case types::sib15_v1430: - c.destroy(); + case types::periodicity2048: + c.set(other.c.get()); break; - case types::sib20_v1430: - c.destroy(); + case types::periodicity4096: + c.set(other.c.get()); break; - case types::sib22_v1430: - c.destroy(); + case types::periodicity8192: + c.set(other.c.get()); break; - case types::sib23_v1530: - c.destroy(); + case types::nulltype: break; default: - break; + log_invalid_choice_id(type_, "pur_periodicity_and_offset_nb_r16_c"); } + + return *this; } -void sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set(types::options e) +uint8_t& pur_periodicity_and_offset_nb_r16_c::set_periodicity8() { - destroy_(); - type_ = e; + set(types::periodicity8); + return c.get(); +} +uint8_t& pur_periodicity_and_offset_nb_r16_c::set_periodicity16() +{ + set(types::periodicity16); + return c.get(); +} +uint8_t& pur_periodicity_and_offset_nb_r16_c::set_periodicity32() +{ + set(types::periodicity32); + return c.get(); +} +uint8_t& pur_periodicity_and_offset_nb_r16_c::set_periodicity64() +{ + set(types::periodicity64); + return c.get(); +} +uint8_t& pur_periodicity_and_offset_nb_r16_c::set_periodicity128() +{ + set(types::periodicity128); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_nb_r16_c::set_periodicity256() +{ + set(types::periodicity256); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_nb_r16_c::set_periodicity512() +{ + set(types::periodicity512); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_nb_r16_c::set_periodicity1024() +{ + set(types::periodicity1024); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_nb_r16_c::set_periodicity2048() +{ + set(types::periodicity2048); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_nb_r16_c::set_periodicity4096() +{ + set(types::periodicity4096); + return c.get(); +} +uint16_t& pur_periodicity_and_offset_nb_r16_c::set_periodicity8192() +{ + set(types::periodicity8192); + return c.get(); +} +void pur_periodicity_and_offset_nb_r16_c::to_json(json_writer& j) const +{ + j.start_obj(); switch (type_) { - case types::sib2_r13: - c.init(); + case types::periodicity8: + j.write_int("periodicity8", c.get()); break; - case types::sib3_r13: - c.init(); + case types::periodicity16: + j.write_int("periodicity16", c.get()); break; - case types::sib4_r13: - c.init(); + case types::periodicity32: + j.write_int("periodicity32", c.get()); break; - case types::sib5_r13: - c.init(); + case types::periodicity64: + j.write_int("periodicity64", c.get()); break; - case types::sib14_r13: - c.init(); + case types::periodicity128: + j.write_int("periodicity128", c.get()); break; - case types::sib16_r13: - c.init(); + case types::periodicity256: + j.write_int("periodicity256", c.get()); break; - case types::sib15_v1430: - c.init(); + case types::periodicity512: + j.write_int("periodicity512", c.get()); break; - case types::sib20_v1430: - c.init(); + case types::periodicity1024: + j.write_int("periodicity1024", c.get()); break; - case types::sib22_v1430: - c.init(); + case types::periodicity2048: + j.write_int("periodicity2048", c.get()); break; - case types::sib23_v1530: - c.init(); + case types::periodicity4096: + j.write_int("periodicity4096", c.get()); break; - case types::nulltype: + case types::periodicity8192: + j.write_int("periodicity8192", c.get()); break; default: - log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + log_invalid_choice_id(type_, "pur_periodicity_and_offset_nb_r16_c"); } + j.end_obj(); } -sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::sib_type_and_info_r13_item_c_( - const sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_& other) +SRSASN_CODE pur_periodicity_and_offset_nb_r16_c::pack(bit_ref& bref) const { - type_ = other.type(); + type_.pack(bref); switch (type_) { - case types::sib2_r13: - c.init(other.c.get()); + case types::periodicity8: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)1u, (uint8_t)7u)); break; - case types::sib3_r13: - c.init(other.c.get()); + case types::periodicity16: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)1u, (uint8_t)15u)); break; - case types::sib4_r13: - c.init(other.c.get()); + case types::periodicity32: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)1u, (uint8_t)31u)); break; - case types::sib5_r13: - c.init(other.c.get()); + case types::periodicity64: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)1u, (uint8_t)63u)); break; - case types::sib14_r13: - c.init(other.c.get()); + case types::periodicity128: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)1u, (uint8_t)127u)); break; - case types::sib16_r13: - c.init(other.c.get()); + case types::periodicity256: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)257u)); break; - case types::sib15_v1430: - c.init(other.c.get()); + case types::periodicity512: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)511u)); break; - case types::sib20_v1430: - c.init(other.c.get()); + case types::periodicity1024: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)1023u)); break; - case types::sib22_v1430: - c.init(other.c.get()); + case types::periodicity2048: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)2047u)); break; - case types::sib23_v1530: - c.init(other.c.get()); + case types::periodicity4096: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)4095u)); break; - case types::nulltype: + case types::periodicity8192: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)1u, (uint16_t)8191u)); break; default: - log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + log_invalid_choice_id(type_, "pur_periodicity_and_offset_nb_r16_c"); + return SRSASN_ERROR_ENCODE_FAIL; } + return SRSASN_SUCCESS; } -sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::operator=( - const sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_& other) +SRSASN_CODE pur_periodicity_and_offset_nb_r16_c::unpack(cbit_ref& bref) { - if (this == &other) { - return *this; - } - set(other.type()); + types e; + e.unpack(bref); + set(e); switch (type_) { - case types::sib2_r13: - c.set(other.c.get()); + case types::periodicity8: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)1u, (uint8_t)7u)); break; - case types::sib3_r13: - c.set(other.c.get()); + case types::periodicity16: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)1u, (uint8_t)15u)); break; - case types::sib4_r13: - c.set(other.c.get()); + case types::periodicity32: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)1u, (uint8_t)31u)); break; - case types::sib5_r13: - c.set(other.c.get()); + case types::periodicity64: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)1u, (uint8_t)63u)); break; - case types::sib14_r13: - c.set(other.c.get()); + case types::periodicity128: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)1u, (uint8_t)127u)); break; - case types::sib16_r13: - c.set(other.c.get()); + case types::periodicity256: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)257u)); break; - case types::sib15_v1430: - c.set(other.c.get()); + case types::periodicity512: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)511u)); break; - case types::sib20_v1430: - c.set(other.c.get()); + case types::periodicity1024: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)1023u)); break; - case types::sib22_v1430: - c.set(other.c.get()); + case types::periodicity2048: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)2047u)); break; - case types::sib23_v1530: - c.set(other.c.get()); + case types::periodicity4096: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)4095u)); break; - case types::nulltype: + case types::periodicity8192: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)1u, (uint16_t)8191u)); break; default: - log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + log_invalid_choice_id(type_, "pur_periodicity_and_offset_nb_r16_c"); + return SRSASN_ERROR_DECODE_FAIL; } + return SRSASN_SUCCESS; +} - return *this; +const char* pur_periodicity_and_offset_nb_r16_c::types_opts::to_string() const +{ + static const char* options[] = {"periodicity8", + "periodicity16", + "periodicity32", + "periodicity64", + "periodicity128", + "periodicity256", + "periodicity512", + "periodicity1024", + "periodicity2048", + "periodicity4096", + "periodicity8192"}; + return convert_enum_idx(options, 11, value, "pur_periodicity_and_offset_nb_r16_c::types"); } -sib_type2_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib2_r13() +uint16_t pur_periodicity_and_offset_nb_r16_c::types_opts::to_number() const { - set(types::sib2_r13); - return c.get(); + static const uint16_t options[] = {8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192}; + return map_enum_number(options, 11, value, "pur_periodicity_and_offset_nb_r16_c::types"); } -sib_type3_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib3_r13() + +// PUR-UL-16QAM-Config-NB-r17 ::= SEQUENCE +SRSASN_CODE pur_ul_minus16_qam_cfg_nb_r17_s::pack(bit_ref& bref) const { - set(types::sib3_r13); - return c.get(); + HANDLE_CODE(ul_pwr_ctrl_ded_r17.pack(bref)); + + return SRSASN_SUCCESS; } -sib_type4_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib4_r13() +SRSASN_CODE pur_ul_minus16_qam_cfg_nb_r17_s::unpack(cbit_ref& bref) { - set(types::sib4_r13); - return c.get(); + HANDLE_CODE(ul_pwr_ctrl_ded_r17.unpack(bref)); + + return SRSASN_SUCCESS; } -sib_type5_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib5_r13() +void pur_ul_minus16_qam_cfg_nb_r17_s::to_json(json_writer& j) const { - set(types::sib5_r13); - return c.get(); + j.start_obj(); + j.write_fieldname("uplinkPowerControlDedicated-r17"); + ul_pwr_ctrl_ded_r17.to_json(j); + j.end_obj(); } -sib_type14_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib14_r13() + +// PUR-Config-NB-r16 ::= SEQUENCE +SRSASN_CODE pur_cfg_nb_r16_s::pack(bit_ref& bref) const { - set(types::sib14_r13); - return c.get(); + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(pur_cfg_id_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_time_align_timer_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_nrsrp_change_thres_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_implicit_release_after_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_rnti_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_resp_win_timer_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_start_time_params_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_phys_cfg_r16_present, 1)); + + if (pur_cfg_id_r16_present) { + HANDLE_CODE(pur_cfg_id_r16.pack(bref)); + } + if (pur_time_align_timer_r16_present) { + HANDLE_CODE(pack_integer(bref, pur_time_align_timer_r16, (uint8_t)1u, (uint8_t)8u)); + } + if (pur_nrsrp_change_thres_r16_present) { + HANDLE_CODE(pur_nrsrp_change_thres_r16.pack(bref)); + } + if (pur_implicit_release_after_r16_present) { + HANDLE_CODE(pur_implicit_release_after_r16.pack(bref)); + } + if (pur_rnti_r16_present) { + HANDLE_CODE(pur_rnti_r16.pack(bref)); + } + if (pur_resp_win_timer_r16_present) { + HANDLE_CODE(pur_resp_win_timer_r16.pack(bref)); + } + if (pur_start_time_params_r16_present) { + HANDLE_CODE(pur_start_time_params_r16.periodicity_and_offset_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, pur_start_time_params_r16.start_sfn_r16, (uint16_t)0u, (uint16_t)1023u)); + HANDLE_CODE(pack_integer(bref, pur_start_time_params_r16.start_sf_r16, (uint8_t)0u, (uint8_t)9u)); + HANDLE_CODE(pur_start_time_params_r16.hsfn_lsb_info_r16.pack(bref)); + } + HANDLE_CODE(pur_num_occasions_r16.pack(bref)); + if (pur_phys_cfg_r16_present) { + HANDLE_CODE(pur_phys_cfg_r16.carrier_cfg_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, pur_phys_cfg_r16.npusch_num_rus_idx_r16, (uint8_t)0u, (uint8_t)7u)); + HANDLE_CODE(pack_integer(bref, pur_phys_cfg_r16.npusch_num_repeats_idx_r16, (uint8_t)0u, (uint8_t)7u)); + HANDLE_CODE(pur_phys_cfg_r16.npusch_sub_carrier_set_idx_r16.pack(bref)); + HANDLE_CODE(pur_phys_cfg_r16.npusch_mcs_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, pur_phys_cfg_r16.p0_ue_npusch_r16, (int8_t)-8, (int8_t)7)); + HANDLE_CODE(pur_phys_cfg_r16.alpha_r16.pack(bref)); + HANDLE_CODE(pur_phys_cfg_r16.npusch_cyclic_shift_r16.pack(bref)); + HANDLE_CODE(pur_phys_cfg_r16.npdcch_cfg_r16.pack(bref)); + } + + if (ext) { + ext_groups_packer_guard group_flags; + group_flags[0] |= pur_phys_cfg_v1650.is_present(); + group_flags[1] |= pur_phys_cfg_v1700.is_present(); + group_flags.pack(bref); + + if (group_flags[0]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(pur_phys_cfg_v1650.is_present(), 1)); + if (pur_phys_cfg_v1650.is_present()) { + HANDLE_CODE(pur_phys_cfg_v1650->ack_nack_num_repeats_r16.pack(bref)); + } + } + if (group_flags[1]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(pur_phys_cfg_v1700.is_present(), 1)); + if (pur_phys_cfg_v1700.is_present()) { + HANDLE_CODE(bref.pack(pur_phys_cfg_v1700->pur_ul_minus16_qam_cfg_r17_present, 1)); + HANDLE_CODE(bref.pack(pur_phys_cfg_v1700->pur_dl_minus16_qam_cfg_r17_present, 1)); + if (pur_phys_cfg_v1700->pur_ul_minus16_qam_cfg_r17_present) { + HANDLE_CODE(pur_phys_cfg_v1700->pur_ul_minus16_qam_cfg_r17.pack(bref)); + } + if (pur_phys_cfg_v1700->pur_dl_minus16_qam_cfg_r17_present) { + HANDLE_CODE(pur_phys_cfg_v1700->pur_dl_minus16_qam_cfg_r17.pack(bref)); + } + } + } + } + return SRSASN_SUCCESS; } -sib_type16_nb_r13_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib16_r13() +SRSASN_CODE pur_cfg_nb_r16_s::unpack(cbit_ref& bref) { - set(types::sib16_r13); - return c.get(); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(pur_cfg_id_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_time_align_timer_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_nrsrp_change_thres_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_implicit_release_after_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_rnti_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_resp_win_timer_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_start_time_params_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_phys_cfg_r16_present, 1)); + + if (pur_cfg_id_r16_present) { + HANDLE_CODE(pur_cfg_id_r16.unpack(bref)); + } + if (pur_time_align_timer_r16_present) { + HANDLE_CODE(unpack_integer(pur_time_align_timer_r16, bref, (uint8_t)1u, (uint8_t)8u)); + } + if (pur_nrsrp_change_thres_r16_present) { + HANDLE_CODE(pur_nrsrp_change_thres_r16.unpack(bref)); + } + if (pur_implicit_release_after_r16_present) { + HANDLE_CODE(pur_implicit_release_after_r16.unpack(bref)); + } + if (pur_rnti_r16_present) { + HANDLE_CODE(pur_rnti_r16.unpack(bref)); + } + if (pur_resp_win_timer_r16_present) { + HANDLE_CODE(pur_resp_win_timer_r16.unpack(bref)); + } + if (pur_start_time_params_r16_present) { + HANDLE_CODE(pur_start_time_params_r16.periodicity_and_offset_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(pur_start_time_params_r16.start_sfn_r16, bref, (uint16_t)0u, (uint16_t)1023u)); + HANDLE_CODE(unpack_integer(pur_start_time_params_r16.start_sf_r16, bref, (uint8_t)0u, (uint8_t)9u)); + HANDLE_CODE(pur_start_time_params_r16.hsfn_lsb_info_r16.unpack(bref)); + } + HANDLE_CODE(pur_num_occasions_r16.unpack(bref)); + if (pur_phys_cfg_r16_present) { + HANDLE_CODE(pur_phys_cfg_r16.carrier_cfg_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(pur_phys_cfg_r16.npusch_num_rus_idx_r16, bref, (uint8_t)0u, (uint8_t)7u)); + HANDLE_CODE(unpack_integer(pur_phys_cfg_r16.npusch_num_repeats_idx_r16, bref, (uint8_t)0u, (uint8_t)7u)); + HANDLE_CODE(pur_phys_cfg_r16.npusch_sub_carrier_set_idx_r16.unpack(bref)); + HANDLE_CODE(pur_phys_cfg_r16.npusch_mcs_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(pur_phys_cfg_r16.p0_ue_npusch_r16, bref, (int8_t)-8, (int8_t)7)); + HANDLE_CODE(pur_phys_cfg_r16.alpha_r16.unpack(bref)); + HANDLE_CODE(pur_phys_cfg_r16.npusch_cyclic_shift_r16.unpack(bref)); + HANDLE_CODE(pur_phys_cfg_r16.npdcch_cfg_r16.unpack(bref)); + } + + if (ext) { + ext_groups_unpacker_guard group_flags(2); + group_flags.unpack(bref); + + if (group_flags[0]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool pur_phys_cfg_v1650_present; + HANDLE_CODE(bref.unpack(pur_phys_cfg_v1650_present, 1)); + pur_phys_cfg_v1650.set_present(pur_phys_cfg_v1650_present); + if (pur_phys_cfg_v1650.is_present()) { + HANDLE_CODE(pur_phys_cfg_v1650->ack_nack_num_repeats_r16.unpack(bref)); + } + } + if (group_flags[1]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + bool pur_phys_cfg_v1700_present; + HANDLE_CODE(bref.unpack(pur_phys_cfg_v1700_present, 1)); + pur_phys_cfg_v1700.set_present(pur_phys_cfg_v1700_present); + if (pur_phys_cfg_v1700.is_present()) { + HANDLE_CODE(bref.unpack(pur_phys_cfg_v1700->pur_ul_minus16_qam_cfg_r17_present, 1)); + HANDLE_CODE(bref.unpack(pur_phys_cfg_v1700->pur_dl_minus16_qam_cfg_r17_present, 1)); + if (pur_phys_cfg_v1700->pur_ul_minus16_qam_cfg_r17_present) { + HANDLE_CODE(pur_phys_cfg_v1700->pur_ul_minus16_qam_cfg_r17.unpack(bref)); + } + if (pur_phys_cfg_v1700->pur_dl_minus16_qam_cfg_r17_present) { + HANDLE_CODE(pur_phys_cfg_v1700->pur_dl_minus16_qam_cfg_r17.unpack(bref)); + } + } + } + } + return SRSASN_SUCCESS; +} +void pur_cfg_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (pur_cfg_id_r16_present) { + j.write_str("pur-ConfigID-r16", pur_cfg_id_r16.to_string()); + } + if (pur_time_align_timer_r16_present) { + j.write_int("pur-TimeAlignmentTimer-r16", pur_time_align_timer_r16); + } + if (pur_nrsrp_change_thres_r16_present) { + j.write_fieldname("pur-NRSRP-ChangeThreshold-r16"); + pur_nrsrp_change_thres_r16.to_json(j); + } + if (pur_implicit_release_after_r16_present) { + j.write_str("pur-ImplicitReleaseAfter-r16", pur_implicit_release_after_r16.to_string()); + } + if (pur_rnti_r16_present) { + j.write_str("pur-RNTI-r16", pur_rnti_r16.to_string()); + } + if (pur_resp_win_timer_r16_present) { + j.write_str("pur-ResponseWindowTimer-r16", pur_resp_win_timer_r16.to_string()); + } + if (pur_start_time_params_r16_present) { + j.write_fieldname("pur-StartTimeParameters-r16"); + j.start_obj(); + j.write_fieldname("periodicityAndOffset-r16"); + pur_start_time_params_r16.periodicity_and_offset_r16.to_json(j); + j.write_int("startSFN-r16", pur_start_time_params_r16.start_sfn_r16); + j.write_int("startSubframe-r16", pur_start_time_params_r16.start_sf_r16); + j.write_str("hsfn-LSB-Info-r16", pur_start_time_params_r16.hsfn_lsb_info_r16.to_string()); + j.end_obj(); + } + j.write_str("pur-NumOccasions-r16", pur_num_occasions_r16.to_string()); + if (pur_phys_cfg_r16_present) { + j.write_fieldname("pur-PhysicalConfig-r16"); + j.start_obj(); + j.write_fieldname("carrierConfig-r16"); + pur_phys_cfg_r16.carrier_cfg_r16.to_json(j); + j.write_int("npusch-NumRUsIndex-r16", pur_phys_cfg_r16.npusch_num_rus_idx_r16); + j.write_int("npusch-NumRepetitionsIndex-r16", pur_phys_cfg_r16.npusch_num_repeats_idx_r16); + j.write_fieldname("npusch-SubCarrierSetIndex-r16"); + pur_phys_cfg_r16.npusch_sub_carrier_set_idx_r16.to_json(j); + j.write_fieldname("npusch-MCS-r16"); + pur_phys_cfg_r16.npusch_mcs_r16.to_json(j); + j.write_int("p0-UE-NPUSCH-r16", pur_phys_cfg_r16.p0_ue_npusch_r16); + j.write_str("alpha-r16", pur_phys_cfg_r16.alpha_r16.to_string()); + j.write_str("npusch-CyclicShift-r16", pur_phys_cfg_r16.npusch_cyclic_shift_r16.to_string()); + j.write_fieldname("npdcch-Config-r16"); + pur_phys_cfg_r16.npdcch_cfg_r16.to_json(j); + j.end_obj(); + } + if (ext) { + if (pur_phys_cfg_v1650.is_present()) { + j.write_fieldname("pur-PhysicalConfig-v1650"); + j.start_obj(); + j.write_str("ack-NACK-NumRepetitions-r16", pur_phys_cfg_v1650->ack_nack_num_repeats_r16.to_string()); + j.end_obj(); + } + if (pur_phys_cfg_v1700.is_present()) { + j.write_fieldname("pur-PhysicalConfig-v1700"); + j.start_obj(); + if (pur_phys_cfg_v1700->pur_ul_minus16_qam_cfg_r17_present) { + j.write_fieldname("pur-UL-16QAM-Config-r17"); + pur_phys_cfg_v1700->pur_ul_minus16_qam_cfg_r17.to_json(j); + } + if (pur_phys_cfg_v1700->pur_dl_minus16_qam_cfg_r17_present) { + j.write_fieldname("pur-DL-16QAM-Config-r17"); + pur_phys_cfg_v1700->pur_dl_minus16_qam_cfg_r17.to_json(j); + } + j.end_obj(); + } + } + j.end_obj(); +} + +const char* pur_cfg_nb_r16_s::pur_implicit_release_after_r16_opts::to_string() const +{ + static const char* options[] = {"n2", "n4", "n8", "spare"}; + return convert_enum_idx(options, 4, value, "pur_cfg_nb_r16_s::pur_implicit_release_after_r16_e_"); +} +uint8_t pur_cfg_nb_r16_s::pur_implicit_release_after_r16_opts::to_number() const +{ + static const uint8_t options[] = {2, 4, 8}; + return map_enum_number(options, 3, value, "pur_cfg_nb_r16_s::pur_implicit_release_after_r16_e_"); +} + +const char* pur_cfg_nb_r16_s::pur_resp_win_timer_r16_opts::to_string() const +{ + static const char* options[] = {"pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32", "pp64"}; + return convert_enum_idx(options, 8, value, "pur_cfg_nb_r16_s::pur_resp_win_timer_r16_e_"); } -sib_type15_nb_r14_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib15_v1430() +uint8_t pur_cfg_nb_r16_s::pur_resp_win_timer_r16_opts::to_number() const { - set(types::sib15_v1430); - return c.get(); + static const uint8_t options[] = {1, 2, 3, 4, 8, 16, 32, 64}; + return map_enum_number(options, 8, value, "pur_cfg_nb_r16_s::pur_resp_win_timer_r16_e_"); } -sib_type20_nb_r14_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib20_v1430() + +const char* pur_cfg_nb_r16_s::pur_num_occasions_r16_opts::to_string() const { - set(types::sib20_v1430); - return c.get(); + static const char* options[] = {"one", "infinite"}; + return convert_enum_idx(options, 2, value, "pur_cfg_nb_r16_s::pur_num_occasions_r16_e_"); } -sib_type22_nb_r14_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib22_v1430() +uint8_t pur_cfg_nb_r16_s::pur_num_occasions_r16_opts::to_number() const { - set(types::sib22_v1430); - return c.get(); + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "pur_cfg_nb_r16_s::pur_num_occasions_r16_e_"); } -sib_type23_nb_r15_s& sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::set_sib23_v1530() + +void pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::destroy_() {} +void pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::set(types::options e) { - set(types::sib23_v1530); - return c.get(); + destroy_(); + type_ = e; } -void sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::to_json(json_writer& j) const +pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::npusch_sub_carrier_set_idx_r16_c_( + const pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_& other) { - j.start_obj(); + type_ = other.type(); switch (type_) { - case types::sib2_r13: - j.write_fieldname("sib2-r13"); - c.get().to_json(j); - break; - case types::sib3_r13: - j.write_fieldname("sib3-r13"); - c.get().to_json(j); - break; - case types::sib4_r13: - j.write_fieldname("sib4-r13"); - c.get().to_json(j); + case types::khz15: + c.init(other.c.get()); break; - case types::sib5_r13: - j.write_fieldname("sib5-r13"); - c.get().to_json(j); + case types::khz3dot75: + c.init(other.c.get()); break; - case types::sib14_r13: - j.write_fieldname("sib14-r13"); - c.get().to_json(j); + case types::nulltype: break; - case types::sib16_r13: - j.write_fieldname("sib16-r13"); - c.get().to_json(j); + default: + log_invalid_choice_id(type_, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_"); + } +} +pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_& +pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::operator=( + const pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::khz15: + c.set(other.c.get()); break; - case types::sib15_v1430: - j.write_fieldname("sib15-v1430"); - c.get().to_json(j); + case types::khz3dot75: + c.set(other.c.get()); break; - case types::sib20_v1430: - j.write_fieldname("sib20-v1430"); - c.get().to_json(j); + case types::nulltype: break; - case types::sib22_v1430: - j.write_fieldname("sib22-v1430"); - c.get().to_json(j); + default: + log_invalid_choice_id(type_, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_"); + } + + return *this; +} +uint8_t& pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::set_khz15() +{ + set(types::khz15); + return c.get(); +} +uint8_t& pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::set_khz3dot75() +{ + set(types::khz3dot75); + return c.get(); +} +void pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::khz15: + j.write_int("khz15", c.get()); break; - case types::sib23_v1530: - j.write_fieldname("sib23-v1530"); - c.get().to_json(j); + case types::khz3dot75: + j.write_int("khz3dot75", c.get()); break; default: - log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + log_invalid_choice_id(type_, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_"); } j.end_obj(); } -SRSASN_CODE sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::pack(bit_ref& bref) const +SRSASN_CODE pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::sib2_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::sib3_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::sib4_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::sib5_r13: - HANDLE_CODE(c.get().pack(bref)); + case types::khz15: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)18u)); break; - case types::sib14_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::sib16_r13: - HANDLE_CODE(c.get().pack(bref)); + case types::khz3dot75: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)47u)); break; - case types::sib15_v1430: { - varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(c.get().pack(bref)); - } break; - case types::sib20_v1430: { - varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(c.get().pack(bref)); - } break; - case types::sib22_v1430: { - varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(c.get().pack(bref)); - } break; - case types::sib23_v1530: { - varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(c.get().pack(bref)); - } break; default: - log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + log_invalid_choice_id(type_, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::unpack(cbit_ref& bref) +SRSASN_CODE pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::sib2_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::sib3_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::sib4_r13: - HANDLE_CODE(c.get().unpack(bref)); + case types::khz15: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)18u)); break; - case types::sib5_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::sib14_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::sib16_r13: - HANDLE_CODE(c.get().unpack(bref)); + case types::khz3dot75: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)47u)); break; - case types::sib15_v1430: { - varlength_field_unpack_guard varlen_scope(bref, false); - HANDLE_CODE(c.get().unpack(bref)); - } break; - case types::sib20_v1430: { - varlength_field_unpack_guard varlen_scope(bref, false); - HANDLE_CODE(c.get().unpack(bref)); - } break; - case types::sib22_v1430: { - varlength_field_unpack_guard varlen_scope(bref, false); - HANDLE_CODE(c.get().unpack(bref)); - } break; - case types::sib23_v1530: { - varlength_field_unpack_guard varlen_scope(bref, false); - HANDLE_CODE(c.get().unpack(bref)); - } break; default: - log_invalid_choice_id(type_, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_"); + log_invalid_choice_id(type_, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::types_opts::to_string() const +const char* pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::types_opts::to_string() const { - static const char* options[] = {"sib2-r13", - "sib3-r13", - "sib4-r13", - "sib5-r13", - "sib14-r13", - "sib16-r13", - "sib15-v1430", - "sib20-v1430", - "sib22-v1430", - "sib23-v1530"}; - return convert_enum_idx(options, 10, value, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::types"); + static const char* options[] = {"khz15", "khz3dot75"}; + return convert_enum_idx( + options, 2, value, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::types"); } -uint8_t sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::types_opts::to_number() const +float pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::types_opts::to_number() const { - static const uint8_t options[] = {2, 3, 4, 5, 14, 16, 15, 20, 22, 23}; - return map_enum_number(options, 10, value, "sys_info_nb_r13_ies_s::sib_type_and_info_r13_item_c_::types"); + static const float options[] = {15.0, 3.75}; + return map_enum_number( + options, 2, value, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::types"); } - -// SystemInformationBlockType1-NB-v1350 ::= SEQUENCE -SRSASN_CODE sib_type1_nb_v1350_s::pack(bit_ref& bref) const +const char* +pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::types_opts::to_number_string() const { - HANDLE_CODE(bref.pack(cell_sel_info_v1350_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - if (cell_sel_info_v1350_present) { - HANDLE_CODE(cell_sel_info_v1350.pack(bref)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); - } + static const char* options[] = {"15", "3.75"}; + return convert_enum_idx( + options, 2, value, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_sub_carrier_set_idx_r16_c_::types"); +} - return SRSASN_SUCCESS; +void pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_::destroy_() {} +void pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_::set(types::options e) +{ + destroy_(); + type_ = e; } -SRSASN_CODE sib_type1_nb_v1350_s::unpack(cbit_ref& bref) +pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_::npusch_mcs_r16_c_( + const pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_& other) { - HANDLE_CODE(bref.unpack(cell_sel_info_v1350_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - if (cell_sel_info_v1350_present) { - HANDLE_CODE(cell_sel_info_v1350.unpack(bref)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); + type_ = other.type(); + switch (type_) { + case types::single_tone: + c.init(other.c.get()); + break; + case types::multi_tone: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_"); } - - return SRSASN_SUCCESS; } -void sib_type1_nb_v1350_s::to_json(json_writer& j) const +pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_& +pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_::operator=( + const pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_& other) { - j.start_obj(); - if (cell_sel_info_v1350_present) { - j.write_fieldname("cellSelectionInfo-v1350"); - cell_sel_info_v1350.to_json(j); + if (this == &other) { + return *this; } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); + set(other.type()); + switch (type_) { + case types::single_tone: + c.set(other.c.get()); + break; + case types::multi_tone: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_"); } - j.end_obj(); -} - -// SystemInformation-NB ::= SEQUENCE -SRSASN_CODE sys_info_nb_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(crit_exts.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE sys_info_nb_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(crit_exts.unpack(bref)); - - return SRSASN_SUCCESS; -} -void sys_info_nb_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("criticalExtensions"); - crit_exts.to_json(j); - j.end_obj(); -} -void sys_info_nb_s::crit_exts_c_::set(types::options e) -{ - type_ = e; + return *this; } -sys_info_nb_r13_ies_s& sys_info_nb_s::crit_exts_c_::set_sys_info_r13() -{ - set(types::sys_info_r13); - return c; +uint8_t& pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_::set_single_tone() +{ + set(types::single_tone); + return c.get(); } -void sys_info_nb_s::crit_exts_c_::set_crit_exts_future() +uint8_t& pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_::set_multi_tone() { - set(types::crit_exts_future); + set(types::multi_tone); + return c.get(); } -void sys_info_nb_s::crit_exts_c_::to_json(json_writer& j) const +void pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::sys_info_r13: - j.write_fieldname("systemInformation-r13"); - c.to_json(j); + case types::single_tone: + j.write_int("singleTone", c.get()); break; - case types::crit_exts_future: + case types::multi_tone: + j.write_int("multiTone", c.get()); break; default: - log_invalid_choice_id(type_, "sys_info_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_"); } j.end_obj(); } -SRSASN_CODE sys_info_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::sys_info_r13: - HANDLE_CODE(c.pack(bref)); + case types::single_tone: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)10u)); break; - case types::crit_exts_future: + case types::multi_tone: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)13u)); break; default: - log_invalid_choice_id(type_, "sys_info_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE sys_info_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::sys_info_r13: - HANDLE_CODE(c.unpack(bref)); + case types::single_tone: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)10u)); break; - case types::crit_exts_future: + case types::multi_tone: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)13u)); break; default: - log_invalid_choice_id(type_, "sys_info_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* sys_info_nb_s::crit_exts_c_::types_opts::to_string() const +const char* pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_::types_opts::to_string() const { - static const char* options[] = {"systemInformation-r13", "criticalExtensionsFuture"}; - return convert_enum_idx(options, 2, value, "sys_info_nb_s::crit_exts_c_::types"); + static const char* options[] = {"singleTone", "multiTone"}; + return convert_enum_idx(options, 2, value, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_mcs_r16_c_::types"); } -// SystemInformationBlockType1-NB ::= SEQUENCE -SRSASN_CODE sib_type1_nb_s::pack(bit_ref& bref) const +const char* pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::alpha_r16_opts::to_string() const { - HANDLE_CODE(bref.pack(p_max_r13_present, 1)); - HANDLE_CODE(bref.pack(freq_band_info_r13_present, 1)); - HANDLE_CODE(bref.pack(multi_band_info_list_r13_present, 1)); - HANDLE_CODE(bref.pack(dl_bitmap_r13_present, 1)); - HANDLE_CODE(bref.pack(eutra_ctrl_region_size_r13_present, 1)); - HANDLE_CODE(bref.pack(nrs_crs_pwr_offset_r13_present, 1)); - HANDLE_CODE(bref.pack(si_radio_frame_offset_r13_present, 1)); - HANDLE_CODE(bref.pack(sys_info_value_tag_list_r13_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - HANDLE_CODE(hyper_sfn_msb_r13.pack(bref)); - HANDLE_CODE(pack_dyn_seq_of(bref, cell_access_related_info_r13.plmn_id_list_r13, 1, 6)); - HANDLE_CODE(cell_access_related_info_r13.tac_r13.pack(bref)); - HANDLE_CODE(cell_access_related_info_r13.cell_id_r13.pack(bref)); - HANDLE_CODE(cell_access_related_info_r13.cell_barred_r13.pack(bref)); - HANDLE_CODE(cell_access_related_info_r13.intra_freq_resel_r13.pack(bref)); - HANDLE_CODE(pack_integer(bref, cell_sel_info_r13.q_rx_lev_min_r13, (int8_t)-70, (int8_t)-22)); - HANDLE_CODE(pack_integer(bref, cell_sel_info_r13.q_qual_min_r13, (int8_t)-34, (int8_t)-3)); - if (p_max_r13_present) { - HANDLE_CODE(pack_integer(bref, p_max_r13, (int8_t)-30, (int8_t)33)); - } - HANDLE_CODE(pack_integer(bref, freq_band_ind_r13, (uint16_t)1u, (uint16_t)256u)); - if (freq_band_info_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_info_r13, 1, 4)); - } - if (multi_band_info_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, multi_band_info_list_r13, 1, 8)); - } - if (dl_bitmap_r13_present) { - HANDLE_CODE(dl_bitmap_r13.pack(bref)); - } - if (eutra_ctrl_region_size_r13_present) { - HANDLE_CODE(eutra_ctrl_region_size_r13.pack(bref)); - } - if (nrs_crs_pwr_offset_r13_present) { - HANDLE_CODE(nrs_crs_pwr_offset_r13.pack(bref)); - } - HANDLE_CODE(pack_dyn_seq_of(bref, sched_info_list_r13, 1, 8)); - HANDLE_CODE(si_win_len_r13.pack(bref)); - if (si_radio_frame_offset_r13_present) { - HANDLE_CODE(pack_integer(bref, si_radio_frame_offset_r13, (uint8_t)1u, (uint8_t)15u)); - } - if (sys_info_value_tag_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, sys_info_value_tag_list_r13, 1, 8, integer_packer(0, 3))); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); - } - - return SRSASN_SUCCESS; + static const char* options[] = {"al0", "al04", "al05", "al06", "al07", "al08", "al09", "al1"}; + return convert_enum_idx(options, 8, value, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::alpha_r16_e_"); } -SRSASN_CODE sib_type1_nb_s::unpack(cbit_ref& bref) +float pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::alpha_r16_opts::to_number() const { - HANDLE_CODE(bref.unpack(p_max_r13_present, 1)); - HANDLE_CODE(bref.unpack(freq_band_info_r13_present, 1)); - HANDLE_CODE(bref.unpack(multi_band_info_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(dl_bitmap_r13_present, 1)); - HANDLE_CODE(bref.unpack(eutra_ctrl_region_size_r13_present, 1)); - HANDLE_CODE(bref.unpack(nrs_crs_pwr_offset_r13_present, 1)); - HANDLE_CODE(bref.unpack(si_radio_frame_offset_r13_present, 1)); - HANDLE_CODE(bref.unpack(sys_info_value_tag_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - HANDLE_CODE(hyper_sfn_msb_r13.unpack(bref)); - HANDLE_CODE(unpack_dyn_seq_of(cell_access_related_info_r13.plmn_id_list_r13, bref, 1, 6)); - HANDLE_CODE(cell_access_related_info_r13.tac_r13.unpack(bref)); - HANDLE_CODE(cell_access_related_info_r13.cell_id_r13.unpack(bref)); - HANDLE_CODE(cell_access_related_info_r13.cell_barred_r13.unpack(bref)); - HANDLE_CODE(cell_access_related_info_r13.intra_freq_resel_r13.unpack(bref)); - HANDLE_CODE(unpack_integer(cell_sel_info_r13.q_rx_lev_min_r13, bref, (int8_t)-70, (int8_t)-22)); - HANDLE_CODE(unpack_integer(cell_sel_info_r13.q_qual_min_r13, bref, (int8_t)-34, (int8_t)-3)); - if (p_max_r13_present) { - HANDLE_CODE(unpack_integer(p_max_r13, bref, (int8_t)-30, (int8_t)33)); - } - HANDLE_CODE(unpack_integer(freq_band_ind_r13, bref, (uint16_t)1u, (uint16_t)256u)); - if (freq_band_info_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(freq_band_info_r13, bref, 1, 4)); - } - if (multi_band_info_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(multi_band_info_list_r13, bref, 1, 8)); - } - if (dl_bitmap_r13_present) { - HANDLE_CODE(dl_bitmap_r13.unpack(bref)); - } - if (eutra_ctrl_region_size_r13_present) { - HANDLE_CODE(eutra_ctrl_region_size_r13.unpack(bref)); - } - if (nrs_crs_pwr_offset_r13_present) { - HANDLE_CODE(nrs_crs_pwr_offset_r13.unpack(bref)); - } - HANDLE_CODE(unpack_dyn_seq_of(sched_info_list_r13, bref, 1, 8)); - HANDLE_CODE(si_win_len_r13.unpack(bref)); - if (si_radio_frame_offset_r13_present) { - HANDLE_CODE(unpack_integer(si_radio_frame_offset_r13, bref, (uint8_t)1u, (uint8_t)15u)); - } - if (sys_info_value_tag_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(sys_info_value_tag_list_r13, bref, 1, 8, integer_packer(0, 3))); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); - } - - return SRSASN_SUCCESS; + static const float options[] = {0.0, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}; + return map_enum_number(options, 8, value, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::alpha_r16_e_"); } -void sib_type1_nb_s::to_json(json_writer& j) const +const char* pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::alpha_r16_opts::to_number_string() const { - j.start_obj(); - j.write_str("hyperSFN-MSB-r13", hyper_sfn_msb_r13.to_string()); - j.write_fieldname("cellAccessRelatedInfo-r13"); - j.start_obj(); - j.start_array("plmn-IdentityList-r13"); - for (const auto& e1 : cell_access_related_info_r13.plmn_id_list_r13) { - e1.to_json(j); - } - j.end_array(); - j.write_str("trackingAreaCode-r13", cell_access_related_info_r13.tac_r13.to_string()); - j.write_str("cellIdentity-r13", cell_access_related_info_r13.cell_id_r13.to_string()); - j.write_str("cellBarred-r13", cell_access_related_info_r13.cell_barred_r13.to_string()); - j.write_str("intraFreqReselection-r13", cell_access_related_info_r13.intra_freq_resel_r13.to_string()); - j.end_obj(); - j.write_fieldname("cellSelectionInfo-r13"); - j.start_obj(); - j.write_int("q-RxLevMin-r13", cell_sel_info_r13.q_rx_lev_min_r13); - j.write_int("q-QualMin-r13", cell_sel_info_r13.q_qual_min_r13); - j.end_obj(); - if (p_max_r13_present) { - j.write_int("p-Max-r13", p_max_r13); - } - j.write_int("freqBandIndicator-r13", freq_band_ind_r13); - if (freq_band_info_r13_present) { - j.start_array("freqBandInfo-r13"); - for (const auto& e1 : freq_band_info_r13) { - e1.to_json(j); - } - j.end_array(); - } - if (multi_band_info_list_r13_present) { - j.start_array("multiBandInfoList-r13"); - for (const auto& e1 : multi_band_info_list_r13) { - e1.to_json(j); - } - j.end_array(); - } - if (dl_bitmap_r13_present) { - j.write_fieldname("downlinkBitmap-r13"); - dl_bitmap_r13.to_json(j); - } - if (eutra_ctrl_region_size_r13_present) { - j.write_str("eutraControlRegionSize-r13", eutra_ctrl_region_size_r13.to_string()); - } - if (nrs_crs_pwr_offset_r13_present) { - j.write_str("nrs-CRS-PowerOffset-r13", nrs_crs_pwr_offset_r13.to_string()); - } - j.start_array("schedulingInfoList-r13"); - for (const auto& e1 : sched_info_list_r13) { - e1.to_json(j); - } - j.end_array(); - j.write_str("si-WindowLength-r13", si_win_len_r13.to_string()); - if (si_radio_frame_offset_r13_present) { - j.write_int("si-RadioFrameOffset-r13", si_radio_frame_offset_r13); - } - if (sys_info_value_tag_list_r13_present) { - j.start_array("systemInfoValueTagList-r13"); - for (const auto& e1 : sys_info_value_tag_list_r13) { - j.write_int(e1); - } - j.end_array(); - } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); - } - j.end_obj(); + static const char* options[] = {"0", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1"}; + return convert_enum_idx(options, 8, value, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::alpha_r16_e_"); } -const char* sib_type1_nb_s::cell_access_related_info_r13_s_::cell_barred_r13_opts::to_string() const +const char* pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_cyclic_shift_r16_opts::to_string() const { - static const char* options[] = {"barred", "notBarred"}; - return convert_enum_idx(options, 2, value, "sib_type1_nb_s::cell_access_related_info_r13_s_::cell_barred_r13_e_"); + static const char* options[] = {"n0", "n6"}; + return convert_enum_idx(options, 2, value, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_cyclic_shift_r16_e_"); } - -const char* sib_type1_nb_s::cell_access_related_info_r13_s_::intra_freq_resel_r13_opts::to_string() const +uint8_t pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_cyclic_shift_r16_opts::to_number() const { - static const char* options[] = {"allowed", "notAllowed"}; - return convert_enum_idx( - options, 2, value, "sib_type1_nb_s::cell_access_related_info_r13_s_::intra_freq_resel_r13_e_"); + static const uint8_t options[] = {0, 6}; + return map_enum_number(options, 2, value, "pur_cfg_nb_r16_s::pur_phys_cfg_r16_s_::npusch_cyclic_shift_r16_e_"); } -const char* sib_type1_nb_s::eutra_ctrl_region_size_r13_opts::to_string() const -{ - static const char* options[] = {"n1", "n2", "n3"}; - return convert_enum_idx(options, 3, value, "sib_type1_nb_s::eutra_ctrl_region_size_r13_e_"); -} -uint8_t sib_type1_nb_s::eutra_ctrl_region_size_r13_opts::to_number() const +// RRCConnectionRelease-NB-v1700-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_release_nb_v1700_ies_s::pack(bit_ref& bref) const { - static const uint8_t options[] = {1, 2, 3}; - return map_enum_number(options, 3, value, "sib_type1_nb_s::eutra_ctrl_region_size_r13_e_"); -} + HANDLE_CODE(bref.pack(cbp_idx_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); -const char* sib_type1_nb_s::nrs_crs_pwr_offset_r13_opts::to_string() const -{ - static const char* options[] = {"dB-6", - "dB-4dot77", - "dB-3", - "dB-1dot77", - "dB0", - "dB1", - "dB1dot23", - "dB2", - "dB3", - "dB4", - "dB4dot23", - "dB5", - "dB6", - "dB7", - "dB8", - "dB9"}; - return convert_enum_idx(options, 16, value, "sib_type1_nb_s::nrs_crs_pwr_offset_r13_e_"); -} -float sib_type1_nb_s::nrs_crs_pwr_offset_r13_opts::to_number() const -{ - static const float options[] = { - -6.0, -4.77, -3.0, -1.77, 0.0, 1.0, 1.23, 2.0, 3.0, 4.0, 4.23, 5.0, 6.0, 7.0, 8.0, 9.0}; - return map_enum_number(options, 16, value, "sib_type1_nb_s::nrs_crs_pwr_offset_r13_e_"); + if (cbp_idx_r17_present) { + HANDLE_CODE(pack_integer(bref, cbp_idx_r17, (uint8_t)1u, (uint8_t)2u)); + } + + return SRSASN_SUCCESS; } -const char* sib_type1_nb_s::nrs_crs_pwr_offset_r13_opts::to_number_string() const +SRSASN_CODE rrc_conn_release_nb_v1700_ies_s::unpack(cbit_ref& bref) { - static const char* options[] = { - "-6", "-4.77", "-3", "-1.77", "0", "1", "1.23", "2", "3", "4", "4.23", "5", "6", "7", "8", "9"}; - return convert_enum_idx(options, 16, value, "sib_type1_nb_s::nrs_crs_pwr_offset_r13_e_"); -} + HANDLE_CODE(bref.unpack(cbp_idx_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); -const char* sib_type1_nb_s::si_win_len_r13_opts::to_string() const + if (cbp_idx_r17_present) { + HANDLE_CODE(unpack_integer(cbp_idx_r17, bref, (uint8_t)1u, (uint8_t)2u)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_release_nb_v1700_ies_s::to_json(json_writer& j) const { - static const char* options[] = {"ms160", "ms320", "ms480", "ms640", "ms960", "ms1280", "ms1600", "spare1"}; - return convert_enum_idx(options, 8, value, "sib_type1_nb_s::si_win_len_r13_e_"); + j.start_obj(); + if (cbp_idx_r17_present) { + j.write_int("cbp-Index-r17", cbp_idx_r17); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); } -uint16_t sib_type1_nb_s::si_win_len_r13_opts::to_number() const + +// RRCConnectionRelease-NB-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_release_nb_v1610_ies_s::pack(bit_ref& bref) const { - static const uint16_t options[] = {160, 320, 480, 640, 960, 1280, 1600}; - return map_enum_number(options, 7, value, "sib_type1_nb_s::si_win_len_r13_e_"); + HANDLE_CODE(bref.pack(resume_id_r16_present, 1)); + HANDLE_CODE(bref.pack(anr_meas_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (resume_id_r16_present) { + HANDLE_CODE(resume_id_r16.pack(bref)); + } + if (anr_meas_cfg_r16_present) { + HANDLE_CODE(anr_meas_cfg_r16.pack(bref)); + } + if (pur_cfg_r16_present) { + HANDLE_CODE(pur_cfg_r16.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; } +SRSASN_CODE rrc_conn_release_nb_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(resume_id_r16_present, 1)); + HANDLE_CODE(bref.unpack(anr_meas_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); -// BCCH-DL-SCH-MessageType-NB ::= CHOICE -void bcch_dl_sch_msg_type_nb_c::set(types::options e) + if (resume_id_r16_present) { + HANDLE_CODE(resume_id_r16.unpack(bref)); + } + if (anr_meas_cfg_r16_present) { + HANDLE_CODE(anr_meas_cfg_r16.unpack(bref)); + } + if (pur_cfg_r16_present) { + HANDLE_CODE(pur_cfg_r16.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_release_nb_v1610_ies_s::to_json(json_writer& j) const { - type_ = e; + j.start_obj(); + if (resume_id_r16_present) { + j.write_str("resumeIdentity-r16", resume_id_r16.to_string()); + } + if (anr_meas_cfg_r16_present) { + j.write_fieldname("anr-MeasConfig-r16"); + anr_meas_cfg_r16.to_json(j); + } + if (pur_cfg_r16_present) { + j.write_fieldname("pur-Config-r16"); + pur_cfg_r16.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); } -bcch_dl_sch_msg_type_nb_c::c1_c_& bcch_dl_sch_msg_type_nb_c::set_c1() + +// RRCConnectionRelease-NB-v15b0-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_release_nb_v15b0_ies_s::pack(bit_ref& bref) const { - set(types::c1); - return c; + HANDLE_CODE(bref.pack(no_last_cell_upd_r15_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; } -void bcch_dl_sch_msg_type_nb_c::set_msg_class_ext() +SRSASN_CODE rrc_conn_release_nb_v15b0_ies_s::unpack(cbit_ref& bref) { - set(types::msg_class_ext); + HANDLE_CODE(bref.unpack(no_last_cell_upd_r15_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; } -void bcch_dl_sch_msg_type_nb_c::to_json(json_writer& j) const +void rrc_conn_release_nb_v15b0_ies_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::c1: - j.write_fieldname("c1"); - c.to_json(j); - break; - case types::msg_class_ext: - break; - default: - log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c"); + if (no_last_cell_upd_r15_present) { + j.write_str("noLastCellUpdate-r15", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); } j.end_obj(); } -SRSASN_CODE bcch_dl_sch_msg_type_nb_c::pack(bit_ref& bref) const + +// RRCConnectionRelease-NB-v1550-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_release_nb_v1550_ies_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::c1: - HANDLE_CODE(c.pack(bref)); - break; - case types::msg_class_ext: - break; - default: - log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c"); - return SRSASN_ERROR_ENCODE_FAIL; + HANDLE_CODE(bref.pack(redirected_carrier_info_v1550_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (redirected_carrier_info_v1550_present) { + HANDLE_CODE(redirected_carrier_info_v1550.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); } + return SRSASN_SUCCESS; } -SRSASN_CODE bcch_dl_sch_msg_type_nb_c::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_release_nb_v1550_ies_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::c1: - HANDLE_CODE(c.unpack(bref)); - break; - case types::msg_class_ext: - break; - default: - log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c"); - return SRSASN_ERROR_DECODE_FAIL; + HANDLE_CODE(bref.unpack(redirected_carrier_info_v1550_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (redirected_carrier_info_v1550_present) { + HANDLE_CODE(redirected_carrier_info_v1550.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); } + return SRSASN_SUCCESS; } - -void bcch_dl_sch_msg_type_nb_c::c1_c_::destroy_() +void rrc_conn_release_nb_v1550_ies_s::to_json(json_writer& j) const { - switch (type_) { - case types::sys_info_r13: - c.destroy(); - break; - case types::sib_type1_r13: - c.destroy(); - break; - default: - break; + j.start_obj(); + if (redirected_carrier_info_v1550_present) { + j.write_fieldname("redirectedCarrierInfo-v1550"); + redirected_carrier_info_v1550.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); } + j.end_obj(); } -void bcch_dl_sch_msg_type_nb_c::c1_c_::set(types::options e) + +// RRCConnectionRelease-NB-v1530-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_release_nb_v1530_ies_s::pack(bit_ref& bref) const { - destroy_(); - type_ = e; - switch (type_) { - case types::sys_info_r13: - c.init(); - break; - case types::sib_type1_r13: - c.init(); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); + HANDLE_CODE(bref.pack(drb_continue_rohc_r15_present, 1)); + HANDLE_CODE(bref.pack(next_hop_chaining_count_r15_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (next_hop_chaining_count_r15_present) { + HANDLE_CODE(pack_integer(bref, next_hop_chaining_count_r15, (uint8_t)0u, (uint8_t)7u)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); } + + return SRSASN_SUCCESS; } -bcch_dl_sch_msg_type_nb_c::c1_c_::c1_c_(const bcch_dl_sch_msg_type_nb_c::c1_c_& other) +SRSASN_CODE rrc_conn_release_nb_v1530_ies_s::unpack(cbit_ref& bref) { - type_ = other.type(); - switch (type_) { - case types::sys_info_r13: - c.init(other.c.get()); - break; - case types::sib_type1_r13: - c.init(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); + HANDLE_CODE(bref.unpack(drb_continue_rohc_r15_present, 1)); + HANDLE_CODE(bref.unpack(next_hop_chaining_count_r15_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (next_hop_chaining_count_r15_present) { + HANDLE_CODE(unpack_integer(next_hop_chaining_count_r15, bref, (uint8_t)0u, (uint8_t)7u)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); } + + return SRSASN_SUCCESS; } -bcch_dl_sch_msg_type_nb_c::c1_c_& -bcch_dl_sch_msg_type_nb_c::c1_c_::operator=(const bcch_dl_sch_msg_type_nb_c::c1_c_& other) +void rrc_conn_release_nb_v1530_ies_s::to_json(json_writer& j) const { - if (this == &other) { - return *this; + j.start_obj(); + if (drb_continue_rohc_r15_present) { + j.write_str("drb-ContinueROHC-r15", "true"); } - set(other.type()); - switch (type_) { - case types::sys_info_r13: - c.set(other.c.get()); - break; - case types::sib_type1_r13: - c.set(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); + if (next_hop_chaining_count_r15_present) { + j.write_int("nextHopChainingCount-r15", next_hop_chaining_count_r15); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// RRCConnectionRelease-NB-v1430-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_release_nb_v1430_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(redirected_carrier_info_v1430_present, 1)); + HANDLE_CODE(bref.pack(extended_wait_time_cpdata_r14_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (redirected_carrier_info_v1430_present) { + HANDLE_CODE(redirected_carrier_info_v1430.pack(bref)); + } + if (extended_wait_time_cpdata_r14_present) { + HANDLE_CODE(pack_integer(bref, extended_wait_time_cpdata_r14, (uint16_t)1u, (uint16_t)1800u)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); } - return *this; -} -sys_info_nb_s& bcch_dl_sch_msg_type_nb_c::c1_c_::set_sys_info_r13() -{ - set(types::sys_info_r13); - return c.get(); + return SRSASN_SUCCESS; } -sib_type1_nb_s& bcch_dl_sch_msg_type_nb_c::c1_c_::set_sib_type1_r13() +SRSASN_CODE rrc_conn_release_nb_v1430_ies_s::unpack(cbit_ref& bref) { - set(types::sib_type1_r13); - return c.get(); + HANDLE_CODE(bref.unpack(redirected_carrier_info_v1430_present, 1)); + HANDLE_CODE(bref.unpack(extended_wait_time_cpdata_r14_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (redirected_carrier_info_v1430_present) { + HANDLE_CODE(redirected_carrier_info_v1430.unpack(bref)); + } + if (extended_wait_time_cpdata_r14_present) { + HANDLE_CODE(unpack_integer(extended_wait_time_cpdata_r14, bref, (uint16_t)1u, (uint16_t)1800u)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; } -void bcch_dl_sch_msg_type_nb_c::c1_c_::to_json(json_writer& j) const +void rrc_conn_release_nb_v1430_ies_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::sys_info_r13: - j.write_fieldname("systemInformation-r13"); - c.get().to_json(j); - break; - case types::sib_type1_r13: - j.write_fieldname("systemInformationBlockType1-r13"); - c.get().to_json(j); - break; - default: - log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); + if (redirected_carrier_info_v1430_present) { + j.write_fieldname("redirectedCarrierInfo-v1430"); + redirected_carrier_info_v1430.to_json(j); + } + if (extended_wait_time_cpdata_r14_present) { + j.write_int("extendedWaitTime-CPdata-r14", extended_wait_time_cpdata_r14); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); } j.end_obj(); } -SRSASN_CODE bcch_dl_sch_msg_type_nb_c::c1_c_::pack(bit_ref& bref) const + +// RRCConnectionResume-NB-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_nb_v1610_ies_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::sys_info_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::sib_type1_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - default: - log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); - return SRSASN_ERROR_ENCODE_FAIL; - } + HANDLE_CODE(bref.pack(full_cfg_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + return SRSASN_SUCCESS; } -SRSASN_CODE bcch_dl_sch_msg_type_nb_c::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_nb_v1610_ies_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::sys_info_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::sib_type1_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - default: - log_invalid_choice_id(type_, "bcch_dl_sch_msg_type_nb_c::c1_c_"); - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; -} + HANDLE_CODE(bref.unpack(full_cfg_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); -const char* bcch_dl_sch_msg_type_nb_c::c1_c_::types_opts::to_string() const -{ - static const char* options[] = {"systemInformation-r13", "systemInformationBlockType1-r13"}; - return convert_enum_idx(options, 2, value, "bcch_dl_sch_msg_type_nb_c::c1_c_::types"); + return SRSASN_SUCCESS; } -uint8_t bcch_dl_sch_msg_type_nb_c::c1_c_::types_opts::to_number() const +void rrc_conn_resume_nb_v1610_ies_s::to_json(json_writer& j) const { - if (value == sib_type1_r13) { - return 1; + j.start_obj(); + if (full_cfg_r16_present) { + j.write_str("fullConfig-r16", "true"); } - invalid_enum_number(value, "bcch_dl_sch_msg_type_nb_c::c1_c_::types"); - return 0; + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); } -const char* bcch_dl_sch_msg_type_nb_c::types_opts::to_string() const -{ - static const char* options[] = {"c1", "messageClassExtension"}; - return convert_enum_idx(options, 2, value, "bcch_dl_sch_msg_type_nb_c::types"); -} -uint8_t bcch_dl_sch_msg_type_nb_c::types_opts::to_number() const +// ReleaseCause-NB-r13 ::= ENUMERATED +const char* release_cause_nb_r13_opts::to_string() const { - static const uint8_t options[] = {1}; - return map_enum_number(options, 1, value, "bcch_dl_sch_msg_type_nb_c::types"); + static const char* options[] = {"loadBalancingTAUrequired", "other", "rrc-Suspend", "spare1"}; + return convert_enum_idx(options, 4, value, "release_cause_nb_r13_e"); } -// BCCH-DL-SCH-Message-NB ::= SEQUENCE -SRSASN_CODE bcch_dl_sch_msg_nb_s::pack(bit_ref& bref) const +// DLInformationTransfer-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE dl_info_transfer_nb_r13_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(msg.pack(bref)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - bref.align_bytes_zero(); + HANDLE_CODE(ded_info_nas_r13.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE bcch_dl_sch_msg_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE dl_info_transfer_nb_r13_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(msg.unpack(bref)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - bref.align_bytes(); + HANDLE_CODE(ded_info_nas_r13.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } -void bcch_dl_sch_msg_nb_s::to_json(json_writer& j) const +void dl_info_transfer_nb_r13_ies_s::to_json(json_writer& j) const { - j.start_array(); j.start_obj(); - j.start_obj("BCCH-DL-SCH-Message-NB"); - j.write_fieldname("message"); - msg.to_json(j); - j.end_obj(); + j.write_str("dedicatedInfoNAS-r13", ded_info_nas_r13.to_string()); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } j.end_obj(); - j.end_array(); } -// RRCConnectionReestablishment-NB-v1430-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_reest_nb_v1430_ies_s::pack(bit_ref& bref) const +// RRCConnectionReconfiguration-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_recfg_nb_r13_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(dl_nas_mac_present, 1)); + HANDLE_CODE(bref.pack(ded_info_nas_list_r13_present, 1)); + HANDLE_CODE(bref.pack(rr_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.pack(full_cfg_r13_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (dl_nas_mac_present) { - HANDLE_CODE(dl_nas_mac.pack(bref)); + if (ded_info_nas_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, ded_info_nas_list_r13, 1, 2)); + } + if (rr_cfg_ded_r13_present) { + HANDLE_CODE(rr_cfg_ded_r13.pack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_nb_v1430_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_recfg_nb_r13_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(dl_nas_mac_present, 1)); + HANDLE_CODE(bref.unpack(ded_info_nas_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(rr_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.unpack(full_cfg_r13_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - if (dl_nas_mac_present) { - HANDLE_CODE(dl_nas_mac.unpack(bref)); + if (ded_info_nas_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(ded_info_nas_list_r13, bref, 1, 2)); + } + if (rr_cfg_ded_r13_present) { + HANDLE_CODE(rr_cfg_ded_r13.unpack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); } return SRSASN_SUCCESS; } -void rrc_conn_reest_nb_v1430_ies_s::to_json(json_writer& j) const +void rrc_conn_recfg_nb_r13_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (dl_nas_mac_present) { - j.write_str("dl-NAS-MAC", dl_nas_mac.to_string()); + if (ded_info_nas_list_r13_present) { + j.start_array("dedicatedInfoNASList-r13"); + for (const auto& e1 : ded_info_nas_list_r13) { + j.write_str(e1.to_string()); + } + j.end_array(); + } + if (rr_cfg_ded_r13_present) { + j.write_fieldname("radioResourceConfigDedicated-r13"); + rr_cfg_ded_r13.to_json(j); + } + if (full_cfg_r13_present) { + j.write_str("fullConfig-r13", "true"); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); @@ -12409,112 +18539,96 @@ void rrc_conn_reest_nb_v1430_ies_s::to_json(json_writer& j) const j.end_obj(); } -// RRCEarlyDataComplete-NB-v1590-IEs ::= SEQUENCE -SRSASN_CODE rrc_early_data_complete_nb_v1590_ies_s::pack(bit_ref& bref) const +// RRCConnectionRelease-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_release_nb_r13_ies_s::pack(bit_ref& bref) const { + HANDLE_CODE(bref.pack(resume_id_r13_present, 1)); + HANDLE_CODE(bref.pack(extended_wait_time_r13_present, 1)); + HANDLE_CODE(bref.pack(redirected_carrier_info_r13_present, 1)); HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + HANDLE_CODE(release_cause_r13.pack(bref)); + if (resume_id_r13_present) { + HANDLE_CODE(resume_id_r13.pack(bref)); + } + if (extended_wait_time_r13_present) { + HANDLE_CODE(pack_integer(bref, extended_wait_time_r13, (uint16_t)1u, (uint16_t)1800u)); + } + if (redirected_carrier_info_r13_present) { + HANDLE_CODE(redirected_carrier_info_r13.pack(bref)); + } if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } - - return SRSASN_SUCCESS; -} -SRSASN_CODE rrc_early_data_complete_nb_v1590_ies_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_release_nb_r13_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(resume_id_r13_present, 1)); + HANDLE_CODE(bref.unpack(extended_wait_time_r13_present, 1)); + HANDLE_CODE(bref.unpack(redirected_carrier_info_r13_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(release_cause_r13.unpack(bref)); + if (resume_id_r13_present) { + HANDLE_CODE(resume_id_r13.unpack(bref)); + } + if (extended_wait_time_r13_present) { + HANDLE_CODE(unpack_integer(extended_wait_time_r13, bref, (uint16_t)1u, (uint16_t)1800u)); + } + if (redirected_carrier_info_r13_present) { + HANDLE_CODE(redirected_carrier_info_r13.unpack(bref)); + } if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } -void rrc_early_data_complete_nb_v1590_ies_s::to_json(json_writer& j) const +void rrc_conn_release_nb_r13_ies_s::to_json(json_writer& j) const { j.start_obj(); + j.write_str("releaseCause-r13", release_cause_r13.to_string()); + if (resume_id_r13_present) { + j.write_str("resumeIdentity-r13", resume_id_r13.to_string()); + } + if (extended_wait_time_r13_present) { + j.write_int("extendedWaitTime-r13", extended_wait_time_r13); + } + if (redirected_carrier_info_r13_present) { + j.write_fieldname("redirectedCarrierInfo-r13"); + redirected_carrier_info_r13.to_json(j); + } if (late_non_crit_ext_present) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } -// RedirectedCarrierInfo-NB-v1430 ::= SEQUENCE -SRSASN_CODE redirected_carrier_info_nb_v1430_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(redirected_carrier_offset_ded_r14.pack(bref)); - HANDLE_CODE(t322_r14.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE redirected_carrier_info_nb_v1430_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(redirected_carrier_offset_ded_r14.unpack(bref)); - HANDLE_CODE(t322_r14.unpack(bref)); - - return SRSASN_SUCCESS; -} -void redirected_carrier_info_nb_v1430_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_str("redirectedCarrierOffsetDedicated-r14", redirected_carrier_offset_ded_r14.to_string()); - j.write_str("t322-r14", t322_r14.to_string()); - j.end_obj(); -} - -const char* redirected_carrier_info_nb_v1430_s::redirected_carrier_offset_ded_r14_opts::to_string() const -{ - static const char* options[] = {"dB1", - "dB2", - "dB3", - "dB4", - "dB5", - "dB6", - "dB8", - "dB10", - "dB12", - "dB14", - "dB16", - "dB18", - "dB20", - "dB22", - "dB24", - "dB26"}; - return convert_enum_idx( - options, 16, value, "redirected_carrier_info_nb_v1430_s::redirected_carrier_offset_ded_r14_e_"); -} -uint8_t redirected_carrier_info_nb_v1430_s::redirected_carrier_offset_ded_r14_opts::to_number() const -{ - static const uint8_t options[] = {1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26}; - return map_enum_number( - options, 16, value, "redirected_carrier_info_nb_v1430_s::redirected_carrier_offset_ded_r14_e_"); -} - -const char* redirected_carrier_info_nb_v1430_s::t322_r14_opts::to_string() const -{ - static const char* options[] = {"min5", "min10", "min20", "min30", "min60", "min120", "min180", "spare1"}; - return convert_enum_idx(options, 8, value, "redirected_carrier_info_nb_v1430_s::t322_r14_e_"); -} -uint8_t redirected_carrier_info_nb_v1430_s::t322_r14_opts::to_number() const -{ - static const uint8_t options[] = {5, 10, 20, 30, 60, 120, 180}; - return map_enum_number(options, 7, value, "redirected_carrier_info_nb_v1430_s::t322_r14_e_"); -} - -// RRCConnectionReestablishment-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_reest_nb_r13_ies_s::pack(bit_ref& bref) const +// RRCConnectionResume-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_nb_r13_ies_s::pack(bit_ref& bref) const { + HANDLE_CODE(bref.pack(rr_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.pack(drb_continue_rohc_r13_present, 1)); HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - HANDLE_CODE(rr_cfg_ded_r13.pack(bref)); + if (rr_cfg_ded_r13_present) { + HANDLE_CODE(rr_cfg_ded_r13.pack(bref)); + } HANDLE_CODE(pack_integer(bref, next_hop_chaining_count_r13, (uint8_t)0u, (uint8_t)7u)); if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.pack(bref)); @@ -12525,12 +18639,16 @@ SRSASN_CODE rrc_conn_reest_nb_r13_ies_s::pack(bit_ref& bref) const return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_nb_r13_ies_s::unpack(cbit_ref& bref) { + HANDLE_CODE(bref.unpack(rr_cfg_ded_r13_present, 1)); + HANDLE_CODE(bref.unpack(drb_continue_rohc_r13_present, 1)); HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - HANDLE_CODE(rr_cfg_ded_r13.unpack(bref)); + if (rr_cfg_ded_r13_present) { + HANDLE_CODE(rr_cfg_ded_r13.unpack(bref)); + } HANDLE_CODE(unpack_integer(next_hop_chaining_count_r13, bref, (uint8_t)0u, (uint8_t)7u)); if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.unpack(bref)); @@ -12541,12 +18659,17 @@ SRSASN_CODE rrc_conn_reest_nb_r13_ies_s::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -void rrc_conn_reest_nb_r13_ies_s::to_json(json_writer& j) const +void rrc_conn_resume_nb_r13_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("radioResourceConfigDedicated-r13"); - rr_cfg_ded_r13.to_json(j); + if (rr_cfg_ded_r13_present) { + j.write_fieldname("radioResourceConfigDedicated-r13"); + rr_cfg_ded_r13.to_json(j); + } j.write_int("nextHopChainingCount-r13", next_hop_chaining_count_r13); + if (drb_continue_rohc_r13_present) { + j.write_str("drb-ContinueROHC-r13", "true"); + } if (late_non_crit_ext_present) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } @@ -12557,40 +18680,32 @@ void rrc_conn_reest_nb_r13_ies_s::to_json(json_writer& j) const j.end_obj(); } -// RRCConnectionReject-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_reject_nb_r13_ies_s::pack(bit_ref& bref) const +// UECapabilityEnquiry-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE ue_cap_enquiry_nb_r13_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(rrc_suspend_ind_r13_present, 1)); HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - HANDLE_CODE(pack_integer(bref, extended_wait_time_r13, (uint16_t)1u, (uint16_t)1800u)); if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reject_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE ue_cap_enquiry_nb_r13_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(rrc_suspend_ind_r13_present, 1)); HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - HANDLE_CODE(unpack_integer(extended_wait_time_r13, bref, (uint16_t)1u, (uint16_t)1800u)); if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.unpack(bref)); } return SRSASN_SUCCESS; } -void rrc_conn_reject_nb_r13_ies_s::to_json(json_writer& j) const +void ue_cap_enquiry_nb_r13_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("extendedWaitTime-r13", extended_wait_time_r13); - if (rrc_suspend_ind_r13_present) { - j.write_str("rrc-SuspendIndication-r13", "true"); - } if (late_non_crit_ext_present) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } @@ -12602,36 +18717,41 @@ void rrc_conn_reject_nb_r13_ies_s::to_json(json_writer& j) const j.end_obj(); } -// RRCConnectionSetup-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_setup_nb_r13_ies_s::pack(bit_ref& bref) const +// UEInformationRequest-NB-r16-IEs ::= SEQUENCE +SRSASN_CODE ue_info_request_nb_r16_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - HANDLE_CODE(rr_cfg_ded_r13.pack(bref)); + HANDLE_CODE(bref.pack(rach_report_req_r16, 1)); + HANDLE_CODE(bref.pack(rlf_report_req_r16, 1)); + HANDLE_CODE(bref.pack(anr_report_req_r16, 1)); if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_setup_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE ue_info_request_nb_r16_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - HANDLE_CODE(rr_cfg_ded_r13.unpack(bref)); + HANDLE_CODE(bref.unpack(rach_report_req_r16, 1)); + HANDLE_CODE(bref.unpack(rlf_report_req_r16, 1)); + HANDLE_CODE(bref.unpack(anr_report_req_r16, 1)); if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.unpack(bref)); } return SRSASN_SUCCESS; } -void rrc_conn_setup_nb_r13_ies_s::to_json(json_writer& j) const +void ue_info_request_nb_r16_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("radioResourceConfigDedicated-r13"); - rr_cfg_ded_r13.to_json(j); + j.write_bool("rach-ReportReq-r16", rach_report_req_r16); + j.write_bool("rlf-ReportReq-r16", rlf_report_req_r16); + j.write_bool("anr-ReportReq-r16", anr_report_req_r16); if (late_non_crit_ext_present) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } @@ -12643,99 +18763,174 @@ void rrc_conn_setup_nb_r13_ies_s::to_json(json_writer& j) const j.end_obj(); } -// RRCEarlyDataComplete-NB-r15-IEs ::= SEQUENCE -SRSASN_CODE rrc_early_data_complete_nb_r15_ies_s::pack(bit_ref& bref) const +// DLInformationTransfer-NB ::= SEQUENCE +SRSASN_CODE dl_info_transfer_nb_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(ded_info_nas_r15_present, 1)); - HANDLE_CODE(bref.pack(extended_wait_time_r15_present, 1)); - HANDLE_CODE(bref.pack(redirected_carrier_info_r15_present, 1)); - HANDLE_CODE(bref.pack(redirected_carrier_info_ext_r15_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.pack(bref)); - if (ded_info_nas_r15_present) { - HANDLE_CODE(ded_info_nas_r15.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE dl_info_transfer_nb_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void dl_info_transfer_nb_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void dl_info_transfer_nb_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +dl_info_transfer_nb_s::crit_exts_c_::c1_c_& dl_info_transfer_nb_s::crit_exts_c_::set_c1() +{ + set(types::c1); + return c; +} +void dl_info_transfer_nb_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void dl_info_transfer_nb_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::c1: + j.write_fieldname("c1"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_"); } - if (extended_wait_time_r15_present) { - HANDLE_CODE(pack_integer(bref, extended_wait_time_r15, (uint16_t)1u, (uint16_t)1800u)); + j.end_obj(); +} +SRSASN_CODE dl_info_transfer_nb_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::c1: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; } - if (redirected_carrier_info_r15_present) { - HANDLE_CODE(redirected_carrier_info_r15.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE dl_info_transfer_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::c1: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; } - if (redirected_carrier_info_ext_r15_present) { - HANDLE_CODE(redirected_carrier_info_ext_r15.pack(bref)); + return SRSASN_SUCCESS; +} + +void dl_info_transfer_nb_s::crit_exts_c_::c1_c_::set(types::options e) +{ + type_ = e; +} +dl_info_transfer_nb_r13_ies_s& dl_info_transfer_nb_s::crit_exts_c_::c1_c_::set_dl_info_transfer_r13() +{ + set(types::dl_info_transfer_r13); + return c; +} +void dl_info_transfer_nb_s::crit_exts_c_::c1_c_::set_spare1() +{ + set(types::spare1); +} +void dl_info_transfer_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::dl_info_transfer_r13: + j.write_fieldname("dlInformationTransfer-r13"); + c.to_json(j); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_::c1_c_"); } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); + j.end_obj(); +} +SRSASN_CODE dl_info_transfer_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::dl_info_transfer_r13: + HANDLE_CODE(c.pack(bref)); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_ENCODE_FAIL; } - return SRSASN_SUCCESS; } -SRSASN_CODE rrc_early_data_complete_nb_r15_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE dl_info_transfer_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(ded_info_nas_r15_present, 1)); - HANDLE_CODE(bref.unpack(extended_wait_time_r15_present, 1)); - HANDLE_CODE(bref.unpack(redirected_carrier_info_r15_present, 1)); - HANDLE_CODE(bref.unpack(redirected_carrier_info_ext_r15_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - if (ded_info_nas_r15_present) { - HANDLE_CODE(ded_info_nas_r15.unpack(bref)); - } - if (extended_wait_time_r15_present) { - HANDLE_CODE(unpack_integer(extended_wait_time_r15, bref, (uint16_t)1u, (uint16_t)1800u)); - } - if (redirected_carrier_info_r15_present) { - HANDLE_CODE(redirected_carrier_info_r15.unpack(bref)); - } - if (redirected_carrier_info_ext_r15_present) { - HANDLE_CODE(redirected_carrier_info_ext_r15.unpack(bref)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::dl_info_transfer_r13: + HANDLE_CODE(c.unpack(bref)); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_::c1_c_"); + return SRSASN_ERROR_DECODE_FAIL; } - return SRSASN_SUCCESS; } -void rrc_early_data_complete_nb_r15_ies_s::to_json(json_writer& j) const + +const char* dl_info_transfer_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const { - j.start_obj(); - if (ded_info_nas_r15_present) { - j.write_str("dedicatedInfoNAS-r15", ded_info_nas_r15.to_string()); - } - if (extended_wait_time_r15_present) { - j.write_int("extendedWaitTime-r15", extended_wait_time_r15); - } - if (redirected_carrier_info_r15_present) { - j.write_fieldname("redirectedCarrierInfo-r15"); - redirected_carrier_info_r15.to_json(j); - } - if (redirected_carrier_info_ext_r15_present) { - j.write_fieldname("redirectedCarrierInfoExt-r15"); - redirected_carrier_info_ext_r15.to_json(j); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); - } - j.end_obj(); + static const char* options[] = {"dlInformationTransfer-r13", "spare1"}; + return convert_enum_idx(options, 2, value, "dl_info_transfer_nb_s::crit_exts_c_::c1_c_::types"); } -// RRCConnectionReestablishment-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_reest_nb_s::pack(bit_ref& bref) const +// RRCConnectionReconfiguration-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_recfg_nb_s::pack(bit_ref& bref) const { HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_recfg_nb_s::unpack(cbit_ref& bref) { HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void rrc_conn_reest_nb_s::to_json(json_writer& j) const +void rrc_conn_recfg_nb_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); @@ -12744,20 +18939,20 @@ void rrc_conn_reest_nb_s::to_json(json_writer& j) const j.end_obj(); } -void rrc_conn_reest_nb_s::crit_exts_c_::set(types::options e) +void rrc_conn_recfg_nb_s::crit_exts_c_::set(types::options e) { type_ = e; } -rrc_conn_reest_nb_s::crit_exts_c_::c1_c_& rrc_conn_reest_nb_s::crit_exts_c_::set_c1() +rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_& rrc_conn_recfg_nb_s::crit_exts_c_::set_c1() { set(types::c1); return c; } -void rrc_conn_reest_nb_s::crit_exts_c_::set_crit_exts_future() +void rrc_conn_recfg_nb_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void rrc_conn_reest_nb_s::crit_exts_c_::to_json(json_writer& j) const +void rrc_conn_recfg_nb_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { @@ -12768,11 +18963,11 @@ void rrc_conn_reest_nb_s::crit_exts_c_::to_json(json_writer& j) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_reest_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_recfg_nb_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { @@ -12782,12 +18977,12 @@ SRSASN_CODE rrc_conn_reest_nb_s::crit_exts_c_::pack(bit_ref& bref) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_recfg_nb_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -12799,114 +18994,117 @@ SRSASN_CODE rrc_conn_reest_nb_s::crit_exts_c_::unpack(cbit_ref& bref) case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::set(types::options e) +void rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::set(types::options e) { type_ = e; } -rrc_conn_reest_nb_r13_ies_s& rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_reest_r13() +rrc_conn_recfg_nb_r13_ies_s& rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_recfg_r13() { - set(types::rrc_conn_reest_r13); + set(types::rrc_conn_recfg_r13); return c; } -void rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::set_spare1() +void rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::set_spare1() { set(types::spare1); } -void rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +void rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_conn_reest_r13: - j.write_fieldname("rrcConnectionReestablishment-r13"); + case types::rrc_conn_recfg_r13: + j.write_fieldname("rrcConnectionReconfiguration-r13"); c.to_json(j); break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_conn_reest_r13: + case types::rrc_conn_recfg_r13: HANDLE_CODE(c.pack(bref)); break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_conn_reest_r13: + case types::rrc_conn_recfg_r13: HANDLE_CODE(c.unpack(bref)); break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const +const char* rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const { - static const char* options[] = {"rrcConnectionReestablishment-r13", "spare1"}; - return convert_enum_idx(options, 2, value, "rrc_conn_reest_nb_s::crit_exts_c_::c1_c_::types"); + static const char* options[] = {"rrcConnectionReconfiguration-r13", "spare1"}; + return convert_enum_idx(options, 2, value, "rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::types"); } -// RRCConnectionReject-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_reject_nb_s::pack(bit_ref& bref) const +// RRCConnectionRelease-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_release_nb_s::pack(bit_ref& bref) const { + HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reject_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_release_nb_s::unpack(cbit_ref& bref) { + HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void rrc_conn_reject_nb_s::to_json(json_writer& j) const +void rrc_conn_release_nb_s::to_json(json_writer& j) const { j.start_obj(); + j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); j.write_fieldname("criticalExtensions"); crit_exts.to_json(j); j.end_obj(); } -void rrc_conn_reject_nb_s::crit_exts_c_::set(types::options e) +void rrc_conn_release_nb_s::crit_exts_c_::set(types::options e) { type_ = e; } -rrc_conn_reject_nb_s::crit_exts_c_::c1_c_& rrc_conn_reject_nb_s::crit_exts_c_::set_c1() +rrc_conn_release_nb_s::crit_exts_c_::c1_c_& rrc_conn_release_nb_s::crit_exts_c_::set_c1() { set(types::c1); return c; } -void rrc_conn_reject_nb_s::crit_exts_c_::set_crit_exts_future() +void rrc_conn_release_nb_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void rrc_conn_reject_nb_s::crit_exts_c_::to_json(json_writer& j) const +void rrc_conn_release_nb_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { @@ -12917,11 +19115,11 @@ void rrc_conn_reject_nb_s::crit_exts_c_::to_json(json_writer& j) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_reject_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_release_nb_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { @@ -12931,12 +19129,12 @@ SRSASN_CODE rrc_conn_reject_nb_s::crit_exts_c_::pack(bit_ref& bref) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reject_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_release_nb_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -12948,95 +19146,95 @@ SRSASN_CODE rrc_conn_reject_nb_s::crit_exts_c_::unpack(cbit_ref& bref) case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::set(types::options e) +void rrc_conn_release_nb_s::crit_exts_c_::c1_c_::set(types::options e) { type_ = e; } -rrc_conn_reject_nb_r13_ies_s& rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_reject_r13() +rrc_conn_release_nb_r13_ies_s& rrc_conn_release_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_release_r13() { - set(types::rrc_conn_reject_r13); + set(types::rrc_conn_release_r13); return c; } -void rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::set_spare1() +void rrc_conn_release_nb_s::crit_exts_c_::c1_c_::set_spare1() { set(types::spare1); } -void rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +void rrc_conn_release_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_conn_reject_r13: - j.write_fieldname("rrcConnectionReject-r13"); + case types::rrc_conn_release_r13: + j.write_fieldname("rrcConnectionRelease-r13"); c.to_json(j); break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_::c1_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_release_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_conn_reject_r13: + case types::rrc_conn_release_r13: HANDLE_CODE(c.pack(bref)); break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_release_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_conn_reject_r13: + case types::rrc_conn_release_r13: HANDLE_CODE(c.unpack(bref)); break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_reject_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const +const char* rrc_conn_release_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const { - static const char* options[] = {"rrcConnectionReject-r13", "spare1"}; - return convert_enum_idx(options, 2, value, "rrc_conn_reject_nb_s::crit_exts_c_::c1_c_::types"); + static const char* options[] = {"rrcConnectionRelease-r13", "spare1"}; + return convert_enum_idx(options, 2, value, "rrc_conn_release_nb_s::crit_exts_c_::c1_c_::types"); } -// RRCConnectionSetup-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_setup_nb_s::pack(bit_ref& bref) const +// RRCConnectionResume-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_nb_s::pack(bit_ref& bref) const { HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_setup_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_nb_s::unpack(cbit_ref& bref) { HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void rrc_conn_setup_nb_s::to_json(json_writer& j) const +void rrc_conn_resume_nb_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); @@ -13045,20 +19243,20 @@ void rrc_conn_setup_nb_s::to_json(json_writer& j) const j.end_obj(); } -void rrc_conn_setup_nb_s::crit_exts_c_::set(types::options e) +void rrc_conn_resume_nb_s::crit_exts_c_::set(types::options e) { type_ = e; } -rrc_conn_setup_nb_s::crit_exts_c_::c1_c_& rrc_conn_setup_nb_s::crit_exts_c_::set_c1() +rrc_conn_resume_nb_s::crit_exts_c_::c1_c_& rrc_conn_resume_nb_s::crit_exts_c_::set_c1() { set(types::c1); return c; } -void rrc_conn_setup_nb_s::crit_exts_c_::set_crit_exts_future() +void rrc_conn_resume_nb_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void rrc_conn_setup_nb_s::crit_exts_c_::to_json(json_writer& j) const +void rrc_conn_resume_nb_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { @@ -13069,11 +19267,11 @@ void rrc_conn_setup_nb_s::crit_exts_c_::to_json(json_writer& j) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_setup_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_resume_nb_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { @@ -13083,12 +19281,12 @@ SRSASN_CODE rrc_conn_setup_nb_s::crit_exts_c_::pack(bit_ref& bref) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_setup_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_nb_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -13100,993 +19298,784 @@ SRSASN_CODE rrc_conn_setup_nb_s::crit_exts_c_::unpack(cbit_ref& bref) case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::set(types::options e) +void rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::set(types::options e) { type_ = e; } -rrc_conn_setup_nb_r13_ies_s& rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_setup_r13() +rrc_conn_resume_nb_r13_ies_s& rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_resume_r13() { - set(types::rrc_conn_setup_r13); + set(types::rrc_conn_resume_r13); return c; } -void rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::set_spare1() +void rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::set_spare1() { set(types::spare1); } -void rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +void rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_conn_setup_r13: - j.write_fieldname("rrcConnectionSetup-r13"); + case types::rrc_conn_resume_r13: + j.write_fieldname("rrcConnectionResume-r13"); c.to_json(j); break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_::c1_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_conn_setup_r13: + case types::rrc_conn_resume_r13: HANDLE_CODE(c.pack(bref)); break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_conn_setup_r13: + case types::rrc_conn_resume_r13: HANDLE_CODE(c.unpack(bref)); break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_setup_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const +const char* rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const { - static const char* options[] = {"rrcConnectionSetup-r13", "spare1"}; - return convert_enum_idx(options, 2, value, "rrc_conn_setup_nb_s::crit_exts_c_::c1_c_::types"); + static const char* options[] = {"rrcConnectionResume-r13", "spare1"}; + return convert_enum_idx(options, 2, value, "rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::types"); } -// RRCEarlyDataComplete-NB-r15 ::= SEQUENCE -SRSASN_CODE rrc_early_data_complete_nb_r15_s::pack(bit_ref& bref) const +// UECapabilityEnquiry-NB ::= SEQUENCE +SRSASN_CODE ue_cap_enquiry_nb_s::pack(bit_ref& bref) const { + HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_early_data_complete_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE ue_cap_enquiry_nb_s::unpack(cbit_ref& bref) { + HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void rrc_early_data_complete_nb_r15_s::to_json(json_writer& j) const +void ue_cap_enquiry_nb_s::to_json(json_writer& j) const { j.start_obj(); + j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); j.write_fieldname("criticalExtensions"); crit_exts.to_json(j); j.end_obj(); } -void rrc_early_data_complete_nb_r15_s::crit_exts_c_::set(types::options e) +void ue_cap_enquiry_nb_s::crit_exts_c_::set(types::options e) { type_ = e; } -rrc_early_data_complete_nb_r15_ies_s& rrc_early_data_complete_nb_r15_s::crit_exts_c_::set_rrc_early_data_complete_r15() +ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_& ue_cap_enquiry_nb_s::crit_exts_c_::set_c1() { - set(types::rrc_early_data_complete_r15); + set(types::c1); return c; } -void rrc_early_data_complete_nb_r15_s::crit_exts_c_::set_crit_exts_future() +void ue_cap_enquiry_nb_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void rrc_early_data_complete_nb_r15_s::crit_exts_c_::to_json(json_writer& j) const +void ue_cap_enquiry_nb_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_early_data_complete_r15: - j.write_fieldname("rrcEarlyDataComplete-r15"); + case types::c1: + j.write_fieldname("c1"); c.to_json(j); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_early_data_complete_nb_r15_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE rrc_early_data_complete_nb_r15_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE ue_cap_enquiry_nb_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_early_data_complete_r15: + case types::c1: HANDLE_CODE(c.pack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_early_data_complete_nb_r15_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_early_data_complete_nb_r15_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE ue_cap_enquiry_nb_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_early_data_complete_r15: + case types::c1: HANDLE_CODE(c.unpack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_early_data_complete_nb_r15_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* rrc_early_data_complete_nb_r15_s::crit_exts_c_::types_opts::to_string() const -{ - static const char* options[] = {"rrcEarlyDataComplete-r15", "criticalExtensionsFuture"}; - return convert_enum_idx(options, 2, value, "rrc_early_data_complete_nb_r15_s::crit_exts_c_::types"); -} - -// DL-CCCH-MessageType-NB ::= CHOICE -void dl_ccch_msg_type_nb_c::set(types::options e) +void ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::set(types::options e) { type_ = e; } -dl_ccch_msg_type_nb_c::c1_c_& dl_ccch_msg_type_nb_c::set_c1() +ue_cap_enquiry_nb_r13_ies_s& ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::set_ue_cap_enquiry_r13() { - set(types::c1); + set(types::ue_cap_enquiry_r13); return c; } -void dl_ccch_msg_type_nb_c::set_msg_class_ext() +void ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::set_spare1() { - set(types::msg_class_ext); + set(types::spare1); } -void dl_ccch_msg_type_nb_c::to_json(json_writer& j) const +void ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::c1: - j.write_fieldname("c1"); + case types::ue_cap_enquiry_r13: + j.write_fieldname("ueCapabilityEnquiry-r13"); c.to_json(j); break; - case types::msg_class_ext: + case types::spare1: break; default: - log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c"); + log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_"); } j.end_obj(); } -SRSASN_CODE dl_ccch_msg_type_nb_c::pack(bit_ref& bref) const +SRSASN_CODE ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::c1: + case types::ue_cap_enquiry_r13: HANDLE_CODE(c.pack(bref)); break; - case types::msg_class_ext: + case types::spare1: break; default: - log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c"); + log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE dl_ccch_msg_type_nb_c::unpack(cbit_ref& bref) +SRSASN_CODE ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::c1: + case types::ue_cap_enquiry_r13: HANDLE_CODE(c.unpack(bref)); break; - case types::msg_class_ext: + case types::spare1: break; default: - log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c"); + log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void dl_ccch_msg_type_nb_c::c1_c_::destroy_() -{ - switch (type_) { - case types::rrc_conn_reest_r13: - c.destroy(); - break; - case types::rrc_conn_reest_reject_r13: - c.destroy(); - break; - case types::rrc_conn_reject_r13: - c.destroy(); - break; - case types::rrc_conn_setup_r13: - c.destroy(); - break; - case types::rrc_early_data_complete_r15: - c.destroy(); - break; - default: - break; - } -} -void dl_ccch_msg_type_nb_c::c1_c_::set(types::options e) -{ - destroy_(); - type_ = e; - switch (type_) { - case types::rrc_conn_reest_r13: - c.init(); - break; - case types::rrc_conn_reest_reject_r13: - c.init(); - break; - case types::rrc_conn_reject_r13: - c.init(); - break; - case types::rrc_conn_setup_r13: - c.init(); - break; - case types::rrc_early_data_complete_r15: - c.init(); - break; - case types::spare3: - break; - case types::spare2: - break; - case types::spare1: - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); - } -} -dl_ccch_msg_type_nb_c::c1_c_::c1_c_(const dl_ccch_msg_type_nb_c::c1_c_& other) +const char* ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const { - type_ = other.type(); - switch (type_) { - case types::rrc_conn_reest_r13: - c.init(other.c.get()); - break; - case types::rrc_conn_reest_reject_r13: - c.init(other.c.get()); - break; - case types::rrc_conn_reject_r13: - c.init(other.c.get()); - break; - case types::rrc_conn_setup_r13: - c.init(other.c.get()); - break; - case types::rrc_early_data_complete_r15: - c.init(other.c.get()); - break; - case types::spare3: - break; - case types::spare2: - break; - case types::spare1: - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); - } + static const char* options[] = {"ueCapabilityEnquiry-r13", "spare1"}; + return convert_enum_idx(options, 2, value, "ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::types"); } -dl_ccch_msg_type_nb_c::c1_c_& dl_ccch_msg_type_nb_c::c1_c_::operator=(const dl_ccch_msg_type_nb_c::c1_c_& other) -{ - if (this == &other) { - return *this; - } - set(other.type()); - switch (type_) { - case types::rrc_conn_reest_r13: - c.set(other.c.get()); - break; - case types::rrc_conn_reest_reject_r13: - c.set(other.c.get()); - break; - case types::rrc_conn_reject_r13: - c.set(other.c.get()); - break; - case types::rrc_conn_setup_r13: - c.set(other.c.get()); - break; - case types::rrc_early_data_complete_r15: - c.set(other.c.get()); - break; - case types::spare3: - break; - case types::spare2: - break; - case types::spare1: - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); - } - return *this; -} -rrc_conn_reest_nb_s& dl_ccch_msg_type_nb_c::c1_c_::set_rrc_conn_reest_r13() -{ - set(types::rrc_conn_reest_r13); - return c.get(); -} -rrc_conn_reest_reject_s& dl_ccch_msg_type_nb_c::c1_c_::set_rrc_conn_reest_reject_r13() -{ - set(types::rrc_conn_reest_reject_r13); - return c.get(); -} -rrc_conn_reject_nb_s& dl_ccch_msg_type_nb_c::c1_c_::set_rrc_conn_reject_r13() +// UEInformationRequest-NB-r16 ::= SEQUENCE +SRSASN_CODE ue_info_request_nb_r16_s::pack(bit_ref& bref) const { - set(types::rrc_conn_reject_r13); - return c.get(); + HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; } -rrc_conn_setup_nb_s& dl_ccch_msg_type_nb_c::c1_c_::set_rrc_conn_setup_r13() +SRSASN_CODE ue_info_request_nb_r16_s::unpack(cbit_ref& bref) { - set(types::rrc_conn_setup_r13); - return c.get(); + HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; } -rrc_early_data_complete_nb_r15_s& dl_ccch_msg_type_nb_c::c1_c_::set_rrc_early_data_complete_r15() +void ue_info_request_nb_r16_s::to_json(json_writer& j) const { - set(types::rrc_early_data_complete_r15); - return c.get(); + j.start_obj(); + j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); } -void dl_ccch_msg_type_nb_c::c1_c_::set_spare3() + +void ue_info_request_nb_r16_s::crit_exts_c_::set(types::options e) { - set(types::spare3); + type_ = e; } -void dl_ccch_msg_type_nb_c::c1_c_::set_spare2() +ue_info_request_nb_r16_ies_s& ue_info_request_nb_r16_s::crit_exts_c_::set_ue_info_request_r16() { - set(types::spare2); + set(types::ue_info_request_r16); + return c; } -void dl_ccch_msg_type_nb_c::c1_c_::set_spare1() +void ue_info_request_nb_r16_s::crit_exts_c_::set_crit_exts_future() { - set(types::spare1); + set(types::crit_exts_future); } -void dl_ccch_msg_type_nb_c::c1_c_::to_json(json_writer& j) const +void ue_info_request_nb_r16_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_conn_reest_r13: - j.write_fieldname("rrcConnectionReestablishment-r13"); - c.get().to_json(j); - break; - case types::rrc_conn_reest_reject_r13: - j.write_fieldname("rrcConnectionReestablishmentReject-r13"); - c.get().to_json(j); - break; - case types::rrc_conn_reject_r13: - j.write_fieldname("rrcConnectionReject-r13"); - c.get().to_json(j); - break; - case types::rrc_conn_setup_r13: - j.write_fieldname("rrcConnectionSetup-r13"); - c.get().to_json(j); - break; - case types::rrc_early_data_complete_r15: - j.write_fieldname("rrcEarlyDataComplete-r15"); - c.get().to_json(j); - break; - case types::spare3: - break; - case types::spare2: + case types::ue_info_request_r16: + j.write_fieldname("ueInformationRequest-r16"); + c.to_json(j); break; - case types::spare1: + case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); + log_invalid_choice_id(type_, "ue_info_request_nb_r16_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE dl_ccch_msg_type_nb_c::c1_c_::pack(bit_ref& bref) const +SRSASN_CODE ue_info_request_nb_r16_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_conn_reest_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::rrc_conn_reest_reject_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::rrc_conn_reject_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::rrc_conn_setup_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::rrc_early_data_complete_r15: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::spare3: - break; - case types::spare2: + case types::ue_info_request_r16: + HANDLE_CODE(c.pack(bref)); break; - case types::spare1: + case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); + log_invalid_choice_id(type_, "ue_info_request_nb_r16_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE dl_ccch_msg_type_nb_c::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE ue_info_request_nb_r16_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_conn_reest_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::rrc_conn_reest_reject_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::rrc_conn_reject_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::rrc_conn_setup_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::rrc_early_data_complete_r15: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::spare3: - break; - case types::spare2: + case types::ue_info_request_r16: + HANDLE_CODE(c.unpack(bref)); break; - case types::spare1: + case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "dl_ccch_msg_type_nb_c::c1_c_"); + log_invalid_choice_id(type_, "ue_info_request_nb_r16_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* dl_ccch_msg_type_nb_c::c1_c_::types_opts::to_string() const +const char* ue_info_request_nb_r16_s::crit_exts_c_::types_opts::to_string() const { - static const char* options[] = {"rrcConnectionReestablishment-r13", - "rrcConnectionReestablishmentReject-r13", - "rrcConnectionReject-r13", - "rrcConnectionSetup-r13", - "rrcEarlyDataComplete-r15", - "spare3", - "spare2", - "spare1"}; - return convert_enum_idx(options, 8, value, "dl_ccch_msg_type_nb_c::c1_c_::types"); + static const char* options[] = {"ueInformationRequest-r16", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "ue_info_request_nb_r16_s::crit_exts_c_::types"); } -const char* dl_ccch_msg_type_nb_c::types_opts::to_string() const -{ - static const char* options[] = {"c1", "messageClassExtension"}; - return convert_enum_idx(options, 2, value, "dl_ccch_msg_type_nb_c::types"); -} -uint8_t dl_ccch_msg_type_nb_c::types_opts::to_number() const +// DL-DCCH-MessageType-NB ::= CHOICE +void dl_dcch_msg_type_nb_c::set(types::options e) { - static const uint8_t options[] = {1}; - return map_enum_number(options, 1, value, "dl_ccch_msg_type_nb_c::types"); + type_ = e; } - -// DL-CCCH-Message-NB ::= SEQUENCE -SRSASN_CODE dl_ccch_msg_nb_s::pack(bit_ref& bref) const +dl_dcch_msg_type_nb_c::c1_c_& dl_dcch_msg_type_nb_c::set_c1() { - HANDLE_CODE(msg.pack(bref)); - - bref.align_bytes_zero(); - - return SRSASN_SUCCESS; + set(types::c1); + return c; } -SRSASN_CODE dl_ccch_msg_nb_s::unpack(cbit_ref& bref) +void dl_dcch_msg_type_nb_c::set_msg_class_ext() { - HANDLE_CODE(msg.unpack(bref)); - - bref.align_bytes(); - - return SRSASN_SUCCESS; + set(types::msg_class_ext); } -void dl_ccch_msg_nb_s::to_json(json_writer& j) const +void dl_dcch_msg_type_nb_c::to_json(json_writer& j) const { - j.start_array(); j.start_obj(); - j.start_obj("DL-CCCH-Message-NB"); - j.write_fieldname("message"); - msg.to_json(j); - j.end_obj(); + switch (type_) { + case types::c1: + j.write_fieldname("c1"); + c.to_json(j); + break; + case types::msg_class_ext: + break; + default: + log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c"); + } j.end_obj(); - j.end_array(); } - -// RRCConnectionRelease-NB-v15b0-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_release_nb_v15b0_ies_s::pack(bit_ref& bref) const +SRSASN_CODE dl_dcch_msg_type_nb_c::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(no_last_cell_upd_r15_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - + type_.pack(bref); + switch (type_) { + case types::c1: + HANDLE_CODE(c.pack(bref)); + break; + case types::msg_class_ext: + break; + default: + log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c"); + return SRSASN_ERROR_ENCODE_FAIL; + } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_release_nb_v15b0_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE dl_dcch_msg_type_nb_c::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(no_last_cell_upd_r15_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::c1: + HANDLE_CODE(c.unpack(bref)); + break; + case types::msg_class_ext: + break; + default: + log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c"); + return SRSASN_ERROR_DECODE_FAIL; + } return SRSASN_SUCCESS; } -void rrc_conn_release_nb_v15b0_ies_s::to_json(json_writer& j) const + +void dl_dcch_msg_type_nb_c::c1_c_::destroy_() { - j.start_obj(); - if (no_last_cell_upd_r15_present) { - j.write_str("noLastCellUpdate-r15", "true"); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + switch (type_) { + case types::dl_info_transfer_r13: + c.destroy(); + break; + case types::rrc_conn_recfg_r13: + c.destroy(); + break; + case types::rrc_conn_release_r13: + c.destroy(); + break; + case types::security_mode_cmd_r13: + c.destroy(); + break; + case types::ue_cap_enquiry_r13: + c.destroy(); + break; + case types::rrc_conn_resume_r13: + c.destroy(); + break; + case types::ue_info_request_r16: + c.destroy(); + break; + default: + break; } - j.end_obj(); } - -// RRCConnectionRelease-NB-v1550-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_release_nb_v1550_ies_s::pack(bit_ref& bref) const +void dl_dcch_msg_type_nb_c::c1_c_::set(types::options e) { - HANDLE_CODE(bref.pack(redirected_carrier_info_v1550_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - if (redirected_carrier_info_v1550_present) { - HANDLE_CODE(redirected_carrier_info_v1550.pack(bref)); + destroy_(); + type_ = e; + switch (type_) { + case types::dl_info_transfer_r13: + c.init(); + break; + case types::rrc_conn_recfg_r13: + c.init(); + break; + case types::rrc_conn_release_r13: + c.init(); + break; + case types::security_mode_cmd_r13: + c.init(); + break; + case types::ue_cap_enquiry_r13: + c.init(); + break; + case types::rrc_conn_resume_r13: + c.init(); + break; + case types::ue_info_request_r16: + c.init(); + break; + case types::spare1: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); +} +dl_dcch_msg_type_nb_c::c1_c_::c1_c_(const dl_dcch_msg_type_nb_c::c1_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::dl_info_transfer_r13: + c.init(other.c.get()); + break; + case types::rrc_conn_recfg_r13: + c.init(other.c.get()); + break; + case types::rrc_conn_release_r13: + c.init(other.c.get()); + break; + case types::security_mode_cmd_r13: + c.init(other.c.get()); + break; + case types::ue_cap_enquiry_r13: + c.init(other.c.get()); + break; + case types::rrc_conn_resume_r13: + c.init(other.c.get()); + break; + case types::ue_info_request_r16: + c.init(other.c.get()); + break; + case types::spare1: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); } - - return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_release_nb_v1550_ies_s::unpack(cbit_ref& bref) +dl_dcch_msg_type_nb_c::c1_c_& dl_dcch_msg_type_nb_c::c1_c_::operator=(const dl_dcch_msg_type_nb_c::c1_c_& other) { - HANDLE_CODE(bref.unpack(redirected_carrier_info_v1550_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - if (redirected_carrier_info_v1550_present) { - HANDLE_CODE(redirected_carrier_info_v1550.unpack(bref)); + if (this == &other) { + return *this; } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); + set(other.type()); + switch (type_) { + case types::dl_info_transfer_r13: + c.set(other.c.get()); + break; + case types::rrc_conn_recfg_r13: + c.set(other.c.get()); + break; + case types::rrc_conn_release_r13: + c.set(other.c.get()); + break; + case types::security_mode_cmd_r13: + c.set(other.c.get()); + break; + case types::ue_cap_enquiry_r13: + c.set(other.c.get()); + break; + case types::rrc_conn_resume_r13: + c.set(other.c.get()); + break; + case types::ue_info_request_r16: + c.set(other.c.get()); + break; + case types::spare1: + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); } - return SRSASN_SUCCESS; + return *this; } -void rrc_conn_release_nb_v1550_ies_s::to_json(json_writer& j) const +dl_info_transfer_nb_s& dl_dcch_msg_type_nb_c::c1_c_::set_dl_info_transfer_r13() { - j.start_obj(); - if (redirected_carrier_info_v1550_present) { - j.write_fieldname("redirectedCarrierInfo-v1550"); - redirected_carrier_info_v1550.to_json(j); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); - } - j.end_obj(); + set(types::dl_info_transfer_r13); + return c.get(); } - -// RRCConnectionRelease-NB-v1530-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_release_nb_v1530_ies_s::pack(bit_ref& bref) const +rrc_conn_recfg_nb_s& dl_dcch_msg_type_nb_c::c1_c_::set_rrc_conn_recfg_r13() { - HANDLE_CODE(bref.pack(drb_continue_rohc_r15_present, 1)); - HANDLE_CODE(bref.pack(next_hop_chaining_count_r15_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - if (next_hop_chaining_count_r15_present) { - HANDLE_CODE(pack_integer(bref, next_hop_chaining_count_r15, (uint8_t)0u, (uint8_t)7u)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); - } - - return SRSASN_SUCCESS; + set(types::rrc_conn_recfg_r13); + return c.get(); } -SRSASN_CODE rrc_conn_release_nb_v1530_ies_s::unpack(cbit_ref& bref) +rrc_conn_release_nb_s& dl_dcch_msg_type_nb_c::c1_c_::set_rrc_conn_release_r13() { - HANDLE_CODE(bref.unpack(drb_continue_rohc_r15_present, 1)); - HANDLE_CODE(bref.unpack(next_hop_chaining_count_r15_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - if (next_hop_chaining_count_r15_present) { - HANDLE_CODE(unpack_integer(next_hop_chaining_count_r15, bref, (uint8_t)0u, (uint8_t)7u)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); - } - - return SRSASN_SUCCESS; + set(types::rrc_conn_release_r13); + return c.get(); } -void rrc_conn_release_nb_v1530_ies_s::to_json(json_writer& j) const +security_mode_cmd_s& dl_dcch_msg_type_nb_c::c1_c_::set_security_mode_cmd_r13() { - j.start_obj(); - if (drb_continue_rohc_r15_present) { - j.write_str("drb-ContinueROHC-r15", "true"); - } - if (next_hop_chaining_count_r15_present) { - j.write_int("nextHopChainingCount-r15", next_hop_chaining_count_r15); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); - } - j.end_obj(); + set(types::security_mode_cmd_r13); + return c.get(); } - -// RRCConnectionRelease-NB-v1430-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_release_nb_v1430_ies_s::pack(bit_ref& bref) const +ue_cap_enquiry_nb_s& dl_dcch_msg_type_nb_c::c1_c_::set_ue_cap_enquiry_r13() { - HANDLE_CODE(bref.pack(redirected_carrier_info_v1430_present, 1)); - HANDLE_CODE(bref.pack(extended_wait_time_cpdata_r14_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - if (redirected_carrier_info_v1430_present) { - HANDLE_CODE(redirected_carrier_info_v1430.pack(bref)); - } - if (extended_wait_time_cpdata_r14_present) { - HANDLE_CODE(pack_integer(bref, extended_wait_time_cpdata_r14, (uint16_t)1u, (uint16_t)1800u)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); - } - - return SRSASN_SUCCESS; + set(types::ue_cap_enquiry_r13); + return c.get(); } -SRSASN_CODE rrc_conn_release_nb_v1430_ies_s::unpack(cbit_ref& bref) +rrc_conn_resume_nb_s& dl_dcch_msg_type_nb_c::c1_c_::set_rrc_conn_resume_r13() { - HANDLE_CODE(bref.unpack(redirected_carrier_info_v1430_present, 1)); - HANDLE_CODE(bref.unpack(extended_wait_time_cpdata_r14_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - if (redirected_carrier_info_v1430_present) { - HANDLE_CODE(redirected_carrier_info_v1430.unpack(bref)); - } - if (extended_wait_time_cpdata_r14_present) { - HANDLE_CODE(unpack_integer(extended_wait_time_cpdata_r14, bref, (uint16_t)1u, (uint16_t)1800u)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); - } - - return SRSASN_SUCCESS; + set(types::rrc_conn_resume_r13); + return c.get(); } -void rrc_conn_release_nb_v1430_ies_s::to_json(json_writer& j) const +ue_info_request_nb_r16_s& dl_dcch_msg_type_nb_c::c1_c_::set_ue_info_request_r16() { - j.start_obj(); - if (redirected_carrier_info_v1430_present) { - j.write_fieldname("redirectedCarrierInfo-v1430"); - redirected_carrier_info_v1430.to_json(j); - } - if (extended_wait_time_cpdata_r14_present) { - j.write_int("extendedWaitTime-CPdata-r14", extended_wait_time_cpdata_r14); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); - } - j.end_obj(); + set(types::ue_info_request_r16); + return c.get(); } - -// ReleaseCause-NB-r13 ::= ENUMERATED -const char* release_cause_nb_r13_opts::to_string() const +void dl_dcch_msg_type_nb_c::c1_c_::set_spare1() { - static const char* options[] = {"loadBalancingTAUrequired", "other", "rrc-Suspend", "spare1"}; - return convert_enum_idx(options, 4, value, "release_cause_nb_r13_e"); + set(types::spare1); } - -// DLInformationTransfer-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE dl_info_transfer_nb_r13_ies_s::pack(bit_ref& bref) const +void dl_dcch_msg_type_nb_c::c1_c_::to_json(json_writer& j) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - HANDLE_CODE(ded_info_nas_r13.pack(bref)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); + j.start_obj(); + switch (type_) { + case types::dl_info_transfer_r13: + j.write_fieldname("dlInformationTransfer-r13"); + c.get().to_json(j); + break; + case types::rrc_conn_recfg_r13: + j.write_fieldname("rrcConnectionReconfiguration-r13"); + c.get().to_json(j); + break; + case types::rrc_conn_release_r13: + j.write_fieldname("rrcConnectionRelease-r13"); + c.get().to_json(j); + break; + case types::security_mode_cmd_r13: + j.write_fieldname("securityModeCommand-r13"); + c.get().to_json(j); + break; + case types::ue_cap_enquiry_r13: + j.write_fieldname("ueCapabilityEnquiry-r13"); + c.get().to_json(j); + break; + case types::rrc_conn_resume_r13: + j.write_fieldname("rrcConnectionResume-r13"); + c.get().to_json(j); + break; + case types::ue_info_request_r16: + j.write_fieldname("ueInformationRequest-r16"); + c.get().to_json(j); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); } - - return SRSASN_SUCCESS; + j.end_obj(); } -SRSASN_CODE dl_info_transfer_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE dl_dcch_msg_type_nb_c::c1_c_::pack(bit_ref& bref) const { - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - HANDLE_CODE(ded_info_nas_r13.unpack(bref)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + type_.pack(bref); + switch (type_) { + case types::dl_info_transfer_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::rrc_conn_recfg_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::rrc_conn_release_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::security_mode_cmd_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ue_cap_enquiry_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::rrc_conn_resume_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::ue_info_request_r16: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); + return SRSASN_ERROR_ENCODE_FAIL; } - return SRSASN_SUCCESS; } -void dl_info_transfer_nb_r13_ies_s::to_json(json_writer& j) const +SRSASN_CODE dl_dcch_msg_type_nb_c::c1_c_::unpack(cbit_ref& bref) { - j.start_obj(); - j.write_str("dedicatedInfoNAS-r13", ded_info_nas_r13.to_string()); - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::dl_info_transfer_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::rrc_conn_recfg_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::rrc_conn_release_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::security_mode_cmd_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ue_cap_enquiry_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::rrc_conn_resume_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::ue_info_request_r16: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::spare1: + break; + default: + log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); + return SRSASN_ERROR_DECODE_FAIL; } - j.end_obj(); + return SRSASN_SUCCESS; } -// RRCConnectionReconfiguration-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_recfg_nb_r13_ies_s::pack(bit_ref& bref) const +const char* dl_dcch_msg_type_nb_c::c1_c_::types_opts::to_string() const { - HANDLE_CODE(bref.pack(ded_info_nas_list_r13_present, 1)); - HANDLE_CODE(bref.pack(rr_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.pack(full_cfg_r13_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - if (ded_info_nas_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, ded_info_nas_list_r13, 1, 2)); - } - if (rr_cfg_ded_r13_present) { - HANDLE_CODE(rr_cfg_ded_r13.pack(bref)); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); - } - - return SRSASN_SUCCESS; + static const char* options[] = {"dlInformationTransfer-r13", + "rrcConnectionReconfiguration-r13", + "rrcConnectionRelease-r13", + "securityModeCommand-r13", + "ueCapabilityEnquiry-r13", + "rrcConnectionResume-r13", + "ueInformationRequest-r16", + "spare1"}; + return convert_enum_idx(options, 8, value, "dl_dcch_msg_type_nb_c::c1_c_::types"); } -SRSASN_CODE rrc_conn_recfg_nb_r13_ies_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(bref.unpack(ded_info_nas_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(rr_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.unpack(full_cfg_r13_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - if (ded_info_nas_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(ded_info_nas_list_r13, bref, 1, 2)); - } - if (rr_cfg_ded_r13_present) { - HANDLE_CODE(rr_cfg_ded_r13.unpack(bref)); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); - } - return SRSASN_SUCCESS; +const char* dl_dcch_msg_type_nb_c::types_opts::to_string() const +{ + static const char* options[] = {"c1", "messageClassExtension"}; + return convert_enum_idx(options, 2, value, "dl_dcch_msg_type_nb_c::types"); } -void rrc_conn_recfg_nb_r13_ies_s::to_json(json_writer& j) const +uint8_t dl_dcch_msg_type_nb_c::types_opts::to_number() const { - j.start_obj(); - if (ded_info_nas_list_r13_present) { - j.start_array("dedicatedInfoNASList-r13"); - for (const auto& e1 : ded_info_nas_list_r13) { - j.write_str(e1.to_string()); - } - j.end_array(); - } - if (rr_cfg_ded_r13_present) { - j.write_fieldname("radioResourceConfigDedicated-r13"); - rr_cfg_ded_r13.to_json(j); - } - if (full_cfg_r13_present) { - j.write_str("fullConfig-r13", "true"); - } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); - } - j.end_obj(); + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "dl_dcch_msg_type_nb_c::types"); } -// RRCConnectionRelease-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_release_nb_r13_ies_s::pack(bit_ref& bref) const +// DL-DCCH-Message-NB ::= SEQUENCE +SRSASN_CODE dl_dcch_msg_nb_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(resume_id_r13_present, 1)); - HANDLE_CODE(bref.pack(extended_wait_time_r13_present, 1)); - HANDLE_CODE(bref.pack(redirected_carrier_info_r13_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + HANDLE_CODE(msg.pack(bref)); - HANDLE_CODE(release_cause_r13.pack(bref)); - if (resume_id_r13_present) { - HANDLE_CODE(resume_id_r13.pack(bref)); - } - if (extended_wait_time_r13_present) { - HANDLE_CODE(pack_integer(bref, extended_wait_time_r13, (uint16_t)1u, (uint16_t)1800u)); - } - if (redirected_carrier_info_r13_present) { - HANDLE_CODE(redirected_carrier_info_r13.pack(bref)); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); - } + bref.align_bytes_zero(); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_release_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE dl_dcch_msg_nb_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(resume_id_r13_present, 1)); - HANDLE_CODE(bref.unpack(extended_wait_time_r13_present, 1)); - HANDLE_CODE(bref.unpack(redirected_carrier_info_r13_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + HANDLE_CODE(msg.unpack(bref)); - HANDLE_CODE(release_cause_r13.unpack(bref)); - if (resume_id_r13_present) { - HANDLE_CODE(resume_id_r13.unpack(bref)); - } - if (extended_wait_time_r13_present) { - HANDLE_CODE(unpack_integer(extended_wait_time_r13, bref, (uint16_t)1u, (uint16_t)1800u)); - } - if (redirected_carrier_info_r13_present) { - HANDLE_CODE(redirected_carrier_info_r13.unpack(bref)); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); - } + bref.align_bytes(); return SRSASN_SUCCESS; } -void rrc_conn_release_nb_r13_ies_s::to_json(json_writer& j) const +void dl_dcch_msg_nb_s::to_json(json_writer& j) const { + j.start_array(); j.start_obj(); - j.write_str("releaseCause-r13", release_cause_r13.to_string()); - if (resume_id_r13_present) { - j.write_str("resumeIdentity-r13", resume_id_r13.to_string()); - } - if (extended_wait_time_r13_present) { - j.write_int("extendedWaitTime-r13", extended_wait_time_r13); - } - if (redirected_carrier_info_r13_present) { - j.write_fieldname("redirectedCarrierInfo-r13"); - redirected_carrier_info_r13.to_json(j); - } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); - } + j.start_obj("DL-DCCH-Message-NB"); + j.write_fieldname("message"); + msg.to_json(j); j.end_obj(); + j.end_obj(); + j.end_array(); } -// RRCConnectionResume-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_resume_nb_r13_ies_s::pack(bit_ref& bref) const +// SupportedBand-NB-r13 ::= SEQUENCE +SRSASN_CODE supported_band_nb_r13_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(rr_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.pack(drb_continue_rohc_r13_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(pwr_class_nb_minus20dbm_r13_present, 1)); - if (rr_cfg_ded_r13_present) { - HANDLE_CODE(rr_cfg_ded_r13.pack(bref)); - } - HANDLE_CODE(pack_integer(bref, next_hop_chaining_count_r13, (uint8_t)0u, (uint8_t)7u)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); - } + HANDLE_CODE(pack_integer(bref, band_r13, (uint16_t)1u, (uint16_t)256u)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_resume_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE supported_band_nb_r13_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(rr_cfg_ded_r13_present, 1)); - HANDLE_CODE(bref.unpack(drb_continue_rohc_r13_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(pwr_class_nb_minus20dbm_r13_present, 1)); - if (rr_cfg_ded_r13_present) { - HANDLE_CODE(rr_cfg_ded_r13.unpack(bref)); - } - HANDLE_CODE(unpack_integer(next_hop_chaining_count_r13, bref, (uint8_t)0u, (uint8_t)7u)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); - } + HANDLE_CODE(unpack_integer(band_r13, bref, (uint16_t)1u, (uint16_t)256u)); return SRSASN_SUCCESS; } -void rrc_conn_resume_nb_r13_ies_s::to_json(json_writer& j) const +void supported_band_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - if (rr_cfg_ded_r13_present) { - j.write_fieldname("radioResourceConfigDedicated-r13"); - rr_cfg_ded_r13.to_json(j); - } - j.write_int("nextHopChainingCount-r13", next_hop_chaining_count_r13); - if (drb_continue_rohc_r13_present) { - j.write_str("drb-ContinueROHC-r13", "true"); - } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + j.write_int("band-r13", band_r13); + if (pwr_class_nb_minus20dbm_r13_present) { + j.write_str("powerClassNB-20dBm-r13", "supported"); } j.end_obj(); } -// UECapabilityEnquiry-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE ue_cap_enquiry_nb_r13_ies_s::pack(bit_ref& bref) const +// AccessStratumRelease-NB-r13 ::= ENUMERATED +const char* access_stratum_release_nb_r13_opts::to_string() const +{ + static const char* options[] = {"rel13", "rel14", "rel15", "rel16", "rel17", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 8, value, "access_stratum_release_nb_r13_e"); +} +uint8_t access_stratum_release_nb_r13_opts::to_number() const +{ + static const uint8_t options[] = {13, 14, 15, 16, 17}; + return map_enum_number(options, 5, value, "access_stratum_release_nb_r13_e"); +} + +// HandoverPreparationInformation-NB-Ext-r14-IEs ::= SEQUENCE +SRSASN_CODE ho_prep_info_nb_ext_r14_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(ue_radio_access_cap_info_ext_r14_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); + if (ue_radio_access_cap_info_ext_r14_present) { + HANDLE_CODE(ue_radio_access_cap_info_ext_r14.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE ue_cap_enquiry_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE ho_prep_info_nb_ext_r14_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(ue_radio_access_cap_info_ext_r14_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + if (ue_radio_access_cap_info_ext_r14_present) { + HANDLE_CODE(ue_radio_access_cap_info_ext_r14.unpack(bref)); } return SRSASN_SUCCESS; } -void ue_cap_enquiry_nb_r13_ies_s::to_json(json_writer& j) const +void ho_prep_info_nb_ext_r14_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + if (ue_radio_access_cap_info_ext_r14_present) { + j.write_str("ue-RadioAccessCapabilityInfoExt-r14", ue_radio_access_cap_info_ext_r14.to_string()); } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); @@ -14096,348 +20085,375 @@ void ue_cap_enquiry_nb_r13_ies_s::to_json(json_writer& j) const j.end_obj(); } -// DLInformationTransfer-NB ::= SEQUENCE -SRSASN_CODE dl_info_transfer_nb_s::pack(bit_ref& bref) const +// PDCP-Parameters-NB-r13 ::= SEQUENCE +SRSASN_CODE pdcp_params_nb_r13_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.pack(bref)); + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(max_num_rohc_context_sessions_r13_present, 1)); + + HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0002, 1)); + HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0003, 1)); + HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0004, 1)); + HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0006, 1)); + HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0102, 1)); + HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0103, 1)); + HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0104, 1)); + if (max_num_rohc_context_sessions_r13_present) { + HANDLE_CODE(max_num_rohc_context_sessions_r13.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE dl_info_transfer_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE pdcp_params_nb_r13_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.unpack(bref)); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(max_num_rohc_context_sessions_r13_present, 1)); + + HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0002, 1)); + HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0003, 1)); + HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0004, 1)); + HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0006, 1)); + HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0102, 1)); + HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0103, 1)); + HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0104, 1)); + if (max_num_rohc_context_sessions_r13_present) { + HANDLE_CODE(max_num_rohc_context_sessions_r13.unpack(bref)); + } return SRSASN_SUCCESS; } -void dl_info_transfer_nb_s::to_json(json_writer& j) const +void pdcp_params_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); - j.write_fieldname("criticalExtensions"); - crit_exts.to_json(j); + j.write_fieldname("supportedROHC-Profiles-r13"); + j.start_obj(); + j.write_bool("profile0x0002", supported_rohc_profiles_r13.profile0x0002); + j.write_bool("profile0x0003", supported_rohc_profiles_r13.profile0x0003); + j.write_bool("profile0x0004", supported_rohc_profiles_r13.profile0x0004); + j.write_bool("profile0x0006", supported_rohc_profiles_r13.profile0x0006); + j.write_bool("profile0x0102", supported_rohc_profiles_r13.profile0x0102); + j.write_bool("profile0x0103", supported_rohc_profiles_r13.profile0x0103); + j.write_bool("profile0x0104", supported_rohc_profiles_r13.profile0x0104); + j.end_obj(); + if (max_num_rohc_context_sessions_r13_present) { + j.write_str("maxNumberROHC-ContextSessions-r13", max_num_rohc_context_sessions_r13.to_string()); + } j.end_obj(); } -void dl_info_transfer_nb_s::crit_exts_c_::set(types::options e) -{ - type_ = e; -} -dl_info_transfer_nb_s::crit_exts_c_::c1_c_& dl_info_transfer_nb_s::crit_exts_c_::set_c1() +const char* pdcp_params_nb_r13_s::max_num_rohc_context_sessions_r13_opts::to_string() const { - set(types::c1); - return c; + static const char* options[] = {"cs2", "cs4", "cs8", "cs12"}; + return convert_enum_idx(options, 4, value, "pdcp_params_nb_r13_s::max_num_rohc_context_sessions_r13_e_"); } -void dl_info_transfer_nb_s::crit_exts_c_::set_crit_exts_future() +uint8_t pdcp_params_nb_r13_s::max_num_rohc_context_sessions_r13_opts::to_number() const { - set(types::crit_exts_future); + static const uint8_t options[] = {2, 4, 8, 12}; + return map_enum_number(options, 4, value, "pdcp_params_nb_r13_s::max_num_rohc_context_sessions_r13_e_"); } -void dl_info_transfer_nb_s::crit_exts_c_::to_json(json_writer& j) const + +// PhyLayerParameters-NB-r13 ::= SEQUENCE +SRSASN_CODE phy_layer_params_nb_r13_s::pack(bit_ref& bref) const { - j.start_obj(); - switch (type_) { - case types::c1: - j.write_fieldname("c1"); - c.to_json(j); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_"); - } - j.end_obj(); + HANDLE_CODE(bref.pack(multi_tone_r13_present, 1)); + HANDLE_CODE(bref.pack(multi_carrier_r13_present, 1)); + + return SRSASN_SUCCESS; } -SRSASN_CODE dl_info_transfer_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE phy_layer_params_nb_r13_s::unpack(cbit_ref& bref) { - type_.pack(bref); - switch (type_) { - case types::c1: - HANDLE_CODE(c.pack(bref)); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_"); - return SRSASN_ERROR_ENCODE_FAIL; - } + HANDLE_CODE(bref.unpack(multi_tone_r13_present, 1)); + HANDLE_CODE(bref.unpack(multi_carrier_r13_present, 1)); + return SRSASN_SUCCESS; } -SRSASN_CODE dl_info_transfer_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +void phy_layer_params_nb_r13_s::to_json(json_writer& j) const { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::c1: - HANDLE_CODE(c.unpack(bref)); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_"); - return SRSASN_ERROR_DECODE_FAIL; + j.start_obj(); + if (multi_tone_r13_present) { + j.write_str("multiTone-r13", "supported"); } - return SRSASN_SUCCESS; + if (multi_carrier_r13_present) { + j.write_str("multiCarrier-r13", "supported"); + } + j.end_obj(); } -void dl_info_transfer_nb_s::crit_exts_c_::c1_c_::set(types::options e) -{ - type_ = e; -} -dl_info_transfer_nb_r13_ies_s& dl_info_transfer_nb_s::crit_exts_c_::c1_c_::set_dl_info_transfer_r13() +// RF-Parameters-NB-r13 ::= SEQUENCE +SRSASN_CODE rf_params_nb_r13_s::pack(bit_ref& bref) const { - set(types::dl_info_transfer_r13); - return c; + HANDLE_CODE(bref.pack(multi_ns_pmax_r13_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_list_r13, 1, 64)); + + return SRSASN_SUCCESS; } -void dl_info_transfer_nb_s::crit_exts_c_::c1_c_::set_spare1() +SRSASN_CODE rf_params_nb_r13_s::unpack(cbit_ref& bref) { - set(types::spare1); + HANDLE_CODE(bref.unpack(multi_ns_pmax_r13_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(supported_band_list_r13, bref, 1, 64)); + + return SRSASN_SUCCESS; } -void dl_info_transfer_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +void rf_params_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::dl_info_transfer_r13: - j.write_fieldname("dlInformationTransfer-r13"); - c.to_json(j); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_::c1_c_"); + j.start_array("supportedBandList-r13"); + for (const auto& e1 : supported_band_list_r13) { + e1.to_json(j); + } + j.end_array(); + if (multi_ns_pmax_r13_present) { + j.write_str("multiNS-Pmax-r13", "supported"); } j.end_obj(); } -SRSASN_CODE dl_info_transfer_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const + +// HandoverPreparationInformation-NB-v1380-IEs ::= SEQUENCE +SRSASN_CODE ho_prep_info_nb_v1380_ies_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::dl_info_transfer_r13: - HANDLE_CODE(c.pack(bref)); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_::c1_c_"); - return SRSASN_ERROR_ENCODE_FAIL; + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); } + return SRSASN_SUCCESS; } -SRSASN_CODE dl_info_transfer_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE ho_prep_info_nb_v1380_ies_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::dl_info_transfer_r13: - HANDLE_CODE(c.unpack(bref)); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "dl_info_transfer_nb_s::crit_exts_c_::c1_c_"); - return SRSASN_ERROR_DECODE_FAIL; + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ho_prep_info_nb_v1380_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); } - return SRSASN_SUCCESS; + j.end_obj(); } -const char* dl_info_transfer_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const +// RRM-Config-NB ::= SEQUENCE +SRSASN_CODE rrm_cfg_nb_s::pack(bit_ref& bref) const { - static const char* options[] = {"dlInformationTransfer-r13", "spare1"}; - return convert_enum_idx(options, 2, value, "dl_info_transfer_nb_s::crit_exts_c_::c1_c_::types"); -} + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ue_inactive_time_present, 1)); -// RRCConnectionReconfiguration-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_recfg_nb_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.pack(bref)); + if (ue_inactive_time_present) { + HANDLE_CODE(ue_inactive_time.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_recfg_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rrm_cfg_nb_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.unpack(bref)); + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ue_inactive_time_present, 1)); + + if (ue_inactive_time_present) { + HANDLE_CODE(ue_inactive_time.unpack(bref)); + } return SRSASN_SUCCESS; } -void rrc_conn_recfg_nb_s::to_json(json_writer& j) const +void rrm_cfg_nb_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); - j.write_fieldname("criticalExtensions"); - crit_exts.to_json(j); + if (ue_inactive_time_present) { + j.write_str("ue-InactiveTime", ue_inactive_time.to_string()); + } j.end_obj(); } -void rrc_conn_recfg_nb_s::crit_exts_c_::set(types::options e) -{ - type_ = e; -} -rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_& rrc_conn_recfg_nb_s::crit_exts_c_::set_c1() -{ - set(types::c1); - return c; -} -void rrc_conn_recfg_nb_s::crit_exts_c_::set_crit_exts_future() -{ - set(types::crit_exts_future); -} -void rrc_conn_recfg_nb_s::crit_exts_c_::to_json(json_writer& j) const +const char* rrm_cfg_nb_s::ue_inactive_time_opts::to_string() const { - j.start_obj(); - switch (type_) { - case types::c1: - j.write_fieldname("c1"); - c.to_json(j); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_"); - } - j.end_obj(); + static const char* options[] = { + "s1", "s2", "s3", "s5", "s7", "s10", "s15", "s20", "s25", "s30", + "s40", "s50", "min1", "min1s20", "min1s40", "min2", "min2s30", "min3", "min3s30", "min4", + "min5", "min6", "min7", "min8", "min9", "min10", "min12", "min14", "min17", "min20", + "min24", "min28", "min33", "min38", "min44", "min50", "hr1", "hr1min30", "hr2", "hr2min30", + "hr3", "hr3min30", "hr4", "hr5", "hr6", "hr8", "hr10", "hr13", "hr16", "hr20", + "day1", "day1hr12", "day2", "day2hr12", "day3", "day4", "day5", "day7", "day10", "day14", + "day19", "day24", "day30", "dayMoreThan30"}; + return convert_enum_idx(options, 64, value, "rrm_cfg_nb_s::ue_inactive_time_e_"); } -SRSASN_CODE rrc_conn_recfg_nb_s::crit_exts_c_::pack(bit_ref& bref) const + +// UE-Capability-NB-r13 ::= SEQUENCE +SRSASN_CODE ue_cap_nb_r13_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::c1: - HANDLE_CODE(c.pack(bref)); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_"); - return SRSASN_ERROR_ENCODE_FAIL; + HANDLE_CODE(bref.pack(ue_category_nb_r13_present, 1)); + HANDLE_CODE(bref.pack(multiple_drb_r13_present, 1)); + HANDLE_CODE(bref.pack(pdcp_params_r13_present, 1)); + HANDLE_CODE(bref.pack(dummy_present, 1)); + + HANDLE_CODE(access_stratum_release_r13.pack(bref)); + if (pdcp_params_r13_present) { + HANDLE_CODE(pdcp_params_r13.pack(bref)); } + HANDLE_CODE(phy_layer_params_r13.pack(bref)); + HANDLE_CODE(rf_params_r13.pack(bref)); + return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_recfg_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE ue_cap_nb_r13_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::c1: - HANDLE_CODE(c.unpack(bref)); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_"); - return SRSASN_ERROR_DECODE_FAIL; + HANDLE_CODE(bref.unpack(ue_category_nb_r13_present, 1)); + HANDLE_CODE(bref.unpack(multiple_drb_r13_present, 1)); + HANDLE_CODE(bref.unpack(pdcp_params_r13_present, 1)); + HANDLE_CODE(bref.unpack(dummy_present, 1)); + + HANDLE_CODE(access_stratum_release_r13.unpack(bref)); + if (pdcp_params_r13_present) { + HANDLE_CODE(pdcp_params_r13.unpack(bref)); } - return SRSASN_SUCCESS; -} + HANDLE_CODE(phy_layer_params_r13.unpack(bref)); + HANDLE_CODE(rf_params_r13.unpack(bref)); -void rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::set(types::options e) -{ - type_ = e; -} -rrc_conn_recfg_nb_r13_ies_s& rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_recfg_r13() -{ - set(types::rrc_conn_recfg_r13); - return c; -} -void rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::set_spare1() -{ - set(types::spare1); + return SRSASN_SUCCESS; } -void rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +void ue_cap_nb_r13_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::rrc_conn_recfg_r13: - j.write_fieldname("rrcConnectionReconfiguration-r13"); - c.to_json(j); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_"); + j.write_str("accessStratumRelease-r13", access_stratum_release_r13.to_string()); + if (ue_category_nb_r13_present) { + j.write_str("ue-Category-NB-r13", "nb1"); + } + if (multiple_drb_r13_present) { + j.write_str("multipleDRB-r13", "supported"); + } + if (pdcp_params_r13_present) { + j.write_fieldname("pdcp-Parameters-r13"); + pdcp_params_r13.to_json(j); + } + j.write_fieldname("phyLayerParameters-r13"); + phy_layer_params_r13.to_json(j); + j.write_fieldname("rf-Parameters-r13"); + rf_params_r13.to_json(j); + if (dummy_present) { + j.write_fieldname("dummy"); + j.start_obj(); + j.end_obj(); } j.end_obj(); } -SRSASN_CODE rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const + +// HandoverPreparationInformation-NB-IEs ::= SEQUENCE +SRSASN_CODE ho_prep_info_nb_ies_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::rrc_conn_recfg_r13: - HANDLE_CODE(c.pack(bref)); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_"); - return SRSASN_ERROR_ENCODE_FAIL; + HANDLE_CODE(bref.pack(rrm_cfg_r13_present, 1)); + HANDLE_CODE(bref.pack(as_context_r13_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(ue_radio_access_cap_info_r13.pack(bref)); + HANDLE_CODE(as_cfg_r13.pack(bref)); + if (rrm_cfg_r13_present) { + HANDLE_CODE(rrm_cfg_r13.pack(bref)); + } + if (as_context_r13_present) { + HANDLE_CODE(as_context_r13.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); } + return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE ho_prep_info_nb_ies_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::rrc_conn_recfg_r13: - HANDLE_CODE(c.unpack(bref)); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_"); - return SRSASN_ERROR_DECODE_FAIL; + HANDLE_CODE(bref.unpack(rrm_cfg_r13_present, 1)); + HANDLE_CODE(bref.unpack(as_context_r13_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(ue_radio_access_cap_info_r13.unpack(bref)); + HANDLE_CODE(as_cfg_r13.unpack(bref)); + if (rrm_cfg_r13_present) { + HANDLE_CODE(rrm_cfg_r13.unpack(bref)); + } + if (as_context_r13_present) { + HANDLE_CODE(as_context_r13.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + return SRSASN_SUCCESS; } - -const char* rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const +void ho_prep_info_nb_ies_s::to_json(json_writer& j) const { - static const char* options[] = {"rrcConnectionReconfiguration-r13", "spare1"}; - return convert_enum_idx(options, 2, value, "rrc_conn_recfg_nb_s::crit_exts_c_::c1_c_::types"); + j.start_obj(); + j.write_fieldname("ue-RadioAccessCapabilityInfo-r13"); + ue_radio_access_cap_info_r13.to_json(j); + j.write_fieldname("as-Config-r13"); + as_cfg_r13.to_json(j); + if (rrm_cfg_r13_present) { + j.write_fieldname("rrm-Config-r13"); + rrm_cfg_r13.to_json(j); + } + if (as_context_r13_present) { + j.write_fieldname("as-Context-r13"); + as_context_r13.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); } -// RRCConnectionRelease-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_release_nb_s::pack(bit_ref& bref) const +// HandoverPreparationInformation-NB ::= SEQUENCE +SRSASN_CODE ho_prep_info_nb_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_release_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE ho_prep_info_nb_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void rrc_conn_release_nb_s::to_json(json_writer& j) const +void ho_prep_info_nb_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); j.write_fieldname("criticalExtensions"); crit_exts.to_json(j); j.end_obj(); } -void rrc_conn_release_nb_s::crit_exts_c_::set(types::options e) +void ho_prep_info_nb_s::crit_exts_c_::set(types::options e) { type_ = e; } -rrc_conn_release_nb_s::crit_exts_c_::c1_c_& rrc_conn_release_nb_s::crit_exts_c_::set_c1() +ho_prep_info_nb_s::crit_exts_c_::c1_c_& ho_prep_info_nb_s::crit_exts_c_::set_c1() { set(types::c1); return c; } -void rrc_conn_release_nb_s::crit_exts_c_::set_crit_exts_future() +void ho_prep_info_nb_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void rrc_conn_release_nb_s::crit_exts_c_::to_json(json_writer& j) const +void ho_prep_info_nb_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { @@ -14448,11 +20464,11 @@ void rrc_conn_release_nb_s::crit_exts_c_::to_json(json_writer& j) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_release_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE ho_prep_info_nb_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { @@ -14462,12 +20478,12 @@ SRSASN_CODE rrc_conn_release_nb_s::crit_exts_c_::pack(bit_ref& bref) const case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_release_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE ho_prep_info_nb_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -14479,269 +20495,395 @@ SRSASN_CODE rrc_conn_release_nb_s::crit_exts_c_::unpack(cbit_ref& bref) case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void rrc_conn_release_nb_s::crit_exts_c_::c1_c_::set(types::options e) +void ho_prep_info_nb_s::crit_exts_c_::c1_c_::set(types::options e) { type_ = e; } -rrc_conn_release_nb_r13_ies_s& rrc_conn_release_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_release_r13() +ho_prep_info_nb_ies_s& ho_prep_info_nb_s::crit_exts_c_::c1_c_::set_ho_prep_info_r13() { - set(types::rrc_conn_release_r13); + set(types::ho_prep_info_r13); return c; } -void rrc_conn_release_nb_s::crit_exts_c_::c1_c_::set_spare1() +void ho_prep_info_nb_s::crit_exts_c_::c1_c_::set_spare3() +{ + set(types::spare3); +} +void ho_prep_info_nb_s::crit_exts_c_::c1_c_::set_spare2() +{ + set(types::spare2); +} +void ho_prep_info_nb_s::crit_exts_c_::c1_c_::set_spare1() { set(types::spare1); } -void rrc_conn_release_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +void ho_prep_info_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_conn_release_r13: - j.write_fieldname("rrcConnectionRelease-r13"); + case types::ho_prep_info_r13: + j.write_fieldname("handoverPreparationInformation-r13"); c.to_json(j); break; + case types::spare3: + break; + case types::spare2: + break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_::c1_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_release_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +SRSASN_CODE ho_prep_info_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_conn_release_r13: + case types::ho_prep_info_r13: HANDLE_CODE(c.pack(bref)); break; + case types::spare3: + break; + case types::spare2: + break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_release_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE ho_prep_info_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_conn_release_r13: + case types::ho_prep_info_r13: HANDLE_CODE(c.unpack(bref)); break; + case types::spare3: + break; + case types::spare2: + break; case types::spare1: break; default: - log_invalid_choice_id(type_, "rrc_conn_release_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_::c1_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* rrc_conn_release_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const +const char* ho_prep_info_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const { - static const char* options[] = {"rrcConnectionRelease-r13", "spare1"}; - return convert_enum_idx(options, 2, value, "rrc_conn_release_nb_s::crit_exts_c_::c1_c_::types"); + static const char* options[] = {"handoverPreparationInformation-r13", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 4, value, "ho_prep_info_nb_s::crit_exts_c_::c1_c_::types"); } -// RRCConnectionResume-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_resume_nb_s::pack(bit_ref& bref) const +// InitialUE-Identity-5GC-NB-r16 ::= CHOICE +void init_ue_id_minus5_gc_nb_r16_c::destroy_() { - HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.pack(bref)); - - return SRSASN_SUCCESS; + switch (type_) { + case types::ng_minus5_g_s_tmsi_r16: + c.destroy >(); + break; + case types::random_value: + c.destroy >(); + break; + default: + break; + } } -SRSASN_CODE rrc_conn_resume_nb_s::unpack(cbit_ref& bref) +void init_ue_id_minus5_gc_nb_r16_c::set(types::options e) { - HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.unpack(bref)); - - return SRSASN_SUCCESS; + destroy_(); + type_ = e; + switch (type_) { + case types::ng_minus5_g_s_tmsi_r16: + c.init >(); + break; + case types::random_value: + c.init >(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_nb_r16_c"); + } } -void rrc_conn_resume_nb_s::to_json(json_writer& j) const +init_ue_id_minus5_gc_nb_r16_c::init_ue_id_minus5_gc_nb_r16_c(const init_ue_id_minus5_gc_nb_r16_c& other) { - j.start_obj(); - j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); - j.write_fieldname("criticalExtensions"); - crit_exts.to_json(j); - j.end_obj(); + type_ = other.type(); + switch (type_) { + case types::ng_minus5_g_s_tmsi_r16: + c.init(other.c.get >()); + break; + case types::random_value: + c.init(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_nb_r16_c"); + } } - -void rrc_conn_resume_nb_s::crit_exts_c_::set(types::options e) +init_ue_id_minus5_gc_nb_r16_c& init_ue_id_minus5_gc_nb_r16_c::operator=(const init_ue_id_minus5_gc_nb_r16_c& other) { - type_ = e; + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::ng_minus5_g_s_tmsi_r16: + c.set(other.c.get >()); + break; + case types::random_value: + c.set(other.c.get >()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_nb_r16_c"); + } + + return *this; } -rrc_conn_resume_nb_s::crit_exts_c_::c1_c_& rrc_conn_resume_nb_s::crit_exts_c_::set_c1() +fixed_bitstring<48>& init_ue_id_minus5_gc_nb_r16_c::set_ng_minus5_g_s_tmsi_r16() { - set(types::c1); - return c; + set(types::ng_minus5_g_s_tmsi_r16); + return c.get >(); } -void rrc_conn_resume_nb_s::crit_exts_c_::set_crit_exts_future() +fixed_bitstring<48>& init_ue_id_minus5_gc_nb_r16_c::set_random_value() { - set(types::crit_exts_future); + set(types::random_value); + return c.get >(); } -void rrc_conn_resume_nb_s::crit_exts_c_::to_json(json_writer& j) const +void init_ue_id_minus5_gc_nb_r16_c::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::c1: - j.write_fieldname("c1"); - c.to_json(j); + case types::ng_minus5_g_s_tmsi_r16: + j.write_str("ng-5G-S-TMSI-r16", c.get >().to_string()); break; - case types::crit_exts_future: + case types::random_value: + j.write_str("randomValue", c.get >().to_string()); break; default: - log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_nb_r16_c"); } j.end_obj(); } -SRSASN_CODE rrc_conn_resume_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE init_ue_id_minus5_gc_nb_r16_c::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::c1: - HANDLE_CODE(c.pack(bref)); + case types::ng_minus5_g_s_tmsi_r16: + HANDLE_CODE(c.get >().pack(bref)); break; - case types::crit_exts_future: + case types::random_value: + HANDLE_CODE(c.get >().pack(bref)); break; default: - log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_nb_r16_c"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_resume_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE init_ue_id_minus5_gc_nb_r16_c::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::c1: - HANDLE_CODE(c.unpack(bref)); + case types::ng_minus5_g_s_tmsi_r16: + HANDLE_CODE(c.get >().unpack(bref)); break; - case types::crit_exts_future: + case types::random_value: + HANDLE_CODE(c.get >().unpack(bref)); break; default: - log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "init_ue_id_minus5_gc_nb_r16_c"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::set(types::options e) +const char* init_ue_id_minus5_gc_nb_r16_c::types_opts::to_string() const { - type_ = e; + static const char* options[] = {"ng-5G-S-TMSI-r16", "randomValue"}; + return convert_enum_idx(options, 2, value, "init_ue_id_minus5_gc_nb_r16_c::types"); } -rrc_conn_resume_nb_r13_ies_s& rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::set_rrc_conn_resume_r13() +int8_t init_ue_id_minus5_gc_nb_r16_c::types_opts::to_number() const { - set(types::rrc_conn_resume_r13); - return c; + static const int8_t options[] = {-5}; + return map_enum_number(options, 1, value, "init_ue_id_minus5_gc_nb_r16_c::types"); } -void rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::set_spare1() + +// PagingRecord-NB-v1610 ::= SEQUENCE +SRSASN_CODE paging_record_nb_v1610_s::pack(bit_ref& bref) const { - set(types::spare1); + HANDLE_CODE(bref.pack(mt_edt_r16_present, 1)); + + return SRSASN_SUCCESS; } -void rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +SRSASN_CODE paging_record_nb_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(mt_edt_r16_present, 1)); + + return SRSASN_SUCCESS; +} +void paging_record_nb_v1610_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::rrc_conn_resume_r13: - j.write_fieldname("rrcConnectionResume-r13"); - c.to_json(j); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_::c1_c_"); + if (mt_edt_r16_present) { + j.write_str("mt-EDT-r16", "true"); } j.end_obj(); } -SRSASN_CODE rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const + +// PagingRecord-NB-r13 ::= SEQUENCE +SRSASN_CODE paging_record_nb_r13_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::rrc_conn_resume_r13: - HANDLE_CODE(c.pack(bref)); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_::c1_c_"); - return SRSASN_ERROR_ENCODE_FAIL; - } + bref.pack(ext, 1); + HANDLE_CODE(ue_id_r13.pack(bref)); + return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE paging_record_nb_r13_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::rrc_conn_resume_r13: - HANDLE_CODE(c.unpack(bref)); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_resume_nb_s::crit_exts_c_::c1_c_"); - return SRSASN_ERROR_DECODE_FAIL; + bref.unpack(ext, 1); + HANDLE_CODE(ue_id_r13.unpack(bref)); + + return SRSASN_SUCCESS; +} +void paging_record_nb_r13_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ue-Identity-r13"); + ue_id_r13.to_json(j); + j.end_obj(); +} + +// Paging-NB-v1610-IEs ::= SEQUENCE +SRSASN_CODE paging_nb_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(paging_record_list_v1610_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (paging_record_list_v1610_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, paging_record_list_v1610, 1, 16)); } + return SRSASN_SUCCESS; } +SRSASN_CODE paging_nb_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(paging_record_list_v1610_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); -const char* rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const + if (paging_record_list_v1610_present) { + HANDLE_CODE(unpack_dyn_seq_of(paging_record_list_v1610, bref, 1, 16)); + } + + return SRSASN_SUCCESS; +} +void paging_nb_v1610_ies_s::to_json(json_writer& j) const { - static const char* options[] = {"rrcConnectionResume-r13", "spare1"}; - return convert_enum_idx(options, 2, value, "rrc_conn_resume_nb_s::crit_exts_c_::c1_c_::types"); + j.start_obj(); + if (paging_record_list_v1610_present) { + j.start_array("pagingRecordList-v1610"); + for (const auto& e1 : paging_record_list_v1610) { + e1.to_json(j); + } + j.end_array(); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); } -// UECapabilityEnquiry-NB ::= SEQUENCE -SRSASN_CODE ue_cap_enquiry_nb_s::pack(bit_ref& bref) const +// Paging-NB ::= SEQUENCE +SRSASN_CODE paging_nb_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.pack(bref)); + HANDLE_CODE(bref.pack(paging_record_list_r13_present, 1)); + HANDLE_CODE(bref.pack(sys_info_mod_r13_present, 1)); + HANDLE_CODE(bref.pack(sys_info_mod_e_drx_r13_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (paging_record_list_r13_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, paging_record_list_r13, 1, 16)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE ue_cap_enquiry_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE paging_nb_s::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.unpack(bref)); + HANDLE_CODE(bref.unpack(paging_record_list_r13_present, 1)); + HANDLE_CODE(bref.unpack(sys_info_mod_r13_present, 1)); + HANDLE_CODE(bref.unpack(sys_info_mod_e_drx_r13_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (paging_record_list_r13_present) { + HANDLE_CODE(unpack_dyn_seq_of(paging_record_list_r13, bref, 1, 16)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } -void ue_cap_enquiry_nb_s::to_json(json_writer& j) const +void paging_nb_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); - j.write_fieldname("criticalExtensions"); - crit_exts.to_json(j); + if (paging_record_list_r13_present) { + j.start_array("pagingRecordList-r13"); + for (const auto& e1 : paging_record_list_r13) { + e1.to_json(j); + } + j.end_array(); + } + if (sys_info_mod_r13_present) { + j.write_str("systemInfoModification-r13", "true"); + } + if (sys_info_mod_e_drx_r13_present) { + j.write_str("systemInfoModification-eDRX-r13", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } j.end_obj(); } -void ue_cap_enquiry_nb_s::crit_exts_c_::set(types::options e) +// PCCH-MessageType-NB ::= CHOICE +void pcch_msg_type_nb_c::set(types::options e) { type_ = e; } -ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_& ue_cap_enquiry_nb_s::crit_exts_c_::set_c1() +pcch_msg_type_nb_c::c1_c_& pcch_msg_type_nb_c::set_c1() { set(types::c1); return c; } -void ue_cap_enquiry_nb_s::crit_exts_c_::set_crit_exts_future() +void pcch_msg_type_nb_c::set_msg_class_ext() { - set(types::crit_exts_future); + set(types::msg_class_ext); } -void ue_cap_enquiry_nb_s::crit_exts_c_::to_json(json_writer& j) const +void pcch_msg_type_nb_c::to_json(json_writer& j) const { j.start_obj(); switch (type_) { @@ -14749,29 +20891,29 @@ void ue_cap_enquiry_nb_s::crit_exts_c_::to_json(json_writer& j) const j.write_fieldname("c1"); c.to_json(j); break; - case types::crit_exts_future: + case types::msg_class_ext: break; default: - log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "pcch_msg_type_nb_c"); } j.end_obj(); } -SRSASN_CODE ue_cap_enquiry_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE pcch_msg_type_nb_c::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { case types::c1: HANDLE_CODE(c.pack(bref)); break; - case types::crit_exts_future: + case types::msg_class_ext: break; default: - log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "pcch_msg_type_nb_c"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE ue_cap_enquiry_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE pcch_msg_type_nb_c::unpack(cbit_ref& bref) { types e; e.unpack(bref); @@ -14780,533 +20922,445 @@ SRSASN_CODE ue_cap_enquiry_nb_s::crit_exts_c_::unpack(cbit_ref& bref) case types::c1: HANDLE_CODE(c.unpack(bref)); break; - case types::crit_exts_future: + case types::msg_class_ext: break; default: - log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "pcch_msg_type_nb_c"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::set(types::options e) -{ - type_ = e; -} -ue_cap_enquiry_nb_r13_ies_s& ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::set_ue_cap_enquiry_r13() -{ - set(types::ue_cap_enquiry_r13); - return c; -} -void ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::set_spare1() -{ - set(types::spare1); -} -void ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +void pcch_msg_type_nb_c::c1_c_::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::ue_cap_enquiry_r13: - j.write_fieldname("ueCapabilityEnquiry-r13"); - c.to_json(j); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_"); - } + j.write_fieldname("paging-r13"); + c.to_json(j); j.end_obj(); } -SRSASN_CODE ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +SRSASN_CODE pcch_msg_type_nb_c::c1_c_::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::ue_cap_enquiry_r13: - HANDLE_CODE(c.pack(bref)); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_"); - return SRSASN_ERROR_ENCODE_FAIL; - } + HANDLE_CODE(c.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE pcch_msg_type_nb_c::c1_c_::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::ue_cap_enquiry_r13: - HANDLE_CODE(c.unpack(bref)); - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_"); - return SRSASN_ERROR_DECODE_FAIL; - } + HANDLE_CODE(c.unpack(bref)); return SRSASN_SUCCESS; } -const char* ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const +const char* pcch_msg_type_nb_c::c1_c_::types_opts::to_string() const { - static const char* options[] = {"ueCapabilityEnquiry-r13", "spare1"}; - return convert_enum_idx(options, 2, value, "ue_cap_enquiry_nb_s::crit_exts_c_::c1_c_::types"); + static const char* options[] = {"paging-r13"}; + return convert_enum_idx(options, 1, value, "pcch_msg_type_nb_c::c1_c_::types"); } -// DL-DCCH-MessageType-NB ::= CHOICE -void dl_dcch_msg_type_nb_c::set(types::options e) +const char* pcch_msg_type_nb_c::types_opts::to_string() const { - type_ = e; + static const char* options[] = {"c1", "messageClassExtension"}; + return convert_enum_idx(options, 2, value, "pcch_msg_type_nb_c::types"); } -dl_dcch_msg_type_nb_c::c1_c_& dl_dcch_msg_type_nb_c::set_c1() +uint8_t pcch_msg_type_nb_c::types_opts::to_number() const { - set(types::c1); - return c; + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "pcch_msg_type_nb_c::types"); } -void dl_dcch_msg_type_nb_c::set_msg_class_ext() + +// PCCH-Message-NB ::= SEQUENCE +SRSASN_CODE pcch_msg_nb_s::pack(bit_ref& bref) const { - set(types::msg_class_ext); + HANDLE_CODE(msg.pack(bref)); + + bref.align_bytes_zero(); + + return SRSASN_SUCCESS; } -void dl_dcch_msg_type_nb_c::to_json(json_writer& j) const +SRSASN_CODE pcch_msg_nb_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(msg.unpack(bref)); + + bref.align_bytes(); + + return SRSASN_SUCCESS; +} +void pcch_msg_nb_s::to_json(json_writer& j) const { + j.start_array(); j.start_obj(); - switch (type_) { - case types::c1: - j.write_fieldname("c1"); - c.to_json(j); - break; - case types::msg_class_ext: - break; - default: - log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c"); - } + j.start_obj("PCCH-Message-NB"); + j.write_fieldname("message"); + msg.to_json(j); j.end_obj(); + j.end_obj(); + j.end_array(); } -SRSASN_CODE dl_dcch_msg_type_nb_c::pack(bit_ref& bref) const + +// PCI-ARFCN-NB-r14 ::= SEQUENCE +SRSASN_CODE pci_arfcn_nb_r14_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::c1: - HANDLE_CODE(c.pack(bref)); - break; - case types::msg_class_ext: - break; - default: - log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c"); - return SRSASN_ERROR_ENCODE_FAIL; + HANDLE_CODE(bref.pack(carrier_freq_r14_present, 1)); + + HANDLE_CODE(pack_integer(bref, pci_r14, (uint16_t)0u, (uint16_t)503u)); + if (carrier_freq_r14_present) { + HANDLE_CODE(carrier_freq_r14.pack(bref)); } + return SRSASN_SUCCESS; } -SRSASN_CODE dl_dcch_msg_type_nb_c::unpack(cbit_ref& bref) +SRSASN_CODE pci_arfcn_nb_r14_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::c1: - HANDLE_CODE(c.unpack(bref)); - break; - case types::msg_class_ext: - break; - default: - log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c"); - return SRSASN_ERROR_DECODE_FAIL; + HANDLE_CODE(bref.unpack(carrier_freq_r14_present, 1)); + + HANDLE_CODE(unpack_integer(pci_r14, bref, (uint16_t)0u, (uint16_t)503u)); + if (carrier_freq_r14_present) { + HANDLE_CODE(carrier_freq_r14.unpack(bref)); } + return SRSASN_SUCCESS; } - -void dl_dcch_msg_type_nb_c::c1_c_::destroy_() +void pci_arfcn_nb_r14_s::to_json(json_writer& j) const { - switch (type_) { - case types::dl_info_transfer_r13: - c.destroy(); - break; - case types::rrc_conn_recfg_r13: - c.destroy(); - break; - case types::rrc_conn_release_r13: - c.destroy(); - break; - case types::security_mode_cmd_r13: - c.destroy(); - break; - case types::ue_cap_enquiry_r13: - c.destroy(); - break; - case types::rrc_conn_resume_r13: - c.destroy(); - break; - default: - break; + j.start_obj(); + j.write_int("physCellId-r14", pci_r14); + if (carrier_freq_r14_present) { + j.write_fieldname("carrierFreq-r14"); + carrier_freq_r14.to_json(j); } + j.end_obj(); +} + +// PUR-ConfigRequest-NB-r16 ::= CHOICE +void pur_cfg_request_nb_r16_c::set(types::options e) +{ + type_ = e; +} +void pur_cfg_request_nb_r16_c::set_pur_release_request() +{ + set(types::pur_release_request); } -void dl_dcch_msg_type_nb_c::c1_c_::set(types::options e) +pur_cfg_request_nb_r16_c::pur_setup_request_s_& pur_cfg_request_nb_r16_c::set_pur_setup_request() { - destroy_(); - type_ = e; + set(types::pur_setup_request); + return c; +} +void pur_cfg_request_nb_r16_c::to_json(json_writer& j) const +{ + j.start_obj(); switch (type_) { - case types::dl_info_transfer_r13: - c.init(); - break; - case types::rrc_conn_recfg_r13: - c.init(); - break; - case types::rrc_conn_release_r13: - c.init(); - break; - case types::security_mode_cmd_r13: - c.init(); - break; - case types::ue_cap_enquiry_r13: - c.init(); - break; - case types::rrc_conn_resume_r13: - c.init(); + case types::pur_release_request: break; - case types::spare2: - break; - case types::spare1: - break; - case types::nulltype: + case types::pur_setup_request: + j.write_fieldname("pur-SetupRequest"); + j.start_obj(); + j.write_str("requestedNumOccasions-r16", c.requested_num_occasions_r16.to_string()); + j.write_fieldname("requestedPeriodicityAndOffset-r16"); + c.requested_periodicity_and_offset_r16.to_json(j); + j.write_str("requestedTBS-r16", c.requested_tbs_r16.to_string()); + if (c.rrc_ack_r16_present) { + j.write_str("rrc-ACK-r16", "true"); + } + j.end_obj(); break; default: - log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); + log_invalid_choice_id(type_, "pur_cfg_request_nb_r16_c"); } + j.end_obj(); } -dl_dcch_msg_type_nb_c::c1_c_::c1_c_(const dl_dcch_msg_type_nb_c::c1_c_& other) +SRSASN_CODE pur_cfg_request_nb_r16_c::pack(bit_ref& bref) const { - type_ = other.type(); + type_.pack(bref); switch (type_) { - case types::dl_info_transfer_r13: - c.init(other.c.get()); - break; - case types::rrc_conn_recfg_r13: - c.init(other.c.get()); - break; - case types::rrc_conn_release_r13: - c.init(other.c.get()); - break; - case types::security_mode_cmd_r13: - c.init(other.c.get()); + case types::pur_release_request: break; - case types::ue_cap_enquiry_r13: - c.init(other.c.get()); - break; - case types::rrc_conn_resume_r13: - c.init(other.c.get()); - break; - case types::spare2: - break; - case types::spare1: - break; - case types::nulltype: + case types::pur_setup_request: + HANDLE_CODE(bref.pack(c.rrc_ack_r16_present, 1)); + HANDLE_CODE(c.requested_num_occasions_r16.pack(bref)); + HANDLE_CODE(c.requested_periodicity_and_offset_r16.pack(bref)); + HANDLE_CODE(c.requested_tbs_r16.pack(bref)); break; default: - log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); + log_invalid_choice_id(type_, "pur_cfg_request_nb_r16_c"); + return SRSASN_ERROR_ENCODE_FAIL; } + return SRSASN_SUCCESS; } -dl_dcch_msg_type_nb_c::c1_c_& dl_dcch_msg_type_nb_c::c1_c_::operator=(const dl_dcch_msg_type_nb_c::c1_c_& other) +SRSASN_CODE pur_cfg_request_nb_r16_c::unpack(cbit_ref& bref) { - if (this == &other) { - return *this; - } - set(other.type()); + types e; + e.unpack(bref); + set(e); switch (type_) { - case types::dl_info_transfer_r13: - c.set(other.c.get()); - break; - case types::rrc_conn_recfg_r13: - c.set(other.c.get()); - break; - case types::rrc_conn_release_r13: - c.set(other.c.get()); - break; - case types::security_mode_cmd_r13: - c.set(other.c.get()); - break; - case types::ue_cap_enquiry_r13: - c.set(other.c.get()); - break; - case types::rrc_conn_resume_r13: - c.set(other.c.get()); - break; - case types::spare2: - break; - case types::spare1: + case types::pur_release_request: break; - case types::nulltype: + case types::pur_setup_request: + HANDLE_CODE(bref.unpack(c.rrc_ack_r16_present, 1)); + HANDLE_CODE(c.requested_num_occasions_r16.unpack(bref)); + HANDLE_CODE(c.requested_periodicity_and_offset_r16.unpack(bref)); + HANDLE_CODE(c.requested_tbs_r16.unpack(bref)); break; default: - log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); + log_invalid_choice_id(type_, "pur_cfg_request_nb_r16_c"); + return SRSASN_ERROR_DECODE_FAIL; } + return SRSASN_SUCCESS; +} - return *this; +const char* pur_cfg_request_nb_r16_c::pur_setup_request_s_::requested_num_occasions_r16_opts::to_string() const +{ + static const char* options[] = {"one", "infinite"}; + return convert_enum_idx( + options, 2, value, "pur_cfg_request_nb_r16_c::pur_setup_request_s_::requested_num_occasions_r16_e_"); } -dl_info_transfer_nb_s& dl_dcch_msg_type_nb_c::c1_c_::set_dl_info_transfer_r13() +uint8_t pur_cfg_request_nb_r16_c::pur_setup_request_s_::requested_num_occasions_r16_opts::to_number() const { - set(types::dl_info_transfer_r13); - return c.get(); + static const uint8_t options[] = {1}; + return map_enum_number( + options, 1, value, "pur_cfg_request_nb_r16_c::pur_setup_request_s_::requested_num_occasions_r16_e_"); } -rrc_conn_recfg_nb_s& dl_dcch_msg_type_nb_c::c1_c_::set_rrc_conn_recfg_r13() + +const char* pur_cfg_request_nb_r16_c::pur_setup_request_s_::requested_tbs_r16_opts::to_string() const { - set(types::rrc_conn_recfg_r13); - return c.get(); + static const char* options[] = {"b328", "b376", "b424", "b472", "b504", "b552", "b584", "b616", + "b680", "b744", "b776", "b808", "b872", "b904", "b936", "b968", + "b1000", "b1032", "b1096", "b1128", "b1192", "b1224", "b1256", "b1352", + "b1384", "b1544", "b1608", "b1736", "b1800", "b2024", "b2280", "b2536"}; + return convert_enum_idx(options, 32, value, "pur_cfg_request_nb_r16_c::pur_setup_request_s_::requested_tbs_r16_e_"); } -rrc_conn_release_nb_s& dl_dcch_msg_type_nb_c::c1_c_::set_rrc_conn_release_r13() +uint16_t pur_cfg_request_nb_r16_c::pur_setup_request_s_::requested_tbs_r16_opts::to_number() const { - set(types::rrc_conn_release_r13); - return c.get(); + static const uint16_t options[] = {328, 376, 424, 472, 504, 552, 584, 616, 680, 744, 776, + 808, 872, 904, 936, 968, 1000, 1032, 1096, 1128, 1192, 1224, + 1256, 1352, 1384, 1544, 1608, 1736, 1800, 2024, 2280, 2536}; + return map_enum_number(options, 32, value, "pur_cfg_request_nb_r16_c::pur_setup_request_s_::requested_tbs_r16_e_"); } -security_mode_cmd_s& dl_dcch_msg_type_nb_c::c1_c_::set_security_mode_cmd_r13() + +const char* pur_cfg_request_nb_r16_c::types_opts::to_string() const { - set(types::security_mode_cmd_r13); - return c.get(); + static const char* options[] = {"pur-ReleaseRequest", "pur-SetupRequest"}; + return convert_enum_idx(options, 2, value, "pur_cfg_request_nb_r16_c::types"); } -ue_cap_enquiry_nb_s& dl_dcch_msg_type_nb_c::c1_c_::set_ue_cap_enquiry_r13() + +// PURConfigurationRequest-NB-r16-IEs ::= SEQUENCE +SRSASN_CODE pur_cfg_request_nb_r16_ies_s::pack(bit_ref& bref) const { - set(types::ue_cap_enquiry_r13); - return c.get(); + HANDLE_CODE(bref.pack(pur_cfg_request_r16_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (pur_cfg_request_r16_present) { + HANDLE_CODE(pur_cfg_request_r16.pack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; } -rrc_conn_resume_nb_s& dl_dcch_msg_type_nb_c::c1_c_::set_rrc_conn_resume_r13() +SRSASN_CODE pur_cfg_request_nb_r16_ies_s::unpack(cbit_ref& bref) { - set(types::rrc_conn_resume_r13); - return c.get(); + HANDLE_CODE(bref.unpack(pur_cfg_request_r16_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (pur_cfg_request_r16_present) { + HANDLE_CODE(pur_cfg_request_r16.unpack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; } -void dl_dcch_msg_type_nb_c::c1_c_::set_spare2() +void pur_cfg_request_nb_r16_ies_s::to_json(json_writer& j) const { - set(types::spare2); + j.start_obj(); + if (pur_cfg_request_r16_present) { + j.write_fieldname("pur-ConfigRequest-r16"); + pur_cfg_request_r16.to_json(j); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); } -void dl_dcch_msg_type_nb_c::c1_c_::set_spare1() + +// PURConfigurationRequest-NB-r16 ::= SEQUENCE +SRSASN_CODE pur_cfg_request_nb_r16_s::pack(bit_ref& bref) const { - set(types::spare1); + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; } -void dl_dcch_msg_type_nb_c::c1_c_::to_json(json_writer& j) const +SRSASN_CODE pur_cfg_request_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void pur_cfg_request_nb_r16_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::dl_info_transfer_r13: - j.write_fieldname("dlInformationTransfer-r13"); - c.get().to_json(j); - break; - case types::rrc_conn_recfg_r13: - j.write_fieldname("rrcConnectionReconfiguration-r13"); - c.get().to_json(j); - break; - case types::rrc_conn_release_r13: - j.write_fieldname("rrcConnectionRelease-r13"); - c.get().to_json(j); - break; - case types::security_mode_cmd_r13: - j.write_fieldname("securityModeCommand-r13"); - c.get().to_json(j); - break; - case types::ue_cap_enquiry_r13: - j.write_fieldname("ueCapabilityEnquiry-r13"); - c.get().to_json(j); - break; - case types::rrc_conn_resume_r13: - j.write_fieldname("rrcConnectionResume-r13"); - c.get().to_json(j); - break; - case types::spare2: - break; - case types::spare1: - break; - default: - log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); - } + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); j.end_obj(); } -SRSASN_CODE dl_dcch_msg_type_nb_c::c1_c_::pack(bit_ref& bref) const + +void pur_cfg_request_nb_r16_s::crit_exts_c_::set(types::options e) { - type_.pack(bref); + type_ = e; +} +pur_cfg_request_nb_r16_ies_s& pur_cfg_request_nb_r16_s::crit_exts_c_::set_pur_cfg_request_r16() +{ + set(types::pur_cfg_request_r16); + return c; +} +void pur_cfg_request_nb_r16_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void pur_cfg_request_nb_r16_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); switch (type_) { - case types::dl_info_transfer_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::rrc_conn_recfg_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::rrc_conn_release_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::security_mode_cmd_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::ue_cap_enquiry_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::rrc_conn_resume_r13: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::spare2: + case types::pur_cfg_request_r16: + j.write_fieldname("purConfigurationRequest-r16"); + c.to_json(j); break; - case types::spare1: + case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); - return SRSASN_ERROR_ENCODE_FAIL; + log_invalid_choice_id(type_, "pur_cfg_request_nb_r16_s::crit_exts_c_"); } - return SRSASN_SUCCESS; + j.end_obj(); } -SRSASN_CODE dl_dcch_msg_type_nb_c::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE pur_cfg_request_nb_r16_s::crit_exts_c_::pack(bit_ref& bref) const { - types e; - e.unpack(bref); - set(e); + type_.pack(bref); switch (type_) { - case types::dl_info_transfer_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::rrc_conn_recfg_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::rrc_conn_release_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::security_mode_cmd_r13: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::ue_cap_enquiry_r13: - HANDLE_CODE(c.get().unpack(bref)); + case types::pur_cfg_request_r16: + HANDLE_CODE(c.pack(bref)); break; - case types::rrc_conn_resume_r13: - HANDLE_CODE(c.get().unpack(bref)); + case types::crit_exts_future: break; - case types::spare2: + default: + log_invalid_choice_id(type_, "pur_cfg_request_nb_r16_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE pur_cfg_request_nb_r16_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::pur_cfg_request_r16: + HANDLE_CODE(c.unpack(bref)); break; - case types::spare1: + case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "dl_dcch_msg_type_nb_c::c1_c_"); + log_invalid_choice_id(type_, "pur_cfg_request_nb_r16_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* dl_dcch_msg_type_nb_c::c1_c_::types_opts::to_string() const -{ - static const char* options[] = {"dlInformationTransfer-r13", - "rrcConnectionReconfiguration-r13", - "rrcConnectionRelease-r13", - "securityModeCommand-r13", - "ueCapabilityEnquiry-r13", - "rrcConnectionResume-r13", - "spare2", - "spare1"}; - return convert_enum_idx(options, 8, value, "dl_dcch_msg_type_nb_c::c1_c_::types"); -} - -const char* dl_dcch_msg_type_nb_c::types_opts::to_string() const -{ - static const char* options[] = {"c1", "messageClassExtension"}; - return convert_enum_idx(options, 2, value, "dl_dcch_msg_type_nb_c::types"); -} -uint8_t dl_dcch_msg_type_nb_c::types_opts::to_number() const +const char* pur_cfg_request_nb_r16_s::crit_exts_c_::types_opts::to_string() const { - static const uint8_t options[] = {1}; - return map_enum_number(options, 1, value, "dl_dcch_msg_type_nb_c::types"); + static const char* options[] = {"purConfigurationRequest-r16", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "pur_cfg_request_nb_r16_s::crit_exts_c_::types"); } -// DL-DCCH-Message-NB ::= SEQUENCE -SRSASN_CODE dl_dcch_msg_nb_s::pack(bit_ref& bref) const +// SupportedBand-NB-v1710 ::= SEQUENCE +SRSASN_CODE supported_band_nb_v1710_s::pack(bit_ref& bref) const { - HANDLE_CODE(msg.pack(bref)); - - bref.align_bytes_zero(); + HANDLE_CODE(bref.pack(npusch_minus16_qam_r17_present, 1)); return SRSASN_SUCCESS; } -SRSASN_CODE dl_dcch_msg_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE supported_band_nb_v1710_s::unpack(cbit_ref& bref) { - HANDLE_CODE(msg.unpack(bref)); - - bref.align_bytes(); + HANDLE_CODE(bref.unpack(npusch_minus16_qam_r17_present, 1)); return SRSASN_SUCCESS; } -void dl_dcch_msg_nb_s::to_json(json_writer& j) const +void supported_band_nb_v1710_s::to_json(json_writer& j) const { - j.start_array(); j.start_obj(); - j.start_obj("DL-DCCH-Message-NB"); - j.write_fieldname("message"); - msg.to_json(j); - j.end_obj(); + if (npusch_minus16_qam_r17_present) { + j.write_str("npusch-16QAM-r17", "supported"); + } j.end_obj(); - j.end_array(); } -// SupportedBand-NB-r13 ::= SEQUENCE -SRSASN_CODE supported_band_nb_r13_s::pack(bit_ref& bref) const +// RF-Parameters-NB-v1710 ::= SEQUENCE +SRSASN_CODE rf_params_nb_v1710_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(pwr_class_nb_minus20dbm_r13_present, 1)); + HANDLE_CODE(bref.pack(supported_band_list_v1710_present, 1)); - HANDLE_CODE(pack_integer(bref, band_r13, (uint16_t)1u, (uint16_t)256u)); + if (supported_band_list_v1710_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_list_v1710, 1, 64)); + } return SRSASN_SUCCESS; } -SRSASN_CODE supported_band_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE rf_params_nb_v1710_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(pwr_class_nb_minus20dbm_r13_present, 1)); + HANDLE_CODE(bref.unpack(supported_band_list_v1710_present, 1)); - HANDLE_CODE(unpack_integer(band_r13, bref, (uint16_t)1u, (uint16_t)256u)); + if (supported_band_list_v1710_present) { + HANDLE_CODE(unpack_dyn_seq_of(supported_band_list_v1710, bref, 1, 64)); + } return SRSASN_SUCCESS; } -void supported_band_nb_r13_s::to_json(json_writer& j) const +void rf_params_nb_v1710_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("band-r13", band_r13); - if (pwr_class_nb_minus20dbm_r13_present) { - j.write_str("powerClassNB-20dBm-r13", "supported"); + if (supported_band_list_v1710_present) { + j.start_array("supportedBandList-v1710"); + for (const auto& e1 : supported_band_list_v1710) { + e1.to_json(j); + } + j.end_array(); } j.end_obj(); } -// AccessStratumRelease-NB-r13 ::= ENUMERATED -const char* access_stratum_release_nb_r13_opts::to_string() const -{ - static const char* options[] = {"rel13", "rel14", "rel15", "spare5", "spare4", "spare3", "spare2", "spare1"}; - return convert_enum_idx(options, 8, value, "access_stratum_release_nb_r13_e"); -} -uint8_t access_stratum_release_nb_r13_opts::to_number() const -{ - static const uint8_t options[] = {13, 14, 15}; - return map_enum_number(options, 3, value, "access_stratum_release_nb_r13_e"); -} - -// HandoverPreparationInformation-NB-Ext-r14-IEs ::= SEQUENCE -SRSASN_CODE ho_prep_info_nb_ext_r14_ies_s::pack(bit_ref& bref) const +// RRCConnectionReconfigurationComplete-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_recfg_complete_nb_r13_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(ue_radio_access_cap_info_ext_r14_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (ue_radio_access_cap_info_ext_r14_present) { - HANDLE_CODE(ue_radio_access_cap_info_ext_r14.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE ho_prep_info_nb_ext_r14_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_recfg_complete_nb_r13_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(ue_radio_access_cap_info_ext_r14_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - if (ue_radio_access_cap_info_ext_r14_present) { - HANDLE_CODE(ue_radio_access_cap_info_ext_r14.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); } return SRSASN_SUCCESS; } -void ho_prep_info_nb_ext_r14_ies_s::to_json(json_writer& j) const +void rrc_conn_recfg_complete_nb_r13_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (ue_radio_access_cap_info_ext_r14_present) { - j.write_str("ue-RadioAccessCapabilityInfoExt-r14", ue_radio_access_cap_info_ext_r14.to_string()); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); @@ -15316,133 +21370,220 @@ void ho_prep_info_nb_ext_r14_ies_s::to_json(json_writer& j) const j.end_obj(); } -// PDCP-Parameters-NB-r13 ::= SEQUENCE -SRSASN_CODE pdcp_params_nb_r13_s::pack(bit_ref& bref) const +// RRCConnectionReconfigurationComplete-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_recfg_complete_nb_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(max_num_rohc_context_sessions_r13_present, 1)); - - HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0002, 1)); - HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0003, 1)); - HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0004, 1)); - HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0006, 1)); - HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0102, 1)); - HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0103, 1)); - HANDLE_CODE(bref.pack(supported_rohc_profiles_r13.profile0x0104, 1)); - if (max_num_rohc_context_sessions_r13_present) { - HANDLE_CODE(max_num_rohc_context_sessions_r13.pack(bref)); - } + HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE pdcp_params_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_recfg_complete_nb_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(max_num_rohc_context_sessions_r13_present, 1)); - - HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0002, 1)); - HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0003, 1)); - HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0004, 1)); - HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0006, 1)); - HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0102, 1)); - HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0103, 1)); - HANDLE_CODE(bref.unpack(supported_rohc_profiles_r13.profile0x0104, 1)); - if (max_num_rohc_context_sessions_r13_present) { - HANDLE_CODE(max_num_rohc_context_sessions_r13.unpack(bref)); - } + HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void pdcp_params_nb_r13_s::to_json(json_writer& j) const +void rrc_conn_recfg_complete_nb_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("supportedROHC-Profiles-r13"); - j.start_obj(); - j.write_bool("profile0x0002", supported_rohc_profiles_r13.profile0x0002); - j.write_bool("profile0x0003", supported_rohc_profiles_r13.profile0x0003); - j.write_bool("profile0x0004", supported_rohc_profiles_r13.profile0x0004); - j.write_bool("profile0x0006", supported_rohc_profiles_r13.profile0x0006); - j.write_bool("profile0x0102", supported_rohc_profiles_r13.profile0x0102); - j.write_bool("profile0x0103", supported_rohc_profiles_r13.profile0x0103); - j.write_bool("profile0x0104", supported_rohc_profiles_r13.profile0x0104); + j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); j.end_obj(); - if (max_num_rohc_context_sessions_r13_present) { - j.write_str("maxNumberROHC-ContextSessions-r13", max_num_rohc_context_sessions_r13.to_string()); +} + +void rrc_conn_recfg_complete_nb_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +rrc_conn_recfg_complete_nb_r13_ies_s& rrc_conn_recfg_complete_nb_s::crit_exts_c_::set_rrc_conn_recfg_complete_r13() +{ + set(types::rrc_conn_recfg_complete_r13); + return c; +} +void rrc_conn_recfg_complete_nb_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void rrc_conn_recfg_complete_nb_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::rrc_conn_recfg_complete_r13: + j.write_fieldname("rrcConnectionReconfigurationComplete-r13"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_recfg_complete_nb_s::crit_exts_c_"); } j.end_obj(); } +SRSASN_CODE rrc_conn_recfg_complete_nb_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::rrc_conn_recfg_complete_r13: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_recfg_complete_nb_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_recfg_complete_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rrc_conn_recfg_complete_r13: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_recfg_complete_nb_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} -const char* pdcp_params_nb_r13_s::max_num_rohc_context_sessions_r13_opts::to_string() const +const char* rrc_conn_recfg_complete_nb_s::crit_exts_c_::types_opts::to_string() const { - static const char* options[] = {"cs2", "cs4", "cs8", "cs12"}; - return convert_enum_idx(options, 4, value, "pdcp_params_nb_r13_s::max_num_rohc_context_sessions_r13_e_"); + static const char* options[] = {"rrcConnectionReconfigurationComplete-r13", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "rrc_conn_recfg_complete_nb_s::crit_exts_c_::types"); } -uint8_t pdcp_params_nb_r13_s::max_num_rohc_context_sessions_r13_opts::to_number() const + +// RRCConnectionReestablishmentComplete-NB-v1710-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_complete_nb_v1710_ies_s::pack(bit_ref& bref) const { - static const uint8_t options[] = {2, 4, 8, 12}; - return map_enum_number(options, 4, value, "pdcp_params_nb_r13_s::max_num_rohc_context_sessions_r13_e_"); + HANDLE_CODE(bref.pack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.pack(bref)); + } + + return SRSASN_SUCCESS; } +SRSASN_CODE rrc_conn_reest_complete_nb_v1710_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); -// PhyLayerParameters-NB-r13 ::= SEQUENCE -SRSASN_CODE phy_layer_params_nb_r13_s::pack(bit_ref& bref) const + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_reest_complete_nb_v1710_ies_s::to_json(json_writer& j) const { - HANDLE_CODE(bref.pack(multi_tone_r13_present, 1)); - HANDLE_CODE(bref.pack(multi_carrier_r13_present, 1)); + j.start_obj(); + if (gnss_validity_dur_r17_present) { + j.write_str("gnss-ValidityDuration-r17", gnss_validity_dur_r17.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// RRCConnectionReestablishmentComplete-NB-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_complete_nb_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(rlf_info_available_r16_present, 1)); + HANDLE_CODE(bref.pack(anr_info_available_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE phy_layer_params_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_reest_complete_nb_v1610_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(multi_tone_r13_present, 1)); - HANDLE_CODE(bref.unpack(multi_carrier_r13_present, 1)); + HANDLE_CODE(bref.unpack(rlf_info_available_r16_present, 1)); + HANDLE_CODE(bref.unpack(anr_info_available_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } -void phy_layer_params_nb_r13_s::to_json(json_writer& j) const +void rrc_conn_reest_complete_nb_v1610_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (multi_tone_r13_present) { - j.write_str("multiTone-r13", "supported"); + if (rlf_info_available_r16_present) { + j.write_str("rlf-InfoAvailable-r16", "true"); } - if (multi_carrier_r13_present) { - j.write_str("multiCarrier-r13", "supported"); + if (anr_info_available_r16_present) { + j.write_str("anr-InfoAvailable-r16", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); } j.end_obj(); } -// RF-Parameters-NB-r13 ::= SEQUENCE -SRSASN_CODE rf_params_nb_r13_s::pack(bit_ref& bref) const +// RRCConnectionReestablishmentComplete-NB-v1470-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_complete_nb_v1470_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(multi_ns_pmax_r13_present, 1)); + HANDLE_CODE(bref.pack(meas_result_serv_cell_r14_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_list_r13, 1, 64)); + if (meas_result_serv_cell_r14_present) { + HANDLE_CODE(meas_result_serv_cell_r14.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE rf_params_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_reest_complete_nb_v1470_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(multi_ns_pmax_r13_present, 1)); + HANDLE_CODE(bref.unpack(meas_result_serv_cell_r14_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - HANDLE_CODE(unpack_dyn_seq_of(supported_band_list_r13, bref, 1, 64)); + if (meas_result_serv_cell_r14_present) { + HANDLE_CODE(meas_result_serv_cell_r14.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } -void rf_params_nb_r13_s::to_json(json_writer& j) const +void rrc_conn_reest_complete_nb_v1470_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.start_array("supportedBandList-r13"); - for (const auto& e1 : supported_band_list_r13) { - e1.to_json(j); + if (meas_result_serv_cell_r14_present) { + j.write_fieldname("measResultServCell-r14"); + meas_result_serv_cell_r14.to_json(j); } - j.end_array(); - if (multi_ns_pmax_r13_present) { - j.write_str("multiNS-Pmax-r13", "supported"); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); } j.end_obj(); } -// HandoverPreparationInformation-NB-v1380-IEs ::= SEQUENCE -SRSASN_CODE ho_prep_info_nb_v1380_ies_s::pack(bit_ref& bref) const +// RRCConnectionReestablishmentComplete-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_complete_nb_r13_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); @@ -15456,7 +21597,7 @@ SRSASN_CODE ho_prep_info_nb_v1380_ies_s::pack(bit_ref& bref) const return SRSASN_SUCCESS; } -SRSASN_CODE ho_prep_info_nb_v1380_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_reest_complete_nb_r13_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -15470,7 +21611,7 @@ SRSASN_CODE ho_prep_info_nb_v1380_ies_s::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -void ho_prep_info_nb_v1380_ies_s::to_json(json_writer& j) const +void rrc_conn_reest_complete_nb_r13_ies_s::to_json(json_writer& j) const { j.start_obj(); if (late_non_crit_ext_present) { @@ -15483,187 +21624,307 @@ void ho_prep_info_nb_v1380_ies_s::to_json(json_writer& j) const j.end_obj(); } -// RRM-Config-NB ::= SEQUENCE -SRSASN_CODE rrm_cfg_nb_s::pack(bit_ref& bref) const +// RRCConnectionReestablishmentComplete-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_complete_nb_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(ue_inactive_time_present, 1)); + HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.pack(bref)); - if (ue_inactive_time_present) { - HANDLE_CODE(ue_inactive_time.pack(bref)); - } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reest_complete_nb_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE rrm_cfg_nb_s::unpack(cbit_ref& bref) +void rrc_conn_reest_complete_nb_s::to_json(json_writer& j) const { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(ue_inactive_time_present, 1)); + j.start_obj(); + j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} - if (ue_inactive_time_present) { - HANDLE_CODE(ue_inactive_time.unpack(bref)); +void rrc_conn_reest_complete_nb_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +rrc_conn_reest_complete_nb_r13_ies_s& rrc_conn_reest_complete_nb_s::crit_exts_c_::set_rrc_conn_reest_complete_r13() +{ + set(types::rrc_conn_reest_complete_r13); + return c; +} +void rrc_conn_reest_complete_nb_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void rrc_conn_reest_complete_nb_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::rrc_conn_reest_complete_r13: + j.write_fieldname("rrcConnectionReestablishmentComplete-r13"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_complete_nb_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE rrc_conn_reest_complete_nb_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::rrc_conn_reest_complete_r13: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_complete_nb_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reest_complete_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rrc_conn_reest_complete_r13: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_complete_nb_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_conn_reest_complete_nb_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"rrcConnectionReestablishmentComplete-r13", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "rrc_conn_reest_complete_nb_s::crit_exts_c_::types"); +} + +// CQI-NPDCCH-Short-NB-r14 ::= ENUMERATED +const char* cqi_npdcch_short_nb_r14_opts::to_string() const +{ + static const char* options[] = {"noMeasurements", "candidateRep-1", "candidateRep-2", "candidateRep-3"}; + return convert_enum_idx(options, 4, value, "cqi_npdcch_short_nb_r14_e"); +} +int8_t cqi_npdcch_short_nb_r14_opts::to_number() const +{ + switch (value) { + case candidate_rep_minus1: + return -1; + case candidate_rep_minus2: + return -2; + case candidate_rep_minus3: + return -3; + default: + invalid_enum_number(value, "cqi_npdcch_short_nb_r14_e"); } + return 0; +} + +// ReestabUE-Identity-CP-5GC-NB-r16 ::= SEQUENCE +SRSASN_CODE reestab_ue_id_cp_minus5_gc_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(truncated5_g_s_tmsi_r16.pack(bref)); + HANDLE_CODE(ul_nas_mac_r16.pack(bref)); + HANDLE_CODE(ul_nas_count_r16.pack(bref)); return SRSASN_SUCCESS; } -void rrm_cfg_nb_s::to_json(json_writer& j) const +SRSASN_CODE reestab_ue_id_cp_minus5_gc_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(truncated5_g_s_tmsi_r16.unpack(bref)); + HANDLE_CODE(ul_nas_mac_r16.unpack(bref)); + HANDLE_CODE(ul_nas_count_r16.unpack(bref)); + + return SRSASN_SUCCESS; +} +void reestab_ue_id_cp_minus5_gc_nb_r16_s::to_json(json_writer& j) const { j.start_obj(); - if (ue_inactive_time_present) { - j.write_str("ue-InactiveTime", ue_inactive_time.to_string()); - } + j.write_str("truncated5G-S-TMSI-r16", truncated5_g_s_tmsi_r16.to_string()); + j.write_str("ul-NAS-MAC-r16", ul_nas_mac_r16.to_string()); + j.write_str("ul-NAS-Count-r16", ul_nas_count_r16.to_string()); j.end_obj(); } -const char* rrm_cfg_nb_s::ue_inactive_time_opts::to_string() const +// ReestablishmentCause-NB-r13 ::= ENUMERATED +const char* reest_cause_nb_r13_opts::to_string() const { - static const char* options[] = { - "s1", "s2", "s3", "s5", "s7", "s10", "s15", "s20", "s25", "s30", - "s40", "s50", "min1", "min1s20", "min1s40", "min2", "min2s30", "min3", "min3s30", "min4", - "min5", "min6", "min7", "min8", "min9", "min10", "min12", "min14", "min17", "min20", - "min24", "min28", "min33", "min38", "min44", "min50", "hr1", "hr1min30", "hr2", "hr2min30", - "hr3", "hr3min30", "hr4", "hr5", "hr6", "hr8", "hr10", "hr13", "hr16", "hr20", - "day1", "day1hr12", "day2", "day2hr12", "day3", "day4", "day5", "day7", "day10", "day14", - "day19", "day24", "day30", "dayMoreThan30"}; - return convert_enum_idx(options, 64, value, "rrm_cfg_nb_s::ue_inactive_time_e_"); + static const char* options[] = {"reconfigurationFailure", "otherFailure", "spare2", "spare1"}; + return convert_enum_idx(options, 4, value, "reest_cause_nb_r13_e"); +} + +// RRCConnectionReestablishmentRequest-5GC-NB-r16-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_request_minus5_gc_nb_r16_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(ue_id_r16.pack(bref)); + HANDLE_CODE(reest_cause_r16.pack(bref)); + HANDLE_CODE(cqi_npdcch_r16.pack(bref)); + HANDLE_CODE(spare.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_reest_request_minus5_gc_nb_r16_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(ue_id_r16.unpack(bref)); + HANDLE_CODE(reest_cause_r16.unpack(bref)); + HANDLE_CODE(cqi_npdcch_r16.unpack(bref)); + HANDLE_CODE(spare.unpack(bref)); + + return SRSASN_SUCCESS; +} +void rrc_conn_reest_request_minus5_gc_nb_r16_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("ue-Identity-r16"); + ue_id_r16.to_json(j); + j.write_str("reestablishmentCause-r16", reest_cause_r16.to_string()); + j.write_str("cqi-NPDCCH-r16", cqi_npdcch_r16.to_string()); + j.write_str("spare", spare.to_string()); + j.end_obj(); +} + +// CQI-NPDCCH-NB-r14 ::= ENUMERATED +const char* cqi_npdcch_nb_r14_opts::to_string() const +{ + static const char* options[] = {"noMeasurements", + "candidateRep-A", + "candidateRep-B", + "candidateRep-C", + "candidateRep-D", + "candidateRep-E", + "candidateRep-F", + "candidateRep-G", + "candidateRep-H", + "candidateRep-I", + "candidateRep-J", + "candidateRep-K", + "candidateRep-L"}; + return convert_enum_idx(options, 13, value, "cqi_npdcch_nb_r14_e"); +} + +// ReestabUE-Identity-CP-NB-r14 ::= SEQUENCE +SRSASN_CODE reestab_ue_id_cp_nb_r14_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(s_tmsi_r14.pack(bref)); + HANDLE_CODE(ul_nas_mac_r14.pack(bref)); + HANDLE_CODE(ul_nas_count_r14.pack(bref)); + + return SRSASN_SUCCESS; } +SRSASN_CODE reestab_ue_id_cp_nb_r14_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(s_tmsi_r14.unpack(bref)); + HANDLE_CODE(ul_nas_mac_r14.unpack(bref)); + HANDLE_CODE(ul_nas_count_r14.unpack(bref)); -// UE-Capability-NB-r13 ::= SEQUENCE -SRSASN_CODE ue_cap_nb_r13_s::pack(bit_ref& bref) const + return SRSASN_SUCCESS; +} +void reestab_ue_id_cp_nb_r14_s::to_json(json_writer& j) const { - HANDLE_CODE(bref.pack(ue_category_nb_r13_present, 1)); - HANDLE_CODE(bref.pack(multiple_drb_r13_present, 1)); - HANDLE_CODE(bref.pack(pdcp_params_r13_present, 1)); - HANDLE_CODE(bref.pack(dummy_present, 1)); + j.start_obj(); + j.write_fieldname("s-TMSI-r14"); + s_tmsi_r14.to_json(j); + j.write_str("ul-NAS-MAC-r14", ul_nas_mac_r14.to_string()); + j.write_str("ul-NAS-Count-r14", ul_nas_count_r14.to_string()); + j.end_obj(); +} - HANDLE_CODE(access_stratum_release_r13.pack(bref)); - if (pdcp_params_r13_present) { - HANDLE_CODE(pdcp_params_r13.pack(bref)); - } - HANDLE_CODE(phy_layer_params_r13.pack(bref)); - HANDLE_CODE(rf_params_r13.pack(bref)); +// RRCConnectionReestablishmentRequest-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_request_nb_r13_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(ue_id_r13.pack(bref)); + HANDLE_CODE(reest_cause_r13.pack(bref)); + HANDLE_CODE(cqi_npdcch_r14.pack(bref)); + HANDLE_CODE(bref.pack(early_contention_resolution_r14, 1)); + HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE ue_cap_nb_r13_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_reest_request_nb_r13_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(ue_category_nb_r13_present, 1)); - HANDLE_CODE(bref.unpack(multiple_drb_r13_present, 1)); - HANDLE_CODE(bref.unpack(pdcp_params_r13_present, 1)); - HANDLE_CODE(bref.unpack(dummy_present, 1)); - - HANDLE_CODE(access_stratum_release_r13.unpack(bref)); - if (pdcp_params_r13_present) { - HANDLE_CODE(pdcp_params_r13.unpack(bref)); - } - HANDLE_CODE(phy_layer_params_r13.unpack(bref)); - HANDLE_CODE(rf_params_r13.unpack(bref)); + HANDLE_CODE(ue_id_r13.unpack(bref)); + HANDLE_CODE(reest_cause_r13.unpack(bref)); + HANDLE_CODE(cqi_npdcch_r14.unpack(bref)); + HANDLE_CODE(bref.unpack(early_contention_resolution_r14, 1)); + HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void ue_cap_nb_r13_s::to_json(json_writer& j) const +void rrc_conn_reest_request_nb_r13_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("accessStratumRelease-r13", access_stratum_release_r13.to_string()); - if (ue_category_nb_r13_present) { - j.write_str("ue-Category-NB-r13", "nb1"); - } - if (multiple_drb_r13_present) { - j.write_str("multipleDRB-r13", "supported"); - } - if (pdcp_params_r13_present) { - j.write_fieldname("pdcp-Parameters-r13"); - pdcp_params_r13.to_json(j); - } - j.write_fieldname("phyLayerParameters-r13"); - phy_layer_params_r13.to_json(j); - j.write_fieldname("rf-Parameters-r13"); - rf_params_r13.to_json(j); - if (dummy_present) { - j.write_fieldname("dummy"); - j.start_obj(); - j.end_obj(); - } + j.write_fieldname("ue-Identity-r13"); + ue_id_r13.to_json(j); + j.write_str("reestablishmentCause-r13", reest_cause_r13.to_string()); + j.write_str("cqi-NPDCCH-r14", cqi_npdcch_r14.to_string()); + j.write_bool("earlyContentionResolution-r14", early_contention_resolution_r14); + j.write_str("spare", spare.to_string()); j.end_obj(); } -// HandoverPreparationInformation-NB-IEs ::= SEQUENCE -SRSASN_CODE ho_prep_info_nb_ies_s::pack(bit_ref& bref) const +// RRCConnectionReestablishmentRequest-NB-r14-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_request_nb_r14_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(rrm_cfg_r13_present, 1)); - HANDLE_CODE(bref.pack(as_context_r13_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - HANDLE_CODE(ue_radio_access_cap_info_r13.pack(bref)); - HANDLE_CODE(as_cfg_r13.pack(bref)); - if (rrm_cfg_r13_present) { - HANDLE_CODE(rrm_cfg_r13.pack(bref)); - } - if (as_context_r13_present) { - HANDLE_CODE(as_context_r13.pack(bref)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); - } + HANDLE_CODE(ue_id_r14.pack(bref)); + HANDLE_CODE(reest_cause_r14.pack(bref)); + HANDLE_CODE(cqi_npdcch_r14.pack(bref)); + HANDLE_CODE(bref.pack(early_contention_resolution_r14, 1)); + HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE ho_prep_info_nb_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_reest_request_nb_r14_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(rrm_cfg_r13_present, 1)); - HANDLE_CODE(bref.unpack(as_context_r13_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - HANDLE_CODE(ue_radio_access_cap_info_r13.unpack(bref)); - HANDLE_CODE(as_cfg_r13.unpack(bref)); - if (rrm_cfg_r13_present) { - HANDLE_CODE(rrm_cfg_r13.unpack(bref)); - } - if (as_context_r13_present) { - HANDLE_CODE(as_context_r13.unpack(bref)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); - } + HANDLE_CODE(ue_id_r14.unpack(bref)); + HANDLE_CODE(reest_cause_r14.unpack(bref)); + HANDLE_CODE(cqi_npdcch_r14.unpack(bref)); + HANDLE_CODE(bref.unpack(early_contention_resolution_r14, 1)); + HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void ho_prep_info_nb_ies_s::to_json(json_writer& j) const +void rrc_conn_reest_request_nb_r14_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("ue-RadioAccessCapabilityInfo-r13"); - ue_radio_access_cap_info_r13.to_json(j); - j.write_fieldname("as-Config-r13"); - as_cfg_r13.to_json(j); - if (rrm_cfg_r13_present) { - j.write_fieldname("rrm-Config-r13"); - rrm_cfg_r13.to_json(j); - } - if (as_context_r13_present) { - j.write_fieldname("as-Context-r13"); - as_context_r13.to_json(j); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); - } + j.write_fieldname("ue-Identity-r14"); + ue_id_r14.to_json(j); + j.write_str("reestablishmentCause-r14", reest_cause_r14.to_string()); + j.write_str("cqi-NPDCCH-r14", cqi_npdcch_r14.to_string()); + j.write_bool("earlyContentionResolution-r14", early_contention_resolution_r14); + j.write_str("spare", spare.to_string()); j.end_obj(); } -// HandoverPreparationInformation-NB ::= SEQUENCE -SRSASN_CODE ho_prep_info_nb_s::pack(bit_ref& bref) const +// RRCConnectionReestablishmentRequest-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_reest_request_nb_s::pack(bit_ref& bref) const { HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE ho_prep_info_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_reest_request_nb_s::unpack(cbit_ref& bref) { HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void ho_prep_info_nb_s::to_json(json_writer& j) const +void rrc_conn_reest_request_nb_s::to_json(json_writer& j) const { j.start_obj(); j.write_fieldname("criticalExtensions"); @@ -15671,541 +21932,749 @@ void ho_prep_info_nb_s::to_json(json_writer& j) const j.end_obj(); } -void ho_prep_info_nb_s::crit_exts_c_::set(types::options e) +void rrc_conn_reest_request_nb_s::crit_exts_c_::destroy_() +{ + switch (type_) { + case types::rrc_conn_reest_request_r13: + c.destroy(); + break; + case types::later: + c.destroy(); + break; + default: + break; + } +} +void rrc_conn_reest_request_nb_s::crit_exts_c_::set(types::options e) { + destroy_(); type_ = e; + switch (type_) { + case types::rrc_conn_reest_request_r13: + c.init(); + break; + case types::later: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); + } } -ho_prep_info_nb_s::crit_exts_c_::c1_c_& ho_prep_info_nb_s::crit_exts_c_::set_c1() +rrc_conn_reest_request_nb_s::crit_exts_c_::crit_exts_c_(const rrc_conn_reest_request_nb_s::crit_exts_c_& other) { - set(types::c1); - return c; + type_ = other.type(); + switch (type_) { + case types::rrc_conn_reest_request_r13: + c.init(other.c.get()); + break; + case types::later: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); + } } -void ho_prep_info_nb_s::crit_exts_c_::set_crit_exts_future() +rrc_conn_reest_request_nb_s::crit_exts_c_& +rrc_conn_reest_request_nb_s::crit_exts_c_::operator=(const rrc_conn_reest_request_nb_s::crit_exts_c_& other) { - set(types::crit_exts_future); + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::rrc_conn_reest_request_r13: + c.set(other.c.get()); + break; + case types::later: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); + } + + return *this; } -void ho_prep_info_nb_s::crit_exts_c_::to_json(json_writer& j) const +rrc_conn_reest_request_nb_r13_ies_s& rrc_conn_reest_request_nb_s::crit_exts_c_::set_rrc_conn_reest_request_r13() +{ + set(types::rrc_conn_reest_request_r13); + return c.get(); +} +rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_& rrc_conn_reest_request_nb_s::crit_exts_c_::set_later() +{ + set(types::later); + return c.get(); +} +void rrc_conn_reest_request_nb_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::c1: - j.write_fieldname("c1"); - c.to_json(j); + case types::rrc_conn_reest_request_r13: + j.write_fieldname("rrcConnectionReestablishmentRequest-r13"); + c.get().to_json(j); break; - case types::crit_exts_future: + case types::later: + j.write_fieldname("later"); + c.get().to_json(j); break; default: - log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE ho_prep_info_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_reest_request_nb_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::c1: - HANDLE_CODE(c.pack(bref)); + case types::rrc_conn_reest_request_r13: + HANDLE_CODE(c.get().pack(bref)); break; - case types::crit_exts_future: + case types::later: + HANDLE_CODE(c.get().pack(bref)); break; default: - log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE ho_prep_info_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_reest_request_nb_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::c1: - HANDLE_CODE(c.unpack(bref)); + case types::rrc_conn_reest_request_r13: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::crit_exts_future: + case types::later: + HANDLE_CODE(c.get().unpack(bref)); break; default: - log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void ho_prep_info_nb_s::crit_exts_c_::c1_c_::set(types::options e) -{ - type_ = e; -} -ho_prep_info_nb_ies_s& ho_prep_info_nb_s::crit_exts_c_::c1_c_::set_ho_prep_info_r13() +void rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::destroy_() { - set(types::ho_prep_info_r13); - return c; -} -void ho_prep_info_nb_s::crit_exts_c_::c1_c_::set_spare3() -{ - set(types::spare3); -} -void ho_prep_info_nb_s::crit_exts_c_::c1_c_::set_spare2() -{ - set(types::spare2); -} -void ho_prep_info_nb_s::crit_exts_c_::c1_c_::set_spare1() -{ - set(types::spare1); + switch (type_) { + case types::rrc_conn_reest_request_r14: + c.destroy(); + break; + case types::later: + c.destroy(); + break; + default: + break; + } } -void ho_prep_info_nb_s::crit_exts_c_::c1_c_::to_json(json_writer& j) const +void rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::set(types::options e) { - j.start_obj(); + destroy_(); + type_ = e; switch (type_) { - case types::ho_prep_info_r13: - j.write_fieldname("handoverPreparationInformation-r13"); - c.to_json(j); - break; - case types::spare3: + case types::rrc_conn_reest_request_r14: + c.init(); break; - case types::spare2: + case types::later: + c.init(); break; - case types::spare1: + case types::nulltype: break; default: - log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_::c1_c_"); + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_"); } - j.end_obj(); } -SRSASN_CODE ho_prep_info_nb_s::crit_exts_c_::c1_c_::pack(bit_ref& bref) const +rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c_( + const rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_& other) { - type_.pack(bref); + type_ = other.type(); switch (type_) { - case types::ho_prep_info_r13: - HANDLE_CODE(c.pack(bref)); - break; - case types::spare3: + case types::rrc_conn_reest_request_r14: + c.init(other.c.get()); break; - case types::spare2: + case types::later: + c.init(other.c.get()); break; - case types::spare1: + case types::nulltype: break; default: - log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_::c1_c_"); - return SRSASN_ERROR_ENCODE_FAIL; + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_"); } - return SRSASN_SUCCESS; } -SRSASN_CODE ho_prep_info_nb_s::crit_exts_c_::c1_c_::unpack(cbit_ref& bref) +rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_& rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::operator=( + const rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_& other) { - types e; - e.unpack(bref); - set(e); + if (this == &other) { + return *this; + } + set(other.type()); switch (type_) { - case types::ho_prep_info_r13: - HANDLE_CODE(c.unpack(bref)); - break; - case types::spare3: + case types::rrc_conn_reest_request_r14: + c.set(other.c.get()); break; - case types::spare2: + case types::later: + c.set(other.c.get()); break; - case types::spare1: + case types::nulltype: break; default: - log_invalid_choice_id(type_, "ho_prep_info_nb_s::crit_exts_c_::c1_c_"); - return SRSASN_ERROR_DECODE_FAIL; + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_"); } - return SRSASN_SUCCESS; -} - -const char* ho_prep_info_nb_s::crit_exts_c_::c1_c_::types_opts::to_string() const -{ - static const char* options[] = {"handoverPreparationInformation-r13", "spare3", "spare2", "spare1"}; - return convert_enum_idx(options, 4, value, "ho_prep_info_nb_s::crit_exts_c_::c1_c_::types"); -} - -// MeasResultServCell-NB-r14 ::= SEQUENCE -SRSASN_CODE meas_result_serv_cell_nb_r14_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, nrsrp_result_r14, (uint8_t)0u, (uint8_t)113u)); - HANDLE_CODE(pack_integer(bref, nrsrq_result_r14, (int8_t)-30, (int8_t)46)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE meas_result_serv_cell_nb_r14_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(nrsrp_result_r14, bref, (uint8_t)0u, (uint8_t)113u)); - HANDLE_CODE(unpack_integer(nrsrq_result_r14, bref, (int8_t)-30, (int8_t)46)); - return SRSASN_SUCCESS; -} -void meas_result_serv_cell_nb_r14_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("nrsrpResult-r14", nrsrp_result_r14); - j.write_int("nrsrqResult-r14", nrsrq_result_r14); - j.end_obj(); + return *this; } - -// PagingRecord-NB-r13 ::= SEQUENCE -SRSASN_CODE paging_record_nb_r13_s::pack(bit_ref& bref) const +rrc_conn_reest_request_nb_r14_ies_s& +rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::set_rrc_conn_reest_request_r14() { - bref.pack(ext, 1); - HANDLE_CODE(ue_id_r13.pack(bref)); - - return SRSASN_SUCCESS; + set(types::rrc_conn_reest_request_r14); + return c.get(); } -SRSASN_CODE paging_record_nb_r13_s::unpack(cbit_ref& bref) +rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__& +rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::set_later() { - bref.unpack(ext, 1); - HANDLE_CODE(ue_id_r13.unpack(bref)); - - return SRSASN_SUCCESS; + set(types::later); + return c.get(); } -void paging_record_nb_r13_s::to_json(json_writer& j) const +void rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("ue-Identity-r13"); - ue_id_r13.to_json(j); + switch (type_) { + case types::rrc_conn_reest_request_r14: + j.write_fieldname("rrcConnectionReestablishmentRequest-r14"); + c.get().to_json(j); + break; + case types::later: + j.write_fieldname("later"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_"); + } j.end_obj(); } - -// Paging-NB ::= SEQUENCE -SRSASN_CODE paging_nb_s::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(paging_record_list_r13_present, 1)); - HANDLE_CODE(bref.pack(sys_info_mod_r13_present, 1)); - HANDLE_CODE(bref.pack(sys_info_mod_e_drx_r13_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - if (paging_record_list_r13_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, paging_record_list_r13, 1, 16)); + type_.pack(bref); + switch (type_) { + case types::rrc_conn_reest_request_r14: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::later: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_"); + return SRSASN_ERROR_ENCODE_FAIL; } - return SRSASN_SUCCESS; } -SRSASN_CODE paging_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(paging_record_list_r13_present, 1)); - HANDLE_CODE(bref.unpack(sys_info_mod_r13_present, 1)); - HANDLE_CODE(bref.unpack(sys_info_mod_e_drx_r13_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - if (paging_record_list_r13_present) { - HANDLE_CODE(unpack_dyn_seq_of(paging_record_list_r13, bref, 1, 16)); + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rrc_conn_reest_request_r14: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::later: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_"); + return SRSASN_ERROR_DECODE_FAIL; } - return SRSASN_SUCCESS; } -void paging_nb_s::to_json(json_writer& j) const -{ - j.start_obj(); - if (paging_record_list_r13_present) { - j.start_array("pagingRecordList-r13"); - for (const auto& e1 : paging_record_list_r13) { - e1.to_json(j); - } - j.end_array(); - } - if (sys_info_mod_r13_present) { - j.write_str("systemInfoModification-r13", "true"); - } - if (sys_info_mod_e_drx_r13_present) { - j.write_str("systemInfoModification-eDRX-r13", "true"); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); - } - j.end_obj(); -} -// PCCH-MessageType-NB ::= CHOICE -void pcch_msg_type_nb_c::set(types::options e) +void rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__::set(types::options e) { type_ = e; } -pcch_msg_type_nb_c::c1_c_& pcch_msg_type_nb_c::set_c1() +rrc_conn_reest_request_minus5_gc_nb_r16_ies_s& +rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__::set_rrc_conn_reest_request_r16() { - set(types::c1); + set(types::rrc_conn_reest_request_r16); return c; } -void pcch_msg_type_nb_c::set_msg_class_ext() +void rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__::set_crit_exts_future() { - set(types::msg_class_ext); + set(types::crit_exts_future); } -void pcch_msg_type_nb_c::to_json(json_writer& j) const +void rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::c1: - j.write_fieldname("c1"); + case types::rrc_conn_reest_request_r16: + j.write_fieldname("rrcConnectionReestablishmentRequest-r16"); c.to_json(j); break; - case types::msg_class_ext: + case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "pcch_msg_type_nb_c"); + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__"); } j.end_obj(); } -SRSASN_CODE pcch_msg_type_nb_c::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::c1: + case types::rrc_conn_reest_request_r16: HANDLE_CODE(c.pack(bref)); break; - case types::msg_class_ext: + case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "pcch_msg_type_nb_c"); + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE pcch_msg_type_nb_c::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::c1: + case types::rrc_conn_reest_request_r16: HANDLE_CODE(c.unpack(bref)); break; - case types::msg_class_ext: + case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "pcch_msg_type_nb_c"); + log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void pcch_msg_type_nb_c::c1_c_::to_json(json_writer& j) const +const char* rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__::types_opts::to_string() const { - j.start_obj(); - j.write_fieldname("paging-r13"); - c.to_json(j); - j.end_obj(); + static const char* options[] = {"rrcConnectionReestablishmentRequest-r16", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::later_c__::types"); +} + +const char* rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::types_opts::to_string() const +{ + static const char* options[] = {"rrcConnectionReestablishmentRequest-r14", "later"}; + return convert_enum_idx(options, 2, value, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::types"); +} + +const char* rrc_conn_reest_request_nb_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"rrcConnectionReestablishmentRequest-r13", "later"}; + return convert_enum_idx(options, 2, value, "rrc_conn_reest_request_nb_s::crit_exts_c_::types"); } -SRSASN_CODE pcch_msg_type_nb_c::c1_c_::pack(bit_ref& bref) const + +// RRCConnectionRequest-5GC-NB-r16-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_request_minus5_gc_nb_r16_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(c.pack(bref)); + HANDLE_CODE(ue_id_r16.pack(bref)); + HANDLE_CODE(establishment_cause_r16.pack(bref)); + HANDLE_CODE(cqi_npdcch_r16.pack(bref)); + HANDLE_CODE(spare.pack(bref)); + return SRSASN_SUCCESS; } -SRSASN_CODE pcch_msg_type_nb_c::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_request_minus5_gc_nb_r16_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(c.unpack(bref)); + HANDLE_CODE(ue_id_r16.unpack(bref)); + HANDLE_CODE(establishment_cause_r16.unpack(bref)); + HANDLE_CODE(cqi_npdcch_r16.unpack(bref)); + HANDLE_CODE(spare.unpack(bref)); + return SRSASN_SUCCESS; } - -const char* pcch_msg_type_nb_c::c1_c_::types_opts::to_string() const +void rrc_conn_request_minus5_gc_nb_r16_ies_s::to_json(json_writer& j) const { - static const char* options[] = {"paging-r13"}; - return convert_enum_idx(options, 1, value, "pcch_msg_type_nb_c::c1_c_::types"); + j.start_obj(); + j.write_fieldname("ue-Identity-r16"); + ue_id_r16.to_json(j); + j.write_str("establishmentCause-r16", establishment_cause_r16.to_string()); + j.write_str("cqi-NPDCCH-r16", cqi_npdcch_r16.to_string()); + j.write_str("spare", spare.to_string()); + j.end_obj(); } -const char* pcch_msg_type_nb_c::types_opts::to_string() const +const char* rrc_conn_request_minus5_gc_nb_r16_ies_s::establishment_cause_r16_opts::to_string() const { - static const char* options[] = {"c1", "messageClassExtension"}; - return convert_enum_idx(options, 2, value, "pcch_msg_type_nb_c::types"); + static const char* options[] = { + "mt-Access", "mo-Signalling", "mo-Data", "mo-ExceptionData", "spare4", "spare3", "spare2", "spare1"}; + return convert_enum_idx(options, 8, value, "rrc_conn_request_minus5_gc_nb_r16_ies_s::establishment_cause_r16_e_"); } -uint8_t pcch_msg_type_nb_c::types_opts::to_number() const + +// EstablishmentCause-NB-r13 ::= ENUMERATED +const char* establishment_cause_nb_r13_opts::to_string() const { - static const uint8_t options[] = {1}; - return map_enum_number(options, 1, value, "pcch_msg_type_nb_c::types"); + static const char* options[] = {"mt-Access", + "mo-Signalling", + "mo-Data", + "mo-ExceptionData", + "delayTolerantAccess-v1330", + "mt-EDT-v1610", + "spare2", + "spare1"}; + return convert_enum_idx(options, 8, value, "establishment_cause_nb_r13_e"); } -// PCCH-Message-NB ::= SEQUENCE -SRSASN_CODE pcch_msg_nb_s::pack(bit_ref& bref) const +// RRCConnectionRequest-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_request_nb_r13_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(msg.pack(bref)); + HANDLE_CODE(bref.pack(multi_tone_support_r13_present, 1)); + HANDLE_CODE(bref.pack(multi_carrier_support_r13_present, 1)); - bref.align_bytes_zero(); + HANDLE_CODE(ue_id_r13.pack(bref)); + HANDLE_CODE(establishment_cause_r13.pack(bref)); + HANDLE_CODE(bref.pack(early_contention_resolution_r14, 1)); + HANDLE_CODE(cqi_npdcch_r14.pack(bref)); + HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE pcch_msg_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_request_nb_r13_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(msg.unpack(bref)); + HANDLE_CODE(bref.unpack(multi_tone_support_r13_present, 1)); + HANDLE_CODE(bref.unpack(multi_carrier_support_r13_present, 1)); - bref.align_bytes(); + HANDLE_CODE(ue_id_r13.unpack(bref)); + HANDLE_CODE(establishment_cause_r13.unpack(bref)); + HANDLE_CODE(bref.unpack(early_contention_resolution_r14, 1)); + HANDLE_CODE(cqi_npdcch_r14.unpack(bref)); + HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void pcch_msg_nb_s::to_json(json_writer& j) const +void rrc_conn_request_nb_r13_ies_s::to_json(json_writer& j) const { - j.start_array(); j.start_obj(); - j.start_obj("PCCH-Message-NB"); - j.write_fieldname("message"); - msg.to_json(j); - j.end_obj(); + j.write_fieldname("ue-Identity-r13"); + ue_id_r13.to_json(j); + j.write_str("establishmentCause-r13", establishment_cause_r13.to_string()); + if (multi_tone_support_r13_present) { + j.write_str("multiToneSupport-r13", "true"); + } + if (multi_carrier_support_r13_present) { + j.write_str("multiCarrierSupport-r13", "true"); + } + j.write_bool("earlyContentionResolution-r14", early_contention_resolution_r14); + j.write_str("cqi-NPDCCH-r14", cqi_npdcch_r14.to_string()); + j.write_str("spare", spare.to_string()); j.end_obj(); - j.end_array(); } -// PCI-ARFCN-NB-r14 ::= SEQUENCE -SRSASN_CODE pci_arfcn_nb_r14_s::pack(bit_ref& bref) const +// RRCConnectionRequest-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_request_nb_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(carrier_freq_r14_present, 1)); - - HANDLE_CODE(pack_integer(bref, pci_r14, (uint16_t)0u, (uint16_t)503u)); - if (carrier_freq_r14_present) { - HANDLE_CODE(carrier_freq_r14.pack(bref)); - } + HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE pci_arfcn_nb_r14_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_request_nb_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(carrier_freq_r14_present, 1)); - - HANDLE_CODE(unpack_integer(pci_r14, bref, (uint16_t)0u, (uint16_t)503u)); - if (carrier_freq_r14_present) { - HANDLE_CODE(carrier_freq_r14.unpack(bref)); - } + HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void pci_arfcn_nb_r14_s::to_json(json_writer& j) const +void rrc_conn_request_nb_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("physCellId-r14", pci_r14); - if (carrier_freq_r14_present) { - j.write_fieldname("carrierFreq-r14"); - carrier_freq_r14.to_json(j); - } + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); j.end_obj(); } -// RRCConnectionReconfigurationComplete-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_recfg_complete_nb_r13_ies_s::pack(bit_ref& bref) const +void rrc_conn_request_nb_s::crit_exts_c_::destroy_() { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); + switch (type_) { + case types::rrc_conn_request_r13: + c.destroy(); + break; + case types::later: + c.destroy(); + break; + default: + break; } - - return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_recfg_complete_nb_r13_ies_s::unpack(cbit_ref& bref) +void rrc_conn_request_nb_s::crit_exts_c_::set(types::options e) { - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + destroy_(); + type_ = e; + switch (type_) { + case types::rrc_conn_request_r13: + c.init(); + break; + case types::later: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_"); } - - return SRSASN_SUCCESS; } -void rrc_conn_recfg_complete_nb_r13_ies_s::to_json(json_writer& j) const +rrc_conn_request_nb_s::crit_exts_c_::crit_exts_c_(const rrc_conn_request_nb_s::crit_exts_c_& other) { - j.start_obj(); - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + type_ = other.type(); + switch (type_) { + case types::rrc_conn_request_r13: + c.init(other.c.get()); + break; + case types::later: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_"); } - j.end_obj(); } - -// RRCConnectionReconfigurationComplete-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_recfg_complete_nb_s::pack(bit_ref& bref) const +rrc_conn_request_nb_s::crit_exts_c_& +rrc_conn_request_nb_s::crit_exts_c_::operator=(const rrc_conn_request_nb_s::crit_exts_c_& other) { - HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.pack(bref)); + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::rrc_conn_request_r13: + c.set(other.c.get()); + break; + case types::later: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_"); + } - return SRSASN_SUCCESS; + return *this; } -SRSASN_CODE rrc_conn_recfg_complete_nb_s::unpack(cbit_ref& bref) +rrc_conn_request_nb_r13_ies_s& rrc_conn_request_nb_s::crit_exts_c_::set_rrc_conn_request_r13() { - HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.unpack(bref)); - - return SRSASN_SUCCESS; + set(types::rrc_conn_request_r13); + return c.get(); } -void rrc_conn_recfg_complete_nb_s::to_json(json_writer& j) const +rrc_conn_request_nb_s::crit_exts_c_::later_c_& rrc_conn_request_nb_s::crit_exts_c_::set_later() +{ + set(types::later); + return c.get(); +} +void rrc_conn_request_nb_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); - j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); - j.write_fieldname("criticalExtensions"); - crit_exts.to_json(j); + switch (type_) { + case types::rrc_conn_request_r13: + j.write_fieldname("rrcConnectionRequest-r13"); + c.get().to_json(j); + break; + case types::later: + j.write_fieldname("later"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_"); + } j.end_obj(); } +SRSASN_CODE rrc_conn_request_nb_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::rrc_conn_request_r13: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::later: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_request_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rrc_conn_request_r13: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::later: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} -void rrc_conn_recfg_complete_nb_s::crit_exts_c_::set(types::options e) +void rrc_conn_request_nb_s::crit_exts_c_::later_c_::set(types::options e) { type_ = e; } -rrc_conn_recfg_complete_nb_r13_ies_s& rrc_conn_recfg_complete_nb_s::crit_exts_c_::set_rrc_conn_recfg_complete_r13() +rrc_conn_request_minus5_gc_nb_r16_ies_s& rrc_conn_request_nb_s::crit_exts_c_::later_c_::set_rrc_conn_request_r16() { - set(types::rrc_conn_recfg_complete_r13); + set(types::rrc_conn_request_r16); return c; } -void rrc_conn_recfg_complete_nb_s::crit_exts_c_::set_crit_exts_future() +void rrc_conn_request_nb_s::crit_exts_c_::later_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void rrc_conn_recfg_complete_nb_s::crit_exts_c_::to_json(json_writer& j) const +void rrc_conn_request_nb_s::crit_exts_c_::later_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_conn_recfg_complete_r13: - j.write_fieldname("rrcConnectionReconfigurationComplete-r13"); + case types::rrc_conn_request_r16: + j.write_fieldname("rrcConnectionRequest-r16"); c.to_json(j); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_recfg_complete_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_::later_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_recfg_complete_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_request_nb_s::crit_exts_c_::later_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_conn_recfg_complete_r13: + case types::rrc_conn_request_r16: HANDLE_CODE(c.pack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_recfg_complete_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_::later_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_recfg_complete_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_request_nb_s::crit_exts_c_::later_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_conn_recfg_complete_r13: + case types::rrc_conn_request_r16: HANDLE_CODE(c.unpack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_recfg_complete_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_::later_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* rrc_conn_recfg_complete_nb_s::crit_exts_c_::types_opts::to_string() const +const char* rrc_conn_request_nb_s::crit_exts_c_::later_c_::types_opts::to_string() const { - static const char* options[] = {"rrcConnectionReconfigurationComplete-r13", "criticalExtensionsFuture"}; - return convert_enum_idx(options, 2, value, "rrc_conn_recfg_complete_nb_s::crit_exts_c_::types"); + static const char* options[] = {"rrcConnectionRequest-r16", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "rrc_conn_request_nb_s::crit_exts_c_::later_c_::types"); } -// RRCConnectionReestablishmentComplete-NB-v1470-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_reest_complete_nb_v1470_ies_s::pack(bit_ref& bref) const +const char* rrc_conn_request_nb_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"rrcConnectionRequest-r13", "later"}; + return convert_enum_idx(options, 2, value, "rrc_conn_request_nb_s::crit_exts_c_::types"); +} + +// RRCConnectionResumeComplete-NB-v1710-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_complete_nb_v1710_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_resume_complete_nb_v1710_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_resume_complete_nb_v1710_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (gnss_validity_dur_r17_present) { + j.write_str("gnss-ValidityDuration-r17", gnss_validity_dur_r17.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// RRCConnectionResumeComplete-NB-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_complete_nb_v1610_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(rlf_info_available_r16_present, 1)); + HANDLE_CODE(bref.pack(anr_info_available_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE rrc_conn_resume_complete_nb_v1610_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(rlf_info_available_r16_present, 1)); + HANDLE_CODE(bref.unpack(anr_info_available_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void rrc_conn_resume_complete_nb_v1610_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (rlf_info_available_r16_present) { + j.write_str("rlf-InfoAvailable-r16", "true"); + } + if (anr_info_available_r16_present) { + j.write_str("anr-InfoAvailable-r16", "true"); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// RRCConnectionResumeComplete-NB-v1470-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_complete_nb_v1470_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(meas_result_serv_cell_r14_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); @@ -16213,10 +22682,13 @@ SRSASN_CODE rrc_conn_reest_complete_nb_v1470_ies_s::pack(bit_ref& bref) const if (meas_result_serv_cell_r14_present) { HANDLE_CODE(meas_result_serv_cell_r14.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_complete_nb_v1470_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_complete_nb_v1470_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(meas_result_serv_cell_r14_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -16224,10 +22696,13 @@ SRSASN_CODE rrc_conn_reest_complete_nb_v1470_ies_s::unpack(cbit_ref& bref) if (meas_result_serv_cell_r14_present) { HANDLE_CODE(meas_result_serv_cell_r14.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } -void rrc_conn_reest_complete_nb_v1470_ies_s::to_json(json_writer& j) const +void rrc_conn_resume_complete_nb_v1470_ies_s::to_json(json_writer& j) const { j.start_obj(); if (meas_result_serv_cell_r14_present) { @@ -16236,18 +22711,25 @@ void rrc_conn_reest_complete_nb_v1470_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } -// RRCConnectionReestablishmentComplete-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_reest_complete_nb_r13_ies_s::pack(bit_ref& bref) const +// RRCConnectionResumeComplete-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_complete_nb_r13_ies_s::pack(bit_ref& bref) const { + HANDLE_CODE(bref.pack(sel_plmn_id_r13_present, 1)); + HANDLE_CODE(bref.pack(ded_info_nas_r13_present, 1)); HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + if (sel_plmn_id_r13_present) { + HANDLE_CODE(pack_integer(bref, sel_plmn_id_r13, (uint8_t)1u, (uint8_t)6u)); + } + if (ded_info_nas_r13_present) { + HANDLE_CODE(ded_info_nas_r13.pack(bref)); + } if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -16257,11 +22739,19 @@ SRSASN_CODE rrc_conn_reest_complete_nb_r13_ies_s::pack(bit_ref& bref) const return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_complete_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_complete_nb_r13_ies_s::unpack(cbit_ref& bref) { + HANDLE_CODE(bref.unpack(sel_plmn_id_r13_present, 1)); + HANDLE_CODE(bref.unpack(ded_info_nas_r13_present, 1)); HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + if (sel_plmn_id_r13_present) { + HANDLE_CODE(unpack_integer(sel_plmn_id_r13, bref, (uint8_t)1u, (uint8_t)6u)); + } + if (ded_info_nas_r13_present) { + HANDLE_CODE(ded_info_nas_r13.unpack(bref)); + } if (late_non_crit_ext_present) { HANDLE_CODE(late_non_crit_ext.unpack(bref)); } @@ -16271,9 +22761,15 @@ SRSASN_CODE rrc_conn_reest_complete_nb_r13_ies_s::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -void rrc_conn_reest_complete_nb_r13_ies_s::to_json(json_writer& j) const +void rrc_conn_resume_complete_nb_r13_ies_s::to_json(json_writer& j) const { j.start_obj(); + if (sel_plmn_id_r13_present) { + j.write_int("selectedPLMN-Identity-r13", sel_plmn_id_r13); + } + if (ded_info_nas_r13_present) { + j.write_str("dedicatedInfoNAS-r13", ded_info_nas_r13.to_string()); + } if (late_non_crit_ext_present) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } @@ -16284,22 +22780,22 @@ void rrc_conn_reest_complete_nb_r13_ies_s::to_json(json_writer& j) const j.end_obj(); } -// RRCConnectionReestablishmentComplete-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_reest_complete_nb_s::pack(bit_ref& bref) const +// RRCConnectionResumeComplete-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_complete_nb_s::pack(bit_ref& bref) const { HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_complete_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_complete_nb_s::unpack(cbit_ref& bref) { HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void rrc_conn_reest_complete_nb_s::to_json(json_writer& j) const +void rrc_conn_resume_complete_nb_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); @@ -16308,227 +22804,157 @@ void rrc_conn_reest_complete_nb_s::to_json(json_writer& j) const j.end_obj(); } -void rrc_conn_reest_complete_nb_s::crit_exts_c_::set(types::options e) +void rrc_conn_resume_complete_nb_s::crit_exts_c_::set(types::options e) { type_ = e; } -rrc_conn_reest_complete_nb_r13_ies_s& rrc_conn_reest_complete_nb_s::crit_exts_c_::set_rrc_conn_reest_complete_r13() +rrc_conn_resume_complete_nb_r13_ies_s& rrc_conn_resume_complete_nb_s::crit_exts_c_::set_rrc_conn_resume_complete_r13() { - set(types::rrc_conn_reest_complete_r13); + set(types::rrc_conn_resume_complete_r13); return c; } -void rrc_conn_reest_complete_nb_s::crit_exts_c_::set_crit_exts_future() +void rrc_conn_resume_complete_nb_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void rrc_conn_reest_complete_nb_s::crit_exts_c_::to_json(json_writer& j) const +void rrc_conn_resume_complete_nb_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_conn_reest_complete_r13: - j.write_fieldname("rrcConnectionReestablishmentComplete-r13"); + case types::rrc_conn_resume_complete_r13: + j.write_fieldname("rrcConnectionResumeComplete-r13"); c.to_json(j); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_complete_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_complete_nb_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_reest_complete_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_resume_complete_nb_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_conn_reest_complete_r13: + case types::rrc_conn_resume_complete_r13: HANDLE_CODE(c.pack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_complete_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_complete_nb_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_complete_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_complete_nb_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_conn_reest_complete_r13: + case types::rrc_conn_resume_complete_r13: HANDLE_CODE(c.unpack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_complete_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_complete_nb_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* rrc_conn_reest_complete_nb_s::crit_exts_c_::types_opts::to_string() const -{ - static const char* options[] = {"rrcConnectionReestablishmentComplete-r13", "criticalExtensionsFuture"}; - return convert_enum_idx(options, 2, value, "rrc_conn_reest_complete_nb_s::crit_exts_c_::types"); -} - -// CQI-NPDCCH-NB-r14 ::= ENUMERATED -const char* cqi_npdcch_nb_r14_opts::to_string() const -{ - static const char* options[] = {"noMeasurements", - "candidateRep-A", - "candidateRep-B", - "candidateRep-C", - "candidateRep-D", - "candidateRep-E", - "candidateRep-F", - "candidateRep-G", - "candidateRep-H", - "candidateRep-I", - "candidateRep-J", - "candidateRep-K", - "candidateRep-L"}; - return convert_enum_idx(options, 13, value, "cqi_npdcch_nb_r14_e"); -} - -// CQI-NPDCCH-Short-NB-r14 ::= ENUMERATED -const char* cqi_npdcch_short_nb_r14_opts::to_string() const -{ - static const char* options[] = {"noMeasurements", "candidateRep-1", "candidateRep-2", "candidateRep-3"}; - return convert_enum_idx(options, 4, value, "cqi_npdcch_short_nb_r14_e"); -} -int8_t cqi_npdcch_short_nb_r14_opts::to_number() const -{ - switch (value) { - case candidate_rep_minus1: - return -1; - case candidate_rep_minus2: - return -2; - case candidate_rep_minus3: - return -3; - default: - invalid_enum_number(value, "cqi_npdcch_short_nb_r14_e"); - } - return 0; -} - -// ReestabUE-Identity-CP-NB-r14 ::= SEQUENCE -SRSASN_CODE reestab_ue_id_cp_nb_r14_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(s_tmsi_r14.pack(bref)); - HANDLE_CODE(ul_nas_mac_r14.pack(bref)); - HANDLE_CODE(ul_nas_count_r14.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE reestab_ue_id_cp_nb_r14_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(s_tmsi_r14.unpack(bref)); - HANDLE_CODE(ul_nas_mac_r14.unpack(bref)); - HANDLE_CODE(ul_nas_count_r14.unpack(bref)); - - return SRSASN_SUCCESS; -} -void reestab_ue_id_cp_nb_r14_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("s-TMSI-r14"); - s_tmsi_r14.to_json(j); - j.write_str("ul-NAS-MAC-r14", ul_nas_mac_r14.to_string()); - j.write_str("ul-NAS-Count-r14", ul_nas_count_r14.to_string()); - j.end_obj(); -} - -// ReestablishmentCause-NB-r13 ::= ENUMERATED -const char* reest_cause_nb_r13_opts::to_string() const +const char* rrc_conn_resume_complete_nb_s::crit_exts_c_::types_opts::to_string() const { - static const char* options[] = {"reconfigurationFailure", "otherFailure", "spare2", "spare1"}; - return convert_enum_idx(options, 4, value, "reest_cause_nb_r13_e"); + static const char* options[] = {"rrcConnectionResumeComplete-r13", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "rrc_conn_resume_complete_nb_s::crit_exts_c_::types"); } -// RRCConnectionReestablishmentRequest-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_reest_request_nb_r13_ies_s::pack(bit_ref& bref) const +// RRCConnectionResumeRequest-5GC-NB-r16-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_request_minus5_gc_nb_r16_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(ue_id_r13.pack(bref)); - HANDLE_CODE(reest_cause_r13.pack(bref)); - HANDLE_CODE(cqi_npdcch_r14.pack(bref)); - HANDLE_CODE(bref.pack(early_contention_resolution_r14, 1)); + HANDLE_CODE(resume_id_r16.pack(bref)); + HANDLE_CODE(short_resume_mac_i_r16.pack(bref)); + HANDLE_CODE(resume_cause_r16.pack(bref)); + HANDLE_CODE(cqi_npdcch_r16.pack(bref)); HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_request_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_request_minus5_gc_nb_r16_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(ue_id_r13.unpack(bref)); - HANDLE_CODE(reest_cause_r13.unpack(bref)); - HANDLE_CODE(cqi_npdcch_r14.unpack(bref)); - HANDLE_CODE(bref.unpack(early_contention_resolution_r14, 1)); + HANDLE_CODE(resume_id_r16.unpack(bref)); + HANDLE_CODE(short_resume_mac_i_r16.unpack(bref)); + HANDLE_CODE(resume_cause_r16.unpack(bref)); + HANDLE_CODE(cqi_npdcch_r16.unpack(bref)); HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void rrc_conn_reest_request_nb_r13_ies_s::to_json(json_writer& j) const +void rrc_conn_resume_request_minus5_gc_nb_r16_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("ue-Identity-r13"); - ue_id_r13.to_json(j); - j.write_str("reestablishmentCause-r13", reest_cause_r13.to_string()); - j.write_str("cqi-NPDCCH-r14", cqi_npdcch_r14.to_string()); - j.write_bool("earlyContentionResolution-r14", early_contention_resolution_r14); + j.write_str("resumeID-r16", resume_id_r16.to_string()); + j.write_str("shortResumeMAC-I-r16", short_resume_mac_i_r16.to_string()); + j.write_str("resumeCause-r16", resume_cause_r16.to_string()); + j.write_str("cqi-NPDCCH-r16", cqi_npdcch_r16.to_string()); j.write_str("spare", spare.to_string()); j.end_obj(); } -// RRCConnectionReestablishmentRequest-NB-r14-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_reest_request_nb_r14_ies_s::pack(bit_ref& bref) const +// RRCConnectionResumeRequest-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_request_nb_r13_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(ue_id_r14.pack(bref)); - HANDLE_CODE(reest_cause_r14.pack(bref)); - HANDLE_CODE(cqi_npdcch_r14.pack(bref)); + HANDLE_CODE(resume_id_r13.pack(bref)); + HANDLE_CODE(short_resume_mac_i_r13.pack(bref)); + HANDLE_CODE(resume_cause_r13.pack(bref)); HANDLE_CODE(bref.pack(early_contention_resolution_r14, 1)); + HANDLE_CODE(cqi_npdcch_r14.pack(bref)); + HANDLE_CODE(bref.pack(anr_info_available_r16, 1)); HANDLE_CODE(spare.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_request_nb_r14_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_request_nb_r13_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(ue_id_r14.unpack(bref)); - HANDLE_CODE(reest_cause_r14.unpack(bref)); - HANDLE_CODE(cqi_npdcch_r14.unpack(bref)); + HANDLE_CODE(resume_id_r13.unpack(bref)); + HANDLE_CODE(short_resume_mac_i_r13.unpack(bref)); + HANDLE_CODE(resume_cause_r13.unpack(bref)); HANDLE_CODE(bref.unpack(early_contention_resolution_r14, 1)); + HANDLE_CODE(cqi_npdcch_r14.unpack(bref)); + HANDLE_CODE(bref.unpack(anr_info_available_r16, 1)); HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void rrc_conn_reest_request_nb_r14_ies_s::to_json(json_writer& j) const +void rrc_conn_resume_request_nb_r13_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("ue-Identity-r14"); - ue_id_r14.to_json(j); - j.write_str("reestablishmentCause-r14", reest_cause_r14.to_string()); - j.write_str("cqi-NPDCCH-r14", cqi_npdcch_r14.to_string()); + j.write_str("resumeID-r13", resume_id_r13.to_string()); + j.write_str("shortResumeMAC-I-r13", short_resume_mac_i_r13.to_string()); + j.write_str("resumeCause-r13", resume_cause_r13.to_string()); j.write_bool("earlyContentionResolution-r14", early_contention_resolution_r14); + j.write_str("cqi-NPDCCH-r14", cqi_npdcch_r14.to_string()); + j.write_bool("anr-InfoAvailable-r16", anr_info_available_r16); j.write_str("spare", spare.to_string()); j.end_obj(); } -// RRCConnectionReestablishmentRequest-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_reest_request_nb_s::pack(bit_ref& bref) const +// RRCConnectionResumeRequest-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_resume_request_nb_s::pack(bit_ref& bref) const { HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_request_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_request_nb_s::unpack(cbit_ref& bref) { HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void rrc_conn_reest_request_nb_s::to_json(json_writer& j) const +void rrc_conn_resume_request_nb_s::to_json(json_writer& j) const { j.start_obj(); j.write_fieldname("criticalExtensions"); @@ -16536,11 +22962,11 @@ void rrc_conn_reest_request_nb_s::to_json(json_writer& j) const j.end_obj(); } -void rrc_conn_reest_request_nb_s::crit_exts_c_::destroy_() +void rrc_conn_resume_request_nb_s::crit_exts_c_::destroy_() { switch (type_) { - case types::rrc_conn_reest_request_r13: - c.destroy(); + case types::rrc_conn_resume_request_r13: + c.destroy(); break; case types::later: c.destroy(); @@ -16549,13 +22975,13 @@ void rrc_conn_reest_request_nb_s::crit_exts_c_::destroy_() break; } } -void rrc_conn_reest_request_nb_s::crit_exts_c_::set(types::options e) +void rrc_conn_resume_request_nb_s::crit_exts_c_::set(types::options e) { destroy_(); type_ = e; switch (type_) { - case types::rrc_conn_reest_request_r13: - c.init(); + case types::rrc_conn_resume_request_r13: + c.init(); break; case types::later: c.init(); @@ -16563,15 +22989,15 @@ void rrc_conn_reest_request_nb_s::crit_exts_c_::set(types::options e) case types::nulltype: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_"); } } -rrc_conn_reest_request_nb_s::crit_exts_c_::crit_exts_c_(const rrc_conn_reest_request_nb_s::crit_exts_c_& other) +rrc_conn_resume_request_nb_s::crit_exts_c_::crit_exts_c_(const rrc_conn_resume_request_nb_s::crit_exts_c_& other) { type_ = other.type(); switch (type_) { - case types::rrc_conn_reest_request_r13: - c.init(other.c.get()); + case types::rrc_conn_resume_request_r13: + c.init(other.c.get()); break; case types::later: c.init(other.c.get()); @@ -16579,19 +23005,19 @@ rrc_conn_reest_request_nb_s::crit_exts_c_::crit_exts_c_(const rrc_conn_reest_req case types::nulltype: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_"); } } -rrc_conn_reest_request_nb_s::crit_exts_c_& -rrc_conn_reest_request_nb_s::crit_exts_c_::operator=(const rrc_conn_reest_request_nb_s::crit_exts_c_& other) +rrc_conn_resume_request_nb_s::crit_exts_c_& +rrc_conn_resume_request_nb_s::crit_exts_c_::operator=(const rrc_conn_resume_request_nb_s::crit_exts_c_& other) { if (this == &other) { return *this; } set(other.type()); switch (type_) { - case types::rrc_conn_reest_request_r13: - c.set(other.c.get()); + case types::rrc_conn_resume_request_r13: + c.set(other.c.get()); break; case types::later: c.set(other.c.get()); @@ -16599,296 +23025,308 @@ rrc_conn_reest_request_nb_s::crit_exts_c_::operator=(const rrc_conn_reest_reques case types::nulltype: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_"); } return *this; } -rrc_conn_reest_request_nb_r13_ies_s& rrc_conn_reest_request_nb_s::crit_exts_c_::set_rrc_conn_reest_request_r13() +rrc_conn_resume_request_nb_r13_ies_s& rrc_conn_resume_request_nb_s::crit_exts_c_::set_rrc_conn_resume_request_r13() { - set(types::rrc_conn_reest_request_r13); - return c.get(); + set(types::rrc_conn_resume_request_r13); + return c.get(); } -rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_& rrc_conn_reest_request_nb_s::crit_exts_c_::set_later() +rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_& rrc_conn_resume_request_nb_s::crit_exts_c_::set_later() { set(types::later); return c.get(); } -void rrc_conn_reest_request_nb_s::crit_exts_c_::to_json(json_writer& j) const +void rrc_conn_resume_request_nb_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_conn_reest_request_r13: - j.write_fieldname("rrcConnectionReestablishmentRequest-r13"); - c.get().to_json(j); + case types::rrc_conn_resume_request_r13: + j.write_fieldname("rrcConnectionResumeRequest-r13"); + c.get().to_json(j); break; case types::later: j.write_fieldname("later"); c.get().to_json(j); break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_reest_request_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_resume_request_nb_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_conn_reest_request_r13: - HANDLE_CODE(c.get().pack(bref)); + case types::rrc_conn_resume_request_r13: + HANDLE_CODE(c.get().pack(bref)); break; case types::later: HANDLE_CODE(c.get().pack(bref)); break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_request_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_request_nb_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_conn_reest_request_r13: - HANDLE_CODE(c.get().unpack(bref)); + case types::rrc_conn_resume_request_r13: + HANDLE_CODE(c.get().unpack(bref)); break; case types::later: HANDLE_CODE(c.get().unpack(bref)); break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -void rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::set(types::options e) +void rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_::set(types::options e) { type_ = e; } -rrc_conn_reest_request_nb_r14_ies_s& -rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::set_rrc_conn_reest_request_r14() +rrc_conn_resume_request_minus5_gc_nb_r16_ies_s& +rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_::set_rrc_conn_resume_request_r16() { - set(types::rrc_conn_reest_request_r14); + set(types::rrc_conn_resume_request_r16); return c; } -void rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::set_crit_exts_future() +void rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::to_json(json_writer& j) const +void rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_conn_reest_request_r14: - j.write_fieldname("rrcConnectionReestablishmentRequest-r14"); + case types::rrc_conn_resume_request_r16: + j.write_fieldname("rrcConnectionResumeRequest-r16"); c.to_json(j); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_conn_reest_request_r14: + case types::rrc_conn_resume_request_r16: HANDLE_CODE(c.pack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_conn_reest_request_r14: + case types::rrc_conn_resume_request_r16: HANDLE_CODE(c.unpack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_"); + log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::types_opts::to_string() const -{ - static const char* options[] = {"rrcConnectionReestablishmentRequest-r14", "criticalExtensionsFuture"}; - return convert_enum_idx(options, 2, value, "rrc_conn_reest_request_nb_s::crit_exts_c_::later_c_::types"); -} - -const char* rrc_conn_reest_request_nb_s::crit_exts_c_::types_opts::to_string() const +const char* rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_::types_opts::to_string() const { - static const char* options[] = {"rrcConnectionReestablishmentRequest-r13", "later"}; - return convert_enum_idx(options, 2, value, "rrc_conn_reest_request_nb_s::crit_exts_c_::types"); + static const char* options[] = {"rrcConnectionResumeRequest-r16", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "rrc_conn_resume_request_nb_s::crit_exts_c_::later_c_::types"); } -// EstablishmentCause-NB-r13 ::= ENUMERATED -const char* establishment_cause_nb_r13_opts::to_string() const +const char* rrc_conn_resume_request_nb_s::crit_exts_c_::types_opts::to_string() const { - static const char* options[] = {"mt-Access", - "mo-Signalling", - "mo-Data", - "mo-ExceptionData", - "delayTolerantAccess-v1330", - "spare3", - "spare2", - "spare1"}; - return convert_enum_idx(options, 8, value, "establishment_cause_nb_r13_e"); + static const char* options[] = {"rrcConnectionResumeRequest-r13", "later"}; + return convert_enum_idx(options, 2, value, "rrc_conn_resume_request_nb_s::crit_exts_c_::types"); } -// RRCConnectionRequest-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_request_nb_r13_ies_s::pack(bit_ref& bref) const +// RRCConnectionSetupComplete-NB-v1710-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_complete_nb_v1710_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(multi_tone_support_r13_present, 1)); - HANDLE_CODE(bref.pack(multi_carrier_support_r13_present, 1)); + HANDLE_CODE(bref.pack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - HANDLE_CODE(ue_id_r13.pack(bref)); - HANDLE_CODE(establishment_cause_r13.pack(bref)); - HANDLE_CODE(bref.pack(early_contention_resolution_r14, 1)); - HANDLE_CODE(cqi_npdcch_r14.pack(bref)); - HANDLE_CODE(spare.pack(bref)); + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_request_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_setup_complete_nb_v1710_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(multi_tone_support_r13_present, 1)); - HANDLE_CODE(bref.unpack(multi_carrier_support_r13_present, 1)); + HANDLE_CODE(bref.unpack(gnss_validity_dur_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - HANDLE_CODE(ue_id_r13.unpack(bref)); - HANDLE_CODE(establishment_cause_r13.unpack(bref)); - HANDLE_CODE(bref.unpack(early_contention_resolution_r14, 1)); - HANDLE_CODE(cqi_npdcch_r14.unpack(bref)); - HANDLE_CODE(spare.unpack(bref)); + if (gnss_validity_dur_r17_present) { + HANDLE_CODE(gnss_validity_dur_r17.unpack(bref)); + } return SRSASN_SUCCESS; } -void rrc_conn_request_nb_r13_ies_s::to_json(json_writer& j) const +void rrc_conn_setup_complete_nb_v1710_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("ue-Identity-r13"); - ue_id_r13.to_json(j); - j.write_str("establishmentCause-r13", establishment_cause_r13.to_string()); - if (multi_tone_support_r13_present) { - j.write_str("multiToneSupport-r13", "true"); + if (gnss_validity_dur_r17_present) { + j.write_str("gnss-ValidityDuration-r17", gnss_validity_dur_r17.to_string()); } - if (multi_carrier_support_r13_present) { - j.write_str("multiCarrierSupport-r13", "true"); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); } - j.write_bool("earlyContentionResolution-r14", early_contention_resolution_r14); - j.write_str("cqi-NPDCCH-r14", cqi_npdcch_r14.to_string()); - j.write_str("spare", spare.to_string()); j.end_obj(); } -// RRCConnectionRequest-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_request_nb_s::pack(bit_ref& bref) const +// RRCConnectionSetupComplete-NB-v1610-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_complete_nb_v1610_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(crit_exts.pack(bref)); + HANDLE_CODE(bref.pack(ng_minus5_g_s_tmsi_r16_present, 1)); + HANDLE_CODE(bref.pack(registered_amf_r16_present, 1)); + HANDLE_CODE(bref.pack(gummei_type_v1610_present, 1)); + HANDLE_CODE(bref.pack(guami_type_r16_present, 1)); + HANDLE_CODE(bref.pack(s_nssai_list_r16_present, 1)); + HANDLE_CODE(bref.pack(ng_u_data_transfer_r16_present, 1)); + HANDLE_CODE(bref.pack(up_cio_t_minus5_gs_optim_r16_present, 1)); + HANDLE_CODE(bref.pack(rlf_info_available_r16_present, 1)); + HANDLE_CODE(bref.pack(anr_info_available_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_cfg_id_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - return SRSASN_SUCCESS; -} -SRSASN_CODE rrc_conn_request_nb_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(crit_exts.unpack(bref)); + if (ng_minus5_g_s_tmsi_r16_present) { + HANDLE_CODE(ng_minus5_g_s_tmsi_r16.pack(bref)); + } + if (registered_amf_r16_present) { + HANDLE_CODE(registered_amf_r16.pack(bref)); + } + if (guami_type_r16_present) { + HANDLE_CODE(guami_type_r16.pack(bref)); + } + if (s_nssai_list_r16_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, s_nssai_list_r16, 1, 8)); + } + if (pur_cfg_id_r16_present) { + HANDLE_CODE(pur_cfg_id_r16.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } -void rrc_conn_request_nb_s::to_json(json_writer& j) const +SRSASN_CODE rrc_conn_setup_complete_nb_v1610_ies_s::unpack(cbit_ref& bref) { - j.start_obj(); - j.write_fieldname("criticalExtensions"); - crit_exts.to_json(j); - j.end_obj(); -} + HANDLE_CODE(bref.unpack(ng_minus5_g_s_tmsi_r16_present, 1)); + HANDLE_CODE(bref.unpack(registered_amf_r16_present, 1)); + HANDLE_CODE(bref.unpack(gummei_type_v1610_present, 1)); + HANDLE_CODE(bref.unpack(guami_type_r16_present, 1)); + HANDLE_CODE(bref.unpack(s_nssai_list_r16_present, 1)); + HANDLE_CODE(bref.unpack(ng_u_data_transfer_r16_present, 1)); + HANDLE_CODE(bref.unpack(up_cio_t_minus5_gs_optim_r16_present, 1)); + HANDLE_CODE(bref.unpack(rlf_info_available_r16_present, 1)); + HANDLE_CODE(bref.unpack(anr_info_available_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_cfg_id_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); -void rrc_conn_request_nb_s::crit_exts_c_::set(types::options e) -{ - type_ = e; -} -rrc_conn_request_nb_r13_ies_s& rrc_conn_request_nb_s::crit_exts_c_::set_rrc_conn_request_r13() -{ - set(types::rrc_conn_request_r13); - return c; -} -void rrc_conn_request_nb_s::crit_exts_c_::set_crit_exts_future() -{ - set(types::crit_exts_future); -} -void rrc_conn_request_nb_s::crit_exts_c_::to_json(json_writer& j) const -{ - j.start_obj(); - switch (type_) { - case types::rrc_conn_request_r13: - j.write_fieldname("rrcConnectionRequest-r13"); - c.to_json(j); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_"); + if (ng_minus5_g_s_tmsi_r16_present) { + HANDLE_CODE(ng_minus5_g_s_tmsi_r16.unpack(bref)); } - j.end_obj(); -} -SRSASN_CODE rrc_conn_request_nb_s::crit_exts_c_::pack(bit_ref& bref) const -{ - type_.pack(bref); - switch (type_) { - case types::rrc_conn_request_r13: - HANDLE_CODE(c.pack(bref)); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_"); - return SRSASN_ERROR_ENCODE_FAIL; + if (registered_amf_r16_present) { + HANDLE_CODE(registered_amf_r16.unpack(bref)); + } + if (guami_type_r16_present) { + HANDLE_CODE(guami_type_r16.unpack(bref)); } + if (s_nssai_list_r16_present) { + HANDLE_CODE(unpack_dyn_seq_of(s_nssai_list_r16, bref, 1, 8)); + } + if (pur_cfg_id_r16_present) { + HANDLE_CODE(pur_cfg_id_r16.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_request_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +void rrc_conn_setup_complete_nb_v1610_ies_s::to_json(json_writer& j) const { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::rrc_conn_request_r13: - HANDLE_CODE(c.unpack(bref)); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_request_nb_s::crit_exts_c_"); - return SRSASN_ERROR_DECODE_FAIL; + j.start_obj(); + if (ng_minus5_g_s_tmsi_r16_present) { + j.write_str("ng-5G-S-TMSI-r16", ng_minus5_g_s_tmsi_r16.to_string()); } - return SRSASN_SUCCESS; + if (registered_amf_r16_present) { + j.write_fieldname("registeredAMF-r16"); + registered_amf_r16.to_json(j); + } + if (gummei_type_v1610_present) { + j.write_str("gummei-Type-v1610", "mappedFrom5G"); + } + if (guami_type_r16_present) { + j.write_str("guami-Type-r16", guami_type_r16.to_string()); + } + if (s_nssai_list_r16_present) { + j.start_array("s-NSSAI-list-r16"); + for (const auto& e1 : s_nssai_list_r16) { + e1.to_json(j); + } + j.end_array(); + } + if (ng_u_data_transfer_r16_present) { + j.write_str("ng-U-DataTransfer-r16", "true"); + } + if (up_cio_t_minus5_gs_optim_r16_present) { + j.write_str("up-CIoT-5GS-Optimisation-r16", "true"); + } + if (rlf_info_available_r16_present) { + j.write_str("rlf-InfoAvailable-r16", "true"); + } + if (anr_info_available_r16_present) { + j.write_str("anr-InfoAvailable-r16", "true"); + } + if (pur_cfg_id_r16_present) { + j.write_str("pur-ConfigID-r16", pur_cfg_id_r16.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); } -const char* rrc_conn_request_nb_s::crit_exts_c_::types_opts::to_string() const +const char* rrc_conn_setup_complete_nb_v1610_ies_s::guami_type_r16_opts::to_string() const { - static const char* options[] = {"rrcConnectionRequest-r13", "criticalExtensionsFuture"}; - return convert_enum_idx(options, 2, value, "rrc_conn_request_nb_s::crit_exts_c_::types"); + static const char* options[] = {"native", "mapped"}; + return convert_enum_idx(options, 2, value, "rrc_conn_setup_complete_nb_v1610_ies_s::guami_type_r16_e_"); } -// RRCConnectionResumeComplete-NB-v1470-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_resume_complete_nb_v1470_ies_s::pack(bit_ref& bref) const +// RRCConnectionSetupComplete-NB-v1470-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_complete_nb_v1470_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(meas_result_serv_cell_r14_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); @@ -16896,10 +23334,13 @@ SRSASN_CODE rrc_conn_resume_complete_nb_v1470_ies_s::pack(bit_ref& bref) const if (meas_result_serv_cell_r14_present) { HANDLE_CODE(meas_result_serv_cell_r14.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_resume_complete_nb_v1470_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_setup_complete_nb_v1470_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(meas_result_serv_cell_r14_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -16907,10 +23348,13 @@ SRSASN_CODE rrc_conn_resume_complete_nb_v1470_ies_s::unpack(cbit_ref& bref) if (meas_result_serv_cell_r14_present) { HANDLE_CODE(meas_result_serv_cell_r14.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } -void rrc_conn_resume_complete_nb_v1470_ies_s::to_json(json_writer& j) const +void rrc_conn_setup_complete_nb_v1470_ies_s::to_json(json_writer& j) const { j.start_obj(); if (meas_result_serv_cell_r14_present) { @@ -16919,28 +23363,20 @@ void rrc_conn_resume_complete_nb_v1470_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } -// RRCConnectionResumeComplete-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_resume_complete_nb_r13_ies_s::pack(bit_ref& bref) const +// RRCConnectionSetupComplete-NB-v1430-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_complete_nb_v1430_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(sel_plmn_id_r13_present, 1)); - HANDLE_CODE(bref.pack(ded_info_nas_r13_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(gummei_type_r14_present, 1)); + HANDLE_CODE(bref.pack(dcn_id_r14_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (sel_plmn_id_r13_present) { - HANDLE_CODE(pack_integer(bref, sel_plmn_id_r13, (uint8_t)1u, (uint8_t)6u)); - } - if (ded_info_nas_r13_present) { - HANDLE_CODE(ded_info_nas_r13.pack(bref)); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); + if (dcn_id_r14_present) { + HANDLE_CODE(pack_integer(bref, dcn_id_r14, (uint32_t)0u, (uint32_t)65535u)); } if (non_crit_ext_present) { HANDLE_CODE(non_crit_ext.pack(bref)); @@ -16948,21 +23384,14 @@ SRSASN_CODE rrc_conn_resume_complete_nb_r13_ies_s::pack(bit_ref& bref) const return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_resume_complete_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_setup_complete_nb_v1430_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(sel_plmn_id_r13_present, 1)); - HANDLE_CODE(bref.unpack(ded_info_nas_r13_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(gummei_type_r14_present, 1)); + HANDLE_CODE(bref.unpack(dcn_id_r14_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - if (sel_plmn_id_r13_present) { - HANDLE_CODE(unpack_integer(sel_plmn_id_r13, bref, (uint8_t)1u, (uint8_t)6u)); - } - if (ded_info_nas_r13_present) { - HANDLE_CODE(ded_info_nas_r13.unpack(bref)); - } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + if (dcn_id_r14_present) { + HANDLE_CODE(unpack_integer(dcn_id_r14, bref, (uint32_t)0u, (uint32_t)65535u)); } if (non_crit_ext_present) { HANDLE_CODE(non_crit_ext.unpack(bref)); @@ -16970,17 +23399,14 @@ SRSASN_CODE rrc_conn_resume_complete_nb_r13_ies_s::unpack(cbit_ref& bref) return SRSASN_SUCCESS; } -void rrc_conn_resume_complete_nb_r13_ies_s::to_json(json_writer& j) const +void rrc_conn_setup_complete_nb_v1430_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (sel_plmn_id_r13_present) { - j.write_int("selectedPLMN-Identity-r13", sel_plmn_id_r13); - } - if (ded_info_nas_r13_present) { - j.write_str("dedicatedInfoNAS-r13", ded_info_nas_r13.to_string()); + if (gummei_type_r14_present) { + j.write_str("gummei-Type-r14", "mapped"); } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + if (dcn_id_r14_present) { + j.write_int("dcn-ID-r14", dcn_id_r14); } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); @@ -16989,249 +23415,227 @@ void rrc_conn_resume_complete_nb_r13_ies_s::to_json(json_writer& j) const j.end_obj(); } -// RRCConnectionResumeComplete-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_resume_complete_nb_s::pack(bit_ref& bref) const +// RRCConnectionSetupComplete-NB-r13-IEs ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_complete_nb_r13_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.pack(bref)); + HANDLE_CODE(bref.pack(s_tmsi_r13_present, 1)); + HANDLE_CODE(bref.pack(registered_mme_r13_present, 1)); + HANDLE_CODE(bref.pack(attach_without_pdn_connect_r13_present, 1)); + HANDLE_CODE(bref.pack(up_cio_t_eps_optim_r13_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - return SRSASN_SUCCESS; -} -SRSASN_CODE rrc_conn_resume_complete_nb_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.unpack(bref)); + HANDLE_CODE(pack_integer(bref, sel_plmn_id_r13, (uint8_t)1u, (uint8_t)6u)); + if (s_tmsi_r13_present) { + HANDLE_CODE(s_tmsi_r13.pack(bref)); + } + if (registered_mme_r13_present) { + HANDLE_CODE(registered_mme_r13.pack(bref)); + } + HANDLE_CODE(ded_info_nas_r13.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } -void rrc_conn_resume_complete_nb_s::to_json(json_writer& j) const +SRSASN_CODE rrc_conn_setup_complete_nb_r13_ies_s::unpack(cbit_ref& bref) { - j.start_obj(); - j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); - j.write_fieldname("criticalExtensions"); - crit_exts.to_json(j); - j.end_obj(); -} + HANDLE_CODE(bref.unpack(s_tmsi_r13_present, 1)); + HANDLE_CODE(bref.unpack(registered_mme_r13_present, 1)); + HANDLE_CODE(bref.unpack(attach_without_pdn_connect_r13_present, 1)); + HANDLE_CODE(bref.unpack(up_cio_t_eps_optim_r13_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); -void rrc_conn_resume_complete_nb_s::crit_exts_c_::set(types::options e) -{ - type_ = e; -} -rrc_conn_resume_complete_nb_r13_ies_s& rrc_conn_resume_complete_nb_s::crit_exts_c_::set_rrc_conn_resume_complete_r13() -{ - set(types::rrc_conn_resume_complete_r13); - return c; -} -void rrc_conn_resume_complete_nb_s::crit_exts_c_::set_crit_exts_future() -{ - set(types::crit_exts_future); -} -void rrc_conn_resume_complete_nb_s::crit_exts_c_::to_json(json_writer& j) const -{ - j.start_obj(); - switch (type_) { - case types::rrc_conn_resume_complete_r13: - j.write_fieldname("rrcConnectionResumeComplete-r13"); - c.to_json(j); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_resume_complete_nb_s::crit_exts_c_"); + HANDLE_CODE(unpack_integer(sel_plmn_id_r13, bref, (uint8_t)1u, (uint8_t)6u)); + if (s_tmsi_r13_present) { + HANDLE_CODE(s_tmsi_r13.unpack(bref)); } - j.end_obj(); -} -SRSASN_CODE rrc_conn_resume_complete_nb_s::crit_exts_c_::pack(bit_ref& bref) const -{ - type_.pack(bref); - switch (type_) { - case types::rrc_conn_resume_complete_r13: - HANDLE_CODE(c.pack(bref)); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_resume_complete_nb_s::crit_exts_c_"); - return SRSASN_ERROR_ENCODE_FAIL; + if (registered_mme_r13_present) { + HANDLE_CODE(registered_mme_r13.unpack(bref)); } - return SRSASN_SUCCESS; -} -SRSASN_CODE rrc_conn_resume_complete_nb_s::crit_exts_c_::unpack(cbit_ref& bref) -{ - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::rrc_conn_resume_complete_r13: - HANDLE_CODE(c.unpack(bref)); - break; - case types::crit_exts_future: - break; - default: - log_invalid_choice_id(type_, "rrc_conn_resume_complete_nb_s::crit_exts_c_"); - return SRSASN_ERROR_DECODE_FAIL; + HANDLE_CODE(ded_info_nas_r13.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); } - return SRSASN_SUCCESS; -} - -const char* rrc_conn_resume_complete_nb_s::crit_exts_c_::types_opts::to_string() const -{ - static const char* options[] = {"rrcConnectionResumeComplete-r13", "criticalExtensionsFuture"}; - return convert_enum_idx(options, 2, value, "rrc_conn_resume_complete_nb_s::crit_exts_c_::types"); -} - -// RRCConnectionResumeRequest-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_resume_request_nb_r13_ies_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(resume_id_r13.pack(bref)); - HANDLE_CODE(short_resume_mac_i_r13.pack(bref)); - HANDLE_CODE(resume_cause_r13.pack(bref)); - HANDLE_CODE(bref.pack(early_contention_resolution_r14, 1)); - HANDLE_CODE(cqi_npdcch_r14.pack(bref)); - HANDLE_CODE(spare.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE rrc_conn_resume_request_nb_r13_ies_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(resume_id_r13.unpack(bref)); - HANDLE_CODE(short_resume_mac_i_r13.unpack(bref)); - HANDLE_CODE(resume_cause_r13.unpack(bref)); - HANDLE_CODE(bref.unpack(early_contention_resolution_r14, 1)); - HANDLE_CODE(cqi_npdcch_r14.unpack(bref)); - HANDLE_CODE(spare.unpack(bref)); return SRSASN_SUCCESS; } -void rrc_conn_resume_request_nb_r13_ies_s::to_json(json_writer& j) const +void rrc_conn_setup_complete_nb_r13_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("resumeID-r13", resume_id_r13.to_string()); - j.write_str("shortResumeMAC-I-r13", short_resume_mac_i_r13.to_string()); - j.write_str("resumeCause-r13", resume_cause_r13.to_string()); - j.write_bool("earlyContentionResolution-r14", early_contention_resolution_r14); - j.write_str("cqi-NPDCCH-r14", cqi_npdcch_r14.to_string()); - j.write_str("spare", spare.to_string()); + j.write_int("selectedPLMN-Identity-r13", sel_plmn_id_r13); + if (s_tmsi_r13_present) { + j.write_fieldname("s-TMSI-r13"); + s_tmsi_r13.to_json(j); + } + if (registered_mme_r13_present) { + j.write_fieldname("registeredMME-r13"); + registered_mme_r13.to_json(j); + } + j.write_str("dedicatedInfoNAS-r13", ded_info_nas_r13.to_string()); + if (attach_without_pdn_connect_r13_present) { + j.write_str("attachWithoutPDN-Connectivity-r13", "true"); + } + if (up_cio_t_eps_optim_r13_present) { + j.write_str("up-CIoT-EPS-Optimisation-r13", "true"); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } j.end_obj(); } -// RRCConnectionResumeRequest-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_resume_request_nb_s::pack(bit_ref& bref) const +// RRCConnectionSetupComplete-NB ::= SEQUENCE +SRSASN_CODE rrc_conn_setup_complete_nb_s::pack(bit_ref& bref) const { + HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_resume_request_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_setup_complete_nb_s::unpack(cbit_ref& bref) { + HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); HANDLE_CODE(crit_exts.unpack(bref)); return SRSASN_SUCCESS; } -void rrc_conn_resume_request_nb_s::to_json(json_writer& j) const +void rrc_conn_setup_complete_nb_s::to_json(json_writer& j) const { j.start_obj(); + j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); j.write_fieldname("criticalExtensions"); crit_exts.to_json(j); j.end_obj(); } -void rrc_conn_resume_request_nb_s::crit_exts_c_::set(types::options e) +void rrc_conn_setup_complete_nb_s::crit_exts_c_::set(types::options e) { type_ = e; } -rrc_conn_resume_request_nb_r13_ies_s& rrc_conn_resume_request_nb_s::crit_exts_c_::set_rrc_conn_resume_request_r13() +rrc_conn_setup_complete_nb_r13_ies_s& rrc_conn_setup_complete_nb_s::crit_exts_c_::set_rrc_conn_setup_complete_r13() { - set(types::rrc_conn_resume_request_r13); + set(types::rrc_conn_setup_complete_r13); return c; } -void rrc_conn_resume_request_nb_s::crit_exts_c_::set_crit_exts_future() +void rrc_conn_setup_complete_nb_s::crit_exts_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void rrc_conn_resume_request_nb_s::crit_exts_c_::to_json(json_writer& j) const +void rrc_conn_setup_complete_nb_s::crit_exts_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_conn_resume_request_r13: - j.write_fieldname("rrcConnectionResumeRequest-r13"); + case types::rrc_conn_setup_complete_r13: + j.write_fieldname("rrcConnectionSetupComplete-r13"); c.to_json(j); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_setup_complete_nb_s::crit_exts_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_resume_request_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_conn_setup_complete_nb_s::crit_exts_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_conn_resume_request_r13: + case types::rrc_conn_setup_complete_r13: HANDLE_CODE(c.pack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_setup_complete_nb_s::crit_exts_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_resume_request_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_conn_setup_complete_nb_s::crit_exts_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_conn_resume_request_r13: + case types::rrc_conn_setup_complete_r13: HANDLE_CODE(c.unpack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_resume_request_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_conn_setup_complete_nb_s::crit_exts_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* rrc_conn_resume_request_nb_s::crit_exts_c_::types_opts::to_string() const +const char* rrc_conn_setup_complete_nb_s::crit_exts_c_::types_opts::to_string() const { - static const char* options[] = {"rrcConnectionResumeRequest-r13", "criticalExtensionsFuture"}; - return convert_enum_idx(options, 2, value, "rrc_conn_resume_request_nb_s::crit_exts_c_::types"); + static const char* options[] = {"rrcConnectionSetupComplete-r13", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "rrc_conn_setup_complete_nb_s::crit_exts_c_::types"); } -// RRCConnectionSetupComplete-NB-v1470-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_setup_complete_nb_v1470_ies_s::pack(bit_ref& bref) const +// RRCEarlyDataRequest-5GC-NB-r16-IEs ::= SEQUENCE +SRSASN_CODE rrc_early_data_request_minus5_gc_nb_r16_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(meas_result_serv_cell_r14_present, 1)); + HANDLE_CODE(bref.pack(cqi_npdcch_r16_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (meas_result_serv_cell_r14_present) { - HANDLE_CODE(meas_result_serv_cell_r14.pack(bref)); + HANDLE_CODE(ng_minus5_g_s_tmsi_r16.pack(bref)); + HANDLE_CODE(establishment_cause_r16.pack(bref)); + if (cqi_npdcch_r16_present) { + HANDLE_CODE(cqi_npdcch_r16.pack(bref)); + } + HANDLE_CODE(ded_info_nas_r16.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_setup_complete_nb_v1470_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_early_data_request_minus5_gc_nb_r16_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(meas_result_serv_cell_r14_present, 1)); + HANDLE_CODE(bref.unpack(cqi_npdcch_r16_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - if (meas_result_serv_cell_r14_present) { - HANDLE_CODE(meas_result_serv_cell_r14.unpack(bref)); + HANDLE_CODE(ng_minus5_g_s_tmsi_r16.unpack(bref)); + HANDLE_CODE(establishment_cause_r16.unpack(bref)); + if (cqi_npdcch_r16_present) { + HANDLE_CODE(cqi_npdcch_r16.unpack(bref)); + } + HANDLE_CODE(ded_info_nas_r16.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); } return SRSASN_SUCCESS; } -void rrc_conn_setup_complete_nb_v1470_ies_s::to_json(json_writer& j) const +void rrc_early_data_request_minus5_gc_nb_r16_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (meas_result_serv_cell_r14_present) { - j.write_fieldname("measResultServCell-r14"); - meas_result_serv_cell_r14.to_json(j); + j.write_str("ng-5G-S-TMSI-r16", ng_minus5_g_s_tmsi_r16.to_string()); + j.write_str("establishmentCause-r16", establishment_cause_r16.to_string()); + if (cqi_npdcch_r16_present) { + j.write_str("cqi-NPDCCH-r16", cqi_npdcch_r16.to_string()); + } + j.write_str("dedicatedInfoNAS-r16", ded_info_nas_r16.to_string()); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); @@ -17241,1460 +23645,2105 @@ void rrc_conn_setup_complete_nb_v1470_ies_s::to_json(json_writer& j) const j.end_obj(); } -// RRCConnectionSetupComplete-NB-v1430-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_setup_complete_nb_v1430_ies_s::pack(bit_ref& bref) const +const char* rrc_early_data_request_minus5_gc_nb_r16_ies_s::establishment_cause_r16_opts::to_string() const { - HANDLE_CODE(bref.pack(gummei_type_r14_present, 1)); - HANDLE_CODE(bref.pack(dcn_id_r14_present, 1)); + static const char* options[] = {"mo-Data", "mo-ExceptionData", "mt-Access", "spare1"}; + return convert_enum_idx( + options, 4, value, "rrc_early_data_request_minus5_gc_nb_r16_ies_s::establishment_cause_r16_e_"); +} + +// RRCEarlyDataRequest-NB-v1590-IEs ::= SEQUENCE +SRSASN_CODE rrc_early_data_request_nb_v1590_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (dcn_id_r14_present) { - HANDLE_CODE(pack_integer(bref, dcn_id_r14, (uint32_t)0u, (uint32_t)65535u)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_setup_complete_nb_v1430_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_early_data_request_nb_v1590_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(gummei_type_r14_present, 1)); - HANDLE_CODE(bref.unpack(dcn_id_r14_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - if (dcn_id_r14_present) { - HANDLE_CODE(unpack_integer(dcn_id_r14, bref, (uint32_t)0u, (uint32_t)65535u)); - } - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); } return SRSASN_SUCCESS; } -void rrc_conn_setup_complete_nb_v1430_ies_s::to_json(json_writer& j) const +void rrc_early_data_request_nb_v1590_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (gummei_type_r14_present) { - j.write_str("gummei-Type-r14", "mapped"); - } - if (dcn_id_r14_present) { - j.write_int("dcn-ID-r14", dcn_id_r14); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); + j.start_obj(); + j.end_obj(); } j.end_obj(); } -// RRCConnectionSetupComplete-NB-r13-IEs ::= SEQUENCE -SRSASN_CODE rrc_conn_setup_complete_nb_r13_ies_s::pack(bit_ref& bref) const +// RRCEarlyDataRequest-NB-r15-IEs ::= SEQUENCE +SRSASN_CODE rrc_early_data_request_nb_r15_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(s_tmsi_r13_present, 1)); - HANDLE_CODE(bref.pack(registered_mme_r13_present, 1)); - HANDLE_CODE(bref.pack(attach_without_pdn_connect_r13_present, 1)); - HANDLE_CODE(bref.pack(up_cio_t_eps_optim_r13_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(cqi_npdcch_r15_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - HANDLE_CODE(pack_integer(bref, sel_plmn_id_r13, (uint8_t)1u, (uint8_t)6u)); - if (s_tmsi_r13_present) { - HANDLE_CODE(s_tmsi_r13.pack(bref)); - } - if (registered_mme_r13_present) { - HANDLE_CODE(registered_mme_r13.pack(bref)); - } - HANDLE_CODE(ded_info_nas_r13.pack(bref)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); + HANDLE_CODE(s_tmsi_r15.pack(bref)); + HANDLE_CODE(establishment_cause_r15.pack(bref)); + if (cqi_npdcch_r15_present) { + HANDLE_CODE(cqi_npdcch_r15.pack(bref)); } + HANDLE_CODE(ded_info_nas_r15.pack(bref)); if (non_crit_ext_present) { HANDLE_CODE(non_crit_ext.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_setup_complete_nb_r13_ies_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_early_data_request_nb_r15_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(s_tmsi_r13_present, 1)); - HANDLE_CODE(bref.unpack(registered_mme_r13_present, 1)); - HANDLE_CODE(bref.unpack(attach_without_pdn_connect_r13_present, 1)); - HANDLE_CODE(bref.unpack(up_cio_t_eps_optim_r13_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(cqi_npdcch_r15_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - HANDLE_CODE(unpack_integer(sel_plmn_id_r13, bref, (uint8_t)1u, (uint8_t)6u)); - if (s_tmsi_r13_present) { - HANDLE_CODE(s_tmsi_r13.unpack(bref)); + HANDLE_CODE(s_tmsi_r15.unpack(bref)); + HANDLE_CODE(establishment_cause_r15.unpack(bref)); + if (cqi_npdcch_r15_present) { + HANDLE_CODE(cqi_npdcch_r15.unpack(bref)); } - if (registered_mme_r13_present) { - HANDLE_CODE(registered_mme_r13.unpack(bref)); + HANDLE_CODE(ded_info_nas_r15.unpack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); } - HANDLE_CODE(ded_info_nas_r13.unpack(bref)); - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + + return SRSASN_SUCCESS; +} +void rrc_early_data_request_nb_r15_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("s-TMSI-r15"); + s_tmsi_r15.to_json(j); + j.write_str("establishmentCause-r15", establishment_cause_r15.to_string()); + if (cqi_npdcch_r15_present) { + j.write_str("cqi-NPDCCH-r15", cqi_npdcch_r15.to_string()); } + j.write_str("dedicatedInfoNAS-r15", ded_info_nas_r15.to_string()); if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); } + j.end_obj(); +} + +const char* rrc_early_data_request_nb_r15_ies_s::establishment_cause_r15_opts::to_string() const +{ + static const char* options[] = {"mo-Data", "mo-ExceptionData", "delayTolerantAccess", "mt-Access-v1610"}; + return convert_enum_idx(options, 4, value, "rrc_early_data_request_nb_r15_ies_s::establishment_cause_r15_e_"); +} + +// RRCEarlyDataRequest-NB-r15 ::= SEQUENCE +SRSASN_CODE rrc_early_data_request_nb_r15_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(crit_exts.pack(bref)); return SRSASN_SUCCESS; } -void rrc_conn_setup_complete_nb_r13_ies_s::to_json(json_writer& j) const +SRSASN_CODE rrc_early_data_request_nb_r15_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void rrc_early_data_request_nb_r15_s::to_json(json_writer& j) const { j.start_obj(); - j.write_int("selectedPLMN-Identity-r13", sel_plmn_id_r13); - if (s_tmsi_r13_present) { - j.write_fieldname("s-TMSI-r13"); - s_tmsi_r13.to_json(j); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void rrc_early_data_request_nb_r15_s::crit_exts_c_::destroy_() +{ + switch (type_) { + case types::rrc_early_data_request_r15: + c.destroy(); + break; + case types::later: + c.destroy(); + break; + default: + break; } - if (registered_mme_r13_present) { - j.write_fieldname("registeredMME-r13"); - registered_mme_r13.to_json(j); +} +void rrc_early_data_request_nb_r15_s::crit_exts_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::rrc_early_data_request_r15: + c.init(); + break; + case types::later: + c.init(); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_"); } - j.write_str("dedicatedInfoNAS-r13", ded_info_nas_r13.to_string()); - if (attach_without_pdn_connect_r13_present) { - j.write_str("attachWithoutPDN-Connectivity-r13", "true"); +} +rrc_early_data_request_nb_r15_s::crit_exts_c_::crit_exts_c_(const rrc_early_data_request_nb_r15_s::crit_exts_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::rrc_early_data_request_r15: + c.init(other.c.get()); + break; + case types::later: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_"); } - if (up_cio_t_eps_optim_r13_present) { - j.write_str("up-CIoT-EPS-Optimisation-r13", "true"); +} +rrc_early_data_request_nb_r15_s::crit_exts_c_& +rrc_early_data_request_nb_r15_s::crit_exts_c_::operator=(const rrc_early_data_request_nb_r15_s::crit_exts_c_& other) +{ + if (this == &other) { + return *this; } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + set(other.type()); + switch (type_) { + case types::rrc_early_data_request_r15: + c.set(other.c.get()); + break; + case types::later: + c.set(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_"); } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); + + return *this; +} +rrc_early_data_request_nb_r15_ies_s& rrc_early_data_request_nb_r15_s::crit_exts_c_::set_rrc_early_data_request_r15() +{ + set(types::rrc_early_data_request_r15); + return c.get(); +} +rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_& rrc_early_data_request_nb_r15_s::crit_exts_c_::set_later() +{ + set(types::later); + return c.get(); +} +void rrc_early_data_request_nb_r15_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::rrc_early_data_request_r15: + j.write_fieldname("rrcEarlyDataRequest-r15"); + c.get().to_json(j); + break; + case types::later: + j.write_fieldname("later"); + c.get().to_json(j); + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_"); } j.end_obj(); } - -// RRCConnectionSetupComplete-NB ::= SEQUENCE -SRSASN_CODE rrc_conn_setup_complete_nb_s::pack(bit_ref& bref) const +SRSASN_CODE rrc_early_data_request_nb_r15_s::crit_exts_c_::pack(bit_ref& bref) const { - HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.pack(bref)); - + type_.pack(bref); + switch (type_) { + case types::rrc_early_data_request_r15: + HANDLE_CODE(c.get().pack(bref)); + break; + case types::later: + HANDLE_CODE(c.get().pack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_setup_complete_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE rrc_early_data_request_nb_r15_s::crit_exts_c_::unpack(cbit_ref& bref) { - HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); - HANDLE_CODE(crit_exts.unpack(bref)); - + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::rrc_early_data_request_r15: + HANDLE_CODE(c.get().unpack(bref)); + break; + case types::later: + HANDLE_CODE(c.get().unpack(bref)); + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } return SRSASN_SUCCESS; } -void rrc_conn_setup_complete_nb_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); - j.write_fieldname("criticalExtensions"); - crit_exts.to_json(j); - j.end_obj(); -} -void rrc_conn_setup_complete_nb_s::crit_exts_c_::set(types::options e) +void rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_::set(types::options e) { type_ = e; } -rrc_conn_setup_complete_nb_r13_ies_s& rrc_conn_setup_complete_nb_s::crit_exts_c_::set_rrc_conn_setup_complete_r13() +rrc_early_data_request_minus5_gc_nb_r16_ies_s& +rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_::set_rrc_early_data_request_r16() { - set(types::rrc_conn_setup_complete_r13); + set(types::rrc_early_data_request_r16); return c; } -void rrc_conn_setup_complete_nb_s::crit_exts_c_::set_crit_exts_future() +void rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_::set_crit_exts_future() { set(types::crit_exts_future); } -void rrc_conn_setup_complete_nb_s::crit_exts_c_::to_json(json_writer& j) const +void rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_conn_setup_complete_r13: - j.write_fieldname("rrcConnectionSetupComplete-r13"); + case types::rrc_early_data_request_r16: + j.write_fieldname("rrcEarlyDataRequest-r16"); c.to_json(j); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_setup_complete_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_"); } j.end_obj(); } -SRSASN_CODE rrc_conn_setup_complete_nb_s::crit_exts_c_::pack(bit_ref& bref) const +SRSASN_CODE rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::rrc_conn_setup_complete_r13: + case types::rrc_early_data_request_r16: HANDLE_CODE(c.pack(bref)); break; case types::crit_exts_future: break; default: - log_invalid_choice_id(type_, "rrc_conn_setup_complete_nb_s::crit_exts_c_"); + log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_conn_setup_complete_nb_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_conn_setup_complete_r13: + case types::rrc_early_data_request_r16: HANDLE_CODE(c.unpack(bref)); break; - case types::crit_exts_future: + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_::types_opts::to_string() const +{ + static const char* options[] = {"rrcEarlyDataRequest-r16", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "rrc_early_data_request_nb_r15_s::crit_exts_c_::later_c_::types"); +} + +const char* rrc_early_data_request_nb_r15_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"rrcEarlyDataRequest-r15", "later"}; + return convert_enum_idx(options, 2, value, "rrc_early_data_request_nb_r15_s::crit_exts_c_::types"); +} + +// SC-MTCH-SchedulingInfo-NB-r14 ::= SEQUENCE +SRSASN_CODE sc_mtch_sched_info_nb_r14_s::pack(bit_ref& bref) const +{ + bref.pack(ext, 1); + HANDLE_CODE(on_dur_timer_scptm_r14.pack(bref)); + HANDLE_CODE(drx_inactivity_timer_scptm_r14.pack(bref)); + HANDLE_CODE(sched_period_start_offset_scptm_r14.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE sc_mtch_sched_info_nb_r14_s::unpack(cbit_ref& bref) +{ + bref.unpack(ext, 1); + HANDLE_CODE(on_dur_timer_scptm_r14.unpack(bref)); + HANDLE_CODE(drx_inactivity_timer_scptm_r14.unpack(bref)); + HANDLE_CODE(sched_period_start_offset_scptm_r14.unpack(bref)); + + return SRSASN_SUCCESS; +} +void sc_mtch_sched_info_nb_r14_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_str("onDurationTimerSCPTM-r14", on_dur_timer_scptm_r14.to_string()); + j.write_str("drx-InactivityTimerSCPTM-r14", drx_inactivity_timer_scptm_r14.to_string()); + j.write_fieldname("schedulingPeriodStartOffsetSCPTM-r14"); + sched_period_start_offset_scptm_r14.to_json(j); + j.end_obj(); +} + +const char* sc_mtch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_opts::to_string() const +{ + static const char* options[] = {"pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32", "spare"}; + return convert_enum_idx(options, 8, value, "sc_mtch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_e_"); +} +uint8_t sc_mtch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_opts::to_number() const +{ + static const uint8_t options[] = {1, 2, 3, 4, 8, 16, 32}; + return map_enum_number(options, 7, value, "sc_mtch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_e_"); +} + +const char* sc_mtch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_opts::to_string() const +{ + static const char* options[] = {"pp0", "pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32"}; + return convert_enum_idx(options, 8, value, "sc_mtch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_e_"); +} +uint8_t sc_mtch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_opts::to_number() const +{ + static const uint8_t options[] = {0, 1, 2, 3, 4, 8, 16, 32}; + return map_enum_number(options, 8, value, "sc_mtch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_e_"); +} + +void sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::destroy_() {} +void sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set(types::options e) +{ + destroy_(); + type_ = e; +} +sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::sched_period_start_offset_scptm_r14_c_( + const sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::sf10: + c.init(other.c.get()); + break; + case types::sf20: + c.init(other.c.get()); + break; + case types::sf32: + c.init(other.c.get()); + break; + case types::sf40: + c.init(other.c.get()); + break; + case types::sf64: + c.init(other.c.get()); + break; + case types::sf80: + c.init(other.c.get()); + break; + case types::sf128: + c.init(other.c.get()); + break; + case types::sf160: + c.init(other.c.get()); + break; + case types::sf256: + c.init(other.c.get()); + break; + case types::sf320: + c.init(other.c.get()); + break; + case types::sf512: + c.init(other.c.get()); + break; + case types::sf640: + c.init(other.c.get()); + break; + case types::sf1024: + c.init(other.c.get()); + break; + case types::sf2048: + c.init(other.c.get()); + break; + case types::sf4096: + c.init(other.c.get()); + break; + case types::sf8192: + c.init(other.c.get()); + break; + case types::nulltype: + break; + default: + log_invalid_choice_id(type_, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + } +} +sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& +sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::operator=( + const sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& other) +{ + if (this == &other) { + return *this; + } + set(other.type()); + switch (type_) { + case types::sf10: + c.set(other.c.get()); + break; + case types::sf20: + c.set(other.c.get()); + break; + case types::sf32: + c.set(other.c.get()); + break; + case types::sf40: + c.set(other.c.get()); + break; + case types::sf64: + c.set(other.c.get()); + break; + case types::sf80: + c.set(other.c.get()); + break; + case types::sf128: + c.set(other.c.get()); + break; + case types::sf160: + c.set(other.c.get()); + break; + case types::sf256: + c.set(other.c.get()); + break; + case types::sf320: + c.set(other.c.get()); + break; + case types::sf512: + c.set(other.c.get()); + break; + case types::sf640: + c.set(other.c.get()); + break; + case types::sf1024: + c.set(other.c.get()); + break; + case types::sf2048: + c.set(other.c.get()); + break; + case types::sf4096: + c.set(other.c.get()); + break; + case types::sf8192: + c.set(other.c.get()); + break; + case types::nulltype: break; default: - log_invalid_choice_id(type_, "rrc_conn_setup_complete_nb_s::crit_exts_c_"); - return SRSASN_ERROR_DECODE_FAIL; + log_invalid_choice_id(type_, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); } - return SRSASN_SUCCESS; -} -const char* rrc_conn_setup_complete_nb_s::crit_exts_c_::types_opts::to_string() const + return *this; +} +uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf10() { - static const char* options[] = {"rrcConnectionSetupComplete-r13", "criticalExtensionsFuture"}; - return convert_enum_idx(options, 2, value, "rrc_conn_setup_complete_nb_s::crit_exts_c_::types"); + set(types::sf10); + return c.get(); } - -// RRCEarlyDataRequest-NB-v1590-IEs ::= SEQUENCE -SRSASN_CODE rrc_early_data_request_nb_v1590_ies_s::pack(bit_ref& bref) const +uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf20() { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); - } - - return SRSASN_SUCCESS; + set(types::sf20); + return c.get(); } -SRSASN_CODE rrc_early_data_request_nb_v1590_ies_s::unpack(cbit_ref& bref) +uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf32() { - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); - } - - return SRSASN_SUCCESS; + set(types::sf32); + return c.get(); } -void rrc_early_data_request_nb_v1590_ies_s::to_json(json_writer& j) const +uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf40() { - j.start_obj(); - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); - } - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); - } - j.end_obj(); + set(types::sf40); + return c.get(); } - -// RRCEarlyDataRequest-NB-r15-IEs ::= SEQUENCE -SRSASN_CODE rrc_early_data_request_nb_r15_ies_s::pack(bit_ref& bref) const +uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf64() { - HANDLE_CODE(bref.pack(cqi_npdcch_r15_present, 1)); - HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - - HANDLE_CODE(s_tmsi_r15.pack(bref)); - HANDLE_CODE(establishment_cause_r15.pack(bref)); - if (cqi_npdcch_r15_present) { - HANDLE_CODE(cqi_npdcch_r15.pack(bref)); - } - HANDLE_CODE(ded_info_nas_r15.pack(bref)); - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.pack(bref)); - } - - return SRSASN_SUCCESS; + set(types::sf64); + return c.get(); } -SRSASN_CODE rrc_early_data_request_nb_r15_ies_s::unpack(cbit_ref& bref) +uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf80() { - HANDLE_CODE(bref.unpack(cqi_npdcch_r15_present, 1)); - HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - - HANDLE_CODE(s_tmsi_r15.unpack(bref)); - HANDLE_CODE(establishment_cause_r15.unpack(bref)); - if (cqi_npdcch_r15_present) { - HANDLE_CODE(cqi_npdcch_r15.unpack(bref)); - } - HANDLE_CODE(ded_info_nas_r15.unpack(bref)); - if (non_crit_ext_present) { - HANDLE_CODE(non_crit_ext.unpack(bref)); - } - - return SRSASN_SUCCESS; + set(types::sf80); + return c.get(); } -void rrc_early_data_request_nb_r15_ies_s::to_json(json_writer& j) const +uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf128() { - j.start_obj(); - j.write_fieldname("s-TMSI-r15"); - s_tmsi_r15.to_json(j); - j.write_str("establishmentCause-r15", establishment_cause_r15.to_string()); - if (cqi_npdcch_r15_present) { - j.write_str("cqi-NPDCCH-r15", cqi_npdcch_r15.to_string()); - } - j.write_str("dedicatedInfoNAS-r15", ded_info_nas_r15.to_string()); - if (non_crit_ext_present) { - j.write_fieldname("nonCriticalExtension"); - non_crit_ext.to_json(j); - } - j.end_obj(); + set(types::sf128); + return c.get(); } - -const char* rrc_early_data_request_nb_r15_ies_s::establishment_cause_r15_opts::to_string() const +uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf160() { - static const char* options[] = {"mo-Data", "mo-ExceptionData", "delayTolerantAccess", "spare1"}; - return convert_enum_idx(options, 4, value, "rrc_early_data_request_nb_r15_ies_s::establishment_cause_r15_e_"); + set(types::sf160); + return c.get(); } - -// RRCEarlyDataRequest-NB-r15 ::= SEQUENCE -SRSASN_CODE rrc_early_data_request_nb_r15_s::pack(bit_ref& bref) const +uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf256() { - HANDLE_CODE(crit_exts.pack(bref)); - - return SRSASN_SUCCESS; + set(types::sf256); + return c.get(); } -SRSASN_CODE rrc_early_data_request_nb_r15_s::unpack(cbit_ref& bref) +uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf320() { - HANDLE_CODE(crit_exts.unpack(bref)); - - return SRSASN_SUCCESS; + set(types::sf320); + return c.get(); } -void rrc_early_data_request_nb_r15_s::to_json(json_writer& j) const +uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf512() { - j.start_obj(); - j.write_fieldname("criticalExtensions"); - crit_exts.to_json(j); - j.end_obj(); + set(types::sf512); + return c.get(); } - -void rrc_early_data_request_nb_r15_s::crit_exts_c_::set(types::options e) +uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf640() { - type_ = e; + set(types::sf640); + return c.get(); } -rrc_early_data_request_nb_r15_ies_s& rrc_early_data_request_nb_r15_s::crit_exts_c_::set_rrc_early_data_request_r15() +uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf1024() { - set(types::rrc_early_data_request_r15); - return c; + set(types::sf1024); + return c.get(); } -void rrc_early_data_request_nb_r15_s::crit_exts_c_::set_crit_exts_future() +uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf2048() { - set(types::crit_exts_future); + set(types::sf2048); + return c.get(); } -void rrc_early_data_request_nb_r15_s::crit_exts_c_::to_json(json_writer& j) const +uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf4096() +{ + set(types::sf4096); + return c.get(); +} +uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf8192() +{ + set(types::sf8192); + return c.get(); +} +void sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::rrc_early_data_request_r15: - j.write_fieldname("rrcEarlyDataRequest-r15"); - c.to_json(j); + case types::sf10: + j.write_int("sf10", c.get()); + break; + case types::sf20: + j.write_int("sf20", c.get()); + break; + case types::sf32: + j.write_int("sf32", c.get()); + break; + case types::sf40: + j.write_int("sf40", c.get()); + break; + case types::sf64: + j.write_int("sf64", c.get()); + break; + case types::sf80: + j.write_int("sf80", c.get()); + break; + case types::sf128: + j.write_int("sf128", c.get()); + break; + case types::sf160: + j.write_int("sf160", c.get()); + break; + case types::sf256: + j.write_int("sf256", c.get()); + break; + case types::sf320: + j.write_int("sf320", c.get()); + break; + case types::sf512: + j.write_int("sf512", c.get()); + break; + case types::sf640: + j.write_int("sf640", c.get()); + break; + case types::sf1024: + j.write_int("sf1024", c.get()); + break; + case types::sf2048: + j.write_int("sf2048", c.get()); + break; + case types::sf4096: + j.write_int("sf4096", c.get()); + break; + case types::sf8192: + j.write_int("sf8192", c.get()); + break; + default: + log_invalid_choice_id(type_, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + } + j.end_obj(); +} +SRSASN_CODE sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::sf10: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)9u)); + break; + case types::sf20: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)19u)); + break; + case types::sf32: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)31u)); + break; + case types::sf40: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)39u)); + break; + case types::sf64: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)63u)); + break; + case types::sf80: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)79u)); + break; + case types::sf128: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); + break; + case types::sf160: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)159u)); break; - case types::crit_exts_future: + case types::sf256: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u)); break; - default: - log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_"); - } - j.end_obj(); -} -SRSASN_CODE rrc_early_data_request_nb_r15_s::crit_exts_c_::pack(bit_ref& bref) const -{ - type_.pack(bref); - switch (type_) { - case types::rrc_early_data_request_r15: - HANDLE_CODE(c.pack(bref)); + case types::sf320: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)319u)); break; - case types::crit_exts_future: + case types::sf512: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)511u)); + break; + case types::sf640: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)639u)); + break; + case types::sf1024: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1023u)); + break; + case types::sf2048: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)2047u)); + break; + case types::sf4096: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u)); + break; + case types::sf8192: + HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)8191u)); break; default: - log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_"); + log_invalid_choice_id(type_, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE rrc_early_data_request_nb_r15_s::crit_exts_c_::unpack(cbit_ref& bref) +SRSASN_CODE sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::rrc_early_data_request_r15: - HANDLE_CODE(c.unpack(bref)); + case types::sf10: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)9u)); break; - case types::crit_exts_future: + case types::sf20: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)19u)); + break; + case types::sf32: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)31u)); + break; + case types::sf40: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)39u)); + break; + case types::sf64: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)63u)); + break; + case types::sf80: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)79u)); + break; + case types::sf128: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); + break; + case types::sf160: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)159u)); + break; + case types::sf256: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u)); + break; + case types::sf320: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)319u)); + break; + case types::sf512: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)511u)); + break; + case types::sf640: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)639u)); + break; + case types::sf1024: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1023u)); + break; + case types::sf2048: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)2047u)); + break; + case types::sf4096: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u)); + break; + case types::sf8192: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)8191u)); break; default: - log_invalid_choice_id(type_, "rrc_early_data_request_nb_r15_s::crit_exts_c_"); + log_invalid_choice_id(type_, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* rrc_early_data_request_nb_r15_s::crit_exts_c_::types_opts::to_string() const +const char* sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types_opts::to_string() const { - static const char* options[] = {"rrcEarlyDataRequest-r15", "criticalExtensionsFuture"}; - return convert_enum_idx(options, 2, value, "rrc_early_data_request_nb_r15_s::crit_exts_c_::types"); + static const char* options[] = {"sf10", + "sf20", + "sf32", + "sf40", + "sf64", + "sf80", + "sf128", + "sf160", + "sf256", + "sf320", + "sf512", + "sf640", + "sf1024", + "sf2048", + "sf4096", + "sf8192"}; + return convert_enum_idx( + options, 16, value, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types"); +} +uint16_t sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types_opts::to_number() const +{ + static const uint16_t options[] = {10, 20, 32, 40, 64, 80, 128, 160, 256, 320, 512, 640, 1024, 2048, 4096, 8192}; + return map_enum_number( + options, 16, value, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types"); } -// SC-MTCH-SchedulingInfo-NB-r14 ::= SEQUENCE -SRSASN_CODE sc_mtch_sched_info_nb_r14_s::pack(bit_ref& bref) const +// SC-MTCH-Info-NB-r14 ::= SEQUENCE +SRSASN_CODE sc_mtch_info_nb_r14_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(on_dur_timer_scptm_r14.pack(bref)); - HANDLE_CODE(drx_inactivity_timer_scptm_r14.pack(bref)); - HANDLE_CODE(sched_period_start_offset_scptm_r14.pack(bref)); + HANDLE_CODE(bref.pack(sc_mtch_sched_info_r14_present, 1)); + HANDLE_CODE(bref.pack(sc_mtch_neighbour_cell_r14_present, 1)); + + HANDLE_CODE(sc_mtch_carrier_cfg_r14.pack(bref)); + HANDLE_CODE(mbms_session_info_r14.pack(bref)); + HANDLE_CODE(g_rnti_r14.pack(bref)); + if (sc_mtch_sched_info_r14_present) { + HANDLE_CODE(sc_mtch_sched_info_r14.pack(bref)); + } + if (sc_mtch_neighbour_cell_r14_present) { + HANDLE_CODE(sc_mtch_neighbour_cell_r14.pack(bref)); + } + HANDLE_CODE(npdcch_npdsch_max_tbs_sc_mtch_r14.pack(bref)); + HANDLE_CODE(npdcch_num_repeats_sc_mtch_r14.pack(bref)); + HANDLE_CODE(npdcch_start_sf_sc_mtch_r14.pack(bref)); + HANDLE_CODE(npdcch_offset_sc_mtch_r14.pack(bref)); return SRSASN_SUCCESS; } -SRSASN_CODE sc_mtch_sched_info_nb_r14_s::unpack(cbit_ref& bref) +SRSASN_CODE sc_mtch_info_nb_r14_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); - HANDLE_CODE(on_dur_timer_scptm_r14.unpack(bref)); - HANDLE_CODE(drx_inactivity_timer_scptm_r14.unpack(bref)); - HANDLE_CODE(sched_period_start_offset_scptm_r14.unpack(bref)); + HANDLE_CODE(bref.unpack(sc_mtch_sched_info_r14_present, 1)); + HANDLE_CODE(bref.unpack(sc_mtch_neighbour_cell_r14_present, 1)); + + HANDLE_CODE(sc_mtch_carrier_cfg_r14.unpack(bref)); + HANDLE_CODE(mbms_session_info_r14.unpack(bref)); + HANDLE_CODE(g_rnti_r14.unpack(bref)); + if (sc_mtch_sched_info_r14_present) { + HANDLE_CODE(sc_mtch_sched_info_r14.unpack(bref)); + } + if (sc_mtch_neighbour_cell_r14_present) { + HANDLE_CODE(sc_mtch_neighbour_cell_r14.unpack(bref)); + } + HANDLE_CODE(npdcch_npdsch_max_tbs_sc_mtch_r14.unpack(bref)); + HANDLE_CODE(npdcch_num_repeats_sc_mtch_r14.unpack(bref)); + HANDLE_CODE(npdcch_start_sf_sc_mtch_r14.unpack(bref)); + HANDLE_CODE(npdcch_offset_sc_mtch_r14.unpack(bref)); return SRSASN_SUCCESS; } -void sc_mtch_sched_info_nb_r14_s::to_json(json_writer& j) const +void sc_mtch_info_nb_r14_s::to_json(json_writer& j) const { j.start_obj(); - j.write_str("onDurationTimerSCPTM-r14", on_dur_timer_scptm_r14.to_string()); - j.write_str("drx-InactivityTimerSCPTM-r14", drx_inactivity_timer_scptm_r14.to_string()); - j.write_fieldname("schedulingPeriodStartOffsetSCPTM-r14"); - sched_period_start_offset_scptm_r14.to_json(j); + j.write_fieldname("sc-mtch-CarrierConfig-r14"); + sc_mtch_carrier_cfg_r14.to_json(j); + j.write_fieldname("mbmsSessionInfo-r14"); + mbms_session_info_r14.to_json(j); + j.write_str("g-RNTI-r14", g_rnti_r14.to_string()); + if (sc_mtch_sched_info_r14_present) { + j.write_fieldname("sc-mtch-SchedulingInfo-r14"); + sc_mtch_sched_info_r14.to_json(j); + } + if (sc_mtch_neighbour_cell_r14_present) { + j.write_str("sc-mtch-NeighbourCell-r14", sc_mtch_neighbour_cell_r14.to_string()); + } + j.write_str("npdcch-NPDSCH-MaxTBS-SC-MTCH-r14", npdcch_npdsch_max_tbs_sc_mtch_r14.to_string()); + j.write_str("npdcch-NumRepetitions-SC-MTCH-r14", npdcch_num_repeats_sc_mtch_r14.to_string()); + j.write_str("npdcch-StartSF-SC-MTCH-r14", npdcch_start_sf_sc_mtch_r14.to_string()); + j.write_str("npdcch-Offset-SC-MTCH-r14", npdcch_offset_sc_mtch_r14.to_string()); j.end_obj(); } -const char* sc_mtch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_opts::to_string() const -{ - static const char* options[] = {"pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32", "spare"}; - return convert_enum_idx(options, 8, value, "sc_mtch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_e_"); -} -uint8_t sc_mtch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_opts::to_number() const -{ - static const uint8_t options[] = {1, 2, 3, 4, 8, 16, 32}; - return map_enum_number(options, 7, value, "sc_mtch_sched_info_nb_r14_s::on_dur_timer_scptm_r14_e_"); -} - -const char* sc_mtch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_opts::to_string() const -{ - static const char* options[] = {"pp0", "pp1", "pp2", "pp3", "pp4", "pp8", "pp16", "pp32"}; - return convert_enum_idx(options, 8, value, "sc_mtch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_e_"); -} -uint8_t sc_mtch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_opts::to_number() const -{ - static const uint8_t options[] = {0, 1, 2, 3, 4, 8, 16, 32}; - return map_enum_number(options, 8, value, "sc_mtch_sched_info_nb_r14_s::drx_inactivity_timer_scptm_r14_e_"); -} - -void sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::destroy_() {} -void sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set(types::options e) -{ - destroy_(); - type_ = e; -} -sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::sched_period_start_offset_scptm_r14_c_( - const sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& other) +void sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::destroy_() { - type_ = other.type(); switch (type_) { - case types::sf10: - c.init(other.c.get()); - break; - case types::sf20: - c.init(other.c.get()); - break; - case types::sf32: - c.init(other.c.get()); - break; - case types::sf40: - c.init(other.c.get()); - break; - case types::sf64: - c.init(other.c.get()); - break; - case types::sf80: - c.init(other.c.get()); - break; - case types::sf128: - c.init(other.c.get()); - break; - case types::sf160: - c.init(other.c.get()); - break; - case types::sf256: - c.init(other.c.get()); - break; - case types::sf320: - c.init(other.c.get()); + case types::dl_carrier_cfg_r14: + c.destroy(); break; - case types::sf512: - c.init(other.c.get()); + default: break; - case types::sf640: - c.init(other.c.get()); + } +} +void sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::set(types::options e) +{ + destroy_(); + type_ = e; + switch (type_) { + case types::dl_carrier_cfg_r14: + c.init(); break; - case types::sf1024: - c.init(other.c.get()); + case types::dl_carrier_idx_r14: break; - case types::sf2048: - c.init(other.c.get()); + case types::nulltype: break; - case types::sf4096: - c.init(other.c.get()); + default: + log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); + } +} +sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::sc_mtch_carrier_cfg_r14_c_( + const sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_& other) +{ + type_ = other.type(); + switch (type_) { + case types::dl_carrier_cfg_r14: + c.init(other.c.get()); break; - case types::sf8192: - c.init(other.c.get()); + case types::dl_carrier_idx_r14: + c.init(other.c.get()); break; case types::nulltype: break; default: - log_invalid_choice_id(type_, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); } } -sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& -sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::operator=( - const sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_& other) +sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_& sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::operator=( + const sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_& other) { if (this == &other) { return *this; } set(other.type()); switch (type_) { - case types::sf10: - c.set(other.c.get()); - break; - case types::sf20: - c.set(other.c.get()); - break; - case types::sf32: - c.set(other.c.get()); - break; - case types::sf40: - c.set(other.c.get()); - break; - case types::sf64: - c.set(other.c.get()); - break; - case types::sf80: - c.set(other.c.get()); - break; - case types::sf128: - c.set(other.c.get()); + case types::dl_carrier_cfg_r14: + c.set(other.c.get()); break; - case types::sf160: + case types::dl_carrier_idx_r14: c.set(other.c.get()); break; - case types::sf256: - c.set(other.c.get()); - break; - case types::sf320: - c.set(other.c.get()); - break; - case types::sf512: - c.set(other.c.get()); + case types::nulltype: break; - case types::sf640: - c.set(other.c.get()); + default: + log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); + } + + return *this; +} +dl_carrier_cfg_common_nb_r14_s& sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::set_dl_carrier_cfg_r14() +{ + set(types::dl_carrier_cfg_r14); + return c.get(); +} +uint8_t& sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::set_dl_carrier_idx_r14() +{ + set(types::dl_carrier_idx_r14); + return c.get(); +} +void sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::dl_carrier_cfg_r14: + j.write_fieldname("dl-CarrierConfig-r14"); + c.get().to_json(j); break; - case types::sf1024: - c.set(other.c.get()); + case types::dl_carrier_idx_r14: + j.write_int("dl-CarrierIndex-r14", c.get()); break; - case types::sf2048: - c.set(other.c.get()); + default: + log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); + } + j.end_obj(); +} +SRSASN_CODE sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::dl_carrier_cfg_r14: + HANDLE_CODE(c.get().pack(bref)); break; - case types::sf4096: - c.set(other.c.get()); + case types::dl_carrier_idx_r14: + HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)15u)); break; - case types::sf8192: - c.set(other.c.get()); + default: + log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::dl_carrier_cfg_r14: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::nulltype: + case types::dl_carrier_idx_r14: + HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)15u)); break; default: - log_invalid_choice_id(type_, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); + return SRSASN_ERROR_DECODE_FAIL; } + return SRSASN_SUCCESS; +} - return *this; +const char* sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::types_opts::to_string() const +{ + static const char* options[] = {"dl-CarrierConfig-r14", "dl-CarrierIndex-r14"}; + return convert_enum_idx(options, 2, value, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::types"); } -uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf10() + +const char* sc_mtch_info_nb_r14_s::npdcch_npdsch_max_tbs_sc_mtch_r14_opts::to_string() const { - set(types::sf10); - return c.get(); + static const char* options[] = {"n680", "n2536"}; + return convert_enum_idx(options, 2, value, "sc_mtch_info_nb_r14_s::npdcch_npdsch_max_tbs_sc_mtch_r14_e_"); } -uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf20() +uint16_t sc_mtch_info_nb_r14_s::npdcch_npdsch_max_tbs_sc_mtch_r14_opts::to_number() const { - set(types::sf20); - return c.get(); + static const uint16_t options[] = {680, 2536}; + return map_enum_number(options, 2, value, "sc_mtch_info_nb_r14_s::npdcch_npdsch_max_tbs_sc_mtch_r14_e_"); } -uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf32() + +const char* sc_mtch_info_nb_r14_s::npdcch_num_repeats_sc_mtch_r14_opts::to_string() const { - set(types::sf32); - return c.get(); + static const char* options[] = {"r1", + "r2", + "r4", + "r8", + "r16", + "r32", + "r64", + "r128", + "r256", + "r512", + "r1024", + "r2048", + "spare4", + "spare3", + "spare2", + "spare1"}; + return convert_enum_idx(options, 16, value, "sc_mtch_info_nb_r14_s::npdcch_num_repeats_sc_mtch_r14_e_"); } -uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf40() +uint16_t sc_mtch_info_nb_r14_s::npdcch_num_repeats_sc_mtch_r14_opts::to_number() const { - set(types::sf40); - return c.get(); + static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; + return map_enum_number(options, 12, value, "sc_mtch_info_nb_r14_s::npdcch_num_repeats_sc_mtch_r14_e_"); } -uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf64() + +const char* sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_opts::to_string() const { - set(types::sf64); - return c.get(); + static const char* options[] = {"v1dot5", "v2", "v4", "v8", "v16", "v32", "v48", "v64"}; + return convert_enum_idx(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_e_"); } -uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf80() +float sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_opts::to_number() const { - set(types::sf80); - return c.get(); + static const float options[] = {1.5, 2.0, 4.0, 8.0, 16.0, 32.0, 48.0, 64.0}; + return map_enum_number(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_e_"); } -uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf128() +const char* sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_opts::to_number_string() const { - set(types::sf128); - return c.get(); + static const char* options[] = {"1.5", "2", "4", "8", "16", "32", "48", "64"}; + return convert_enum_idx(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_e_"); } -uint8_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf160() + +const char* sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_opts::to_string() const { - set(types::sf160); - return c.get(); + static const char* options[] = { + "zero", "oneEighth", "oneQuarter", "threeEighth", "oneHalf", "fiveEighth", "threeQuarter", "sevenEighth"}; + return convert_enum_idx(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_e_"); } -uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf256() +float sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_opts::to_number() const { - set(types::sf256); - return c.get(); + static const float options[] = {0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875}; + return map_enum_number(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_e_"); } -uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf320() +const char* sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_opts::to_number_string() const { - set(types::sf320); - return c.get(); + static const char* options[] = {"0", "1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "7/8"}; + return convert_enum_idx(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_e_"); +} + +// SCPTMConfiguration-NB-v1610 ::= SEQUENCE +SRSASN_CODE scptm_cfg_nb_v1610_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(multi_tb_gap_r16_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, sc_mtch_info_list_multi_tb_r16, 0, 64)); + if (multi_tb_gap_r16_present) { + HANDLE_CODE(multi_tb_gap_r16.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE scptm_cfg_nb_v1610_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(multi_tb_gap_r16_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(sc_mtch_info_list_multi_tb_r16, bref, 0, 64)); + if (multi_tb_gap_r16_present) { + HANDLE_CODE(multi_tb_gap_r16.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void scptm_cfg_nb_v1610_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("sc-mtch-InfoListMultiTB-r16"); + for (const auto& e1 : sc_mtch_info_list_multi_tb_r16) { + e1.to_json(j); + } + j.end_array(); + if (multi_tb_gap_r16_present) { + j.write_str("multiTB-Gap-r16", multi_tb_gap_r16.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +const char* scptm_cfg_nb_v1610_s::multi_tb_gap_r16_opts::to_string() const +{ + static const char* options[] = {"sf16", "sf32", "sf64", "sf128"}; + return convert_enum_idx(options, 4, value, "scptm_cfg_nb_v1610_s::multi_tb_gap_r16_e_"); +} +uint8_t scptm_cfg_nb_v1610_s::multi_tb_gap_r16_opts::to_number() const +{ + static const uint8_t options[] = {16, 32, 64, 128}; + return map_enum_number(options, 4, value, "scptm_cfg_nb_v1610_s::multi_tb_gap_r16_e_"); } -uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf512() + +// SCPTMConfiguration-NB-r14 ::= SEQUENCE +SRSASN_CODE scptm_cfg_nb_r14_s::pack(bit_ref& bref) const { - set(types::sf512); - return c.get(); + HANDLE_CODE(bref.pack(scptm_neighbour_cell_list_r14_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(pack_dyn_seq_of(bref, sc_mtch_info_list_r14, 0, 64)); + if (scptm_neighbour_cell_list_r14_present) { + HANDLE_CODE(pack_dyn_seq_of(bref, scptm_neighbour_cell_list_r14, 1, 8)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; } -uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf640() +SRSASN_CODE scptm_cfg_nb_r14_s::unpack(cbit_ref& bref) { - set(types::sf640); - return c.get(); + HANDLE_CODE(bref.unpack(scptm_neighbour_cell_list_r14_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(unpack_dyn_seq_of(sc_mtch_info_list_r14, bref, 0, 64)); + if (scptm_neighbour_cell_list_r14_present) { + HANDLE_CODE(unpack_dyn_seq_of(scptm_neighbour_cell_list_r14, bref, 1, 8)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; } -uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf1024() +void scptm_cfg_nb_r14_s::to_json(json_writer& j) const { - set(types::sf1024); - return c.get(); + j.start_obj(); + j.start_array("sc-mtch-InfoList-r14"); + for (const auto& e1 : sc_mtch_info_list_r14) { + e1.to_json(j); + } + j.end_array(); + if (scptm_neighbour_cell_list_r14_present) { + j.start_array("scptm-NeighbourCellList-r14"); + for (const auto& e1 : scptm_neighbour_cell_list_r14) { + e1.to_json(j); + } + j.end_array(); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); } -uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf2048() + +// SC-MCCH-MessageType-NB ::= CHOICE +void sc_mcch_msg_type_nb_c::set(types::options e) { - set(types::sf2048); - return c.get(); + type_ = e; } -uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf4096() +sc_mcch_msg_type_nb_c::c1_c_& sc_mcch_msg_type_nb_c::set_c1() { - set(types::sf4096); - return c.get(); + set(types::c1); + return c; } -uint16_t& sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::set_sf8192() +void sc_mcch_msg_type_nb_c::set_msg_class_ext() { - set(types::sf8192); - return c.get(); + set(types::msg_class_ext); } -void sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::to_json(json_writer& j) const +void sc_mcch_msg_type_nb_c::to_json(json_writer& j) const { j.start_obj(); switch (type_) { - case types::sf10: - j.write_int("sf10", c.get()); - break; - case types::sf20: - j.write_int("sf20", c.get()); - break; - case types::sf32: - j.write_int("sf32", c.get()); - break; - case types::sf40: - j.write_int("sf40", c.get()); - break; - case types::sf64: - j.write_int("sf64", c.get()); - break; - case types::sf80: - j.write_int("sf80", c.get()); - break; - case types::sf128: - j.write_int("sf128", c.get()); - break; - case types::sf160: - j.write_int("sf160", c.get()); - break; - case types::sf256: - j.write_int("sf256", c.get()); - break; - case types::sf320: - j.write_int("sf320", c.get()); - break; - case types::sf512: - j.write_int("sf512", c.get()); - break; - case types::sf640: - j.write_int("sf640", c.get()); - break; - case types::sf1024: - j.write_int("sf1024", c.get()); - break; - case types::sf2048: - j.write_int("sf2048", c.get()); - break; - case types::sf4096: - j.write_int("sf4096", c.get()); + case types::c1: + j.write_fieldname("c1"); + c.to_json(j); break; - case types::sf8192: - j.write_int("sf8192", c.get()); + case types::msg_class_ext: break; default: - log_invalid_choice_id(type_, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + log_invalid_choice_id(type_, "sc_mcch_msg_type_nb_c"); } j.end_obj(); } -SRSASN_CODE sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::pack(bit_ref& bref) const +SRSASN_CODE sc_mcch_msg_type_nb_c::pack(bit_ref& bref) const { type_.pack(bref); switch (type_) { - case types::sf10: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)9u)); - break; - case types::sf20: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)19u)); - break; - case types::sf32: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)31u)); - break; - case types::sf40: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)39u)); - break; - case types::sf64: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)63u)); - break; - case types::sf80: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)79u)); - break; - case types::sf128: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)127u)); - break; - case types::sf160: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)159u)); - break; - case types::sf256: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)255u)); - break; - case types::sf320: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)319u)); - break; - case types::sf512: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)511u)); - break; - case types::sf640: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)639u)); - break; - case types::sf1024: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)1023u)); - break; - case types::sf2048: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)2047u)); - break; - case types::sf4096: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)4095u)); + case types::c1: + HANDLE_CODE(c.pack(bref)); break; - case types::sf8192: - HANDLE_CODE(pack_integer(bref, c.get(), (uint16_t)0u, (uint16_t)8191u)); + case types::msg_class_ext: break; default: - log_invalid_choice_id(type_, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + log_invalid_choice_id(type_, "sc_mcch_msg_type_nb_c"); return SRSASN_ERROR_ENCODE_FAIL; } return SRSASN_SUCCESS; } -SRSASN_CODE sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::unpack(cbit_ref& bref) +SRSASN_CODE sc_mcch_msg_type_nb_c::unpack(cbit_ref& bref) { types e; e.unpack(bref); set(e); switch (type_) { - case types::sf10: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)9u)); - break; - case types::sf20: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)19u)); - break; - case types::sf32: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)31u)); - break; - case types::sf40: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)39u)); - break; - case types::sf64: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)63u)); - break; - case types::sf80: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)79u)); - break; - case types::sf128: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)127u)); - break; - case types::sf160: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)159u)); - break; - case types::sf256: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)255u)); - break; - case types::sf320: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)319u)); - break; - case types::sf512: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)511u)); - break; - case types::sf640: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)639u)); - break; - case types::sf1024: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)1023u)); - break; - case types::sf2048: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)2047u)); - break; - case types::sf4096: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)4095u)); + case types::c1: + HANDLE_CODE(c.unpack(bref)); break; - case types::sf8192: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint16_t)0u, (uint16_t)8191u)); + case types::msg_class_ext: break; default: - log_invalid_choice_id(type_, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_"); + log_invalid_choice_id(type_, "sc_mcch_msg_type_nb_c"); return SRSASN_ERROR_DECODE_FAIL; } return SRSASN_SUCCESS; } -const char* sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types_opts::to_string() const +void sc_mcch_msg_type_nb_c::c1_c_::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_fieldname("scptmConfiguration-r14"); + c.to_json(j); + j.end_obj(); +} +SRSASN_CODE sc_mcch_msg_type_nb_c::c1_c_::pack(bit_ref& bref) const +{ + HANDLE_CODE(c.pack(bref)); + return SRSASN_SUCCESS; +} +SRSASN_CODE sc_mcch_msg_type_nb_c::c1_c_::unpack(cbit_ref& bref) +{ + HANDLE_CODE(c.unpack(bref)); + return SRSASN_SUCCESS; +} + +const char* sc_mcch_msg_type_nb_c::c1_c_::types_opts::to_string() const { - static const char* options[] = {"sf10", - "sf20", - "sf32", - "sf40", - "sf64", - "sf80", - "sf128", - "sf160", - "sf256", - "sf320", - "sf512", - "sf640", - "sf1024", - "sf2048", - "sf4096", - "sf8192"}; - return convert_enum_idx( - options, 16, value, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types"); + static const char* options[] = {"scptmConfiguration-r14"}; + return convert_enum_idx(options, 1, value, "sc_mcch_msg_type_nb_c::c1_c_::types"); } -uint16_t sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types_opts::to_number() const + +const char* sc_mcch_msg_type_nb_c::types_opts::to_string() const { - static const uint16_t options[] = {10, 20, 32, 40, 64, 80, 128, 160, 256, 320, 512, 640, 1024, 2048, 4096, 8192}; - return map_enum_number( - options, 16, value, "sc_mtch_sched_info_nb_r14_s::sched_period_start_offset_scptm_r14_c_::types"); + static const char* options[] = {"c1", "messageClassExtension"}; + return convert_enum_idx(options, 2, value, "sc_mcch_msg_type_nb_c::types"); +} +uint8_t sc_mcch_msg_type_nb_c::types_opts::to_number() const +{ + static const uint8_t options[] = {1}; + return map_enum_number(options, 1, value, "sc_mcch_msg_type_nb_c::types"); } -// SC-MTCH-Info-NB-r14 ::= SEQUENCE -SRSASN_CODE sc_mtch_info_nb_r14_s::pack(bit_ref& bref) const +// SC-MCCH-Message-NB ::= SEQUENCE +SRSASN_CODE sc_mcch_msg_nb_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(sc_mtch_sched_info_r14_present, 1)); - HANDLE_CODE(bref.pack(sc_mtch_neighbour_cell_r14_present, 1)); + HANDLE_CODE(msg.pack(bref)); - HANDLE_CODE(sc_mtch_carrier_cfg_r14.pack(bref)); - HANDLE_CODE(mbms_session_info_r14.pack(bref)); - HANDLE_CODE(g_rnti_r14.pack(bref)); - if (sc_mtch_sched_info_r14_present) { - HANDLE_CODE(sc_mtch_sched_info_r14.pack(bref)); - } - if (sc_mtch_neighbour_cell_r14_present) { - HANDLE_CODE(sc_mtch_neighbour_cell_r14.pack(bref)); - } - HANDLE_CODE(npdcch_npdsch_max_tbs_sc_mtch_r14.pack(bref)); - HANDLE_CODE(npdcch_num_repeats_sc_mtch_r14.pack(bref)); - HANDLE_CODE(npdcch_start_sf_sc_mtch_r14.pack(bref)); - HANDLE_CODE(npdcch_offset_sc_mtch_r14.pack(bref)); + bref.align_bytes_zero(); return SRSASN_SUCCESS; } -SRSASN_CODE sc_mtch_info_nb_r14_s::unpack(cbit_ref& bref) +SRSASN_CODE sc_mcch_msg_nb_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(sc_mtch_sched_info_r14_present, 1)); - HANDLE_CODE(bref.unpack(sc_mtch_neighbour_cell_r14_present, 1)); + HANDLE_CODE(msg.unpack(bref)); - HANDLE_CODE(sc_mtch_carrier_cfg_r14.unpack(bref)); - HANDLE_CODE(mbms_session_info_r14.unpack(bref)); - HANDLE_CODE(g_rnti_r14.unpack(bref)); - if (sc_mtch_sched_info_r14_present) { - HANDLE_CODE(sc_mtch_sched_info_r14.unpack(bref)); - } - if (sc_mtch_neighbour_cell_r14_present) { - HANDLE_CODE(sc_mtch_neighbour_cell_r14.unpack(bref)); - } - HANDLE_CODE(npdcch_npdsch_max_tbs_sc_mtch_r14.unpack(bref)); - HANDLE_CODE(npdcch_num_repeats_sc_mtch_r14.unpack(bref)); - HANDLE_CODE(npdcch_start_sf_sc_mtch_r14.unpack(bref)); - HANDLE_CODE(npdcch_offset_sc_mtch_r14.unpack(bref)); + bref.align_bytes(); return SRSASN_SUCCESS; } -void sc_mtch_info_nb_r14_s::to_json(json_writer& j) const +void sc_mcch_msg_nb_s::to_json(json_writer& j) const { + j.start_array(); j.start_obj(); - j.write_fieldname("sc-mtch-CarrierConfig-r14"); - sc_mtch_carrier_cfg_r14.to_json(j); - j.write_fieldname("mbmsSessionInfo-r14"); - mbms_session_info_r14.to_json(j); - j.write_str("g-RNTI-r14", g_rnti_r14.to_string()); - if (sc_mtch_sched_info_r14_present) { - j.write_fieldname("sc-mtch-SchedulingInfo-r14"); - sc_mtch_sched_info_r14.to_json(j); + j.start_obj("SC-MCCH-Message-NB"); + j.write_fieldname("message"); + msg.to_json(j); + j.end_obj(); + j.end_obj(); + j.end_array(); +} + +// PhyLayerParameters-NB-v1430 ::= SEQUENCE +SRSASN_CODE phy_layer_params_nb_v1430_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(multi_carrier_nprach_r14_present, 1)); + HANDLE_CODE(bref.pack(two_harq_processes_r14_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE phy_layer_params_nb_v1430_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(multi_carrier_nprach_r14_present, 1)); + HANDLE_CODE(bref.unpack(two_harq_processes_r14_present, 1)); + + return SRSASN_SUCCESS; +} +void phy_layer_params_nb_v1430_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (multi_carrier_nprach_r14_present) { + j.write_str("multiCarrier-NPRACH-r14", "supported"); } - if (sc_mtch_neighbour_cell_r14_present) { - j.write_str("sc-mtch-NeighbourCell-r14", sc_mtch_neighbour_cell_r14.to_string()); + if (two_harq_processes_r14_present) { + j.write_str("twoHARQ-Processes-r14", "supported"); } - j.write_str("npdcch-NPDSCH-MaxTBS-SC-MTCH-r14", npdcch_npdsch_max_tbs_sc_mtch_r14.to_string()); - j.write_str("npdcch-NumRepetitions-SC-MTCH-r14", npdcch_num_repeats_sc_mtch_r14.to_string()); - j.write_str("npdcch-StartSF-SC-MTCH-r14", npdcch_start_sf_sc_mtch_r14.to_string()); - j.write_str("npdcch-Offset-SC-MTCH-r14", npdcch_offset_sc_mtch_r14.to_string()); j.end_obj(); } -void sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::destroy_() +// PhyLayerParameters-NB-v1530 ::= SEQUENCE +SRSASN_CODE phy_layer_params_nb_v1530_s::pack(bit_ref& bref) const { - switch (type_) { - case types::dl_carrier_cfg_r14: - c.destroy(); - break; - default: - break; - } + HANDLE_CODE(bref.pack(mixed_operation_mode_r15_present, 1)); + HANDLE_CODE(bref.pack(sr_with_harq_ack_r15_present, 1)); + HANDLE_CODE(bref.pack(sr_without_harq_ack_r15_present, 1)); + HANDLE_CODE(bref.pack(nprach_format2_r15_present, 1)); + HANDLE_CODE(bref.pack(add_tx_sib1_r15_present, 1)); + HANDLE_CODE(bref.pack(npusch_minus3dot75k_hz_scs_tdd_r15_present, 1)); + + return SRSASN_SUCCESS; } -void sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::set(types::options e) +SRSASN_CODE phy_layer_params_nb_v1530_s::unpack(cbit_ref& bref) { - destroy_(); - type_ = e; - switch (type_) { - case types::dl_carrier_cfg_r14: - c.init(); - break; - case types::dl_carrier_idx_r14: - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); + HANDLE_CODE(bref.unpack(mixed_operation_mode_r15_present, 1)); + HANDLE_CODE(bref.unpack(sr_with_harq_ack_r15_present, 1)); + HANDLE_CODE(bref.unpack(sr_without_harq_ack_r15_present, 1)); + HANDLE_CODE(bref.unpack(nprach_format2_r15_present, 1)); + HANDLE_CODE(bref.unpack(add_tx_sib1_r15_present, 1)); + HANDLE_CODE(bref.unpack(npusch_minus3dot75k_hz_scs_tdd_r15_present, 1)); + + return SRSASN_SUCCESS; +} +void phy_layer_params_nb_v1530_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (mixed_operation_mode_r15_present) { + j.write_str("mixedOperationMode-r15", "supported"); + } + if (sr_with_harq_ack_r15_present) { + j.write_str("sr-WithHARQ-ACK-r15", "supported"); + } + if (sr_without_harq_ack_r15_present) { + j.write_str("sr-WithoutHARQ-ACK-r15", "supported"); + } + if (nprach_format2_r15_present) { + j.write_str("nprach-Format2-r15", "supported"); + } + if (add_tx_sib1_r15_present) { + j.write_str("additionalTransmissionSIB1-r15", "supported"); + } + if (npusch_minus3dot75k_hz_scs_tdd_r15_present) { + j.write_str("npusch-3dot75kHz-SCS-TDD-r15", "supported"); } + j.end_obj(); } -sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::sc_mtch_carrier_cfg_r14_c_( - const sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_& other) + +// TDD-UE-Capability-NB-r15 ::= SEQUENCE +SRSASN_CODE tdd_ue_cap_nb_r15_s::pack(bit_ref& bref) const { - type_ = other.type(); - switch (type_) { - case types::dl_carrier_cfg_r14: - c.init(other.c.get()); - break; - case types::dl_carrier_idx_r14: - c.init(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); + bref.pack(ext, 1); + HANDLE_CODE(bref.pack(ue_category_nb_r15_present, 1)); + HANDLE_CODE(bref.pack(phy_layer_params_rel13_r15_present, 1)); + HANDLE_CODE(bref.pack(phy_layer_params_rel14_r15_present, 1)); + HANDLE_CODE(bref.pack(phy_layer_params_v1530_present, 1)); + + if (phy_layer_params_rel13_r15_present) { + HANDLE_CODE(phy_layer_params_rel13_r15.pack(bref)); + } + if (phy_layer_params_rel14_r15_present) { + HANDLE_CODE(phy_layer_params_rel14_r15.pack(bref)); + } + if (phy_layer_params_v1530_present) { + HANDLE_CODE(phy_layer_params_v1530.pack(bref)); } + + return SRSASN_SUCCESS; } -sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_& sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::operator=( - const sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_& other) +SRSASN_CODE tdd_ue_cap_nb_r15_s::unpack(cbit_ref& bref) { - if (this == &other) { - return *this; + bref.unpack(ext, 1); + HANDLE_CODE(bref.unpack(ue_category_nb_r15_present, 1)); + HANDLE_CODE(bref.unpack(phy_layer_params_rel13_r15_present, 1)); + HANDLE_CODE(bref.unpack(phy_layer_params_rel14_r15_present, 1)); + HANDLE_CODE(bref.unpack(phy_layer_params_v1530_present, 1)); + + if (phy_layer_params_rel13_r15_present) { + HANDLE_CODE(phy_layer_params_rel13_r15.unpack(bref)); } - set(other.type()); - switch (type_) { - case types::dl_carrier_cfg_r14: - c.set(other.c.get()); - break; - case types::dl_carrier_idx_r14: - c.set(other.c.get()); - break; - case types::nulltype: - break; - default: - log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); + if (phy_layer_params_rel14_r15_present) { + HANDLE_CODE(phy_layer_params_rel14_r15.unpack(bref)); + } + if (phy_layer_params_v1530_present) { + HANDLE_CODE(phy_layer_params_v1530.unpack(bref)); } - return *this; + return SRSASN_SUCCESS; } -dl_carrier_cfg_common_nb_r14_s& sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::set_dl_carrier_cfg_r14() +void tdd_ue_cap_nb_r15_s::to_json(json_writer& j) const { - set(types::dl_carrier_cfg_r14); - return c.get(); + j.start_obj(); + if (ue_category_nb_r15_present) { + j.write_str("ue-Category-NB-r15", "nb2"); + } + if (phy_layer_params_rel13_r15_present) { + j.write_fieldname("phyLayerParametersRel13-r15"); + phy_layer_params_rel13_r15.to_json(j); + } + if (phy_layer_params_rel14_r15_present) { + j.write_fieldname("phyLayerParametersRel14-r15"); + phy_layer_params_rel14_r15.to_json(j); + } + if (phy_layer_params_v1530_present) { + j.write_fieldname("phyLayerParameters-v1530"); + phy_layer_params_v1530.to_json(j); + } + j.end_obj(); } -uint8_t& sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::set_dl_carrier_idx_r14() + +// PhyLayerParameters-NB-v1700 ::= SEQUENCE +SRSASN_CODE phy_layer_params_nb_v1700_s::pack(bit_ref& bref) const { - set(types::dl_carrier_idx_r14); - return c.get(); + HANDLE_CODE(bref.pack(npdsch_minus16_qam_r17_present, 1)); + + return SRSASN_SUCCESS; } -void sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::to_json(json_writer& j) const +SRSASN_CODE phy_layer_params_nb_v1700_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(npdsch_minus16_qam_r17_present, 1)); + + return SRSASN_SUCCESS; +} +void phy_layer_params_nb_v1700_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::dl_carrier_cfg_r14: - j.write_fieldname("dl-CarrierConfig-r14"); - c.get().to_json(j); - break; - case types::dl_carrier_idx_r14: - j.write_int("dl-CarrierIndex-r14", c.get()); - break; - default: - log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); + if (npdsch_minus16_qam_r17_present) { + j.write_str("npdsch-16QAM-r17", "supported"); } j.end_obj(); } -SRSASN_CODE sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::pack(bit_ref& bref) const + +// TDD-UE-Capability-NB-v1710 ::= SEQUENCE +SRSASN_CODE tdd_ue_cap_nb_v1710_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::dl_carrier_cfg_r14: - HANDLE_CODE(c.get().pack(bref)); - break; - case types::dl_carrier_idx_r14: - HANDLE_CODE(pack_integer(bref, c.get(), (uint8_t)0u, (uint8_t)15u)); - break; - default: - log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); - return SRSASN_ERROR_ENCODE_FAIL; + HANDLE_CODE(bref.pack(phy_layer_params_v1710_present, 1)); + + if (phy_layer_params_v1710_present) { + HANDLE_CODE(phy_layer_params_v1710.pack(bref)); } + return SRSASN_SUCCESS; } -SRSASN_CODE sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::unpack(cbit_ref& bref) +SRSASN_CODE tdd_ue_cap_nb_v1710_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::dl_carrier_cfg_r14: - HANDLE_CODE(c.get().unpack(bref)); - break; - case types::dl_carrier_idx_r14: - HANDLE_CODE(unpack_integer(c.get(), bref, (uint8_t)0u, (uint8_t)15u)); - break; - default: - log_invalid_choice_id(type_, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_"); - return SRSASN_ERROR_DECODE_FAIL; + HANDLE_CODE(bref.unpack(phy_layer_params_v1710_present, 1)); + + if (phy_layer_params_v1710_present) { + HANDLE_CODE(phy_layer_params_v1710.unpack(bref)); } + return SRSASN_SUCCESS; } +void tdd_ue_cap_nb_v1710_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (phy_layer_params_v1710_present) { + j.write_fieldname("phyLayerParameters-v1710"); + phy_layer_params_v1710.to_json(j); + } + j.end_obj(); +} -const char* sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::types_opts::to_string() const +// NTN-Parameters-NB-v1720 ::= SEQUENCE +SRSASN_CODE ntn_params_nb_v1720_s::pack(bit_ref& bref) const { - static const char* options[] = {"dl-CarrierConfig-r14", "dl-CarrierIndex-r14"}; - return convert_enum_idx(options, 2, value, "sc_mtch_info_nb_r14_s::sc_mtch_carrier_cfg_r14_c_::types"); + HANDLE_CODE(bref.pack(ntn_segmented_precompensation_gaps_r17_present, 1)); + + if (ntn_segmented_precompensation_gaps_r17_present) { + HANDLE_CODE(ntn_segmented_precompensation_gaps_r17.pack(bref)); + } + + return SRSASN_SUCCESS; } +SRSASN_CODE ntn_params_nb_v1720_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(ntn_segmented_precompensation_gaps_r17_present, 1)); -const char* sc_mtch_info_nb_r14_s::npdcch_npdsch_max_tbs_sc_mtch_r14_opts::to_string() const + if (ntn_segmented_precompensation_gaps_r17_present) { + HANDLE_CODE(ntn_segmented_precompensation_gaps_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ntn_params_nb_v1720_s::to_json(json_writer& j) const { - static const char* options[] = {"n680", "n2536"}; - return convert_enum_idx(options, 2, value, "sc_mtch_info_nb_r14_s::npdcch_npdsch_max_tbs_sc_mtch_r14_e_"); + j.start_obj(); + if (ntn_segmented_precompensation_gaps_r17_present) { + j.write_str("ntn-SegmentedPrecompensationGaps-r17", ntn_segmented_precompensation_gaps_r17.to_string()); + } + j.end_obj(); } -uint16_t sc_mtch_info_nb_r14_s::npdcch_npdsch_max_tbs_sc_mtch_r14_opts::to_number() const + +const char* ntn_params_nb_v1720_s::ntn_segmented_precompensation_gaps_r17_opts::to_string() const { - static const uint16_t options[] = {680, 2536}; - return map_enum_number(options, 2, value, "sc_mtch_info_nb_r14_s::npdcch_npdsch_max_tbs_sc_mtch_r14_e_"); + static const char* options[] = {"sym1", "sl1", "sl2"}; + return convert_enum_idx(options, 3, value, "ntn_params_nb_v1720_s::ntn_segmented_precompensation_gaps_r17_e_"); } -const char* sc_mtch_info_nb_r14_s::npdcch_num_repeats_sc_mtch_r14_opts::to_string() const +// MeasParameters-NB-v1710 ::= SEQUENCE +SRSASN_CODE meas_params_nb_v1710_s::pack(bit_ref& bref) const { - static const char* options[] = {"r1", - "r2", - "r4", - "r8", - "r16", - "r32", - "r64", - "r128", - "r256", - "r512", - "r1024", - "r2048", - "spare4", - "spare3", - "spare2", - "spare1"}; - return convert_enum_idx(options, 16, value, "sc_mtch_info_nb_r14_s::npdcch_num_repeats_sc_mtch_r14_e_"); + HANDLE_CODE(bref.pack(conn_mode_meas_intra_freq_r17_present, 1)); + HANDLE_CODE(bref.pack(conn_mode_meas_inter_freq_r17_present, 1)); + + return SRSASN_SUCCESS; } -uint16_t sc_mtch_info_nb_r14_s::npdcch_num_repeats_sc_mtch_r14_opts::to_number() const +SRSASN_CODE meas_params_nb_v1710_s::unpack(cbit_ref& bref) { - static const uint16_t options[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048}; - return map_enum_number(options, 12, value, "sc_mtch_info_nb_r14_s::npdcch_num_repeats_sc_mtch_r14_e_"); + HANDLE_CODE(bref.unpack(conn_mode_meas_intra_freq_r17_present, 1)); + HANDLE_CODE(bref.unpack(conn_mode_meas_inter_freq_r17_present, 1)); + + return SRSASN_SUCCESS; +} +void meas_params_nb_v1710_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (conn_mode_meas_intra_freq_r17_present) { + j.write_str("connModeMeasIntraFreq-r17", "supported"); + } + if (conn_mode_meas_inter_freq_r17_present) { + j.write_str("connModeMeasInterFreq-r17", "supported"); + } + j.end_obj(); } -const char* sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_opts::to_string() const +// UE-Capability-NB-v1720-IEs ::= SEQUENCE +SRSASN_CODE ue_cap_nb_v1720_ies_s::pack(bit_ref& bref) const { - static const char* options[] = {"v1dot5", "v2", "v4", "v8", "v16", "v32", "v48", "v64"}; - return convert_enum_idx(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_e_"); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(ntn_params_v1720.pack(bref)); + + return SRSASN_SUCCESS; } -float sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_opts::to_number() const +SRSASN_CODE ue_cap_nb_v1720_ies_s::unpack(cbit_ref& bref) { - static const float options[] = {1.5, 2.0, 4.0, 8.0, 16.0, 32.0, 48.0, 64.0}; - return map_enum_number(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_e_"); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(ntn_params_v1720.unpack(bref)); + + return SRSASN_SUCCESS; } -const char* sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_opts::to_number_string() const +void ue_cap_nb_v1720_ies_s::to_json(json_writer& j) const { - static const char* options[] = {"1.5", "2", "4", "8", "16", "32", "48", "64"}; - return convert_enum_idx(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_start_sf_sc_mtch_r14_e_"); + j.start_obj(); + j.write_fieldname("ntn-Parameters-v1720"); + ntn_params_v1720.to_json(j); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); } -const char* sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_opts::to_string() const +// NTN-Parameters-NB-r17 ::= SEQUENCE +SRSASN_CODE ntn_params_nb_r17_s::pack(bit_ref& bref) const { - static const char* options[] = { - "zero", "oneEighth", "oneQuarter", "threeEighth", "oneHalf", "fiveEighth", "threeQuarter", "sevenEighth"}; - return convert_enum_idx(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_e_"); + HANDLE_CODE(bref.pack(ntn_connect_epc_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_ta_report_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_pur_timer_delay_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_offset_timing_enh_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_scenario_support_r17_present, 1)); + + if (ntn_scenario_support_r17_present) { + HANDLE_CODE(ntn_scenario_support_r17.pack(bref)); + } + + return SRSASN_SUCCESS; } -float sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_opts::to_number() const +SRSASN_CODE ntn_params_nb_r17_s::unpack(cbit_ref& bref) { - static const float options[] = {0.0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875}; - return map_enum_number(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_e_"); + HANDLE_CODE(bref.unpack(ntn_connect_epc_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_ta_report_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_pur_timer_delay_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_offset_timing_enh_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_scenario_support_r17_present, 1)); + + if (ntn_scenario_support_r17_present) { + HANDLE_CODE(ntn_scenario_support_r17.unpack(bref)); + } + + return SRSASN_SUCCESS; } -const char* sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_opts::to_number_string() const +void ntn_params_nb_r17_s::to_json(json_writer& j) const { - static const char* options[] = {"0", "1/8", "1/4", "3/8", "1/2", "5/8", "3/4", "7/8"}; - return convert_enum_idx(options, 8, value, "sc_mtch_info_nb_r14_s::npdcch_offset_sc_mtch_r14_e_"); + j.start_obj(); + if (ntn_connect_epc_r17_present) { + j.write_str("ntn-Connectivity-EPC-r17", "supported"); + } + if (ntn_ta_report_r17_present) { + j.write_str("ntn-TA-Report-r17", "supported"); + } + if (ntn_pur_timer_delay_r17_present) { + j.write_str("ntn-PUR-TimerDelay-r17", "supported"); + } + if (ntn_offset_timing_enh_r17_present) { + j.write_str("ntn-OffsetTimingEnh-r17", "supported"); + } + if (ntn_scenario_support_r17_present) { + j.write_str("ntn-ScenarioSupport-r17", ntn_scenario_support_r17.to_string()); + } + j.end_obj(); } -// SCPTMConfiguration-NB-r14 ::= SEQUENCE -SRSASN_CODE scptm_cfg_nb_r14_s::pack(bit_ref& bref) const +const char* ntn_params_nb_r17_s::ntn_scenario_support_r17_opts::to_string() const { - HANDLE_CODE(bref.pack(scptm_neighbour_cell_list_r14_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + static const char* options[] = {"ngso", "gso"}; + return convert_enum_idx(options, 2, value, "ntn_params_nb_r17_s::ntn_scenario_support_r17_e_"); +} + +// UE-Capability-NB-v1710-IEs ::= SEQUENCE +SRSASN_CODE ue_cap_nb_v1710_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(meas_params_v1710_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - HANDLE_CODE(pack_dyn_seq_of(bref, sc_mtch_info_list_r14, 0, 64)); - if (scptm_neighbour_cell_list_r14_present) { - HANDLE_CODE(pack_dyn_seq_of(bref, scptm_neighbour_cell_list_r14, 1, 8)); + if (meas_params_v1710_present) { + HANDLE_CODE(meas_params_v1710.pack(bref)); } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.pack(bref)); + HANDLE_CODE(rf_params_v1710.pack(bref)); + HANDLE_CODE(tdd_ue_cap_v1710.pack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE scptm_cfg_nb_r14_s::unpack(cbit_ref& bref) +SRSASN_CODE ue_cap_nb_v1710_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(scptm_neighbour_cell_list_r14_present, 1)); - HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(meas_params_v1710_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - HANDLE_CODE(unpack_dyn_seq_of(sc_mtch_info_list_r14, bref, 0, 64)); - if (scptm_neighbour_cell_list_r14_present) { - HANDLE_CODE(unpack_dyn_seq_of(scptm_neighbour_cell_list_r14, bref, 1, 8)); + if (meas_params_v1710_present) { + HANDLE_CODE(meas_params_v1710.unpack(bref)); } - if (late_non_crit_ext_present) { - HANDLE_CODE(late_non_crit_ext.unpack(bref)); + HANDLE_CODE(rf_params_v1710.unpack(bref)); + HANDLE_CODE(tdd_ue_cap_v1710.unpack(bref)); + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); } return SRSASN_SUCCESS; } -void scptm_cfg_nb_r14_s::to_json(json_writer& j) const +void ue_cap_nb_v1710_ies_s::to_json(json_writer& j) const { j.start_obj(); - j.start_array("sc-mtch-InfoList-r14"); - for (const auto& e1 : sc_mtch_info_list_r14) { - e1.to_json(j); - } - j.end_array(); - if (scptm_neighbour_cell_list_r14_present) { - j.start_array("scptm-NeighbourCellList-r14"); - for (const auto& e1 : scptm_neighbour_cell_list_r14) { - e1.to_json(j); - } - j.end_array(); - } - if (late_non_crit_ext_present) { - j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + if (meas_params_v1710_present) { + j.write_fieldname("measParameters-v1710"); + meas_params_v1710.to_json(j); } + j.write_fieldname("rf-Parameters-v1710"); + rf_params_v1710.to_json(j); + j.write_fieldname("tdd-UE-Capability-v1710"); + tdd_ue_cap_v1710.to_json(j); if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } -// SC-MCCH-MessageType-NB ::= CHOICE -void sc_mcch_msg_type_nb_c::set(types::options e) +// UE-Capability-NB-v1700-IEs ::= SEQUENCE +SRSASN_CODE ue_cap_nb_v1700_ies_s::pack(bit_ref& bref) const { - type_ = e; + HANDLE_CODE(bref.pack(coverage_based_paging_r17_present, 1)); + HANDLE_CODE(bref.pack(ntn_params_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + HANDLE_CODE(phy_layer_params_v1700.pack(bref)); + if (ntn_params_r17_present) { + HANDLE_CODE(ntn_params_r17.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; } -sc_mcch_msg_type_nb_c::c1_c_& sc_mcch_msg_type_nb_c::set_c1() +SRSASN_CODE ue_cap_nb_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(coverage_based_paging_r17_present, 1)); + HANDLE_CODE(bref.unpack(ntn_params_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + HANDLE_CODE(phy_layer_params_v1700.unpack(bref)); + if (ntn_params_r17_present) { + HANDLE_CODE(ntn_params_r17.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_cap_nb_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (coverage_based_paging_r17_present) { + j.write_str("coverageBasedPaging-r17", "supported"); + } + j.write_fieldname("phyLayerParameters-v1700"); + phy_layer_params_v1700.to_json(j); + if (ntn_params_r17_present) { + j.write_fieldname("ntn-Parameters-r17"); + ntn_params_r17.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); + } + j.end_obj(); +} + +// MAC-Parameters-NB-v1610 ::= SEQUENCE +SRSASN_CODE mac_params_nb_v1610_s::pack(bit_ref& bref) const { - set(types::c1); - return c; + HANDLE_CODE(bref.pack(rai_support_enh_r16_present, 1)); + + return SRSASN_SUCCESS; } -void sc_mcch_msg_type_nb_c::set_msg_class_ext() +SRSASN_CODE mac_params_nb_v1610_s::unpack(cbit_ref& bref) { - set(types::msg_class_ext); + HANDLE_CODE(bref.unpack(rai_support_enh_r16_present, 1)); + + return SRSASN_SUCCESS; } -void sc_mcch_msg_type_nb_c::to_json(json_writer& j) const +void mac_params_nb_v1610_s::to_json(json_writer& j) const { j.start_obj(); - switch (type_) { - case types::c1: - j.write_fieldname("c1"); - c.to_json(j); - break; - case types::msg_class_ext: - break; - default: - log_invalid_choice_id(type_, "sc_mcch_msg_type_nb_c"); + if (rai_support_enh_r16_present) { + j.write_str("rai-SupportEnh-r16", "supported"); } j.end_obj(); } -SRSASN_CODE sc_mcch_msg_type_nb_c::pack(bit_ref& bref) const + +// MeasParameters-NB-r16 ::= SEQUENCE +SRSASN_CODE meas_params_nb_r16_s::pack(bit_ref& bref) const { - type_.pack(bref); - switch (type_) { - case types::c1: - HANDLE_CODE(c.pack(bref)); - break; - case types::msg_class_ext: - break; - default: - log_invalid_choice_id(type_, "sc_mcch_msg_type_nb_c"); - return SRSASN_ERROR_ENCODE_FAIL; - } + HANDLE_CODE(bref.pack(dl_ch_quality_report_r16_present, 1)); + return SRSASN_SUCCESS; } -SRSASN_CODE sc_mcch_msg_type_nb_c::unpack(cbit_ref& bref) +SRSASN_CODE meas_params_nb_r16_s::unpack(cbit_ref& bref) { - types e; - e.unpack(bref); - set(e); - switch (type_) { - case types::c1: - HANDLE_CODE(c.unpack(bref)); - break; - case types::msg_class_ext: - break; - default: - log_invalid_choice_id(type_, "sc_mcch_msg_type_nb_c"); - return SRSASN_ERROR_DECODE_FAIL; - } + HANDLE_CODE(bref.unpack(dl_ch_quality_report_r16_present, 1)); + return SRSASN_SUCCESS; } - -void sc_mcch_msg_type_nb_c::c1_c_::to_json(json_writer& j) const +void meas_params_nb_r16_s::to_json(json_writer& j) const { j.start_obj(); - j.write_fieldname("scptmConfiguration-r14"); - c.to_json(j); + if (dl_ch_quality_report_r16_present) { + j.write_str("dl-ChannelQualityReporting-r16", "supported"); + } j.end_obj(); } -SRSASN_CODE sc_mcch_msg_type_nb_c::c1_c_::pack(bit_ref& bref) const + +// PUR-Parameters-NB-r16 ::= SEQUENCE +SRSASN_CODE pur_params_nb_r16_s::pack(bit_ref& bref) const { - HANDLE_CODE(c.pack(bref)); + HANDLE_CODE(bref.pack(pur_cp_epc_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_cp_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_up_epc_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_up_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_nrsrp_validation_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_cp_l1_ack_r16_present, 1)); + return SRSASN_SUCCESS; } -SRSASN_CODE sc_mcch_msg_type_nb_c::c1_c_::unpack(cbit_ref& bref) +SRSASN_CODE pur_params_nb_r16_s::unpack(cbit_ref& bref) { - HANDLE_CODE(c.unpack(bref)); + HANDLE_CODE(bref.unpack(pur_cp_epc_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_cp_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_up_epc_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_up_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_nrsrp_validation_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_cp_l1_ack_r16_present, 1)); + return SRSASN_SUCCESS; } - -const char* sc_mcch_msg_type_nb_c::c1_c_::types_opts::to_string() const +void pur_params_nb_r16_s::to_json(json_writer& j) const { - static const char* options[] = {"scptmConfiguration-r14"}; - return convert_enum_idx(options, 1, value, "sc_mcch_msg_type_nb_c::c1_c_::types"); + j.start_obj(); + if (pur_cp_epc_r16_present) { + j.write_str("pur-CP-EPC-r16", "supported"); + } + if (pur_cp_minus5_gc_r16_present) { + j.write_str("pur-CP-5GC-r16", "supported"); + } + if (pur_up_epc_r16_present) { + j.write_str("pur-UP-EPC-r16", "supported"); + } + if (pur_up_minus5_gc_r16_present) { + j.write_str("pur-UP-5GC-r16", "supported"); + } + if (pur_nrsrp_validation_r16_present) { + j.write_str("pur-NRSRP-Validation-r16", "supported"); + } + if (pur_cp_l1_ack_r16_present) { + j.write_str("pur-CP-L1Ack-r16", "supported"); + } + j.end_obj(); } -const char* sc_mcch_msg_type_nb_c::types_opts::to_string() const +// PhyLayerParameters-NB-v1610 ::= SEQUENCE +SRSASN_CODE phy_layer_params_nb_v1610_s::pack(bit_ref& bref) const { - static const char* options[] = {"c1", "messageClassExtension"}; - return convert_enum_idx(options, 2, value, "sc_mcch_msg_type_nb_c::types"); + HANDLE_CODE(bref.pack(npdsch_multi_tb_r16_present, 1)); + HANDLE_CODE(bref.pack(npdsch_multi_tb_interleaving_r16_present, 1)); + HANDLE_CODE(bref.pack(npusch_multi_tb_r16_present, 1)); + HANDLE_CODE(bref.pack(npusch_multi_tb_interleaving_r16_present, 1)); + HANDLE_CODE(bref.pack(multi_tb_harq_ack_bundling_r16_present, 1)); + HANDLE_CODE(bref.pack(slot_symbol_res_resv_dl_r16_present, 1)); + HANDLE_CODE(bref.pack(slot_symbol_res_resv_ul_r16_present, 1)); + HANDLE_CODE(bref.pack(sf_res_resv_dl_r16_present, 1)); + HANDLE_CODE(bref.pack(sf_res_resv_ul_r16_present, 1)); + + return SRSASN_SUCCESS; } -uint8_t sc_mcch_msg_type_nb_c::types_opts::to_number() const +SRSASN_CODE phy_layer_params_nb_v1610_s::unpack(cbit_ref& bref) { - static const uint8_t options[] = {1}; - return map_enum_number(options, 1, value, "sc_mcch_msg_type_nb_c::types"); -} + HANDLE_CODE(bref.unpack(npdsch_multi_tb_r16_present, 1)); + HANDLE_CODE(bref.unpack(npdsch_multi_tb_interleaving_r16_present, 1)); + HANDLE_CODE(bref.unpack(npusch_multi_tb_r16_present, 1)); + HANDLE_CODE(bref.unpack(npusch_multi_tb_interleaving_r16_present, 1)); + HANDLE_CODE(bref.unpack(multi_tb_harq_ack_bundling_r16_present, 1)); + HANDLE_CODE(bref.unpack(slot_symbol_res_resv_dl_r16_present, 1)); + HANDLE_CODE(bref.unpack(slot_symbol_res_resv_ul_r16_present, 1)); + HANDLE_CODE(bref.unpack(sf_res_resv_dl_r16_present, 1)); + HANDLE_CODE(bref.unpack(sf_res_resv_ul_r16_present, 1)); -// SC-MCCH-Message-NB ::= SEQUENCE -SRSASN_CODE sc_mcch_msg_nb_s::pack(bit_ref& bref) const + return SRSASN_SUCCESS; +} +void phy_layer_params_nb_v1610_s::to_json(json_writer& j) const { - HANDLE_CODE(msg.pack(bref)); + j.start_obj(); + if (npdsch_multi_tb_r16_present) { + j.write_str("npdsch-MultiTB-r16", "supported"); + } + if (npdsch_multi_tb_interleaving_r16_present) { + j.write_str("npdsch-MultiTB-Interleaving-r16", "supported"); + } + if (npusch_multi_tb_r16_present) { + j.write_str("npusch-MultiTB-r16", "supported"); + } + if (npusch_multi_tb_interleaving_r16_present) { + j.write_str("npusch-MultiTB-Interleaving-r16", "supported"); + } + if (multi_tb_harq_ack_bundling_r16_present) { + j.write_str("multiTB-HARQ-AckBundling-r16", "supported"); + } + if (slot_symbol_res_resv_dl_r16_present) { + j.write_str("slotSymbolResourceResvDL-r16", "supported"); + } + if (slot_symbol_res_resv_ul_r16_present) { + j.write_str("slotSymbolResourceResvUL-r16", "supported"); + } + if (sf_res_resv_dl_r16_present) { + j.write_str("subframeResourceResvDL-r16", "supported"); + } + if (sf_res_resv_ul_r16_present) { + j.write_str("subframeResourceResvUL-r16", "supported"); + } + j.end_obj(); +} - bref.align_bytes_zero(); +// SON-Parameters-NB-r16 ::= SEQUENCE +SRSASN_CODE son_params_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(anr_report_r16_present, 1)); + HANDLE_CODE(bref.pack(rach_report_r16_present, 1)); return SRSASN_SUCCESS; } -SRSASN_CODE sc_mcch_msg_nb_s::unpack(cbit_ref& bref) +SRSASN_CODE son_params_nb_r16_s::unpack(cbit_ref& bref) { - HANDLE_CODE(msg.unpack(bref)); - - bref.align_bytes(); + HANDLE_CODE(bref.unpack(anr_report_r16_present, 1)); + HANDLE_CODE(bref.unpack(rach_report_r16_present, 1)); return SRSASN_SUCCESS; } -void sc_mcch_msg_nb_s::to_json(json_writer& j) const +void son_params_nb_r16_s::to_json(json_writer& j) const { - j.start_array(); j.start_obj(); - j.start_obj("SC-MCCH-Message-NB"); - j.write_fieldname("message"); - msg.to_json(j); - j.end_obj(); + if (anr_report_r16_present) { + j.write_str("anr-Report-r16", "supported"); + } + if (rach_report_r16_present) { + j.write_str("rach-Report-r16", "supported"); + } j.end_obj(); - j.end_array(); } -// PhyLayerParameters-NB-v1430 ::= SEQUENCE -SRSASN_CODE phy_layer_params_nb_v1430_s::pack(bit_ref& bref) const +// TDD-UE-Capability-NB-v1610 ::= SEQUENCE +SRSASN_CODE tdd_ue_cap_nb_v1610_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(multi_carrier_nprach_r14_present, 1)); - HANDLE_CODE(bref.pack(two_harq_processes_r14_present, 1)); + HANDLE_CODE(bref.pack(slot_symbol_res_resv_dl_r16_present, 1)); + HANDLE_CODE(bref.pack(slot_symbol_res_resv_ul_r16_present, 1)); + HANDLE_CODE(bref.pack(sf_res_resv_dl_r16_present, 1)); + HANDLE_CODE(bref.pack(sf_res_resv_ul_r16_present, 1)); return SRSASN_SUCCESS; } -SRSASN_CODE phy_layer_params_nb_v1430_s::unpack(cbit_ref& bref) +SRSASN_CODE tdd_ue_cap_nb_v1610_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(multi_carrier_nprach_r14_present, 1)); - HANDLE_CODE(bref.unpack(two_harq_processes_r14_present, 1)); + HANDLE_CODE(bref.unpack(slot_symbol_res_resv_dl_r16_present, 1)); + HANDLE_CODE(bref.unpack(slot_symbol_res_resv_ul_r16_present, 1)); + HANDLE_CODE(bref.unpack(sf_res_resv_dl_r16_present, 1)); + HANDLE_CODE(bref.unpack(sf_res_resv_ul_r16_present, 1)); return SRSASN_SUCCESS; } -void phy_layer_params_nb_v1430_s::to_json(json_writer& j) const +void tdd_ue_cap_nb_v1610_s::to_json(json_writer& j) const { j.start_obj(); - if (multi_carrier_nprach_r14_present) { - j.write_str("multiCarrier-NPRACH-r14", "supported"); + if (slot_symbol_res_resv_dl_r16_present) { + j.write_str("slotSymbolResourceResvDL-r16", "supported"); } - if (two_harq_processes_r14_present) { - j.write_str("twoHARQ-Processes-r14", "supported"); + if (slot_symbol_res_resv_ul_r16_present) { + j.write_str("slotSymbolResourceResvUL-r16", "supported"); + } + if (sf_res_resv_dl_r16_present) { + j.write_str("subframeResourceResvDL-r16", "supported"); + } + if (sf_res_resv_ul_r16_present) { + j.write_str("subframeResourceResvUL-r16", "supported"); } j.end_obj(); } -// PhyLayerParameters-NB-v1530 ::= SEQUENCE -SRSASN_CODE phy_layer_params_nb_v1530_s::pack(bit_ref& bref) const +// UE-Capability-NB-v16x0-IEs ::= SEQUENCE +SRSASN_CODE ue_cap_nb_v16x0_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(mixed_operation_mode_r15_present, 1)); - HANDLE_CODE(bref.pack(sr_with_harq_ack_r15_present, 1)); - HANDLE_CODE(bref.pack(sr_without_harq_ack_r15_present, 1)); - HANDLE_CODE(bref.pack(nprach_format2_r15_present, 1)); - HANDLE_CODE(bref.pack(add_tx_sib1_r15_present, 1)); - HANDLE_CODE(bref.pack(npusch_minus3dot75k_hz_scs_tdd_r15_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE phy_layer_params_nb_v1530_s::unpack(cbit_ref& bref) +SRSASN_CODE ue_cap_nb_v16x0_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(mixed_operation_mode_r15_present, 1)); - HANDLE_CODE(bref.unpack(sr_with_harq_ack_r15_present, 1)); - HANDLE_CODE(bref.unpack(sr_without_harq_ack_r15_present, 1)); - HANDLE_CODE(bref.unpack(nprach_format2_r15_present, 1)); - HANDLE_CODE(bref.unpack(add_tx_sib1_r15_present, 1)); - HANDLE_CODE(bref.unpack(npusch_minus3dot75k_hz_scs_tdd_r15_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } -void phy_layer_params_nb_v1530_s::to_json(json_writer& j) const +void ue_cap_nb_v16x0_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (mixed_operation_mode_r15_present) { - j.write_str("mixedOperationMode-r15", "supported"); - } - if (sr_with_harq_ack_r15_present) { - j.write_str("sr-WithHARQ-ACK-r15", "supported"); - } - if (sr_without_harq_ack_r15_present) { - j.write_str("sr-WithoutHARQ-ACK-r15", "supported"); - } - if (nprach_format2_r15_present) { - j.write_str("nprach-Format2-r15", "supported"); - } - if (add_tx_sib1_r15_present) { - j.write_str("additionalTransmissionSIB1-r15", "supported"); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } - if (npusch_minus3dot75k_hz_scs_tdd_r15_present) { - j.write_str("npusch-3dot75kHz-SCS-TDD-r15", "supported"); + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); } j.end_obj(); } -// TDD-UE-Capability-NB-r15 ::= SEQUENCE -SRSASN_CODE tdd_ue_cap_nb_r15_s::pack(bit_ref& bref) const +// UE-Capability-NB-v1610-IEs ::= SEQUENCE +SRSASN_CODE ue_cap_nb_v1610_ies_s::pack(bit_ref& bref) const { - bref.pack(ext, 1); - HANDLE_CODE(bref.pack(ue_category_nb_r15_present, 1)); - HANDLE_CODE(bref.pack(phy_layer_params_rel13_r15_present, 1)); - HANDLE_CODE(bref.pack(phy_layer_params_rel14_r15_present, 1)); - HANDLE_CODE(bref.pack(phy_layer_params_v1530_present, 1)); + HANDLE_CODE(bref.pack(early_security_reactivation_r16_present, 1)); + HANDLE_CODE(bref.pack(early_data_up_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.pack(pur_params_r16_present, 1)); + HANDLE_CODE(bref.pack(phy_layer_params_v1610_present, 1)); + HANDLE_CODE(bref.pack(son_params_r16_present, 1)); + HANDLE_CODE(bref.pack(tdd_ue_cap_v1610_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (phy_layer_params_rel13_r15_present) { - HANDLE_CODE(phy_layer_params_rel13_r15.pack(bref)); + if (pur_params_r16_present) { + HANDLE_CODE(pur_params_r16.pack(bref)); } - if (phy_layer_params_rel14_r15_present) { - HANDLE_CODE(phy_layer_params_rel14_r15.pack(bref)); + HANDLE_CODE(mac_params_v1610.pack(bref)); + if (phy_layer_params_v1610_present) { + HANDLE_CODE(phy_layer_params_v1610.pack(bref)); } - if (phy_layer_params_v1530_present) { - HANDLE_CODE(phy_layer_params_v1530.pack(bref)); + if (son_params_r16_present) { + HANDLE_CODE(son_params_r16.pack(bref)); + } + HANDLE_CODE(meas_params_r16.pack(bref)); + if (tdd_ue_cap_v1610_present) { + HANDLE_CODE(tdd_ue_cap_v1610.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); } return SRSASN_SUCCESS; } -SRSASN_CODE tdd_ue_cap_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE ue_cap_nb_v1610_ies_s::unpack(cbit_ref& bref) { - bref.unpack(ext, 1); - HANDLE_CODE(bref.unpack(ue_category_nb_r15_present, 1)); - HANDLE_CODE(bref.unpack(phy_layer_params_rel13_r15_present, 1)); - HANDLE_CODE(bref.unpack(phy_layer_params_rel14_r15_present, 1)); - HANDLE_CODE(bref.unpack(phy_layer_params_v1530_present, 1)); + HANDLE_CODE(bref.unpack(early_security_reactivation_r16_present, 1)); + HANDLE_CODE(bref.unpack(early_data_up_minus5_gc_r16_present, 1)); + HANDLE_CODE(bref.unpack(pur_params_r16_present, 1)); + HANDLE_CODE(bref.unpack(phy_layer_params_v1610_present, 1)); + HANDLE_CODE(bref.unpack(son_params_r16_present, 1)); + HANDLE_CODE(bref.unpack(tdd_ue_cap_v1610_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); - if (phy_layer_params_rel13_r15_present) { - HANDLE_CODE(phy_layer_params_rel13_r15.unpack(bref)); + if (pur_params_r16_present) { + HANDLE_CODE(pur_params_r16.unpack(bref)); } - if (phy_layer_params_rel14_r15_present) { - HANDLE_CODE(phy_layer_params_rel14_r15.unpack(bref)); + HANDLE_CODE(mac_params_v1610.unpack(bref)); + if (phy_layer_params_v1610_present) { + HANDLE_CODE(phy_layer_params_v1610.unpack(bref)); } - if (phy_layer_params_v1530_present) { - HANDLE_CODE(phy_layer_params_v1530.unpack(bref)); + if (son_params_r16_present) { + HANDLE_CODE(son_params_r16.unpack(bref)); + } + HANDLE_CODE(meas_params_r16.unpack(bref)); + if (tdd_ue_cap_v1610_present) { + HANDLE_CODE(tdd_ue_cap_v1610.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); } return SRSASN_SUCCESS; } -void tdd_ue_cap_nb_r15_s::to_json(json_writer& j) const +void ue_cap_nb_v1610_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (ue_category_nb_r15_present) { - j.write_str("ue-Category-NB-r15", "nb2"); + if (early_security_reactivation_r16_present) { + j.write_str("earlySecurityReactivation-r16", "supported"); } - if (phy_layer_params_rel13_r15_present) { - j.write_fieldname("phyLayerParametersRel13-r15"); - phy_layer_params_rel13_r15.to_json(j); + if (early_data_up_minus5_gc_r16_present) { + j.write_str("earlyData-UP-5GC-r16", "supported"); } - if (phy_layer_params_rel14_r15_present) { - j.write_fieldname("phyLayerParametersRel14-r15"); - phy_layer_params_rel14_r15.to_json(j); + if (pur_params_r16_present) { + j.write_fieldname("pur-Parameters-r16"); + pur_params_r16.to_json(j); } - if (phy_layer_params_v1530_present) { - j.write_fieldname("phyLayerParameters-v1530"); - phy_layer_params_v1530.to_json(j); + j.write_fieldname("mac-Parameters-v1610"); + mac_params_v1610.to_json(j); + if (phy_layer_params_v1610_present) { + j.write_fieldname("phyLayerParameters-v1610"); + phy_layer_params_v1610.to_json(j); + } + if (son_params_r16_present) { + j.write_fieldname("son-Parameters-r16"); + son_params_r16.to_json(j); + } + j.write_fieldname("measParameters-r16"); + meas_params_r16.to_json(j); + if (tdd_ue_cap_v1610_present) { + j.write_fieldname("tdd-UE-Capability-v1610"); + tdd_ue_cap_v1610.to_json(j); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -18715,30 +25764,72 @@ SRSASN_CODE mac_params_nb_v1530_s::unpack(cbit_ref& bref) void mac_params_nb_v1530_s::to_json(json_writer& j) const { j.start_obj(); - if (sr_sps_bsr_r15_present) { - j.write_str("sr-SPS-BSR-r15", "supported"); + if (sr_sps_bsr_r15_present) { + j.write_str("sr-SPS-BSR-r15", "supported"); + } + j.end_obj(); +} + +// RLC-Parameters-NB-r15 ::= SEQUENCE +SRSASN_CODE rlc_params_nb_r15_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(rlc_um_r15_present, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rlc_params_nb_r15_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(rlc_um_r15_present, 1)); + + return SRSASN_SUCCESS; +} +void rlc_params_nb_r15_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (rlc_um_r15_present) { + j.write_str("rlc-UM-r15", "supported"); } j.end_obj(); } -// RLC-Parameters-NB-r15 ::= SEQUENCE -SRSASN_CODE rlc_params_nb_r15_s::pack(bit_ref& bref) const +// UE-Capability-NB-v15x0-IEs ::= SEQUENCE +SRSASN_CODE ue_cap_nb_v15x0_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(rlc_um_r15_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } -SRSASN_CODE rlc_params_nb_r15_s::unpack(cbit_ref& bref) +SRSASN_CODE ue_cap_nb_v15x0_ies_s::unpack(cbit_ref& bref) { - HANDLE_CODE(bref.unpack(rlc_um_r15_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } -void rlc_params_nb_r15_s::to_json(json_writer& j) const +void ue_cap_nb_v15x0_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (rlc_um_r15_present) { - j.write_str("rlc-UM-r15", "supported"); + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -18759,6 +25850,9 @@ SRSASN_CODE ue_cap_nb_v1530_ies_s::pack(bit_ref& bref) const if (tdd_ue_cap_r15_present) { HANDLE_CODE(tdd_ue_cap_r15.pack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -18777,6 +25871,9 @@ SRSASN_CODE ue_cap_nb_v1530_ies_s::unpack(cbit_ref& bref) if (tdd_ue_cap_r15_present) { HANDLE_CODE(tdd_ue_cap_r15.unpack(bref)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -18800,8 +25897,7 @@ void ue_cap_nb_v1530_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -19039,6 +26135,9 @@ SRSASN_CODE ue_radio_paging_info_nb_r13_s::pack(bit_ref& bref) const group_flags[1] |= wake_up_signal_r15_present; group_flags[1] |= wake_up_signal_min_gap_e_drx_r15_present; group_flags[1] |= multi_carrier_paging_tdd_r15_present; + group_flags[2] |= ue_category_nb_r16_present; + group_flags[2] |= group_wake_up_signal_r16_present; + group_flags[2] |= group_wake_up_signal_alternation_r16_present; group_flags.pack(bref); if (group_flags[0]) { @@ -19057,6 +26156,13 @@ SRSASN_CODE ue_radio_paging_info_nb_r13_s::pack(bit_ref& bref) const HANDLE_CODE(wake_up_signal_min_gap_e_drx_r15.pack(bref)); } } + if (group_flags[2]) { + varlength_field_pack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.pack(ue_category_nb_r16_present, 1)); + HANDLE_CODE(bref.pack(group_wake_up_signal_r16_present, 1)); + HANDLE_CODE(bref.pack(group_wake_up_signal_alternation_r16_present, 1)); + } } return SRSASN_SUCCESS; } @@ -19066,7 +26172,7 @@ SRSASN_CODE ue_radio_paging_info_nb_r13_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(ue_category_nb_r13_present, 1)); if (ext) { - ext_groups_unpacker_guard group_flags(2); + ext_groups_unpacker_guard group_flags(3); group_flags.unpack(bref); if (group_flags[0]) { @@ -19085,6 +26191,13 @@ SRSASN_CODE ue_radio_paging_info_nb_r13_s::unpack(cbit_ref& bref) HANDLE_CODE(wake_up_signal_min_gap_e_drx_r15.unpack(bref)); } } + if (group_flags[2]) { + varlength_field_unpack_guard varlen_scope(bref, false); + + HANDLE_CODE(bref.unpack(ue_category_nb_r16_present, 1)); + HANDLE_CODE(bref.unpack(group_wake_up_signal_r16_present, 1)); + HANDLE_CODE(bref.unpack(group_wake_up_signal_alternation_r16_present, 1)); + } } return SRSASN_SUCCESS; } @@ -19110,6 +26223,15 @@ void ue_radio_paging_info_nb_r13_s::to_json(json_writer& j) const if (multi_carrier_paging_tdd_r15_present) { j.write_str("multiCarrierPagingTDD-r15", "true"); } + if (ue_category_nb_r16_present) { + j.write_str("ue-Category-NB-r16", "nb2"); + } + if (group_wake_up_signal_r16_present) { + j.write_str("groupWakeUpSignal-r16", "true"); + } + if (group_wake_up_signal_alternation_r16_present) { + j.write_str("groupWakeUpSignalAlternation-r16", "true"); + } } j.end_obj(); } @@ -19295,6 +26417,236 @@ const char* ue_cap_info_nb_s::crit_exts_c_::types_opts::to_string() const return convert_enum_idx(options, 2, value, "ue_cap_info_nb_s::crit_exts_c_::types"); } +// RACH-Report-NB-r16 ::= SEQUENCE +SRSASN_CODE rach_report_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, nof_preambs_sent_r16, (uint8_t)1u, (uint8_t)64u)); + HANDLE_CODE(bref.pack(contention_detected_r16, 1)); + HANDLE_CODE(pack_integer(bref, init_nrsrp_level_r16, (uint8_t)0u, (uint8_t)2u)); + HANDLE_CODE(bref.pack(edt_fallback_r16, 1)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE rach_report_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(nof_preambs_sent_r16, bref, (uint8_t)1u, (uint8_t)64u)); + HANDLE_CODE(bref.unpack(contention_detected_r16, 1)); + HANDLE_CODE(unpack_integer(init_nrsrp_level_r16, bref, (uint8_t)0u, (uint8_t)2u)); + HANDLE_CODE(bref.unpack(edt_fallback_r16, 1)); + + return SRSASN_SUCCESS; +} +void rach_report_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("numberOfPreamblesSent-r16", nof_preambs_sent_r16); + j.write_bool("contentionDetected-r16", contention_detected_r16); + j.write_int("initialNRSRP-Level-r16", init_nrsrp_level_r16); + j.write_bool("edt-Fallback-r16", edt_fallback_r16); + j.end_obj(); +} + +// UEInformationResponse-NB-r16-IEs ::= SEQUENCE +SRSASN_CODE ue_info_resp_nb_r16_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(rach_report_r16_present, 1)); + HANDLE_CODE(bref.pack(rlf_report_r16_present, 1)); + HANDLE_CODE(bref.pack(anr_meas_report_r16_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (rach_report_r16_present) { + HANDLE_CODE(rach_report_r16.pack(bref)); + } + if (rlf_report_r16_present) { + HANDLE_CODE(rlf_report_r16.pack(bref)); + } + if (anr_meas_report_r16_present) { + HANDLE_CODE(anr_meas_report_r16.pack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_info_resp_nb_r16_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(rach_report_r16_present, 1)); + HANDLE_CODE(bref.unpack(rlf_report_r16_present, 1)); + HANDLE_CODE(bref.unpack(anr_meas_report_r16_present, 1)); + HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (rach_report_r16_present) { + HANDLE_CODE(rach_report_r16.unpack(bref)); + } + if (rlf_report_r16_present) { + HANDLE_CODE(rlf_report_r16.unpack(bref)); + } + if (anr_meas_report_r16_present) { + HANDLE_CODE(anr_meas_report_r16.unpack(bref)); + } + if (late_non_crit_ext_present) { + HANDLE_CODE(late_non_crit_ext.unpack(bref)); + } + + return SRSASN_SUCCESS; +} +void ue_info_resp_nb_r16_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (rach_report_r16_present) { + j.write_fieldname("rach-Report-r16"); + rach_report_r16.to_json(j); + } + if (rlf_report_r16_present) { + j.write_fieldname("rlf-Report-r16"); + rlf_report_r16.to_json(j); + } + if (anr_meas_report_r16_present) { + j.write_fieldname("anr-MeasReport-r16"); + anr_meas_report_r16.to_json(j); + } + if (late_non_crit_ext_present) { + j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + +// UEInformationResponse-NB-r16 ::= SEQUENCE +SRSASN_CODE ue_info_resp_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, rrc_transaction_id, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.pack(bref)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_info_resp_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(rrc_transaction_id, bref, (uint8_t)0u, (uint8_t)3u)); + HANDLE_CODE(crit_exts.unpack(bref)); + + return SRSASN_SUCCESS; +} +void ue_info_resp_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("rrc-TransactionIdentifier", rrc_transaction_id); + j.write_fieldname("criticalExtensions"); + crit_exts.to_json(j); + j.end_obj(); +} + +void ue_info_resp_nb_r16_s::crit_exts_c_::set(types::options e) +{ + type_ = e; +} +ue_info_resp_nb_r16_ies_s& ue_info_resp_nb_r16_s::crit_exts_c_::set_ue_info_resp_r16() +{ + set(types::ue_info_resp_r16); + return c; +} +void ue_info_resp_nb_r16_s::crit_exts_c_::set_crit_exts_future() +{ + set(types::crit_exts_future); +} +void ue_info_resp_nb_r16_s::crit_exts_c_::to_json(json_writer& j) const +{ + j.start_obj(); + switch (type_) { + case types::ue_info_resp_r16: + j.write_fieldname("ueInformationResponse-r16"); + c.to_json(j); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "ue_info_resp_nb_r16_s::crit_exts_c_"); + } + j.end_obj(); +} +SRSASN_CODE ue_info_resp_nb_r16_s::crit_exts_c_::pack(bit_ref& bref) const +{ + type_.pack(bref); + switch (type_) { + case types::ue_info_resp_r16: + HANDLE_CODE(c.pack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "ue_info_resp_nb_r16_s::crit_exts_c_"); + return SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_info_resp_nb_r16_s::crit_exts_c_::unpack(cbit_ref& bref) +{ + types e; + e.unpack(bref); + set(e); + switch (type_) { + case types::ue_info_resp_r16: + HANDLE_CODE(c.unpack(bref)); + break; + case types::crit_exts_future: + break; + default: + log_invalid_choice_id(type_, "ue_info_resp_nb_r16_s::crit_exts_c_"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* ue_info_resp_nb_r16_s::crit_exts_c_::types_opts::to_string() const +{ + static const char* options[] = {"ueInformationResponse-r16", "criticalExtensionsFuture"}; + return convert_enum_idx(options, 2, value, "ue_info_resp_nb_r16_s::crit_exts_c_::types"); +} + +// UEPagingCoverageInformation-NB-v1700-IEs ::= SEQUENCE +SRSASN_CODE ue_paging_coverage_info_nb_v1700_ies_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(bref.pack(cbp_idx_r17_present, 1)); + HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); + + if (cbp_idx_r17_present) { + HANDLE_CODE(pack_integer(bref, cbp_idx_r17, (uint8_t)1u, (uint8_t)2u)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ue_paging_coverage_info_nb_v1700_ies_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(cbp_idx_r17_present, 1)); + HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); + + if (cbp_idx_r17_present) { + HANDLE_CODE(unpack_integer(cbp_idx_r17, bref, (uint8_t)1u, (uint8_t)2u)); + } + + return SRSASN_SUCCESS; +} +void ue_paging_coverage_info_nb_v1700_ies_s::to_json(json_writer& j) const +{ + j.start_obj(); + if (cbp_idx_r17_present) { + j.write_int("cbp-Index-r17", cbp_idx_r17); + } + if (non_crit_ext_present) { + j.write_fieldname("nonCriticalExtension"); + j.start_obj(); + j.end_obj(); + } + j.end_obj(); +} + // UEPagingCoverageInformation-NB-IEs ::= SEQUENCE SRSASN_CODE ue_paging_coverage_info_nb_ies_s::pack(bit_ref& bref) const { @@ -19304,6 +26656,9 @@ SRSASN_CODE ue_paging_coverage_info_nb_ies_s::pack(bit_ref& bref) const if (npdcch_num_repeat_paging_r13_present) { HANDLE_CODE(pack_integer(bref, npdcch_num_repeat_paging_r13, (uint16_t)1u, (uint16_t)2048u)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.pack(bref)); + } return SRSASN_SUCCESS; } @@ -19315,6 +26670,9 @@ SRSASN_CODE ue_paging_coverage_info_nb_ies_s::unpack(cbit_ref& bref) if (npdcch_num_repeat_paging_r13_present) { HANDLE_CODE(unpack_integer(npdcch_num_repeat_paging_r13, bref, (uint16_t)1u, (uint16_t)2048u)); } + if (non_crit_ext_present) { + HANDLE_CODE(non_crit_ext.unpack(bref)); + } return SRSASN_SUCCESS; } @@ -19326,8 +26684,7 @@ void ue_paging_coverage_info_nb_ies_s::to_json(json_writer& j) const } if (non_crit_ext_present) { j.write_fieldname("nonCriticalExtension"); - j.start_obj(); - j.end_obj(); + non_crit_ext.to_json(j); } j.end_obj(); } @@ -20493,6 +27850,12 @@ void ul_dcch_msg_type_nb_c::c1_c_::destroy_() case types::rrc_conn_resume_complete_r13: c.destroy(); break; + case types::ue_info_resp_r16: + c.destroy(); + break; + case types::pur_cfg_request_r16: + c.destroy(); + break; default: break; } @@ -20526,9 +27889,11 @@ void ul_dcch_msg_type_nb_c::c1_c_::set(types::options e) case types::rrc_conn_resume_complete_r13: c.init(); break; - case types::spare8: + case types::ue_info_resp_r16: + c.init(); break; - case types::spare7: + case types::pur_cfg_request_r16: + c.init(); break; case types::spare6: break; @@ -20576,9 +27941,11 @@ ul_dcch_msg_type_nb_c::c1_c_::c1_c_(const ul_dcch_msg_type_nb_c::c1_c_& other) case types::rrc_conn_resume_complete_r13: c.init(other.c.get()); break; - case types::spare8: + case types::ue_info_resp_r16: + c.init(other.c.get()); break; - case types::spare7: + case types::pur_cfg_request_r16: + c.init(other.c.get()); break; case types::spare6: break; @@ -20629,9 +27996,11 @@ ul_dcch_msg_type_nb_c::c1_c_& ul_dcch_msg_type_nb_c::c1_c_::operator=(const ul_d case types::rrc_conn_resume_complete_r13: c.set(other.c.get()); break; - case types::spare8: + case types::ue_info_resp_r16: + c.set(other.c.get()); break; - case types::spare7: + case types::pur_cfg_request_r16: + c.set(other.c.get()); break; case types::spare6: break; @@ -20693,13 +28062,15 @@ rrc_conn_resume_complete_nb_s& ul_dcch_msg_type_nb_c::c1_c_::set_rrc_conn_resume set(types::rrc_conn_resume_complete_r13); return c.get(); } -void ul_dcch_msg_type_nb_c::c1_c_::set_spare8() +ue_info_resp_nb_r16_s& ul_dcch_msg_type_nb_c::c1_c_::set_ue_info_resp_r16() { - set(types::spare8); + set(types::ue_info_resp_r16); + return c.get(); } -void ul_dcch_msg_type_nb_c::c1_c_::set_spare7() +pur_cfg_request_nb_r16_s& ul_dcch_msg_type_nb_c::c1_c_::set_pur_cfg_request_r16() { - set(types::spare7); + set(types::pur_cfg_request_r16); + return c.get(); } void ul_dcch_msg_type_nb_c::c1_c_::set_spare6() { @@ -20761,9 +28132,13 @@ void ul_dcch_msg_type_nb_c::c1_c_::to_json(json_writer& j) const j.write_fieldname("rrcConnectionResumeComplete-r13"); c.get().to_json(j); break; - case types::spare8: + case types::ue_info_resp_r16: + j.write_fieldname("ueInformationResponse-r16"); + c.get().to_json(j); break; - case types::spare7: + case types::pur_cfg_request_r16: + j.write_fieldname("purConfigurationRequest-r16"); + c.get().to_json(j); break; case types::spare6: break; @@ -20810,9 +28185,11 @@ SRSASN_CODE ul_dcch_msg_type_nb_c::c1_c_::pack(bit_ref& bref) const case types::rrc_conn_resume_complete_r13: HANDLE_CODE(c.get().pack(bref)); break; - case types::spare8: + case types::ue_info_resp_r16: + HANDLE_CODE(c.get().pack(bref)); break; - case types::spare7: + case types::pur_cfg_request_r16: + HANDLE_CODE(c.get().pack(bref)); break; case types::spare6: break; @@ -20862,9 +28239,11 @@ SRSASN_CODE ul_dcch_msg_type_nb_c::c1_c_::unpack(cbit_ref& bref) case types::rrc_conn_resume_complete_r13: HANDLE_CODE(c.get().unpack(bref)); break; - case types::spare8: + case types::ue_info_resp_r16: + HANDLE_CODE(c.get().unpack(bref)); break; - case types::spare7: + case types::pur_cfg_request_r16: + HANDLE_CODE(c.get().unpack(bref)); break; case types::spare6: break; @@ -20895,8 +28274,8 @@ const char* ul_dcch_msg_type_nb_c::c1_c_::types_opts::to_string() const "ueCapabilityInformation-r13", "ulInformationTransfer-r13", "rrcConnectionResumeComplete-r13", - "spare8", - "spare7", + "ueInformationResponse-r16", + "purConfigurationRequest-r16", "spare6", "spare5", "spare4", @@ -20945,3 +28324,72 @@ void ul_dcch_msg_nb_s::to_json(json_writer& j) const j.end_obj(); j.end_array(); } + +// VarANR-MeasConfig-NB-r16 ::= SEQUENCE +SRSASN_CODE var_anr_meas_cfg_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_integer(bref, anr_quality_thres_r16, (uint8_t)0u, (uint8_t)113u)); + HANDLE_CODE(pack_dyn_seq_of(bref, anr_carrier_list_r16, 1, 2)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE var_anr_meas_cfg_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_integer(anr_quality_thres_r16, bref, (uint8_t)0u, (uint8_t)113u)); + HANDLE_CODE(unpack_dyn_seq_of(anr_carrier_list_r16, bref, 1, 2)); + + return SRSASN_SUCCESS; +} +void var_anr_meas_cfg_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.write_int("anr-QualityThreshold-r16", anr_quality_thres_r16); + j.start_array("anr-CarrierList-r16"); + for (const auto& e1 : anr_carrier_list_r16) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} + +// VarANR-MeasReport-NB-r16 ::= SEQUENCE +SRSASN_CODE var_anr_meas_report_nb_r16_s::pack(bit_ref& bref) const +{ + HANDLE_CODE(pack_dyn_seq_of(bref, plmn_id_list_r16, 1, 16)); + HANDLE_CODE(serv_cell_id_r16.pack(bref)); + HANDLE_CODE(meas_result_serv_cell_r16.pack(bref)); + HANDLE_CODE(pack_integer(bref, relative_time_stamp_r16, (uint8_t)0u, (uint8_t)95u)); + HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_list_r16, 1, 2)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE var_anr_meas_report_nb_r16_s::unpack(cbit_ref& bref) +{ + HANDLE_CODE(unpack_dyn_seq_of(plmn_id_list_r16, bref, 1, 16)); + HANDLE_CODE(serv_cell_id_r16.unpack(bref)); + HANDLE_CODE(meas_result_serv_cell_r16.unpack(bref)); + HANDLE_CODE(unpack_integer(relative_time_stamp_r16, bref, (uint8_t)0u, (uint8_t)95u)); + HANDLE_CODE(unpack_dyn_seq_of(meas_result_list_r16, bref, 1, 2)); + + return SRSASN_SUCCESS; +} +void var_anr_meas_report_nb_r16_s::to_json(json_writer& j) const +{ + j.start_obj(); + j.start_array("plmn-IdentityList-r16"); + for (const auto& e1 : plmn_id_list_r16) { + e1.to_json(j); + } + j.end_array(); + j.write_fieldname("servCellIdentity-r16"); + serv_cell_id_r16.to_json(j); + j.write_fieldname("measResultServCell-r16"); + meas_result_serv_cell_r16.to_json(j); + j.write_int("relativeTimeStamp-r16", relative_time_stamp_r16); + j.start_array("measResultList-r16"); + for (const auto& e1 : meas_result_list_r16) { + e1.to_json(j); + } + j.end_array(); + j.end_obj(); +} diff --git a/lib/src/asn1/rrc_nr.cc b/lib/src/asn1/rrc_nr.cc index 8aafe61a3e..16a9375173 100644 --- a/lib/src/asn1/rrc_nr.cc +++ b/lib/src/asn1/rrc_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -381,10 +381,10 @@ void eutra_freq_neigh_cell_info_s::to_json(json_writer& j) const // EUTRA-MultiBandInfo ::= SEQUENCE SRSASN_CODE eutra_multi_band_info_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(eutra_ns_pmax_list_present, 1)); + HANDLE_CODE(bref.pack(eutra_ns_pmax_list.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, eutra_freq_band_ind, (uint16_t)1u, (uint16_t)256u)); - if (eutra_ns_pmax_list_present) { + if (eutra_ns_pmax_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, eutra_ns_pmax_list, 1, 8)); } @@ -392,6 +392,7 @@ SRSASN_CODE eutra_multi_band_info_s::pack(bit_ref& bref) const } SRSASN_CODE eutra_multi_band_info_s::unpack(cbit_ref& bref) { + bool eutra_ns_pmax_list_present; HANDLE_CODE(bref.unpack(eutra_ns_pmax_list_present, 1)); HANDLE_CODE(unpack_integer(eutra_freq_band_ind, bref, (uint16_t)1u, (uint16_t)256u)); @@ -405,7 +406,7 @@ void eutra_multi_band_info_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("eutra-FreqBandIndicator", eutra_freq_band_ind); - if (eutra_ns_pmax_list_present) { + if (eutra_ns_pmax_list.size() > 0) { j.start_array("eutra-NS-PmaxList"); for (const auto& e1 : eutra_ns_pmax_list) { e1.to_json(j); @@ -538,12 +539,12 @@ void inter_freq_neigh_cell_info_s::to_json(json_writer& j) const SRSASN_CODE nr_multi_band_info_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(freq_band_ind_nr_present, 1)); - HANDLE_CODE(bref.pack(nr_ns_pmax_list_present, 1)); + HANDLE_CODE(bref.pack(nr_ns_pmax_list.size() > 0, 1)); if (freq_band_ind_nr_present) { HANDLE_CODE(pack_integer(bref, freq_band_ind_nr, (uint16_t)1u, (uint16_t)1024u)); } - if (nr_ns_pmax_list_present) { + if (nr_ns_pmax_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, nr_ns_pmax_list, 1, 8)); } @@ -552,6 +553,7 @@ SRSASN_CODE nr_multi_band_info_s::pack(bit_ref& bref) const SRSASN_CODE nr_multi_band_info_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(freq_band_ind_nr_present, 1)); + bool nr_ns_pmax_list_present; HANDLE_CODE(bref.unpack(nr_ns_pmax_list_present, 1)); if (freq_band_ind_nr_present) { @@ -569,7 +571,7 @@ void nr_multi_band_info_s::to_json(json_writer& j) const if (freq_band_ind_nr_present) { j.write_int("freqBandIndicatorNR", freq_band_ind_nr); } - if (nr_ns_pmax_list_present) { + if (nr_ns_pmax_list.size() > 0) { j.start_array("nr-NS-PmaxList"); for (const auto& e1 : nr_ns_pmax_list) { e1.to_json(j); @@ -743,8 +745,8 @@ const char* cell_resel_sub_prio_opts::to_number_string() const SRSASN_CODE ctrl_res_set_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(tci_states_pdcch_to_add_list_present, 1)); - HANDLE_CODE(bref.pack(tci_states_pdcch_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(tci_states_pdcch_to_add_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(tci_states_pdcch_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(tci_present_in_dci_present, 1)); HANDLE_CODE(bref.pack(pdcch_dmrs_scrambling_id_present, 1)); @@ -753,10 +755,10 @@ SRSASN_CODE ctrl_res_set_s::pack(bit_ref& bref) const HANDLE_CODE(pack_integer(bref, dur, (uint8_t)1u, (uint8_t)3u)); HANDLE_CODE(cce_reg_map_type.pack(bref)); HANDLE_CODE(precoder_granularity.pack(bref)); - if (tci_states_pdcch_to_add_list_present) { + if (tci_states_pdcch_to_add_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, tci_states_pdcch_to_add_list, 1, 64, integer_packer(0, 127))); } - if (tci_states_pdcch_to_release_list_present) { + if (tci_states_pdcch_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, tci_states_pdcch_to_release_list, 1, 64, integer_packer(0, 127))); } if (pdcch_dmrs_scrambling_id_present) { @@ -768,7 +770,9 @@ SRSASN_CODE ctrl_res_set_s::pack(bit_ref& bref) const SRSASN_CODE ctrl_res_set_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool tci_states_pdcch_to_add_list_present; HANDLE_CODE(bref.unpack(tci_states_pdcch_to_add_list_present, 1)); + bool tci_states_pdcch_to_release_list_present; HANDLE_CODE(bref.unpack(tci_states_pdcch_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(tci_present_in_dci_present, 1)); HANDLE_CODE(bref.unpack(pdcch_dmrs_scrambling_id_present, 1)); @@ -799,14 +803,14 @@ void ctrl_res_set_s::to_json(json_writer& j) const j.write_fieldname("cce-REG-MappingType"); cce_reg_map_type.to_json(j); j.write_str("precoderGranularity", precoder_granularity.to_string()); - if (tci_states_pdcch_to_add_list_present) { + if (tci_states_pdcch_to_add_list.size() > 0) { j.start_array("tci-StatesPDCCH-ToAddList"); for (const auto& e1 : tci_states_pdcch_to_add_list) { j.write_int(e1); } j.end_array(); } - if (tci_states_pdcch_to_release_list_present) { + if (tci_states_pdcch_to_release_list.size() > 0) { j.start_array("tci-StatesPDCCH-ToReleaseList"); for (const auto& e1 : tci_states_pdcch_to_release_list) { j.write_int(e1); @@ -2567,21 +2571,21 @@ void bwp_s::to_json(json_writer& j) const // CarrierFreqEUTRA ::= SEQUENCE SRSASN_CODE carrier_freq_eutra_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(eutra_multi_band_info_list_present, 1)); - HANDLE_CODE(bref.pack(eutra_freq_neigh_cell_list_present, 1)); - HANDLE_CODE(bref.pack(eutra_black_cell_list_present, 1)); + HANDLE_CODE(bref.pack(eutra_multi_band_info_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(eutra_freq_neigh_cell_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(eutra_black_cell_list.size() > 0, 1)); HANDLE_CODE(bref.pack(cell_resel_prio_present, 1)); HANDLE_CODE(bref.pack(cell_resel_sub_prio_present, 1)); HANDLE_CODE(bref.pack(thresh_x_q_present, 1)); HANDLE_CODE(pack_integer(bref, carrier_freq, (uint32_t)0u, (uint32_t)262143u)); - if (eutra_multi_band_info_list_present) { + if (eutra_multi_band_info_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, eutra_multi_band_info_list, 1, 8)); } - if (eutra_freq_neigh_cell_list_present) { + if (eutra_freq_neigh_cell_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, eutra_freq_neigh_cell_list, 1, 8)); } - if (eutra_black_cell_list_present) { + if (eutra_black_cell_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, eutra_black_cell_list, 1, 16)); } HANDLE_CODE(allowed_meas_bw.pack(bref)); @@ -2606,8 +2610,11 @@ SRSASN_CODE carrier_freq_eutra_s::pack(bit_ref& bref) const } SRSASN_CODE carrier_freq_eutra_s::unpack(cbit_ref& bref) { + bool eutra_multi_band_info_list_present; HANDLE_CODE(bref.unpack(eutra_multi_band_info_list_present, 1)); + bool eutra_freq_neigh_cell_list_present; HANDLE_CODE(bref.unpack(eutra_freq_neigh_cell_list_present, 1)); + bool eutra_black_cell_list_present; HANDLE_CODE(bref.unpack(eutra_black_cell_list_present, 1)); HANDLE_CODE(bref.unpack(cell_resel_prio_present, 1)); HANDLE_CODE(bref.unpack(cell_resel_sub_prio_present, 1)); @@ -2647,21 +2654,21 @@ void carrier_freq_eutra_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("carrierFreq", carrier_freq); - if (eutra_multi_band_info_list_present) { + if (eutra_multi_band_info_list.size() > 0) { j.start_array("eutra-multiBandInfoList"); for (const auto& e1 : eutra_multi_band_info_list) { e1.to_json(j); } j.end_array(); } - if (eutra_freq_neigh_cell_list_present) { + if (eutra_freq_neigh_cell_list.size() > 0) { j.start_array("eutra-FreqNeighCellList"); for (const auto& e1 : eutra_freq_neigh_cell_list) { e1.to_json(j); } j.end_array(); } - if (eutra_black_cell_list_present) { + if (eutra_black_cell_list.size() > 0) { j.start_array("eutra-BlackCellList"); for (const auto& e1 : eutra_black_cell_list) { e1.to_json(j); @@ -2695,8 +2702,8 @@ void carrier_freq_eutra_s::to_json(json_writer& j) const SRSASN_CODE inter_freq_carrier_freq_info_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(freq_band_list_present, 1)); - HANDLE_CODE(bref.pack(freq_band_list_sul_present, 1)); + HANDLE_CODE(bref.pack(freq_band_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(freq_band_list_sul.size() > 0, 1)); HANDLE_CODE(bref.pack(nrof_ss_blocks_to_average_present, 1)); HANDLE_CODE(bref.pack(abs_thresh_ss_blocks_consolidation_present, 1)); HANDLE_CODE(bref.pack(smtc_present, 1)); @@ -2710,14 +2717,14 @@ SRSASN_CODE inter_freq_carrier_freq_info_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(cell_resel_prio_present, 1)); HANDLE_CODE(bref.pack(cell_resel_sub_prio_present, 1)); HANDLE_CODE(bref.pack(q_offset_freq_present, 1)); - HANDLE_CODE(bref.pack(inter_freq_neigh_cell_list_present, 1)); - HANDLE_CODE(bref.pack(inter_freq_black_cell_list_present, 1)); + HANDLE_CODE(bref.pack(inter_freq_neigh_cell_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(inter_freq_black_cell_list.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, dl_carrier_freq, (uint32_t)0u, (uint32_t)3279165u)); - if (freq_band_list_present) { + if (freq_band_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list, 1, 8)); } - if (freq_band_list_sul_present) { + if (freq_band_list_sul.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list_sul, 1, 8)); } if (nrof_ss_blocks_to_average_present) { @@ -2766,10 +2773,10 @@ SRSASN_CODE inter_freq_carrier_freq_info_s::pack(bit_ref& bref) const if (q_offset_freq_present) { HANDLE_CODE(q_offset_freq.pack(bref)); } - if (inter_freq_neigh_cell_list_present) { + if (inter_freq_neigh_cell_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_neigh_cell_list, 1, 16)); } - if (inter_freq_black_cell_list_present) { + if (inter_freq_black_cell_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_black_cell_list, 1, 16)); } @@ -2778,7 +2785,9 @@ SRSASN_CODE inter_freq_carrier_freq_info_s::pack(bit_ref& bref) const SRSASN_CODE inter_freq_carrier_freq_info_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool freq_band_list_present; HANDLE_CODE(bref.unpack(freq_band_list_present, 1)); + bool freq_band_list_sul_present; HANDLE_CODE(bref.unpack(freq_band_list_sul_present, 1)); HANDLE_CODE(bref.unpack(nrof_ss_blocks_to_average_present, 1)); HANDLE_CODE(bref.unpack(abs_thresh_ss_blocks_consolidation_present, 1)); @@ -2793,7 +2802,9 @@ SRSASN_CODE inter_freq_carrier_freq_info_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(cell_resel_prio_present, 1)); HANDLE_CODE(bref.unpack(cell_resel_sub_prio_present, 1)); HANDLE_CODE(bref.unpack(q_offset_freq_present, 1)); + bool inter_freq_neigh_cell_list_present; HANDLE_CODE(bref.unpack(inter_freq_neigh_cell_list_present, 1)); + bool inter_freq_black_cell_list_present; HANDLE_CODE(bref.unpack(inter_freq_black_cell_list_present, 1)); HANDLE_CODE(unpack_integer(dl_carrier_freq, bref, (uint32_t)0u, (uint32_t)3279165u)); @@ -2862,14 +2873,14 @@ void inter_freq_carrier_freq_info_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("dl-CarrierFreq", dl_carrier_freq); - if (freq_band_list_present) { + if (freq_band_list.size() > 0) { j.start_array("frequencyBandList"); for (const auto& e1 : freq_band_list) { e1.to_json(j); } j.end_array(); } - if (freq_band_list_sul_present) { + if (freq_band_list_sul.size() > 0) { j.start_array("frequencyBandListSUL"); for (const auto& e1 : freq_band_list_sul) { e1.to_json(j); @@ -2930,14 +2941,14 @@ void inter_freq_carrier_freq_info_s::to_json(json_writer& j) const if (q_offset_freq_present) { j.write_str("q-OffsetFreq", q_offset_freq.to_string()); } - if (inter_freq_neigh_cell_list_present) { + if (inter_freq_neigh_cell_list.size() > 0) { j.start_array("interFreqNeighCellList"); for (const auto& e1 : inter_freq_neigh_cell_list) { e1.to_json(j); } j.end_array(); } - if (inter_freq_black_cell_list_present) { + if (inter_freq_black_cell_list.size() > 0) { j.start_array("interFreqBlackCellList"); for (const auto& e1 : inter_freq_black_cell_list) { e1.to_json(j); @@ -3014,7 +3025,7 @@ SRSASN_CODE pdcch_cfg_common_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(ctrl_res_set_zero_present, 1)); HANDLE_CODE(bref.pack(common_ctrl_res_set_present, 1)); HANDLE_CODE(bref.pack(search_space_zero_present, 1)); - HANDLE_CODE(bref.pack(common_search_space_list_present, 1)); + HANDLE_CODE(bref.pack(common_search_space_list.size() > 0, 1)); HANDLE_CODE(bref.pack(search_space_sib1_present, 1)); HANDLE_CODE(bref.pack(search_space_other_sys_info_present, 1)); HANDLE_CODE(bref.pack(paging_search_space_present, 1)); @@ -3029,7 +3040,7 @@ SRSASN_CODE pdcch_cfg_common_s::pack(bit_ref& bref) const if (search_space_zero_present) { HANDLE_CODE(pack_integer(bref, search_space_zero, (uint8_t)0u, (uint8_t)15u)); } - if (common_search_space_list_present) { + if (common_search_space_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, common_search_space_list, 1, 4)); } if (search_space_sib1_present) { @@ -3048,7 +3059,7 @@ SRSASN_CODE pdcch_cfg_common_s::pack(bit_ref& bref) const if (ext) { ext_groups_packer_guard group_flags; group_flags[0] |= first_pdcch_monitoring_occasion_of_po.is_present(); - HANDLE_CODE(group_flags.pack(bref)); + group_flags.pack(bref); if (group_flags[0]) { varlength_field_pack_guard varlen_scope(bref, false); @@ -3067,6 +3078,7 @@ SRSASN_CODE pdcch_cfg_common_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(ctrl_res_set_zero_present, 1)); HANDLE_CODE(bref.unpack(common_ctrl_res_set_present, 1)); HANDLE_CODE(bref.unpack(search_space_zero_present, 1)); + bool common_search_space_list_present; HANDLE_CODE(bref.unpack(common_search_space_list_present, 1)); HANDLE_CODE(bref.unpack(search_space_sib1_present, 1)); HANDLE_CODE(bref.unpack(search_space_other_sys_info_present, 1)); @@ -3100,7 +3112,7 @@ SRSASN_CODE pdcch_cfg_common_s::unpack(cbit_ref& bref) if (ext) { ext_groups_unpacker_guard group_flags(1); - HANDLE_CODE(group_flags.unpack(bref)); + group_flags.unpack(bref); if (group_flags[0]) { varlength_field_unpack_guard varlen_scope(bref, false); @@ -3128,7 +3140,7 @@ void pdcch_cfg_common_s::to_json(json_writer& j) const if (search_space_zero_present) { j.write_int("searchSpaceZero", search_space_zero); } - if (common_search_space_list_present) { + if (common_search_space_list.size() > 0) { j.start_array("commonSearchSpaceList"); for (const auto& e1 : common_search_space_list) { e1.to_json(j); @@ -3554,9 +3566,9 @@ const char* pdcch_cfg_common_s::first_pdcch_monitoring_occasion_of_po_c_::types_ SRSASN_CODE pdsch_cfg_common_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(pdsch_time_domain_alloc_list_present, 1)); + HANDLE_CODE(bref.pack(pdsch_time_domain_alloc_list.size() > 0, 1)); - if (pdsch_time_domain_alloc_list_present) { + if (pdsch_time_domain_alloc_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, pdsch_time_domain_alloc_list, 1, 16)); } @@ -3565,6 +3577,7 @@ SRSASN_CODE pdsch_cfg_common_s::pack(bit_ref& bref) const SRSASN_CODE pdsch_cfg_common_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool pdsch_time_domain_alloc_list_present; HANDLE_CODE(bref.unpack(pdsch_time_domain_alloc_list_present, 1)); if (pdsch_time_domain_alloc_list_present) { @@ -3576,7 +3589,7 @@ SRSASN_CODE pdsch_cfg_common_s::unpack(cbit_ref& bref) void pdsch_cfg_common_s::to_json(json_writer& j) const { j.start_obj(); - if (pdsch_time_domain_alloc_list_present) { + if (pdsch_time_domain_alloc_list.size() > 0) { j.start_array("pdsch-TimeDomainAllocationList"); for (const auto& e1 : pdsch_time_domain_alloc_list) { e1.to_json(j); @@ -3695,11 +3708,11 @@ SRSASN_CODE pusch_cfg_common_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(group_hop_enabled_transform_precoding_present, 1)); - HANDLE_CODE(bref.pack(pusch_time_domain_alloc_list_present, 1)); + HANDLE_CODE(bref.pack(pusch_time_domain_alloc_list.size() > 0, 1)); HANDLE_CODE(bref.pack(msg3_delta_preamb_present, 1)); HANDLE_CODE(bref.pack(p0_nominal_with_grant_present, 1)); - if (pusch_time_domain_alloc_list_present) { + if (pusch_time_domain_alloc_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, pusch_time_domain_alloc_list, 1, 16)); } if (msg3_delta_preamb_present) { @@ -3715,6 +3728,7 @@ SRSASN_CODE pusch_cfg_common_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(group_hop_enabled_transform_precoding_present, 1)); + bool pusch_time_domain_alloc_list_present; HANDLE_CODE(bref.unpack(pusch_time_domain_alloc_list_present, 1)); HANDLE_CODE(bref.unpack(msg3_delta_preamb_present, 1)); HANDLE_CODE(bref.unpack(p0_nominal_with_grant_present, 1)); @@ -3737,7 +3751,7 @@ void pusch_cfg_common_s::to_json(json_writer& j) const if (group_hop_enabled_transform_precoding_present) { j.write_str("groupHoppingEnabledTransformPrecoding", "enabled"); } - if (pusch_time_domain_alloc_list_present) { + if (pusch_time_domain_alloc_list.size() > 0) { j.start_array("pusch-TimeDomainAllocationList"); for (const auto& e1 : pusch_time_domain_alloc_list) { e1.to_json(j); @@ -4697,12 +4711,12 @@ void freq_info_dl_sib_s::to_json(json_writer& j) const SRSASN_CODE freq_info_ul_sib_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(freq_band_list_present, 1)); + HANDLE_CODE(bref.pack(freq_band_list.size() > 0, 1)); HANDLE_CODE(bref.pack(absolute_freq_point_a_present, 1)); HANDLE_CODE(bref.pack(p_max_present, 1)); HANDLE_CODE(bref.pack(freq_shift7p5khz_present, 1)); - if (freq_band_list_present) { + if (freq_band_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list, 1, 8)); } if (absolute_freq_point_a_present) { @@ -4718,6 +4732,7 @@ SRSASN_CODE freq_info_ul_sib_s::pack(bit_ref& bref) const SRSASN_CODE freq_info_ul_sib_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool freq_band_list_present; HANDLE_CODE(bref.unpack(freq_band_list_present, 1)); HANDLE_CODE(bref.unpack(absolute_freq_point_a_present, 1)); HANDLE_CODE(bref.unpack(p_max_present, 1)); @@ -4739,7 +4754,7 @@ SRSASN_CODE freq_info_ul_sib_s::unpack(cbit_ref& bref) void freq_info_ul_sib_s::to_json(json_writer& j) const { j.start_obj(); - if (freq_band_list_present) { + if (freq_band_list.size() > 0) { j.start_array("frequencyBandList"); for (const auto& e1 : freq_band_list) { e1.to_json(j); @@ -5952,8 +5967,8 @@ SRSASN_CODE sib2_s::intra_freq_cell_resel_info_s_::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(q_rx_lev_min_sul_present, 1)); HANDLE_CODE(bref.pack(q_qual_min_present, 1)); HANDLE_CODE(bref.pack(s_intra_search_q_present, 1)); - HANDLE_CODE(bref.pack(freq_band_list_present, 1)); - HANDLE_CODE(bref.pack(freq_band_list_sul_present, 1)); + HANDLE_CODE(bref.pack(freq_band_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(freq_band_list_sul.size() > 0, 1)); HANDLE_CODE(bref.pack(p_max_present, 1)); HANDLE_CODE(bref.pack(smtc_present, 1)); HANDLE_CODE(bref.pack(ss_rssi_meas_present, 1)); @@ -5971,10 +5986,10 @@ SRSASN_CODE sib2_s::intra_freq_cell_resel_info_s_::pack(bit_ref& bref) const HANDLE_CODE(pack_integer(bref, s_intra_search_q, (uint8_t)0u, (uint8_t)31u)); } HANDLE_CODE(pack_integer(bref, t_resel_nr, (uint8_t)0u, (uint8_t)7u)); - if (freq_band_list_present) { + if (freq_band_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list, 1, 8)); } - if (freq_band_list_sul_present) { + if (freq_band_list_sul.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list_sul, 1, 8)); } if (p_max_present) { @@ -6013,7 +6028,9 @@ SRSASN_CODE sib2_s::intra_freq_cell_resel_info_s_::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(q_rx_lev_min_sul_present, 1)); HANDLE_CODE(bref.unpack(q_qual_min_present, 1)); HANDLE_CODE(bref.unpack(s_intra_search_q_present, 1)); + bool freq_band_list_present; HANDLE_CODE(bref.unpack(freq_band_list_present, 1)); + bool freq_band_list_sul_present; HANDLE_CODE(bref.unpack(freq_band_list_sul_present, 1)); HANDLE_CODE(bref.unpack(p_max_present, 1)); HANDLE_CODE(bref.unpack(smtc_present, 1)); @@ -6084,14 +6101,14 @@ void sib2_s::intra_freq_cell_resel_info_s_::to_json(json_writer& j) const j.write_int("s-IntraSearchQ", s_intra_search_q); } j.write_int("t-ReselectionNR", t_resel_nr); - if (freq_band_list_present) { + if (freq_band_list.size() > 0) { j.start_array("frequencyBandList"); for (const auto& e1 : freq_band_list) { e1.to_json(j); } j.end_array(); } - if (freq_band_list_sul_present) { + if (freq_band_list_sul.size() > 0) { j.start_array("frequencyBandListSUL"); for (const auto& e1 : freq_band_list_sul) { e1.to_json(j); @@ -6127,17 +6144,17 @@ void sib2_s::intra_freq_cell_resel_info_s_::to_json(json_writer& j) const SRSASN_CODE sib3_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(intra_freq_neigh_cell_list_present, 1)); - HANDLE_CODE(bref.pack(intra_freq_black_cell_list_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(intra_freq_neigh_cell_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(intra_freq_black_cell_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); - if (intra_freq_neigh_cell_list_present) { + if (intra_freq_neigh_cell_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, intra_freq_neigh_cell_list, 1, 16)); } - if (intra_freq_black_cell_list_present) { + if (intra_freq_black_cell_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, intra_freq_black_cell_list, 1, 16)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -6146,8 +6163,11 @@ SRSASN_CODE sib3_s::pack(bit_ref& bref) const SRSASN_CODE sib3_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool intra_freq_neigh_cell_list_present; HANDLE_CODE(bref.unpack(intra_freq_neigh_cell_list_present, 1)); + bool intra_freq_black_cell_list_present; HANDLE_CODE(bref.unpack(intra_freq_black_cell_list_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); if (intra_freq_neigh_cell_list_present) { @@ -6165,21 +6185,21 @@ SRSASN_CODE sib3_s::unpack(cbit_ref& bref) void sib3_s::to_json(json_writer& j) const { j.start_obj(); - if (intra_freq_neigh_cell_list_present) { + if (intra_freq_neigh_cell_list.size() > 0) { j.start_array("intraFreqNeighCellList"); for (const auto& e1 : intra_freq_neigh_cell_list) { e1.to_json(j); } j.end_array(); } - if (intra_freq_black_cell_list_present) { + if (intra_freq_black_cell_list.size() > 0) { j.start_array("intraFreqBlackCellList"); for (const auto& e1 : intra_freq_black_cell_list) { e1.to_json(j); } j.end_array(); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } j.end_obj(); @@ -6189,10 +6209,10 @@ void sib3_s::to_json(json_writer& j) const SRSASN_CODE sib4_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(pack_dyn_seq_of(bref, inter_freq_carrier_freq_list, 1, 8)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -6201,6 +6221,7 @@ SRSASN_CODE sib4_s::pack(bit_ref& bref) const SRSASN_CODE sib4_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(unpack_dyn_seq_of(inter_freq_carrier_freq_list, bref, 1, 8)); @@ -6218,7 +6239,7 @@ void sib4_s::to_json(json_writer& j) const e1.to_json(j); } j.end_array(); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } j.end_obj(); @@ -6228,18 +6249,18 @@ void sib4_s::to_json(json_writer& j) const SRSASN_CODE sib5_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(carrier_freq_list_eutra_present, 1)); + HANDLE_CODE(bref.pack(carrier_freq_list_eutra.size() > 0, 1)); HANDLE_CODE(bref.pack(t_resel_eutra_sf_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); - if (carrier_freq_list_eutra_present) { + if (carrier_freq_list_eutra.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, carrier_freq_list_eutra, 1, 8)); } HANDLE_CODE(pack_integer(bref, t_resel_eutra, (uint8_t)0u, (uint8_t)7u)); if (t_resel_eutra_sf_present) { HANDLE_CODE(t_resel_eutra_sf.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -6248,8 +6269,10 @@ SRSASN_CODE sib5_s::pack(bit_ref& bref) const SRSASN_CODE sib5_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool carrier_freq_list_eutra_present; HANDLE_CODE(bref.unpack(carrier_freq_list_eutra_present, 1)); HANDLE_CODE(bref.unpack(t_resel_eutra_sf_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); if (carrier_freq_list_eutra_present) { @@ -6268,7 +6291,7 @@ SRSASN_CODE sib5_s::unpack(cbit_ref& bref) void sib5_s::to_json(json_writer& j) const { j.start_obj(); - if (carrier_freq_list_eutra_present) { + if (carrier_freq_list_eutra.size() > 0) { j.start_array("carrierFreqListEUTRA"); for (const auto& e1 : carrier_freq_list_eutra) { e1.to_json(j); @@ -6280,7 +6303,7 @@ void sib5_s::to_json(json_writer& j) const j.write_fieldname("t-ReselectionEUTRA-SF"); t_resel_eutra_sf.to_json(j); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } j.end_obj(); @@ -6290,12 +6313,12 @@ void sib5_s::to_json(json_writer& j) const SRSASN_CODE sib6_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(msg_id.pack(bref)); HANDLE_CODE(serial_num.pack(bref)); HANDLE_CODE(warning_type.pack(bref)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -6304,6 +6327,7 @@ SRSASN_CODE sib6_s::pack(bit_ref& bref) const SRSASN_CODE sib6_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(msg_id.unpack(bref)); @@ -6321,7 +6345,7 @@ void sib6_s::to_json(json_writer& j) const j.write_str("messageIdentifier", msg_id.to_string()); j.write_str("serialNumber", serial_num.to_string()); j.write_str("warningType", warning_type.to_string()); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } j.end_obj(); @@ -6332,7 +6356,7 @@ SRSASN_CODE sib7_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(data_coding_scheme_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(msg_id.pack(bref)); HANDLE_CODE(serial_num.pack(bref)); @@ -6342,7 +6366,7 @@ SRSASN_CODE sib7_s::pack(bit_ref& bref) const if (data_coding_scheme_present) { HANDLE_CODE(data_coding_scheme.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -6352,6 +6376,7 @@ SRSASN_CODE sib7_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(data_coding_scheme_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(msg_id.unpack(bref)); @@ -6379,7 +6404,7 @@ void sib7_s::to_json(json_writer& j) const if (data_coding_scheme_present) { j.write_str("dataCodingScheme", data_coding_scheme.to_string()); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } j.end_obj(); @@ -6396,8 +6421,8 @@ SRSASN_CODE sib8_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(data_coding_scheme_present, 1)); - HANDLE_CODE(bref.pack(warning_area_coordinates_segment_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(warning_area_coordinates_segment.size() > 0, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(msg_id.pack(bref)); HANDLE_CODE(serial_num.pack(bref)); @@ -6407,10 +6432,10 @@ SRSASN_CODE sib8_s::pack(bit_ref& bref) const if (data_coding_scheme_present) { HANDLE_CODE(data_coding_scheme.pack(bref)); } - if (warning_area_coordinates_segment_present) { + if (warning_area_coordinates_segment.size() > 0) { HANDLE_CODE(warning_area_coordinates_segment.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -6420,7 +6445,9 @@ SRSASN_CODE sib8_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(data_coding_scheme_present, 1)); + bool warning_area_coordinates_segment_present; HANDLE_CODE(bref.unpack(warning_area_coordinates_segment_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(msg_id.unpack(bref)); @@ -6451,10 +6478,10 @@ void sib8_s::to_json(json_writer& j) const if (data_coding_scheme_present) { j.write_str("dataCodingScheme", data_coding_scheme.to_string()); } - if (warning_area_coordinates_segment_present) { + if (warning_area_coordinates_segment.size() > 0) { j.write_str("warningAreaCoordinatesSegment", warning_area_coordinates_segment.to_string()); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } j.end_obj(); @@ -6471,7 +6498,7 @@ SRSASN_CODE sib9_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(time_info_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); if (time_info_present) { HANDLE_CODE(bref.pack(time_info.day_light_saving_time_present, 1)); @@ -6488,7 +6515,7 @@ SRSASN_CODE sib9_s::pack(bit_ref& bref) const HANDLE_CODE(pack_integer(bref, time_info.local_time_offset, (int8_t)-63, (int8_t)64)); } } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -6498,6 +6525,7 @@ SRSASN_CODE sib9_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(time_info_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); if (time_info_present) { @@ -6539,7 +6567,7 @@ void sib9_s::to_json(json_writer& j) const } j.end_obj(); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } j.end_obj(); @@ -7187,11 +7215,11 @@ uint8_t serving_cell_cfg_common_sib_s::ssb_periodicity_serving_cell_opts::to_num // SystemInformation-IEs ::= SEQUENCE SRSASN_CODE sys_info_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); HANDLE_CODE(pack_dyn_seq_of(bref, sib_type_and_info, 1, 32)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -7199,6 +7227,7 @@ SRSASN_CODE sys_info_ies_s::pack(bit_ref& bref) const } SRSASN_CODE sys_info_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -7217,7 +7246,7 @@ void sys_info_ies_s::to_json(json_writer& j) const e1.to_json(j); } j.end_array(); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -7668,7 +7697,7 @@ SRSASN_CODE sib1_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(ue_timers_and_consts_present, 1)); HANDLE_CODE(bref.pack(uac_barr_info_present, 1)); HANDLE_CODE(bref.pack(use_full_resume_id_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (cell_sel_info_present) { @@ -7704,13 +7733,13 @@ SRSASN_CODE sib1_s::pack(bit_ref& bref) const HANDLE_CODE(ue_timers_and_consts.pack(bref)); } if (uac_barr_info_present) { - HANDLE_CODE(bref.pack(uac_barr_info.uac_barr_for_common_present, 1)); - HANDLE_CODE(bref.pack(uac_barr_info.uac_barr_per_plmn_list_present, 1)); + HANDLE_CODE(bref.pack(uac_barr_info.uac_barr_for_common.size() > 0, 1)); + HANDLE_CODE(bref.pack(uac_barr_info.uac_barr_per_plmn_list.size() > 0, 1)); HANDLE_CODE(bref.pack(uac_barr_info.uac_access_category1_sel_assist_info_present, 1)); - if (uac_barr_info.uac_barr_for_common_present) { + if (uac_barr_info.uac_barr_for_common.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, uac_barr_info.uac_barr_for_common, 1, 63)); } - if (uac_barr_info.uac_barr_per_plmn_list_present) { + if (uac_barr_info.uac_barr_per_plmn_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, uac_barr_info.uac_barr_per_plmn_list, 1, 12)); } HANDLE_CODE(pack_dyn_seq_of(bref, uac_barr_info.uac_barr_info_set_list, 1, 8)); @@ -7718,7 +7747,7 @@ SRSASN_CODE sib1_s::pack(bit_ref& bref) const HANDLE_CODE(uac_barr_info.uac_access_category1_sel_assist_info.pack(bref)); } } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -7735,6 +7764,7 @@ SRSASN_CODE sib1_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(ue_timers_and_consts_present, 1)); HANDLE_CODE(bref.unpack(uac_barr_info_present, 1)); HANDLE_CODE(bref.unpack(use_full_resume_id_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -7771,13 +7801,15 @@ SRSASN_CODE sib1_s::unpack(cbit_ref& bref) HANDLE_CODE(ue_timers_and_consts.unpack(bref)); } if (uac_barr_info_present) { - HANDLE_CODE(bref.unpack(uac_barr_info.uac_barr_for_common_present, 1)); - HANDLE_CODE(bref.unpack(uac_barr_info.uac_barr_per_plmn_list_present, 1)); + bool uac_barr_for_common_present; + HANDLE_CODE(bref.unpack(uac_barr_for_common_present, 1)); + bool uac_barr_per_plmn_list_present; + HANDLE_CODE(bref.unpack(uac_barr_per_plmn_list_present, 1)); HANDLE_CODE(bref.unpack(uac_barr_info.uac_access_category1_sel_assist_info_present, 1)); - if (uac_barr_info.uac_barr_for_common_present) { + if (uac_barr_for_common_present) { HANDLE_CODE(unpack_dyn_seq_of(uac_barr_info.uac_barr_for_common, bref, 1, 63)); } - if (uac_barr_info.uac_barr_per_plmn_list_present) { + if (uac_barr_per_plmn_list_present) { HANDLE_CODE(unpack_dyn_seq_of(uac_barr_info.uac_barr_per_plmn_list, bref, 1, 12)); } HANDLE_CODE(unpack_dyn_seq_of(uac_barr_info.uac_barr_info_set_list, bref, 1, 8)); @@ -7839,14 +7871,14 @@ void sib1_s::to_json(json_writer& j) const if (uac_barr_info_present) { j.write_fieldname("uac-BarringInfo"); j.start_obj(); - if (uac_barr_info.uac_barr_for_common_present) { + if (uac_barr_info.uac_barr_for_common.size() > 0) { j.start_array("uac-BarringForCommon"); for (const auto& e1 : uac_barr_info.uac_barr_for_common) { e1.to_json(j); } j.end_array(); } - if (uac_barr_info.uac_barr_per_plmn_list_present) { + if (uac_barr_info.uac_barr_per_plmn_list.size() > 0) { j.start_array("uac-BarringPerPLMN-List"); for (const auto& e1 : uac_barr_info.uac_barr_per_plmn_list) { e1.to_json(j); @@ -7867,7 +7899,7 @@ void sib1_s::to_json(json_writer& j) const if (use_full_resume_id_present) { j.write_str("useFullResumeID", "true"); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -8861,17 +8893,17 @@ uint16_t pdcp_cfg_s::t_reordering_opts::to_number() const SRSASN_CODE sdap_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(mapped_qos_flows_to_add_present, 1)); - HANDLE_CODE(bref.pack(mapped_qos_flows_to_release_present, 1)); + HANDLE_CODE(bref.pack(mapped_qos_flows_to_add.size() > 0, 1)); + HANDLE_CODE(bref.pack(mapped_qos_flows_to_release.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, pdu_session, (uint16_t)0u, (uint16_t)255u)); HANDLE_CODE(sdap_hdr_dl.pack(bref)); HANDLE_CODE(sdap_hdr_ul.pack(bref)); HANDLE_CODE(bref.pack(default_drb, 1)); - if (mapped_qos_flows_to_add_present) { + if (mapped_qos_flows_to_add.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, mapped_qos_flows_to_add, 1, 64, integer_packer(0, 63))); } - if (mapped_qos_flows_to_release_present) { + if (mapped_qos_flows_to_release.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, mapped_qos_flows_to_release, 1, 64, integer_packer(0, 63))); } @@ -8880,7 +8912,9 @@ SRSASN_CODE sdap_cfg_s::pack(bit_ref& bref) const SRSASN_CODE sdap_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool mapped_qos_flows_to_add_present; HANDLE_CODE(bref.unpack(mapped_qos_flows_to_add_present, 1)); + bool mapped_qos_flows_to_release_present; HANDLE_CODE(bref.unpack(mapped_qos_flows_to_release_present, 1)); HANDLE_CODE(unpack_integer(pdu_session, bref, (uint16_t)0u, (uint16_t)255u)); @@ -8903,14 +8937,14 @@ void sdap_cfg_s::to_json(json_writer& j) const j.write_str("sdap-HeaderDL", sdap_hdr_dl.to_string()); j.write_str("sdap-HeaderUL", sdap_hdr_ul.to_string()); j.write_bool("defaultDRB", default_drb); - if (mapped_qos_flows_to_add_present) { + if (mapped_qos_flows_to_add.size() > 0) { j.start_array("mappedQoS-FlowsToAdd"); for (const auto& e1 : mapped_qos_flows_to_add) { j.write_int(e1); } j.end_array(); } - if (mapped_qos_flows_to_release_present) { + if (mapped_qos_flows_to_release.size() > 0) { j.start_array("mappedQoS-FlowsToRelease"); for (const auto& e1 : mapped_qos_flows_to_release) { j.write_int(e1); @@ -9255,19 +9289,19 @@ const char* security_cfg_s::key_to_use_opts::to_string() const SRSASN_CODE radio_bearer_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(srb_to_add_mod_list_present, 1)); + HANDLE_CODE(bref.pack(srb_to_add_mod_list.size() > 0, 1)); HANDLE_CODE(bref.pack(srb3_to_release_present, 1)); - HANDLE_CODE(bref.pack(drb_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(drb_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(drb_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(drb_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(security_cfg_present, 1)); - if (srb_to_add_mod_list_present) { + if (srb_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, srb_to_add_mod_list, 1, 2)); } - if (drb_to_add_mod_list_present) { + if (drb_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, drb_to_add_mod_list, 1, 29)); } - if (drb_to_release_list_present) { + if (drb_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, drb_to_release_list, 1, 29, integer_packer(1, 32))); } if (security_cfg_present) { @@ -9279,9 +9313,12 @@ SRSASN_CODE radio_bearer_cfg_s::pack(bit_ref& bref) const SRSASN_CODE radio_bearer_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool srb_to_add_mod_list_present; HANDLE_CODE(bref.unpack(srb_to_add_mod_list_present, 1)); HANDLE_CODE(bref.unpack(srb3_to_release_present, 1)); + bool drb_to_add_mod_list_present; HANDLE_CODE(bref.unpack(drb_to_add_mod_list_present, 1)); + bool drb_to_release_list_present; HANDLE_CODE(bref.unpack(drb_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(security_cfg_present, 1)); @@ -9303,7 +9340,7 @@ SRSASN_CODE radio_bearer_cfg_s::unpack(cbit_ref& bref) void radio_bearer_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (srb_to_add_mod_list_present) { + if (srb_to_add_mod_list.size() > 0) { j.start_array("srb-ToAddModList"); for (const auto& e1 : srb_to_add_mod_list) { e1.to_json(j); @@ -9313,14 +9350,14 @@ void radio_bearer_cfg_s::to_json(json_writer& j) const if (srb3_to_release_present) { j.write_str("srb3-ToRelease", "true"); } - if (drb_to_add_mod_list_present) { + if (drb_to_add_mod_list.size() > 0) { j.start_array("drb-ToAddModList"); for (const auto& e1 : drb_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (drb_to_release_list_present) { + if (drb_to_release_list.size() > 0) { j.start_array("drb-ToReleaseList"); for (const auto& e1 : drb_to_release_list) { j.write_int(e1); @@ -9338,13 +9375,13 @@ void radio_bearer_cfg_s::to_json(json_writer& j) const SRSASN_CODE rrc_reject_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(wait_time_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (wait_time_present) { HANDLE_CODE(pack_integer(bref, wait_time, (uint8_t)1u, (uint8_t)16u)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -9353,6 +9390,7 @@ SRSASN_CODE rrc_reject_ies_s::pack(bit_ref& bref) const SRSASN_CODE rrc_reject_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(wait_time_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -9371,7 +9409,7 @@ void rrc_reject_ies_s::to_json(json_writer& j) const if (wait_time_present) { j.write_int("waitTime", wait_time); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -9385,12 +9423,12 @@ void rrc_reject_ies_s::to_json(json_writer& j) const // RRCSetup-IEs ::= SEQUENCE SRSASN_CODE rrc_setup_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); HANDLE_CODE(radio_bearer_cfg.pack(bref)); HANDLE_CODE(master_cell_group.pack(bref)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -9398,6 +9436,7 @@ SRSASN_CODE rrc_setup_ies_s::pack(bit_ref& bref) const } SRSASN_CODE rrc_setup_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -9415,7 +9454,7 @@ void rrc_setup_ies_s::to_json(json_writer& j) const j.write_fieldname("radioBearerConfig"); radio_bearer_cfg.to_json(j); j.write_str("masterCellGroup", master_cell_group.to_string()); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -11925,10 +11964,10 @@ int8_t periodical_report_cfg_inter_rat_s::report_amount_opts::to_number() const // RAN-AreaConfig ::= SEQUENCE SRSASN_CODE ran_area_cfg_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(ran_area_code_list_present, 1)); + HANDLE_CODE(bref.pack(ran_area_code_list.size() > 0, 1)); HANDLE_CODE(tac.pack(bref)); - if (ran_area_code_list_present) { + if (ran_area_code_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ran_area_code_list, 1, 32, integer_packer(0, 255))); } @@ -11936,6 +11975,7 @@ SRSASN_CODE ran_area_cfg_s::pack(bit_ref& bref) const } SRSASN_CODE ran_area_cfg_s::unpack(cbit_ref& bref) { + bool ran_area_code_list_present; HANDLE_CODE(bref.unpack(ran_area_code_list_present, 1)); HANDLE_CODE(tac.unpack(bref)); @@ -11949,7 +11989,7 @@ void ran_area_cfg_s::to_json(json_writer& j) const { j.start_obj(); j.write_str("trackingAreaCode", tac.to_string()); - if (ran_area_code_list_present) { + if (ran_area_code_list.size() > 0) { j.start_array("ran-AreaCodeList"); for (const auto& e1 : ran_area_code_list) { j.write_int(e1); @@ -12149,9 +12189,9 @@ void report_sftd_nr_s::to_json(json_writer& j) const // SSB-MTC2 ::= SEQUENCE SRSASN_CODE ssb_mtc2_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(pci_list_present, 1)); + HANDLE_CODE(bref.pack(pci_list.size() > 0, 1)); - if (pci_list_present) { + if (pci_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, pci_list, 1, 64, integer_packer(0, 1007))); } HANDLE_CODE(periodicity.pack(bref)); @@ -12160,6 +12200,7 @@ SRSASN_CODE ssb_mtc2_s::pack(bit_ref& bref) const } SRSASN_CODE ssb_mtc2_s::unpack(cbit_ref& bref) { + bool pci_list_present; HANDLE_CODE(bref.unpack(pci_list_present, 1)); if (pci_list_present) { @@ -12172,7 +12213,7 @@ SRSASN_CODE ssb_mtc2_s::unpack(cbit_ref& bref) void ssb_mtc2_s::to_json(json_writer& j) const { j.start_obj(); - if (pci_list_present) { + if (pci_list.size() > 0) { j.start_array("pci-List"); for (const auto& e1 : pci_list) { j.write_int(e1); @@ -12362,24 +12403,24 @@ const char* mrdc_secondary_cell_group_cfg_s::mrdc_secondary_cell_group_c_::types SRSASN_CODE meas_obj_eutra_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(cells_to_rem_list_eutran_present, 1)); - HANDLE_CODE(bref.pack(cells_to_add_mod_list_eutran_present, 1)); - HANDLE_CODE(bref.pack(black_cells_to_rem_list_eutran_present, 1)); - HANDLE_CODE(bref.pack(black_cells_to_add_mod_list_eutran_present, 1)); + HANDLE_CODE(bref.pack(cells_to_rem_list_eutran.size() > 0, 1)); + HANDLE_CODE(bref.pack(cells_to_add_mod_list_eutran.size() > 0, 1)); + HANDLE_CODE(bref.pack(black_cells_to_rem_list_eutran.size() > 0, 1)); + HANDLE_CODE(bref.pack(black_cells_to_add_mod_list_eutran.size() > 0, 1)); HANDLE_CODE(bref.pack(eutra_q_offset_range_present, 1)); HANDLE_CODE(pack_integer(bref, carrier_freq, (uint32_t)0u, (uint32_t)262143u)); HANDLE_CODE(allowed_meas_bw.pack(bref)); - if (cells_to_rem_list_eutran_present) { + if (cells_to_rem_list_eutran.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, cells_to_rem_list_eutran, 1, 32, integer_packer(1, 32))); } - if (cells_to_add_mod_list_eutran_present) { + if (cells_to_add_mod_list_eutran.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, cells_to_add_mod_list_eutran, 1, 32)); } - if (black_cells_to_rem_list_eutran_present) { + if (black_cells_to_rem_list_eutran.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, black_cells_to_rem_list_eutran, 1, 32, integer_packer(1, 32))); } - if (black_cells_to_add_mod_list_eutran_present) { + if (black_cells_to_add_mod_list_eutran.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, black_cells_to_add_mod_list_eutran, 1, 32)); } HANDLE_CODE(bref.pack(eutra_presence_ant_port1, 1)); @@ -12393,9 +12434,13 @@ SRSASN_CODE meas_obj_eutra_s::pack(bit_ref& bref) const SRSASN_CODE meas_obj_eutra_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool cells_to_rem_list_eutran_present; HANDLE_CODE(bref.unpack(cells_to_rem_list_eutran_present, 1)); + bool cells_to_add_mod_list_eutran_present; HANDLE_CODE(bref.unpack(cells_to_add_mod_list_eutran_present, 1)); + bool black_cells_to_rem_list_eutran_present; HANDLE_CODE(bref.unpack(black_cells_to_rem_list_eutran_present, 1)); + bool black_cells_to_add_mod_list_eutran_present; HANDLE_CODE(bref.unpack(black_cells_to_add_mod_list_eutran_present, 1)); HANDLE_CODE(bref.unpack(eutra_q_offset_range_present, 1)); @@ -12426,28 +12471,28 @@ void meas_obj_eutra_s::to_json(json_writer& j) const j.start_obj(); j.write_int("carrierFreq", carrier_freq); j.write_str("allowedMeasBandwidth", allowed_meas_bw.to_string()); - if (cells_to_rem_list_eutran_present) { + if (cells_to_rem_list_eutran.size() > 0) { j.start_array("cellsToRemoveListEUTRAN"); for (const auto& e1 : cells_to_rem_list_eutran) { j.write_int(e1); } j.end_array(); } - if (cells_to_add_mod_list_eutran_present) { + if (cells_to_add_mod_list_eutran.size() > 0) { j.start_array("cellsToAddModListEUTRAN"); for (const auto& e1 : cells_to_add_mod_list_eutran) { e1.to_json(j); } j.end_array(); } - if (black_cells_to_rem_list_eutran_present) { + if (black_cells_to_rem_list_eutran.size() > 0) { j.start_array("blackCellsToRemoveListEUTRAN"); for (const auto& e1 : black_cells_to_rem_list_eutran) { j.write_int(e1); } j.end_array(); } - if (black_cells_to_add_mod_list_eutran_present) { + if (black_cells_to_add_mod_list_eutran.size() > 0) { j.start_array("blackCellsToAddModListEUTRAN"); for (const auto& e1 : black_cells_to_add_mod_list_eutran) { e1.to_json(j); @@ -12475,12 +12520,12 @@ SRSASN_CODE meas_obj_nr_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(abs_thresh_csi_rs_consolidation_present, 1)); HANDLE_CODE(bref.pack(nrof_ss_blocks_to_average_present, 1)); HANDLE_CODE(bref.pack(nrof_csi_rs_res_to_average_present, 1)); - HANDLE_CODE(bref.pack(cells_to_rem_list_present, 1)); - HANDLE_CODE(bref.pack(cells_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(black_cells_to_rem_list_present, 1)); - HANDLE_CODE(bref.pack(black_cells_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(white_cells_to_rem_list_present, 1)); - HANDLE_CODE(bref.pack(white_cells_to_add_mod_list_present, 1)); + HANDLE_CODE(bref.pack(cells_to_rem_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(cells_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(black_cells_to_rem_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(black_cells_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(white_cells_to_rem_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(white_cells_to_add_mod_list.size() > 0, 1)); if (ssb_freq_present) { HANDLE_CODE(pack_integer(bref, ssb_freq, (uint32_t)0u, (uint32_t)3279165u)); @@ -12512,22 +12557,22 @@ SRSASN_CODE meas_obj_nr_s::pack(bit_ref& bref) const } HANDLE_CODE(pack_integer(bref, quant_cfg_idx, (uint8_t)1u, (uint8_t)2u)); HANDLE_CODE(offset_mo.pack(bref)); - if (cells_to_rem_list_present) { + if (cells_to_rem_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, cells_to_rem_list, 1, 32, integer_packer(0, 1007))); } - if (cells_to_add_mod_list_present) { + if (cells_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, cells_to_add_mod_list, 1, 32)); } - if (black_cells_to_rem_list_present) { + if (black_cells_to_rem_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, black_cells_to_rem_list, 1, 8, integer_packer(1, 8))); } - if (black_cells_to_add_mod_list_present) { + if (black_cells_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, black_cells_to_add_mod_list, 1, 8)); } - if (white_cells_to_rem_list_present) { + if (white_cells_to_rem_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, white_cells_to_rem_list, 1, 8, integer_packer(1, 8))); } - if (white_cells_to_add_mod_list_present) { + if (white_cells_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, white_cells_to_add_mod_list, 1, 8)); } @@ -12564,11 +12609,17 @@ SRSASN_CODE meas_obj_nr_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(abs_thresh_csi_rs_consolidation_present, 1)); HANDLE_CODE(bref.unpack(nrof_ss_blocks_to_average_present, 1)); HANDLE_CODE(bref.unpack(nrof_csi_rs_res_to_average_present, 1)); + bool cells_to_rem_list_present; HANDLE_CODE(bref.unpack(cells_to_rem_list_present, 1)); + bool cells_to_add_mod_list_present; HANDLE_CODE(bref.unpack(cells_to_add_mod_list_present, 1)); + bool black_cells_to_rem_list_present; HANDLE_CODE(bref.unpack(black_cells_to_rem_list_present, 1)); + bool black_cells_to_add_mod_list_present; HANDLE_CODE(bref.unpack(black_cells_to_add_mod_list_present, 1)); + bool white_cells_to_rem_list_present; HANDLE_CODE(bref.unpack(white_cells_to_rem_list_present, 1)); + bool white_cells_to_add_mod_list_present; HANDLE_CODE(bref.unpack(white_cells_to_add_mod_list_present, 1)); if (ssb_freq_present) { @@ -12678,42 +12729,42 @@ void meas_obj_nr_s::to_json(json_writer& j) const j.write_int("quantityConfigIndex", quant_cfg_idx); j.write_fieldname("offsetMO"); offset_mo.to_json(j); - if (cells_to_rem_list_present) { + if (cells_to_rem_list.size() > 0) { j.start_array("cellsToRemoveList"); for (const auto& e1 : cells_to_rem_list) { j.write_int(e1); } j.end_array(); } - if (cells_to_add_mod_list_present) { + if (cells_to_add_mod_list.size() > 0) { j.start_array("cellsToAddModList"); for (const auto& e1 : cells_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (black_cells_to_rem_list_present) { + if (black_cells_to_rem_list.size() > 0) { j.start_array("blackCellsToRemoveList"); for (const auto& e1 : black_cells_to_rem_list) { j.write_int(e1); } j.end_array(); } - if (black_cells_to_add_mod_list_present) { + if (black_cells_to_add_mod_list.size() > 0) { j.start_array("blackCellsToAddModList"); for (const auto& e1 : black_cells_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (white_cells_to_rem_list_present) { + if (white_cells_to_rem_list.size() > 0) { j.start_array("whiteCellsToRemoveList"); for (const auto& e1 : white_cells_to_rem_list) { j.write_int(e1); } j.end_array(); } - if (white_cells_to_add_mod_list_present) { + if (white_cells_to_add_mod_list.size() > 0) { j.start_array("whiteCellsToAddModList"); for (const auto& e1 : white_cells_to_add_mod_list) { e1.to_json(j); @@ -13798,14 +13849,14 @@ const char* rat_type_opts::to_string() const SRSASN_CODE rrc_recfg_v1560_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(mrdc_secondary_cell_group_cfg_present, 1)); - HANDLE_CODE(bref.pack(radio_bearer_cfg2_present, 1)); + HANDLE_CODE(bref.pack(radio_bearer_cfg2.size() > 0, 1)); HANDLE_CODE(bref.pack(sk_counter_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (mrdc_secondary_cell_group_cfg_present) { HANDLE_CODE(mrdc_secondary_cell_group_cfg.pack(bref)); } - if (radio_bearer_cfg2_present) { + if (radio_bearer_cfg2.size() > 0) { HANDLE_CODE(radio_bearer_cfg2.pack(bref)); } if (sk_counter_present) { @@ -13817,6 +13868,7 @@ SRSASN_CODE rrc_recfg_v1560_ies_s::pack(bit_ref& bref) const SRSASN_CODE rrc_recfg_v1560_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(mrdc_secondary_cell_group_cfg_present, 1)); + bool radio_bearer_cfg2_present; HANDLE_CODE(bref.unpack(radio_bearer_cfg2_present, 1)); HANDLE_CODE(bref.unpack(sk_counter_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -13840,7 +13892,7 @@ void rrc_recfg_v1560_ies_s::to_json(json_writer& j) const j.write_fieldname("mrdc-SecondaryCellGroupConfig"); mrdc_secondary_cell_group_cfg.to_json(j); } - if (radio_bearer_cfg2_present) { + if (radio_bearer_cfg2.size() > 0) { j.write_str("radioBearerConfig2", radio_bearer_cfg2.to_string()); } if (sk_counter_present) { @@ -14085,11 +14137,11 @@ void drb_count_msb_info_s::to_json(json_writer& j) const SRSASN_CODE master_key_upd_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(nas_container_present, 1)); + HANDLE_CODE(bref.pack(nas_container.size() > 0, 1)); HANDLE_CODE(bref.pack(key_set_change_ind, 1)); HANDLE_CODE(pack_integer(bref, next_hop_chaining_count, (uint8_t)0u, (uint8_t)7u)); - if (nas_container_present) { + if (nas_container.size() > 0) { HANDLE_CODE(nas_container.pack(bref)); } @@ -14098,6 +14150,7 @@ SRSASN_CODE master_key_upd_s::pack(bit_ref& bref) const SRSASN_CODE master_key_upd_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool nas_container_present; HANDLE_CODE(bref.unpack(nas_container_present, 1)); HANDLE_CODE(bref.unpack(key_set_change_ind, 1)); @@ -14113,7 +14166,7 @@ void master_key_upd_s::to_json(json_writer& j) const j.start_obj(); j.write_bool("keySetChangeIndicator", key_set_change_ind); j.write_int("nextHopChainingCount", next_hop_chaining_count); - if (nas_container_present) { + if (nas_container.size() > 0) { j.write_str("nas-Container", nas_container.to_string()); } j.end_obj(); @@ -14422,9 +14475,9 @@ uint16_t periodic_rnau_timer_value_opts::to_number() const SRSASN_CODE quant_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(quant_cfg_nr_list_present, 1)); + HANDLE_CODE(bref.pack(quant_cfg_nr_list.size() > 0, 1)); - if (quant_cfg_nr_list_present) { + if (quant_cfg_nr_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, quant_cfg_nr_list, 1, 2)); } @@ -14447,6 +14500,7 @@ SRSASN_CODE quant_cfg_s::pack(bit_ref& bref) const SRSASN_CODE quant_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool quant_cfg_nr_list_present; HANDLE_CODE(bref.unpack(quant_cfg_nr_list_present, 1)); if (quant_cfg_nr_list_present) { @@ -14473,7 +14527,7 @@ SRSASN_CODE quant_cfg_s::unpack(cbit_ref& bref) void quant_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (quant_cfg_nr_list_present) { + if (quant_cfg_nr_list.size() > 0) { j.start_array("quantityConfigNR-List"); for (const auto& e1 : quant_cfg_nr_list) { e1.to_json(j); @@ -14725,10 +14779,10 @@ uint8_t redirected_carrier_info_eutra_s::cn_type_opts::to_number() const SRSASN_CODE ue_cap_rat_request_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(cap_request_filt_present, 1)); + HANDLE_CODE(bref.pack(cap_request_filt.size() > 0, 1)); HANDLE_CODE(rat_type.pack(bref)); - if (cap_request_filt_present) { + if (cap_request_filt.size() > 0) { HANDLE_CODE(cap_request_filt.pack(bref)); } @@ -14737,6 +14791,7 @@ SRSASN_CODE ue_cap_rat_request_s::pack(bit_ref& bref) const SRSASN_CODE ue_cap_rat_request_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool cap_request_filt_present; HANDLE_CODE(bref.unpack(cap_request_filt_present, 1)); HANDLE_CODE(rat_type.unpack(bref)); @@ -14750,7 +14805,7 @@ void ue_cap_rat_request_s::to_json(json_writer& j) const { j.start_obj(); j.write_str("rat-Type", rat_type.to_string()); - if (cap_request_filt_present) { + if (cap_request_filt.size() > 0) { j.write_str("capabilityRequestFilter", cap_request_filt.to_string()); } j.end_obj(); @@ -14760,14 +14815,14 @@ void ue_cap_rat_request_s::to_json(json_writer& j) const SRSASN_CODE cell_resel_priorities_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(freq_prio_list_eutra_present, 1)); - HANDLE_CODE(bref.pack(freq_prio_list_nr_present, 1)); + HANDLE_CODE(bref.pack(freq_prio_list_eutra.size() > 0, 1)); + HANDLE_CODE(bref.pack(freq_prio_list_nr.size() > 0, 1)); HANDLE_CODE(bref.pack(t320_present, 1)); - if (freq_prio_list_eutra_present) { + if (freq_prio_list_eutra.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, freq_prio_list_eutra, 1, 8)); } - if (freq_prio_list_nr_present) { + if (freq_prio_list_nr.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, freq_prio_list_nr, 1, 8)); } if (t320_present) { @@ -14779,7 +14834,9 @@ SRSASN_CODE cell_resel_priorities_s::pack(bit_ref& bref) const SRSASN_CODE cell_resel_priorities_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool freq_prio_list_eutra_present; HANDLE_CODE(bref.unpack(freq_prio_list_eutra_present, 1)); + bool freq_prio_list_nr_present; HANDLE_CODE(bref.unpack(freq_prio_list_nr_present, 1)); HANDLE_CODE(bref.unpack(t320_present, 1)); @@ -14798,14 +14855,14 @@ SRSASN_CODE cell_resel_priorities_s::unpack(cbit_ref& bref) void cell_resel_priorities_s::to_json(json_writer& j) const { j.start_obj(); - if (freq_prio_list_eutra_present) { + if (freq_prio_list_eutra.size() > 0) { j.start_array("freqPriorityListEUTRA"); for (const auto& e1 : freq_prio_list_eutra) { e1.to_json(j); } j.end_array(); } - if (freq_prio_list_nr_present) { + if (freq_prio_list_nr.size() > 0) { j.start_array("freqPriorityListNR"); for (const auto& e1 : freq_prio_list_nr) { e1.to_json(j); @@ -14833,33 +14890,33 @@ uint8_t cell_resel_priorities_s::t320_opts::to_number() const SRSASN_CODE meas_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(meas_obj_to_rem_list_present, 1)); - HANDLE_CODE(bref.pack(meas_obj_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(report_cfg_to_rem_list_present, 1)); - HANDLE_CODE(bref.pack(report_cfg_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(meas_id_to_rem_list_present, 1)); - HANDLE_CODE(bref.pack(meas_id_to_add_mod_list_present, 1)); + HANDLE_CODE(bref.pack(meas_obj_to_rem_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(meas_obj_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(report_cfg_to_rem_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(report_cfg_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(meas_id_to_rem_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(meas_id_to_add_mod_list.size() > 0, 1)); HANDLE_CODE(bref.pack(s_measure_cfg_present, 1)); HANDLE_CODE(bref.pack(quant_cfg_present, 1)); HANDLE_CODE(bref.pack(meas_gap_cfg_present, 1)); HANDLE_CODE(bref.pack(meas_gap_sharing_cfg_present, 1)); - if (meas_obj_to_rem_list_present) { + if (meas_obj_to_rem_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_obj_to_rem_list, 1, 64, integer_packer(1, 64))); } - if (meas_obj_to_add_mod_list_present) { + if (meas_obj_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_obj_to_add_mod_list, 1, 64)); } - if (report_cfg_to_rem_list_present) { + if (report_cfg_to_rem_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, report_cfg_to_rem_list, 1, 64, integer_packer(1, 64))); } - if (report_cfg_to_add_mod_list_present) { + if (report_cfg_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, report_cfg_to_add_mod_list, 1, 64)); } - if (meas_id_to_rem_list_present) { + if (meas_id_to_rem_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_id_to_rem_list, 1, 64, integer_packer(1, 64))); } - if (meas_id_to_add_mod_list_present) { + if (meas_id_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_id_to_add_mod_list, 1, 64)); } if (s_measure_cfg_present) { @@ -14880,11 +14937,17 @@ SRSASN_CODE meas_cfg_s::pack(bit_ref& bref) const SRSASN_CODE meas_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool meas_obj_to_rem_list_present; HANDLE_CODE(bref.unpack(meas_obj_to_rem_list_present, 1)); + bool meas_obj_to_add_mod_list_present; HANDLE_CODE(bref.unpack(meas_obj_to_add_mod_list_present, 1)); + bool report_cfg_to_rem_list_present; HANDLE_CODE(bref.unpack(report_cfg_to_rem_list_present, 1)); + bool report_cfg_to_add_mod_list_present; HANDLE_CODE(bref.unpack(report_cfg_to_add_mod_list_present, 1)); + bool meas_id_to_rem_list_present; HANDLE_CODE(bref.unpack(meas_id_to_rem_list_present, 1)); + bool meas_id_to_add_mod_list_present; HANDLE_CODE(bref.unpack(meas_id_to_add_mod_list_present, 1)); HANDLE_CODE(bref.unpack(s_measure_cfg_present, 1)); HANDLE_CODE(bref.unpack(quant_cfg_present, 1)); @@ -14927,42 +14990,42 @@ SRSASN_CODE meas_cfg_s::unpack(cbit_ref& bref) void meas_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (meas_obj_to_rem_list_present) { + if (meas_obj_to_rem_list.size() > 0) { j.start_array("measObjectToRemoveList"); for (const auto& e1 : meas_obj_to_rem_list) { j.write_int(e1); } j.end_array(); } - if (meas_obj_to_add_mod_list_present) { + if (meas_obj_to_add_mod_list.size() > 0) { j.start_array("measObjectToAddModList"); for (const auto& e1 : meas_obj_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (report_cfg_to_rem_list_present) { + if (report_cfg_to_rem_list.size() > 0) { j.start_array("reportConfigToRemoveList"); for (const auto& e1 : report_cfg_to_rem_list) { j.write_int(e1); } j.end_array(); } - if (report_cfg_to_add_mod_list_present) { + if (report_cfg_to_add_mod_list.size() > 0) { j.start_array("reportConfigToAddModList"); for (const auto& e1 : report_cfg_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (meas_id_to_rem_list_present) { + if (meas_id_to_rem_list.size() > 0) { j.start_array("measIdToRemoveList"); for (const auto& e1 : meas_id_to_rem_list) { j.write_int(e1); } j.end_array(); } - if (meas_id_to_add_mod_list_present) { + if (meas_id_to_add_mod_list.size() > 0) { j.start_array("measIdToAddModList"); for (const auto& e1 : meas_id_to_add_mod_list) { e1.to_json(j); @@ -15100,28 +15163,28 @@ const char* meas_cfg_s::s_measure_cfg_c_::types_opts::to_string() const // RRCReconfiguration-v1530-IEs ::= SEQUENCE SRSASN_CODE rrc_recfg_v1530_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(master_cell_group_present, 1)); + HANDLE_CODE(bref.pack(master_cell_group.size() > 0, 1)); HANDLE_CODE(bref.pack(full_cfg_present, 1)); - HANDLE_CODE(bref.pack(ded_nas_msg_list_present, 1)); + HANDLE_CODE(bref.pack(ded_nas_msg_list.size() > 0, 1)); HANDLE_CODE(bref.pack(master_key_upd_present, 1)); - HANDLE_CODE(bref.pack(ded_sib1_delivery_present, 1)); - HANDLE_CODE(bref.pack(ded_sys_info_delivery_present, 1)); + HANDLE_CODE(bref.pack(ded_sib1_delivery.size() > 0, 1)); + HANDLE_CODE(bref.pack(ded_sys_info_delivery.size() > 0, 1)); HANDLE_CODE(bref.pack(other_cfg_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (master_cell_group_present) { + if (master_cell_group.size() > 0) { HANDLE_CODE(master_cell_group.pack(bref)); } - if (ded_nas_msg_list_present) { + if (ded_nas_msg_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ded_nas_msg_list, 1, 29)); } if (master_key_upd_present) { HANDLE_CODE(master_key_upd.pack(bref)); } - if (ded_sib1_delivery_present) { + if (ded_sib1_delivery.size() > 0) { HANDLE_CODE(ded_sib1_delivery.pack(bref)); } - if (ded_sys_info_delivery_present) { + if (ded_sys_info_delivery.size() > 0) { HANDLE_CODE(ded_sys_info_delivery.pack(bref)); } if (other_cfg_present) { @@ -15135,11 +15198,15 @@ SRSASN_CODE rrc_recfg_v1530_ies_s::pack(bit_ref& bref) const } SRSASN_CODE rrc_recfg_v1530_ies_s::unpack(cbit_ref& bref) { + bool master_cell_group_present; HANDLE_CODE(bref.unpack(master_cell_group_present, 1)); HANDLE_CODE(bref.unpack(full_cfg_present, 1)); + bool ded_nas_msg_list_present; HANDLE_CODE(bref.unpack(ded_nas_msg_list_present, 1)); HANDLE_CODE(bref.unpack(master_key_upd_present, 1)); + bool ded_sib1_delivery_present; HANDLE_CODE(bref.unpack(ded_sib1_delivery_present, 1)); + bool ded_sys_info_delivery_present; HANDLE_CODE(bref.unpack(ded_sys_info_delivery_present, 1)); HANDLE_CODE(bref.unpack(other_cfg_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -15171,13 +15238,13 @@ SRSASN_CODE rrc_recfg_v1530_ies_s::unpack(cbit_ref& bref) void rrc_recfg_v1530_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (master_cell_group_present) { + if (master_cell_group.size() > 0) { j.write_str("masterCellGroup", master_cell_group.to_string()); } if (full_cfg_present) { j.write_str("fullConfig", "true"); } - if (ded_nas_msg_list_present) { + if (ded_nas_msg_list.size() > 0) { j.start_array("dedicatedNAS-MessageList"); for (const auto& e1 : ded_nas_msg_list) { j.write_str(e1.to_string()); @@ -15188,10 +15255,10 @@ void rrc_recfg_v1530_ies_s::to_json(json_writer& j) const j.write_fieldname("masterKeyUpdate"); master_key_upd.to_json(j); } - if (ded_sib1_delivery_present) { + if (ded_sib1_delivery.size() > 0) { j.write_str("dedicatedSIB1-Delivery", ded_sib1_delivery.to_string()); } - if (ded_sys_info_delivery_present) { + if (ded_sys_info_delivery.size() > 0) { j.write_str("dedicatedSystemInformationDelivery", ded_sys_info_delivery.to_string()); } if (other_cfg_present) { @@ -15245,11 +15312,11 @@ void rrc_release_v1540_ies_s::to_json(json_writer& j) const // RRCResume-v1560-IEs ::= SEQUENCE SRSASN_CODE rrc_resume_v1560_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(radio_bearer_cfg2_present, 1)); + HANDLE_CODE(bref.pack(radio_bearer_cfg2.size() > 0, 1)); HANDLE_CODE(bref.pack(sk_counter_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (radio_bearer_cfg2_present) { + if (radio_bearer_cfg2.size() > 0) { HANDLE_CODE(radio_bearer_cfg2.pack(bref)); } if (sk_counter_present) { @@ -15260,6 +15327,7 @@ SRSASN_CODE rrc_resume_v1560_ies_s::pack(bit_ref& bref) const } SRSASN_CODE rrc_resume_v1560_ies_s::unpack(cbit_ref& bref) { + bool radio_bearer_cfg2_present; HANDLE_CODE(bref.unpack(radio_bearer_cfg2_present, 1)); HANDLE_CODE(bref.unpack(sk_counter_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -15276,7 +15344,7 @@ SRSASN_CODE rrc_resume_v1560_ies_s::unpack(cbit_ref& bref) void rrc_resume_v1560_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (radio_bearer_cfg2_present) { + if (radio_bearer_cfg2.size() > 0) { j.write_str("radioBearerConfig2", radio_bearer_cfg2.to_string()); } if (sk_counter_present) { @@ -15508,11 +15576,11 @@ void suspend_cfg_s::to_json(json_writer& j) const // CounterCheck-IEs ::= SEQUENCE SRSASN_CODE counter_check_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); HANDLE_CODE(pack_dyn_seq_of(bref, drb_count_msb_info_list, 1, 29)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -15520,6 +15588,7 @@ SRSASN_CODE counter_check_ies_s::pack(bit_ref& bref) const } SRSASN_CODE counter_check_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -15538,7 +15607,7 @@ void counter_check_ies_s::to_json(json_writer& j) const e1.to_json(j); } j.end_array(); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -15552,14 +15621,14 @@ void counter_check_ies_s::to_json(json_writer& j) const // DLInformationTransfer-IEs ::= SEQUENCE SRSASN_CODE dl_info_transfer_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(ded_nas_msg_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(ded_nas_msg.size() > 0, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (ded_nas_msg_present) { + if (ded_nas_msg.size() > 0) { HANDLE_CODE(ded_nas_msg.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -15567,7 +15636,9 @@ SRSASN_CODE dl_info_transfer_ies_s::pack(bit_ref& bref) const } SRSASN_CODE dl_info_transfer_ies_s::unpack(cbit_ref& bref) { + bool ded_nas_msg_present; HANDLE_CODE(bref.unpack(ded_nas_msg_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -15583,10 +15654,10 @@ SRSASN_CODE dl_info_transfer_ies_s::unpack(cbit_ref& bref) void dl_info_transfer_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (ded_nas_msg_present) { + if (ded_nas_msg.size() > 0) { j.write_str("dedicatedNAS-Message", ded_nas_msg.to_string()); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -15600,16 +15671,16 @@ void dl_info_transfer_ies_s::to_json(json_writer& j) const // MobilityFromNRCommand-IEs ::= SEQUENCE SRSASN_CODE mob_from_nr_cmd_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(nas_security_param_from_nr_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(nas_security_param_from_nr.size() > 0, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); HANDLE_CODE(target_rat_type.pack(bref)); HANDLE_CODE(target_rat_msg_container.pack(bref)); - if (nas_security_param_from_nr_present) { + if (nas_security_param_from_nr.size() > 0) { HANDLE_CODE(nas_security_param_from_nr.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -15617,7 +15688,9 @@ SRSASN_CODE mob_from_nr_cmd_ies_s::pack(bit_ref& bref) const } SRSASN_CODE mob_from_nr_cmd_ies_s::unpack(cbit_ref& bref) { + bool nas_security_param_from_nr_present; HANDLE_CODE(bref.unpack(nas_security_param_from_nr_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -15637,10 +15710,10 @@ void mob_from_nr_cmd_ies_s::to_json(json_writer& j) const j.start_obj(); j.write_str("targetRAT-Type", target_rat_type.to_string()); j.write_str("targetRAT-MessageContainer", target_rat_msg_container.to_string()); - if (nas_security_param_from_nr_present) { + if (nas_security_param_from_nr.size() > 0) { j.write_str("nas-SecurityParamFromNR", nas_security_param_from_nr.to_string()); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -15661,21 +15734,21 @@ const char* mob_from_nr_cmd_ies_s::target_rat_type_opts::to_string() const SRSASN_CODE rrc_recfg_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(radio_bearer_cfg_present, 1)); - HANDLE_CODE(bref.pack(secondary_cell_group_present, 1)); + HANDLE_CODE(bref.pack(secondary_cell_group.size() > 0, 1)); HANDLE_CODE(bref.pack(meas_cfg_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (radio_bearer_cfg_present) { HANDLE_CODE(radio_bearer_cfg.pack(bref)); } - if (secondary_cell_group_present) { + if (secondary_cell_group.size() > 0) { HANDLE_CODE(secondary_cell_group.pack(bref)); } if (meas_cfg_present) { HANDLE_CODE(meas_cfg.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } if (non_crit_ext_present) { @@ -15687,8 +15760,10 @@ SRSASN_CODE rrc_recfg_ies_s::pack(bit_ref& bref) const SRSASN_CODE rrc_recfg_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(radio_bearer_cfg_present, 1)); + bool secondary_cell_group_present; HANDLE_CODE(bref.unpack(secondary_cell_group_present, 1)); HANDLE_CODE(bref.unpack(meas_cfg_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -15717,14 +15792,14 @@ void rrc_recfg_ies_s::to_json(json_writer& j) const j.write_fieldname("radioBearerConfig"); radio_bearer_cfg.to_json(j); } - if (secondary_cell_group_present) { + if (secondary_cell_group.size() > 0) { j.write_str("secondaryCellGroup", secondary_cell_group.to_string()); } if (meas_cfg_present) { j.write_fieldname("measConfig"); meas_cfg.to_json(j); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -15737,11 +15812,11 @@ void rrc_recfg_ies_s::to_json(json_writer& j) const // RRCReestablishment-IEs ::= SEQUENCE SRSASN_CODE rrc_reest_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); HANDLE_CODE(pack_integer(bref, next_hop_chaining_count, (uint8_t)0u, (uint8_t)7u)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -15749,6 +15824,7 @@ SRSASN_CODE rrc_reest_ies_s::pack(bit_ref& bref) const } SRSASN_CODE rrc_reest_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -15763,7 +15839,7 @@ void rrc_reest_ies_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("nextHopChainingCount", next_hop_chaining_count); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -15781,7 +15857,7 @@ SRSASN_CODE rrc_release_ies_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(cell_resel_priorities_present, 1)); HANDLE_CODE(bref.pack(suspend_cfg_present, 1)); HANDLE_CODE(bref.pack(depriorit_req_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (redirected_carrier_info_present) { @@ -15797,7 +15873,7 @@ SRSASN_CODE rrc_release_ies_s::pack(bit_ref& bref) const HANDLE_CODE(depriorit_req.depriorit_type.pack(bref)); HANDLE_CODE(depriorit_req.depriorit_timer.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } if (non_crit_ext_present) { @@ -15812,6 +15888,7 @@ SRSASN_CODE rrc_release_ies_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(cell_resel_priorities_present, 1)); HANDLE_CODE(bref.unpack(suspend_cfg_present, 1)); HANDLE_CODE(bref.unpack(depriorit_req_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -15859,7 +15936,7 @@ void rrc_release_ies_s::to_json(json_writer& j) const j.write_str("deprioritisationTimer", depriorit_req.depriorit_timer.to_string()); j.end_obj(); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -15890,22 +15967,22 @@ uint8_t rrc_release_ies_s::depriorit_req_s_::depriorit_timer_opts::to_number() c SRSASN_CODE rrc_resume_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(radio_bearer_cfg_present, 1)); - HANDLE_CODE(bref.pack(master_cell_group_present, 1)); + HANDLE_CODE(bref.pack(master_cell_group.size() > 0, 1)); HANDLE_CODE(bref.pack(meas_cfg_present, 1)); HANDLE_CODE(bref.pack(full_cfg_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (radio_bearer_cfg_present) { HANDLE_CODE(radio_bearer_cfg.pack(bref)); } - if (master_cell_group_present) { + if (master_cell_group.size() > 0) { HANDLE_CODE(master_cell_group.pack(bref)); } if (meas_cfg_present) { HANDLE_CODE(meas_cfg.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } if (non_crit_ext_present) { @@ -15917,9 +15994,11 @@ SRSASN_CODE rrc_resume_ies_s::pack(bit_ref& bref) const SRSASN_CODE rrc_resume_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(radio_bearer_cfg_present, 1)); + bool master_cell_group_present; HANDLE_CODE(bref.unpack(master_cell_group_present, 1)); HANDLE_CODE(bref.unpack(meas_cfg_present, 1)); HANDLE_CODE(bref.unpack(full_cfg_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -15948,7 +16027,7 @@ void rrc_resume_ies_s::to_json(json_writer& j) const j.write_fieldname("radioBearerConfig"); radio_bearer_cfg.to_json(j); } - if (master_cell_group_present) { + if (master_cell_group.size() > 0) { j.write_str("masterCellGroup", master_cell_group.to_string()); } if (meas_cfg_present) { @@ -15958,7 +16037,7 @@ void rrc_resume_ies_s::to_json(json_writer& j) const if (full_cfg_present) { j.write_str("fullConfig", "true"); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -15971,11 +16050,11 @@ void rrc_resume_ies_s::to_json(json_writer& j) const // SecurityModeCommand-IEs ::= SEQUENCE SRSASN_CODE security_mode_cmd_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); HANDLE_CODE(security_cfg_smc.pack(bref)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -15983,6 +16062,7 @@ SRSASN_CODE security_mode_cmd_ies_s::pack(bit_ref& bref) const } SRSASN_CODE security_mode_cmd_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -15998,7 +16078,7 @@ void security_mode_cmd_ies_s::to_json(json_writer& j) const j.start_obj(); j.write_fieldname("securityConfigSMC"); security_cfg_smc.to_json(j); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -16012,14 +16092,14 @@ void security_mode_cmd_ies_s::to_json(json_writer& j) const // UECapabilityEnquiry-IEs ::= SEQUENCE SRSASN_CODE ue_cap_enquiry_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); - HANDLE_CODE(bref.pack(ue_cap_enquiry_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); + HANDLE_CODE(bref.pack(ue_cap_enquiry_ext.size() > 0, 1)); HANDLE_CODE(pack_dyn_seq_of(bref, ue_cap_rat_request_list, 1, 8)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } - if (ue_cap_enquiry_ext_present) { + if (ue_cap_enquiry_ext.size() > 0) { HANDLE_CODE(ue_cap_enquiry_ext.pack(bref)); } @@ -16027,7 +16107,9 @@ SRSASN_CODE ue_cap_enquiry_ies_s::pack(bit_ref& bref) const } SRSASN_CODE ue_cap_enquiry_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); + bool ue_cap_enquiry_ext_present; HANDLE_CODE(bref.unpack(ue_cap_enquiry_ext_present, 1)); HANDLE_CODE(unpack_dyn_seq_of(ue_cap_rat_request_list, bref, 1, 8)); @@ -16048,10 +16130,10 @@ void ue_cap_enquiry_ies_s::to_json(json_writer& j) const e1.to_json(j); } j.end_array(); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } - if (ue_cap_enquiry_ext_present) { + if (ue_cap_enquiry_ext.size() > 0) { j.write_str("ue-CapabilityEnquiryExt", ue_cap_enquiry_ext.to_string()); } j.end_obj(); @@ -17601,14 +17683,14 @@ void paging_record_s::to_json(json_writer& j) const // Paging ::= SEQUENCE SRSASN_CODE paging_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(paging_record_list_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(paging_record_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (paging_record_list_present) { + if (paging_record_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, paging_record_list, 1, 32)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -17616,7 +17698,9 @@ SRSASN_CODE paging_s::pack(bit_ref& bref) const } SRSASN_CODE paging_s::unpack(cbit_ref& bref) { + bool paging_record_list_present; HANDLE_CODE(bref.unpack(paging_record_list_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -17632,14 +17716,14 @@ SRSASN_CODE paging_s::unpack(cbit_ref& bref) void paging_s::to_json(json_writer& j) const { j.start_obj(); - if (paging_record_list_present) { + if (paging_record_list.size() > 0) { j.start_array("pagingRecordList"); for (const auto& e1 : paging_record_list) { e1.to_json(j); } j.end_array(); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -19218,14 +19302,14 @@ void results_per_ssb_idx_s::to_json(json_writer& j) const SRSASN_CODE cgi_info_nr_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(plmn_id_info_list_present, 1)); - HANDLE_CODE(bref.pack(freq_band_list_present, 1)); + HANDLE_CODE(bref.pack(plmn_id_info_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(freq_band_list.size() > 0, 1)); HANDLE_CODE(bref.pack(no_sib1_present, 1)); - if (plmn_id_info_list_present) { + if (plmn_id_info_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, plmn_id_info_list, 1, 12)); } - if (freq_band_list_present) { + if (freq_band_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list, 1, 8, integer_packer(1, 1024))); } if (no_sib1_present) { @@ -19238,7 +19322,9 @@ SRSASN_CODE cgi_info_nr_s::pack(bit_ref& bref) const SRSASN_CODE cgi_info_nr_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool plmn_id_info_list_present; HANDLE_CODE(bref.unpack(plmn_id_info_list_present, 1)); + bool freq_band_list_present; HANDLE_CODE(bref.unpack(freq_band_list_present, 1)); HANDLE_CODE(bref.unpack(no_sib1_present, 1)); @@ -19258,14 +19344,14 @@ SRSASN_CODE cgi_info_nr_s::unpack(cbit_ref& bref) void cgi_info_nr_s::to_json(json_writer& j) const { j.start_obj(); - if (plmn_id_info_list_present) { + if (plmn_id_info_list.size() > 0) { j.start_array("plmn-IdentityInfoList"); for (const auto& e1 : plmn_id_info_list) { e1.to_json(j); } j.end_array(); } - if (freq_band_list_present) { + if (freq_band_list.size() > 0) { j.start_array("frequencyBandList"); for (const auto& e1 : freq_band_list) { j.write_int(e1); @@ -19361,22 +19447,22 @@ void cell_access_related_info_eutra_epc_s::to_json(json_writer& j) const SRSASN_CODE cgi_info_eutra_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(cgi_info_epc_present, 1)); - HANDLE_CODE(bref.pack(cgi_info_minus5_gc_present, 1)); - HANDLE_CODE(bref.pack(multi_band_info_list_present, 1)); + HANDLE_CODE(bref.pack(cgi_info_minus5_gc.size() > 0, 1)); + HANDLE_CODE(bref.pack(multi_band_info_list.size() > 0, 1)); HANDLE_CODE(bref.pack(freq_band_ind_prio_present, 1)); if (cgi_info_epc_present) { - HANDLE_CODE(bref.pack(cgi_info_epc.cgi_info_epc_list_present, 1)); + HANDLE_CODE(bref.pack(cgi_info_epc.cgi_info_epc_list.size() > 0, 1)); HANDLE_CODE(cgi_info_epc.cgi_info_epc_legacy.pack(bref)); - if (cgi_info_epc.cgi_info_epc_list_present) { + if (cgi_info_epc.cgi_info_epc_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, cgi_info_epc.cgi_info_epc_list, 1, 12)); } } - if (cgi_info_minus5_gc_present) { + if (cgi_info_minus5_gc.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, cgi_info_minus5_gc, 1, 12)); } HANDLE_CODE(pack_integer(bref, freq_band_ind, (uint16_t)1u, (uint16_t)256u)); - if (multi_band_info_list_present) { + if (multi_band_info_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, multi_band_info_list, 1, 8, integer_packer(1, 256))); } @@ -19385,14 +19471,17 @@ SRSASN_CODE cgi_info_eutra_s::pack(bit_ref& bref) const SRSASN_CODE cgi_info_eutra_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(cgi_info_epc_present, 1)); + bool cgi_info_minus5_gc_present; HANDLE_CODE(bref.unpack(cgi_info_minus5_gc_present, 1)); + bool multi_band_info_list_present; HANDLE_CODE(bref.unpack(multi_band_info_list_present, 1)); HANDLE_CODE(bref.unpack(freq_band_ind_prio_present, 1)); if (cgi_info_epc_present) { - HANDLE_CODE(bref.unpack(cgi_info_epc.cgi_info_epc_list_present, 1)); + bool cgi_info_epc_list_present; + HANDLE_CODE(bref.unpack(cgi_info_epc_list_present, 1)); HANDLE_CODE(cgi_info_epc.cgi_info_epc_legacy.unpack(bref)); - if (cgi_info_epc.cgi_info_epc_list_present) { + if (cgi_info_epc_list_present) { HANDLE_CODE(unpack_dyn_seq_of(cgi_info_epc.cgi_info_epc_list, bref, 1, 12)); } } @@ -19414,7 +19503,7 @@ void cgi_info_eutra_s::to_json(json_writer& j) const j.start_obj(); j.write_fieldname("cgi-info-EPC-legacy"); cgi_info_epc.cgi_info_epc_legacy.to_json(j); - if (cgi_info_epc.cgi_info_epc_list_present) { + if (cgi_info_epc.cgi_info_epc_list.size() > 0) { j.start_array("cgi-info-EPC-list"); for (const auto& e1 : cgi_info_epc.cgi_info_epc_list) { e1.to_json(j); @@ -19423,7 +19512,7 @@ void cgi_info_eutra_s::to_json(json_writer& j) const } j.end_obj(); } - if (cgi_info_minus5_gc_present) { + if (cgi_info_minus5_gc.size() > 0) { j.start_array("cgi-info-5GC"); for (const auto& e1 : cgi_info_minus5_gc) { e1.to_json(j); @@ -19431,7 +19520,7 @@ void cgi_info_eutra_s::to_json(json_writer& j) const j.end_array(); } j.write_int("freqBandIndicator", freq_band_ind); - if (multi_band_info_list_present) { + if (multi_band_info_list.size() > 0) { j.start_array("multiBandInfoList"); for (const auto& e1 : multi_band_info_list) { j.write_int(e1); @@ -19515,12 +19604,12 @@ SRSASN_CODE meas_result_nr_s::pack(bit_ref& bref) const HANDLE_CODE(meas_result.cell_results.results_csi_rs_cell.pack(bref)); } if (meas_result.rs_idx_results_present) { - HANDLE_CODE(bref.pack(meas_result.rs_idx_results.results_ssb_idxes_present, 1)); - HANDLE_CODE(bref.pack(meas_result.rs_idx_results.results_csi_rs_idxes_present, 1)); - if (meas_result.rs_idx_results.results_ssb_idxes_present) { + HANDLE_CODE(bref.pack(meas_result.rs_idx_results.results_ssb_idxes.size() > 0, 1)); + HANDLE_CODE(bref.pack(meas_result.rs_idx_results.results_csi_rs_idxes.size() > 0, 1)); + if (meas_result.rs_idx_results.results_ssb_idxes.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_result.rs_idx_results.results_ssb_idxes, 1, 64)); } - if (meas_result.rs_idx_results.results_csi_rs_idxes_present) { + if (meas_result.rs_idx_results.results_csi_rs_idxes.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_result.rs_idx_results.results_csi_rs_idxes, 1, 64)); } } @@ -19559,12 +19648,14 @@ SRSASN_CODE meas_result_nr_s::unpack(cbit_ref& bref) HANDLE_CODE(meas_result.cell_results.results_csi_rs_cell.unpack(bref)); } if (meas_result.rs_idx_results_present) { - HANDLE_CODE(bref.unpack(meas_result.rs_idx_results.results_ssb_idxes_present, 1)); - HANDLE_CODE(bref.unpack(meas_result.rs_idx_results.results_csi_rs_idxes_present, 1)); - if (meas_result.rs_idx_results.results_ssb_idxes_present) { + bool results_ssb_idxes_present; + HANDLE_CODE(bref.unpack(results_ssb_idxes_present, 1)); + bool results_csi_rs_idxes_present; + HANDLE_CODE(bref.unpack(results_csi_rs_idxes_present, 1)); + if (results_ssb_idxes_present) { HANDLE_CODE(unpack_dyn_seq_of(meas_result.rs_idx_results.results_ssb_idxes, bref, 1, 64)); } - if (meas_result.rs_idx_results.results_csi_rs_idxes_present) { + if (results_csi_rs_idxes_present) { HANDLE_CODE(unpack_dyn_seq_of(meas_result.rs_idx_results.results_csi_rs_idxes, bref, 1, 64)); } } @@ -19608,14 +19699,14 @@ void meas_result_nr_s::to_json(json_writer& j) const if (meas_result.rs_idx_results_present) { j.write_fieldname("rsIndexResults"); j.start_obj(); - if (meas_result.rs_idx_results.results_ssb_idxes_present) { + if (meas_result.rs_idx_results.results_ssb_idxes.size() > 0) { j.start_array("resultsSSB-Indexes"); for (const auto& e1 : meas_result.rs_idx_results.results_ssb_idxes) { e1.to_json(j); } j.end_array(); } - if (meas_result.rs_idx_results.results_csi_rs_idxes_present) { + if (meas_result.rs_idx_results.results_csi_rs_idxes.size() > 0) { j.start_array("resultsCSI-RS-Indexes"); for (const auto& e1 : meas_result.rs_idx_results.results_csi_rs_idxes) { e1.to_json(j); @@ -19804,7 +19895,7 @@ SRSASN_CODE meas_result2_nr_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(ssb_freq_present, 1)); HANDLE_CODE(bref.pack(ref_freq_csi_rs_present, 1)); HANDLE_CODE(bref.pack(meas_result_serving_cell_present, 1)); - HANDLE_CODE(bref.pack(meas_result_neigh_cell_list_nr_present, 1)); + HANDLE_CODE(bref.pack(meas_result_neigh_cell_list_nr.size() > 0, 1)); if (ssb_freq_present) { HANDLE_CODE(pack_integer(bref, ssb_freq, (uint32_t)0u, (uint32_t)3279165u)); @@ -19815,7 +19906,7 @@ SRSASN_CODE meas_result2_nr_s::pack(bit_ref& bref) const if (meas_result_serving_cell_present) { HANDLE_CODE(meas_result_serving_cell.pack(bref)); } - if (meas_result_neigh_cell_list_nr_present) { + if (meas_result_neigh_cell_list_nr.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_neigh_cell_list_nr, 1, 8)); } @@ -19827,6 +19918,7 @@ SRSASN_CODE meas_result2_nr_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(ssb_freq_present, 1)); HANDLE_CODE(bref.unpack(ref_freq_csi_rs_present, 1)); HANDLE_CODE(bref.unpack(meas_result_serving_cell_present, 1)); + bool meas_result_neigh_cell_list_nr_present; HANDLE_CODE(bref.unpack(meas_result_neigh_cell_list_nr_present, 1)); if (ssb_freq_present) { @@ -19857,7 +19949,7 @@ void meas_result2_nr_s::to_json(json_writer& j) const j.write_fieldname("measResultServingCell"); meas_result_serving_cell.to_json(j); } - if (meas_result_neigh_cell_list_nr_present) { + if (meas_result_neigh_cell_list_nr.size() > 0) { j.start_array("measResultNeighCellListNR"); for (const auto& e1 : meas_result_neigh_cell_list_nr) { e1.to_json(j); @@ -20490,14 +20582,14 @@ const char* fail_info_rlc_bearer_s::fail_type_opts::to_string() const SRSASN_CODE fail_report_scg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(meas_result_freq_list_present, 1)); - HANDLE_CODE(bref.pack(meas_result_scg_fail_present, 1)); + HANDLE_CODE(bref.pack(meas_result_freq_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(meas_result_scg_fail.size() > 0, 1)); HANDLE_CODE(fail_type.pack(bref)); - if (meas_result_freq_list_present) { + if (meas_result_freq_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_freq_list, 1, 8)); } - if (meas_result_scg_fail_present) { + if (meas_result_scg_fail.size() > 0) { HANDLE_CODE(meas_result_scg_fail.pack(bref)); } @@ -20506,7 +20598,9 @@ SRSASN_CODE fail_report_scg_s::pack(bit_ref& bref) const SRSASN_CODE fail_report_scg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool meas_result_freq_list_present; HANDLE_CODE(bref.unpack(meas_result_freq_list_present, 1)); + bool meas_result_scg_fail_present; HANDLE_CODE(bref.unpack(meas_result_scg_fail_present, 1)); HANDLE_CODE(fail_type.unpack(bref)); @@ -20523,14 +20617,14 @@ void fail_report_scg_s::to_json(json_writer& j) const { j.start_obj(); j.write_str("failureType", fail_type.to_string()); - if (meas_result_freq_list_present) { + if (meas_result_freq_list.size() > 0) { j.start_array("measResultFreqList"); for (const auto& e1 : meas_result_freq_list) { e1.to_json(j); } j.end_array(); } - if (meas_result_scg_fail_present) { + if (meas_result_scg_fail.size() > 0) { j.write_str("measResultSCG-Failure", meas_result_scg_fail.to_string()); } j.end_obj(); @@ -20565,14 +20659,14 @@ uint16_t fail_report_scg_s::fail_type_opts::to_number() const SRSASN_CODE fail_report_scg_eutra_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(meas_result_freq_list_mrdc_present, 1)); - HANDLE_CODE(bref.pack(meas_result_scg_fail_mrdc_present, 1)); + HANDLE_CODE(bref.pack(meas_result_freq_list_mrdc.size() > 0, 1)); + HANDLE_CODE(bref.pack(meas_result_scg_fail_mrdc.size() > 0, 1)); HANDLE_CODE(fail_type.pack(bref)); - if (meas_result_freq_list_mrdc_present) { + if (meas_result_freq_list_mrdc.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_freq_list_mrdc, 1, 8)); } - if (meas_result_scg_fail_mrdc_present) { + if (meas_result_scg_fail_mrdc.size() > 0) { HANDLE_CODE(meas_result_scg_fail_mrdc.pack(bref)); } @@ -20581,7 +20675,9 @@ SRSASN_CODE fail_report_scg_eutra_s::pack(bit_ref& bref) const SRSASN_CODE fail_report_scg_eutra_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool meas_result_freq_list_mrdc_present; HANDLE_CODE(bref.unpack(meas_result_freq_list_mrdc_present, 1)); + bool meas_result_scg_fail_mrdc_present; HANDLE_CODE(bref.unpack(meas_result_scg_fail_mrdc_present, 1)); HANDLE_CODE(fail_type.unpack(bref)); @@ -20598,14 +20694,14 @@ void fail_report_scg_eutra_s::to_json(json_writer& j) const { j.start_obj(); j.write_str("failureType", fail_type.to_string()); - if (meas_result_freq_list_mrdc_present) { + if (meas_result_freq_list_mrdc.size() > 0) { j.start_array("measResultFreqListMRDC"); for (const auto& e1 : meas_result_freq_list_mrdc) { e1.to_json(j); } j.end_array(); } - if (meas_result_scg_fail_mrdc_present) { + if (meas_result_scg_fail_mrdc.size() > 0) { j.write_str("measResultSCG-FailureMRDC", meas_result_scg_fail_mrdc.to_string()); } j.end_obj(); @@ -21003,10 +21099,10 @@ const char* meas_results_s::meas_result_neigh_cells_c_::types_opts::to_string() // RRCReconfigurationComplete-v1530-IEs ::= SEQUENCE SRSASN_CODE rrc_recfg_complete_v1530_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(ul_tx_direct_current_list_present, 1)); + HANDLE_CODE(bref.pack(ul_tx_direct_current_list.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (ul_tx_direct_current_list_present) { + if (ul_tx_direct_current_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ul_tx_direct_current_list, 1, 32)); } if (non_crit_ext_present) { @@ -21017,6 +21113,7 @@ SRSASN_CODE rrc_recfg_complete_v1530_ies_s::pack(bit_ref& bref) const } SRSASN_CODE rrc_recfg_complete_v1530_ies_s::unpack(cbit_ref& bref) { + bool ul_tx_direct_current_list_present; HANDLE_CODE(bref.unpack(ul_tx_direct_current_list_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -21032,7 +21129,7 @@ SRSASN_CODE rrc_recfg_complete_v1530_ies_s::unpack(cbit_ref& bref) void rrc_recfg_complete_v1530_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (ul_tx_direct_current_list_present) { + if (ul_tx_direct_current_list.size() > 0) { j.start_array("uplinkTxDirectCurrentList"); for (const auto& e1 : ul_tx_direct_current_list) { e1.to_json(j); @@ -21217,10 +21314,10 @@ const char* s_nssai_c::types_opts::to_string() const // SCGFailureInformation-v1590-IEs ::= SEQUENCE SRSASN_CODE scg_fail_info_v1590_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -21228,6 +21325,7 @@ SRSASN_CODE scg_fail_info_v1590_ies_s::pack(bit_ref& bref) const } SRSASN_CODE scg_fail_info_v1590_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -21240,7 +21338,7 @@ SRSASN_CODE scg_fail_info_v1590_ies_s::unpack(cbit_ref& bref) void scg_fail_info_v1590_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -21254,10 +21352,10 @@ void scg_fail_info_v1590_ies_s::to_json(json_writer& j) const // SCGFailureInformationEUTRA-v1590-IEs ::= SEQUENCE SRSASN_CODE scg_fail_info_eutra_v1590_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -21265,6 +21363,7 @@ SRSASN_CODE scg_fail_info_eutra_v1590_ies_s::pack(bit_ref& bref) const } SRSASN_CODE scg_fail_info_eutra_v1590_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -21277,7 +21376,7 @@ SRSASN_CODE scg_fail_info_eutra_v1590_ies_s::unpack(cbit_ref& bref) void scg_fail_info_eutra_v1590_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -21329,11 +21428,11 @@ void ueassist_info_v1540_ies_s::to_json(json_writer& j) const // CounterCheckResponse-IEs ::= SEQUENCE SRSASN_CODE counter_check_resp_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); HANDLE_CODE(pack_dyn_seq_of(bref, drb_count_info_list, 0, 29)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -21341,6 +21440,7 @@ SRSASN_CODE counter_check_resp_ies_s::pack(bit_ref& bref) const } SRSASN_CODE counter_check_resp_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -21359,7 +21459,7 @@ void counter_check_resp_ies_s::to_json(json_writer& j) const e1.to_json(j); } j.end_array(); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -21374,13 +21474,13 @@ void counter_check_resp_ies_s::to_json(json_writer& j) const SRSASN_CODE fail_info_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(fail_info_rlc_bearer_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (fail_info_rlc_bearer_present) { HANDLE_CODE(fail_info_rlc_bearer.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -21389,6 +21489,7 @@ SRSASN_CODE fail_info_ies_s::pack(bit_ref& bref) const SRSASN_CODE fail_info_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(fail_info_rlc_bearer_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -21408,7 +21509,7 @@ void fail_info_ies_s::to_json(json_writer& j) const j.write_fieldname("failureInfoRLC-Bearer"); fail_info_rlc_bearer.to_json(j); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -21422,11 +21523,11 @@ void fail_info_ies_s::to_json(json_writer& j) const // LocationMeasurementIndication-IEs ::= SEQUENCE SRSASN_CODE location_meas_ind_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); HANDLE_CODE(meas_ind.pack(bref)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -21434,6 +21535,7 @@ SRSASN_CODE location_meas_ind_ies_s::pack(bit_ref& bref) const } SRSASN_CODE location_meas_ind_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -21449,7 +21551,7 @@ void location_meas_ind_ies_s::to_json(json_writer& j) const j.start_obj(); j.write_fieldname("measurementIndication"); meas_ind.to_json(j); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -21463,11 +21565,11 @@ void location_meas_ind_ies_s::to_json(json_writer& j) const // MeasurementReport-IEs ::= SEQUENCE SRSASN_CODE meas_report_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); HANDLE_CODE(meas_results.pack(bref)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -21475,6 +21577,7 @@ SRSASN_CODE meas_report_ies_s::pack(bit_ref& bref) const } SRSASN_CODE meas_report_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -21490,7 +21593,7 @@ void meas_report_ies_s::to_json(json_writer& j) const j.start_obj(); j.write_fieldname("measResults"); meas_results.to_json(j); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -21504,10 +21607,10 @@ void meas_report_ies_s::to_json(json_writer& j) const // RRCReconfigurationComplete-IEs ::= SEQUENCE SRSASN_CODE rrc_recfg_complete_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } if (non_crit_ext_present) { @@ -21518,6 +21621,7 @@ SRSASN_CODE rrc_recfg_complete_ies_s::pack(bit_ref& bref) const } SRSASN_CODE rrc_recfg_complete_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -21533,7 +21637,7 @@ SRSASN_CODE rrc_recfg_complete_ies_s::unpack(cbit_ref& bref) void rrc_recfg_complete_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -21546,10 +21650,10 @@ void rrc_recfg_complete_ies_s::to_json(json_writer& j) const // RRCReestablishmentComplete-IEs ::= SEQUENCE SRSASN_CODE rrc_reest_complete_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -21557,6 +21661,7 @@ SRSASN_CODE rrc_reest_complete_ies_s::pack(bit_ref& bref) const } SRSASN_CODE rrc_reest_complete_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -21569,7 +21674,7 @@ SRSASN_CODE rrc_reest_complete_ies_s::unpack(cbit_ref& bref) void rrc_reest_complete_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -21583,22 +21688,22 @@ void rrc_reest_complete_ies_s::to_json(json_writer& j) const // RRCResumeComplete-IEs ::= SEQUENCE SRSASN_CODE rrc_resume_complete_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(ded_nas_msg_present, 1)); + HANDLE_CODE(bref.pack(ded_nas_msg.size() > 0, 1)); HANDLE_CODE(bref.pack(sel_plmn_id_present, 1)); - HANDLE_CODE(bref.pack(ul_tx_direct_current_list_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(ul_tx_direct_current_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (ded_nas_msg_present) { + if (ded_nas_msg.size() > 0) { HANDLE_CODE(ded_nas_msg.pack(bref)); } if (sel_plmn_id_present) { HANDLE_CODE(pack_integer(bref, sel_plmn_id, (uint8_t)1u, (uint8_t)12u)); } - if (ul_tx_direct_current_list_present) { + if (ul_tx_direct_current_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ul_tx_direct_current_list, 1, 32)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -21606,9 +21711,12 @@ SRSASN_CODE rrc_resume_complete_ies_s::pack(bit_ref& bref) const } SRSASN_CODE rrc_resume_complete_ies_s::unpack(cbit_ref& bref) { + bool ded_nas_msg_present; HANDLE_CODE(bref.unpack(ded_nas_msg_present, 1)); HANDLE_CODE(bref.unpack(sel_plmn_id_present, 1)); + bool ul_tx_direct_current_list_present; HANDLE_CODE(bref.unpack(ul_tx_direct_current_list_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -21630,20 +21738,20 @@ SRSASN_CODE rrc_resume_complete_ies_s::unpack(cbit_ref& bref) void rrc_resume_complete_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (ded_nas_msg_present) { + if (ded_nas_msg.size() > 0) { j.write_str("dedicatedNAS-Message", ded_nas_msg.to_string()); } if (sel_plmn_id_present) { j.write_int("selectedPLMN-Identity", sel_plmn_id); } - if (ul_tx_direct_current_list_present) { + if (ul_tx_direct_current_list.size() > 0) { j.start_array("uplinkTxDirectCurrentList"); for (const auto& e1 : ul_tx_direct_current_list) { e1.to_json(j); } j.end_array(); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -21659,9 +21767,9 @@ SRSASN_CODE rrc_setup_complete_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(registered_amf_present, 1)); HANDLE_CODE(bref.pack(guami_type_present, 1)); - HANDLE_CODE(bref.pack(s_nssai_list_present, 1)); + HANDLE_CODE(bref.pack(s_nssai_list.size() > 0, 1)); HANDLE_CODE(bref.pack(ng_minus5_g_s_tmsi_value_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); HANDLE_CODE(pack_integer(bref, sel_plmn_id, (uint8_t)1u, (uint8_t)12u)); @@ -21671,14 +21779,14 @@ SRSASN_CODE rrc_setup_complete_ies_s::pack(bit_ref& bref) const if (guami_type_present) { HANDLE_CODE(guami_type.pack(bref)); } - if (s_nssai_list_present) { + if (s_nssai_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, s_nssai_list, 1, 8)); } HANDLE_CODE(ded_nas_msg.pack(bref)); if (ng_minus5_g_s_tmsi_value_present) { HANDLE_CODE(ng_minus5_g_s_tmsi_value.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -21688,8 +21796,10 @@ SRSASN_CODE rrc_setup_complete_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(registered_amf_present, 1)); HANDLE_CODE(bref.unpack(guami_type_present, 1)); + bool s_nssai_list_present; HANDLE_CODE(bref.unpack(s_nssai_list_present, 1)); HANDLE_CODE(bref.unpack(ng_minus5_g_s_tmsi_value_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -21724,7 +21834,7 @@ void rrc_setup_complete_ies_s::to_json(json_writer& j) const if (guami_type_present) { j.write_str("guami-Type", guami_type.to_string()); } - if (s_nssai_list_present) { + if (s_nssai_list.size() > 0) { j.start_array("s-NSSAI-List"); for (const auto& e1 : s_nssai_list) { e1.to_json(j); @@ -21736,7 +21846,7 @@ void rrc_setup_complete_ies_s::to_json(json_writer& j) const j.write_fieldname("ng-5G-S-TMSI-Value"); ng_minus5_g_s_tmsi_value.to_json(j); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -21977,10 +22087,10 @@ void scg_fail_info_eutra_ies_s::to_json(json_writer& j) const // SecurityModeComplete-IEs ::= SEQUENCE SRSASN_CODE security_mode_complete_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -21988,6 +22098,7 @@ SRSASN_CODE security_mode_complete_ies_s::pack(bit_ref& bref) const } SRSASN_CODE security_mode_complete_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -22000,7 +22111,7 @@ SRSASN_CODE security_mode_complete_ies_s::unpack(cbit_ref& bref) void security_mode_complete_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -22014,10 +22125,10 @@ void security_mode_complete_ies_s::to_json(json_writer& j) const // SecurityModeFailure-IEs ::= SEQUENCE SRSASN_CODE security_mode_fail_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -22025,6 +22136,7 @@ SRSASN_CODE security_mode_fail_ies_s::pack(bit_ref& bref) const } SRSASN_CODE security_mode_fail_ies_s::unpack(cbit_ref& bref) { + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -22037,7 +22149,7 @@ SRSASN_CODE security_mode_fail_ies_s::unpack(cbit_ref& bref) void security_mode_fail_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -22052,13 +22164,13 @@ void security_mode_fail_ies_s::to_json(json_writer& j) const SRSASN_CODE ueassist_info_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(delay_budget_report_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (delay_budget_report_present) { HANDLE_CODE(delay_budget_report.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } if (non_crit_ext_present) { @@ -22070,6 +22182,7 @@ SRSASN_CODE ueassist_info_ies_s::pack(bit_ref& bref) const SRSASN_CODE ueassist_info_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(delay_budget_report_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -22092,7 +22205,7 @@ void ueassist_info_ies_s::to_json(json_writer& j) const j.write_fieldname("delayBudgetReport"); delay_budget_report.to_json(j); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -22106,13 +22219,13 @@ void ueassist_info_ies_s::to_json(json_writer& j) const SRSASN_CODE ue_cap_info_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(ue_cap_rat_container_list_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (ue_cap_rat_container_list_present) { HANDLE_CODE(pack_dyn_seq_of(bref, ue_cap_rat_container_list, 0, 8)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -22121,6 +22234,7 @@ SRSASN_CODE ue_cap_info_ies_s::pack(bit_ref& bref) const SRSASN_CODE ue_cap_info_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(ue_cap_rat_container_list_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -22143,7 +22257,7 @@ void ue_cap_info_ies_s::to_json(json_writer& j) const } j.end_array(); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -22157,14 +22271,14 @@ void ue_cap_info_ies_s::to_json(json_writer& j) const // ULInformationTransfer-IEs ::= SEQUENCE SRSASN_CODE ul_info_transfer_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(ded_nas_msg_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(ded_nas_msg.size() > 0, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (ded_nas_msg_present) { + if (ded_nas_msg.size() > 0) { HANDLE_CODE(ded_nas_msg.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -22172,7 +22286,9 @@ SRSASN_CODE ul_info_transfer_ies_s::pack(bit_ref& bref) const } SRSASN_CODE ul_info_transfer_ies_s::unpack(cbit_ref& bref) { + bool ded_nas_msg_present; HANDLE_CODE(bref.unpack(ded_nas_msg_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -22188,10 +22304,10 @@ SRSASN_CODE ul_info_transfer_ies_s::unpack(cbit_ref& bref) void ul_info_transfer_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (ded_nas_msg_present) { + if (ded_nas_msg.size() > 0) { j.write_str("dedicatedNAS-Message", ded_nas_msg.to_string()); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -22205,18 +22321,18 @@ void ul_info_transfer_ies_s::to_json(json_writer& j) const // ULInformationTransferMRDC-IEs ::= SEQUENCE SRSASN_CODE ul_info_transfer_mrdc_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(ul_dcch_msg_nr_present, 1)); - HANDLE_CODE(bref.pack(ul_dcch_msg_eutra_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(ul_dcch_msg_nr.size() > 0, 1)); + HANDLE_CODE(bref.pack(ul_dcch_msg_eutra.size() > 0, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (ul_dcch_msg_nr_present) { + if (ul_dcch_msg_nr.size() > 0) { HANDLE_CODE(ul_dcch_msg_nr.pack(bref)); } - if (ul_dcch_msg_eutra_present) { + if (ul_dcch_msg_eutra.size() > 0) { HANDLE_CODE(ul_dcch_msg_eutra.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -22224,8 +22340,11 @@ SRSASN_CODE ul_info_transfer_mrdc_ies_s::pack(bit_ref& bref) const } SRSASN_CODE ul_info_transfer_mrdc_ies_s::unpack(cbit_ref& bref) { + bool ul_dcch_msg_nr_present; HANDLE_CODE(bref.unpack(ul_dcch_msg_nr_present, 1)); + bool ul_dcch_msg_eutra_present; HANDLE_CODE(bref.unpack(ul_dcch_msg_eutra_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -22244,13 +22363,13 @@ SRSASN_CODE ul_info_transfer_mrdc_ies_s::unpack(cbit_ref& bref) void ul_info_transfer_mrdc_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (ul_dcch_msg_nr_present) { + if (ul_dcch_msg_nr.size() > 0) { j.write_str("ul-DCCH-MessageNR", ul_dcch_msg_nr.to_string()); } - if (ul_dcch_msg_eutra_present) { + if (ul_dcch_msg_eutra.size() > 0) { j.write_str("ul-DCCH-MessageEUTRA", ul_dcch_msg_eutra.to_string()); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -24419,11 +24538,11 @@ void ul_dcch_msg_s::to_json(json_writer& j) const SRSASN_CODE bfr_csirs_res_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(ra_occasion_list_present, 1)); + HANDLE_CODE(bref.pack(ra_occasion_list.size() > 0, 1)); HANDLE_CODE(bref.pack(ra_preamb_idx_present, 1)); HANDLE_CODE(pack_integer(bref, csi_rs, (uint8_t)0u, (uint8_t)191u)); - if (ra_occasion_list_present) { + if (ra_occasion_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ra_occasion_list, 1, 64, integer_packer(0, 511))); } if (ra_preamb_idx_present) { @@ -24435,6 +24554,7 @@ SRSASN_CODE bfr_csirs_res_s::pack(bit_ref& bref) const SRSASN_CODE bfr_csirs_res_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool ra_occasion_list_present; HANDLE_CODE(bref.unpack(ra_occasion_list_present, 1)); HANDLE_CODE(bref.unpack(ra_preamb_idx_present, 1)); @@ -24452,7 +24572,7 @@ void bfr_csirs_res_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("csi-RS", csi_rs); - if (ra_occasion_list_present) { + if (ra_occasion_list.size() > 0) { j.start_array("ra-OccasionList"); for (const auto& e1 : ra_occasion_list) { j.write_int(e1); @@ -26801,25 +26921,25 @@ void zp_csi_rs_res_set_s::to_json(json_writer& j) const SRSASN_CODE pdcch_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(ctrl_res_set_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(ctrl_res_set_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(search_spaces_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(search_spaces_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(ctrl_res_set_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ctrl_res_set_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(search_spaces_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(search_spaces_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(dl_preemption_present, 1)); HANDLE_CODE(bref.pack(tpc_pusch_present, 1)); HANDLE_CODE(bref.pack(tpc_pucch_present, 1)); HANDLE_CODE(bref.pack(tpc_srs_present, 1)); - if (ctrl_res_set_to_add_mod_list_present) { + if (ctrl_res_set_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ctrl_res_set_to_add_mod_list, 1, 3)); } - if (ctrl_res_set_to_release_list_present) { + if (ctrl_res_set_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ctrl_res_set_to_release_list, 1, 3, integer_packer(0, 11))); } - if (search_spaces_to_add_mod_list_present) { + if (search_spaces_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, search_spaces_to_add_mod_list, 1, 10)); } - if (search_spaces_to_release_list_present) { + if (search_spaces_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, search_spaces_to_release_list, 1, 10, integer_packer(0, 39))); } if (dl_preemption_present) { @@ -26840,9 +26960,13 @@ SRSASN_CODE pdcch_cfg_s::pack(bit_ref& bref) const SRSASN_CODE pdcch_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool ctrl_res_set_to_add_mod_list_present; HANDLE_CODE(bref.unpack(ctrl_res_set_to_add_mod_list_present, 1)); + bool ctrl_res_set_to_release_list_present; HANDLE_CODE(bref.unpack(ctrl_res_set_to_release_list_present, 1)); + bool search_spaces_to_add_mod_list_present; HANDLE_CODE(bref.unpack(search_spaces_to_add_mod_list_present, 1)); + bool search_spaces_to_release_list_present; HANDLE_CODE(bref.unpack(search_spaces_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(dl_preemption_present, 1)); HANDLE_CODE(bref.unpack(tpc_pusch_present, 1)); @@ -26879,28 +27003,28 @@ SRSASN_CODE pdcch_cfg_s::unpack(cbit_ref& bref) void pdcch_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (ctrl_res_set_to_add_mod_list_present) { + if (ctrl_res_set_to_add_mod_list.size() > 0) { j.start_array("controlResourceSetToAddModList"); for (const auto& e1 : ctrl_res_set_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (ctrl_res_set_to_release_list_present) { + if (ctrl_res_set_to_release_list.size() > 0) { j.start_array("controlResourceSetToReleaseList"); for (const auto& e1 : ctrl_res_set_to_release_list) { j.write_int(e1); } j.end_array(); } - if (search_spaces_to_add_mod_list_present) { + if (search_spaces_to_add_mod_list.size() > 0) { j.start_array("searchSpacesToAddModList"); for (const auto& e1 : search_spaces_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (search_spaces_to_release_list_present) { + if (search_spaces_to_release_list.size() > 0) { j.start_array("searchSpacesToReleaseList"); for (const auto& e1 : search_spaces_to_release_list) { j.write_int(e1); @@ -26933,23 +27057,23 @@ SRSASN_CODE pdsch_cfg_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(data_scrambling_id_pdsch_present, 1)); HANDLE_CODE(bref.pack(dmrs_dl_for_pdsch_map_type_a_present, 1)); HANDLE_CODE(bref.pack(dmrs_dl_for_pdsch_map_type_b_present, 1)); - HANDLE_CODE(bref.pack(tci_states_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(tci_states_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(tci_states_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(tci_states_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(vrb_to_prb_interleaver_present, 1)); HANDLE_CODE(bref.pack(pdsch_time_domain_alloc_list_present, 1)); HANDLE_CODE(bref.pack(pdsch_aggregation_factor_present, 1)); - HANDLE_CODE(bref.pack(rate_match_pattern_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(rate_match_pattern_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(rate_match_pattern_group1_present, 1)); - HANDLE_CODE(bref.pack(rate_match_pattern_group2_present, 1)); + HANDLE_CODE(bref.pack(rate_match_pattern_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(rate_match_pattern_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(rate_match_pattern_group1.size() > 0, 1)); + HANDLE_CODE(bref.pack(rate_match_pattern_group2.size() > 0, 1)); HANDLE_CODE(bref.pack(mcs_table_present, 1)); HANDLE_CODE(bref.pack(max_nrof_code_words_sched_by_dci_present, 1)); - HANDLE_CODE(bref.pack(zp_csi_rs_res_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(zp_csi_rs_res_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(aperiodic_zp_csi_rs_res_sets_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(aperiodic_zp_csi_rs_res_sets_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(sp_zp_csi_rs_res_sets_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(sp_zp_csi_rs_res_sets_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(zp_csi_rs_res_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(zp_csi_rs_res_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(aperiodic_zp_csi_rs_res_sets_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(aperiodic_zp_csi_rs_res_sets_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(sp_zp_csi_rs_res_sets_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(sp_zp_csi_rs_res_sets_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(p_zp_csi_rs_res_set_present, 1)); if (data_scrambling_id_pdsch_present) { @@ -26961,10 +27085,10 @@ SRSASN_CODE pdsch_cfg_s::pack(bit_ref& bref) const if (dmrs_dl_for_pdsch_map_type_b_present) { HANDLE_CODE(dmrs_dl_for_pdsch_map_type_b.pack(bref)); } - if (tci_states_to_add_mod_list_present) { + if (tci_states_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, tci_states_to_add_mod_list, 1, 128)); } - if (tci_states_to_release_list_present) { + if (tci_states_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, tci_states_to_release_list, 1, 128, integer_packer(0, 127))); } if (vrb_to_prb_interleaver_present) { @@ -26977,16 +27101,16 @@ SRSASN_CODE pdsch_cfg_s::pack(bit_ref& bref) const if (pdsch_aggregation_factor_present) { HANDLE_CODE(pdsch_aggregation_factor.pack(bref)); } - if (rate_match_pattern_to_add_mod_list_present) { + if (rate_match_pattern_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, rate_match_pattern_to_add_mod_list, 1, 4)); } - if (rate_match_pattern_to_release_list_present) { + if (rate_match_pattern_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, rate_match_pattern_to_release_list, 1, 4, integer_packer(0, 3))); } - if (rate_match_pattern_group1_present) { + if (rate_match_pattern_group1.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, rate_match_pattern_group1, 1, 8)); } - if (rate_match_pattern_group2_present) { + if (rate_match_pattern_group2.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, rate_match_pattern_group2, 1, 8)); } HANDLE_CODE(rbg_size.pack(bref)); @@ -26997,23 +27121,23 @@ SRSASN_CODE pdsch_cfg_s::pack(bit_ref& bref) const HANDLE_CODE(max_nrof_code_words_sched_by_dci.pack(bref)); } HANDLE_CODE(prb_bundling_type.pack(bref)); - if (zp_csi_rs_res_to_add_mod_list_present) { + if (zp_csi_rs_res_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, zp_csi_rs_res_to_add_mod_list, 1, 32)); } - if (zp_csi_rs_res_to_release_list_present) { + if (zp_csi_rs_res_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, zp_csi_rs_res_to_release_list, 1, 32, integer_packer(0, 31))); } - if (aperiodic_zp_csi_rs_res_sets_to_add_mod_list_present) { + if (aperiodic_zp_csi_rs_res_sets_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, aperiodic_zp_csi_rs_res_sets_to_add_mod_list, 1, 16)); } - if (aperiodic_zp_csi_rs_res_sets_to_release_list_present) { + if (aperiodic_zp_csi_rs_res_sets_to_release_list.size() > 0) { HANDLE_CODE( pack_dyn_seq_of(bref, aperiodic_zp_csi_rs_res_sets_to_release_list, 1, 16, integer_packer(0, 15))); } - if (sp_zp_csi_rs_res_sets_to_add_mod_list_present) { + if (sp_zp_csi_rs_res_sets_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, sp_zp_csi_rs_res_sets_to_add_mod_list, 1, 16)); } - if (sp_zp_csi_rs_res_sets_to_release_list_present) { + if (sp_zp_csi_rs_res_sets_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, sp_zp_csi_rs_res_sets_to_release_list, 1, 16, integer_packer(0, 15))); } if (p_zp_csi_rs_res_set_present) { @@ -27028,22 +27152,34 @@ SRSASN_CODE pdsch_cfg_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(data_scrambling_id_pdsch_present, 1)); HANDLE_CODE(bref.unpack(dmrs_dl_for_pdsch_map_type_a_present, 1)); HANDLE_CODE(bref.unpack(dmrs_dl_for_pdsch_map_type_b_present, 1)); + bool tci_states_to_add_mod_list_present; HANDLE_CODE(bref.unpack(tci_states_to_add_mod_list_present, 1)); + bool tci_states_to_release_list_present; HANDLE_CODE(bref.unpack(tci_states_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(vrb_to_prb_interleaver_present, 1)); HANDLE_CODE(bref.unpack(pdsch_time_domain_alloc_list_present, 1)); HANDLE_CODE(bref.unpack(pdsch_aggregation_factor_present, 1)); + bool rate_match_pattern_to_add_mod_list_present; HANDLE_CODE(bref.unpack(rate_match_pattern_to_add_mod_list_present, 1)); + bool rate_match_pattern_to_release_list_present; HANDLE_CODE(bref.unpack(rate_match_pattern_to_release_list_present, 1)); + bool rate_match_pattern_group1_present; HANDLE_CODE(bref.unpack(rate_match_pattern_group1_present, 1)); + bool rate_match_pattern_group2_present; HANDLE_CODE(bref.unpack(rate_match_pattern_group2_present, 1)); HANDLE_CODE(bref.unpack(mcs_table_present, 1)); HANDLE_CODE(bref.unpack(max_nrof_code_words_sched_by_dci_present, 1)); + bool zp_csi_rs_res_to_add_mod_list_present; HANDLE_CODE(bref.unpack(zp_csi_rs_res_to_add_mod_list_present, 1)); + bool zp_csi_rs_res_to_release_list_present; HANDLE_CODE(bref.unpack(zp_csi_rs_res_to_release_list_present, 1)); + bool aperiodic_zp_csi_rs_res_sets_to_add_mod_list_present; HANDLE_CODE(bref.unpack(aperiodic_zp_csi_rs_res_sets_to_add_mod_list_present, 1)); + bool aperiodic_zp_csi_rs_res_sets_to_release_list_present; HANDLE_CODE(bref.unpack(aperiodic_zp_csi_rs_res_sets_to_release_list_present, 1)); + bool sp_zp_csi_rs_res_sets_to_add_mod_list_present; HANDLE_CODE(bref.unpack(sp_zp_csi_rs_res_sets_to_add_mod_list_present, 1)); + bool sp_zp_csi_rs_res_sets_to_release_list_present; HANDLE_CODE(bref.unpack(sp_zp_csi_rs_res_sets_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(p_zp_csi_rs_res_set_present, 1)); @@ -27131,14 +27267,14 @@ void pdsch_cfg_s::to_json(json_writer& j) const j.write_fieldname("dmrs-DownlinkForPDSCH-MappingTypeB"); dmrs_dl_for_pdsch_map_type_b.to_json(j); } - if (tci_states_to_add_mod_list_present) { + if (tci_states_to_add_mod_list.size() > 0) { j.start_array("tci-StatesToAddModList"); for (const auto& e1 : tci_states_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (tci_states_to_release_list_present) { + if (tci_states_to_release_list.size() > 0) { j.start_array("tci-StatesToReleaseList"); for (const auto& e1 : tci_states_to_release_list) { j.write_int(e1); @@ -27156,28 +27292,28 @@ void pdsch_cfg_s::to_json(json_writer& j) const if (pdsch_aggregation_factor_present) { j.write_str("pdsch-AggregationFactor", pdsch_aggregation_factor.to_string()); } - if (rate_match_pattern_to_add_mod_list_present) { + if (rate_match_pattern_to_add_mod_list.size() > 0) { j.start_array("rateMatchPatternToAddModList"); for (const auto& e1 : rate_match_pattern_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (rate_match_pattern_to_release_list_present) { + if (rate_match_pattern_to_release_list.size() > 0) { j.start_array("rateMatchPatternToReleaseList"); for (const auto& e1 : rate_match_pattern_to_release_list) { j.write_int(e1); } j.end_array(); } - if (rate_match_pattern_group1_present) { + if (rate_match_pattern_group1.size() > 0) { j.start_array("rateMatchPatternGroup1"); for (const auto& e1 : rate_match_pattern_group1) { e1.to_json(j); } j.end_array(); } - if (rate_match_pattern_group2_present) { + if (rate_match_pattern_group2.size() > 0) { j.start_array("rateMatchPatternGroup2"); for (const auto& e1 : rate_match_pattern_group2) { e1.to_json(j); @@ -27193,42 +27329,42 @@ void pdsch_cfg_s::to_json(json_writer& j) const } j.write_fieldname("prb-BundlingType"); prb_bundling_type.to_json(j); - if (zp_csi_rs_res_to_add_mod_list_present) { + if (zp_csi_rs_res_to_add_mod_list.size() > 0) { j.start_array("zp-CSI-RS-ResourceToAddModList"); for (const auto& e1 : zp_csi_rs_res_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (zp_csi_rs_res_to_release_list_present) { + if (zp_csi_rs_res_to_release_list.size() > 0) { j.start_array("zp-CSI-RS-ResourceToReleaseList"); for (const auto& e1 : zp_csi_rs_res_to_release_list) { j.write_int(e1); } j.end_array(); } - if (aperiodic_zp_csi_rs_res_sets_to_add_mod_list_present) { + if (aperiodic_zp_csi_rs_res_sets_to_add_mod_list.size() > 0) { j.start_array("aperiodic-ZP-CSI-RS-ResourceSetsToAddModList"); for (const auto& e1 : aperiodic_zp_csi_rs_res_sets_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (aperiodic_zp_csi_rs_res_sets_to_release_list_present) { + if (aperiodic_zp_csi_rs_res_sets_to_release_list.size() > 0) { j.start_array("aperiodic-ZP-CSI-RS-ResourceSetsToReleaseList"); for (const auto& e1 : aperiodic_zp_csi_rs_res_sets_to_release_list) { j.write_int(e1); } j.end_array(); } - if (sp_zp_csi_rs_res_sets_to_add_mod_list_present) { + if (sp_zp_csi_rs_res_sets_to_add_mod_list.size() > 0) { j.start_array("sp-ZP-CSI-RS-ResourceSetsToAddModList"); for (const auto& e1 : sp_zp_csi_rs_res_sets_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (sp_zp_csi_rs_res_sets_to_release_list_present) { + if (sp_zp_csi_rs_res_sets_to_release_list.size() > 0) { j.start_array("sp-ZP-CSI-RS-ResourceSetsToReleaseList"); for (const auto& e1 : sp_zp_csi_rs_res_sets_to_release_list) { j.write_int(e1); @@ -27510,15 +27646,15 @@ const char* pdsch_cfg_s::prb_bundling_type_c_::types_opts::to_string() const SRSASN_CODE radio_link_monitoring_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(fail_detection_res_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(fail_detection_res_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(fail_detection_res_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(fail_detection_res_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(beam_fail_instance_max_count_present, 1)); HANDLE_CODE(bref.pack(beam_fail_detection_timer_present, 1)); - if (fail_detection_res_to_add_mod_list_present) { + if (fail_detection_res_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, fail_detection_res_to_add_mod_list, 1, 10)); } - if (fail_detection_res_to_release_list_present) { + if (fail_detection_res_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, fail_detection_res_to_release_list, 1, 10, integer_packer(0, 9))); } if (beam_fail_instance_max_count_present) { @@ -27533,7 +27669,9 @@ SRSASN_CODE radio_link_monitoring_cfg_s::pack(bit_ref& bref) const SRSASN_CODE radio_link_monitoring_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool fail_detection_res_to_add_mod_list_present; HANDLE_CODE(bref.unpack(fail_detection_res_to_add_mod_list_present, 1)); + bool fail_detection_res_to_release_list_present; HANDLE_CODE(bref.unpack(fail_detection_res_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(beam_fail_instance_max_count_present, 1)); HANDLE_CODE(bref.unpack(beam_fail_detection_timer_present, 1)); @@ -27556,14 +27694,14 @@ SRSASN_CODE radio_link_monitoring_cfg_s::unpack(cbit_ref& bref) void radio_link_monitoring_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (fail_detection_res_to_add_mod_list_present) { + if (fail_detection_res_to_add_mod_list.size() > 0) { j.start_array("failureDetectionResourcesToAddModList"); for (const auto& e1 : fail_detection_res_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (fail_detection_res_to_release_list_present) { + if (fail_detection_res_to_release_list.size() > 0) { j.start_array("failureDetectionResourcesToReleaseList"); for (const auto& e1 : fail_detection_res_to_release_list) { j.write_int(e1); @@ -29721,8 +29859,8 @@ SRSASN_CODE pucch_pwr_ctrl_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(delta_f_pucch_f2_present, 1)); HANDLE_CODE(bref.pack(delta_f_pucch_f3_present, 1)); HANDLE_CODE(bref.pack(delta_f_pucch_f4_present, 1)); - HANDLE_CODE(bref.pack(p0_set_present, 1)); - HANDLE_CODE(bref.pack(pathloss_ref_rss_present, 1)); + HANDLE_CODE(bref.pack(p0_set.size() > 0, 1)); + HANDLE_CODE(bref.pack(pathloss_ref_rss.size() > 0, 1)); HANDLE_CODE(bref.pack(two_pucch_pc_adjustment_states_present, 1)); if (delta_f_pucch_f0_present) { @@ -29740,10 +29878,10 @@ SRSASN_CODE pucch_pwr_ctrl_s::pack(bit_ref& bref) const if (delta_f_pucch_f4_present) { HANDLE_CODE(pack_integer(bref, delta_f_pucch_f4, (int8_t)-16, (int8_t)15)); } - if (p0_set_present) { + if (p0_set.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, p0_set, 1, 8)); } - if (pathloss_ref_rss_present) { + if (pathloss_ref_rss.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, pathloss_ref_rss, 1, 4)); } @@ -29757,7 +29895,9 @@ SRSASN_CODE pucch_pwr_ctrl_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(delta_f_pucch_f2_present, 1)); HANDLE_CODE(bref.unpack(delta_f_pucch_f3_present, 1)); HANDLE_CODE(bref.unpack(delta_f_pucch_f4_present, 1)); + bool p0_set_present; HANDLE_CODE(bref.unpack(p0_set_present, 1)); + bool pathloss_ref_rss_present; HANDLE_CODE(bref.unpack(pathloss_ref_rss_present, 1)); HANDLE_CODE(bref.unpack(two_pucch_pc_adjustment_states_present, 1)); @@ -29803,14 +29943,14 @@ void pucch_pwr_ctrl_s::to_json(json_writer& j) const if (delta_f_pucch_f4_present) { j.write_int("deltaF-PUCCH-f4", delta_f_pucch_f4); } - if (p0_set_present) { + if (p0_set.size() > 0) { j.start_array("p0-Set"); for (const auto& e1 : p0_set) { e1.to_json(j); } j.end_array(); } - if (pathloss_ref_rss_present) { + if (pathloss_ref_rss.size() > 0) { j.start_array("pathlossReferenceRSs"); for (const auto& e1 : pathloss_ref_rss) { e1.to_json(j); @@ -30350,13 +30490,13 @@ SRSASN_CODE pusch_pwr_ctrl_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(tpc_accumulation_present, 1)); HANDLE_CODE(bref.pack(msg3_alpha_present, 1)); HANDLE_CODE(bref.pack(p0_nominal_without_grant_present, 1)); - HANDLE_CODE(bref.pack(p0_alpha_sets_present, 1)); - HANDLE_CODE(bref.pack(pathloss_ref_rs_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(pathloss_ref_rs_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(p0_alpha_sets.size() > 0, 1)); + HANDLE_CODE(bref.pack(pathloss_ref_rs_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(pathloss_ref_rs_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(two_pusch_pc_adjustment_states_present, 1)); HANDLE_CODE(bref.pack(delta_mcs_present, 1)); - HANDLE_CODE(bref.pack(sri_pusch_map_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(sri_pusch_map_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(sri_pusch_map_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(sri_pusch_map_to_release_list.size() > 0, 1)); if (msg3_alpha_present) { HANDLE_CODE(msg3_alpha.pack(bref)); @@ -30364,19 +30504,19 @@ SRSASN_CODE pusch_pwr_ctrl_s::pack(bit_ref& bref) const if (p0_nominal_without_grant_present) { HANDLE_CODE(pack_integer(bref, p0_nominal_without_grant, (int16_t)-202, (int16_t)24)); } - if (p0_alpha_sets_present) { + if (p0_alpha_sets.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, p0_alpha_sets, 1, 30)); } - if (pathloss_ref_rs_to_add_mod_list_present) { + if (pathloss_ref_rs_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, pathloss_ref_rs_to_add_mod_list, 1, 4)); } - if (pathloss_ref_rs_to_release_list_present) { + if (pathloss_ref_rs_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, pathloss_ref_rs_to_release_list, 1, 4, integer_packer(0, 3))); } - if (sri_pusch_map_to_add_mod_list_present) { + if (sri_pusch_map_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, sri_pusch_map_to_add_mod_list, 1, 16)); } - if (sri_pusch_map_to_release_list_present) { + if (sri_pusch_map_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, sri_pusch_map_to_release_list, 1, 16, integer_packer(0, 15))); } @@ -30387,12 +30527,17 @@ SRSASN_CODE pusch_pwr_ctrl_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(tpc_accumulation_present, 1)); HANDLE_CODE(bref.unpack(msg3_alpha_present, 1)); HANDLE_CODE(bref.unpack(p0_nominal_without_grant_present, 1)); + bool p0_alpha_sets_present; HANDLE_CODE(bref.unpack(p0_alpha_sets_present, 1)); + bool pathloss_ref_rs_to_add_mod_list_present; HANDLE_CODE(bref.unpack(pathloss_ref_rs_to_add_mod_list_present, 1)); + bool pathloss_ref_rs_to_release_list_present; HANDLE_CODE(bref.unpack(pathloss_ref_rs_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(two_pusch_pc_adjustment_states_present, 1)); HANDLE_CODE(bref.unpack(delta_mcs_present, 1)); + bool sri_pusch_map_to_add_mod_list_present; HANDLE_CODE(bref.unpack(sri_pusch_map_to_add_mod_list_present, 1)); + bool sri_pusch_map_to_release_list_present; HANDLE_CODE(bref.unpack(sri_pusch_map_to_release_list_present, 1)); if (msg3_alpha_present) { @@ -30431,21 +30576,21 @@ void pusch_pwr_ctrl_s::to_json(json_writer& j) const if (p0_nominal_without_grant_present) { j.write_int("p0-NominalWithoutGrant", p0_nominal_without_grant); } - if (p0_alpha_sets_present) { + if (p0_alpha_sets.size() > 0) { j.start_array("p0-AlphaSets"); for (const auto& e1 : p0_alpha_sets) { e1.to_json(j); } j.end_array(); } - if (pathloss_ref_rs_to_add_mod_list_present) { + if (pathloss_ref_rs_to_add_mod_list.size() > 0) { j.start_array("pathlossReferenceRSToAddModList"); for (const auto& e1 : pathloss_ref_rs_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (pathloss_ref_rs_to_release_list_present) { + if (pathloss_ref_rs_to_release_list.size() > 0) { j.start_array("pathlossReferenceRSToReleaseList"); for (const auto& e1 : pathloss_ref_rs_to_release_list) { j.write_int(e1); @@ -30458,14 +30603,14 @@ void pusch_pwr_ctrl_s::to_json(json_writer& j) const if (delta_mcs_present) { j.write_str("deltaMCS", "enabled"); } - if (sri_pusch_map_to_add_mod_list_present) { + if (sri_pusch_map_to_add_mod_list.size() > 0) { j.start_array("sri-PUSCH-MappingToAddModList"); for (const auto& e1 : sri_pusch_map_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (sri_pusch_map_to_release_list_present) { + if (sri_pusch_map_to_release_list.size() > 0) { j.start_array("sri-PUSCH-MappingToReleaseList"); for (const auto& e1 : sri_pusch_map_to_release_list) { j.write_int(e1); @@ -31003,14 +31148,14 @@ const char* srs_res_s::res_type_c_::types_opts::to_string() const SRSASN_CODE srs_res_set_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(srs_res_id_list_present, 1)); + HANDLE_CODE(bref.pack(srs_res_id_list.size() > 0, 1)); HANDLE_CODE(bref.pack(alpha_present, 1)); HANDLE_CODE(bref.pack(p0_present, 1)); HANDLE_CODE(bref.pack(pathloss_ref_rs_present, 1)); HANDLE_CODE(bref.pack(srs_pwr_ctrl_adjustment_states_present, 1)); HANDLE_CODE(pack_integer(bref, srs_res_set_id, (uint8_t)0u, (uint8_t)15u)); - if (srs_res_id_list_present) { + if (srs_res_id_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, srs_res_id_list, 1, 16, integer_packer(0, 63))); } HANDLE_CODE(res_type.pack(bref)); @@ -31033,6 +31178,7 @@ SRSASN_CODE srs_res_set_s::pack(bit_ref& bref) const SRSASN_CODE srs_res_set_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool srs_res_id_list_present; HANDLE_CODE(bref.unpack(srs_res_id_list_present, 1)); HANDLE_CODE(bref.unpack(alpha_present, 1)); HANDLE_CODE(bref.unpack(p0_present, 1)); @@ -31064,7 +31210,7 @@ void srs_res_set_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("srs-ResourceSetId", srs_res_set_id); - if (srs_res_id_list_present) { + if (srs_res_id_list.size() > 0) { j.start_array("srs-ResourceIdList"); for (const auto& e1 : srs_res_id_list) { j.write_int(e1); @@ -32087,7 +32233,7 @@ SRSASN_CODE beam_fail_recovery_cfg_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(root_seq_idx_bfr_present, 1)); HANDLE_CODE(bref.pack(rach_cfg_bfr_present, 1)); HANDLE_CODE(bref.pack(rsrp_thres_ssb_present, 1)); - HANDLE_CODE(bref.pack(candidate_beam_rs_list_present, 1)); + HANDLE_CODE(bref.pack(candidate_beam_rs_list.size() > 0, 1)); HANDLE_CODE(bref.pack(ssb_per_rach_occasion_present, 1)); HANDLE_CODE(bref.pack(ra_ssb_occasion_mask_idx_present, 1)); HANDLE_CODE(bref.pack(recovery_search_space_id_present, 1)); @@ -32103,7 +32249,7 @@ SRSASN_CODE beam_fail_recovery_cfg_s::pack(bit_ref& bref) const if (rsrp_thres_ssb_present) { HANDLE_CODE(pack_integer(bref, rsrp_thres_ssb, (uint8_t)0u, (uint8_t)127u)); } - if (candidate_beam_rs_list_present) { + if (candidate_beam_rs_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, candidate_beam_rs_list, 1, 16)); } if (ssb_per_rach_occasion_present) { @@ -32144,6 +32290,7 @@ SRSASN_CODE beam_fail_recovery_cfg_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(root_seq_idx_bfr_present, 1)); HANDLE_CODE(bref.unpack(rach_cfg_bfr_present, 1)); HANDLE_CODE(bref.unpack(rsrp_thres_ssb_present, 1)); + bool candidate_beam_rs_list_present; HANDLE_CODE(bref.unpack(candidate_beam_rs_list_present, 1)); HANDLE_CODE(bref.unpack(ssb_per_rach_occasion_present, 1)); HANDLE_CODE(bref.unpack(ra_ssb_occasion_mask_idx_present, 1)); @@ -32207,7 +32354,7 @@ void beam_fail_recovery_cfg_s::to_json(json_writer& j) const if (rsrp_thres_ssb_present) { j.write_int("rsrp-ThresholdSSB", rsrp_thres_ssb); } - if (candidate_beam_rs_list_present) { + if (candidate_beam_rs_list.size() > 0) { j.start_array("candidateBeamRSList"); for (const auto& e1 : candidate_beam_rs_list) { e1.to_json(j); @@ -32552,32 +32699,32 @@ const char* cfgured_grant_cfg_s::periodicity_opts::to_string() const SRSASN_CODE pucch_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(res_set_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(res_set_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(res_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(res_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(res_set_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(res_set_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(res_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(res_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(format1_present, 1)); HANDLE_CODE(bref.pack(format2_present, 1)); HANDLE_CODE(bref.pack(format3_present, 1)); HANDLE_CODE(bref.pack(format4_present, 1)); - HANDLE_CODE(bref.pack(sched_request_res_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(sched_request_res_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(multi_csi_pucch_res_list_present, 1)); - HANDLE_CODE(bref.pack(dl_data_to_ul_ack_present, 1)); - HANDLE_CODE(bref.pack(spatial_relation_info_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(spatial_relation_info_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(sched_request_res_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(sched_request_res_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(multi_csi_pucch_res_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(dl_data_to_ul_ack.size() > 0, 1)); + HANDLE_CODE(bref.pack(spatial_relation_info_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(spatial_relation_info_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(pucch_pwr_ctrl_present, 1)); - if (res_set_to_add_mod_list_present) { + if (res_set_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, res_set_to_add_mod_list, 1, 4)); } - if (res_set_to_release_list_present) { + if (res_set_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, res_set_to_release_list, 1, 4, integer_packer(0, 3))); } - if (res_to_add_mod_list_present) { + if (res_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, res_to_add_mod_list, 1, 128)); } - if (res_to_release_list_present) { + if (res_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, res_to_release_list, 1, 128, integer_packer(0, 127))); } if (format1_present) { @@ -32592,22 +32739,22 @@ SRSASN_CODE pucch_cfg_s::pack(bit_ref& bref) const if (format4_present) { HANDLE_CODE(format4.pack(bref)); } - if (sched_request_res_to_add_mod_list_present) { + if (sched_request_res_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, sched_request_res_to_add_mod_list, 1, 8)); } - if (sched_request_res_to_release_list_present) { + if (sched_request_res_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, sched_request_res_to_release_list, 1, 8, integer_packer(1, 8))); } - if (multi_csi_pucch_res_list_present) { + if (multi_csi_pucch_res_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, multi_csi_pucch_res_list, 1, 2, integer_packer(0, 127))); } - if (dl_data_to_ul_ack_present) { + if (dl_data_to_ul_ack.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, dl_data_to_ul_ack, 1, 8, integer_packer(0, 15))); } - if (spatial_relation_info_to_add_mod_list_present) { + if (spatial_relation_info_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, spatial_relation_info_to_add_mod_list, 1, 8)); } - if (spatial_relation_info_to_release_list_present) { + if (spatial_relation_info_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, spatial_relation_info_to_release_list, 1, 8, integer_packer(1, 8))); } if (pucch_pwr_ctrl_present) { @@ -32619,19 +32766,29 @@ SRSASN_CODE pucch_cfg_s::pack(bit_ref& bref) const SRSASN_CODE pucch_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool res_set_to_add_mod_list_present; HANDLE_CODE(bref.unpack(res_set_to_add_mod_list_present, 1)); + bool res_set_to_release_list_present; HANDLE_CODE(bref.unpack(res_set_to_release_list_present, 1)); + bool res_to_add_mod_list_present; HANDLE_CODE(bref.unpack(res_to_add_mod_list_present, 1)); + bool res_to_release_list_present; HANDLE_CODE(bref.unpack(res_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(format1_present, 1)); HANDLE_CODE(bref.unpack(format2_present, 1)); HANDLE_CODE(bref.unpack(format3_present, 1)); HANDLE_CODE(bref.unpack(format4_present, 1)); + bool sched_request_res_to_add_mod_list_present; HANDLE_CODE(bref.unpack(sched_request_res_to_add_mod_list_present, 1)); + bool sched_request_res_to_release_list_present; HANDLE_CODE(bref.unpack(sched_request_res_to_release_list_present, 1)); + bool multi_csi_pucch_res_list_present; HANDLE_CODE(bref.unpack(multi_csi_pucch_res_list_present, 1)); + bool dl_data_to_ul_ack_present; HANDLE_CODE(bref.unpack(dl_data_to_ul_ack_present, 1)); + bool spatial_relation_info_to_add_mod_list_present; HANDLE_CODE(bref.unpack(spatial_relation_info_to_add_mod_list_present, 1)); + bool spatial_relation_info_to_release_list_present; HANDLE_CODE(bref.unpack(spatial_relation_info_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(pucch_pwr_ctrl_present, 1)); @@ -32686,28 +32843,28 @@ SRSASN_CODE pucch_cfg_s::unpack(cbit_ref& bref) void pucch_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (res_set_to_add_mod_list_present) { + if (res_set_to_add_mod_list.size() > 0) { j.start_array("resourceSetToAddModList"); for (const auto& e1 : res_set_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (res_set_to_release_list_present) { + if (res_set_to_release_list.size() > 0) { j.start_array("resourceSetToReleaseList"); for (const auto& e1 : res_set_to_release_list) { j.write_int(e1); } j.end_array(); } - if (res_to_add_mod_list_present) { + if (res_to_add_mod_list.size() > 0) { j.start_array("resourceToAddModList"); for (const auto& e1 : res_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (res_to_release_list_present) { + if (res_to_release_list.size() > 0) { j.start_array("resourceToReleaseList"); for (const auto& e1 : res_to_release_list) { j.write_int(e1); @@ -32730,42 +32887,42 @@ void pucch_cfg_s::to_json(json_writer& j) const j.write_fieldname("format4"); format4.to_json(j); } - if (sched_request_res_to_add_mod_list_present) { + if (sched_request_res_to_add_mod_list.size() > 0) { j.start_array("schedulingRequestResourceToAddModList"); for (const auto& e1 : sched_request_res_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (sched_request_res_to_release_list_present) { + if (sched_request_res_to_release_list.size() > 0) { j.start_array("schedulingRequestResourceToReleaseList"); for (const auto& e1 : sched_request_res_to_release_list) { j.write_int(e1); } j.end_array(); } - if (multi_csi_pucch_res_list_present) { + if (multi_csi_pucch_res_list.size() > 0) { j.start_array("multi-CSI-PUCCH-ResourceList"); for (const auto& e1 : multi_csi_pucch_res_list) { j.write_int(e1); } j.end_array(); } - if (dl_data_to_ul_ack_present) { + if (dl_data_to_ul_ack.size() > 0) { j.start_array("dl-DataToUL-ACK"); for (const auto& e1 : dl_data_to_ul_ack) { j.write_int(e1); } j.end_array(); } - if (spatial_relation_info_to_add_mod_list_present) { + if (spatial_relation_info_to_add_mod_list.size() > 0) { j.start_array("spatialRelationInfoToAddModList"); for (const auto& e1 : spatial_relation_info_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (spatial_relation_info_to_release_list_present) { + if (spatial_relation_info_to_release_list.size() > 0) { j.start_array("spatialRelationInfoToReleaseList"); for (const auto& e1 : spatial_relation_info_to_release_list) { j.write_int(e1); @@ -32789,7 +32946,7 @@ SRSASN_CODE pusch_cfg_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(dmrs_ul_for_pusch_map_type_b_present, 1)); HANDLE_CODE(bref.pack(pusch_pwr_ctrl_present, 1)); HANDLE_CODE(bref.pack(freq_hop_present, 1)); - HANDLE_CODE(bref.pack(freq_hop_offset_lists_present, 1)); + HANDLE_CODE(bref.pack(freq_hop_offset_lists.size() > 0, 1)); HANDLE_CODE(bref.pack(pusch_time_domain_alloc_list_present, 1)); HANDLE_CODE(bref.pack(pusch_aggregation_factor_present, 1)); HANDLE_CODE(bref.pack(mcs_table_present, 1)); @@ -32819,7 +32976,7 @@ SRSASN_CODE pusch_cfg_s::pack(bit_ref& bref) const if (freq_hop_present) { HANDLE_CODE(freq_hop.pack(bref)); } - if (freq_hop_offset_lists_present) { + if (freq_hop_offset_lists.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, freq_hop_offset_lists, 1, 4, integer_packer(1, 274))); } HANDLE_CODE(res_alloc.pack(bref)); @@ -32859,6 +33016,7 @@ SRSASN_CODE pusch_cfg_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(dmrs_ul_for_pusch_map_type_b_present, 1)); HANDLE_CODE(bref.unpack(pusch_pwr_ctrl_present, 1)); HANDLE_CODE(bref.unpack(freq_hop_present, 1)); + bool freq_hop_offset_lists_present; HANDLE_CODE(bref.unpack(freq_hop_offset_lists_present, 1)); HANDLE_CODE(bref.unpack(pusch_time_domain_alloc_list_present, 1)); HANDLE_CODE(bref.unpack(pusch_aggregation_factor_present, 1)); @@ -32944,7 +33102,7 @@ void pusch_cfg_s::to_json(json_writer& j) const if (freq_hop_present) { j.write_str("frequencyHopping", freq_hop.to_string()); } - if (freq_hop_offset_lists_present) { + if (freq_hop_offset_lists.size() > 0) { j.start_array("frequencyHoppingOffsetLists"); for (const auto& e1 : freq_hop_offset_lists) { j.write_int(e1); @@ -33059,22 +33217,22 @@ const char* pusch_cfg_s::codebook_subset_opts::to_string() const SRSASN_CODE srs_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(srs_res_set_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(srs_res_set_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(srs_res_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(srs_res_to_add_mod_list_present, 1)); + HANDLE_CODE(bref.pack(srs_res_set_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(srs_res_set_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(srs_res_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(srs_res_to_add_mod_list.size() > 0, 1)); HANDLE_CODE(bref.pack(tpc_accumulation_present, 1)); - if (srs_res_set_to_release_list_present) { + if (srs_res_set_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, srs_res_set_to_release_list, 1, 16, integer_packer(0, 15))); } - if (srs_res_set_to_add_mod_list_present) { + if (srs_res_set_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, srs_res_set_to_add_mod_list, 1, 16)); } - if (srs_res_to_release_list_present) { + if (srs_res_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, srs_res_to_release_list, 1, 64, integer_packer(0, 63))); } - if (srs_res_to_add_mod_list_present) { + if (srs_res_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, srs_res_to_add_mod_list, 1, 64)); } @@ -33083,9 +33241,13 @@ SRSASN_CODE srs_cfg_s::pack(bit_ref& bref) const SRSASN_CODE srs_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool srs_res_set_to_release_list_present; HANDLE_CODE(bref.unpack(srs_res_set_to_release_list_present, 1)); + bool srs_res_set_to_add_mod_list_present; HANDLE_CODE(bref.unpack(srs_res_set_to_add_mod_list_present, 1)); + bool srs_res_to_release_list_present; HANDLE_CODE(bref.unpack(srs_res_to_release_list_present, 1)); + bool srs_res_to_add_mod_list_present; HANDLE_CODE(bref.unpack(srs_res_to_add_mod_list_present, 1)); HANDLE_CODE(bref.unpack(tpc_accumulation_present, 1)); @@ -33107,28 +33269,28 @@ SRSASN_CODE srs_cfg_s::unpack(cbit_ref& bref) void srs_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (srs_res_set_to_release_list_present) { + if (srs_res_set_to_release_list.size() > 0) { j.start_array("srs-ResourceSetToReleaseList"); for (const auto& e1 : srs_res_set_to_release_list) { j.write_int(e1); } j.end_array(); } - if (srs_res_set_to_add_mod_list_present) { + if (srs_res_set_to_add_mod_list.size() > 0) { j.start_array("srs-ResourceSetToAddModList"); for (const auto& e1 : srs_res_set_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (srs_res_to_release_list_present) { + if (srs_res_to_release_list.size() > 0) { j.start_array("srs-ResourceToReleaseList"); for (const auto& e1 : srs_res_to_release_list) { j.write_int(e1); } j.end_array(); } - if (srs_res_to_add_mod_list_present) { + if (srs_res_to_add_mod_list.size() > 0) { j.start_array("srs-ResourceToAddModList"); for (const auto& e1 : srs_res_to_add_mod_list) { e1.to_json(j); @@ -37768,7 +37930,7 @@ void csi_associated_report_cfg_info_s::res_for_ch_c_::to_json(json_writer& j) co j.write_fieldname("nzp-CSI-RS"); j.start_obj(); j.write_int("resourceSet", c.get().res_set); - if (c.get().qcl_info_present) { + if (c.get().qcl_info.size() > 0) { j.start_array("qcl-info"); for (const auto& e1 : c.get().qcl_info) { j.write_int(e1); @@ -37790,9 +37952,9 @@ SRSASN_CODE csi_associated_report_cfg_info_s::res_for_ch_c_::pack(bit_ref& bref) type_.pack(bref); switch (type_) { case types::nzp_csi_rs: - HANDLE_CODE(bref.pack(c.get().qcl_info_present, 1)); + HANDLE_CODE(bref.pack(c.get().qcl_info.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, c.get().res_set, (uint8_t)1u, (uint8_t)16u)); - if (c.get().qcl_info_present) { + if (c.get().qcl_info.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, c.get().qcl_info, 1, 16, integer_packer(0, 127))); } break; @@ -37812,9 +37974,10 @@ SRSASN_CODE csi_associated_report_cfg_info_s::res_for_ch_c_::unpack(cbit_ref& br set(e); switch (type_) { case types::nzp_csi_rs: - HANDLE_CODE(bref.unpack(c.get().qcl_info_present, 1)); + bool qcl_info_present; + HANDLE_CODE(bref.unpack(qcl_info_present, 1)); HANDLE_CODE(unpack_integer(c.get().res_set, bref, (uint8_t)1u, (uint8_t)16u)); - if (c.get().qcl_info_present) { + if (qcl_info_present) { HANDLE_CODE(unpack_dyn_seq_of(c.get().qcl_info, bref, 1, 16, integer_packer(0, 127))); } break; @@ -40893,7 +41056,7 @@ SRSASN_CODE csi_report_cfg_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(codebook_cfg_present, 1)); HANDLE_CODE(bref.pack(dummy_present, 1)); HANDLE_CODE(bref.pack(cqi_table_present, 1)); - HANDLE_CODE(bref.pack(non_pmi_port_ind_present, 1)); + HANDLE_CODE(bref.pack(non_pmi_port_ind.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, report_cfg_id, (uint8_t)0u, (uint8_t)47u)); if (carrier_present) { @@ -40935,7 +41098,7 @@ SRSASN_CODE csi_report_cfg_s::pack(bit_ref& bref) const HANDLE_CODE(cqi_table.pack(bref)); } HANDLE_CODE(subband_size.pack(bref)); - if (non_pmi_port_ind_present) { + if (non_pmi_port_ind.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, non_pmi_port_ind, 1, 128)); } @@ -40965,6 +41128,7 @@ SRSASN_CODE csi_report_cfg_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(codebook_cfg_present, 1)); HANDLE_CODE(bref.unpack(dummy_present, 1)); HANDLE_CODE(bref.unpack(cqi_table_present, 1)); + bool non_pmi_port_ind_present; HANDLE_CODE(bref.unpack(non_pmi_port_ind_present, 1)); HANDLE_CODE(unpack_integer(report_cfg_id, bref, (uint8_t)0u, (uint8_t)47u)); @@ -41076,7 +41240,7 @@ void csi_report_cfg_s::to_json(json_writer& j) const j.write_str("cqi-Table", cqi_table.to_string()); } j.write_str("subbandSize", subband_size.to_string()); - if (non_pmi_port_ind_present) { + if (non_pmi_port_ind.size() > 0) { j.start_array("non-PMI-PortIndication"); for (const auto& e1 : non_pmi_port_ind) { e1.to_json(j); @@ -42325,7 +42489,7 @@ void csi_res_cfg_s::csi_rs_res_set_list_c_::to_json(json_writer& j) const case types::nzp_csi_rs_ssb: j.write_fieldname("nzp-CSI-RS-SSB"); j.start_obj(); - if (c.get().nzp_csi_rs_res_set_list_present) { + if (c.get().nzp_csi_rs_res_set_list.size() > 0) { j.start_array("nzp-CSI-RS-ResourceSetList"); for (const auto& e1 : c.get().nzp_csi_rs_res_set_list) { j.write_int(e1); @@ -42358,9 +42522,9 @@ SRSASN_CODE csi_res_cfg_s::csi_rs_res_set_list_c_::pack(bit_ref& bref) const type_.pack(bref); switch (type_) { case types::nzp_csi_rs_ssb: - HANDLE_CODE(bref.pack(c.get().nzp_csi_rs_res_set_list_present, 1)); + HANDLE_CODE(bref.pack(c.get().nzp_csi_rs_res_set_list.size() > 0, 1)); HANDLE_CODE(bref.pack(c.get().csi_ssb_res_set_list_present, 1)); - if (c.get().nzp_csi_rs_res_set_list_present) { + if (c.get().nzp_csi_rs_res_set_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of( bref, c.get().nzp_csi_rs_res_set_list, 1, 16, integer_packer(0, 63))); } @@ -42387,9 +42551,10 @@ SRSASN_CODE csi_res_cfg_s::csi_rs_res_set_list_c_::unpack(cbit_ref& bref) set(e); switch (type_) { case types::nzp_csi_rs_ssb: - HANDLE_CODE(bref.unpack(c.get().nzp_csi_rs_res_set_list_present, 1)); + bool nzp_csi_rs_res_set_list_present; + HANDLE_CODE(bref.unpack(nzp_csi_rs_res_set_list_present, 1)); HANDLE_CODE(bref.unpack(c.get().csi_ssb_res_set_list_present, 1)); - if (c.get().nzp_csi_rs_res_set_list_present) { + if (nzp_csi_rs_res_set_list_present) { HANDLE_CODE(unpack_dyn_seq_of( c.get().nzp_csi_rs_res_set_list, bref, 1, 16, integer_packer(0, 63))); } @@ -42598,64 +42763,64 @@ const char* nzp_csi_rs_res_set_s::repeat_opts::to_string() const SRSASN_CODE csi_meas_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(nzp_csi_rs_res_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(nzp_csi_rs_res_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(nzp_csi_rs_res_set_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(nzp_csi_rs_res_set_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(csi_im_res_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(csi_im_res_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(csi_im_res_set_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(csi_im_res_set_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(csi_ssb_res_set_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(csi_ssb_res_set_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(csi_res_cfg_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(csi_res_cfg_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(csi_report_cfg_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(csi_report_cfg_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(nzp_csi_rs_res_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(nzp_csi_rs_res_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(nzp_csi_rs_res_set_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(nzp_csi_rs_res_set_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(csi_im_res_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(csi_im_res_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(csi_im_res_set_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(csi_im_res_set_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(csi_ssb_res_set_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(csi_ssb_res_set_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(csi_res_cfg_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(csi_res_cfg_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(csi_report_cfg_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(csi_report_cfg_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(report_trigger_size_present, 1)); HANDLE_CODE(bref.pack(aperiodic_trigger_state_list_present, 1)); HANDLE_CODE(bref.pack(semi_persistent_on_pusch_trigger_state_list_present, 1)); - if (nzp_csi_rs_res_to_add_mod_list_present) { + if (nzp_csi_rs_res_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, nzp_csi_rs_res_to_add_mod_list, 1, 192)); } - if (nzp_csi_rs_res_to_release_list_present) { + if (nzp_csi_rs_res_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, nzp_csi_rs_res_to_release_list, 1, 192, integer_packer(0, 191))); } - if (nzp_csi_rs_res_set_to_add_mod_list_present) { + if (nzp_csi_rs_res_set_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, nzp_csi_rs_res_set_to_add_mod_list, 1, 64)); } - if (nzp_csi_rs_res_set_to_release_list_present) { + if (nzp_csi_rs_res_set_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, nzp_csi_rs_res_set_to_release_list, 1, 64, integer_packer(0, 63))); } - if (csi_im_res_to_add_mod_list_present) { + if (csi_im_res_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, csi_im_res_to_add_mod_list, 1, 32)); } - if (csi_im_res_to_release_list_present) { + if (csi_im_res_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, csi_im_res_to_release_list, 1, 32, integer_packer(0, 31))); } - if (csi_im_res_set_to_add_mod_list_present) { + if (csi_im_res_set_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, csi_im_res_set_to_add_mod_list, 1, 64)); } - if (csi_im_res_set_to_release_list_present) { + if (csi_im_res_set_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, csi_im_res_set_to_release_list, 1, 64, integer_packer(0, 63))); } - if (csi_ssb_res_set_to_add_mod_list_present) { + if (csi_ssb_res_set_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, csi_ssb_res_set_to_add_mod_list, 1, 64)); } - if (csi_ssb_res_set_to_release_list_present) { + if (csi_ssb_res_set_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, csi_ssb_res_set_to_release_list, 1, 64, integer_packer(0, 63))); } - if (csi_res_cfg_to_add_mod_list_present) { + if (csi_res_cfg_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, csi_res_cfg_to_add_mod_list, 1, 112)); } - if (csi_res_cfg_to_release_list_present) { + if (csi_res_cfg_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, csi_res_cfg_to_release_list, 1, 112, integer_packer(0, 111))); } - if (csi_report_cfg_to_add_mod_list_present) { + if (csi_report_cfg_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, csi_report_cfg_to_add_mod_list, 1, 48)); } - if (csi_report_cfg_to_release_list_present) { + if (csi_report_cfg_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, csi_report_cfg_to_release_list, 1, 48, integer_packer(0, 47))); } if (report_trigger_size_present) { @@ -42673,19 +42838,33 @@ SRSASN_CODE csi_meas_cfg_s::pack(bit_ref& bref) const SRSASN_CODE csi_meas_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool nzp_csi_rs_res_to_add_mod_list_present; HANDLE_CODE(bref.unpack(nzp_csi_rs_res_to_add_mod_list_present, 1)); + bool nzp_csi_rs_res_to_release_list_present; HANDLE_CODE(bref.unpack(nzp_csi_rs_res_to_release_list_present, 1)); + bool nzp_csi_rs_res_set_to_add_mod_list_present; HANDLE_CODE(bref.unpack(nzp_csi_rs_res_set_to_add_mod_list_present, 1)); + bool nzp_csi_rs_res_set_to_release_list_present; HANDLE_CODE(bref.unpack(nzp_csi_rs_res_set_to_release_list_present, 1)); + bool csi_im_res_to_add_mod_list_present; HANDLE_CODE(bref.unpack(csi_im_res_to_add_mod_list_present, 1)); + bool csi_im_res_to_release_list_present; HANDLE_CODE(bref.unpack(csi_im_res_to_release_list_present, 1)); + bool csi_im_res_set_to_add_mod_list_present; HANDLE_CODE(bref.unpack(csi_im_res_set_to_add_mod_list_present, 1)); + bool csi_im_res_set_to_release_list_present; HANDLE_CODE(bref.unpack(csi_im_res_set_to_release_list_present, 1)); + bool csi_ssb_res_set_to_add_mod_list_present; HANDLE_CODE(bref.unpack(csi_ssb_res_set_to_add_mod_list_present, 1)); + bool csi_ssb_res_set_to_release_list_present; HANDLE_CODE(bref.unpack(csi_ssb_res_set_to_release_list_present, 1)); + bool csi_res_cfg_to_add_mod_list_present; HANDLE_CODE(bref.unpack(csi_res_cfg_to_add_mod_list_present, 1)); + bool csi_res_cfg_to_release_list_present; HANDLE_CODE(bref.unpack(csi_res_cfg_to_release_list_present, 1)); + bool csi_report_cfg_to_add_mod_list_present; HANDLE_CODE(bref.unpack(csi_report_cfg_to_add_mod_list_present, 1)); + bool csi_report_cfg_to_release_list_present; HANDLE_CODE(bref.unpack(csi_report_cfg_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(report_trigger_size_present, 1)); HANDLE_CODE(bref.unpack(aperiodic_trigger_state_list_present, 1)); @@ -42748,98 +42927,98 @@ SRSASN_CODE csi_meas_cfg_s::unpack(cbit_ref& bref) void csi_meas_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (nzp_csi_rs_res_to_add_mod_list_present) { + if (nzp_csi_rs_res_to_add_mod_list.size() > 0) { j.start_array("nzp-CSI-RS-ResourceToAddModList"); for (const auto& e1 : nzp_csi_rs_res_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (nzp_csi_rs_res_to_release_list_present) { + if (nzp_csi_rs_res_to_release_list.size() > 0) { j.start_array("nzp-CSI-RS-ResourceToReleaseList"); for (const auto& e1 : nzp_csi_rs_res_to_release_list) { j.write_int(e1); } j.end_array(); } - if (nzp_csi_rs_res_set_to_add_mod_list_present) { + if (nzp_csi_rs_res_set_to_add_mod_list.size() > 0) { j.start_array("nzp-CSI-RS-ResourceSetToAddModList"); for (const auto& e1 : nzp_csi_rs_res_set_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (nzp_csi_rs_res_set_to_release_list_present) { + if (nzp_csi_rs_res_set_to_release_list.size() > 0) { j.start_array("nzp-CSI-RS-ResourceSetToReleaseList"); for (const auto& e1 : nzp_csi_rs_res_set_to_release_list) { j.write_int(e1); } j.end_array(); } - if (csi_im_res_to_add_mod_list_present) { + if (csi_im_res_to_add_mod_list.size() > 0) { j.start_array("csi-IM-ResourceToAddModList"); for (const auto& e1 : csi_im_res_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (csi_im_res_to_release_list_present) { + if (csi_im_res_to_release_list.size() > 0) { j.start_array("csi-IM-ResourceToReleaseList"); for (const auto& e1 : csi_im_res_to_release_list) { j.write_int(e1); } j.end_array(); } - if (csi_im_res_set_to_add_mod_list_present) { + if (csi_im_res_set_to_add_mod_list.size() > 0) { j.start_array("csi-IM-ResourceSetToAddModList"); for (const auto& e1 : csi_im_res_set_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (csi_im_res_set_to_release_list_present) { + if (csi_im_res_set_to_release_list.size() > 0) { j.start_array("csi-IM-ResourceSetToReleaseList"); for (const auto& e1 : csi_im_res_set_to_release_list) { j.write_int(e1); } j.end_array(); } - if (csi_ssb_res_set_to_add_mod_list_present) { + if (csi_ssb_res_set_to_add_mod_list.size() > 0) { j.start_array("csi-SSB-ResourceSetToAddModList"); for (const auto& e1 : csi_ssb_res_set_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (csi_ssb_res_set_to_release_list_present) { + if (csi_ssb_res_set_to_release_list.size() > 0) { j.start_array("csi-SSB-ResourceSetToReleaseList"); for (const auto& e1 : csi_ssb_res_set_to_release_list) { j.write_int(e1); } j.end_array(); } - if (csi_res_cfg_to_add_mod_list_present) { + if (csi_res_cfg_to_add_mod_list.size() > 0) { j.start_array("csi-ResourceConfigToAddModList"); for (const auto& e1 : csi_res_cfg_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (csi_res_cfg_to_release_list_present) { + if (csi_res_cfg_to_release_list.size() > 0) { j.start_array("csi-ResourceConfigToReleaseList"); for (const auto& e1 : csi_res_cfg_to_release_list) { j.write_int(e1); } j.end_array(); } - if (csi_report_cfg_to_add_mod_list_present) { + if (csi_report_cfg_to_add_mod_list.size() > 0) { j.start_array("csi-ReportConfigToAddModList"); for (const auto& e1 : csi_report_cfg_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (csi_report_cfg_to_release_list_present) { + if (csi_report_cfg_to_release_list.size() > 0) { j.start_array("csi-ReportConfigToReleaseList"); for (const auto& e1 : csi_report_cfg_to_release_list) { j.write_int(e1); @@ -43313,13 +43492,13 @@ void freq_info_dl_s::to_json(json_writer& j) const SRSASN_CODE freq_info_ul_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(freq_band_list_present, 1)); + HANDLE_CODE(bref.pack(freq_band_list.size() > 0, 1)); HANDLE_CODE(bref.pack(absolute_freq_point_a_present, 1)); HANDLE_CODE(bref.pack(add_spec_emission_present, 1)); HANDLE_CODE(bref.pack(p_max_present, 1)); HANDLE_CODE(bref.pack(freq_shift7p5khz_present, 1)); - if (freq_band_list_present) { + if (freq_band_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list, 1, 8, integer_packer(1, 1024))); } if (absolute_freq_point_a_present) { @@ -43338,6 +43517,7 @@ SRSASN_CODE freq_info_ul_s::pack(bit_ref& bref) const SRSASN_CODE freq_info_ul_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool freq_band_list_present; HANDLE_CODE(bref.unpack(freq_band_list_present, 1)); HANDLE_CODE(bref.unpack(absolute_freq_point_a_present, 1)); HANDLE_CODE(bref.unpack(add_spec_emission_present, 1)); @@ -43363,7 +43543,7 @@ SRSASN_CODE freq_info_ul_s::unpack(cbit_ref& bref) void freq_info_ul_s::to_json(json_writer& j) const { j.start_obj(); - if (freq_band_list_present) { + if (freq_band_list.size() > 0) { j.start_array("frequencyBandList"); for (const auto& e1 : freq_band_list) { j.write_int(e1); @@ -43428,9 +43608,9 @@ uint8_t pusch_code_block_group_tx_s::max_code_block_groups_per_transport_block_o // SRS-TPC-PDCCH-Config ::= SEQUENCE SRSASN_CODE srs_tpc_pdcch_cfg_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(srs_cc_set_idxlist_present, 1)); + HANDLE_CODE(bref.pack(srs_cc_set_idxlist.size() > 0, 1)); - if (srs_cc_set_idxlist_present) { + if (srs_cc_set_idxlist.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, srs_cc_set_idxlist, 1, 4)); } @@ -43438,6 +43618,7 @@ SRSASN_CODE srs_tpc_pdcch_cfg_s::pack(bit_ref& bref) const } SRSASN_CODE srs_tpc_pdcch_cfg_s::unpack(cbit_ref& bref) { + bool srs_cc_set_idxlist_present; HANDLE_CODE(bref.unpack(srs_cc_set_idxlist_present, 1)); if (srs_cc_set_idxlist_present) { @@ -43449,7 +43630,7 @@ SRSASN_CODE srs_tpc_pdcch_cfg_s::unpack(cbit_ref& bref) void srs_tpc_pdcch_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (srs_cc_set_idxlist_present) { + if (srs_cc_set_idxlist.size() > 0) { j.start_array("srs-CC-SetIndexlist"); for (const auto& e1 : srs_cc_set_idxlist) { e1.to_json(j); @@ -43464,7 +43645,7 @@ SRSASN_CODE slot_format_combinations_per_cell_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(subcarrier_spacing2_present, 1)); - HANDLE_CODE(bref.pack(slot_format_combinations_present, 1)); + HANDLE_CODE(bref.pack(slot_format_combinations.size() > 0, 1)); HANDLE_CODE(bref.pack(position_in_dci_present, 1)); HANDLE_CODE(pack_integer(bref, serving_cell_id, (uint8_t)0u, (uint8_t)31u)); @@ -43472,7 +43653,7 @@ SRSASN_CODE slot_format_combinations_per_cell_s::pack(bit_ref& bref) const if (subcarrier_spacing2_present) { HANDLE_CODE(subcarrier_spacing2.pack(bref)); } - if (slot_format_combinations_present) { + if (slot_format_combinations.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, slot_format_combinations, 1, 512)); } if (position_in_dci_present) { @@ -43485,6 +43666,7 @@ SRSASN_CODE slot_format_combinations_per_cell_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(subcarrier_spacing2_present, 1)); + bool slot_format_combinations_present; HANDLE_CODE(bref.unpack(slot_format_combinations_present, 1)); HANDLE_CODE(bref.unpack(position_in_dci_present, 1)); @@ -43510,7 +43692,7 @@ void slot_format_combinations_per_cell_s::to_json(json_writer& j) const if (subcarrier_spacing2_present) { j.write_str("subcarrierSpacing2", subcarrier_spacing2.to_string()); } - if (slot_format_combinations_present) { + if (slot_format_combinations.size() > 0) { j.start_array("slotFormatCombinations"); for (const auto& e1 : slot_format_combinations) { e1.to_json(j); @@ -43751,11 +43933,11 @@ int32_t poll_pdu_opts::to_number() const // RateMatchPatternLTE-CRS ::= SEQUENCE SRSASN_CODE rate_match_pattern_lte_crs_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(mbsfn_sf_cfg_list_present, 1)); + HANDLE_CODE(bref.pack(mbsfn_sf_cfg_list.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, carrier_freq_dl, (uint16_t)0u, (uint16_t)16383u)); HANDLE_CODE(carrier_bw_dl.pack(bref)); - if (mbsfn_sf_cfg_list_present) { + if (mbsfn_sf_cfg_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, mbsfn_sf_cfg_list, 1, 8)); } HANDLE_CODE(nrof_crs_ports.pack(bref)); @@ -43765,6 +43947,7 @@ SRSASN_CODE rate_match_pattern_lte_crs_s::pack(bit_ref& bref) const } SRSASN_CODE rate_match_pattern_lte_crs_s::unpack(cbit_ref& bref) { + bool mbsfn_sf_cfg_list_present; HANDLE_CODE(bref.unpack(mbsfn_sf_cfg_list_present, 1)); HANDLE_CODE(unpack_integer(carrier_freq_dl, bref, (uint16_t)0u, (uint16_t)16383u)); @@ -43782,7 +43965,7 @@ void rate_match_pattern_lte_crs_s::to_json(json_writer& j) const j.start_obj(); j.write_int("carrierFreqDL", carrier_freq_dl); j.write_str("carrierBandwidthDL", carrier_bw_dl.to_string()); - if (mbsfn_sf_cfg_list_present) { + if (mbsfn_sf_cfg_list.size() > 0) { j.start_array("mbsfn-SubframeConfigList"); for (const auto& e1 : mbsfn_sf_cfg_list) { e1.to_json(j); @@ -43857,7 +44040,7 @@ SRSASN_CODE srs_carrier_switching_s::pack(bit_ref& bref) const bref.pack(ext, 1); HANDLE_CODE(bref.pack(srs_switch_from_serv_cell_idx_present, 1)); HANDLE_CODE(bref.pack(srs_tpc_pdcch_group_present, 1)); - HANDLE_CODE(bref.pack(monitoring_cells_present, 1)); + HANDLE_CODE(bref.pack(monitoring_cells.size() > 0, 1)); if (srs_switch_from_serv_cell_idx_present) { HANDLE_CODE(pack_integer(bref, srs_switch_from_serv_cell_idx, (uint8_t)0u, (uint8_t)31u)); @@ -43866,7 +44049,7 @@ SRSASN_CODE srs_carrier_switching_s::pack(bit_ref& bref) const if (srs_tpc_pdcch_group_present) { HANDLE_CODE(srs_tpc_pdcch_group.pack(bref)); } - if (monitoring_cells_present) { + if (monitoring_cells.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, monitoring_cells, 1, 32, integer_packer(0, 31))); } @@ -43877,6 +44060,7 @@ SRSASN_CODE srs_carrier_switching_s::unpack(cbit_ref& bref) bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(srs_switch_from_serv_cell_idx_present, 1)); HANDLE_CODE(bref.unpack(srs_tpc_pdcch_group_present, 1)); + bool monitoring_cells_present; HANDLE_CODE(bref.unpack(monitoring_cells_present, 1)); if (srs_switch_from_serv_cell_idx_present) { @@ -43903,7 +44087,7 @@ void srs_carrier_switching_s::to_json(json_writer& j) const j.write_fieldname("srs-TPC-PDCCH-Group"); srs_tpc_pdcch_group.to_json(j); } - if (monitoring_cells_present) { + if (monitoring_cells.size() > 0) { j.start_array("monitoringCells"); for (const auto& e1 : monitoring_cells) { j.write_int(e1); @@ -44064,15 +44248,15 @@ const char* srs_carrier_switching_s::srs_tpc_pdcch_group_c_::types_opts::to_stri SRSASN_CODE slot_format_ind_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(slot_format_comb_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(slot_format_comb_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(slot_format_comb_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(slot_format_comb_to_release_list.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, sfi_rnti, (uint32_t)0u, (uint32_t)65535u)); HANDLE_CODE(pack_integer(bref, dci_payload_size, (uint8_t)1u, (uint8_t)128u)); - if (slot_format_comb_to_add_mod_list_present) { + if (slot_format_comb_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, slot_format_comb_to_add_mod_list, 1, 16)); } - if (slot_format_comb_to_release_list_present) { + if (slot_format_comb_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, slot_format_comb_to_release_list, 1, 16, integer_packer(0, 31))); } @@ -44081,7 +44265,9 @@ SRSASN_CODE slot_format_ind_s::pack(bit_ref& bref) const SRSASN_CODE slot_format_ind_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool slot_format_comb_to_add_mod_list_present; HANDLE_CODE(bref.unpack(slot_format_comb_to_add_mod_list_present, 1)); + bool slot_format_comb_to_release_list_present; HANDLE_CODE(bref.unpack(slot_format_comb_to_release_list_present, 1)); HANDLE_CODE(unpack_integer(sfi_rnti, bref, (uint32_t)0u, (uint32_t)65535u)); @@ -44100,14 +44286,14 @@ void slot_format_ind_s::to_json(json_writer& j) const j.start_obj(); j.write_int("sfi-RNTI", sfi_rnti); j.write_int("dci-PayloadSize", dci_payload_size); - if (slot_format_comb_to_add_mod_list_present) { + if (slot_format_comb_to_add_mod_list.size() > 0) { j.start_array("slotFormatCombToAddModList"); for (const auto& e1 : slot_format_comb_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (slot_format_comb_to_release_list_present) { + if (slot_format_comb_to_release_list.size() > 0) { j.start_array("slotFormatCombToReleaseList"); for (const auto& e1 : slot_format_comb_to_release_list) { j.write_int(e1); @@ -44859,8 +45045,8 @@ SRSASN_CODE serving_cell_cfg_common_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(ssb_positions_in_burst_present, 1)); HANDLE_CODE(bref.pack(ssb_periodicity_serving_cell_present, 1)); HANDLE_CODE(bref.pack(lte_crs_to_match_around_present, 1)); - HANDLE_CODE(bref.pack(rate_match_pattern_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(rate_match_pattern_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(rate_match_pattern_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(rate_match_pattern_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(ssb_subcarrier_spacing_present, 1)); HANDLE_CODE(bref.pack(tdd_ul_dl_cfg_common_present, 1)); @@ -44889,10 +45075,10 @@ SRSASN_CODE serving_cell_cfg_common_s::pack(bit_ref& bref) const if (lte_crs_to_match_around_present) { HANDLE_CODE(lte_crs_to_match_around.pack(bref)); } - if (rate_match_pattern_to_add_mod_list_present) { + if (rate_match_pattern_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, rate_match_pattern_to_add_mod_list, 1, 4)); } - if (rate_match_pattern_to_release_list_present) { + if (rate_match_pattern_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, rate_match_pattern_to_release_list, 1, 4, integer_packer(0, 3))); } if (ssb_subcarrier_spacing_present) { @@ -44916,7 +45102,9 @@ SRSASN_CODE serving_cell_cfg_common_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(ssb_positions_in_burst_present, 1)); HANDLE_CODE(bref.unpack(ssb_periodicity_serving_cell_present, 1)); HANDLE_CODE(bref.unpack(lte_crs_to_match_around_present, 1)); + bool rate_match_pattern_to_add_mod_list_present; HANDLE_CODE(bref.unpack(rate_match_pattern_to_add_mod_list_present, 1)); + bool rate_match_pattern_to_release_list_present; HANDLE_CODE(bref.unpack(rate_match_pattern_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(ssb_subcarrier_spacing_present, 1)); HANDLE_CODE(bref.unpack(tdd_ul_dl_cfg_common_present, 1)); @@ -44995,14 +45183,14 @@ void serving_cell_cfg_common_s::to_json(json_writer& j) const j.write_fieldname("lte-CRS-ToMatchAround"); lte_crs_to_match_around.to_json(j); } - if (rate_match_pattern_to_add_mod_list_present) { + if (rate_match_pattern_to_add_mod_list.size() > 0) { j.start_array("rateMatchPatternToAddModList"); for (const auto& e1 : rate_match_pattern_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (rate_match_pattern_to_release_list_present) { + if (rate_match_pattern_to_release_list.size() > 0) { j.start_array("rateMatchPatternToReleaseList"); for (const auto& e1 : rate_match_pattern_to_release_list) { j.write_int(e1); @@ -45243,13 +45431,13 @@ void tag_s::to_json(json_writer& j) const SRSASN_CODE tdd_ul_dl_cfg_ded_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(slot_specific_cfgs_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(slot_specific_cfgs_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(slot_specific_cfgs_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(slot_specific_cfgs_to_release_list.size() > 0, 1)); - if (slot_specific_cfgs_to_add_mod_list_present) { + if (slot_specific_cfgs_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, slot_specific_cfgs_to_add_mod_list, 1, 320)); } - if (slot_specific_cfgs_to_release_list_present) { + if (slot_specific_cfgs_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, slot_specific_cfgs_to_release_list, 1, 320, integer_packer(0, 319))); } @@ -45258,7 +45446,9 @@ SRSASN_CODE tdd_ul_dl_cfg_ded_s::pack(bit_ref& bref) const SRSASN_CODE tdd_ul_dl_cfg_ded_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool slot_specific_cfgs_to_add_mod_list_present; HANDLE_CODE(bref.unpack(slot_specific_cfgs_to_add_mod_list_present, 1)); + bool slot_specific_cfgs_to_release_list_present; HANDLE_CODE(bref.unpack(slot_specific_cfgs_to_release_list_present, 1)); if (slot_specific_cfgs_to_add_mod_list_present) { @@ -45273,14 +45463,14 @@ SRSASN_CODE tdd_ul_dl_cfg_ded_s::unpack(cbit_ref& bref) void tdd_ul_dl_cfg_ded_s::to_json(json_writer& j) const { j.start_obj(); - if (slot_specific_cfgs_to_add_mod_list_present) { + if (slot_specific_cfgs_to_add_mod_list.size() > 0) { j.start_array("slotSpecificConfigurationsToAddModList"); for (const auto& e1 : slot_specific_cfgs_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (slot_specific_cfgs_to_release_list_present) { + if (slot_specific_cfgs_to_release_list.size() > 0) { j.start_array("slotSpecificConfigurationsToReleaseList"); for (const auto& e1 : slot_specific_cfgs_to_release_list) { j.write_int(e1); @@ -45378,8 +45568,8 @@ SRSASN_CODE ul_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(init_ul_bwp_present, 1)); - HANDLE_CODE(bref.pack(ul_bwp_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(ul_bwp_to_add_mod_list_present, 1)); + HANDLE_CODE(bref.pack(ul_bwp_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(ul_bwp_to_add_mod_list.size() > 0, 1)); HANDLE_CODE(bref.pack(first_active_ul_bwp_id_present, 1)); HANDLE_CODE(bref.pack(pusch_serving_cell_cfg_present, 1)); HANDLE_CODE(bref.pack(carrier_switching_present, 1)); @@ -45387,10 +45577,10 @@ SRSASN_CODE ul_cfg_s::pack(bit_ref& bref) const if (init_ul_bwp_present) { HANDLE_CODE(init_ul_bwp.pack(bref)); } - if (ul_bwp_to_release_list_present) { + if (ul_bwp_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ul_bwp_to_release_list, 1, 4, integer_packer(0, 4))); } - if (ul_bwp_to_add_mod_list_present) { + if (ul_bwp_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ul_bwp_to_add_mod_list, 1, 4)); } if (first_active_ul_bwp_id_present) { @@ -45428,7 +45618,9 @@ SRSASN_CODE ul_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(init_ul_bwp_present, 1)); + bool ul_bwp_to_release_list_present; HANDLE_CODE(bref.unpack(ul_bwp_to_release_list_present, 1)); + bool ul_bwp_to_add_mod_list_present; HANDLE_CODE(bref.unpack(ul_bwp_to_add_mod_list_present, 1)); HANDLE_CODE(bref.unpack(first_active_ul_bwp_id_present, 1)); HANDLE_CODE(bref.unpack(pusch_serving_cell_cfg_present, 1)); @@ -45481,14 +45673,14 @@ void ul_cfg_s::to_json(json_writer& j) const j.write_fieldname("initialUplinkBWP"); init_ul_bwp.to_json(j); } - if (ul_bwp_to_release_list_present) { + if (ul_bwp_to_release_list.size() > 0) { j.start_array("uplinkBWP-ToReleaseList"); for (const auto& e1 : ul_bwp_to_release_list) { j.write_int(e1); } j.end_array(); } - if (ul_bwp_to_add_mod_list_present) { + if (ul_bwp_to_add_mod_list.size() > 0) { j.start_array("uplinkBWP-ToAddModList"); for (const auto& e1 : ul_bwp_to_add_mod_list) { e1.to_json(j); @@ -46394,8 +46586,8 @@ void lc_ch_cfg_s::to_json(json_writer& j) const SRSASN_CODE lc_ch_cfg_s::ul_specific_params_s_::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(allowed_serving_cells_present, 1)); - HANDLE_CODE(bref.pack(allowed_scs_list_present, 1)); + HANDLE_CODE(bref.pack(allowed_serving_cells.size() > 0, 1)); + HANDLE_CODE(bref.pack(allowed_scs_list.size() > 0, 1)); HANDLE_CODE(bref.pack(max_pusch_dur_present, 1)); HANDLE_CODE(bref.pack(cfgured_grant_type1_allowed_present, 1)); HANDLE_CODE(bref.pack(lc_ch_group_present, 1)); @@ -46404,10 +46596,10 @@ SRSASN_CODE lc_ch_cfg_s::ul_specific_params_s_::pack(bit_ref& bref) const HANDLE_CODE(pack_integer(bref, prio, (uint8_t)1u, (uint8_t)16u)); HANDLE_CODE(prioritised_bit_rate.pack(bref)); HANDLE_CODE(bucket_size_dur.pack(bref)); - if (allowed_serving_cells_present) { + if (allowed_serving_cells.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, allowed_serving_cells, 1, 31, integer_packer(0, 31))); } - if (allowed_scs_list_present) { + if (allowed_scs_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, allowed_scs_list, 1, 5)); } if (max_pusch_dur_present) { @@ -46434,7 +46626,9 @@ SRSASN_CODE lc_ch_cfg_s::ul_specific_params_s_::pack(bit_ref& bref) const SRSASN_CODE lc_ch_cfg_s::ul_specific_params_s_::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool allowed_serving_cells_present; HANDLE_CODE(bref.unpack(allowed_serving_cells_present, 1)); + bool allowed_scs_list_present; HANDLE_CODE(bref.unpack(allowed_scs_list_present, 1)); HANDLE_CODE(bref.unpack(max_pusch_dur_present, 1)); HANDLE_CODE(bref.unpack(cfgured_grant_type1_allowed_present, 1)); @@ -46477,14 +46671,14 @@ void lc_ch_cfg_s::ul_specific_params_s_::to_json(json_writer& j) const j.write_int("priority", prio); j.write_str("prioritisedBitRate", prioritised_bit_rate.to_string()); j.write_str("bucketSizeDuration", bucket_size_dur.to_string()); - if (allowed_serving_cells_present) { + if (allowed_serving_cells.size() > 0) { j.start_array("allowedServingCells"); for (const auto& e1 : allowed_serving_cells) { j.write_int(e1); } j.end_array(); } - if (allowed_scs_list_present) { + if (allowed_scs_list.size() > 0) { j.start_array("allowedSCS-List"); for (const auto& e1 : allowed_scs_list) { j.write_str(e1.to_string()); @@ -47208,13 +47402,13 @@ const char* recfg_with_sync_s::rach_cfg_ded_c_::types_opts::to_string() const // SchedulingRequestConfig ::= SEQUENCE SRSASN_CODE sched_request_cfg_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(sched_request_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(sched_request_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(sched_request_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(sched_request_to_release_list.size() > 0, 1)); - if (sched_request_to_add_mod_list_present) { + if (sched_request_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, sched_request_to_add_mod_list, 1, 8)); } - if (sched_request_to_release_list_present) { + if (sched_request_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, sched_request_to_release_list, 1, 8, integer_packer(0, 7))); } @@ -47222,7 +47416,9 @@ SRSASN_CODE sched_request_cfg_s::pack(bit_ref& bref) const } SRSASN_CODE sched_request_cfg_s::unpack(cbit_ref& bref) { + bool sched_request_to_add_mod_list_present; HANDLE_CODE(bref.unpack(sched_request_to_add_mod_list_present, 1)); + bool sched_request_to_release_list_present; HANDLE_CODE(bref.unpack(sched_request_to_release_list_present, 1)); if (sched_request_to_add_mod_list_present) { @@ -47237,14 +47433,14 @@ SRSASN_CODE sched_request_cfg_s::unpack(cbit_ref& bref) void sched_request_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (sched_request_to_add_mod_list_present) { + if (sched_request_to_add_mod_list.size() > 0) { j.start_array("schedulingRequestToAddModList"); for (const auto& e1 : sched_request_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (sched_request_to_release_list_present) { + if (sched_request_to_release_list.size() > 0) { j.start_array("schedulingRequestToReleaseList"); for (const auto& e1 : sched_request_to_release_list) { j.write_int(e1); @@ -47260,8 +47456,8 @@ SRSASN_CODE serving_cell_cfg_s::pack(bit_ref& bref) const bref.pack(ext, 1); HANDLE_CODE(bref.pack(tdd_ul_dl_cfg_ded_present, 1)); HANDLE_CODE(bref.pack(init_dl_bwp_present, 1)); - HANDLE_CODE(bref.pack(dl_bwp_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(dl_bwp_to_add_mod_list_present, 1)); + HANDLE_CODE(bref.pack(dl_bwp_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(dl_bwp_to_add_mod_list.size() > 0, 1)); HANDLE_CODE(bref.pack(first_active_dl_bwp_id_present, 1)); HANDLE_CODE(bref.pack(bwp_inactivity_timer_present, 1)); HANDLE_CODE(bref.pack(default_dl_bwp_id_present, 1)); @@ -47282,10 +47478,10 @@ SRSASN_CODE serving_cell_cfg_s::pack(bit_ref& bref) const if (init_dl_bwp_present) { HANDLE_CODE(init_dl_bwp.pack(bref)); } - if (dl_bwp_to_release_list_present) { + if (dl_bwp_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, dl_bwp_to_release_list, 1, 4, integer_packer(0, 4))); } - if (dl_bwp_to_add_mod_list_present) { + if (dl_bwp_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, dl_bwp_to_add_mod_list, 1, 4)); } if (first_active_dl_bwp_id_present) { @@ -47362,7 +47558,9 @@ SRSASN_CODE serving_cell_cfg_s::unpack(cbit_ref& bref) bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(tdd_ul_dl_cfg_ded_present, 1)); HANDLE_CODE(bref.unpack(init_dl_bwp_present, 1)); + bool dl_bwp_to_release_list_present; HANDLE_CODE(bref.unpack(dl_bwp_to_release_list_present, 1)); + bool dl_bwp_to_add_mod_list_present; HANDLE_CODE(bref.unpack(dl_bwp_to_add_mod_list_present, 1)); HANDLE_CODE(bref.unpack(first_active_dl_bwp_id_present, 1)); HANDLE_CODE(bref.unpack(bwp_inactivity_timer_present, 1)); @@ -47474,14 +47672,14 @@ void serving_cell_cfg_s::to_json(json_writer& j) const j.write_fieldname("initialDownlinkBWP"); init_dl_bwp.to_json(j); } - if (dl_bwp_to_release_list_present) { + if (dl_bwp_to_release_list.size() > 0) { j.start_array("downlinkBWP-ToReleaseList"); for (const auto& e1 : dl_bwp_to_release_list) { j.write_int(e1); } j.end_array(); } - if (dl_bwp_to_add_mod_list_present) { + if (dl_bwp_to_add_mod_list.size() > 0) { j.start_array("downlinkBWP-ToAddModList"); for (const auto& e1 : dl_bwp_to_add_mod_list) { e1.to_json(j); @@ -47614,13 +47812,13 @@ const char* serving_cell_cfg_s::pathloss_ref_linking_opts::to_string() const // TAG-Config ::= SEQUENCE SRSASN_CODE tag_cfg_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(tag_to_release_list_present, 1)); - HANDLE_CODE(bref.pack(tag_to_add_mod_list_present, 1)); + HANDLE_CODE(bref.pack(tag_to_release_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(tag_to_add_mod_list.size() > 0, 1)); - if (tag_to_release_list_present) { + if (tag_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, tag_to_release_list, 1, 4, integer_packer(0, 3))); } - if (tag_to_add_mod_list_present) { + if (tag_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, tag_to_add_mod_list, 1, 4)); } @@ -47628,7 +47826,9 @@ SRSASN_CODE tag_cfg_s::pack(bit_ref& bref) const } SRSASN_CODE tag_cfg_s::unpack(cbit_ref& bref) { + bool tag_to_release_list_present; HANDLE_CODE(bref.unpack(tag_to_release_list_present, 1)); + bool tag_to_add_mod_list_present; HANDLE_CODE(bref.unpack(tag_to_add_mod_list_present, 1)); if (tag_to_release_list_present) { @@ -47643,14 +47843,14 @@ SRSASN_CODE tag_cfg_s::unpack(cbit_ref& bref) void tag_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (tag_to_release_list_present) { + if (tag_to_release_list.size() > 0) { j.start_array("tag-ToReleaseList"); for (const auto& e1 : tag_to_release_list) { j.write_int(e1); } j.end_array(); } - if (tag_to_add_mod_list_present) { + if (tag_to_add_mod_list.size() > 0) { j.start_array("tag-ToAddModList"); for (const auto& e1 : tag_to_add_mod_list) { e1.to_json(j); @@ -48331,19 +48531,19 @@ void sp_cell_cfg_s::to_json(json_writer& j) const SRSASN_CODE cell_group_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(rlc_bearer_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(rlc_bearer_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(rlc_bearer_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(rlc_bearer_to_release_list.size() > 0, 1)); HANDLE_CODE(bref.pack(mac_cell_group_cfg_present, 1)); HANDLE_CODE(bref.pack(phys_cell_group_cfg_present, 1)); HANDLE_CODE(bref.pack(sp_cell_cfg_present, 1)); - HANDLE_CODE(bref.pack(scell_to_add_mod_list_present, 1)); - HANDLE_CODE(bref.pack(scell_to_release_list_present, 1)); + HANDLE_CODE(bref.pack(scell_to_add_mod_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(scell_to_release_list.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, cell_group_id, (uint8_t)0u, (uint8_t)3u)); - if (rlc_bearer_to_add_mod_list_present) { + if (rlc_bearer_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, rlc_bearer_to_add_mod_list, 1, 32)); } - if (rlc_bearer_to_release_list_present) { + if (rlc_bearer_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, rlc_bearer_to_release_list, 1, 32, integer_packer(1, 32))); } if (mac_cell_group_cfg_present) { @@ -48355,10 +48555,10 @@ SRSASN_CODE cell_group_cfg_s::pack(bit_ref& bref) const if (sp_cell_cfg_present) { HANDLE_CODE(sp_cell_cfg.pack(bref)); } - if (scell_to_add_mod_list_present) { + if (scell_to_add_mod_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, scell_to_add_mod_list, 1, 31)); } - if (scell_to_release_list_present) { + if (scell_to_release_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, scell_to_release_list, 1, 31, integer_packer(1, 31))); } @@ -48378,12 +48578,16 @@ SRSASN_CODE cell_group_cfg_s::pack(bit_ref& bref) const SRSASN_CODE cell_group_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool rlc_bearer_to_add_mod_list_present; HANDLE_CODE(bref.unpack(rlc_bearer_to_add_mod_list_present, 1)); + bool rlc_bearer_to_release_list_present; HANDLE_CODE(bref.unpack(rlc_bearer_to_release_list_present, 1)); HANDLE_CODE(bref.unpack(mac_cell_group_cfg_present, 1)); HANDLE_CODE(bref.unpack(phys_cell_group_cfg_present, 1)); HANDLE_CODE(bref.unpack(sp_cell_cfg_present, 1)); + bool scell_to_add_mod_list_present; HANDLE_CODE(bref.unpack(scell_to_add_mod_list_present, 1)); + bool scell_to_release_list_present; HANDLE_CODE(bref.unpack(scell_to_release_list_present, 1)); HANDLE_CODE(unpack_integer(cell_group_id, bref, (uint8_t)0u, (uint8_t)3u)); @@ -48425,14 +48629,14 @@ void cell_group_cfg_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("cellGroupId", cell_group_id); - if (rlc_bearer_to_add_mod_list_present) { + if (rlc_bearer_to_add_mod_list.size() > 0) { j.start_array("rlc-BearerToAddModList"); for (const auto& e1 : rlc_bearer_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (rlc_bearer_to_release_list_present) { + if (rlc_bearer_to_release_list.size() > 0) { j.start_array("rlc-BearerToReleaseList"); for (const auto& e1 : rlc_bearer_to_release_list) { j.write_int(e1); @@ -48451,14 +48655,14 @@ void cell_group_cfg_s::to_json(json_writer& j) const j.write_fieldname("spCellConfig"); sp_cell_cfg.to_json(j); } - if (scell_to_add_mod_list_present) { + if (scell_to_add_mod_list.size() > 0) { j.start_array("sCellToAddModList"); for (const auto& e1 : scell_to_add_mod_list) { e1.to_json(j); } j.end_array(); } - if (scell_to_release_list_present) { + if (scell_to_release_list.size() > 0) { j.start_array("sCellToReleaseList"); for (const auto& e1 : scell_to_release_list) { j.write_int(e1); @@ -49115,10 +49319,10 @@ SRSASN_CODE feature_set_dl_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(time_dur_for_qcl_present, 1)); HANDLE_CODE(bref.pack(pdsch_processing_type1_different_tb_per_slot_present, 1)); HANDLE_CODE(bref.pack(dummy3_present, 1)); - HANDLE_CODE(bref.pack(dummy4_present, 1)); - HANDLE_CODE(bref.pack(dummy5_present, 1)); - HANDLE_CODE(bref.pack(dummy6_present, 1)); - HANDLE_CODE(bref.pack(dummy7_present, 1)); + HANDLE_CODE(bref.pack(dummy4.size() > 0, 1)); + HANDLE_CODE(bref.pack(dummy5.size() > 0, 1)); + HANDLE_CODE(bref.pack(dummy6.size() > 0, 1)); + HANDLE_CODE(bref.pack(dummy7.size() > 0, 1)); HANDLE_CODE(pack_dyn_seq_of(bref, feature_set_list_per_dl_cc, 1, 32, integer_packer(1, 1024))); if (intra_band_freq_separation_dl_present) { @@ -49161,16 +49365,16 @@ SRSASN_CODE feature_set_dl_s::pack(bit_ref& bref) const if (dummy3_present) { HANDLE_CODE(dummy3.pack(bref)); } - if (dummy4_present) { + if (dummy4.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, dummy4, 1, 16)); } - if (dummy5_present) { + if (dummy5.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, dummy5, 1, 16)); } - if (dummy6_present) { + if (dummy6.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, dummy6, 1, 16)); } - if (dummy7_present) { + if (dummy7.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, dummy7, 1, 16)); } @@ -49192,9 +49396,13 @@ SRSASN_CODE feature_set_dl_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(time_dur_for_qcl_present, 1)); HANDLE_CODE(bref.unpack(pdsch_processing_type1_different_tb_per_slot_present, 1)); HANDLE_CODE(bref.unpack(dummy3_present, 1)); + bool dummy4_present; HANDLE_CODE(bref.unpack(dummy4_present, 1)); + bool dummy5_present; HANDLE_CODE(bref.unpack(dummy5_present, 1)); + bool dummy6_present; HANDLE_CODE(bref.unpack(dummy6_present, 1)); + bool dummy7_present; HANDLE_CODE(bref.unpack(dummy7_present, 1)); HANDLE_CODE(unpack_dyn_seq_of(feature_set_list_per_dl_cc, bref, 1, 32, integer_packer(1, 1024))); @@ -49326,28 +49534,28 @@ void feature_set_dl_s::to_json(json_writer& j) const j.write_fieldname("dummy3"); dummy3.to_json(j); } - if (dummy4_present) { + if (dummy4.size() > 0) { j.start_array("dummy4"); for (const auto& e1 : dummy4) { e1.to_json(j); } j.end_array(); } - if (dummy5_present) { + if (dummy5.size() > 0) { j.start_array("dummy5"); for (const auto& e1 : dummy5) { e1.to_json(j); } j.end_array(); } - if (dummy6_present) { + if (dummy6.size() > 0) { j.start_array("dummy6"); for (const auto& e1 : dummy6) { e1.to_json(j); } j.end_array(); } - if (dummy7_present) { + if (dummy7.size() > 0) { j.start_array("dummy7"); for (const auto& e1 : dummy7) { e1.to_json(j); @@ -50522,21 +50730,21 @@ void feature_set_ul_per_cc_v1540_s::to_json(json_writer& j) const SRSASN_CODE feature_sets_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(feature_sets_dl_present, 1)); - HANDLE_CODE(bref.pack(feature_sets_dl_per_cc_present, 1)); - HANDLE_CODE(bref.pack(feature_sets_ul_present, 1)); - HANDLE_CODE(bref.pack(feature_sets_ul_per_cc_present, 1)); + HANDLE_CODE(bref.pack(feature_sets_dl.size() > 0, 1)); + HANDLE_CODE(bref.pack(feature_sets_dl_per_cc.size() > 0, 1)); + HANDLE_CODE(bref.pack(feature_sets_ul.size() > 0, 1)); + HANDLE_CODE(bref.pack(feature_sets_ul_per_cc.size() > 0, 1)); - if (feature_sets_dl_present) { + if (feature_sets_dl.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, feature_sets_dl, 1, 1024)); } - if (feature_sets_dl_per_cc_present) { + if (feature_sets_dl_per_cc.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, feature_sets_dl_per_cc, 1, 1024)); } - if (feature_sets_ul_present) { + if (feature_sets_ul.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, feature_sets_ul, 1, 1024)); } - if (feature_sets_ul_per_cc_present) { + if (feature_sets_ul_per_cc.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, feature_sets_ul_per_cc, 1, 1024)); } @@ -50578,9 +50786,13 @@ SRSASN_CODE feature_sets_s::pack(bit_ref& bref) const SRSASN_CODE feature_sets_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool feature_sets_dl_present; HANDLE_CODE(bref.unpack(feature_sets_dl_present, 1)); + bool feature_sets_dl_per_cc_present; HANDLE_CODE(bref.unpack(feature_sets_dl_per_cc_present, 1)); + bool feature_sets_ul_present; HANDLE_CODE(bref.unpack(feature_sets_ul_present, 1)); + bool feature_sets_ul_per_cc_present; HANDLE_CODE(bref.unpack(feature_sets_ul_per_cc_present, 1)); if (feature_sets_dl_present) { @@ -50638,28 +50850,28 @@ SRSASN_CODE feature_sets_s::unpack(cbit_ref& bref) void feature_sets_s::to_json(json_writer& j) const { j.start_obj(); - if (feature_sets_dl_present) { + if (feature_sets_dl.size() > 0) { j.start_array("featureSetsDownlink"); for (const auto& e1 : feature_sets_dl) { e1.to_json(j); } j.end_array(); } - if (feature_sets_dl_per_cc_present) { + if (feature_sets_dl_per_cc.size() > 0) { j.start_array("featureSetsDownlinkPerCC"); for (const auto& e1 : feature_sets_dl_per_cc) { e1.to_json(j); } j.end_array(); } - if (feature_sets_ul_present) { + if (feature_sets_ul.size() > 0) { j.start_array("featureSetsUplink"); for (const auto& e1 : feature_sets_ul) { e1.to_json(j); } j.end_array(); } - if (feature_sets_ul_per_cc_present) { + if (feature_sets_ul_per_cc.size() > 0) { j.start_array("featureSetsUplinkPerCC"); for (const auto& e1 : feature_sets_ul_per_cc) { e1.to_json(j); @@ -52049,7 +52261,7 @@ SRSASN_CODE nrdc_params_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(tdd_add_ue_nrdc_cap_present, 1)); HANDLE_CODE(bref.pack(fr1_add_ue_nrdc_cap_present, 1)); HANDLE_CODE(bref.pack(fr2_add_ue_nrdc_cap_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(dummy_present, 1)); if (meas_and_mob_params_nrdc_present) { @@ -52070,7 +52282,7 @@ SRSASN_CODE nrdc_params_s::pack(bit_ref& bref) const if (fr2_add_ue_nrdc_cap_present) { HANDLE_CODE(fr2_add_ue_nrdc_cap.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } @@ -52084,6 +52296,7 @@ SRSASN_CODE nrdc_params_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(tdd_add_ue_nrdc_cap_present, 1)); HANDLE_CODE(bref.unpack(fr1_add_ue_nrdc_cap_present, 1)); HANDLE_CODE(bref.unpack(fr2_add_ue_nrdc_cap_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(dummy_present, 1)); @@ -52138,7 +52351,7 @@ void nrdc_params_s::to_json(json_writer& j) const j.write_fieldname("fr2-Add-UE-NRDC-Capabilities"); fr2_add_ue_nrdc_cap.to_json(j); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (dummy_present) { @@ -53392,9 +53605,9 @@ uint16_t naics_cap_entry_s::nof_aggregated_prb_opts::to_number() const SRSASN_CODE phy_params_mrdc_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(naics_cap_list_present, 1)); + HANDLE_CODE(bref.pack(naics_cap_list.size() > 0, 1)); - if (naics_cap_list_present) { + if (naics_cap_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, naics_cap_list, 1, 8)); } @@ -53417,6 +53630,7 @@ SRSASN_CODE phy_params_mrdc_s::pack(bit_ref& bref) const SRSASN_CODE phy_params_mrdc_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool naics_cap_list_present; HANDLE_CODE(bref.unpack(naics_cap_list_present, 1)); if (naics_cap_list_present) { @@ -53443,7 +53657,7 @@ SRSASN_CODE phy_params_mrdc_s::unpack(cbit_ref& bref) void phy_params_mrdc_s::to_json(json_writer& j) const { j.start_obj(); - if (naics_cap_list_present) { + if (naics_cap_list.size() > 0) { j.start_array("naics-Capability-List"); for (const auto& e1 : naics_cap_list) { e1.to_json(j); @@ -53463,14 +53677,14 @@ void phy_params_mrdc_s::to_json(json_writer& j) const SRSASN_CODE rf_params_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(supported_band_combination_list_present, 1)); - HANDLE_CODE(bref.pack(applied_freq_band_list_filt_present, 1)); + HANDLE_CODE(bref.pack(supported_band_combination_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(applied_freq_band_list_filt.size() > 0, 1)); HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_list_nr, 1, 1024)); - if (supported_band_combination_list_present) { + if (supported_band_combination_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_combination_list, 1, 65536)); } - if (applied_freq_band_list_filt_present) { + if (applied_freq_band_list_filt.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, applied_freq_band_list_filt, 1, 1280)); } @@ -53513,7 +53727,9 @@ SRSASN_CODE rf_params_s::pack(bit_ref& bref) const SRSASN_CODE rf_params_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool supported_band_combination_list_present; HANDLE_CODE(bref.unpack(supported_band_combination_list_present, 1)); + bool applied_freq_band_list_filt_present; HANDLE_CODE(bref.unpack(applied_freq_band_list_filt_present, 1)); HANDLE_CODE(unpack_dyn_seq_of(supported_band_list_nr, bref, 1, 1024)); @@ -53570,14 +53786,14 @@ void rf_params_s::to_json(json_writer& j) const e1.to_json(j); } j.end_array(); - if (supported_band_combination_list_present) { + if (supported_band_combination_list.size() > 0) { j.start_array("supportedBandCombinationList"); for (const auto& e1 : supported_band_combination_list) { e1.to_json(j); } j.end_array(); } - if (applied_freq_band_list_filt_present) { + if (applied_freq_band_list_filt.size() > 0) { j.start_array("appliedFreqBandListFilter"); for (const auto& e1 : applied_freq_band_list_filt) { e1.to_json(j); @@ -53617,13 +53833,13 @@ void rf_params_s::to_json(json_writer& j) const SRSASN_CODE rf_params_mrdc_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(supported_band_combination_list_present, 1)); - HANDLE_CODE(bref.pack(applied_freq_band_list_filt_present, 1)); + HANDLE_CODE(bref.pack(supported_band_combination_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(applied_freq_band_list_filt.size() > 0, 1)); - if (supported_band_combination_list_present) { + if (supported_band_combination_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_combination_list, 1, 65536)); } - if (applied_freq_band_list_filt_present) { + if (applied_freq_band_list_filt.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, applied_freq_band_list_filt, 1, 1280)); } @@ -53699,32 +53915,32 @@ SRSASN_CODE rf_params_mrdc_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(supported_band_combination_list_nedc_only_v15a0.is_present(), 1)); if (supported_band_combination_list_nedc_only_v15a0.is_present()) { HANDLE_CODE(bref.pack( - supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1540_present, 1)); + supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1540.size() > 0, 1)); HANDLE_CODE(bref.pack( - supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1560_present, 1)); + supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1560.size() > 0, 1)); HANDLE_CODE(bref.pack( - supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1570_present, 1)); + supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1570.size() > 0, 1)); HANDLE_CODE(bref.pack( - supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1580_present, 1)); + supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1580.size() > 0, 1)); HANDLE_CODE(bref.pack( - supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1590_present, 1)); - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1540_present) { + supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1590.size() > 0, 1)); + if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1540.size() > 0) { HANDLE_CODE(pack_dyn_seq_of( bref, supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1540, 1, 65536)); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1560_present) { + if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1560.size() > 0) { HANDLE_CODE(pack_dyn_seq_of( bref, supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1560, 1, 65536)); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1570_present) { + if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1570.size() > 0) { HANDLE_CODE(pack_dyn_seq_of( bref, supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1570, 1, 65536)); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1580_present) { + if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1580.size() > 0) { HANDLE_CODE(pack_dyn_seq_of( bref, supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1580, 1, 65536)); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1590_present) { + if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1590.size() > 0) { HANDLE_CODE(pack_dyn_seq_of( bref, supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1590, 1, 65536)); } @@ -53736,7 +53952,9 @@ SRSASN_CODE rf_params_mrdc_s::pack(bit_ref& bref) const SRSASN_CODE rf_params_mrdc_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool supported_band_combination_list_present; HANDLE_CODE(bref.unpack(supported_band_combination_list_present, 1)); + bool applied_freq_band_list_filt_present; HANDLE_CODE(bref.unpack(applied_freq_band_list_filt_present, 1)); if (supported_band_combination_list_present) { @@ -53825,33 +54043,33 @@ SRSASN_CODE rf_params_mrdc_s::unpack(cbit_ref& bref) supported_band_combination_list_nedc_only_v15a0.set_present( supported_band_combination_list_nedc_only_v15a0_present); if (supported_band_combination_list_nedc_only_v15a0.is_present()) { - HANDLE_CODE(bref.unpack( - supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1540_present, 1)); - HANDLE_CODE(bref.unpack( - supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1560_present, 1)); - HANDLE_CODE(bref.unpack( - supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1570_present, 1)); - HANDLE_CODE(bref.unpack( - supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1580_present, 1)); - HANDLE_CODE(bref.unpack( - supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1590_present, 1)); - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1540_present) { + bool supported_band_combination_list_v1540_present; + HANDLE_CODE(bref.unpack(supported_band_combination_list_v1540_present, 1)); + bool supported_band_combination_list_v1560_present; + HANDLE_CODE(bref.unpack(supported_band_combination_list_v1560_present, 1)); + bool supported_band_combination_list_v1570_present; + HANDLE_CODE(bref.unpack(supported_band_combination_list_v1570_present, 1)); + bool supported_band_combination_list_v1580_present; + HANDLE_CODE(bref.unpack(supported_band_combination_list_v1580_present, 1)); + bool supported_band_combination_list_v1590_present; + HANDLE_CODE(bref.unpack(supported_band_combination_list_v1590_present, 1)); + if (supported_band_combination_list_v1540_present) { HANDLE_CODE(unpack_dyn_seq_of( supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1540, bref, 1, 65536)); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1560_present) { + if (supported_band_combination_list_v1560_present) { HANDLE_CODE(unpack_dyn_seq_of( supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1560, bref, 1, 65536)); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1570_present) { + if (supported_band_combination_list_v1570_present) { HANDLE_CODE(unpack_dyn_seq_of( supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1570, bref, 1, 65536)); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1580_present) { + if (supported_band_combination_list_v1580_present) { HANDLE_CODE(unpack_dyn_seq_of( supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1580, bref, 1, 65536)); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1590_present) { + if (supported_band_combination_list_v1590_present) { HANDLE_CODE(unpack_dyn_seq_of( supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1590, bref, 1, 65536)); } @@ -53863,14 +54081,14 @@ SRSASN_CODE rf_params_mrdc_s::unpack(cbit_ref& bref) void rf_params_mrdc_s::to_json(json_writer& j) const { j.start_obj(); - if (supported_band_combination_list_present) { + if (supported_band_combination_list.size() > 0) { j.start_array("supportedBandCombinationList"); for (const auto& e1 : supported_band_combination_list) { e1.to_json(j); } j.end_array(); } - if (applied_freq_band_list_filt_present) { + if (applied_freq_band_list_filt.size() > 0) { j.start_array("appliedFreqBandListFilter"); for (const auto& e1 : applied_freq_band_list_filt) { e1.to_json(j); @@ -53933,35 +54151,35 @@ void rf_params_mrdc_s::to_json(json_writer& j) const if (supported_band_combination_list_nedc_only_v15a0.is_present()) { j.write_fieldname("supportedBandCombinationListNEDC-Only-v15a0"); j.start_obj(); - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1540_present) { + if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1540.size() > 0) { j.start_array("supportedBandCombinationList-v1540"); for (const auto& e1 : supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1540) { e1.to_json(j); } j.end_array(); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1560_present) { + if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1560.size() > 0) { j.start_array("supportedBandCombinationList-v1560"); for (const auto& e1 : supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1560) { e1.to_json(j); } j.end_array(); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1570_present) { + if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1570.size() > 0) { j.start_array("supportedBandCombinationList-v1570"); for (const auto& e1 : supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1570) { e1.to_json(j); } j.end_array(); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1580_present) { + if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1580.size() > 0) { j.start_array("supportedBandCombinationList-v1580"); for (const auto& e1 : supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1580) { e1.to_json(j); } j.end_array(); } - if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1590_present) { + if (supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1590.size() > 0) { j.start_array("supportedBandCombinationList-v1590"); for (const auto& e1 : supported_band_combination_list_nedc_only_v15a0->supported_band_combination_list_v1590) { e1.to_json(j); @@ -54006,10 +54224,10 @@ void ue_cap_request_filt_nr_v1540_s::to_json(json_writer& j) const // UE-CapabilityRequestFilterNR ::= SEQUENCE SRSASN_CODE ue_cap_request_filt_nr_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(freq_band_list_filt_present, 1)); + HANDLE_CODE(bref.pack(freq_band_list_filt.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (freq_band_list_filt_present) { + if (freq_band_list_filt.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, freq_band_list_filt, 1, 1280)); } if (non_crit_ext_present) { @@ -54020,6 +54238,7 @@ SRSASN_CODE ue_cap_request_filt_nr_s::pack(bit_ref& bref) const } SRSASN_CODE ue_cap_request_filt_nr_s::unpack(cbit_ref& bref) { + bool freq_band_list_filt_present; HANDLE_CODE(bref.unpack(freq_band_list_filt_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -54035,7 +54254,7 @@ SRSASN_CODE ue_cap_request_filt_nr_s::unpack(cbit_ref& bref) void ue_cap_request_filt_nr_s::to_json(json_writer& j) const { j.start_obj(); - if (freq_band_list_filt_present) { + if (freq_band_list_filt.size() > 0) { j.start_array("frequencyBandListFilter"); for (const auto& e1 : freq_band_list_filt) { e1.to_json(j); @@ -54110,13 +54329,13 @@ void pdcp_params_mrdc_s::to_json(json_writer& j) const // UE-MRDC-Capability-v1560 ::= SEQUENCE SRSASN_CODE ue_mrdc_cap_v1560_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(rx_filts_present, 1)); + HANDLE_CODE(bref.pack(rx_filts.size() > 0, 1)); HANDLE_CODE(bref.pack(meas_and_mob_params_mrdc_v1560_present, 1)); HANDLE_CODE(bref.pack(fdd_add_ue_mrdc_cap_v1560_present, 1)); HANDLE_CODE(bref.pack(tdd_add_ue_mrdc_cap_v1560_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (rx_filts_present) { + if (rx_filts.size() > 0) { HANDLE_CODE(rx_filts.pack(bref)); } if (meas_and_mob_params_mrdc_v1560_present) { @@ -54133,6 +54352,7 @@ SRSASN_CODE ue_mrdc_cap_v1560_s::pack(bit_ref& bref) const } SRSASN_CODE ue_mrdc_cap_v1560_s::unpack(cbit_ref& bref) { + bool rx_filts_present; HANDLE_CODE(bref.unpack(rx_filts_present, 1)); HANDLE_CODE(bref.unpack(meas_and_mob_params_mrdc_v1560_present, 1)); HANDLE_CODE(bref.unpack(fdd_add_ue_mrdc_cap_v1560_present, 1)); @@ -54157,7 +54377,7 @@ SRSASN_CODE ue_mrdc_cap_v1560_s::unpack(cbit_ref& bref) void ue_mrdc_cap_v1560_s::to_json(json_writer& j) const { j.start_obj(); - if (rx_filts_present) { + if (rx_filts.size() > 0) { j.write_str("receivedFilters", rx_filts.to_string()); } if (meas_and_mob_params_mrdc_v1560_present) { @@ -54190,9 +54410,9 @@ SRSASN_CODE ue_mrdc_cap_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(tdd_add_ue_mrdc_cap_present, 1)); HANDLE_CODE(bref.pack(fr1_add_ue_mrdc_cap_present, 1)); HANDLE_CODE(bref.pack(fr2_add_ue_mrdc_cap_present, 1)); - HANDLE_CODE(bref.pack(feature_set_combinations_present, 1)); + HANDLE_CODE(bref.pack(feature_set_combinations.size() > 0, 1)); HANDLE_CODE(bref.pack(pdcp_params_mrdc_v1530_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (meas_and_mob_params_mrdc_present) { @@ -54217,7 +54437,7 @@ SRSASN_CODE ue_mrdc_cap_s::pack(bit_ref& bref) const if (fr2_add_ue_mrdc_cap_present) { HANDLE_CODE(fr2_add_ue_mrdc_cap.pack(bref)); } - if (feature_set_combinations_present) { + if (feature_set_combinations.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, feature_set_combinations, 1, @@ -54227,7 +54447,7 @@ SRSASN_CODE ue_mrdc_cap_s::pack(bit_ref& bref) const if (pdcp_params_mrdc_v1530_present) { HANDLE_CODE(pdcp_params_mrdc_v1530.pack(bref)); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } if (non_crit_ext_present) { @@ -54245,8 +54465,10 @@ SRSASN_CODE ue_mrdc_cap_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(tdd_add_ue_mrdc_cap_present, 1)); HANDLE_CODE(bref.unpack(fr1_add_ue_mrdc_cap_present, 1)); HANDLE_CODE(bref.unpack(fr2_add_ue_mrdc_cap_present, 1)); + bool feature_set_combinations_present; HANDLE_CODE(bref.unpack(feature_set_combinations_present, 1)); HANDLE_CODE(bref.unpack(pdcp_params_mrdc_v1530_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -54324,7 +54546,7 @@ void ue_mrdc_cap_s::to_json(json_writer& j) const j.write_fieldname("fr2-Add-UE-MRDC-Capabilities"); fr2_add_ue_mrdc_cap.to_json(j); } - if (feature_set_combinations_present) { + if (feature_set_combinations.size() > 0) { j.start_array("featureSetCombinations"); for (const auto& e1 : feature_set_combinations) { j.start_array(); @@ -54343,7 +54565,7 @@ void ue_mrdc_cap_s::to_json(json_writer& j) const j.write_fieldname("pdcp-ParametersMRDC-v1530"); pdcp_params_mrdc_v1530.to_json(j); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -54417,13 +54639,13 @@ void ue_nr_cap_v1570_s::to_json(json_writer& j) const SRSASN_CODE ue_nr_cap_v1560_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(nrdc_params_present, 1)); - HANDLE_CODE(bref.pack(rx_filts_present, 1)); + HANDLE_CODE(bref.pack(rx_filts.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (nrdc_params_present) { HANDLE_CODE(nrdc_params.pack(bref)); } - if (rx_filts_present) { + if (rx_filts.size() > 0) { HANDLE_CODE(rx_filts.pack(bref)); } if (non_crit_ext_present) { @@ -54435,6 +54657,7 @@ SRSASN_CODE ue_nr_cap_v1560_s::pack(bit_ref& bref) const SRSASN_CODE ue_nr_cap_v1560_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(nrdc_params_present, 1)); + bool rx_filts_present; HANDLE_CODE(bref.unpack(rx_filts_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -54457,7 +54680,7 @@ void ue_nr_cap_v1560_s::to_json(json_writer& j) const j.write_fieldname("nrdc-Parameters"); nrdc_params.to_json(j); } - if (rx_filts_present) { + if (rx_filts.size() > 0) { j.write_str("receivedFilters", rx_filts.to_string()); } if (non_crit_ext_present) { @@ -55025,8 +55248,8 @@ SRSASN_CODE ue_nr_cap_s::pack(bit_ref& bref) const HANDLE_CODE(bref.pack(fr1_add_ue_nr_cap_present, 1)); HANDLE_CODE(bref.pack(fr2_add_ue_nr_cap_present, 1)); HANDLE_CODE(bref.pack(feature_sets_present, 1)); - HANDLE_CODE(bref.pack(feature_set_combinations_present, 1)); - HANDLE_CODE(bref.pack(late_non_crit_ext_present, 1)); + HANDLE_CODE(bref.pack(feature_set_combinations.size() > 0, 1)); + HANDLE_CODE(bref.pack(late_non_crit_ext.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); HANDLE_CODE(access_stratum_release.pack(bref)); @@ -55057,14 +55280,14 @@ SRSASN_CODE ue_nr_cap_s::pack(bit_ref& bref) const if (feature_sets_present) { HANDLE_CODE(feature_sets.pack(bref)); } - if (feature_set_combinations_present) { + if (feature_set_combinations.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, feature_set_combinations, 1, 1024, SeqOfPacker >(1, 32, SeqOfPacker(1, 128, Packer())))); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { HANDLE_CODE(late_non_crit_ext.pack(bref)); } if (non_crit_ext_present) { @@ -55083,7 +55306,9 @@ SRSASN_CODE ue_nr_cap_s::unpack(cbit_ref& bref) HANDLE_CODE(bref.unpack(fr1_add_ue_nr_cap_present, 1)); HANDLE_CODE(bref.unpack(fr2_add_ue_nr_cap_present, 1)); HANDLE_CODE(bref.unpack(feature_sets_present, 1)); + bool feature_set_combinations_present; HANDLE_CODE(bref.unpack(feature_set_combinations_present, 1)); + bool late_non_crit_ext_present; HANDLE_CODE(bref.unpack(late_non_crit_ext_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -55173,7 +55398,7 @@ void ue_nr_cap_s::to_json(json_writer& j) const j.write_fieldname("featureSets"); feature_sets.to_json(j); } - if (feature_set_combinations_present) { + if (feature_set_combinations.size() > 0) { j.start_array("featureSetCombinations"); for (const auto& e1 : feature_set_combinations) { j.start_array(); @@ -55188,7 +55413,7 @@ void ue_nr_cap_s::to_json(json_writer& j) const } j.end_array(); } - if (late_non_crit_ext_present) { + if (late_non_crit_ext.size() > 0) { j.write_str("lateNonCriticalExtension", late_non_crit_ext.to_string()); } if (non_crit_ext_present) { @@ -55291,25 +55516,25 @@ SRSASN_CODE as_cfg_s::pack(bit_ref& bref) const if (ext) { ext_groups_packer_guard group_flags; - group_flags[0] |= source_rb_sn_cfg_present; - group_flags[0] |= source_scg_nr_cfg_present; - group_flags[0] |= source_scg_eutra_cfg_present; + group_flags[0] |= source_rb_sn_cfg.size() > 0; + group_flags[0] |= source_scg_nr_cfg.size() > 0; + group_flags[0] |= source_scg_eutra_cfg.size() > 0; group_flags[1] |= source_scg_cfgured_present; group_flags.pack(bref); if (group_flags[0]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(source_rb_sn_cfg_present, 1)); - HANDLE_CODE(bref.pack(source_scg_nr_cfg_present, 1)); - HANDLE_CODE(bref.pack(source_scg_eutra_cfg_present, 1)); - if (source_rb_sn_cfg_present) { + HANDLE_CODE(bref.pack(source_rb_sn_cfg.size() > 0, 1)); + HANDLE_CODE(bref.pack(source_scg_nr_cfg.size() > 0, 1)); + HANDLE_CODE(bref.pack(source_scg_eutra_cfg.size() > 0, 1)); + if (source_rb_sn_cfg.size() > 0) { HANDLE_CODE(source_rb_sn_cfg.pack(bref)); } - if (source_scg_nr_cfg_present) { + if (source_scg_nr_cfg.size() > 0) { HANDLE_CODE(source_scg_nr_cfg.pack(bref)); } - if (source_scg_eutra_cfg_present) { + if (source_scg_eutra_cfg.size() > 0) { HANDLE_CODE(source_scg_eutra_cfg.pack(bref)); } } @@ -55333,8 +55558,11 @@ SRSASN_CODE as_cfg_s::unpack(cbit_ref& bref) if (group_flags[0]) { varlength_field_unpack_guard varlen_scope(bref, false); + bool source_rb_sn_cfg_present; HANDLE_CODE(bref.unpack(source_rb_sn_cfg_present, 1)); + bool source_scg_nr_cfg_present; HANDLE_CODE(bref.unpack(source_scg_nr_cfg_present, 1)); + bool source_scg_eutra_cfg_present; HANDLE_CODE(bref.unpack(source_scg_eutra_cfg_present, 1)); if (source_rb_sn_cfg_present) { HANDLE_CODE(source_rb_sn_cfg.unpack(bref)); @@ -55359,13 +55587,13 @@ void as_cfg_s::to_json(json_writer& j) const j.start_obj(); j.write_str("rrcReconfiguration", rrc_recfg.to_string()); if (ext) { - if (source_rb_sn_cfg_present) { + if (source_rb_sn_cfg.size() > 0) { j.write_str("sourceRB-SN-Config", source_rb_sn_cfg.to_string()); } - if (source_scg_nr_cfg_present) { + if (source_scg_nr_cfg.size() > 0) { j.write_str("sourceSCG-NR-Config", source_scg_nr_cfg.to_string()); } - if (source_scg_eutra_cfg_present) { + if (source_scg_eutra_cfg.size() > 0) { j.write_str("sourceSCG-EUTRA-Config", source_scg_eutra_cfg.to_string()); } if (source_scg_cfgured_present) { @@ -55455,13 +55683,13 @@ void band_combination_info_sn_s::to_json(json_writer& j) const SRSASN_CODE cfg_restrict_info_scg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(allowed_bc_list_mrdc_present, 1)); + HANDLE_CODE(bref.pack(allowed_bc_list_mrdc.size() > 0, 1)); HANDLE_CODE(bref.pack(pwr_coordination_fr1_present, 1)); HANDLE_CODE(bref.pack(serv_cell_idx_range_scg_present, 1)); HANDLE_CODE(bref.pack(max_meas_freqs_scg_present, 1)); HANDLE_CODE(bref.pack(dummy_present, 1)); - if (allowed_bc_list_mrdc_present) { + if (allowed_bc_list_mrdc.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, allowed_bc_list_mrdc, 1, 65536)); } if (pwr_coordination_fr1_present) { @@ -55536,6 +55764,7 @@ SRSASN_CODE cfg_restrict_info_scg_s::pack(bit_ref& bref) const SRSASN_CODE cfg_restrict_info_scg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool allowed_bc_list_mrdc_present; HANDLE_CODE(bref.unpack(allowed_bc_list_mrdc_present, 1)); HANDLE_CODE(bref.unpack(pwr_coordination_fr1_present, 1)); HANDLE_CODE(bref.unpack(serv_cell_idx_range_scg_present, 1)); @@ -55614,7 +55843,7 @@ SRSASN_CODE cfg_restrict_info_scg_s::unpack(cbit_ref& bref) void cfg_restrict_info_scg_s::to_json(json_writer& j) const { j.start_obj(); - if (allowed_bc_list_mrdc_present) { + if (allowed_bc_list_mrdc.size() > 0) { j.start_array("allowedBC-ListMRDC"); for (const auto& e1 : allowed_bc_list_mrdc) { e1.to_json(j); @@ -55679,11 +55908,11 @@ void cfg_restrict_info_scg_s::to_json(json_writer& j) const // ReestablishmentInfo ::= SEQUENCE SRSASN_CODE reest_info_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(add_reestab_info_list_present, 1)); + HANDLE_CODE(bref.pack(add_reestab_info_list.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, source_pci, (uint16_t)0u, (uint16_t)1007u)); HANDLE_CODE(target_cell_short_mac_i.pack(bref)); - if (add_reestab_info_list_present) { + if (add_reestab_info_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, add_reestab_info_list, 1, 32)); } @@ -55691,6 +55920,7 @@ SRSASN_CODE reest_info_s::pack(bit_ref& bref) const } SRSASN_CODE reest_info_s::unpack(cbit_ref& bref) { + bool add_reestab_info_list_present; HANDLE_CODE(bref.unpack(add_reestab_info_list_present, 1)); HANDLE_CODE(unpack_integer(source_pci, bref, (uint16_t)0u, (uint16_t)1007u)); @@ -55706,7 +55936,7 @@ void reest_info_s::to_json(json_writer& j) const j.start_obj(); j.write_int("sourcePhysCellId", source_pci); j.write_str("targetCellShortMAC-I", target_cell_short_mac_i.to_string()); - if (add_reestab_info_list_present) { + if (add_reestab_info_list.size() > 0) { j.start_array("additionalReestabInfoList"); for (const auto& e1 : add_reestab_info_list) { e1.to_json(j); @@ -55733,7 +55963,7 @@ SRSASN_CODE as_context_s::pack(bit_ref& bref) const if (ext) { ext_groups_packer_guard group_flags; group_flags[0] |= ran_notif_area_info.is_present(); - group_flags[1] |= ue_assist_info_present; + group_flags[1] |= ue_assist_info.size() > 0; group_flags[2] |= sel_band_combination_sn.is_present(); group_flags.pack(bref); @@ -55748,8 +55978,8 @@ SRSASN_CODE as_context_s::pack(bit_ref& bref) const if (group_flags[1]) { varlength_field_pack_guard varlen_scope(bref, false); - HANDLE_CODE(bref.pack(ue_assist_info_present, 1)); - if (ue_assist_info_present) { + HANDLE_CODE(bref.pack(ue_assist_info.size() > 0, 1)); + if (ue_assist_info.size() > 0) { HANDLE_CODE(ue_assist_info.pack(bref)); } } @@ -55794,6 +56024,7 @@ SRSASN_CODE as_context_s::unpack(cbit_ref& bref) if (group_flags[1]) { varlength_field_unpack_guard varlen_scope(bref, false); + bool ue_assist_info_present; HANDLE_CODE(bref.unpack(ue_assist_info_present, 1)); if (ue_assist_info_present) { HANDLE_CODE(ue_assist_info.unpack(bref)); @@ -55828,7 +56059,7 @@ void as_context_s::to_json(json_writer& j) const j.write_fieldname("ran-NotificationAreaInfo"); ran_notif_area_info->to_json(j); } - if (ue_assist_info_present) { + if (ue_assist_info.size() > 0) { j.write_str("ueAssistanceInformation", ue_assist_info.to_string()); } if (sel_band_combination_sn.is_present()) { @@ -55894,8 +56125,8 @@ SRSASN_CODE affected_carrier_freq_comb_info_mrdc_s::pack(bit_ref& bref) const HANDLE_CODE(victim_sys_type.pack(bref)); HANDLE_CODE(interference_direction_mrdc.pack(bref)); if (affected_carrier_freq_comb_mrdc_present) { - HANDLE_CODE(bref.pack(affected_carrier_freq_comb_mrdc.affected_carrier_freq_comb_eutra_present, 1)); - if (affected_carrier_freq_comb_mrdc.affected_carrier_freq_comb_eutra_present) { + HANDLE_CODE(bref.pack(affected_carrier_freq_comb_mrdc.affected_carrier_freq_comb_eutra.size() > 0, 1)); + if (affected_carrier_freq_comb_mrdc.affected_carrier_freq_comb_eutra.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, affected_carrier_freq_comb_mrdc.affected_carrier_freq_comb_eutra, 1, @@ -55918,8 +56149,9 @@ SRSASN_CODE affected_carrier_freq_comb_info_mrdc_s::unpack(cbit_ref& bref) HANDLE_CODE(victim_sys_type.unpack(bref)); HANDLE_CODE(interference_direction_mrdc.unpack(bref)); if (affected_carrier_freq_comb_mrdc_present) { - HANDLE_CODE(bref.unpack(affected_carrier_freq_comb_mrdc.affected_carrier_freq_comb_eutra_present, 1)); - if (affected_carrier_freq_comb_mrdc.affected_carrier_freq_comb_eutra_present) { + bool affected_carrier_freq_comb_eutra_present; + HANDLE_CODE(bref.unpack(affected_carrier_freq_comb_eutra_present, 1)); + if (affected_carrier_freq_comb_eutra_present) { HANDLE_CODE(unpack_dyn_seq_of(affected_carrier_freq_comb_mrdc.affected_carrier_freq_comb_eutra, bref, 1, @@ -55944,7 +56176,7 @@ void affected_carrier_freq_comb_info_mrdc_s::to_json(json_writer& j) const if (affected_carrier_freq_comb_mrdc_present) { j.write_fieldname("affectedCarrierFreqCombMRDC"); j.start_obj(); - if (affected_carrier_freq_comb_mrdc.affected_carrier_freq_comb_eutra_present) { + if (affected_carrier_freq_comb_mrdc.affected_carrier_freq_comb_eutra.size() > 0) { j.start_array("affectedCarrierFreqCombEUTRA"); for (const auto& e1 : affected_carrier_freq_comb_mrdc.affected_carrier_freq_comb_eutra) { j.write_int(e1); @@ -56003,14 +56235,14 @@ uint8_t ph_ul_carrier_scg_s::ph_type1or3_opts::to_number() const // CG-Config-v1590-IEs ::= SEQUENCE SRSASN_CODE cg_cfg_v1590_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(scell_frequencies_sn_nr_present, 1)); - HANDLE_CODE(bref.pack(scell_frequencies_sn_eutra_present, 1)); + HANDLE_CODE(bref.pack(scell_frequencies_sn_nr.size() > 0, 1)); + HANDLE_CODE(bref.pack(scell_frequencies_sn_eutra.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (scell_frequencies_sn_nr_present) { + if (scell_frequencies_sn_nr.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, scell_frequencies_sn_nr, 1, 31, integer_packer(0, 3279165))); } - if (scell_frequencies_sn_eutra_present) { + if (scell_frequencies_sn_eutra.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, scell_frequencies_sn_eutra, 1, 31, integer_packer(0, 262143))); } @@ -56018,7 +56250,9 @@ SRSASN_CODE cg_cfg_v1590_ies_s::pack(bit_ref& bref) const } SRSASN_CODE cg_cfg_v1590_ies_s::unpack(cbit_ref& bref) { + bool scell_frequencies_sn_nr_present; HANDLE_CODE(bref.unpack(scell_frequencies_sn_nr_present, 1)); + bool scell_frequencies_sn_eutra_present; HANDLE_CODE(bref.unpack(scell_frequencies_sn_eutra_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -56034,14 +56268,14 @@ SRSASN_CODE cg_cfg_v1590_ies_s::unpack(cbit_ref& bref) void cg_cfg_v1590_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (scell_frequencies_sn_nr_present) { + if (scell_frequencies_sn_nr.size() > 0) { j.start_array("scellFrequenciesSN-NR"); for (const auto& e1 : scell_frequencies_sn_nr) { j.write_int(e1); } j.end_array(); } - if (scell_frequencies_sn_eutra_present) { + if (scell_frequencies_sn_eutra.size() > 0) { j.start_array("scellFrequenciesSN-EUTRA"); for (const auto& e1 : scell_frequencies_sn_eutra) { j.write_int(e1); @@ -56100,9 +56334,9 @@ void ph_info_scg_s::to_json(json_writer& j) const SRSASN_CODE cg_cfg_v1560_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(pscell_freq_eutra_present, 1)); - HANDLE_CODE(bref.pack(scg_cell_group_cfg_eutra_present, 1)); - HANDLE_CODE(bref.pack(candidate_cell_info_list_sn_eutra_present, 1)); - HANDLE_CODE(bref.pack(candidate_serving_freq_list_eutra_present, 1)); + HANDLE_CODE(bref.pack(scg_cell_group_cfg_eutra.size() > 0, 1)); + HANDLE_CODE(bref.pack(candidate_cell_info_list_sn_eutra.size() > 0, 1)); + HANDLE_CODE(bref.pack(candidate_serving_freq_list_eutra.size() > 0, 1)); HANDLE_CODE(bref.pack(need_for_gaps_present, 1)); HANDLE_CODE(bref.pack(drx_cfg_scg_present, 1)); HANDLE_CODE(bref.pack(report_cgi_request_eutra_present, 1)); @@ -56111,13 +56345,13 @@ SRSASN_CODE cg_cfg_v1560_ies_s::pack(bit_ref& bref) const if (pscell_freq_eutra_present) { HANDLE_CODE(pack_integer(bref, pscell_freq_eutra, (uint32_t)0u, (uint32_t)262143u)); } - if (scg_cell_group_cfg_eutra_present) { + if (scg_cell_group_cfg_eutra.size() > 0) { HANDLE_CODE(scg_cell_group_cfg_eutra.pack(bref)); } - if (candidate_cell_info_list_sn_eutra_present) { + if (candidate_cell_info_list_sn_eutra.size() > 0) { HANDLE_CODE(candidate_cell_info_list_sn_eutra.pack(bref)); } - if (candidate_serving_freq_list_eutra_present) { + if (candidate_serving_freq_list_eutra.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, candidate_serving_freq_list_eutra, 1, 32, integer_packer(0, 262143))); } if (drx_cfg_scg_present) { @@ -56143,8 +56377,11 @@ SRSASN_CODE cg_cfg_v1560_ies_s::pack(bit_ref& bref) const SRSASN_CODE cg_cfg_v1560_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(pscell_freq_eutra_present, 1)); + bool scg_cell_group_cfg_eutra_present; HANDLE_CODE(bref.unpack(scg_cell_group_cfg_eutra_present, 1)); + bool candidate_cell_info_list_sn_eutra_present; HANDLE_CODE(bref.unpack(candidate_cell_info_list_sn_eutra_present, 1)); + bool candidate_serving_freq_list_eutra_present; HANDLE_CODE(bref.unpack(candidate_serving_freq_list_eutra_present, 1)); HANDLE_CODE(bref.unpack(need_for_gaps_present, 1)); HANDLE_CODE(bref.unpack(drx_cfg_scg_present, 1)); @@ -56189,13 +56426,13 @@ void cg_cfg_v1560_ies_s::to_json(json_writer& j) const if (pscell_freq_eutra_present) { j.write_int("pSCellFrequencyEUTRA", pscell_freq_eutra); } - if (scg_cell_group_cfg_eutra_present) { + if (scg_cell_group_cfg_eutra.size() > 0) { j.write_str("scg-CellGroupConfigEUTRA", scg_cell_group_cfg_eutra.to_string()); } - if (candidate_cell_info_list_sn_eutra_present) { + if (candidate_cell_info_list_sn_eutra.size() > 0) { j.write_str("candidateCellInfoListSN-EUTRA", candidate_cell_info_list_sn_eutra.to_string()); } - if (candidate_serving_freq_list_eutra_present) { + if (candidate_serving_freq_list_eutra.size() > 0) { j.start_array("candidateServingFreqListEUTRA"); for (const auto& e1 : candidate_serving_freq_list_eutra) { j.write_int(e1); @@ -56300,7 +56537,7 @@ SRSASN_CODE cg_cfg_v1540_ies_s::pack(bit_ref& bref) const { HANDLE_CODE(bref.pack(pscell_freq_present, 1)); HANDLE_CODE(bref.pack(report_cgi_request_nr_present, 1)); - HANDLE_CODE(bref.pack(ph_info_scg_present, 1)); + HANDLE_CODE(bref.pack(ph_info_scg.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); if (pscell_freq_present) { @@ -56315,7 +56552,7 @@ SRSASN_CODE cg_cfg_v1540_ies_s::pack(bit_ref& bref) const bref, report_cgi_request_nr.requested_cell_info.cell_for_which_to_report_cgi, (uint16_t)0u, (uint16_t)1007u)); } } - if (ph_info_scg_present) { + if (ph_info_scg.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ph_info_scg, 1, 32)); } if (non_crit_ext_present) { @@ -56328,6 +56565,7 @@ SRSASN_CODE cg_cfg_v1540_ies_s::unpack(cbit_ref& bref) { HANDLE_CODE(bref.unpack(pscell_freq_present, 1)); HANDLE_CODE(bref.unpack(report_cgi_request_nr_present, 1)); + bool ph_info_scg_present; HANDLE_CODE(bref.unpack(ph_info_scg_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -56370,7 +56608,7 @@ void cg_cfg_v1540_ies_s::to_json(json_writer& j) const } j.end_obj(); } - if (ph_info_scg_present) { + if (ph_info_scg.size() > 0) { j.start_array("ph-InfoSCG"); for (const auto& e1 : ph_info_scg) { e1.to_json(j); @@ -57010,9 +57248,9 @@ uint16_t drx_info_s::short_drx_s_::drx_short_cycle_opts::to_number() const SRSASN_CODE meas_cfg_sn_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(measured_frequencies_sn_present, 1)); + HANDLE_CODE(bref.pack(measured_frequencies_sn.size() > 0, 1)); - if (measured_frequencies_sn_present) { + if (measured_frequencies_sn.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, measured_frequencies_sn, 1, 32)); } @@ -57021,6 +57259,7 @@ SRSASN_CODE meas_cfg_sn_s::pack(bit_ref& bref) const SRSASN_CODE meas_cfg_sn_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool measured_frequencies_sn_present; HANDLE_CODE(bref.unpack(measured_frequencies_sn_present, 1)); if (measured_frequencies_sn_present) { @@ -57032,7 +57271,7 @@ SRSASN_CODE meas_cfg_sn_s::unpack(cbit_ref& bref) void meas_cfg_sn_s::to_json(json_writer& j) const { j.start_obj(); - if (measured_frequencies_sn_present) { + if (measured_frequencies_sn.size() > 0) { j.start_array("measuredFrequenciesSN"); for (const auto& e1 : measured_frequencies_sn) { e1.to_json(j); @@ -57045,21 +57284,21 @@ void meas_cfg_sn_s::to_json(json_writer& j) const // CG-Config-IEs ::= SEQUENCE SRSASN_CODE cg_cfg_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(scg_cell_group_cfg_present, 1)); - HANDLE_CODE(bref.pack(scg_rb_cfg_present, 1)); + HANDLE_CODE(bref.pack(scg_cell_group_cfg.size() > 0, 1)); + HANDLE_CODE(bref.pack(scg_rb_cfg.size() > 0, 1)); HANDLE_CODE(bref.pack(cfg_restrict_mod_req_present, 1)); HANDLE_CODE(bref.pack(drx_info_scg_present, 1)); - HANDLE_CODE(bref.pack(candidate_cell_info_list_sn_present, 1)); + HANDLE_CODE(bref.pack(candidate_cell_info_list_sn.size() > 0, 1)); HANDLE_CODE(bref.pack(meas_cfg_sn_present, 1)); HANDLE_CODE(bref.pack(sel_band_combination_present, 1)); - HANDLE_CODE(bref.pack(fr_info_list_scg_present, 1)); - HANDLE_CODE(bref.pack(candidate_serving_freq_list_nr_present, 1)); + HANDLE_CODE(bref.pack(fr_info_list_scg.size() > 0, 1)); + HANDLE_CODE(bref.pack(candidate_serving_freq_list_nr.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (scg_cell_group_cfg_present) { + if (scg_cell_group_cfg.size() > 0) { HANDLE_CODE(scg_cell_group_cfg.pack(bref)); } - if (scg_rb_cfg_present) { + if (scg_rb_cfg.size() > 0) { HANDLE_CODE(scg_rb_cfg.pack(bref)); } if (cfg_restrict_mod_req_present) { @@ -57068,7 +57307,7 @@ SRSASN_CODE cg_cfg_ies_s::pack(bit_ref& bref) const if (drx_info_scg_present) { HANDLE_CODE(drx_info_scg.pack(bref)); } - if (candidate_cell_info_list_sn_present) { + if (candidate_cell_info_list_sn.size() > 0) { HANDLE_CODE(candidate_cell_info_list_sn.pack(bref)); } if (meas_cfg_sn_present) { @@ -57077,10 +57316,10 @@ SRSASN_CODE cg_cfg_ies_s::pack(bit_ref& bref) const if (sel_band_combination_present) { HANDLE_CODE(sel_band_combination.pack(bref)); } - if (fr_info_list_scg_present) { + if (fr_info_list_scg.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, fr_info_list_scg, 1, 31)); } - if (candidate_serving_freq_list_nr_present) { + if (candidate_serving_freq_list_nr.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, candidate_serving_freq_list_nr, 1, 32, integer_packer(0, 3279165))); } if (non_crit_ext_present) { @@ -57091,14 +57330,19 @@ SRSASN_CODE cg_cfg_ies_s::pack(bit_ref& bref) const } SRSASN_CODE cg_cfg_ies_s::unpack(cbit_ref& bref) { + bool scg_cell_group_cfg_present; HANDLE_CODE(bref.unpack(scg_cell_group_cfg_present, 1)); + bool scg_rb_cfg_present; HANDLE_CODE(bref.unpack(scg_rb_cfg_present, 1)); HANDLE_CODE(bref.unpack(cfg_restrict_mod_req_present, 1)); HANDLE_CODE(bref.unpack(drx_info_scg_present, 1)); + bool candidate_cell_info_list_sn_present; HANDLE_CODE(bref.unpack(candidate_cell_info_list_sn_present, 1)); HANDLE_CODE(bref.unpack(meas_cfg_sn_present, 1)); HANDLE_CODE(bref.unpack(sel_band_combination_present, 1)); + bool fr_info_list_scg_present; HANDLE_CODE(bref.unpack(fr_info_list_scg_present, 1)); + bool candidate_serving_freq_list_nr_present; HANDLE_CODE(bref.unpack(candidate_serving_freq_list_nr_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -57138,10 +57382,10 @@ SRSASN_CODE cg_cfg_ies_s::unpack(cbit_ref& bref) void cg_cfg_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (scg_cell_group_cfg_present) { + if (scg_cell_group_cfg.size() > 0) { j.write_str("scg-CellGroupConfig", scg_cell_group_cfg.to_string()); } - if (scg_rb_cfg_present) { + if (scg_rb_cfg.size() > 0) { j.write_str("scg-RB-Config", scg_rb_cfg.to_string()); } if (cfg_restrict_mod_req_present) { @@ -57152,7 +57396,7 @@ void cg_cfg_ies_s::to_json(json_writer& j) const j.write_fieldname("drx-InfoSCG"); drx_info_scg.to_json(j); } - if (candidate_cell_info_list_sn_present) { + if (candidate_cell_info_list_sn.size() > 0) { j.write_str("candidateCellInfoListSN", candidate_cell_info_list_sn.to_string()); } if (meas_cfg_sn_present) { @@ -57163,14 +57407,14 @@ void cg_cfg_ies_s::to_json(json_writer& j) const j.write_fieldname("selectedBandCombination"); sel_band_combination.to_json(j); } - if (fr_info_list_scg_present) { + if (fr_info_list_scg.size() > 0) { j.start_array("fr-InfoListSCG"); for (const auto& e1 : fr_info_list_scg) { e1.to_json(j); } j.end_array(); } - if (candidate_serving_freq_list_nr_present) { + if (candidate_serving_freq_list_nr.size() > 0) { j.start_array("candidateServingFreqListNR"); for (const auto& e1 : candidate_serving_freq_list_nr) { j.write_int(e1); @@ -57367,10 +57611,10 @@ uint8_t cg_cfg_s::crit_exts_c_::types_opts::to_number() const // CG-ConfigInfo-v1590-IEs ::= SEQUENCE SRSASN_CODE cg_cfg_info_v1590_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(serv_frequencies_mn_nr_present, 1)); + HANDLE_CODE(bref.pack(serv_frequencies_mn_nr.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (serv_frequencies_mn_nr_present) { + if (serv_frequencies_mn_nr.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, serv_frequencies_mn_nr, 1, 31, integer_packer(0, 3279165))); } @@ -57378,6 +57622,7 @@ SRSASN_CODE cg_cfg_info_v1590_ies_s::pack(bit_ref& bref) const } SRSASN_CODE cg_cfg_info_v1590_ies_s::unpack(cbit_ref& bref) { + bool serv_frequencies_mn_nr_present; HANDLE_CODE(bref.unpack(serv_frequencies_mn_nr_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -57390,7 +57635,7 @@ SRSASN_CODE cg_cfg_info_v1590_ies_s::unpack(cbit_ref& bref) void cg_cfg_info_v1590_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (serv_frequencies_mn_nr_present) { + if (serv_frequencies_mn_nr.size() > 0) { j.start_array("servFrequenciesMN-NR"); for (const auto& e1 : serv_frequencies_mn_nr) { j.write_int(e1); @@ -57441,14 +57686,14 @@ uint8_t ph_ul_carrier_mcg_s::ph_type1or3_opts::to_number() const // CG-ConfigInfo-v1570-IEs ::= SEQUENCE SRSASN_CODE cg_cfg_info_v1570_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(sftd_freq_list_nr_present, 1)); - HANDLE_CODE(bref.pack(sftd_freq_list_eutra_present, 1)); + HANDLE_CODE(bref.pack(sftd_freq_list_nr.size() > 0, 1)); + HANDLE_CODE(bref.pack(sftd_freq_list_eutra.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (sftd_freq_list_nr_present) { + if (sftd_freq_list_nr.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, sftd_freq_list_nr, 1, 3, integer_packer(0, 3279165))); } - if (sftd_freq_list_eutra_present) { + if (sftd_freq_list_eutra.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, sftd_freq_list_eutra, 1, 3, integer_packer(0, 262143))); } if (non_crit_ext_present) { @@ -57459,7 +57704,9 @@ SRSASN_CODE cg_cfg_info_v1570_ies_s::pack(bit_ref& bref) const } SRSASN_CODE cg_cfg_info_v1570_ies_s::unpack(cbit_ref& bref) { + bool sftd_freq_list_nr_present; HANDLE_CODE(bref.unpack(sftd_freq_list_nr_present, 1)); + bool sftd_freq_list_eutra_present; HANDLE_CODE(bref.unpack(sftd_freq_list_eutra_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -57478,14 +57725,14 @@ SRSASN_CODE cg_cfg_info_v1570_ies_s::unpack(cbit_ref& bref) void cg_cfg_info_v1570_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (sftd_freq_list_nr_present) { + if (sftd_freq_list_nr.size() > 0) { j.start_array("sftdFrequencyList-NR"); for (const auto& e1 : sftd_freq_list_nr) { j.write_int(e1); } j.end_array(); } - if (sftd_freq_list_eutra_present) { + if (sftd_freq_list_eutra.size() > 0) { j.start_array("sftdFrequencyList-EUTRA"); for (const auto& e1 : sftd_freq_list_eutra) { j.write_int(e1); @@ -57542,23 +57789,23 @@ void ph_info_mcg_s::to_json(json_writer& j) const // CG-ConfigInfo-v1560-IEs ::= SEQUENCE SRSASN_CODE cg_cfg_info_v1560_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(candidate_cell_info_list_mn_eutra_present, 1)); - HANDLE_CODE(bref.pack(candidate_cell_info_list_sn_eutra_present, 1)); - HANDLE_CODE(bref.pack(source_cfg_scg_eutra_present, 1)); + HANDLE_CODE(bref.pack(candidate_cell_info_list_mn_eutra.size() > 0, 1)); + HANDLE_CODE(bref.pack(candidate_cell_info_list_sn_eutra.size() > 0, 1)); + HANDLE_CODE(bref.pack(source_cfg_scg_eutra.size() > 0, 1)); HANDLE_CODE(bref.pack(scg_fail_info_eutra_present, 1)); HANDLE_CODE(bref.pack(drx_cfg_mcg_present, 1)); HANDLE_CODE(bref.pack(meas_result_report_cgi_eutra_present, 1)); - HANDLE_CODE(bref.pack(meas_result_cell_list_sftd_eutra_present, 1)); - HANDLE_CODE(bref.pack(fr_info_list_mcg_present, 1)); + HANDLE_CODE(bref.pack(meas_result_cell_list_sftd_eutra.size() > 0, 1)); + HANDLE_CODE(bref.pack(fr_info_list_mcg.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (candidate_cell_info_list_mn_eutra_present) { + if (candidate_cell_info_list_mn_eutra.size() > 0) { HANDLE_CODE(candidate_cell_info_list_mn_eutra.pack(bref)); } - if (candidate_cell_info_list_sn_eutra_present) { + if (candidate_cell_info_list_sn_eutra.size() > 0) { HANDLE_CODE(candidate_cell_info_list_sn_eutra.pack(bref)); } - if (source_cfg_scg_eutra_present) { + if (source_cfg_scg_eutra.size() > 0) { HANDLE_CODE(source_cfg_scg_eutra.pack(bref)); } if (scg_fail_info_eutra_present) { @@ -57574,10 +57821,10 @@ SRSASN_CODE cg_cfg_info_v1560_ies_s::pack(bit_ref& bref) const bref, meas_result_report_cgi_eutra.cell_for_which_to_report_cgi_eutra, (uint16_t)0u, (uint16_t)503u)); HANDLE_CODE(meas_result_report_cgi_eutra.cgi_info_eutra.pack(bref)); } - if (meas_result_cell_list_sftd_eutra_present) { + if (meas_result_cell_list_sftd_eutra.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_cell_list_sftd_eutra, 1, 3)); } - if (fr_info_list_mcg_present) { + if (fr_info_list_mcg.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, fr_info_list_mcg, 1, 31)); } if (non_crit_ext_present) { @@ -57588,13 +57835,18 @@ SRSASN_CODE cg_cfg_info_v1560_ies_s::pack(bit_ref& bref) const } SRSASN_CODE cg_cfg_info_v1560_ies_s::unpack(cbit_ref& bref) { + bool candidate_cell_info_list_mn_eutra_present; HANDLE_CODE(bref.unpack(candidate_cell_info_list_mn_eutra_present, 1)); + bool candidate_cell_info_list_sn_eutra_present; HANDLE_CODE(bref.unpack(candidate_cell_info_list_sn_eutra_present, 1)); + bool source_cfg_scg_eutra_present; HANDLE_CODE(bref.unpack(source_cfg_scg_eutra_present, 1)); HANDLE_CODE(bref.unpack(scg_fail_info_eutra_present, 1)); HANDLE_CODE(bref.unpack(drx_cfg_mcg_present, 1)); HANDLE_CODE(bref.unpack(meas_result_report_cgi_eutra_present, 1)); + bool meas_result_cell_list_sftd_eutra_present; HANDLE_CODE(bref.unpack(meas_result_cell_list_sftd_eutra_present, 1)); + bool fr_info_list_mcg_present; HANDLE_CODE(bref.unpack(fr_info_list_mcg_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -57635,13 +57887,13 @@ SRSASN_CODE cg_cfg_info_v1560_ies_s::unpack(cbit_ref& bref) void cg_cfg_info_v1560_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (candidate_cell_info_list_mn_eutra_present) { + if (candidate_cell_info_list_mn_eutra.size() > 0) { j.write_str("candidateCellInfoListMN-EUTRA", candidate_cell_info_list_mn_eutra.to_string()); } - if (candidate_cell_info_list_sn_eutra_present) { + if (candidate_cell_info_list_sn_eutra.size() > 0) { j.write_str("candidateCellInfoListSN-EUTRA", candidate_cell_info_list_sn_eutra.to_string()); } - if (source_cfg_scg_eutra_present) { + if (source_cfg_scg_eutra.size() > 0) { j.write_str("sourceConfigSCG-EUTRA", source_cfg_scg_eutra.to_string()); } if (scg_fail_info_eutra_present) { @@ -57664,14 +57916,14 @@ void cg_cfg_info_v1560_ies_s::to_json(json_writer& j) const meas_result_report_cgi_eutra.cgi_info_eutra.to_json(j); j.end_obj(); } - if (meas_result_cell_list_sftd_eutra_present) { + if (meas_result_cell_list_sftd_eutra.size() > 0) { j.start_array("measResultCellListSFTD-EUTRA"); for (const auto& e1 : meas_result_cell_list_sftd_eutra) { e1.to_json(j); } j.end_array(); } - if (fr_info_list_mcg_present) { + if (fr_info_list_mcg.size() > 0) { j.start_array("fr-InfoListMCG"); for (const auto& e1 : fr_info_list_mcg) { e1.to_json(j); @@ -57699,11 +57951,11 @@ uint16_t cg_cfg_info_v1560_ies_s::scg_fail_info_eutra_s_::fail_type_eutra_opts:: // CG-ConfigInfo-v1540-IEs ::= SEQUENCE SRSASN_CODE cg_cfg_info_v1540_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(ph_info_mcg_present, 1)); + HANDLE_CODE(bref.pack(ph_info_mcg.size() > 0, 1)); HANDLE_CODE(bref.pack(meas_result_report_cgi_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (ph_info_mcg_present) { + if (ph_info_mcg.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, ph_info_mcg, 1, 32)); } if (meas_result_report_cgi_present) { @@ -57719,6 +57971,7 @@ SRSASN_CODE cg_cfg_info_v1540_ies_s::pack(bit_ref& bref) const } SRSASN_CODE cg_cfg_info_v1540_ies_s::unpack(cbit_ref& bref) { + bool ph_info_mcg_present; HANDLE_CODE(bref.unpack(ph_info_mcg_present, 1)); HANDLE_CODE(bref.unpack(meas_result_report_cgi_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -57741,7 +57994,7 @@ SRSASN_CODE cg_cfg_info_v1540_ies_s::unpack(cbit_ref& bref) void cg_cfg_info_v1540_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (ph_info_mcg_present) { + if (ph_info_mcg.size() > 0) { j.start_array("ph-InfoMCG"); for (const auto& e1 : ph_info_mcg) { e1.to_json(j); @@ -57794,11 +58047,11 @@ void mrdc_assist_info_s::to_json(json_writer& j) const SRSASN_CODE meas_cfg_mn_s::pack(bit_ref& bref) const { bref.pack(ext, 1); - HANDLE_CODE(bref.pack(measured_frequencies_mn_present, 1)); + HANDLE_CODE(bref.pack(measured_frequencies_mn.size() > 0, 1)); HANDLE_CODE(bref.pack(meas_gap_cfg_present, 1)); HANDLE_CODE(bref.pack(gap_purpose_present, 1)); - if (measured_frequencies_mn_present) { + if (measured_frequencies_mn.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, measured_frequencies_mn, 1, 32)); } if (meas_gap_cfg_present) { @@ -57827,6 +58080,7 @@ SRSASN_CODE meas_cfg_mn_s::pack(bit_ref& bref) const SRSASN_CODE meas_cfg_mn_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); + bool measured_frequencies_mn_present; HANDLE_CODE(bref.unpack(measured_frequencies_mn_present, 1)); HANDLE_CODE(bref.unpack(meas_gap_cfg_present, 1)); HANDLE_CODE(bref.unpack(gap_purpose_present, 1)); @@ -57861,7 +58115,7 @@ SRSASN_CODE meas_cfg_mn_s::unpack(cbit_ref& bref) void meas_cfg_mn_s::to_json(json_writer& j) const { j.start_obj(); - if (measured_frequencies_mn_present) { + if (measured_frequencies_mn.size() > 0) { j.start_array("measuredFrequenciesMN"); for (const auto& e1 : measured_frequencies_mn) { e1.to_json(j); @@ -57901,30 +58155,30 @@ uint8_t meas_cfg_mn_s::gap_purpose_opts::to_number() const // CG-ConfigInfo-IEs ::= SEQUENCE SRSASN_CODE cg_cfg_info_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(ue_cap_info_present, 1)); - HANDLE_CODE(bref.pack(candidate_cell_info_list_mn_present, 1)); - HANDLE_CODE(bref.pack(candidate_cell_info_list_sn_present, 1)); - HANDLE_CODE(bref.pack(meas_result_cell_list_sftd_nr_present, 1)); + HANDLE_CODE(bref.pack(ue_cap_info.size() > 0, 1)); + HANDLE_CODE(bref.pack(candidate_cell_info_list_mn.size() > 0, 1)); + HANDLE_CODE(bref.pack(candidate_cell_info_list_sn.size() > 0, 1)); + HANDLE_CODE(bref.pack(meas_result_cell_list_sftd_nr.size() > 0, 1)); HANDLE_CODE(bref.pack(scg_fail_info_present, 1)); HANDLE_CODE(bref.pack(cfg_restrict_info_present, 1)); HANDLE_CODE(bref.pack(drx_info_mcg_present, 1)); HANDLE_CODE(bref.pack(meas_cfg_mn_present, 1)); - HANDLE_CODE(bref.pack(source_cfg_scg_present, 1)); - HANDLE_CODE(bref.pack(scg_rb_cfg_present, 1)); - HANDLE_CODE(bref.pack(mcg_rb_cfg_present, 1)); + HANDLE_CODE(bref.pack(source_cfg_scg.size() > 0, 1)); + HANDLE_CODE(bref.pack(scg_rb_cfg.size() > 0, 1)); + HANDLE_CODE(bref.pack(mcg_rb_cfg.size() > 0, 1)); HANDLE_CODE(bref.pack(mrdc_assist_info_present, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (ue_cap_info_present) { + if (ue_cap_info.size() > 0) { HANDLE_CODE(ue_cap_info.pack(bref)); } - if (candidate_cell_info_list_mn_present) { + if (candidate_cell_info_list_mn.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, candidate_cell_info_list_mn, 1, 8)); } - if (candidate_cell_info_list_sn_present) { + if (candidate_cell_info_list_sn.size() > 0) { HANDLE_CODE(candidate_cell_info_list_sn.pack(bref)); } - if (meas_result_cell_list_sftd_nr_present) { + if (meas_result_cell_list_sftd_nr.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_result_cell_list_sftd_nr, 1, 3)); } if (scg_fail_info_present) { @@ -57940,13 +58194,13 @@ SRSASN_CODE cg_cfg_info_ies_s::pack(bit_ref& bref) const if (meas_cfg_mn_present) { HANDLE_CODE(meas_cfg_mn.pack(bref)); } - if (source_cfg_scg_present) { + if (source_cfg_scg.size() > 0) { HANDLE_CODE(source_cfg_scg.pack(bref)); } - if (scg_rb_cfg_present) { + if (scg_rb_cfg.size() > 0) { HANDLE_CODE(scg_rb_cfg.pack(bref)); } - if (mcg_rb_cfg_present) { + if (mcg_rb_cfg.size() > 0) { HANDLE_CODE(mcg_rb_cfg.pack(bref)); } if (mrdc_assist_info_present) { @@ -57960,16 +58214,23 @@ SRSASN_CODE cg_cfg_info_ies_s::pack(bit_ref& bref) const } SRSASN_CODE cg_cfg_info_ies_s::unpack(cbit_ref& bref) { + bool ue_cap_info_present; HANDLE_CODE(bref.unpack(ue_cap_info_present, 1)); + bool candidate_cell_info_list_mn_present; HANDLE_CODE(bref.unpack(candidate_cell_info_list_mn_present, 1)); + bool candidate_cell_info_list_sn_present; HANDLE_CODE(bref.unpack(candidate_cell_info_list_sn_present, 1)); + bool meas_result_cell_list_sftd_nr_present; HANDLE_CODE(bref.unpack(meas_result_cell_list_sftd_nr_present, 1)); HANDLE_CODE(bref.unpack(scg_fail_info_present, 1)); HANDLE_CODE(bref.unpack(cfg_restrict_info_present, 1)); HANDLE_CODE(bref.unpack(drx_info_mcg_present, 1)); HANDLE_CODE(bref.unpack(meas_cfg_mn_present, 1)); + bool source_cfg_scg_present; HANDLE_CODE(bref.unpack(source_cfg_scg_present, 1)); + bool scg_rb_cfg_present; HANDLE_CODE(bref.unpack(scg_rb_cfg_present, 1)); + bool mcg_rb_cfg_present; HANDLE_CODE(bref.unpack(mcg_rb_cfg_present, 1)); HANDLE_CODE(bref.unpack(mrdc_assist_info_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -58020,20 +58281,20 @@ SRSASN_CODE cg_cfg_info_ies_s::unpack(cbit_ref& bref) void cg_cfg_info_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (ue_cap_info_present) { + if (ue_cap_info.size() > 0) { j.write_str("ue-CapabilityInfo", ue_cap_info.to_string()); } - if (candidate_cell_info_list_mn_present) { + if (candidate_cell_info_list_mn.size() > 0) { j.start_array("candidateCellInfoListMN"); for (const auto& e1 : candidate_cell_info_list_mn) { e1.to_json(j); } j.end_array(); } - if (candidate_cell_info_list_sn_present) { + if (candidate_cell_info_list_sn.size() > 0) { j.write_str("candidateCellInfoListSN", candidate_cell_info_list_sn.to_string()); } - if (meas_result_cell_list_sftd_nr_present) { + if (meas_result_cell_list_sftd_nr.size() > 0) { j.start_array("measResultCellListSFTD-NR"); for (const auto& e1 : meas_result_cell_list_sftd_nr) { e1.to_json(j); @@ -58059,13 +58320,13 @@ void cg_cfg_info_ies_s::to_json(json_writer& j) const j.write_fieldname("measConfigMN"); meas_cfg_mn.to_json(j); } - if (source_cfg_scg_present) { + if (source_cfg_scg.size() > 0) { j.write_str("sourceConfigSCG", source_cfg_scg.to_string()); } - if (scg_rb_cfg_present) { + if (scg_rb_cfg.size() > 0) { j.write_str("scg-RB-Config", scg_rb_cfg.to_string()); } - if (mcg_rb_cfg_present) { + if (mcg_rb_cfg.size() > 0) { j.write_str("mcg-RB-Config", mcg_rb_cfg.to_string()); } if (mrdc_assist_info_present) { @@ -58605,12 +58866,12 @@ SRSASN_CODE rrm_cfg_s::pack(bit_ref& bref) const { bref.pack(ext, 1); HANDLE_CODE(bref.pack(ue_inactive_time_present, 1)); - HANDLE_CODE(bref.pack(candidate_cell_info_list_present, 1)); + HANDLE_CODE(bref.pack(candidate_cell_info_list.size() > 0, 1)); if (ue_inactive_time_present) { HANDLE_CODE(ue_inactive_time.pack(bref)); } - if (candidate_cell_info_list_present) { + if (candidate_cell_info_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, candidate_cell_info_list, 1, 8)); } @@ -58634,6 +58895,7 @@ SRSASN_CODE rrm_cfg_s::unpack(cbit_ref& bref) { bref.unpack(ext, 1); HANDLE_CODE(bref.unpack(ue_inactive_time_present, 1)); + bool candidate_cell_info_list_present; HANDLE_CODE(bref.unpack(candidate_cell_info_list_present, 1)); if (ue_inactive_time_present) { @@ -58666,7 +58928,7 @@ void rrm_cfg_s::to_json(json_writer& j) const if (ue_inactive_time_present) { j.write_str("ue-InactiveTime", ue_inactive_time.to_string()); } - if (candidate_cell_info_list_present) { + if (candidate_cell_info_list.size() > 0) { j.start_array("candidateCellInfoList"); for (const auto& e1 : candidate_cell_info_list) { e1.to_json(j); @@ -59083,10 +59345,10 @@ void meas_timing_cfg_v1550_ies_s::to_json(json_writer& j) const // MeasurementTimingConfiguration-IEs ::= SEQUENCE SRSASN_CODE meas_timing_cfg_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(meas_timing_present, 1)); + HANDLE_CODE(bref.pack(meas_timing.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (meas_timing_present) { + if (meas_timing.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_timing, 1, 32)); } if (non_crit_ext_present) { @@ -59097,6 +59359,7 @@ SRSASN_CODE meas_timing_cfg_ies_s::pack(bit_ref& bref) const } SRSASN_CODE meas_timing_cfg_ies_s::unpack(cbit_ref& bref) { + bool meas_timing_present; HANDLE_CODE(bref.unpack(meas_timing_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -59112,7 +59375,7 @@ SRSASN_CODE meas_timing_cfg_ies_s::unpack(cbit_ref& bref) void meas_timing_cfg_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (meas_timing_present) { + if (meas_timing.size() > 0) { j.start_array("measTiming"); for (const auto& e1 : meas_timing) { e1.to_json(j); @@ -59559,10 +59822,10 @@ uint8_t ue_radio_access_cap_info_s::crit_exts_c_::types_opts::to_number() const // UERadioPagingInformation-IEs ::= SEQUENCE SRSASN_CODE ue_radio_paging_info_ies_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(supported_band_list_nr_for_paging_present, 1)); + HANDLE_CODE(bref.pack(supported_band_list_nr_for_paging.size() > 0, 1)); HANDLE_CODE(bref.pack(non_crit_ext_present, 1)); - if (supported_band_list_nr_for_paging_present) { + if (supported_band_list_nr_for_paging.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, supported_band_list_nr_for_paging, 1, 1024, integer_packer(1, 1024))); } @@ -59570,6 +59833,7 @@ SRSASN_CODE ue_radio_paging_info_ies_s::pack(bit_ref& bref) const } SRSASN_CODE ue_radio_paging_info_ies_s::unpack(cbit_ref& bref) { + bool supported_band_list_nr_for_paging_present; HANDLE_CODE(bref.unpack(supported_band_list_nr_for_paging_present, 1)); HANDLE_CODE(bref.unpack(non_crit_ext_present, 1)); @@ -59582,7 +59846,7 @@ SRSASN_CODE ue_radio_paging_info_ies_s::unpack(cbit_ref& bref) void ue_radio_paging_info_ies_s::to_json(json_writer& j) const { j.start_obj(); - if (supported_band_list_nr_for_paging_present) { + if (supported_band_list_nr_for_paging.size() > 0) { j.start_array("supportedBandListNRForPaging"); for (const auto& e1 : supported_band_list_nr_for_paging) { j.write_int(e1); @@ -59821,19 +60085,19 @@ uint8_t ue_radio_paging_info_s::crit_exts_c_::types_opts::to_number() const // VarMeasConfig ::= SEQUENCE SRSASN_CODE var_meas_cfg_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(meas_id_list_present, 1)); - HANDLE_CODE(bref.pack(meas_obj_list_present, 1)); - HANDLE_CODE(bref.pack(report_cfg_list_present, 1)); + HANDLE_CODE(bref.pack(meas_id_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(meas_obj_list.size() > 0, 1)); + HANDLE_CODE(bref.pack(report_cfg_list.size() > 0, 1)); HANDLE_CODE(bref.pack(quant_cfg_present, 1)); HANDLE_CODE(bref.pack(s_measure_cfg_present, 1)); - if (meas_id_list_present) { + if (meas_id_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_id_list, 1, 64)); } - if (meas_obj_list_present) { + if (meas_obj_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, meas_obj_list, 1, 64)); } - if (report_cfg_list_present) { + if (report_cfg_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, report_cfg_list, 1, 64)); } if (quant_cfg_present) { @@ -59847,8 +60111,11 @@ SRSASN_CODE var_meas_cfg_s::pack(bit_ref& bref) const } SRSASN_CODE var_meas_cfg_s::unpack(cbit_ref& bref) { + bool meas_id_list_present; HANDLE_CODE(bref.unpack(meas_id_list_present, 1)); + bool meas_obj_list_present; HANDLE_CODE(bref.unpack(meas_obj_list_present, 1)); + bool report_cfg_list_present; HANDLE_CODE(bref.unpack(report_cfg_list_present, 1)); HANDLE_CODE(bref.unpack(quant_cfg_present, 1)); HANDLE_CODE(bref.unpack(s_measure_cfg_present, 1)); @@ -59874,21 +60141,21 @@ SRSASN_CODE var_meas_cfg_s::unpack(cbit_ref& bref) void var_meas_cfg_s::to_json(json_writer& j) const { j.start_obj(); - if (meas_id_list_present) { + if (meas_id_list.size() > 0) { j.start_array("measIdList"); for (const auto& e1 : meas_id_list) { e1.to_json(j); } j.end_array(); } - if (meas_obj_list_present) { + if (meas_obj_list.size() > 0) { j.start_array("measObjectList"); for (const auto& e1 : meas_obj_list) { e1.to_json(j); } j.end_array(); } - if (report_cfg_list_present) { + if (report_cfg_list.size() > 0) { j.start_array("reportConfigList"); for (const auto& e1 : report_cfg_list) { e1.to_json(j); @@ -60019,10 +60286,10 @@ const char* var_meas_cfg_s::s_measure_cfg_c_::types_opts::to_string() const // VarMeasReport ::= SEQUENCE SRSASN_CODE var_meas_report_s::pack(bit_ref& bref) const { - HANDLE_CODE(bref.pack(cells_triggered_list_present, 1)); + HANDLE_CODE(bref.pack(cells_triggered_list.size() > 0, 1)); HANDLE_CODE(pack_integer(bref, meas_id, (uint8_t)1u, (uint8_t)64u)); - if (cells_triggered_list_present) { + if (cells_triggered_list.size() > 0) { HANDLE_CODE(pack_dyn_seq_of(bref, cells_triggered_list, 1, 32)); } HANDLE_CODE(pack_unconstrained_integer(bref, nof_reports_sent)); @@ -60031,6 +60298,7 @@ SRSASN_CODE var_meas_report_s::pack(bit_ref& bref) const } SRSASN_CODE var_meas_report_s::unpack(cbit_ref& bref) { + bool cells_triggered_list_present; HANDLE_CODE(bref.unpack(cells_triggered_list_present, 1)); HANDLE_CODE(unpack_integer(meas_id, bref, (uint8_t)1u, (uint8_t)64u)); @@ -60045,7 +60313,7 @@ void var_meas_report_s::to_json(json_writer& j) const { j.start_obj(); j.write_int("measId", meas_id); - if (cells_triggered_list_present) { + if (cells_triggered_list.size() > 0) { j.start_array("cellsTriggeredList"); for (const auto& e1 : cells_triggered_list) { e1.to_json(j); diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 54256ebce2..b2f9d104fa 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,6 +20,7 @@ */ #include "srsran/asn1/rrc_nr_utils.h" +#include "srsran/asn1/obj_id_cmp_utils.h" #include "srsran/asn1/rrc_nr.h" #include "srsran/common/band_helper.h" #include "srsran/config.h" @@ -82,8 +83,7 @@ bool make_mac_dl_harq_cfg_nr_t(const pdsch_serving_cell_cfg_s& asn1_type, dl_har if (asn1_type.nrof_harq_processes_for_pdsch_present) { dl_harq_cfg_nr.nof_procs = asn1_type.nrof_harq_processes_for_pdsch.to_number(); } else { - asn1::log_warning("Option nrof_harq_processes_for_pdsch not present"); - return false; + dl_harq_cfg_nr.nof_procs = 8; } *out_dl_harq_cfg_nr = dl_harq_cfg_nr; return true; @@ -98,30 +98,53 @@ bool make_mac_phr_cfg_t(const phr_cfg_s& asn1_type, phr_cfg_nr_t* phr_cfg_nr) return true; } -rach_nr_cfg_t make_mac_rach_cfg(const rach_cfg_common_s& asn1_type) +void make_mac_rach_cfg(const rach_cfg_common_s& asn1_type, rach_cfg_nr_t* rach_cfg_nr) { - rach_nr_cfg_t rach_nr_cfg = {}; - rach_nr_cfg.powerRampingStep = asn1_type.rach_cfg_generic.pwr_ramp_step.to_number(); - rach_nr_cfg.ra_responseWindow = asn1_type.rach_cfg_generic.ra_resp_win.to_number(); - rach_nr_cfg.prach_ConfigurationIndex = asn1_type.rach_cfg_generic.prach_cfg_idx; - rach_nr_cfg.PreambleReceivedTargetPower = asn1_type.rach_cfg_generic.preamb_rx_target_pwr; - rach_nr_cfg.preambleTransMax = asn1_type.rach_cfg_generic.preamb_trans_max.to_number(); - rach_nr_cfg.ra_ContentionResolutionTimer = asn1_type.ra_contention_resolution_timer.to_number(); - return rach_nr_cfg; + rach_cfg_nr->powerRampingStep = asn1_type.rach_cfg_generic.pwr_ramp_step.to_number(); + rach_cfg_nr->ra_responseWindow = asn1_type.rach_cfg_generic.ra_resp_win.to_number(); + rach_cfg_nr->prach_ConfigurationIndex = asn1_type.rach_cfg_generic.prach_cfg_idx; + rach_cfg_nr->PreambleReceivedTargetPower = asn1_type.rach_cfg_generic.preamb_rx_target_pwr; + rach_cfg_nr->preambleTransMax = asn1_type.rach_cfg_generic.preamb_trans_max.to_number(); + rach_cfg_nr->ra_ContentionResolutionTimer = asn1_type.ra_contention_resolution_timer.to_number(); }; -int make_rlc_config_t(const rlc_cfg_c& asn1_type, rlc_config_t* cfg_out) +int make_rlc_config_t(const rlc_cfg_c& asn1_type, uint8_t bearer_id, rlc_config_t* cfg_out) { - rlc_config_t rlc_cfg = rlc_config_t::default_rlc_um_nr_config(); + rlc_config_t rlc_cfg = {}; rlc_cfg.rat = srsran_rat_t::nr; switch (asn1_type.type().value) { case rlc_cfg_c::types_opts::am: - asn1::log_warning("NR RLC type %s is not supported", asn1_type.type().to_string()); - return SRSRAN_ERROR; + rlc_cfg = rlc_config_t::default_rlc_am_nr_config(); + if (asn1_type.am().dl_am_rlc.sn_field_len_present && asn1_type.am().ul_am_rlc.sn_field_len_present && + asn1_type.am().dl_am_rlc.sn_field_len != asn1_type.am().ul_am_rlc.sn_field_len) { + asn1::log_warning("NR RLC sequence number length is not the same in uplink and downlink"); + return SRSRAN_ERROR; + } + rlc_cfg.rlc_mode = rlc_mode_t::am; + switch (asn1_type.am().dl_am_rlc.sn_field_len.value) { + case asn1::rrc_nr::sn_field_len_am_opts::options::size12: + rlc_cfg.am_nr.tx_sn_field_length = rlc_am_nr_sn_size_t::size12bits; + rlc_cfg.am_nr.rx_sn_field_length = rlc_am_nr_sn_size_t::size12bits; + break; + case asn1::rrc_nr::sn_field_len_am_opts::options::size18: + rlc_cfg.am_nr.tx_sn_field_length = rlc_am_nr_sn_size_t::size18bits; + rlc_cfg.am_nr.rx_sn_field_length = rlc_am_nr_sn_size_t::size18bits; + break; + default: + break; + } + rlc_cfg.am_nr.t_poll_retx = asn1_type.am().ul_am_rlc.t_poll_retx.to_number(); + rlc_cfg.am_nr.poll_pdu = asn1_type.am().ul_am_rlc.poll_pdu.to_number(); + rlc_cfg.am_nr.poll_byte = asn1_type.am().ul_am_rlc.poll_byte.to_number(); + rlc_cfg.am_nr.max_retx_thresh = asn1_type.am().ul_am_rlc.max_retx_thres.to_number(); + rlc_cfg.am_nr.t_reassembly = asn1_type.am().dl_am_rlc.t_reassembly.to_number(); + rlc_cfg.am_nr.t_status_prohibit = asn1_type.am().dl_am_rlc.t_status_prohibit.to_number(); + break; case rlc_cfg_c::types_opts::um_bi_dir: + rlc_cfg = rlc_config_t::default_rlc_um_nr_config(); rlc_cfg.rlc_mode = rlc_mode_t::um; rlc_cfg.um_nr.t_reassembly_ms = asn1_type.um_bi_dir().dl_um_rlc.t_reassembly.to_number(); - + rlc_cfg.um_nr.bearer_id = bearer_id; if (asn1_type.um_bi_dir().dl_um_rlc.sn_field_len_present && asn1_type.um_bi_dir().ul_um_rlc.sn_field_len_present && asn1_type.um_bi_dir().dl_um_rlc.sn_field_len != asn1_type.um_bi_dir().ul_um_rlc.sn_field_len) { @@ -139,6 +162,7 @@ int make_rlc_config_t(const rlc_cfg_c& asn1_type, rlc_config_t* cfg_out) default: break; } + rlc_cfg.um_nr.t_reassembly_ms = asn1_type.um_bi_dir().dl_um_rlc.t_reassembly.to_number(); break; case rlc_cfg_c::types_opts::um_uni_dir_dl: asn1::log_warning("NR RLC type %s is not supported", asn1_type.type().to_string()); @@ -154,6 +178,20 @@ int make_rlc_config_t(const rlc_cfg_c& asn1_type, rlc_config_t* cfg_out) return SRSRAN_SUCCESS; } +srsran::pdcp_config_t make_nr_srb_pdcp_config_t(const uint8_t bearer_id, bool is_ue) +{ + pdcp_config_t cfg(bearer_id, + PDCP_RB_IS_SRB, + is_ue ? SECURITY_DIRECTION_UPLINK : SECURITY_DIRECTION_DOWNLINK, + is_ue ? SECURITY_DIRECTION_DOWNLINK : SECURITY_DIRECTION_UPLINK, + PDCP_SN_LEN_12, + pdcp_t_reordering_t::ms500, + pdcp_discard_timer_t::infinity, + false, + srsran_rat_t::nr); + return cfg; +} + srsran::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue, const pdcp_cfg_s& pdcp_cfg) { // TODO: complete config processing @@ -213,14 +251,119 @@ srsran::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue } } - pdcp_t_reordering_t t_reordering = pdcp_t_reordering_t::ms500; + pdcp_t_reordering_t t_reordering = pdcp_t_reordering_t::infinity; if (pdcp_cfg.t_reordering_present) { switch (pdcp_cfg.t_reordering.to_number()) { case 0: t_reordering = pdcp_t_reordering_t::ms0; break; - default: + case 1: + t_reordering = pdcp_t_reordering_t::ms1; + break; + case 2: + t_reordering = pdcp_t_reordering_t::ms2; + break; + case 4: + t_reordering = pdcp_t_reordering_t::ms4; + break; + case 5: + t_reordering = pdcp_t_reordering_t::ms5; + break; + case 8: + t_reordering = pdcp_t_reordering_t::ms8; + break; + case 10: + t_reordering = pdcp_t_reordering_t::ms10; + break; + case 15: + t_reordering = pdcp_t_reordering_t::ms15; + break; + case 20: + t_reordering = pdcp_t_reordering_t::ms20; + break; + case 30: + t_reordering = pdcp_t_reordering_t::ms30; + break; + case 40: + t_reordering = pdcp_t_reordering_t::ms40; + break; + case 50: + t_reordering = pdcp_t_reordering_t::ms50; + break; + case 60: + t_reordering = pdcp_t_reordering_t::ms60; + break; + case 80: + t_reordering = pdcp_t_reordering_t::ms80; + break; + case 100: + t_reordering = pdcp_t_reordering_t::ms100; + break; + case 120: + t_reordering = pdcp_t_reordering_t::ms120; + break; + case 140: + t_reordering = pdcp_t_reordering_t::ms140; + break; + case 160: + t_reordering = pdcp_t_reordering_t::ms160; + break; + case 180: + t_reordering = pdcp_t_reordering_t::ms180; + break; + case 200: + t_reordering = pdcp_t_reordering_t::ms200; + break; + case 220: + t_reordering = pdcp_t_reordering_t::ms220; + break; + case 240: + t_reordering = pdcp_t_reordering_t::ms240; + break; + case 260: + t_reordering = pdcp_t_reordering_t::ms260; + break; + case 280: + t_reordering = pdcp_t_reordering_t::ms280; + break; + case 300: + t_reordering = pdcp_t_reordering_t::ms300; + break; + case 500: t_reordering = pdcp_t_reordering_t::ms500; + break; + case 750: + t_reordering = pdcp_t_reordering_t::ms750; + break; + case 1000: + t_reordering = pdcp_t_reordering_t::ms1000; + break; + case 1250: + t_reordering = pdcp_t_reordering_t::ms1250; + break; + case 1500: + t_reordering = pdcp_t_reordering_t::ms1500; + break; + case 1750: + t_reordering = pdcp_t_reordering_t::ms1750; + break; + case 2000: + t_reordering = pdcp_t_reordering_t::ms2000; + break; + case 2250: + t_reordering = pdcp_t_reordering_t::ms2250; + break; + case 2500: + t_reordering = pdcp_t_reordering_t::ms2500; + break; + case 2750: + t_reordering = pdcp_t_reordering_t::ms2750; + break; + case 3000: + t_reordering = pdcp_t_reordering_t::ms3000; + break; + default: + t_reordering = pdcp_t_reordering_t::ms50; } } @@ -249,14 +392,22 @@ srsran::pdcp_config_t make_drb_pdcp_config_t(const uint8_t bearer_id, bool is_ue return cfg; } -bool make_phy_rach_cfg(const rach_cfg_common_s& asn1_type, srsran_prach_cfg_t* prach_cfg) +bool make_phy_rach_cfg(const rach_cfg_common_s& asn1_type, + srsran_duplex_mode_t duplex_mode, + srsran_prach_cfg_t* prach_cfg) { prach_cfg->is_nr = true; prach_cfg->config_idx = asn1_type.rach_cfg_generic.prach_cfg_idx; prach_cfg->zero_corr_zone = (uint32_t)asn1_type.rach_cfg_generic.zero_correlation_zone_cfg; - prach_cfg->num_ra_preambles = 64; // Hard-coded - prach_cfg->hs_flag = false; // Hard-coded - prach_cfg->tdd_config = {}; // Hard-coded + prach_cfg->num_ra_preambles = 64; + if (asn1_type.total_nof_ra_preambs_present) { + prach_cfg->num_ra_preambles = asn1_type.total_nof_ra_preambs; + } + prach_cfg->hs_flag = false; // Hard-coded + prach_cfg->tdd_config = {}; + if (duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { + prach_cfg->tdd_config.configured = true; + } // As the current PRACH is based on LTE, the freq-offset shall be subtracted 1 for aligning with NR bandwidth // For example. A 52 PRB cell with an freq_offset of 1 will match a LTE 50 PRB cell with freq_offset of 0 @@ -266,11 +417,12 @@ bool make_phy_rach_cfg(const rach_cfg_common_s& asn1_type, srsran_prach_cfg_t* p return false; } - switch (prach_cfg->root_seq_idx = asn1_type.prach_root_seq_idx.type()) { + switch (asn1_type.prach_root_seq_idx.type().value) { case rach_cfg_common_s::prach_root_seq_idx_c_::types_opts::l839: prach_cfg->root_seq_idx = (uint32_t)asn1_type.prach_root_seq_idx.l839(); break; case rach_cfg_common_s::prach_root_seq_idx_c_::types_opts::l139: + prach_cfg->root_seq_idx = (uint32_t)asn1_type.prach_root_seq_idx.l139(); default: asn1::log_error("Not-implemented option for prach_root_seq_idx type %s", asn1_type.prach_root_seq_idx.type().to_string()); @@ -280,6 +432,40 @@ bool make_phy_rach_cfg(const rach_cfg_common_s& asn1_type, srsran_prach_cfg_t* p return true; }; +bool fill_rach_cfg_common(const srsran_prach_cfg_t& prach_cfg, asn1::rrc_nr::rach_cfg_common_s& asn1_type) +{ + asn1_type = {}; + // rach-ConfigGeneric + asn1_type.rach_cfg_generic.prach_cfg_idx = prach_cfg.config_idx; + asn1_type.rach_cfg_generic.msg1_fdm.value = rach_cfg_generic_s::msg1_fdm_opts::one; + asn1_type.rach_cfg_generic.msg1_freq_start = prach_cfg.freq_offset; + asn1_type.rach_cfg_generic.zero_correlation_zone_cfg = prach_cfg.zero_corr_zone; + asn1_type.rach_cfg_generic.preamb_rx_target_pwr = -110; + asn1_type.rach_cfg_generic.preamb_trans_max.value = rach_cfg_generic_s::preamb_trans_max_opts::n7; + asn1_type.rach_cfg_generic.pwr_ramp_step.value = rach_cfg_generic_s::pwr_ramp_step_opts::db4; + asn1_type.rach_cfg_generic.ra_resp_win.value = rach_cfg_generic_s::ra_resp_win_opts::sl10; + + // totalNumberOfRA-Preambles + if (prach_cfg.num_ra_preambles != 64) { + asn1_type.total_nof_ra_preambs_present = true; + asn1_type.total_nof_ra_preambs = prach_cfg.num_ra_preambles; + } + + // ssb-perRACH-OccasionAndCB-PreamblesPerSSB + asn1_type.ssb_per_rach_occasion_and_cb_preambs_per_ssb_present = true; + if (not asn1::number_to_enum(asn1_type.ssb_per_rach_occasion_and_cb_preambs_per_ssb.set_one(), + prach_cfg.num_ra_preambles)) { + asn1::log_error("Invalid number of RA preambles=%d", prach_cfg.num_ra_preambles); + return false; + } + + asn1_type.ra_contention_resolution_timer.value = rach_cfg_common_s::ra_contention_resolution_timer_opts::sf64; + asn1_type.prach_root_seq_idx.set_l839() = prach_cfg.root_seq_idx; + asn1_type.restricted_set_cfg.value = rach_cfg_common_s::restricted_set_cfg_opts::unrestricted_set; + + return true; +} + bool make_phy_tdd_cfg(const tdd_ul_dl_cfg_common_s& tdd_ul_dl_cfg_common, srsran_duplex_config_nr_t* in_srsran_duplex_config_nr) { @@ -313,43 +499,103 @@ bool make_phy_tdd_cfg(const tdd_ul_dl_cfg_common_s& tdd_ul_dl_cfg_common, srsran_duplex_config_nr.tdd.pattern1.nof_dl_symbols = tdd_ul_dl_cfg_common.pattern1.nrof_dl_symbols; srsran_duplex_config_nr.tdd.pattern1.nof_ul_slots = tdd_ul_dl_cfg_common.pattern1.nrof_ul_slots; srsran_duplex_config_nr.tdd.pattern1.nof_ul_symbols = tdd_ul_dl_cfg_common.pattern1.nrof_ul_symbols; + + if (tdd_ul_dl_cfg_common.pattern2_present) { + switch (tdd_ul_dl_cfg_common.pattern2.dl_ul_tx_periodicity) { + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1: + srsran_duplex_config_nr.tdd.pattern2.period_ms = 1; + break; + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms2: + srsran_duplex_config_nr.tdd.pattern2.period_ms = 2; + break; + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms5: + srsran_duplex_config_nr.tdd.pattern2.period_ms = 5; + break; + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10: + srsran_duplex_config_nr.tdd.pattern2.period_ms = 10; + break; + + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1p25: + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms0p5: + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms0p625: + case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms2p5: + default: + asn1::log_warning("Invalid option for pattern2 dl_ul_tx_periodicity_opts %s", + tdd_ul_dl_cfg_common.pattern2.dl_ul_tx_periodicity.to_string()); + return false; + } + + srsran_duplex_config_nr.tdd.pattern2.nof_dl_slots = tdd_ul_dl_cfg_common.pattern2.nrof_dl_slots; + srsran_duplex_config_nr.tdd.pattern2.nof_dl_symbols = tdd_ul_dl_cfg_common.pattern2.nrof_dl_symbols; + srsran_duplex_config_nr.tdd.pattern2.nof_ul_slots = tdd_ul_dl_cfg_common.pattern2.nrof_ul_slots; + srsran_duplex_config_nr.tdd.pattern2.nof_ul_symbols = tdd_ul_dl_cfg_common.pattern2.nrof_ul_symbols; + } + // Copy and return struct *in_srsran_duplex_config_nr = srsran_duplex_config_nr; - if (not tdd_ul_dl_cfg_common.pattern2_present) { + return true; +} + +bool make_phy_tdd_cfg(const srsran_duplex_config_nr_t& srsran_duplex_config_nr, + srsran_subcarrier_spacing_t scs, + asn1::rrc_nr::tdd_ul_dl_cfg_common_s* tdd_ul_dl_cfg_common) +{ + if (srsran_duplex_config_nr.mode == SRSRAN_DUPLEX_MODE_FDD) { return true; } + tdd_ul_dl_cfg_common->ref_subcarrier_spacing.value = (asn1::rrc_nr::subcarrier_spacing_e::options)scs; - switch (tdd_ul_dl_cfg_common.pattern2.dl_ul_tx_periodicity) { - case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1: - srsran_duplex_config_nr.tdd.pattern2.period_ms = 1; + switch (srsran_duplex_config_nr.tdd.pattern1.period_ms) { + case 1: + tdd_ul_dl_cfg_common->pattern1.dl_ul_tx_periodicity = tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1; break; - case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms2: - srsran_duplex_config_nr.tdd.pattern2.period_ms = 2; + case 2: + tdd_ul_dl_cfg_common->pattern1.dl_ul_tx_periodicity = tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms2; break; - case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms5: - srsran_duplex_config_nr.tdd.pattern2.period_ms = 5; + case 5: + tdd_ul_dl_cfg_common->pattern1.dl_ul_tx_periodicity = tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms5; break; - case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10: - srsran_duplex_config_nr.tdd.pattern2.period_ms = 10; + case 10: + tdd_ul_dl_cfg_common->pattern1.dl_ul_tx_periodicity = tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10; break; - - case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1p25: - case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms0p5: - case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms0p625: - case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms2p5: default: - asn1::log_warning("Invalid option for pattern2 dl_ul_tx_periodicity_opts %s", - tdd_ul_dl_cfg_common.pattern2.dl_ul_tx_periodicity.to_string()); + asn1::log_warning("Invalid option for dl_ul_tx_periodicity_opts %d", + srsran_duplex_config_nr.tdd.pattern1.period_ms); return false; } + tdd_ul_dl_cfg_common->pattern1.nrof_dl_slots = srsran_duplex_config_nr.tdd.pattern1.nof_dl_slots; + tdd_ul_dl_cfg_common->pattern1.nrof_dl_symbols = srsran_duplex_config_nr.tdd.pattern1.nof_dl_symbols; + tdd_ul_dl_cfg_common->pattern1.nrof_ul_slots = srsran_duplex_config_nr.tdd.pattern1.nof_ul_slots; + tdd_ul_dl_cfg_common->pattern1.nrof_ul_symbols = srsran_duplex_config_nr.tdd.pattern1.nof_ul_symbols; - srsran_duplex_config_nr.tdd.pattern2.nof_dl_slots = tdd_ul_dl_cfg_common.pattern2.nrof_dl_slots; - srsran_duplex_config_nr.tdd.pattern2.nof_dl_symbols = tdd_ul_dl_cfg_common.pattern2.nrof_dl_symbols; - srsran_duplex_config_nr.tdd.pattern2.nof_ul_slots = tdd_ul_dl_cfg_common.pattern2.nrof_ul_slots; - srsran_duplex_config_nr.tdd.pattern2.nof_ul_symbols = tdd_ul_dl_cfg_common.pattern2.nrof_ul_symbols; - // Copy and return struct - *in_srsran_duplex_config_nr = srsran_duplex_config_nr; + if (srsran_duplex_config_nr.tdd.pattern2.period_ms == 0) { + return true; + } + + tdd_ul_dl_cfg_common->pattern2_present = true; + switch (srsran_duplex_config_nr.tdd.pattern2.period_ms) { + case 1: + tdd_ul_dl_cfg_common->pattern2.dl_ul_tx_periodicity.value = tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1; + break; + case 2: + tdd_ul_dl_cfg_common->pattern2.dl_ul_tx_periodicity.value = tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms2; + break; + case 5: + tdd_ul_dl_cfg_common->pattern2.dl_ul_tx_periodicity.value = tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms5; + break; + case 10: + tdd_ul_dl_cfg_common->pattern2.dl_ul_tx_periodicity.value = tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10; + break; + default: + asn1::log_warning("Invalid option for pattern2 dl_ul_tx_periodicity_opts %d", + srsran_duplex_config_nr.tdd.pattern2.period_ms); + return false; + } + tdd_ul_dl_cfg_common->pattern2.nrof_dl_slots = srsran_duplex_config_nr.tdd.pattern2.nof_dl_slots; + tdd_ul_dl_cfg_common->pattern2.nrof_dl_symbols = srsran_duplex_config_nr.tdd.pattern2.nof_dl_symbols; + tdd_ul_dl_cfg_common->pattern2.nrof_ul_slots = srsran_duplex_config_nr.tdd.pattern2.nof_ul_slots; + tdd_ul_dl_cfg_common->pattern2.nrof_ul_symbols = srsran_duplex_config_nr.tdd.pattern2.nof_ul_symbols; return true; } @@ -377,6 +623,21 @@ bool make_phy_harq_ack_cfg(const phys_cell_group_cfg_s& phys_cell_group_cfg, return true; } +void make_phy_search_space0_cfg(srsran_search_space_t* in_srsran_search_space) +{ + in_srsran_search_space->id = 0; + in_srsran_search_space->coreset_id = 0; + in_srsran_search_space->type = srsran_search_space_type_common_0; + in_srsran_search_space->nof_candidates[0] = 0; + in_srsran_search_space->nof_candidates[1] = 0; + in_srsran_search_space->nof_candidates[2] = 4; + in_srsran_search_space->nof_candidates[3] = 2; + in_srsran_search_space->nof_candidates[4] = 0; + in_srsran_search_space->nof_formats = 1; + in_srsran_search_space->formats[0] = srsran_dci_format_nr_1_0; + in_srsran_search_space->duration = 1; +} + bool make_phy_search_space_cfg(const search_space_s& search_space, srsran_search_space_t* in_srsran_search_space) { srsran_search_space_t srsran_search_space = {}; @@ -490,42 +751,41 @@ bool make_phy_csi_report(const csi_report_cfg_s& csi_report_cfg, } if (srsran_csi_hl_report_cfg.type == SRSRAN_CSI_REPORT_TYPE_PERIODIC) { - srsran_csi_hl_report_cfg.periodic.period = - csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.type().to_number(); - switch (csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.type()) { + const auto& csi_periodic = csi_report_cfg.report_cfg_type.periodic(); + srsran_csi_hl_report_cfg.periodic.period = csi_periodic.report_slot_cfg.type().to_number(); + switch (csi_periodic.report_slot_cfg.type()) { case csi_report_periodicity_and_offset_c::types_opts::slots4: - srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots4(); + srsran_csi_hl_report_cfg.periodic.offset = csi_periodic.report_slot_cfg.slots4(); break; case csi_report_periodicity_and_offset_c::types_opts::slots5: - srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots5(); + srsran_csi_hl_report_cfg.periodic.offset = csi_periodic.report_slot_cfg.slots5(); break; case csi_report_periodicity_and_offset_c::types_opts::slots8: - srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots8(); + srsran_csi_hl_report_cfg.periodic.offset = csi_periodic.report_slot_cfg.slots8(); break; case csi_report_periodicity_and_offset_c::types_opts::slots10: - srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots10(); + srsran_csi_hl_report_cfg.periodic.offset = csi_periodic.report_slot_cfg.slots10(); break; case csi_report_periodicity_and_offset_c::types_opts::slots16: - srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots16(); + srsran_csi_hl_report_cfg.periodic.offset = csi_periodic.report_slot_cfg.slots16(); break; case csi_report_periodicity_and_offset_c::types_opts::slots20: - srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots20(); + srsran_csi_hl_report_cfg.periodic.offset = csi_periodic.report_slot_cfg.slots20(); break; case csi_report_periodicity_and_offset_c::types_opts::slots40: - srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots40(); + srsran_csi_hl_report_cfg.periodic.offset = csi_periodic.report_slot_cfg.slots40(); break; case csi_report_periodicity_and_offset_c::types_opts::slots80: - srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots80(); + srsran_csi_hl_report_cfg.periodic.offset = csi_periodic.report_slot_cfg.slots80(); break; case csi_report_periodicity_and_offset_c::types_opts::slots160: - srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots160(); + srsran_csi_hl_report_cfg.periodic.offset = csi_periodic.report_slot_cfg.slots160(); break; case csi_report_periodicity_and_offset_c::types_opts::slots320: - srsran_csi_hl_report_cfg.periodic.offset = csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.slots320(); + srsran_csi_hl_report_cfg.periodic.offset = csi_periodic.report_slot_cfg.slots320(); break; default: - asn1::log_warning("Invalid option for report_slot_cfg %s", - csi_report_cfg.report_cfg_type.periodic().report_slot_cfg.type().to_string()); + asn1::log_warning("Invalid option for report_slot_cfg %s", csi_periodic.report_slot_cfg.type().to_string()); return false; } } @@ -609,6 +869,7 @@ bool make_phy_csi_report(const csi_report_cfg_s& csi_report_cfg, asn1::log_warning("Invalid option for cqi_table %s", csi_report_cfg.cqi_table.to_string()); return false; } + *in_srsran_csi_hl_report_cfg = srsran_csi_hl_report_cfg; return true; } @@ -715,6 +976,10 @@ bool make_phy_res_config(const pucch_res_s& pucch_res, { srsran_pucch_nr_resource_t srsran_pucch_nr_resource = {}; srsran_pucch_nr_resource.starting_prb = pucch_res.start_prb; + srsran_pucch_nr_resource.intra_slot_hopping = pucch_res.intra_slot_freq_hop_present; + if (pucch_res.second_hop_prb_present) { + srsran_pucch_nr_resource.second_hop_prb = pucch_res.second_hop_prb; + } switch (pucch_res.format.type()) { case pucch_res_s::format_c_::types_opts::format0: srsran_pucch_nr_resource.format = SRSRAN_PUCCH_NR_FORMAT_0; @@ -1002,8 +1267,8 @@ bool make_phy_pusch_scaling(const uci_on_pusch_s& uci_on_pusch, float* in_scalin bool make_phy_zp_csi_rs_resource(const asn1::rrc_nr::zp_csi_rs_res_s& zp_csi_rs_res, srsran_csi_rs_zp_resource_t* out_zp_csi_rs_resource) { - srsran_csi_rs_zp_resource_t zp_csi_rs_resource; - zp_csi_rs_resource.id = zp_csi_rs_res.zp_csi_rs_res_id; + srsran_csi_rs_zp_resource_t zp_csi_rs_resource = {}; + zp_csi_rs_resource.id = zp_csi_rs_res.zp_csi_rs_res_id; switch (zp_csi_rs_res.res_map.freq_domain_alloc.type()) { case csi_rs_res_map_s::freq_domain_alloc_c_::types_opts::options::row1: zp_csi_rs_resource.resource_mapping.row = srsran_csi_rs_resource_mapping_row_1; @@ -1167,8 +1432,8 @@ bool make_phy_zp_csi_rs_resource(const asn1::rrc_nr::zp_csi_rs_res_s& zp_csi_rs_ bool make_phy_nzp_csi_rs_resource(const asn1::rrc_nr::nzp_csi_rs_res_s& asn1_nzp_csi_rs_res, srsran_csi_rs_nzp_resource_t* out_csi_rs_nzp_resource) { - srsran_csi_rs_nzp_resource_t csi_rs_nzp_resource; - csi_rs_nzp_resource.id = asn1_nzp_csi_rs_res.nzp_csi_rs_res_id; + srsran_csi_rs_nzp_resource_t csi_rs_nzp_resource = {}; + csi_rs_nzp_resource.id = asn1_nzp_csi_rs_res.nzp_csi_rs_res_id; switch (asn1_nzp_csi_rs_res.res_map.freq_domain_alloc.type()) { case csi_rs_res_map_s::freq_domain_alloc_c_::types_opts::options::row1: csi_rs_nzp_resource.resource_mapping.row = srsran_csi_rs_resource_mapping_row_1; @@ -1407,6 +1672,91 @@ static inline void make_ssb_positions_in_burst(const bitstring_t& } } +void fill_ssb_pos_in_burst(const asn1::rrc_nr::serving_cell_cfg_common_sib_s& cfg, phy_cfg_nr_t::ssb_cfg_t* out_ssb) +{ + auto& ssb_pos = cfg.ssb_positions_in_burst; + + out_ssb->position_in_burst = {}; + uint32_t N = ssb_pos.in_one_group.length(); + for (uint32_t i = 0; i < N; ++i) { + out_ssb->position_in_burst[i] = ssb_pos.in_one_group.get(i); + } + if (ssb_pos.group_presence_present) { + for (uint32_t i = 1; i < ssb_pos.group_presence.length(); ++i) { + if (ssb_pos.group_presence.get(i)) { + std::copy(out_ssb->position_in_burst.begin(), + out_ssb->position_in_burst.begin() + N, + out_ssb->position_in_burst.begin() + i * N); + } + } + } +} + +bool fill_ssb_pattern_scs(const srsran_carrier_nr_t& carrier, + srsran_ssb_pattern_t* pattern, + srsran_subcarrier_spacing_t* ssb_scs) +{ + srsran::srsran_band_helper bands; + uint16_t band = bands.get_band_from_dl_freq_Hz(carrier.ssb_center_freq_hz); + if (band == UINT16_MAX) { + asn1::log_error("Invalid band for SSB frequency %.3f MHz", carrier.ssb_center_freq_hz); + return false; + } + + // TODO: Generalize conversion for other SCS + *pattern = bands.get_ssb_pattern(band, srsran_subcarrier_spacing_15kHz); + if (*pattern == SRSRAN_SSB_PATTERN_A) { + *ssb_scs = carrier.scs; + } else { + // try to optain SSB pattern for same band with 30kHz SCS + *pattern = bands.get_ssb_pattern(band, srsran_subcarrier_spacing_30kHz); + if (*pattern == SRSRAN_SSB_PATTERN_B || *pattern == SRSRAN_SSB_PATTERN_C) { + // SSB SCS is 30 kHz + *ssb_scs = srsran_subcarrier_spacing_30kHz; + } else { + asn1::log_error("Can't derive SSB pattern from band %d", band); + return false; + } + } + return true; +} + +bool fill_phy_ssb_cfg(const srsran_carrier_nr_t& carrier, + const asn1::rrc_nr::serving_cell_cfg_common_sib_s& serv_cell_cfg, + srsran_ssb_cfg_t* out_ssb) +{ + *out_ssb = {}; + + out_ssb->center_freq_hz = carrier.dl_center_frequency_hz; + out_ssb->ssb_freq_hz = carrier.ssb_center_freq_hz; + if (not fill_ssb_pattern_scs(carrier, &out_ssb->pattern, &out_ssb->scs)) { + return false; + } + + out_ssb->duplex_mode = SRSRAN_DUPLEX_MODE_FDD; + if (serv_cell_cfg.tdd_ul_dl_cfg_common_present) { + out_ssb->duplex_mode = SRSRAN_DUPLEX_MODE_TDD; + } + + out_ssb->periodicity_ms = serv_cell_cfg.ssb_periodicity_serving_cell.to_number(); + return true; +} + +// SA case +bool fill_phy_ssb_cfg(const srsran_carrier_nr_t& carrier, + const asn1::rrc_nr::serving_cell_cfg_common_sib_s& serv_cell_cfg, + phy_cfg_nr_t::ssb_cfg_t* out_ssb) +{ + // Derive SSB pattern and SCS + if (not fill_ssb_pattern_scs(carrier, &out_ssb->pattern, &out_ssb->scs)) { + return false; + } + fill_ssb_pos_in_burst(serv_cell_cfg, out_ssb); + out_ssb->periodicity_ms = (uint32_t)serv_cell_cfg.ssb_periodicity_serving_cell.to_number(); + + return true; +} + bool make_phy_ssb_cfg(const srsran_carrier_nr_t& carrier, const asn1::rrc_nr::serving_cell_cfg_common_s& serv_cell_cfg, phy_cfg_nr_t::ssb_cfg_t* out_ssb) @@ -1489,32 +1839,45 @@ bool make_phy_ssb_cfg(const srsran_carrier_nr_t& carrier, return true; } +bool make_phy_mib(const asn1::rrc_nr::mib_s& mib_cfg, srsran_mib_nr_t* mib) +{ + mib->sfn = 0; + mib->ssb_idx = 0; + mib->hrf = false; + mib->scs_common = + mib_cfg.sub_carrier_spacing_common.value == asn1::rrc_nr::mib_s::sub_carrier_spacing_common_opts::scs15or60 + ? srsran_subcarrier_spacing_15kHz + : srsran_subcarrier_spacing_30kHz; + mib->ssb_offset = mib_cfg.ssb_subcarrier_offset; + mib->dmrs_typeA_pos = (srsran_dmrs_sch_typeA_pos_t)mib_cfg.dmrs_type_a_position.value; + mib->coreset0_idx = mib_cfg.pdcch_cfg_sib1.ctrl_res_set_zero; + mib->ss0_idx = mib_cfg.pdcch_cfg_sib1.search_space_zero; + mib->cell_barred = mib_cfg.cell_barred.value == asn1::rrc_nr::mib_s::cell_barred_opts::barred; + mib->intra_freq_reselection = mib_cfg.intra_freq_resel.value == asn1::rrc_nr::mib_s::intra_freq_resel_opts::allowed; + return true; +} + bool make_pdsch_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_sch_hl_cfg_nr_t* sch_hl) { - if (serv_cell.csi_meas_cfg_present and - serv_cell.csi_meas_cfg.type().value == - setup_release_c< ::asn1::rrc_nr::csi_meas_cfg_s>::types_opts::options::setup) { + if (serv_cell.csi_meas_cfg_present and serv_cell.csi_meas_cfg.is_setup()) { auto& setup = serv_cell.csi_meas_cfg.setup(); // Configure NZP-CSI - if (setup.nzp_csi_rs_res_set_to_add_mod_list_present) { - for (auto& nzp_set : setup.nzp_csi_rs_res_set_to_add_mod_list) { - auto& uecfg_set = sch_hl->nzp_csi_rs_sets[nzp_set.nzp_csi_res_set_id]; - uecfg_set.trs_info = nzp_set.trs_info_present; - uecfg_set.count = nzp_set.nzp_csi_rs_res.size(); - uint32_t count = 0; - for (uint8_t nzp_rs_idx : nzp_set.nzp_csi_rs_res) { - auto& res = uecfg_set.data[count++]; - if (not srsran::make_phy_nzp_csi_rs_resource(setup.nzp_csi_rs_res_to_add_mod_list[nzp_rs_idx], &res)) { - return false; - } + for (auto& nzp_set : setup.nzp_csi_rs_res_set_to_add_mod_list) { + auto& uecfg_set = sch_hl->nzp_csi_rs_sets[nzp_set.nzp_csi_res_set_id]; + uecfg_set.trs_info = nzp_set.trs_info_present; + uecfg_set.count = nzp_set.nzp_csi_rs_res.size(); + uint32_t count = 0; + for (uint8_t nzp_rs_idx : nzp_set.nzp_csi_rs_res) { + auto& res = uecfg_set.data[count++]; + if (not srsran::make_phy_nzp_csi_rs_resource(setup.nzp_csi_rs_res_to_add_mod_list[nzp_rs_idx], &res)) { + return false; } } } } - if (serv_cell.init_dl_bwp.pdsch_cfg_present and - serv_cell.init_dl_bwp.pdsch_cfg.type() == setup_release_c::types_opts::setup) { + if (serv_cell.init_dl_bwp.pdsch_cfg_present and serv_cell.init_dl_bwp.pdsch_cfg.is_setup()) { const auto& setup = serv_cell.init_dl_bwp.pdsch_cfg.setup(); if (setup.p_zp_csi_rs_res_set_present) { auto& setup_set = setup.p_zp_csi_rs_res_set.setup(); @@ -1534,16 +1897,27 @@ bool make_pdsch_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_ bool make_csi_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_s& serv_cell, srsran_csi_hl_cfg_t* csi_hl) { - if (serv_cell.csi_meas_cfg_present and - serv_cell.csi_meas_cfg.type().value == - setup_release_c< ::asn1::rrc_nr::csi_meas_cfg_s>::types_opts::options::setup) { + if (serv_cell.csi_meas_cfg_present and serv_cell.csi_meas_cfg.is_setup()) { auto& setup = serv_cell.csi_meas_cfg.setup(); // Configure CSI-Report - if (setup.csi_report_cfg_to_add_mod_list_present) { - for (uint32_t i = 0; i < setup.csi_report_cfg_to_add_mod_list.size(); ++i) { - const auto& csi_rep = setup.csi_report_cfg_to_add_mod_list[i]; - if (not make_phy_csi_report(csi_rep, &csi_hl->reports[i])) { + for (uint32_t i = 0; i < setup.csi_report_cfg_to_add_mod_list.size(); ++i) { + const auto& csi_rep = setup.csi_report_cfg_to_add_mod_list[i]; + if (not make_phy_csi_report(csi_rep, &csi_hl->reports[i])) { + return false; + } + if (csi_rep.report_cfg_type.type().value == csi_report_cfg_s::report_cfg_type_c_::types_opts::periodic) { + const auto& pucch_setup = serv_cell.ul_cfg.init_ul_bwp.pucch_cfg.setup(); + srsran_pucch_nr_resource_t& resource = csi_hl->reports[i].periodic.resource; + uint32_t pucch_resource_id = csi_rep.report_cfg_type.periodic().pucch_csi_res_list[0].pucch_res; + const auto& asn1_resource = pucch_setup.res_to_add_mod_list[pucch_resource_id]; + uint32_t format2_rate = 0; + if (pucch_setup.format2_present and + pucch_setup.format2.type().value == asn1::setup_release_c::types_opts::setup and + pucch_setup.format2.setup().max_code_rate_present) { + format2_rate = pucch_setup.format2.setup().max_code_rate.to_number(); + } + if (not make_phy_res_config(asn1_resource, format2_rate, &resource)) { return false; } } @@ -1567,18 +1941,14 @@ bool make_duplex_cfg_from_serv_cell(const asn1::rrc_nr::serving_cell_cfg_common_ bool fill_phy_pdcch_cfg(const asn1::rrc_nr::pdcch_cfg_s& pdcch_cfg, srsran_pdcch_cfg_nr_t* pdcch) { - if (pdcch_cfg.ctrl_res_set_to_add_mod_list_present) { - for (const ctrl_res_set_s& coreset : pdcch_cfg.ctrl_res_set_to_add_mod_list) { - pdcch->coreset_present[coreset.ctrl_res_set_id] = true; - make_phy_coreset_cfg(coreset, &pdcch->coreset[coreset.ctrl_res_set_id]); - } + for (const ctrl_res_set_s& coreset : pdcch_cfg.ctrl_res_set_to_add_mod_list) { + pdcch->coreset_present[coreset.ctrl_res_set_id] = true; + make_phy_coreset_cfg(coreset, &pdcch->coreset[coreset.ctrl_res_set_id]); } - if (pdcch_cfg.search_spaces_to_add_mod_list_present) { - for (const search_space_s& ss : pdcch_cfg.search_spaces_to_add_mod_list) { - pdcch->search_space_present[ss.search_space_id] = true; - make_phy_search_space_cfg(ss, &pdcch->search_space[ss.search_space_id]); - } + for (const search_space_s& ss : pdcch_cfg.search_spaces_to_add_mod_list) { + pdcch->search_space_present[ss.search_space_id] = true; + make_phy_search_space_cfg(ss, &pdcch->search_space[ss.search_space_id]); } return true; } @@ -1589,47 +1959,225 @@ bool fill_phy_pdcch_cfg_common(const asn1::rrc_nr::pdcch_cfg_common_s& pdcch_cfg pdcch->coreset_present[pdcch_cfg.common_ctrl_res_set.ctrl_res_set_id] = true; make_phy_coreset_cfg(pdcch_cfg.common_ctrl_res_set, &pdcch->coreset[pdcch_cfg.common_ctrl_res_set.ctrl_res_set_id]); } - if (pdcch_cfg.common_search_space_list_present) { - for (const search_space_s& ss : pdcch_cfg.common_search_space_list) { - pdcch->search_space_present[ss.search_space_id] = true; - make_phy_search_space_cfg(ss, &pdcch->search_space[ss.search_space_id]); - if (pdcch_cfg.ra_search_space_present and pdcch_cfg.ra_search_space == ss.search_space_id) { - pdcch->ra_search_space_present = true; - pdcch->ra_search_space = pdcch->search_space[ss.search_space_id]; + for (const search_space_s& ss : pdcch_cfg.common_search_space_list) { + pdcch->search_space_present[ss.search_space_id] = true; + if (not make_phy_search_space_cfg(ss, &pdcch->search_space[ss.search_space_id])) { + asn1::log_error("Failed to convert SearchSpace Configuration"); + return false; + } + if (pdcch_cfg.ra_search_space_present and pdcch_cfg.ra_search_space == ss.search_space_id) { + pdcch->ra_search_space_present = true; + pdcch->ra_search_space = pdcch->search_space[ss.search_space_id]; + pdcch->ra_search_space.type = srsran_search_space_type_common_1; + pdcch->ra_search_space.nof_formats = 1; + pdcch->ra_search_space.formats[0] = srsran_dci_format_nr_1_0; + } + } + return true; +} + +void fill_phy_pucch_cfg_common(const asn1::rrc_nr::pucch_cfg_common_s& pucch_cfg, srsran_pucch_nr_common_cfg_t* pucch) +{ + if (pucch_cfg.pucch_res_common_present) { + pucch->resource_common = pucch_cfg.pucch_res_common; + } + if (pucch_cfg.hop_id_present) { + pucch->hopping_id_present = true; + pucch->hopping_id = pucch_cfg.hop_id; + } + if (pucch_cfg.p0_nominal_present) { + pucch->p0_nominal = pucch_cfg.p0_nominal; + } + + switch (pucch_cfg.pucch_group_hop) { + case pucch_cfg_common_s::pucch_group_hop_opts::enable: + pucch->group_hopping = SRSRAN_PUCCH_NR_GROUP_HOPPING_ENABLE; + break; + case pucch_cfg_common_s::pucch_group_hop_opts::disable: + pucch->group_hopping = SRSRAN_PUCCH_NR_GROUP_HOPPING_DISABLE; + break; + default: + pucch->group_hopping = SRSRAN_PUCCH_NR_GROUP_HOPPING_NEITHER; + break; + } +} + +bool fill_phy_pucch_cfg(const asn1::rrc_nr::pucch_cfg_s& pucch_cfg, srsran_pucch_nr_hl_cfg_t* pucch) +{ + // sanity check to avoid pucch->sets[n] goes out of bound + if (pucch_cfg.res_set_to_add_mod_list.size() > SRSRAN_PUCCH_NR_MAX_NOF_SETS) { + return false; + } + + // iterate over the sets of resourceSetToAddModList + for (size_t n = 0; n < pucch_cfg.res_set_to_add_mod_list.size(); n++) { + auto& res_set = pucch_cfg.res_set_to_add_mod_list[n]; + pucch->sets[n].nof_resources = res_set.res_list.size(); + if (res_set.max_payload_size_present) { + pucch->sets[n].max_payload_size = res_set.max_payload_size; + } + // NOTE: res_set.pucch_res_set_id does not have a corresponding field in the PHY struct + + // for each set, iterate over the elements (an element is an index). For each of the element or index, find the + // corresponding pucch_res_s object in the pucch_cfg.res_to_add_mod_list + for (size_t res_idx = 0; res_idx < res_set.res_list.size(); res_idx++) { + size_t pucch_resource_id = res_set.res_list[res_idx]; + + // Find the pucch_res_s object corresponding to pucch_resource_id in the pucch_cfg.res_to_add_mod_list + size_t m = 0; + while (m <= pucch_cfg.res_to_add_mod_list.size()) { + if (m == pucch_cfg.res_to_add_mod_list.size()) { + // if we get here, the list pucch_cfg.res_to_add_mod_list does not contain any object corresponding to + // pucch_resource_id + return false; + } + if (pucch_cfg.res_to_add_mod_list[m].pucch_res_id == pucch_resource_id) { + break; // item found, exit the loop + } + m++; + } + + // Below is the object corresponding to pucch_resource_id in the pucch_cfg.res_to_add_mod_list + const auto& asn1_resource = pucch_cfg.res_to_add_mod_list[m]; + + // sanity check to avoid pucch->sets[n].resources[res_idx] goes out of bound; + if (res_idx >= SRSRAN_PUCCH_NR_MAX_NOF_RESOURCES_PER_SET) { + return false; + } + + auto& resource = pucch->sets[n].resources[res_idx]; + uint32_t format2_rate = 0; + if (pucch_cfg.format2_present and + pucch_cfg.format2.type().value == asn1::setup_release_c::types_opts::setup and + pucch_cfg.format2.setup().max_code_rate_present) { + format2_rate = pucch_cfg.format2.setup().max_code_rate.to_number(); + } + if (not make_phy_res_config(asn1_resource, format2_rate, &resource)) { + return false; } } } - return true; + // configure scheduling request resources + return fill_phy_pucch_hl_cfg(pucch_cfg, pucch); } -} // namespace srsran +bool fill_phy_pucch_hl_cfg(const asn1::rrc_nr::pucch_cfg_s& pucch_cfg, srsran_pucch_nr_hl_cfg_t* pucch) +{ + for (size_t n = 0; n < pucch_cfg.sched_request_res_to_add_mod_list.size(); n++) { + // fill each sr_resource's cnf + auto& asn_sr_res = pucch_cfg.sched_request_res_to_add_mod_list[n]; + srsran_pucch_nr_sr_resource_t* sr_res = &pucch->sr_resources[asn_sr_res.sched_request_res_id]; + make_phy_sr_resource(asn_sr_res, sr_res); + + // get the pucch_resource from pucch_cfg.res_to_add_mod_list and copy it into the sr_resouce.resource + const auto& asn1_pucch_resource = pucch_cfg.res_to_add_mod_list[asn_sr_res.res]; + auto& pucch_resource = sr_res->resource; + uint32_t format2_rate = 0; + if (pucch_cfg.format2_present and + pucch_cfg.format2.type().value == asn1::setup_release_c::types_opts::setup and + pucch_cfg.format2.setup().max_code_rate_present) { + format2_rate = pucch_cfg.format2.setup().max_code_rate.to_number(); + } + if (not make_phy_res_config(asn1_pucch_resource, format2_rate, &pucch_resource)) { + return false; + } + } -namespace srsenb { + return true; +} -int set_sched_cell_cfg_sib1(srsenb::sched_interface::cell_cfg_t* sched_cfg, const asn1::rrc_nr::sib1_s& sib1) +bool fill_phy_pdsch_cfg_common(const asn1::rrc_nr::pdsch_cfg_common_s& pdsch_cfg, srsran_sch_hl_cfg_nr_t* pdsch) { - sched_cfg = {}; + for (uint32_t i = 0; i < pdsch_cfg.pdsch_time_domain_alloc_list.size(); i++) { + srsran_sch_time_ra_t common_time_ra; + if (make_phy_common_time_ra(pdsch_cfg.pdsch_time_domain_alloc_list[i], &common_time_ra) == true) { + pdsch->common_time_ra[i] = common_time_ra; + pdsch->nof_common_time_ra = i + 1; + } else { + asn1::log_warning("Warning while building common_time_ra structure"); + return false; + } + } + return true; +} - // set SIB1 and SIB2+ period - sched_cfg->sibs[0].period_rf = 16; // SIB1 is always 16 rf - for (uint32_t i = 0; i < sib1.si_sched_info.sched_info_list.size(); i++) { - sched_cfg->sibs[i + 1].period_rf = sib1.si_sched_info.sched_info_list[i].si_periodicity.to_number(); +bool fill_phy_pusch_cfg_common(const asn1::rrc_nr::pusch_cfg_common_s& pusch_cfg, srsran_sch_hl_cfg_nr_t* pusch) +{ + for (uint32_t i = 0; i < pusch_cfg.pusch_time_domain_alloc_list.size(); i++) { + srsran_sch_time_ra_t common_time_ra; + if (make_phy_common_time_ra(pusch_cfg.pusch_time_domain_alloc_list[i], &common_time_ra) == true) { + pusch->common_time_ra[i] = common_time_ra; + pusch->nof_common_time_ra = i + 1; + } else { + asn1::log_warning("Warning while building common_time_ra structure"); + return false; + } } + return true; +} + +void fill_phy_carrier_cfg(const asn1::rrc_nr::serving_cell_cfg_common_sib_s& serv_cell_cfg, + srsran_carrier_nr_t* out_carrier_nr) +{ + // TODO: Currently ony one carrier is supported + auto& freq_info_dl = serv_cell_cfg.dl_cfg_common.freq_info_dl; + out_carrier_nr->offset_to_carrier = freq_info_dl.scs_specific_carrier_list[0].offset_to_carrier; + out_carrier_nr->scs = make_subcarrier_spacing(freq_info_dl.scs_specific_carrier_list[0].subcarrier_spacing); + out_carrier_nr->nof_prb = freq_info_dl.scs_specific_carrier_list[0].carrier_bw; - // si-WindowLength - sched_cfg->si_window_ms = sib1.si_sched_info.si_win_len.to_number(); + auto& freq_info_ul = serv_cell_cfg.ul_cfg_common.freq_info_ul; + srsran::srsran_band_helper bands; + out_carrier_nr->ul_center_frequency_hz = bands.get_center_freq_from_abs_freq_point_a( + freq_info_ul.scs_specific_carrier_list[0].carrier_bw, freq_info_ul.absolute_freq_point_a); +} + +void fill_phy_ssb_cfg(const asn1::rrc_nr::serving_cell_cfg_common_sib_s& serv_cell_cfg, + phy_cfg_nr_t::ssb_cfg_t* out_ssb) +{ + out_ssb->periodicity_ms = serv_cell_cfg.ssb_periodicity_serving_cell.to_number(); - // setup PRACH - if (not sib1.si_sched_info.si_request_cfg.rach_occasions_si_present) { - asn1::log_warning("rach_occasions_si option not present"); - return SRSRAN_ERROR; + if (serv_cell_cfg.ssb_positions_in_burst.group_presence_present) { + make_ssb_positions_in_burst(serv_cell_cfg.ssb_positions_in_burst.group_presence, out_ssb->position_in_burst); + } else { + make_ssb_positions_in_burst(serv_cell_cfg.ssb_positions_in_burst.in_one_group, out_ssb->position_in_burst); } - sched_cfg->prach_rar_window = sib1.si_sched_info.si_request_cfg.rach_occasions_si.rach_cfg_si.ra_resp_win.to_number(); - sched_cfg->prach_freq_offset = sib1.si_sched_info.si_request_cfg.rach_occasions_si.rach_cfg_si.msg1_freq_start; - sched_cfg->maxharq_msg3tx = sib1.si_sched_info.si_request_cfg.rach_occasions_si.rach_cfg_si.preamb_trans_max; +} - return SRSRAN_SUCCESS; +/************************** + * Asn1 Obj Id + *************************/ + +ASN1_OBJ_ID_DEFINE(asn1::rrc_nr::srb_to_add_mod_s, srb_id); +ASN1_OBJ_ID_DEFINE(asn1::rrc_nr::drb_to_add_mod_s, drb_id); +ASN1_OBJ_ID_DEFINE(asn1::rrc_nr::meas_obj_to_add_mod_s, meas_obj_id); +ASN1_OBJ_ID_DEFINE(asn1::rrc_nr::report_cfg_to_add_mod_s, report_cfg_id); +ASN1_OBJ_ID_DEFINE(asn1::rrc_nr::meas_id_to_add_mod_s, meas_id); + +} // namespace srsran + +namespace asn1 { + +namespace rrc_nr { + +bool operator==(const srb_to_add_mod_s& lhs, const srb_to_add_mod_s& rhs) +{ + if (lhs.srb_id != rhs.srb_id or lhs.pdcp_cfg_present != rhs.pdcp_cfg_present) { + return false; + } + // TODO: check remaining fields + return true; } +bool operator==(const drb_to_add_mod_s& lhs, const drb_to_add_mod_s& rhs) +{ + if (lhs.drb_id != rhs.drb_id or lhs.pdcp_cfg_present != rhs.pdcp_cfg_present or + lhs.cn_assoc_present != rhs.cn_assoc_present) { + return false; + } + // TODO: check remaining fields + return true; +} + +} // namespace rrc_nr -} // namespace srsenb +} // namespace asn1 diff --git a/lib/src/asn1/rrc_utils.cc b/lib/src/asn1/rrc_utils.cc index 6eca68be36..f52fa1eb24 100644 --- a/lib/src/asn1/rrc_utils.cc +++ b/lib/src/asn1/rrc_utils.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,6 +20,8 @@ */ #include "srsran/asn1/rrc_utils.h" +#include "srsenb/hdr/stack/rrc/rrc_cell_cfg.h" +#include "srsran/asn1/obj_id_cmp_utils.h" #include "srsran/asn1/rrc.h" #include "srsran/config.h" #include @@ -931,36 +933,144 @@ int get_carrier_freq(const asn1::rrc::meas_obj_to_add_mod_s& obj) */ template -static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, const T& ue_eutra_cap) +static void +set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, const srsenb::ue_cell_ded& pcell, const T& ue_eutra_cap) { if (ue_eutra_cap.non_crit_ext_present) { - set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + set_rrc_ue_eutra_cap_t_gen(ue_cap, pcell, ue_eutra_cap.non_crit_ext); } } -static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, const asn1::rrc::ue_eutra_cap_s& ue_eutra_cap) +static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, + const srsenb::ue_cell_ded& pcell, + const asn1::rrc::ue_eutra_cap_s& ue_eutra_cap) { ue_cap.release = ue_eutra_cap.access_stratum_release.to_number(); ue_cap.category = ue_eutra_cap.ue_category; if (ue_eutra_cap.non_crit_ext_present) { - set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + set_rrc_ue_eutra_cap_t_gen(ue_cap, pcell, ue_eutra_cap.non_crit_ext); } } +bool is_ca_band_combo_supported(const band_combination_params_r10_l& enb_band_combo, + const band_combination_params_r10_l& ue_band_combo) +{ + if (enb_band_combo.size() != ue_band_combo.size()) { + return false; + } + + for (unsigned i = 0; i < enb_band_combo.size(); ++i) { + if (ue_band_combo[i].band_eutra_r10 != enb_band_combo[i].band_eutra_r10) { + return false; + } + } + + for (unsigned i = 0; i < enb_band_combo.size(); ++i) { + const auto& enb_band = enb_band_combo[i]; + const auto& ue_band = ue_band_combo[i]; + + if (enb_band.band_params_dl_r10_present and !ue_band.band_params_dl_r10_present) { + return false; + } + // for SCells this depends on the ul_allowed parameter + if (i == 0 and enb_band.band_params_ul_r10_present and !ue_band.band_params_ul_r10_present) { + return false; + } + + if (enb_band.band_params_dl_r10_present and ue_band.band_params_dl_r10_present) { + if (enb_band.band_params_dl_r10.size() != ue_band.band_params_dl_r10.size()) { + return false; + } + for (unsigned j = 0; j < enb_band.band_params_dl_r10.size(); ++j) { + if (enb_band.band_params_dl_r10[j].ca_bw_class_dl_r10 > ue_band.band_params_dl_r10[j].ca_bw_class_dl_r10) { + return false; + } + } + } + + if (enb_band.band_params_ul_r10_present and ue_band.band_params_ul_r10_present) { + if (enb_band.band_params_ul_r10.size() != ue_band.band_params_ul_r10.size()) { + return false; + } + for (unsigned j = 0; j < enb_band.band_params_ul_r10.size(); ++j) { + if (enb_band.band_params_ul_r10[j].ca_bw_class_ul_r10 > ue_band.band_params_ul_r10[j].ca_bw_class_ul_r10) { + return false; + } + } + } + } + return true; +} + +bool is_ul_ca_supported(const band_combination_params_r10_l& ue_band_combo) +{ + uint32_t ul_band_num = 0; + for (const auto& ue_band : ue_band_combo) { + if (ue_band.band_params_ul_r10_present) { + ul_band_num++; + } + } + return ul_band_num == ue_band_combo.size(); +} + static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, + const srsenb::ue_cell_ded& pcell, const asn1::rrc::ue_eutra_cap_v1020_ies_s& ue_eutra_cap) { if (ue_eutra_cap.ue_category_v1020_present) { ue_cap.category = ue_eutra_cap.ue_category_v1020; } + if (ue_eutra_cap.rf_params_v1020_present) { + const asn1::rrc::rf_params_v1020_s& rf_params = ue_eutra_cap.rf_params_v1020; + const srsenb::enb_cell_common* pcell_cfg = pcell.cell_common; + uint32_t cc_num = 1 + pcell_cfg->scells.size(); + band_combination_params_r10_l enb_band_combo; + + // TODO: add proper class (currently hardcoded class A) and mimo_cap checks + for (unsigned i = 0; i < cc_num; ++i) { + ca_mimo_params_dl_r10_s ca_mimo_params_dl; + ca_mimo_params_dl.ca_bw_class_dl_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_dl.supported_mimo_cap_dl_r10_present = false; + ca_mimo_params_dl.supported_mimo_cap_dl_r10 = mimo_cap_dl_r10_opts::nulltype; + + ca_mimo_params_ul_r10_s ca_mimo_params_ul; + ca_mimo_params_ul.ca_bw_class_ul_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_ul.supported_mimo_cap_ul_r10_present = false; + ca_mimo_params_ul.supported_mimo_cap_ul_r10 = mimo_cap_ul_r10_opts::nulltype; + + band_params_r10_s band_params; + uint32_t dl_earfcn = i == 0 ? pcell_cfg->cell_cfg.dl_earfcn : pcell_cfg->scells[i - 1]->cell_cfg.dl_earfcn; + band_params.band_eutra_r10 = (uint8_t)srsran_band_get_band(dl_earfcn); + band_params.band_params_dl_r10_present = true; + band_params.band_params_dl_r10.push_back(ca_mimo_params_dl); + + // PCell always supports UL, SCell depending on the config + if (i == 0 or (i >= 1 and pcell_cfg->cell_cfg.scell_list[i - 1].ul_allowed)) { + band_params.band_params_ul_r10_present = true; + band_params.band_params_ul_r10.push_back(ca_mimo_params_ul); + } + enb_band_combo.push_back(band_params); + } + + // compare the currently used CA band combo with band combos from UE + for (const auto& ue_band_combo : rf_params.supported_band_combination_r10) { + ue_cap.support_ca_bands |= is_ca_band_combo_supported(enb_band_combo, ue_band_combo); + if (ue_cap.support_ca_bands) { + ue_cap.support_ul_ca = is_ul_ca_supported(ue_band_combo); + break; + } + } + } + if (ue_eutra_cap.non_crit_ext_present) { - set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + set_rrc_ue_eutra_cap_t_gen(ue_cap, pcell, ue_eutra_cap.non_crit_ext); } } static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, + const srsenb::ue_cell_ded& pcell, const asn1::rrc::ue_eutra_cap_v1250_ies_s& ue_eutra_cap) { if (ue_eutra_cap.ue_category_dl_r12_present) { @@ -984,20 +1094,22 @@ static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& } if (ue_eutra_cap.non_crit_ext_present) { - set_rrc_ue_eutra_cap_t_gen(ue_cap, ue_eutra_cap.non_crit_ext); + set_rrc_ue_eutra_cap_t_gen(ue_cap, pcell, ue_eutra_cap.non_crit_ext); } } static void set_rrc_ue_eutra_cap_t_gen(rrc_ue_capabilities_t& ue_cap, + const srsenb::ue_cell_ded& pcell, const asn1::rrc::ue_eutra_cap_v1530_ies_s& ue_eutra_cap) { ; // Do nothing } -rrc_ue_capabilities_t make_rrc_ue_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_cap_s) +rrc_ue_capabilities_t make_rrc_ue_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_cap_s, + const srsenb::ue_cell_ded& pcell) { rrc_ue_capabilities_t ue_cap; - set_rrc_ue_eutra_cap_t_gen(ue_cap, eutra_cap_s); + set_rrc_ue_eutra_cap_t_gen(ue_cap, pcell, eutra_cap_s); ue_cap.support_ul_64qam |= (ue_cap.category == 5) or (ue_cap.category == 8 and ue_cap.release >= 10); return ue_cap; } @@ -1091,9 +1203,9 @@ mbsfn_area_info_t make_mbsfn_area_info(const asn1::rrc::mbsfn_area_info_r16_s& a ret.mcch_cfg.sf_alloc_info_is_r16 = true; ret.mcch_cfg.sig_mcs = (mbsfn_area_info_t::mcch_cfg_t::sig_mcs_t)asn1_type.mcch_cfg_r16.sig_mcs_r16.value; ret.subcarrier_spacing = (mbsfn_area_info_t::subcarrier_spacing_t)asn1_type.subcarrier_spacing_mbms_r16.value; - if (asn1_type.pmch_bandwidth_v16xy_present) { - ret.pmch_bandwidth = asn1_type.pmch_bandwidth_v16xy.to_number(); - } +// if (asn1_type.pmch_bandwidth_v16xy_present) { +// ret.pmch_bandwidth = asn1_type.pmch_bandwidth_v16xy.to_number(); +// } return ret; } @@ -1156,10 +1268,19 @@ static_assert(ASN1_RRC_MAX_SESSION_PER_PMCH == pmch_info_t::max_session_per_pmch sib13_t make_sib13(const asn1::rrc::sib_type13_r9_s& asn1_type) { sib13_t sib13{}; - if (asn1_type.mbsfn_area_info_list_r16_present) { - sib13.nof_mbsfn_area_info = asn1_type.mbsfn_area_info_list_r16.size(); + if (asn1_type.mbsfn_area_info_list_r17.is_present()) { + sib13.nof_mbsfn_area_info = asn1_type.mbsfn_area_info_list_r17->size(); + auto* area_info_list = asn1_type.mbsfn_area_info_list_r17.get(); + for (uint32_t i = 0; i < sib13.nof_mbsfn_area_info; i++) { + auto area_info = (*area_info_list)[i]; + sib13.mbsfn_area_info_list[i] = make_mbsfn_area_info(area_info.mbsfn_area_info_r17); + sib13.mbsfn_area_info_list[i].pmch_bandwidth = area_info.pmch_bw_r17.to_number(); + } + } else if (asn1_type.mbsfn_area_info_list_r16.is_present()) { + sib13.nof_mbsfn_area_info = asn1_type.mbsfn_area_info_list_r16->size(); + auto* area_info_list = asn1_type.mbsfn_area_info_list_r16.get(); for (uint32_t i = 0; i < sib13.nof_mbsfn_area_info; i++) { - sib13.mbsfn_area_info_list[i] = make_mbsfn_area_info(asn1_type.mbsfn_area_info_list_r16[i]); + sib13.mbsfn_area_info_list[i] = make_mbsfn_area_info((*area_info_list)[i]); } } else { sib13.nof_mbsfn_area_info = asn1_type.mbsfn_area_info_list_r9.size(); @@ -1171,88 +1292,18 @@ sib13_t make_sib13(const asn1::rrc::sib_type13_r9_s& asn1_type) return sib13; } -} // namespace srsran - -namespace asn1 { -namespace rrc { - /************************** - * RRC Obj Id + * Asn1 Obj Id *************************/ -uint8_t get_rrc_obj_id(const srb_to_add_mod_s& srb) -{ - return srb.srb_id; -} -uint8_t get_rrc_obj_id(const drb_to_add_mod_s& drb) -{ - return drb.drb_id; -} -uint8_t get_rrc_obj_id(const black_cells_to_add_mod_s& obj) -{ - return obj.cell_idx; -} -uint8_t get_rrc_obj_id(const cells_to_add_mod_s& obj) -{ - return obj.cell_idx; -} -uint8_t get_rrc_obj_id(const cells_to_add_mod_nr_r15_s& obj) -{ - return obj.cell_idx_r15; -} -uint8_t get_rrc_obj_id(const meas_obj_to_add_mod_s& obj) -{ - return obj.meas_obj_id; -} -uint8_t get_rrc_obj_id(const report_cfg_to_add_mod_s& obj) -{ - return obj.report_cfg_id; -} -uint8_t get_rrc_obj_id(const meas_id_to_add_mod_s& obj) -{ - return obj.meas_id; -} -uint8_t get_rrc_obj_id(const scell_to_add_mod_r10_s& obj) -{ - return obj.scell_idx_r10; -} +ASN1_OBJ_ID_DEFINE(asn1::rrc::srb_to_add_mod_s, srb_id); +ASN1_OBJ_ID_DEFINE(asn1::rrc::drb_to_add_mod_s, drb_id); +ASN1_OBJ_ID_DEFINE(asn1::rrc::excluded_cells_to_add_mod_s, cell_idx); +ASN1_OBJ_ID_DEFINE(asn1::rrc::cells_to_add_mod_s, cell_idx); +ASN1_OBJ_ID_DEFINE(asn1::rrc::cells_to_add_mod_nr_r15_s, cell_idx_r15); +ASN1_OBJ_ID_DEFINE(asn1::rrc::meas_obj_to_add_mod_s, meas_obj_id); +ASN1_OBJ_ID_DEFINE(asn1::rrc::report_cfg_to_add_mod_s, report_cfg_id); +ASN1_OBJ_ID_DEFINE(asn1::rrc::meas_id_to_add_mod_s, meas_id); +ASN1_OBJ_ID_DEFINE(asn1::rrc::scell_to_add_mod_r10_s, scell_idx_r10); -void set_rrc_obj_id(srb_to_add_mod_s& srb, uint8_t id) -{ - srb.srb_id = id; -} -void set_rrc_obj_id(drb_to_add_mod_s& drb, uint8_t id) -{ - drb.drb_id = id; -} -void set_rrc_obj_id(black_cells_to_add_mod_s& obj, uint8_t id) -{ - obj.cell_idx = id; -} -void set_rrc_obj_id(cells_to_add_mod_s& obj, uint8_t id) -{ - obj.cell_idx = id; -} -void set_rrc_obj_id(cells_to_add_mod_nr_r15_s& obj, uint8_t id) -{ - obj.cell_idx_r15 = id; -} -void set_rrc_obj_id(meas_obj_to_add_mod_s& obj, uint8_t id) -{ - obj.meas_obj_id = id; -} -void set_rrc_obj_id(report_cfg_to_add_mod_s& obj, uint8_t id) -{ - obj.report_cfg_id = id; -} -void set_rrc_obj_id(meas_id_to_add_mod_s& obj, uint8_t id) -{ - obj.meas_id = id; -} -void set_rrc_obj_id(scell_to_add_mod_r10_s& obj, uint8_t id) -{ - obj.scell_idx_r10 = id; -} - -} // namespace rrc -} // namespace asn1 +} // namespace srsran diff --git a/lib/src/asn1/s1ap.cc b/lib/src/asn1/s1ap.cc index cdcd636224..fc2744b045 100644 --- a/lib/src/asn1/s1ap.cc +++ b/lib/src/asn1/s1ap.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,20 +29,6 @@ using namespace asn1::s1ap; * Struct Methods ******************************************************************************/ -// Criticality ::= ENUMERATED -const char* crit_opts::to_string() const -{ - static const char* options[] = {"reject", "ignore", "notify"}; - return convert_enum_idx(options, 3, value, "crit_e"); -} - -// Presence ::= ENUMERATED -const char* presence_opts::to_string() const -{ - static const char* options[] = {"optional", "conditional", "mandatory"}; - return convert_enum_idx(options, 3, value, "presence_e"); -} - // PrivateIE-ID ::= CHOICE void private_ie_id_c::set(types::options e) { @@ -139,130 +125,6 @@ void private_ie_field_s::to_json(json_writer& j) const j.end_obj(); } -// ProtocolExtensionField{S1AP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE{{S1AP-PROTOCOL-EXTENSION}} -template -SRSASN_CODE protocol_ext_field_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); - warn_assert(crit != ext_set_paramT_::get_crit(id), __func__, __LINE__); - HANDLE_CODE(crit.pack(bref)); - HANDLE_CODE(ext_value.pack(bref)); - - return SRSASN_SUCCESS; -} -template -SRSASN_CODE protocol_ext_field_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.unpack(bref)); - ext_value = ext_set_paramT_::get_ext(id); - HANDLE_CODE(ext_value.unpack(bref)); - - return SRSASN_SUCCESS; -} -template -void protocol_ext_field_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("id", id); - j.write_str("criticality", crit.to_string()); - j.end_obj(); -} -template -bool protocol_ext_field_s::load_info_obj(const uint32_t& id_) -{ - if (not ext_set_paramT_::is_id_valid(id_)) { - return false; - } - id = id_; - crit = ext_set_paramT_::get_crit(id); - ext_value = ext_set_paramT_::get_ext(id); - return ext_value.type().value != ext_set_paramT_::ext_c::types_opts::nulltype; -} - -// ProtocolIE-Field{S1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{S1AP-PROTOCOL-IES}} -template -SRSASN_CODE protocol_ie_field_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); - warn_assert(crit != ies_set_paramT_::get_crit(id), __func__, __LINE__); - HANDLE_CODE(crit.pack(bref)); - HANDLE_CODE(value.pack(bref)); - - return SRSASN_SUCCESS; -} -template -SRSASN_CODE protocol_ie_field_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.unpack(bref)); - value = ies_set_paramT_::get_value(id); - HANDLE_CODE(value.unpack(bref)); - - return SRSASN_SUCCESS; -} -template -void protocol_ie_field_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("id", id); - j.write_str("criticality", crit.to_string()); - j.end_obj(); -} -template -bool protocol_ie_field_s::load_info_obj(const uint32_t& id_) -{ - if (not ies_set_paramT_::is_id_valid(id_)) { - return false; - } - id = id_; - crit = ies_set_paramT_::get_crit(id); - value = ies_set_paramT_::get_value(id); - return value.type().value != ies_set_paramT_::value_c::types_opts::nulltype; -} - -// ProtocolIE-SingleContainer{S1AP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{S1AP-PROTOCOL-IES}} -template -SRSASN_CODE protocol_ie_single_container_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); - warn_assert(crit != ies_set_paramT_::get_crit(id), __func__, __LINE__); - HANDLE_CODE(crit.pack(bref)); - HANDLE_CODE(value.pack(bref)); - - return SRSASN_SUCCESS; -} -template -SRSASN_CODE protocol_ie_single_container_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.unpack(bref)); - value = ies_set_paramT_::get_value(id); - HANDLE_CODE(value.unpack(bref)); - - return SRSASN_SUCCESS; -} -template -void protocol_ie_single_container_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("id", id); - j.write_str("criticality", crit.to_string()); - j.end_obj(); -} -template -bool protocol_ie_single_container_s::load_info_obj(const uint32_t& id_) -{ - if (not ies_set_paramT_::is_id_valid(id_)) { - return false; - } - id = id_; - crit = ies_set_paramT_::get_crit(id); - value = ies_set_paramT_::get_value(id); - return value.type().value != ies_set_paramT_::value_c::types_opts::nulltype; -} -template bool protocol_ie_single_container_s::load_info_obj(const uint32_t& id_); - // ProtocolIE-FieldPair{S1AP-PROTOCOL-IES-PAIR : IEsSetParam} ::= SEQUENCE{{S1AP-PROTOCOL-IES-PAIR}} template SRSASN_CODE protocol_ie_field_pair_s::pack(bit_ref& bref) const @@ -336,109 +198,6 @@ void activ_cells_list_item_s::to_json(json_writer& j) const j.end_obj(); } -uint32_t s1ap_protocol_ext_empty_o::idx_to_id(uint32_t idx) -{ - asn1::log_error("object set is empty\n"); - return 0; -} -bool s1ap_protocol_ext_empty_o::is_id_valid(const uint32_t& id) -{ - asn1::log_error("object set is empty\n"); - return false; -} -crit_e s1ap_protocol_ext_empty_o::get_crit(const uint32_t& id) -{ - return {}; -} -s1ap_protocol_ext_empty_o::ext_c s1ap_protocol_ext_empty_o::get_ext(const uint32_t& id) -{ - return {}; -} -presence_e s1ap_protocol_ext_empty_o::get_presence(const uint32_t& id) -{ - return {}; -} - -// Extension ::= OPEN TYPE -void s1ap_protocol_ext_empty_o::ext_c::to_json(json_writer& j) const -{ - j.start_obj(); - j.end_obj(); -} -SRSASN_CODE s1ap_protocol_ext_empty_o::ext_c::pack(bit_ref& bref) const -{ - varlength_field_pack_guard varlen_scope(bref, true); - return SRSASN_SUCCESS; -} -SRSASN_CODE s1ap_protocol_ext_empty_o::ext_c::unpack(cbit_ref& bref) -{ - varlength_field_unpack_guard varlen_scope(bref, true); - return SRSASN_SUCCESS; -} - -const char* s1ap_protocol_ext_empty_o::ext_c::types_opts::to_string() const -{ - static const char* options[] = {}; - return convert_enum_idx(options, 0, value, "s1ap_protocol_ext_empty_o::ext_c::types"); -} - -template -protocol_ext_container_item_s::protocol_ext_container_item_s(uint32_t id_, crit_e crit_) : id(id_), crit(crit_) - -{} -template -SRSASN_CODE protocol_ext_container_item_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.pack(bref)); - { - varlength_field_pack_guard varlen_scope(bref, true); - HANDLE_CODE(ext.pack(bref)); - } - return SRSASN_SUCCESS; -} -template -SRSASN_CODE protocol_ext_container_item_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.unpack(bref)); - { - varlength_field_unpack_guard varlen_scope(bref, true); - HANDLE_CODE(ext.unpack(bref)); - } - return SRSASN_SUCCESS; -} -template -void protocol_ext_container_item_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("id", id); - j.write_str("criticality", crit.to_string()); - j.end_obj(); -} - -SRSASN_CODE protocol_ext_container_empty_l::pack(bit_ref& bref) const -{ - uint32_t nof_ies = 0; - pack_length(bref, nof_ies, 1u, 65535u, true); - - return SRSASN_SUCCESS; -} -SRSASN_CODE protocol_ext_container_empty_l::unpack(cbit_ref& bref) -{ - uint32_t nof_ies = 0; - unpack_length(nof_ies, bref, 1u, 65535u, true); - if (nof_ies > 0) { - return SRSASN_ERROR_DECODE_FAIL; - } - return SRSASN_SUCCESS; -} -void protocol_ext_container_empty_l::to_json(json_writer& j) const -{ - j.start_obj(); - j.end_obj(); -} - // GUMMEI ::= SEQUENCE SRSASN_CODE gummei_s::pack(bit_ref& bref) const { @@ -1493,7 +1252,7 @@ const char* recommended_cell_item_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 1, value, "recommended_cell_item_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // NextPagingAreaScope ::= ENUMERATED const char* next_paging_area_scope_opts::to_string() const @@ -2184,7 +1943,7 @@ void coun_tvalue_s::to_json(json_writer& j) const j.end_obj(); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; bearers_subject_to_status_transfer_item_ext_ies_container::bearers_subject_to_status_transfer_item_ext_ies_container() : ulcount_value_extended(179, crit_e::ignore), @@ -2232,47 +1991,59 @@ SRSASN_CODE bearers_subject_to_status_transfer_item_ext_ies_container::unpack(cb unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 179: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 179: { ulcount_value_extended_present = true; - ulcount_value_extended.id = c.id; - ulcount_value_extended.crit = c.crit; - ulcount_value_extended.ext = c.ext_value.ulcount_value_extended(); + ulcount_value_extended.id = id; + HANDLE_CODE(ulcount_value_extended.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ulcount_value_extended.ext.unpack(bref)); break; - case 180: + } + case 180: { dlcount_value_extended_present = true; - dlcount_value_extended.id = c.id; - dlcount_value_extended.crit = c.crit; - dlcount_value_extended.ext = c.ext_value.dlcount_value_extended(); + dlcount_value_extended.id = id; + HANDLE_CODE(dlcount_value_extended.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(dlcount_value_extended.ext.unpack(bref)); break; - case 181: + } + case 181: { receive_status_of_ulpdcpsdus_extended_present = true; - receive_status_of_ulpdcpsdus_extended.id = c.id; - receive_status_of_ulpdcpsdus_extended.crit = c.crit; - receive_status_of_ulpdcpsdus_extended.ext = c.ext_value.receive_status_of_ulpdcpsdus_extended(); + receive_status_of_ulpdcpsdus_extended.id = id; + HANDLE_CODE(receive_status_of_ulpdcpsdus_extended.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(receive_status_of_ulpdcpsdus_extended.ext.unpack(bref)); break; - case 217: + } + case 217: { ulcount_value_pdcp_snlen18_present = true; - ulcount_value_pdcp_snlen18.id = c.id; - ulcount_value_pdcp_snlen18.crit = c.crit; - ulcount_value_pdcp_snlen18.ext = c.ext_value.ulcount_value_pdcp_snlen18(); + ulcount_value_pdcp_snlen18.id = id; + HANDLE_CODE(ulcount_value_pdcp_snlen18.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ulcount_value_pdcp_snlen18.ext.unpack(bref)); break; - case 218: + } + case 218: { dlcount_value_pdcp_snlen18_present = true; - dlcount_value_pdcp_snlen18.id = c.id; - dlcount_value_pdcp_snlen18.crit = c.crit; - dlcount_value_pdcp_snlen18.ext = c.ext_value.dlcount_value_pdcp_snlen18(); + dlcount_value_pdcp_snlen18.id = id; + HANDLE_CODE(dlcount_value_pdcp_snlen18.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(dlcount_value_pdcp_snlen18.ext.unpack(bref)); break; - case 219: + } + case 219: { receive_status_of_ulpdcpsdus_pdcp_snlen18_present = true; - receive_status_of_ulpdcpsdus_pdcp_snlen18.id = c.id; - receive_status_of_ulpdcpsdus_pdcp_snlen18.crit = c.crit; - receive_status_of_ulpdcpsdus_pdcp_snlen18.ext = c.ext_value.receive_status_of_ulpdcpsdus_pdcp_snlen18(); + receive_status_of_ulpdcpsdus_pdcp_snlen18.id = id; + HANDLE_CODE(receive_status_of_ulpdcpsdus_pdcp_snlen18.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(receive_status_of_ulpdcpsdus_pdcp_snlen18.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -2427,7 +2198,7 @@ const char* bearers_subject_to_status_transfer_item_ies_o::value_c::types_opts:: return convert_enum_idx(options, 1, value, "bearers_subject_to_status_transfer_item_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // BluetoothMeasConfig ::= ENUMERATED const char* bluetooth_meas_cfg_opts::to_string() const @@ -4748,42 +4519,7 @@ const char* cell_traffic_trace_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 6, value, "cell_traffic_trace_ies_o::value_c::types"); } -template -protocol_ie_container_item_s::protocol_ie_container_item_s(uint32_t id_, crit_e crit_) : id(id_), crit(crit_) - -{} -template -SRSASN_CODE protocol_ie_container_item_s::pack(bit_ref& bref) const -{ - HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.pack(bref)); - { - varlength_field_pack_guard varlen_scope(bref, true); - HANDLE_CODE(value.pack(bref)); - } - return SRSASN_SUCCESS; -} -template -SRSASN_CODE protocol_ie_container_item_s::unpack(cbit_ref& bref) -{ - HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); - HANDLE_CODE(crit.unpack(bref)); - { - varlength_field_unpack_guard varlen_scope(bref, true); - HANDLE_CODE(value.unpack(bref)); - } - return SRSASN_SUCCESS; -} -template -void protocol_ie_container_item_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_int("id", id); - j.write_str("criticality", crit.to_string()); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; cell_traffic_trace_ies_container::cell_traffic_trace_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -4818,47 +4554,59 @@ SRSASN_CODE cell_traffic_trace_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 5; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 86: + } + case 86: { nof_mandatory_ies--; - e_utran_trace_id.id = c.id; - e_utran_trace_id.crit = c.crit; - e_utran_trace_id.value = c.value.e_utran_trace_id(); + e_utran_trace_id.id = id; + HANDLE_CODE(e_utran_trace_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e_utran_trace_id.value.unpack(bref)); break; - case 100: + } + case 100: { nof_mandatory_ies--; - eutran_cgi.id = c.id; - eutran_cgi.crit = c.crit; - eutran_cgi.value = c.value.eutran_cgi(); + eutran_cgi.id = id; + HANDLE_CODE(eutran_cgi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(eutran_cgi.value.unpack(bref)); break; - case 131: + } + case 131: { nof_mandatory_ies--; - trace_collection_entity_ip_address.id = c.id; - trace_collection_entity_ip_address.crit = c.crit; - trace_collection_entity_ip_address.value = c.value.trace_collection_entity_ip_address(); + trace_collection_entity_ip_address.id = id; + HANDLE_CODE(trace_collection_entity_ip_address.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(trace_collection_entity_ip_address.value.unpack(bref)); break; - case 166: + } + case 166: { privacy_ind_present = true; - privacy_ind.id = c.id; - privacy_ind.crit = c.crit; - privacy_ind.value = c.value.privacy_ind(); + privacy_ind.id = id; + HANDLE_CODE(privacy_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(privacy_ind.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -4889,29 +4637,6 @@ void cell_traffic_trace_ies_container::to_json(json_writer& j) const j.end_obj(); } -// CellTrafficTrace ::= SEQUENCE -SRSASN_CODE cell_traffic_trace_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE cell_traffic_trace_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void cell_traffic_trace_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // Cell-Size ::= ENUMERATED const char* cell_size_opts::to_string() const { @@ -5528,7 +5253,7 @@ const char* erab_qos_params_ext_ies_o::ext_c::types_opts::to_string() const return convert_enum_idx(options, 2, value, "erab_qos_params_ext_ies_o::ext_c::types"); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; gbr_qos_info_ext_ies_container::gbr_qos_info_ext_ies_container() : extended_erab_maximum_bitrate_dl(255, crit_e::ignore), @@ -5566,35 +5291,43 @@ SRSASN_CODE gbr_qos_info_ext_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 255: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 255: { extended_erab_maximum_bitrate_dl_present = true; - extended_erab_maximum_bitrate_dl.id = c.id; - extended_erab_maximum_bitrate_dl.crit = c.crit; - extended_erab_maximum_bitrate_dl.ext = c.ext_value.extended_erab_maximum_bitrate_dl(); + extended_erab_maximum_bitrate_dl.id = id; + HANDLE_CODE(extended_erab_maximum_bitrate_dl.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(extended_erab_maximum_bitrate_dl.ext.unpack(bref)); break; - case 256: + } + case 256: { extended_erab_maximum_bitrate_ul_present = true; - extended_erab_maximum_bitrate_ul.id = c.id; - extended_erab_maximum_bitrate_ul.crit = c.crit; - extended_erab_maximum_bitrate_ul.ext = c.ext_value.extended_erab_maximum_bitrate_ul(); + extended_erab_maximum_bitrate_ul.id = id; + HANDLE_CODE(extended_erab_maximum_bitrate_ul.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(extended_erab_maximum_bitrate_ul.ext.unpack(bref)); break; - case 257: + } + case 257: { extended_erab_guaranteed_bitrate_dl_present = true; - extended_erab_guaranteed_bitrate_dl.id = c.id; - extended_erab_guaranteed_bitrate_dl.crit = c.crit; - extended_erab_guaranteed_bitrate_dl.ext = c.ext_value.extended_erab_guaranteed_bitrate_dl(); + extended_erab_guaranteed_bitrate_dl.id = id; + HANDLE_CODE(extended_erab_guaranteed_bitrate_dl.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(extended_erab_guaranteed_bitrate_dl.ext.unpack(bref)); break; - case 258: + } + case 258: { extended_erab_guaranteed_bitrate_ul_present = true; - extended_erab_guaranteed_bitrate_ul.id = c.id; - extended_erab_guaranteed_bitrate_ul.crit = c.crit; - extended_erab_guaranteed_bitrate_ul.ext = c.ext_value.extended_erab_guaranteed_bitrate_ul(); + extended_erab_guaranteed_bitrate_ul.id = id; + HANDLE_CODE(extended_erab_guaranteed_bitrate_ul.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(extended_erab_guaranteed_bitrate_ul.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -5777,7 +5510,7 @@ void dl_cp_security_info_s::to_json(json_writer& j) const j.end_obj(); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; erab_qos_params_ext_ies_container::erab_qos_params_ext_ies_container() : dl_packet_loss_rate(273, crit_e::ignore), ul_packet_loss_rate(274, crit_e::ignore) @@ -5804,23 +5537,27 @@ SRSASN_CODE erab_qos_params_ext_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 273: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 273: { dl_packet_loss_rate_present = true; - dl_packet_loss_rate.id = c.id; - dl_packet_loss_rate.crit = c.crit; - dl_packet_loss_rate.ext = c.ext_value.dl_packet_loss_rate(); + dl_packet_loss_rate.id = id; + HANDLE_CODE(dl_packet_loss_rate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(dl_packet_loss_rate.ext.unpack(bref)); break; - case 274: + } + case 274: { ul_packet_loss_rate_present = true; - ul_packet_loss_rate.id = c.id; - ul_packet_loss_rate.crit = c.crit; - ul_packet_loss_rate.ext = c.ext_value.ul_packet_loss_rate(); + ul_packet_loss_rate.id = id; + HANDLE_CODE(ul_packet_loss_rate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ul_packet_loss_rate.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -6491,7 +6228,7 @@ const char* conn_establishment_ind_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 9, value, "conn_establishment_ind_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; conn_establishment_ind_ies_container::conn_establishment_ind_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -6550,65 +6287,83 @@ SRSASN_CODE conn_establishment_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 74: + } + case 74: { ue_radio_cap_present = true; - ue_radio_cap.id = c.id; - ue_radio_cap.crit = c.crit; - ue_radio_cap.value = c.value.ue_radio_cap(); + ue_radio_cap.id = id; + HANDLE_CODE(ue_radio_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap.value.unpack(bref)); break; - case 251: + } + case 251: { enhanced_coverage_restricted_present = true; - enhanced_coverage_restricted.id = c.id; - enhanced_coverage_restricted.crit = c.crit; - enhanced_coverage_restricted.value = c.value.enhanced_coverage_restricted(); + enhanced_coverage_restricted.id = id; + HANDLE_CODE(enhanced_coverage_restricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enhanced_coverage_restricted.value.unpack(bref)); break; - case 253: + } + case 253: { dl_cp_security_info_present = true; - dl_cp_security_info.id = c.id; - dl_cp_security_info.crit = c.crit; - dl_cp_security_info.value = c.value.dl_cp_security_info(); + dl_cp_security_info.id = id; + HANDLE_CODE(dl_cp_security_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(dl_cp_security_info.value.unpack(bref)); break; - case 271: + } + case 271: { ce_mode_brestricted_present = true; - ce_mode_brestricted.id = c.id; - ce_mode_brestricted.crit = c.crit; - ce_mode_brestricted.value = c.value.ce_mode_brestricted(); + ce_mode_brestricted.id = id; + HANDLE_CODE(ce_mode_brestricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ce_mode_brestricted.value.unpack(bref)); break; - case 280: + } + case 280: { end_ind_present = true; - end_ind.id = c.id; - end_ind.crit = c.crit; - end_ind.value = c.value.end_ind(); + end_ind.id = id; + HANDLE_CODE(end_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(end_ind.value.unpack(bref)); break; - case 278: + } + case 278: { subscription_based_ue_differentiation_info_present = true; - subscription_based_ue_differentiation_info.id = c.id; - subscription_based_ue_differentiation_info.crit = c.crit; - subscription_based_ue_differentiation_info.value = c.value.subscription_based_ue_differentiation_info(); + subscription_based_ue_differentiation_info.id = id; + HANDLE_CODE(subscription_based_ue_differentiation_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(subscription_based_ue_differentiation_info.value.unpack(bref)); break; - case 252: + } + case 252: { ue_level_qos_params_present = true; - ue_level_qos_params.id = c.id; - ue_level_qos_params.crit = c.crit; - ue_level_qos_params.value = c.value.ue_level_qos_params(); + ue_level_qos_params.id = id; + HANDLE_CODE(ue_level_qos_params.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_level_qos_params.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -6657,29 +6412,6 @@ void conn_establishment_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// ConnectionEstablishmentIndication ::= SEQUENCE -SRSASN_CODE conn_establishment_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE conn_establishment_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void conn_establishment_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // ENB-ID ::= CHOICE void enb_id_c::destroy_() { @@ -7596,7 +7328,7 @@ const char* deactiv_trace_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "deactiv_trace_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; deactiv_trace_ies_container::deactiv_trace_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), enb_ue_s1ap_id(8, crit_e::reject), e_utran_trace_id(86, crit_e::ignore) @@ -7620,29 +7352,35 @@ SRSASN_CODE deactiv_trace_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 86: + } + case 86: { nof_mandatory_ies--; - e_utran_trace_id.id = c.id; - e_utran_trace_id.crit = c.crit; - e_utran_trace_id.value = c.value.e_utran_trace_id(); + e_utran_trace_id.id = id; + HANDLE_CODE(e_utran_trace_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e_utran_trace_id.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -7665,29 +7403,6 @@ void deactiv_trace_ies_container::to_json(json_writer& j) const j.end_obj(); } -// DeactivateTrace ::= SEQUENCE -SRSASN_CODE deactiv_trace_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE deactiv_trace_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void deactiv_trace_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // ForbiddenLAs-Item ::= SEQUENCE SRSASN_CODE forbidden_las_item_s::pack(bit_ref& bref) const { @@ -8131,7 +7846,7 @@ const char* dlnaspdu_delivery_ack_request_opts::to_string() const return convert_enum_idx(options, 1, value, "dlnaspdu_delivery_ack_request_e"); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; ho_restrict_list_ext_ies_container::ho_restrict_list_ext_ies_container() : nrrestrictin_ep_sas_secondary_rat(261, crit_e::ignore), @@ -8174,41 +7889,51 @@ SRSASN_CODE ho_restrict_list_ext_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 261: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 261: { nrrestrictin_ep_sas_secondary_rat_present = true; - nrrestrictin_ep_sas_secondary_rat.id = c.id; - nrrestrictin_ep_sas_secondary_rat.crit = c.crit; - nrrestrictin_ep_sas_secondary_rat.ext = c.ext_value.nrrestrictin_ep_sas_secondary_rat(); + nrrestrictin_ep_sas_secondary_rat.id = id; + HANDLE_CODE(nrrestrictin_ep_sas_secondary_rat.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrrestrictin_ep_sas_secondary_rat.ext.unpack(bref)); break; - case 270: + } + case 270: { unlicensed_spec_restrict_present = true; - unlicensed_spec_restrict.id = c.id; - unlicensed_spec_restrict.crit = c.crit; - unlicensed_spec_restrict.ext = c.ext_value.unlicensed_spec_restrict(); + unlicensed_spec_restrict.id = id; + HANDLE_CODE(unlicensed_spec_restrict.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(unlicensed_spec_restrict.ext.unpack(bref)); break; - case 282: + } + case 282: { cn_type_restricts_present = true; - cn_type_restricts.id = c.id; - cn_type_restricts.crit = c.crit; - cn_type_restricts.ext = c.ext_value.cn_type_restricts(); + cn_type_restricts.id = id; + HANDLE_CODE(cn_type_restricts.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cn_type_restricts.ext.unpack(bref)); break; - case 287: + } + case 287: { nrrestrictin5_gs_present = true; - nrrestrictin5_gs.id = c.id; - nrrestrictin5_gs.crit = c.crit; - nrrestrictin5_gs.ext = c.ext_value.nrrestrictin5_gs(); + nrrestrictin5_gs.id = id; + HANDLE_CODE(nrrestrictin5_gs.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrrestrictin5_gs.ext.unpack(bref)); break; - case 290: + } + case 290: { last_ng_ranplmn_id_present = true; - last_ng_ranplmn_id.id = c.id; - last_ng_ranplmn_id.crit = c.crit; - last_ng_ranplmn_id.ext = c.ext_value.last_ng_ranplmn_id(); + last_ng_ranplmn_id.id = id; + HANDLE_CODE(last_ng_ranplmn_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(last_ng_ranplmn_id.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -9104,7 +8829,7 @@ const char* dl_nas_transport_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 16, value, "dl_nas_transport_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; dl_nas_transport_ies_container::dl_nas_transport_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -9195,107 +8920,139 @@ SRSASN_CODE dl_nas_transport_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 26: + } + case 26: { nof_mandatory_ies--; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; - case 41: + } + case 41: { ho_restrict_list_present = true; - ho_restrict_list.id = c.id; - ho_restrict_list.crit = c.crit; - ho_restrict_list.value = c.value.ho_restrict_list(); + ho_restrict_list.id = id; + HANDLE_CODE(ho_restrict_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ho_restrict_list.value.unpack(bref)); break; - case 106: + } + case 106: { subscriber_profile_idfor_rfp_present = true; - subscriber_profile_idfor_rfp.id = c.id; - subscriber_profile_idfor_rfp.crit = c.crit; - subscriber_profile_idfor_rfp.value = c.value.subscriber_profile_idfor_rfp(); + subscriber_profile_idfor_rfp.id = id; + HANDLE_CODE(subscriber_profile_idfor_rfp.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(subscriber_profile_idfor_rfp.value.unpack(bref)); break; - case 124: + } + case 124: { srvcc_operation_possible_present = true; - srvcc_operation_possible.id = c.id; - srvcc_operation_possible.crit = c.crit; - srvcc_operation_possible.value = c.value.srvcc_operation_possible(); + srvcc_operation_possible.id = id; + HANDLE_CODE(srvcc_operation_possible.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(srvcc_operation_possible.value.unpack(bref)); break; - case 74: + } + case 74: { ue_radio_cap_present = true; - ue_radio_cap.id = c.id; - ue_radio_cap.crit = c.crit; - ue_radio_cap.value = c.value.ue_radio_cap(); + ue_radio_cap.id = id; + HANDLE_CODE(ue_radio_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap.value.unpack(bref)); break; - case 249: + } + case 249: { dlnaspdu_delivery_ack_request_present = true; - dlnaspdu_delivery_ack_request.id = c.id; - dlnaspdu_delivery_ack_request.crit = c.crit; - dlnaspdu_delivery_ack_request.value = c.value.dlnaspdu_delivery_ack_request(); + dlnaspdu_delivery_ack_request.id = id; + HANDLE_CODE(dlnaspdu_delivery_ack_request.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(dlnaspdu_delivery_ack_request.value.unpack(bref)); break; - case 251: + } + case 251: { enhanced_coverage_restricted_present = true; - enhanced_coverage_restricted.id = c.id; - enhanced_coverage_restricted.crit = c.crit; - enhanced_coverage_restricted.value = c.value.enhanced_coverage_restricted(); + enhanced_coverage_restricted.id = id; + HANDLE_CODE(enhanced_coverage_restricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enhanced_coverage_restricted.value.unpack(bref)); break; - case 269: + } + case 269: { nrue_security_cap_present = true; - nrue_security_cap.id = c.id; - nrue_security_cap.crit = c.crit; - nrue_security_cap.value = c.value.nrue_security_cap(); + nrue_security_cap.id = id; + HANDLE_CODE(nrue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrue_security_cap.value.unpack(bref)); break; - case 271: + } + case 271: { ce_mode_brestricted_present = true; - ce_mode_brestricted.id = c.id; - ce_mode_brestricted.crit = c.crit; - ce_mode_brestricted.value = c.value.ce_mode_brestricted(); + ce_mode_brestricted.id = id; + HANDLE_CODE(ce_mode_brestricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ce_mode_brestricted.value.unpack(bref)); break; - case 275: + } + case 275: { ue_cap_info_request_present = true; - ue_cap_info_request.id = c.id; - ue_cap_info_request.crit = c.crit; - ue_cap_info_request.value = c.value.ue_cap_info_request(); + ue_cap_info_request.id = id; + HANDLE_CODE(ue_cap_info_request.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_cap_info_request.value.unpack(bref)); break; - case 280: + } + case 280: { end_ind_present = true; - end_ind.id = c.id; - end_ind.crit = c.crit; - end_ind.value = c.value.end_ind(); + end_ind.id = id; + HANDLE_CODE(end_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(end_ind.value.unpack(bref)); break; - case 283: + } + case 283: { pending_data_ind_present = true; - pending_data_ind.id = c.id; - pending_data_ind.crit = c.crit; - pending_data_ind.value = c.value.pending_data_ind(); + pending_data_ind.id = id; + HANDLE_CODE(pending_data_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pending_data_ind.value.unpack(bref)); break; - case 278: + } + case 278: { subscription_based_ue_differentiation_info_present = true; - subscription_based_ue_differentiation_info.id = c.id; - subscription_based_ue_differentiation_info.crit = c.crit; - subscription_based_ue_differentiation_info.value = c.value.subscription_based_ue_differentiation_info(); + subscription_based_ue_differentiation_info.id = id; + HANDLE_CODE(subscription_based_ue_differentiation_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(subscription_based_ue_differentiation_info.value.unpack(bref)); break; - case 299: + } + case 299: { add_rrm_prio_idx_present = true; - add_rrm_prio_idx.id = c.id; - add_rrm_prio_idx.crit = c.crit; - add_rrm_prio_idx.value = c.value.add_rrm_prio_idx(); + add_rrm_prio_idx.id = id; + HANDLE_CODE(add_rrm_prio_idx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(add_rrm_prio_idx.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -9370,29 +9127,6 @@ void dl_nas_transport_ies_container::to_json(json_writer& j) const j.end_obj(); } -// DownlinkNASTransport ::= SEQUENCE -SRSASN_CODE dl_nas_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE dl_nas_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void dl_nas_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // DownlinkNonUEAssociatedLPPaTransport-IEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t dl_non_ueassociated_lp_pa_transport_ies_o::idx_to_id(uint32_t idx) { @@ -9595,7 +9329,7 @@ uint8_t dl_non_ueassociated_lp_pa_transport_ies_o::value_c::types_opts::to_numbe return map_enum_number(options, 1, value, "dl_non_ueassociated_lp_pa_transport_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; dl_non_ueassociated_lp_pa_transport_ies_container::dl_non_ueassociated_lp_pa_transport_ies_container() : routing_id(148, crit_e::reject), lp_pa_pdu(147, crit_e::reject) @@ -9618,23 +9352,27 @@ SRSASN_CODE dl_non_ueassociated_lp_pa_transport_ies_container::unpack(cbit_ref& uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 148: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 148: { nof_mandatory_ies--; - routing_id.id = c.id; - routing_id.crit = c.crit; - routing_id.value = c.value.routing_id(); + routing_id.id = id; + HANDLE_CODE(routing_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(routing_id.value.unpack(bref)); break; - case 147: + } + case 147: { nof_mandatory_ies--; - lp_pa_pdu.id = c.id; - lp_pa_pdu.crit = c.crit; - lp_pa_pdu.value = c.value.lp_pa_pdu(); + lp_pa_pdu.id = id; + HANDLE_CODE(lp_pa_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(lp_pa_pdu.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -9655,29 +9393,6 @@ void dl_non_ueassociated_lp_pa_transport_ies_container::to_json(json_writer& j) j.end_obj(); } -// DownlinkNonUEAssociatedLPPaTransport ::= SEQUENCE -SRSASN_CODE dl_non_ueassociated_lp_pa_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE dl_non_ueassociated_lp_pa_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void dl_non_ueassociated_lp_pa_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // E-RABDataForwardingItem ::= SEQUENCE SRSASN_CODE erab_data_forwarding_item_s::pack(bit_ref& bref) const { @@ -10186,7 +9901,7 @@ const char* dl_s1cdma2000tunnelling_ies_o::value_c::types_opts::to_string() cons return convert_enum_idx(options, 6, value, "dl_s1cdma2000tunnelling_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; dl_s1cdma2000tunnelling_ies_container::dl_s1cdma2000tunnelling_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -10224,47 +9939,59 @@ SRSASN_CODE dl_s1cdma2000tunnelling_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 12: + } + case 12: { erab_subjectto_data_forwarding_list_present = true; - erab_subjectto_data_forwarding_list.id = c.id; - erab_subjectto_data_forwarding_list.crit = c.crit; - erab_subjectto_data_forwarding_list.value = c.value.erab_subjectto_data_forwarding_list(); + erab_subjectto_data_forwarding_list.id = id; + HANDLE_CODE(erab_subjectto_data_forwarding_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_subjectto_data_forwarding_list.value.unpack(bref)); break; - case 83: + } + case 83: { cdma2000_ho_status_present = true; - cdma2000_ho_status.id = c.id; - cdma2000_ho_status.crit = c.crit; - cdma2000_ho_status.value = c.value.cdma2000_ho_status(); + cdma2000_ho_status.id = id; + HANDLE_CODE(cdma2000_ho_status.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cdma2000_ho_status.value.unpack(bref)); break; - case 71: + } + case 71: { nof_mandatory_ies--; - cdma2000_rat_type.id = c.id; - cdma2000_rat_type.crit = c.crit; - cdma2000_rat_type.value = c.value.cdma2000_rat_type(); + cdma2000_rat_type.id = id; + HANDLE_CODE(cdma2000_rat_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cdma2000_rat_type.value.unpack(bref)); break; - case 70: + } + case 70: { nof_mandatory_ies--; - cdma2000_pdu.id = c.id; - cdma2000_pdu.crit = c.crit; - cdma2000_pdu.value = c.value.cdma2000_pdu(); + cdma2000_pdu.id = id; + HANDLE_CODE(cdma2000_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cdma2000_pdu.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -10297,29 +10024,6 @@ void dl_s1cdma2000tunnelling_ies_container::to_json(json_writer& j) const j.end_obj(); } -// DownlinkS1cdma2000tunnelling ::= SEQUENCE -SRSASN_CODE dl_s1cdma2000tunnelling_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE dl_s1cdma2000tunnelling_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void dl_s1cdma2000tunnelling_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // DownlinkUEAssociatedLPPaTransport-IEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t dl_ueassociated_lp_pa_transport_ies_o::idx_to_id(uint32_t idx) { @@ -10584,7 +10288,7 @@ const char* dl_ueassociated_lp_pa_transport_ies_o::value_c::types_opts::to_strin return convert_enum_idx(options, 4, value, "dl_ueassociated_lp_pa_transport_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; dl_ueassociated_lp_pa_transport_ies_container::dl_ueassociated_lp_pa_transport_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -10612,35 +10316,43 @@ SRSASN_CODE dl_ueassociated_lp_pa_transport_ies_container::unpack(cbit_ref& bref uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 148: + } + case 148: { nof_mandatory_ies--; - routing_id.id = c.id; - routing_id.crit = c.crit; - routing_id.value = c.value.routing_id(); + routing_id.id = id; + HANDLE_CODE(routing_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(routing_id.value.unpack(bref)); break; - case 147: + } + case 147: { nof_mandatory_ies--; - lp_pa_pdu.id = c.id; - lp_pa_pdu.crit = c.crit; - lp_pa_pdu.value = c.value.lp_pa_pdu(); + lp_pa_pdu.id = id; + HANDLE_CODE(lp_pa_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(lp_pa_pdu.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -10665,29 +10377,6 @@ void dl_ueassociated_lp_pa_transport_ies_container::to_json(json_writer& j) cons j.end_obj(); } -// DownlinkUEAssociatedLPPaTransport ::= SEQUENCE -SRSASN_CODE dl_ueassociated_lp_pa_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE dl_ueassociated_lp_pa_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void dl_ueassociated_lp_pa_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // E-RABAdmittedItem ::= SEQUENCE SRSASN_CODE erab_admitted_item_s::pack(bit_ref& bref) const { @@ -11261,7 +10950,7 @@ const char* erab_info_list_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 1, value, "erab_info_list_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // E-RABItem ::= SEQUENCE SRSASN_CODE erab_item_s::pack(bit_ref& bref) const @@ -11365,7 +11054,7 @@ const char* erab_item_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 1, value, "erab_item_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // E-RABModifyItemBearerModConf ::= SEQUENCE SRSASN_CODE erab_modify_item_bearer_mod_conf_s::pack(bit_ref& bref) const @@ -11465,7 +11154,7 @@ const char* erab_modify_item_bearer_mod_conf_ies_o::value_c::types_opts::to_stri return convert_enum_idx(options, 1, value, "erab_modify_item_bearer_mod_conf_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // E-RABModificationConfirmIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t erab_mod_confirm_ies_o::idx_to_id(uint32_t idx) @@ -11863,7 +11552,7 @@ const char* erab_mod_confirm_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 7, value, "erab_mod_confirm_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; erab_mod_confirm_ies_container::erab_mod_confirm_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -11912,53 +11601,67 @@ SRSASN_CODE erab_mod_confirm_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 203: + } + case 203: { erab_modify_list_bearer_mod_conf_present = true; - erab_modify_list_bearer_mod_conf.id = c.id; - erab_modify_list_bearer_mod_conf.crit = c.crit; - erab_modify_list_bearer_mod_conf.value = c.value.erab_modify_list_bearer_mod_conf(); + erab_modify_list_bearer_mod_conf.id = id; + HANDLE_CODE(erab_modify_list_bearer_mod_conf.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_modify_list_bearer_mod_conf.value.unpack(bref)); break; - case 205: + } + case 205: { erab_failed_to_modify_list_bearer_mod_conf_present = true; - erab_failed_to_modify_list_bearer_mod_conf.id = c.id; - erab_failed_to_modify_list_bearer_mod_conf.crit = c.crit; - erab_failed_to_modify_list_bearer_mod_conf.value = c.value.erab_failed_to_modify_list_bearer_mod_conf(); + erab_failed_to_modify_list_bearer_mod_conf.id = id; + HANDLE_CODE(erab_failed_to_modify_list_bearer_mod_conf.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_failed_to_modify_list_bearer_mod_conf.value.unpack(bref)); break; - case 210: + } + case 210: { erab_to_be_released_list_bearer_mod_conf_present = true; - erab_to_be_released_list_bearer_mod_conf.id = c.id; - erab_to_be_released_list_bearer_mod_conf.crit = c.crit; - erab_to_be_released_list_bearer_mod_conf.value = c.value.erab_to_be_released_list_bearer_mod_conf(); + erab_to_be_released_list_bearer_mod_conf.id = id; + HANDLE_CODE(erab_to_be_released_list_bearer_mod_conf.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_to_be_released_list_bearer_mod_conf.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 146: + } + case 146: { csg_membership_status_present = true; - csg_membership_status.id = c.id; - csg_membership_status.crit = c.crit; - csg_membership_status.value = c.value.csg_membership_status(); + csg_membership_status.id = id; + HANDLE_CODE(csg_membership_status.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_membership_status.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -11999,29 +11702,6 @@ void erab_mod_confirm_ies_container::to_json(json_writer& j) const j.end_obj(); } -// E-RABModificationConfirm ::= SEQUENCE -SRSASN_CODE erab_mod_confirm_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE erab_mod_confirm_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void erab_mod_confirm_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // E-RABUsageReportItem ::= SEQUENCE SRSASN_CODE erabusage_report_item_s::pack(bit_ref& bref) const { @@ -12129,7 +11809,7 @@ const char* erabusage_report_item_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 1, value, "erabusage_report_item_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // NR-CGI ::= SEQUENCE SRSASN_CODE nr_cgi_s::pack(bit_ref& bref) const @@ -12595,7 +12275,7 @@ const char* user_location_info_ext_ies_o::ext_c::types_opts::to_string() const return convert_enum_idx(options, 1, value, "user_location_info_ext_ies_o::ext_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // TunnelInformation ::= SEQUENCE SRSASN_CODE tunnel_info_s::pack(bit_ref& bref) const @@ -13124,7 +12804,7 @@ const char* erab_mod_ind_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 8, value, "erab_mod_ind_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; erab_mod_ind_ies_container::erab_mod_ind_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -13175,59 +12855,75 @@ SRSASN_CODE erab_mod_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 199: + } + case 199: { nof_mandatory_ies--; - erab_to_be_modified_list_bearer_mod_ind.id = c.id; - erab_to_be_modified_list_bearer_mod_ind.crit = c.crit; - erab_to_be_modified_list_bearer_mod_ind.value = c.value.erab_to_be_modified_list_bearer_mod_ind(); + erab_to_be_modified_list_bearer_mod_ind.id = id; + HANDLE_CODE(erab_to_be_modified_list_bearer_mod_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_to_be_modified_list_bearer_mod_ind.value.unpack(bref)); break; - case 201: + } + case 201: { erab_not_to_be_modified_list_bearer_mod_ind_present = true; - erab_not_to_be_modified_list_bearer_mod_ind.id = c.id; - erab_not_to_be_modified_list_bearer_mod_ind.crit = c.crit; - erab_not_to_be_modified_list_bearer_mod_ind.value = c.value.erab_not_to_be_modified_list_bearer_mod_ind(); + erab_not_to_be_modified_list_bearer_mod_ind.id = id; + HANDLE_CODE(erab_not_to_be_modified_list_bearer_mod_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_not_to_be_modified_list_bearer_mod_ind.value.unpack(bref)); break; - case 226: + } + case 226: { csg_membership_info_present = true; - csg_membership_info.id = c.id; - csg_membership_info.crit = c.crit; - csg_membership_info.value = c.value.csg_membership_info(); + csg_membership_info.id = id; + HANDLE_CODE(csg_membership_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_membership_info.value.unpack(bref)); break; - case 176: + } + case 176: { tunnel_info_for_bbf_present = true; - tunnel_info_for_bbf.id = c.id; - tunnel_info_for_bbf.crit = c.crit; - tunnel_info_for_bbf.value = c.value.tunnel_info_for_bbf(); + tunnel_info_for_bbf.id = id; + HANDLE_CODE(tunnel_info_for_bbf.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tunnel_info_for_bbf.value.unpack(bref)); break; - case 264: + } + case 264: { secondary_rat_data_usage_report_list_present = true; - secondary_rat_data_usage_report_list.id = c.id; - secondary_rat_data_usage_report_list.crit = c.crit; - secondary_rat_data_usage_report_list.value = c.value.secondary_rat_data_usage_report_list(); + secondary_rat_data_usage_report_list.id = id; + HANDLE_CODE(secondary_rat_data_usage_report_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(secondary_rat_data_usage_report_list.value.unpack(bref)); break; - case 189: + } + case 189: { user_location_info_present = true; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -13270,29 +12966,6 @@ void erab_mod_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// E-RABModificationIndication ::= SEQUENCE -SRSASN_CODE erab_mod_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE erab_mod_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void erab_mod_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // E-RABModifyItemBearerModRes ::= SEQUENCE SRSASN_CODE erab_modify_item_bearer_mod_res_s::pack(bit_ref& bref) const { @@ -13391,7 +13064,7 @@ const char* erab_modify_item_bearer_mod_res_ies_o::value_c::types_opts::to_strin return convert_enum_idx(options, 1, value, "erab_modify_item_bearer_mod_res_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // TransportInformation ::= SEQUENCE SRSASN_CODE transport_info_s::pack(bit_ref& bref) const @@ -13764,7 +13437,7 @@ const char* ue_aggregate_maximum_bitrates_ext_ies_o::ext_c::types_opts::to_strin return convert_enum_idx(options, 2, value, "ue_aggregate_maximum_bitrates_ext_ies_o::ext_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // SecondaryRATDataUsageRequest ::= ENUMERATED const char* secondary_rat_data_usage_request_opts::to_string() const @@ -13773,7 +13446,7 @@ const char* secondary_rat_data_usage_request_opts::to_string() const return convert_enum_idx(options, 1, value, "secondary_rat_data_usage_request_e"); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; ue_aggregate_maximum_bitrates_ext_ies_container::ue_aggregate_maximum_bitrates_ext_ies_container() : extended_u_eaggregate_maximum_bit_rate_dl(259, crit_e::ignore), @@ -13801,23 +13474,27 @@ SRSASN_CODE ue_aggregate_maximum_bitrates_ext_ies_container::unpack(cbit_ref& br unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 259: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 259: { extended_u_eaggregate_maximum_bit_rate_dl_present = true; - extended_u_eaggregate_maximum_bit_rate_dl.id = c.id; - extended_u_eaggregate_maximum_bit_rate_dl.crit = c.crit; - extended_u_eaggregate_maximum_bit_rate_dl.ext = c.ext_value.extended_u_eaggregate_maximum_bit_rate_dl(); + extended_u_eaggregate_maximum_bit_rate_dl.id = id; + HANDLE_CODE(extended_u_eaggregate_maximum_bit_rate_dl.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(extended_u_eaggregate_maximum_bit_rate_dl.ext.unpack(bref)); break; - case 260: + } + case 260: { extended_u_eaggregate_maximum_bit_rate_ul_present = true; - extended_u_eaggregate_maximum_bit_rate_ul.id = c.id; - extended_u_eaggregate_maximum_bit_rate_ul.crit = c.crit; - extended_u_eaggregate_maximum_bit_rate_ul.ext = c.ext_value.extended_u_eaggregate_maximum_bit_rate_ul(); + extended_u_eaggregate_maximum_bit_rate_ul.id = id; + HANDLE_CODE(extended_u_eaggregate_maximum_bit_rate_ul.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(extended_u_eaggregate_maximum_bit_rate_ul.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -14188,7 +13865,7 @@ const char* erab_modify_request_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 5, value, "erab_modify_request_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; erab_modify_request_ies_container::erab_modify_request_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -14224,41 +13901,51 @@ SRSASN_CODE erab_modify_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 66: + } + case 66: { ueaggregate_maximum_bitrate_present = true; - ueaggregate_maximum_bitrate.id = c.id; - ueaggregate_maximum_bitrate.crit = c.crit; - ueaggregate_maximum_bitrate.value = c.value.ueaggregate_maximum_bitrate(); + ueaggregate_maximum_bitrate.id = id; + HANDLE_CODE(ueaggregate_maximum_bitrate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ueaggregate_maximum_bitrate.value.unpack(bref)); break; - case 30: + } + case 30: { nof_mandatory_ies--; - erab_to_be_modified_list_bearer_mod_req.id = c.id; - erab_to_be_modified_list_bearer_mod_req.crit = c.crit; - erab_to_be_modified_list_bearer_mod_req.value = c.value.erab_to_be_modified_list_bearer_mod_req(); + erab_to_be_modified_list_bearer_mod_req.id = id; + HANDLE_CODE(erab_to_be_modified_list_bearer_mod_req.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_to_be_modified_list_bearer_mod_req.value.unpack(bref)); break; - case 268: + } + case 268: { secondary_rat_data_usage_request_present = true; - secondary_rat_data_usage_request.id = c.id; - secondary_rat_data_usage_request.crit = c.crit; - secondary_rat_data_usage_request.value = c.value.secondary_rat_data_usage_request(); + secondary_rat_data_usage_request.id = id; + HANDLE_CODE(secondary_rat_data_usage_request.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(secondary_rat_data_usage_request.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -14289,29 +13976,6 @@ void erab_modify_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// E-RABModifyRequest ::= SEQUENCE -SRSASN_CODE erab_modify_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE erab_modify_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void erab_modify_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // E-RABModifyResponseIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t erab_modify_resp_ies_o::idx_to_id(uint32_t idx) { @@ -14674,8 +14338,7 @@ const char* erab_modify_resp_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 6, value, "erab_modify_resp_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_field_s; erab_modify_resp_ies_container::erab_modify_resp_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -14719,47 +14382,59 @@ SRSASN_CODE erab_modify_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 31: + } + case 31: { erab_modify_list_bearer_mod_res_present = true; - erab_modify_list_bearer_mod_res.id = c.id; - erab_modify_list_bearer_mod_res.crit = c.crit; - erab_modify_list_bearer_mod_res.value = c.value.erab_modify_list_bearer_mod_res(); + erab_modify_list_bearer_mod_res.id = id; + HANDLE_CODE(erab_modify_list_bearer_mod_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_modify_list_bearer_mod_res.value.unpack(bref)); break; - case 32: + } + case 32: { erab_failed_to_modify_list_present = true; - erab_failed_to_modify_list.id = c.id; - erab_failed_to_modify_list.crit = c.crit; - erab_failed_to_modify_list.value = c.value.erab_failed_to_modify_list(); + erab_failed_to_modify_list.id = id; + HANDLE_CODE(erab_failed_to_modify_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_failed_to_modify_list.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 264: + } + case 264: { secondary_rat_data_usage_report_list_present = true; - secondary_rat_data_usage_report_list.id = c.id; - secondary_rat_data_usage_report_list.crit = c.crit; - secondary_rat_data_usage_report_list.value = c.value.secondary_rat_data_usage_report_list(); + secondary_rat_data_usage_report_list.id = id; + HANDLE_CODE(secondary_rat_data_usage_report_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(secondary_rat_data_usage_report_list.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -14796,29 +14471,6 @@ void erab_modify_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// E-RABModifyResponse ::= SEQUENCE -SRSASN_CODE erab_modify_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE erab_modify_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void erab_modify_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // E-RABReleaseCommandIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t erab_release_cmd_ies_o::idx_to_id(uint32_t idx) { @@ -15130,7 +14782,7 @@ const char* erab_release_cmd_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 5, value, "erab_release_cmd_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; erab_release_cmd_ies_container::erab_release_cmd_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -15166,41 +14818,51 @@ SRSASN_CODE erab_release_cmd_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 66: + } + case 66: { ueaggregate_maximum_bitrate_present = true; - ueaggregate_maximum_bitrate.id = c.id; - ueaggregate_maximum_bitrate.crit = c.crit; - ueaggregate_maximum_bitrate.value = c.value.ueaggregate_maximum_bitrate(); + ueaggregate_maximum_bitrate.id = id; + HANDLE_CODE(ueaggregate_maximum_bitrate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ueaggregate_maximum_bitrate.value.unpack(bref)); break; - case 33: + } + case 33: { nof_mandatory_ies--; - erab_to_be_released_list.id = c.id; - erab_to_be_released_list.crit = c.crit; - erab_to_be_released_list.value = c.value.erab_to_be_released_list(); + erab_to_be_released_list.id = id; + HANDLE_CODE(erab_to_be_released_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_to_be_released_list.value.unpack(bref)); break; - case 26: + } + case 26: { nas_pdu_present = true; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -15231,29 +14893,6 @@ void erab_release_cmd_ies_container::to_json(json_writer& j) const j.end_obj(); } -// E-RABReleaseCommand ::= SEQUENCE -SRSASN_CODE erab_release_cmd_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE erab_release_cmd_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void erab_release_cmd_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // E-RABReleaseIndicationIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t erab_release_ind_ies_o::idx_to_id(uint32_t idx) { @@ -15573,7 +15212,7 @@ const char* erab_release_ind_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 5, value, "erab_release_ind_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; erab_release_ind_ies_container::erab_release_ind_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -15609,41 +15248,51 @@ SRSASN_CODE erab_release_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 110: + } + case 110: { nof_mandatory_ies--; - erab_released_list.id = c.id; - erab_released_list.crit = c.crit; - erab_released_list.value = c.value.erab_released_list(); + erab_released_list.id = id; + HANDLE_CODE(erab_released_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_released_list.value.unpack(bref)); break; - case 189: + } + case 189: { user_location_info_present = true; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 264: + } + case 264: { secondary_rat_data_usage_report_list_present = true; - secondary_rat_data_usage_report_list.id = c.id; - secondary_rat_data_usage_report_list.crit = c.crit; - secondary_rat_data_usage_report_list.value = c.value.secondary_rat_data_usage_report_list(); + secondary_rat_data_usage_report_list.id = id; + HANDLE_CODE(secondary_rat_data_usage_report_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(secondary_rat_data_usage_report_list.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -15674,29 +15323,6 @@ void erab_release_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// E-RABReleaseIndication ::= SEQUENCE -SRSASN_CODE erab_release_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE erab_release_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void erab_release_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // E-RABReleaseItemBearerRelComp ::= SEQUENCE SRSASN_CODE erab_release_item_bearer_rel_comp_s::pack(bit_ref& bref) const { @@ -15795,7 +15421,7 @@ const char* erab_release_item_bearer_rel_comp_ies_o::value_c::types_opts::to_str return convert_enum_idx(options, 1, value, "erab_release_item_bearer_rel_comp_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // E-RABReleaseResponseIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t erab_release_resp_ies_o::idx_to_id(uint32_t idx) @@ -16199,7 +15825,7 @@ const char* erab_release_resp_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 7, value, "erab_release_resp_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; erab_release_resp_ies_container::erab_release_resp_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -16248,53 +15874,67 @@ SRSASN_CODE erab_release_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 69: + } + case 69: { erab_release_list_bearer_rel_comp_present = true; - erab_release_list_bearer_rel_comp.id = c.id; - erab_release_list_bearer_rel_comp.crit = c.crit; - erab_release_list_bearer_rel_comp.value = c.value.erab_release_list_bearer_rel_comp(); + erab_release_list_bearer_rel_comp.id = id; + HANDLE_CODE(erab_release_list_bearer_rel_comp.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_release_list_bearer_rel_comp.value.unpack(bref)); break; - case 34: + } + case 34: { erab_failed_to_release_list_present = true; - erab_failed_to_release_list.id = c.id; - erab_failed_to_release_list.crit = c.crit; - erab_failed_to_release_list.value = c.value.erab_failed_to_release_list(); + erab_failed_to_release_list.id = id; + HANDLE_CODE(erab_failed_to_release_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_failed_to_release_list.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 189: + } + case 189: { user_location_info_present = true; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 264: + } + case 264: { secondary_rat_data_usage_report_list_present = true; - secondary_rat_data_usage_report_list.id = c.id; - secondary_rat_data_usage_report_list.crit = c.crit; - secondary_rat_data_usage_report_list.value = c.value.secondary_rat_data_usage_report_list(); + secondary_rat_data_usage_report_list.id = id; + HANDLE_CODE(secondary_rat_data_usage_report_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(secondary_rat_data_usage_report_list.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -16335,29 +15975,6 @@ void erab_release_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// E-RABReleaseResponse ::= SEQUENCE -SRSASN_CODE erab_release_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE erab_release_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void erab_release_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // E-RABSetupItemBearerSURes ::= SEQUENCE SRSASN_CODE erab_setup_item_bearer_su_res_s::pack(bit_ref& bref) const { @@ -16566,9 +16183,9 @@ const char* erab_setup_item_ctxt_su_res_ies_o::value_c::types_opts::to_string() return convert_enum_idx(options, 1, value, "erab_setup_item_ctxt_su_res_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // BearerType ::= ENUMERATED const char* bearer_type_opts::to_string() const @@ -16812,7 +16429,7 @@ const char* erab_to_be_setup_item_bearer_su_req_ext_ies_o::ext_c::types_opts::to return convert_enum_idx(options, 3, value, "erab_to_be_setup_item_bearer_su_req_ext_ies_o::ext_c::types"); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; erab_to_be_setup_item_bearer_su_req_ext_ies_container::erab_to_be_setup_item_bearer_su_req_ext_ies_container() : correlation_id(156, crit_e::ignore), sipto_correlation_id(183, crit_e::ignore), bearer_type(233, crit_e::reject) @@ -16843,29 +16460,35 @@ SRSASN_CODE erab_to_be_setup_item_bearer_su_req_ext_ies_container::unpack(cbit_r unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 156: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 156: { correlation_id_present = true; - correlation_id.id = c.id; - correlation_id.crit = c.crit; - correlation_id.ext = c.ext_value.correlation_id(); + correlation_id.id = id; + HANDLE_CODE(correlation_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(correlation_id.ext.unpack(bref)); break; - case 183: + } + case 183: { sipto_correlation_id_present = true; - sipto_correlation_id.id = c.id; - sipto_correlation_id.crit = c.crit; - sipto_correlation_id.ext = c.ext_value.sipto_correlation_id(); + sipto_correlation_id.id = id; + HANDLE_CODE(sipto_correlation_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(sipto_correlation_id.ext.unpack(bref)); break; - case 233: + } + case 233: { bearer_type_present = true; - bearer_type.id = c.id; - bearer_type.crit = c.crit; - bearer_type.ext = c.ext_value.bearer_type(); + bearer_type.id = id; + HANDLE_CODE(bearer_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(bearer_type.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -17002,7 +16625,7 @@ const char* erab_to_be_setup_item_bearer_su_req_ies_o::value_c::types_opts::to_s return convert_enum_idx(options, 1, value, "erab_to_be_setup_item_bearer_su_req_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // E-RABSetupRequestIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t erab_setup_request_ies_o::idx_to_id(uint32_t idx) @@ -17278,7 +16901,7 @@ const char* erab_setup_request_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 4, value, "erab_setup_request_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; erab_setup_request_ies_container::erab_setup_request_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -17309,35 +16932,43 @@ SRSASN_CODE erab_setup_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 66: + } + case 66: { ueaggregate_maximum_bitrate_present = true; - ueaggregate_maximum_bitrate.id = c.id; - ueaggregate_maximum_bitrate.crit = c.crit; - ueaggregate_maximum_bitrate.value = c.value.ueaggregate_maximum_bitrate(); + ueaggregate_maximum_bitrate.id = id; + HANDLE_CODE(ueaggregate_maximum_bitrate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ueaggregate_maximum_bitrate.value.unpack(bref)); break; - case 16: + } + case 16: { nof_mandatory_ies--; - erab_to_be_setup_list_bearer_su_req.id = c.id; - erab_to_be_setup_list_bearer_su_req.crit = c.crit; - erab_to_be_setup_list_bearer_su_req.value = c.value.erab_to_be_setup_list_bearer_su_req(); + erab_to_be_setup_list_bearer_su_req.id = id; + HANDLE_CODE(erab_to_be_setup_list_bearer_su_req.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_to_be_setup_list_bearer_su_req.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -17364,29 +16995,6 @@ void erab_setup_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// E-RABSetupRequest ::= SEQUENCE -SRSASN_CODE erab_setup_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE erab_setup_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void erab_setup_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // E-RABSetupResponseIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t erab_setup_resp_ies_o::idx_to_id(uint32_t idx) { @@ -17704,7 +17312,7 @@ const char* erab_setup_resp_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 5, value, "erab_setup_resp_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; erab_setup_resp_ies_container::erab_setup_resp_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -17743,41 +17351,51 @@ SRSASN_CODE erab_setup_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 28: + } + case 28: { erab_setup_list_bearer_su_res_present = true; - erab_setup_list_bearer_su_res.id = c.id; - erab_setup_list_bearer_su_res.crit = c.crit; - erab_setup_list_bearer_su_res.value = c.value.erab_setup_list_bearer_su_res(); + erab_setup_list_bearer_su_res.id = id; + HANDLE_CODE(erab_setup_list_bearer_su_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_setup_list_bearer_su_res.value.unpack(bref)); break; - case 29: + } + case 29: { erab_failed_to_setup_list_bearer_su_res_present = true; - erab_failed_to_setup_list_bearer_su_res.id = c.id; - erab_failed_to_setup_list_bearer_su_res.crit = c.crit; - erab_failed_to_setup_list_bearer_su_res.value = c.value.erab_failed_to_setup_list_bearer_su_res(); + erab_failed_to_setup_list_bearer_su_res.id = id; + HANDLE_CODE(erab_failed_to_setup_list_bearer_su_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_failed_to_setup_list_bearer_su_res.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -17810,29 +17428,6 @@ void erab_setup_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// E-RABSetupResponse ::= SEQUENCE -SRSASN_CODE erab_setup_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE erab_setup_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void erab_setup_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // E-RABToBeSetupItemCtxtSUReqExtIEs ::= OBJECT SET OF S1AP-PROTOCOL-EXTENSION uint32_t erab_to_be_setup_item_ctxt_su_req_ext_ies_o::idx_to_id(uint32_t idx) { @@ -18068,7 +17663,7 @@ const char* erab_to_be_setup_item_ctxt_su_req_ext_ies_o::ext_c::types_opts::to_s return convert_enum_idx(options, 3, value, "erab_to_be_setup_item_ctxt_su_req_ext_ies_o::ext_c::types"); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; erab_to_be_setup_item_ctxt_su_req_ext_ies_container::erab_to_be_setup_item_ctxt_su_req_ext_ies_container() : correlation_id(156, crit_e::ignore), sipto_correlation_id(183, crit_e::ignore), bearer_type(233, crit_e::reject) @@ -18099,29 +17694,35 @@ SRSASN_CODE erab_to_be_setup_item_ctxt_su_req_ext_ies_container::unpack(cbit_ref unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 156: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 156: { correlation_id_present = true; - correlation_id.id = c.id; - correlation_id.crit = c.crit; - correlation_id.ext = c.ext_value.correlation_id(); + correlation_id.id = id; + HANDLE_CODE(correlation_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(correlation_id.ext.unpack(bref)); break; - case 183: + } + case 183: { sipto_correlation_id_present = true; - sipto_correlation_id.id = c.id; - sipto_correlation_id.crit = c.crit; - sipto_correlation_id.ext = c.ext_value.sipto_correlation_id(); + sipto_correlation_id.id = id; + HANDLE_CODE(sipto_correlation_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(sipto_correlation_id.ext.unpack(bref)); break; - case 233: + } + case 233: { bearer_type_present = true; - bearer_type.id = c.id; - bearer_type.crit = c.crit; - bearer_type.ext = c.ext_value.bearer_type(); + bearer_type.id = id; + HANDLE_CODE(bearer_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(bearer_type.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -18448,7 +18049,7 @@ const char* erab_to_be_setup_item_ho_req_ext_ies_o::ext_c::types_opts::to_string return convert_enum_idx(options, 2, value, "erab_to_be_setup_item_ho_req_ext_ies_o::ext_c::types"); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; erab_to_be_setup_item_ho_req_ext_ies_container::erab_to_be_setup_item_ho_req_ext_ies_container() : data_forwarding_not_possible(143, crit_e::ignore), bearer_type(233, crit_e::reject) @@ -18475,23 +18076,27 @@ SRSASN_CODE erab_to_be_setup_item_ho_req_ext_ies_container::unpack(cbit_ref& bre unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 143: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 143: { data_forwarding_not_possible_present = true; - data_forwarding_not_possible.id = c.id; - data_forwarding_not_possible.crit = c.crit; - data_forwarding_not_possible.ext = c.ext_value.data_forwarding_not_possible(); + data_forwarding_not_possible.id = id; + HANDLE_CODE(data_forwarding_not_possible.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(data_forwarding_not_possible.ext.unpack(bref)); break; - case 233: + } + case 233: { bearer_type_present = true; - bearer_type.id = c.id; - bearer_type.crit = c.crit; - bearer_type.ext = c.ext_value.bearer_type(); + bearer_type.id = id; + HANDLE_CODE(bearer_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(bearer_type.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -18620,7 +18225,7 @@ const char* erab_to_be_setup_item_ho_req_ies_o::value_c::types_opts::to_string() return convert_enum_idx(options, 1, value, "erab_to_be_setup_item_ho_req_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // E-RABToBeSwitchedDLItem ::= SEQUENCE SRSASN_CODE erab_to_be_switched_dl_item_s::pack(bit_ref& bref) const @@ -19658,7 +19263,7 @@ const char* son_info_reply_ext_ies_o::ext_c::types_opts::to_string() const return convert_enum_idx(options, 1, value, "son_info_reply_ext_ies_o::ext_c::types"); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; x2_tnl_cfg_info_ext_ies_container::x2_tnl_cfg_info_ext_ies_container() : enbx2_extended_transport_layer_addresses(153, crit_e::ignore), @@ -19686,23 +19291,27 @@ SRSASN_CODE x2_tnl_cfg_info_ext_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 153: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 153: { enbx2_extended_transport_layer_addresses_present = true; - enbx2_extended_transport_layer_addresses.id = c.id; - enbx2_extended_transport_layer_addresses.crit = c.crit; - enbx2_extended_transport_layer_addresses.ext = c.ext_value.enbx2_extended_transport_layer_addresses(); + enbx2_extended_transport_layer_addresses.id = id; + HANDLE_CODE(enbx2_extended_transport_layer_addresses.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enbx2_extended_transport_layer_addresses.ext.unpack(bref)); break; - case 193: + } + case 193: { enb_indirect_x2_transport_layer_addresses_present = true; - enb_indirect_x2_transport_layer_addresses.id = c.id; - enb_indirect_x2_transport_layer_addresses.crit = c.crit; - enb_indirect_x2_transport_layer_addresses.ext = c.ext_value.enb_indirect_x2_transport_layer_addresses(); + enb_indirect_x2_transport_layer_addresses.id = id; + HANDLE_CODE(enb_indirect_x2_transport_layer_addresses.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_indirect_x2_transport_layer_addresses.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -19881,7 +19490,7 @@ void en_dc_transfer_type_request_s::to_json(json_writer& j) const j.end_obj(); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // SONInformationReply ::= SEQUENCE SRSASN_CODE son_info_reply_s::pack(bit_ref& bref) const @@ -20725,7 +20334,7 @@ uint8_t enbcp_relocation_ind_ies_o::value_c::types_opts::to_number() const return map_enum_number(options, 1, value, "enbcp_relocation_ind_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; enbcp_relocation_ind_ies_container::enbcp_relocation_ind_ies_container() : enb_ue_s1ap_id(8, crit_e::reject), @@ -20755,41 +20364,51 @@ SRSASN_CODE enbcp_relocation_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 5; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 8: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 96: + } + case 96: { nof_mandatory_ies--; - s_tmsi.id = c.id; - s_tmsi.crit = c.crit; - s_tmsi.value = c.value.s_tmsi(); + s_tmsi.id = id; + HANDLE_CODE(s_tmsi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(s_tmsi.value.unpack(bref)); break; - case 100: + } + case 100: { nof_mandatory_ies--; - eutran_cgi.id = c.id; - eutran_cgi.crit = c.crit; - eutran_cgi.value = c.value.eutran_cgi(); + eutran_cgi.id = id; + HANDLE_CODE(eutran_cgi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(eutran_cgi.value.unpack(bref)); break; - case 67: + } + case 67: { nof_mandatory_ies--; - tai.id = c.id; - tai.crit = c.crit; - tai.value = c.value.tai(); + tai.id = id; + HANDLE_CODE(tai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tai.value.unpack(bref)); break; - case 254: + } + case 254: { nof_mandatory_ies--; - ul_cp_security_info.id = c.id; - ul_cp_security_info.crit = c.crit; - ul_cp_security_info.value = c.value.ul_cp_security_info(); + ul_cp_security_info.id = id; + HANDLE_CODE(ul_cp_security_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ul_cp_security_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -20816,29 +20435,6 @@ void enbcp_relocation_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// ENBCPRelocationIndication ::= SEQUENCE -SRSASN_CODE enbcp_relocation_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE enbcp_relocation_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void enbcp_relocation_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // ListeningSubframePattern ::= SEQUENCE SRSASN_CODE listening_sf_pattern_s::pack(bit_ref& bref) const { @@ -21246,7 +20842,7 @@ void targetenb_id_s::to_json(json_writer& j) const j.end_obj(); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; son_cfg_transfer_ext_ies_container::son_cfg_transfer_ext_ies_container() : x2_tnl_cfg_info(152, crit_e::ignore), synchronisation_info(209, crit_e::ignore) @@ -21273,23 +20869,27 @@ SRSASN_CODE son_cfg_transfer_ext_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 152: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 152: { x2_tnl_cfg_info_present = true; - x2_tnl_cfg_info.id = c.id; - x2_tnl_cfg_info.crit = c.crit; - x2_tnl_cfg_info.ext = c.ext_value.x2_tnl_cfg_info(); + x2_tnl_cfg_info.id = id; + HANDLE_CODE(x2_tnl_cfg_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(x2_tnl_cfg_info.ext.unpack(bref)); break; - case 209: + } + case 209: { synchronisation_info_present = true; - synchronisation_info.id = c.id; - synchronisation_info.crit = c.crit; - synchronisation_info.ext = c.ext_value.synchronisation_info(); + synchronisation_info.id = id; + HANDLE_CODE(synchronisation_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(synchronisation_info.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -21556,7 +21156,7 @@ const char* enb_cfg_transfer_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 2, value, "enb_cfg_transfer_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; enb_cfg_transfer_ies_container::enb_cfg_transfer_ies_container() : son_cfg_transfer_ect(129, crit_e::ignore), en_dcson_cfg_transfer_ect(294, crit_e::ignore) @@ -21583,23 +21183,27 @@ SRSASN_CODE enb_cfg_transfer_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 129: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 129: { son_cfg_transfer_ect_present = true; - son_cfg_transfer_ect.id = c.id; - son_cfg_transfer_ect.crit = c.crit; - son_cfg_transfer_ect.value = c.value.son_cfg_transfer_ect(); + son_cfg_transfer_ect.id = id; + HANDLE_CODE(son_cfg_transfer_ect.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(son_cfg_transfer_ect.value.unpack(bref)); break; - case 294: + } + case 294: { en_dcson_cfg_transfer_ect_present = true; - en_dcson_cfg_transfer_ect.id = c.id; - en_dcson_cfg_transfer_ect.crit = c.crit; - en_dcson_cfg_transfer_ect.value = c.value.en_dcson_cfg_transfer_ect(); + en_dcson_cfg_transfer_ect.id = id; + HANDLE_CODE(en_dcson_cfg_transfer_ect.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(en_dcson_cfg_transfer_ect.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -21620,29 +21224,6 @@ void enb_cfg_transfer_ies_container::to_json(json_writer& j) const j.end_obj(); } -// ENBConfigurationTransfer ::= SEQUENCE -SRSASN_CODE enb_cfg_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE enb_cfg_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void enb_cfg_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // NB-IoT-DefaultPagingDRX ::= ENUMERATED const char* nb_io_t_default_paging_drx_opts::to_string() const { @@ -22069,7 +21650,7 @@ const char* enb_cfg_upd_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 7, value, "enb_cfg_upd_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; enb_cfg_upd_ies_container::enb_cfg_upd_ies_container() : enbname(60, crit_e::ignore), @@ -22122,53 +21703,67 @@ SRSASN_CODE enb_cfg_upd_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 60: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 60: { enbname_present = true; - enbname.id = c.id; - enbname.crit = c.crit; - enbname.value = c.value.enbname(); + enbname.id = id; + HANDLE_CODE(enbname.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enbname.value.unpack(bref)); break; - case 64: + } + case 64: { supported_tas_present = true; - supported_tas.id = c.id; - supported_tas.crit = c.crit; - supported_tas.value = c.value.supported_tas(); + supported_tas.id = id; + HANDLE_CODE(supported_tas.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(supported_tas.value.unpack(bref)); break; - case 128: + } + case 128: { csg_id_list_present = true; - csg_id_list.id = c.id; - csg_id_list.crit = c.crit; - csg_id_list.value = c.value.csg_id_list(); + csg_id_list.id = id; + HANDLE_CODE(csg_id_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_id_list.value.unpack(bref)); break; - case 137: + } + case 137: { default_paging_drx_present = true; - default_paging_drx.id = c.id; - default_paging_drx.crit = c.crit; - default_paging_drx.value = c.value.default_paging_drx(); + default_paging_drx.id = id; + HANDLE_CODE(default_paging_drx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(default_paging_drx.value.unpack(bref)); break; - case 234: + } + case 234: { nb_io_t_default_paging_drx_present = true; - nb_io_t_default_paging_drx.id = c.id; - nb_io_t_default_paging_drx.crit = c.crit; - nb_io_t_default_paging_drx.value = c.value.nb_io_t_default_paging_drx(); + nb_io_t_default_paging_drx.id = id; + HANDLE_CODE(nb_io_t_default_paging_drx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nb_io_t_default_paging_drx.value.unpack(bref)); break; - case 292: + } + case 292: { connectedeng_nb_to_add_list_present = true; - connectedeng_nb_to_add_list.id = c.id; - connectedeng_nb_to_add_list.crit = c.crit; - connectedeng_nb_to_add_list.value = c.value.connectedeng_nb_to_add_list(); + connectedeng_nb_to_add_list.id = id; + HANDLE_CODE(connectedeng_nb_to_add_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(connectedeng_nb_to_add_list.value.unpack(bref)); break; - case 293: + } + case 293: { connectedeng_nb_to_rem_list_present = true; - connectedeng_nb_to_rem_list.id = c.id; - connectedeng_nb_to_rem_list.crit = c.crit; - connectedeng_nb_to_rem_list.value = c.value.connectedeng_nb_to_rem_list(); + connectedeng_nb_to_rem_list.id = id; + HANDLE_CODE(connectedeng_nb_to_rem_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(connectedeng_nb_to_rem_list.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -22209,29 +21804,6 @@ void enb_cfg_upd_ies_container::to_json(json_writer& j) const j.end_obj(); } -// ENBConfigurationUpdate ::= SEQUENCE -SRSASN_CODE enb_cfg_upd_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE enb_cfg_upd_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void enb_cfg_upd_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // ENBConfigurationUpdateAcknowledgeIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t enb_cfg_upd_ack_ies_o::idx_to_id(uint32_t idx) { @@ -22294,28 +21866,6 @@ const char* enb_cfg_upd_ack_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 1, value, "enb_cfg_upd_ack_ies_o::value_c::types"); } -// ENBConfigurationUpdateAcknowledge ::= SEQUENCE -SRSASN_CODE enb_cfg_upd_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(pack_dyn_seq_of(bref, protocol_ies, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE enb_cfg_upd_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(unpack_dyn_seq_of(protocol_ies, bref, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -void enb_cfg_upd_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - j.end_obj(); -} - // TimeToWait ::= ENUMERATED const char* time_to_wait_opts::to_string() const { @@ -22563,7 +22113,7 @@ const char* enb_cfg_upd_fail_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "enb_cfg_upd_fail_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; enb_cfg_upd_fail_ies_container::enb_cfg_upd_fail_ies_container() : cause(2, crit_e::ignore), time_to_wait(65, crit_e::ignore), crit_diagnostics(58, crit_e::ignore) @@ -22593,29 +22143,35 @@ SRSASN_CODE enb_cfg_upd_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 1; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 2: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 65: + } + case 65: { time_to_wait_present = true; - time_to_wait.id = c.id; - time_to_wait.crit = c.crit; - time_to_wait.value = c.value.time_to_wait(); + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -22642,29 +22198,6 @@ void enb_cfg_upd_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// ENBConfigurationUpdateFailure ::= SEQUENCE -SRSASN_CODE enb_cfg_upd_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE enb_cfg_upd_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void enb_cfg_upd_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // LAI ::= SEQUENCE SRSASN_CODE lai_s::pack(bit_ref& bref) const { @@ -23117,28 +22650,6 @@ const char* enb_direct_info_transfer_ies_o::value_c::types_opts::to_string() con return convert_enum_idx(options, 1, value, "enb_direct_info_transfer_ies_o::value_c::types"); } -// ENBDirectInformationTransfer ::= SEQUENCE -SRSASN_CODE enb_direct_info_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(pack_dyn_seq_of(bref, protocol_ies, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE enb_direct_info_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(unpack_dyn_seq_of(protocol_ies, bref, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -void enb_direct_info_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - j.end_obj(); -} - // ENBStatusTransferIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t enb_status_transfer_ies_o::idx_to_id(uint32_t idx) { @@ -23372,7 +22883,7 @@ const char* enb_status_transfer_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "enb_status_transfer_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; enb_status_transfer_ies_container::enb_status_transfer_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -23398,29 +22909,35 @@ SRSASN_CODE enb_status_transfer_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 90: + } + case 90: { nof_mandatory_ies--; - enb_status_transfer_transparent_container.id = c.id; - enb_status_transfer_transparent_container.crit = c.crit; - enb_status_transfer_transparent_container.value = c.value.enb_status_transfer_transparent_container(); + enb_status_transfer_transparent_container.id = id; + HANDLE_CODE(enb_status_transfer_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_status_transfer_transparent_container.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -23443,29 +22960,6 @@ void enb_status_transfer_ies_container::to_json(json_writer& j) const j.end_obj(); } -// ENBStatusTransfer ::= SEQUENCE -SRSASN_CODE enb_status_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE enb_status_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void enb_status_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // EUTRANResponse ::= SEQUENCE SRSASN_CODE eutran_resp_s::pack(bit_ref& bref) const { @@ -23800,7 +23294,7 @@ const char* error_ind_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 5, value, "error_ind_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; error_ind_ies_container::error_ind_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -23843,41 +23337,51 @@ SRSASN_CODE error_ind_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { mme_ue_s1ap_id_present = true; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { enb_ue_s1ap_id_present = true; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 2: + } + case 2: { cause_present = true; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 96: + } + case 96: { s_tmsi_present = true; - s_tmsi.id = c.id; - s_tmsi.crit = c.crit; - s_tmsi.value = c.value.s_tmsi(); + s_tmsi.id = id; + HANDLE_CODE(s_tmsi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(s_tmsi.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -23910,29 +23414,6 @@ void error_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// ErrorIndication ::= SEQUENCE -SRSASN_CODE error_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE error_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void error_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // NumberOfMeasurementReportingLevels ::= ENUMERATED const char* nof_meas_report_levels_opts::to_string() const { @@ -24526,7 +24007,7 @@ const char* ho_cancel_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "ho_cancel_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_cancel_ies_container::ho_cancel_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), enb_ue_s1ap_id(8, crit_e::reject), cause(2, crit_e::ignore) @@ -24550,29 +24031,35 @@ SRSASN_CODE ho_cancel_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -24595,29 +24082,6 @@ void ho_cancel_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverCancel ::= SEQUENCE -SRSASN_CODE ho_cancel_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_cancel_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_cancel_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // HandoverCancelAcknowledgeIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t ho_cancel_ack_ies_o::idx_to_id(uint32_t idx) { @@ -24847,7 +24311,7 @@ const char* ho_cancel_ack_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 3, value, "ho_cancel_ack_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_cancel_ack_ies_container::ho_cancel_ack_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), enb_ue_s1ap_id(8, crit_e::ignore), crit_diagnostics(58, crit_e::ignore) @@ -24874,29 +24338,35 @@ SRSASN_CODE ho_cancel_ack_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -24921,29 +24391,6 @@ void ho_cancel_ack_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverCancelAcknowledge ::= SEQUENCE -SRSASN_CODE ho_cancel_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_cancel_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_cancel_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // HandoverType ::= ENUMERATED const char* handov_type_opts::to_string() const { @@ -25432,7 +24879,7 @@ const char* ho_cmd_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 9, value, "ho_cmd_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_cmd_ies_container::ho_cmd_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -25485,66 +24932,83 @@ SRSASN_CODE ho_cmd_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 1: + } + case 1: { nof_mandatory_ies--; - handov_type.id = c.id; - handov_type.crit = c.crit; - handov_type.value = c.value.handov_type(); + handov_type.id = id; + HANDLE_CODE(handov_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(handov_type.value.unpack(bref)); break; - case 135: + } + case 135: { nas_security_paramsfrom_e_utran_present = true; - nas_security_paramsfrom_e_utran.id = c.id; - nas_security_paramsfrom_e_utran.crit = c.crit; - nas_security_paramsfrom_e_utran.value = c.value.nas_security_paramsfrom_e_utran(); + nas_security_paramsfrom_e_utran.id = id; + HANDLE_CODE(nas_security_paramsfrom_e_utran.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_security_paramsfrom_e_utran.value.unpack(bref)); break; - case 12: + } + case 12: { erab_subjectto_data_forwarding_list_present = true; - erab_subjectto_data_forwarding_list.id = c.id; - erab_subjectto_data_forwarding_list.crit = c.crit; - erab_subjectto_data_forwarding_list.value = c.value.erab_subjectto_data_forwarding_list(); + erab_subjectto_data_forwarding_list.id = id; + HANDLE_CODE(erab_subjectto_data_forwarding_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_subjectto_data_forwarding_list.value.unpack(bref)); break; - case 13: + } + case 13: { erab_to_release_list_ho_cmd_present = true; - erab_to_release_list_ho_cmd.id = c.id; - erab_to_release_list_ho_cmd.crit = c.crit; - erab_to_release_list_ho_cmd.value = c.value.erab_to_release_list_ho_cmd(); + erab_to_release_list_ho_cmd.id = id; + HANDLE_CODE(erab_to_release_list_ho_cmd.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_to_release_list_ho_cmd.value.unpack(bref)); break; - case 123: + } + case 123: { nof_mandatory_ies--; - target_to_source_transparent_container.id = c.id; - target_to_source_transparent_container.crit = c.crit; - target_to_source_transparent_container.value = c.value.target_to_source_transparent_container(); + target_to_source_transparent_container.id = id; + HANDLE_CODE(target_to_source_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(target_to_source_transparent_container.value.unpack(bref)); break; - case 139: + } + case 139: { target_to_source_transparent_container_secondary_present = true; - target_to_source_transparent_container_secondary.id = c.id; - target_to_source_transparent_container_secondary.crit = c.crit; - target_to_source_transparent_container_secondary.value = - c.value.target_to_source_transparent_container_secondary(); + target_to_source_transparent_container_secondary.id = id; + HANDLE_CODE(target_to_source_transparent_container_secondary.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(target_to_source_transparent_container_secondary.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -25589,29 +25053,6 @@ void ho_cmd_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverCommand ::= SEQUENCE -SRSASN_CODE ho_cmd_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_cmd_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_cmd_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // HandoverFailureIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t ho_fail_ies_o::idx_to_id(uint32_t idx) { @@ -25851,7 +25292,7 @@ uint8_t ho_fail_ies_o::value_c::types_opts::to_number() const return map_enum_number(options, 1, value, "ho_fail_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_fail_ies_container::ho_fail_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), cause(2, crit_e::ignore), crit_diagnostics(58, crit_e::ignore) @@ -25878,29 +25319,35 @@ SRSASN_CODE ho_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -25925,29 +25372,6 @@ void ho_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverFailure ::= SEQUENCE -SRSASN_CODE ho_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // HandoverNotifyIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t ho_notify_ies_o::idx_to_id(uint32_t idx) { @@ -26338,7 +25762,7 @@ const char* ho_notify_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 7, value, "ho_notify_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_notify_ies_container::ho_notify_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -26381,53 +25805,67 @@ SRSASN_CODE ho_notify_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 100: + } + case 100: { nof_mandatory_ies--; - eutran_cgi.id = c.id; - eutran_cgi.crit = c.crit; - eutran_cgi.value = c.value.eutran_cgi(); + eutran_cgi.id = id; + HANDLE_CODE(eutran_cgi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(eutran_cgi.value.unpack(bref)); break; - case 67: + } + case 67: { nof_mandatory_ies--; - tai.id = c.id; - tai.crit = c.crit; - tai.value = c.value.tai(); + tai.id = id; + HANDLE_CODE(tai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tai.value.unpack(bref)); break; - case 176: + } + case 176: { tunnel_info_for_bbf_present = true; - tunnel_info_for_bbf.id = c.id; - tunnel_info_for_bbf.crit = c.crit; - tunnel_info_for_bbf.value = c.value.tunnel_info_for_bbf(); + tunnel_info_for_bbf.id = id; + HANDLE_CODE(tunnel_info_for_bbf.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tunnel_info_for_bbf.value.unpack(bref)); break; - case 186: + } + case 186: { lhn_id_present = true; - lhn_id.id = c.id; - lhn_id.crit = c.crit; - lhn_id.value = c.value.lhn_id(); + lhn_id.id = id; + HANDLE_CODE(lhn_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(lhn_id.value.unpack(bref)); break; - case 288: + } + case 288: { ps_cell_info_present = true; - ps_cell_info.id = c.id; - ps_cell_info.crit = c.crit; - ps_cell_info.value = c.value.ps_cell_info(); + ps_cell_info.id = id; + HANDLE_CODE(ps_cell_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ps_cell_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -26464,29 +25902,6 @@ void ho_notify_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverNotify ::= SEQUENCE -SRSASN_CODE ho_notify_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_notify_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_notify_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // HandoverPreparationFailureIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t ho_prep_fail_ies_o::idx_to_id(uint32_t idx) { @@ -26756,7 +26171,7 @@ const char* ho_prep_fail_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 4, value, "ho_prep_fail_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_prep_fail_ies_container::ho_prep_fail_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -26787,35 +26202,43 @@ SRSASN_CODE ho_prep_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -26842,29 +26265,6 @@ void ho_prep_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverPreparationFailure ::= SEQUENCE -SRSASN_CODE ho_prep_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_prep_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_prep_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // MBSFN-ResultToLogInfo ::= SEQUENCE SRSASN_CODE mbsfn_result_to_log_info_s::pack(bit_ref& bref) const { @@ -28303,7 +27703,7 @@ const char* mdt_mode_ext_ie_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 1, value, "mdt_mode_ext_ie_o::value_c::types"); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; immediate_mdt_ext_ies_container::immediate_mdt_ext_ies_container() : m3_cfg(171, crit_e::ignore), @@ -28361,59 +27761,75 @@ SRSASN_CODE immediate_mdt_ext_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 171: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 171: { m3_cfg_present = true; - m3_cfg.id = c.id; - m3_cfg.crit = c.crit; - m3_cfg.ext = c.ext_value.m3_cfg(); + m3_cfg.id = id; + HANDLE_CODE(m3_cfg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(m3_cfg.ext.unpack(bref)); break; - case 172: + } + case 172: { m4_cfg_present = true; - m4_cfg.id = c.id; - m4_cfg.crit = c.crit; - m4_cfg.ext = c.ext_value.m4_cfg(); + m4_cfg.id = id; + HANDLE_CODE(m4_cfg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(m4_cfg.ext.unpack(bref)); break; - case 173: + } + case 173: { m5_cfg_present = true; - m5_cfg.id = c.id; - m5_cfg.crit = c.crit; - m5_cfg.ext = c.ext_value.m5_cfg(); + m5_cfg.id = id; + HANDLE_CODE(m5_cfg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(m5_cfg.ext.unpack(bref)); break; - case 174: + } + case 174: { mdt_location_info_present = true; - mdt_location_info.id = c.id; - mdt_location_info.crit = c.crit; - mdt_location_info.ext = c.ext_value.mdt_location_info(); + mdt_location_info.id = id; + HANDLE_CODE(mdt_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mdt_location_info.ext.unpack(bref)); break; - case 220: + } + case 220: { m6_cfg_present = true; - m6_cfg.id = c.id; - m6_cfg.crit = c.crit; - m6_cfg.ext = c.ext_value.m6_cfg(); + m6_cfg.id = id; + HANDLE_CODE(m6_cfg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(m6_cfg.ext.unpack(bref)); break; - case 221: + } + case 221: { m7_cfg_present = true; - m7_cfg.id = c.id; - m7_cfg.crit = c.crit; - m7_cfg.ext = c.ext_value.m7_cfg(); + m7_cfg.id = id; + HANDLE_CODE(m7_cfg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(m7_cfg.ext.unpack(bref)); break; - case 284: + } + case 284: { bluetooth_meas_cfg_present = true; - bluetooth_meas_cfg.id = c.id; - bluetooth_meas_cfg.crit = c.crit; - bluetooth_meas_cfg.ext = c.ext_value.bluetooth_meas_cfg(); + bluetooth_meas_cfg.id = id; + HANDLE_CODE(bluetooth_meas_cfg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(bluetooth_meas_cfg.ext.unpack(bref)); break; - case 285: + } + case 285: { wlan_meas_cfg_present = true; - wlan_meas_cfg.id = c.id; - wlan_meas_cfg.crit = c.crit; - wlan_meas_cfg.ext = c.ext_value.wlan_meas_cfg(); + wlan_meas_cfg.id = id; + HANDLE_CODE(wlan_meas_cfg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(wlan_meas_cfg.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -28521,7 +27937,7 @@ void immediate_mdt_s::to_json(json_writer& j) const j.end_obj(); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; logged_mdt_ext_ies_container::logged_mdt_ext_ies_container() : bluetooth_meas_cfg(284, crit_e::ignore), wlan_meas_cfg(285, crit_e::ignore) @@ -28548,23 +27964,27 @@ SRSASN_CODE logged_mdt_ext_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 284: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 284: { bluetooth_meas_cfg_present = true; - bluetooth_meas_cfg.id = c.id; - bluetooth_meas_cfg.crit = c.crit; - bluetooth_meas_cfg.ext = c.ext_value.bluetooth_meas_cfg(); + bluetooth_meas_cfg.id = id; + HANDLE_CODE(bluetooth_meas_cfg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(bluetooth_meas_cfg.ext.unpack(bref)); break; - case 285: + } + case 285: { wlan_meas_cfg_present = true; - wlan_meas_cfg.id = c.id; - wlan_meas_cfg.crit = c.crit; - wlan_meas_cfg.ext = c.ext_value.wlan_meas_cfg(); + wlan_meas_cfg.id = id; + HANDLE_CODE(wlan_meas_cfg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(wlan_meas_cfg.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -28624,7 +28044,7 @@ void logged_mdt_s::to_json(json_writer& j) const j.end_obj(); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // ServiceType ::= ENUMERATED const char* service_type_opts::to_string() const @@ -29555,7 +28975,7 @@ void security_context_s::to_json(json_writer& j) const j.end_obj(); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; trace_activation_ext_ies_container::trace_activation_ext_ies_container() : mdt_cfg(162, crit_e::ignore), ue_app_layer_meas_cfg(262, crit_e::ignore) @@ -29582,23 +29002,27 @@ SRSASN_CODE trace_activation_ext_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 162: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 162: { mdt_cfg_present = true; - mdt_cfg.id = c.id; - mdt_cfg.crit = c.crit; - mdt_cfg.ext = c.ext_value.mdt_cfg(); + mdt_cfg.id = id; + HANDLE_CODE(mdt_cfg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mdt_cfg.ext.unpack(bref)); break; - case 262: + } + case 262: { ue_app_layer_meas_cfg_present = true; - ue_app_layer_meas_cfg.id = c.id; - ue_app_layer_meas_cfg.crit = c.crit; - ue_app_layer_meas_cfg.ext = c.ext_value.ue_app_layer_meas_cfg(); + ue_app_layer_meas_cfg.id = id; + HANDLE_CODE(ue_app_layer_meas_cfg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_app_layer_meas_cfg.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -31152,7 +30576,7 @@ const char* ho_request_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 32, value, "ho_request_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_request_ies_container::ho_request_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -31308,203 +30732,267 @@ SRSASN_CODE ho_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 8; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 1: + } + case 1: { nof_mandatory_ies--; - handov_type.id = c.id; - handov_type.crit = c.crit; - handov_type.value = c.value.handov_type(); + handov_type.id = id; + HANDLE_CODE(handov_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(handov_type.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 66: + } + case 66: { nof_mandatory_ies--; - ueaggregate_maximum_bitrate.id = c.id; - ueaggregate_maximum_bitrate.crit = c.crit; - ueaggregate_maximum_bitrate.value = c.value.ueaggregate_maximum_bitrate(); + ueaggregate_maximum_bitrate.id = id; + HANDLE_CODE(ueaggregate_maximum_bitrate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ueaggregate_maximum_bitrate.value.unpack(bref)); break; - case 53: + } + case 53: { nof_mandatory_ies--; - erab_to_be_setup_list_ho_req.id = c.id; - erab_to_be_setup_list_ho_req.crit = c.crit; - erab_to_be_setup_list_ho_req.value = c.value.erab_to_be_setup_list_ho_req(); + erab_to_be_setup_list_ho_req.id = id; + HANDLE_CODE(erab_to_be_setup_list_ho_req.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_to_be_setup_list_ho_req.value.unpack(bref)); break; - case 104: + } + case 104: { nof_mandatory_ies--; - source_to_target_transparent_container.id = c.id; - source_to_target_transparent_container.crit = c.crit; - source_to_target_transparent_container.value = c.value.source_to_target_transparent_container(); + source_to_target_transparent_container.id = id; + HANDLE_CODE(source_to_target_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(source_to_target_transparent_container.value.unpack(bref)); break; - case 107: + } + case 107: { nof_mandatory_ies--; - ue_security_cap.id = c.id; - ue_security_cap.crit = c.crit; - ue_security_cap.value = c.value.ue_security_cap(); + ue_security_cap.id = id; + HANDLE_CODE(ue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_security_cap.value.unpack(bref)); break; - case 41: + } + case 41: { ho_restrict_list_present = true; - ho_restrict_list.id = c.id; - ho_restrict_list.crit = c.crit; - ho_restrict_list.value = c.value.ho_restrict_list(); + ho_restrict_list.id = id; + HANDLE_CODE(ho_restrict_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ho_restrict_list.value.unpack(bref)); break; - case 25: + } + case 25: { trace_activation_present = true; - trace_activation.id = c.id; - trace_activation.crit = c.crit; - trace_activation.value = c.value.trace_activation(); + trace_activation.id = id; + HANDLE_CODE(trace_activation.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(trace_activation.value.unpack(bref)); break; - case 98: + } + case 98: { request_type_present = true; - request_type.id = c.id; - request_type.crit = c.crit; - request_type.value = c.value.request_type(); + request_type.id = id; + HANDLE_CODE(request_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(request_type.value.unpack(bref)); break; - case 124: + } + case 124: { srvcc_operation_possible_present = true; - srvcc_operation_possible.id = c.id; - srvcc_operation_possible.crit = c.crit; - srvcc_operation_possible.value = c.value.srvcc_operation_possible(); + srvcc_operation_possible.id = id; + HANDLE_CODE(srvcc_operation_possible.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(srvcc_operation_possible.value.unpack(bref)); break; - case 40: + } + case 40: { nof_mandatory_ies--; - security_context.id = c.id; - security_context.crit = c.crit; - security_context.value = c.value.security_context(); + security_context.id = id; + HANDLE_CODE(security_context.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_context.value.unpack(bref)); break; - case 136: + } + case 136: { nas_security_paramsto_e_utran_present = true; - nas_security_paramsto_e_utran.id = c.id; - nas_security_paramsto_e_utran.crit = c.crit; - nas_security_paramsto_e_utran.value = c.value.nas_security_paramsto_e_utran(); + nas_security_paramsto_e_utran.id = id; + HANDLE_CODE(nas_security_paramsto_e_utran.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_security_paramsto_e_utran.value.unpack(bref)); break; - case 127: + } + case 127: { csg_id_present = true; - csg_id.id = c.id; - csg_id.crit = c.crit; - csg_id.value = c.value.csg_id(); + csg_id.id = id; + HANDLE_CODE(csg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_id.value.unpack(bref)); break; - case 146: + } + case 146: { csg_membership_status_present = true; - csg_membership_status.id = c.id; - csg_membership_status.crit = c.crit; - csg_membership_status.value = c.value.csg_membership_status(); + csg_membership_status.id = id; + HANDLE_CODE(csg_membership_status.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_membership_status.value.unpack(bref)); break; - case 75: + } + case 75: { gummei_id_present = true; - gummei_id.id = c.id; - gummei_id.crit = c.crit; - gummei_id.value = c.value.gummei_id(); + gummei_id.id = id; + HANDLE_CODE(gummei_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(gummei_id.value.unpack(bref)); break; - case 158: + } + case 158: { mme_ue_s1ap_id_minus2_present = true; - mme_ue_s1ap_id_minus2.id = c.id; - mme_ue_s1ap_id_minus2.crit = c.crit; - mme_ue_s1ap_id_minus2.value = c.value.mme_ue_s1ap_id_minus2(); + mme_ue_s1ap_id_minus2.id = id; + HANDLE_CODE(mme_ue_s1ap_id_minus2.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id_minus2.value.unpack(bref)); break; - case 165: + } + case 165: { management_based_mdt_allowed_present = true; - management_based_mdt_allowed.id = c.id; - management_based_mdt_allowed.crit = c.crit; - management_based_mdt_allowed.value = c.value.management_based_mdt_allowed(); + management_based_mdt_allowed.id = id; + HANDLE_CODE(management_based_mdt_allowed.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(management_based_mdt_allowed.value.unpack(bref)); break; - case 177: + } + case 177: { management_based_mdtplmn_list_present = true; - management_based_mdtplmn_list.id = c.id; - management_based_mdtplmn_list.crit = c.crit; - management_based_mdtplmn_list.value = c.value.management_based_mdtplmn_list(); + management_based_mdtplmn_list.id = id; + HANDLE_CODE(management_based_mdtplmn_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(management_based_mdtplmn_list.value.unpack(bref)); break; - case 192: + } + case 192: { masked_imeisv_present = true; - masked_imeisv.id = c.id; - masked_imeisv.crit = c.crit; - masked_imeisv.value = c.value.masked_imeisv(); + masked_imeisv.id = id; + HANDLE_CODE(masked_imeisv.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(masked_imeisv.value.unpack(bref)); break; - case 196: + } + case 196: { expected_ue_behaviour_present = true; - expected_ue_behaviour.id = c.id; - expected_ue_behaviour.crit = c.crit; - expected_ue_behaviour.value = c.value.expected_ue_behaviour(); + expected_ue_behaviour.id = id; + HANDLE_CODE(expected_ue_behaviour.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(expected_ue_behaviour.value.unpack(bref)); break; - case 195: + } + case 195: { pro_se_authorized_present = true; - pro_se_authorized.id = c.id; - pro_se_authorized.crit = c.crit; - pro_se_authorized.value = c.value.pro_se_authorized(); + pro_se_authorized.id = id; + HANDLE_CODE(pro_se_authorized.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pro_se_authorized.value.unpack(bref)); break; - case 241: + } + case 241: { ueuser_plane_cio_tsupport_ind_present = true; - ueuser_plane_cio_tsupport_ind.id = c.id; - ueuser_plane_cio_tsupport_ind.crit = c.crit; - ueuser_plane_cio_tsupport_ind.value = c.value.ueuser_plane_cio_tsupport_ind(); + ueuser_plane_cio_tsupport_ind.id = id; + HANDLE_CODE(ueuser_plane_cio_tsupport_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ueuser_plane_cio_tsupport_ind.value.unpack(bref)); break; - case 240: + } + case 240: { v2xservices_authorized_present = true; - v2xservices_authorized.id = c.id; - v2xservices_authorized.crit = c.crit; - v2xservices_authorized.value = c.value.v2xservices_authorized(); + v2xservices_authorized.id = id; + HANDLE_CODE(v2xservices_authorized.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(v2xservices_authorized.value.unpack(bref)); break; - case 248: + } + case 248: { ue_sidelink_aggregate_maximum_bitrate_present = true; - ue_sidelink_aggregate_maximum_bitrate.id = c.id; - ue_sidelink_aggregate_maximum_bitrate.crit = c.crit; - ue_sidelink_aggregate_maximum_bitrate.value = c.value.ue_sidelink_aggregate_maximum_bitrate(); + ue_sidelink_aggregate_maximum_bitrate.id = id; + HANDLE_CODE(ue_sidelink_aggregate_maximum_bitrate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_sidelink_aggregate_maximum_bitrate.value.unpack(bref)); break; - case 251: + } + case 251: { enhanced_coverage_restricted_present = true; - enhanced_coverage_restricted.id = c.id; - enhanced_coverage_restricted.crit = c.crit; - enhanced_coverage_restricted.value = c.value.enhanced_coverage_restricted(); + enhanced_coverage_restricted.id = id; + HANDLE_CODE(enhanced_coverage_restricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enhanced_coverage_restricted.value.unpack(bref)); break; - case 269: + } + case 269: { nrue_security_cap_present = true; - nrue_security_cap.id = c.id; - nrue_security_cap.crit = c.crit; - nrue_security_cap.value = c.value.nrue_security_cap(); + nrue_security_cap.id = id; + HANDLE_CODE(nrue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrue_security_cap.value.unpack(bref)); break; - case 271: + } + case 271: { ce_mode_brestricted_present = true; - ce_mode_brestricted.id = c.id; - ce_mode_brestricted.crit = c.crit; - ce_mode_brestricted.value = c.value.ce_mode_brestricted(); + ce_mode_brestricted.id = id; + HANDLE_CODE(ce_mode_brestricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ce_mode_brestricted.value.unpack(bref)); break; - case 277: + } + case 277: { aerial_uesubscription_info_present = true; - aerial_uesubscription_info.id = c.id; - aerial_uesubscription_info.crit = c.crit; - aerial_uesubscription_info.value = c.value.aerial_uesubscription_info(); + aerial_uesubscription_info.id = id; + HANDLE_CODE(aerial_uesubscription_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(aerial_uesubscription_info.value.unpack(bref)); break; - case 283: + } + case 283: { pending_data_ind_present = true; - pending_data_ind.id = c.id; - pending_data_ind.crit = c.crit; - pending_data_ind.value = c.value.pending_data_ind(); + pending_data_ind.id = id; + HANDLE_CODE(pending_data_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pending_data_ind.value.unpack(bref)); break; - case 278: + } + case 278: { subscription_based_ue_differentiation_info_present = true; - subscription_based_ue_differentiation_info.id = c.id; - subscription_based_ue_differentiation_info.crit = c.crit; - subscription_based_ue_differentiation_info.value = c.value.subscription_based_ue_differentiation_info(); + subscription_based_ue_differentiation_info.id = id; + HANDLE_CODE(subscription_based_ue_differentiation_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(subscription_based_ue_differentiation_info.value.unpack(bref)); break; - case 299: + } + case 299: { add_rrm_prio_idx_present = true; - add_rrm_prio_idx.id = c.id; - add_rrm_prio_idx.crit = c.crit; - add_rrm_prio_idx.value = c.value.add_rrm_prio_idx(); + add_rrm_prio_idx.id = id; + HANDLE_CODE(add_rrm_prio_idx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(add_rrm_prio_idx.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -31633,29 +31121,6 @@ void ho_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverRequest ::= SEQUENCE -SRSASN_CODE ho_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // CE-mode-B-SupportIndicator ::= ENUMERATED const char* ce_mode_b_support_ind_opts::to_string() const { @@ -32124,7 +31589,7 @@ const char* ho_request_ack_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 9, value, "ho_request_ack_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_request_ack_ies_container::ho_request_ack_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -32177,65 +31642,83 @@ SRSASN_CODE ho_request_ack_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 18: + } + case 18: { nof_mandatory_ies--; - erab_admitted_list.id = c.id; - erab_admitted_list.crit = c.crit; - erab_admitted_list.value = c.value.erab_admitted_list(); + erab_admitted_list.id = id; + HANDLE_CODE(erab_admitted_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_admitted_list.value.unpack(bref)); break; - case 19: + } + case 19: { erab_failed_to_setup_list_ho_req_ack_present = true; - erab_failed_to_setup_list_ho_req_ack.id = c.id; - erab_failed_to_setup_list_ho_req_ack.crit = c.crit; - erab_failed_to_setup_list_ho_req_ack.value = c.value.erab_failed_to_setup_list_ho_req_ack(); + erab_failed_to_setup_list_ho_req_ack.id = id; + HANDLE_CODE(erab_failed_to_setup_list_ho_req_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_failed_to_setup_list_ho_req_ack.value.unpack(bref)); break; - case 123: + } + case 123: { nof_mandatory_ies--; - target_to_source_transparent_container.id = c.id; - target_to_source_transparent_container.crit = c.crit; - target_to_source_transparent_container.value = c.value.target_to_source_transparent_container(); + target_to_source_transparent_container.id = id; + HANDLE_CODE(target_to_source_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(target_to_source_transparent_container.value.unpack(bref)); break; - case 127: + } + case 127: { csg_id_present = true; - csg_id.id = c.id; - csg_id.crit = c.crit; - csg_id.value = c.value.csg_id(); + csg_id.id = id; + HANDLE_CODE(csg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_id.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 145: + } + case 145: { cell_access_mode_present = true; - cell_access_mode.id = c.id; - cell_access_mode.crit = c.crit; - cell_access_mode.value = c.value.cell_access_mode(); + cell_access_mode.id = id; + HANDLE_CODE(cell_access_mode.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cell_access_mode.value.unpack(bref)); break; - case 242: + } + case 242: { ce_mode_b_support_ind_present = true; - ce_mode_b_support_ind.id = c.id; - ce_mode_b_support_ind.crit = c.crit; - ce_mode_b_support_ind.value = c.value.ce_mode_b_support_ind(); + ce_mode_b_support_ind.id = id; + HANDLE_CODE(ce_mode_b_support_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ce_mode_b_support_ind.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -32280,29 +31763,6 @@ void ho_request_ack_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverRequestAcknowledge ::= SEQUENCE -SRSASN_CODE ho_request_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_request_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_request_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // TargetNgRanNode-ID ::= SEQUENCE SRSASN_CODE target_ng_ran_node_id_s::pack(bit_ref& bref) const { @@ -33198,7 +32658,7 @@ const char* ho_required_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 14, value, "ho_required_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ho_required_ies_container::ho_required_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -33270,96 +32730,123 @@ SRSASN_CODE ho_required_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 6; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 1: + } + case 1: { nof_mandatory_ies--; - handov_type.id = c.id; - handov_type.crit = c.crit; - handov_type.value = c.value.handov_type(); + handov_type.id = id; + HANDLE_CODE(handov_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(handov_type.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 4: + } + case 4: { nof_mandatory_ies--; - target_id.id = c.id; - target_id.crit = c.crit; - target_id.value = c.value.target_id(); + target_id.id = id; + HANDLE_CODE(target_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(target_id.value.unpack(bref)); break; - case 79: + } + case 79: { direct_forwarding_path_availability_present = true; - direct_forwarding_path_availability.id = c.id; - direct_forwarding_path_availability.crit = c.crit; - direct_forwarding_path_availability.value = c.value.direct_forwarding_path_availability(); + direct_forwarding_path_availability.id = id; + HANDLE_CODE(direct_forwarding_path_availability.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(direct_forwarding_path_availability.value.unpack(bref)); break; - case 125: + } + case 125: { srvccho_ind_present = true; - srvccho_ind.id = c.id; - srvccho_ind.crit = c.crit; - srvccho_ind.value = c.value.srvccho_ind(); + srvccho_ind.id = id; + HANDLE_CODE(srvccho_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(srvccho_ind.value.unpack(bref)); break; - case 104: + } + case 104: { nof_mandatory_ies--; - source_to_target_transparent_container.id = c.id; - source_to_target_transparent_container.crit = c.crit; - source_to_target_transparent_container.value = c.value.source_to_target_transparent_container(); + source_to_target_transparent_container.id = id; + HANDLE_CODE(source_to_target_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(source_to_target_transparent_container.value.unpack(bref)); break; - case 138: + } + case 138: { source_to_target_transparent_container_secondary_present = true; - source_to_target_transparent_container_secondary.id = c.id; - source_to_target_transparent_container_secondary.crit = c.crit; - source_to_target_transparent_container_secondary.value = - c.value.source_to_target_transparent_container_secondary(); + source_to_target_transparent_container_secondary.id = id; + HANDLE_CODE(source_to_target_transparent_container_secondary.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(source_to_target_transparent_container_secondary.value.unpack(bref)); break; - case 132: + } + case 132: { ms_classmark2_present = true; - ms_classmark2.id = c.id; - ms_classmark2.crit = c.crit; - ms_classmark2.value = c.value.ms_classmark2(); + ms_classmark2.id = id; + HANDLE_CODE(ms_classmark2.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ms_classmark2.value.unpack(bref)); break; - case 133: + } + case 133: { ms_classmark3_present = true; - ms_classmark3.id = c.id; - ms_classmark3.crit = c.crit; - ms_classmark3.value = c.value.ms_classmark3(); + ms_classmark3.id = id; + HANDLE_CODE(ms_classmark3.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ms_classmark3.value.unpack(bref)); break; - case 127: + } + case 127: { csg_id_present = true; - csg_id.id = c.id; - csg_id.crit = c.crit; - csg_id.value = c.value.csg_id(); + csg_id.id = id; + HANDLE_CODE(csg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_id.value.unpack(bref)); break; - case 145: + } + case 145: { cell_access_mode_present = true; - cell_access_mode.id = c.id; - cell_access_mode.crit = c.crit; - cell_access_mode.value = c.value.cell_access_mode(); + cell_access_mode.id = id; + HANDLE_CODE(cell_access_mode.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cell_access_mode.value.unpack(bref)); break; - case 150: + } + case 150: { ps_service_not_available_present = true; - ps_service_not_available.id = c.id; - ps_service_not_available.crit = c.crit; - ps_service_not_available.value = c.value.ps_service_not_available(); + ps_service_not_available.id = id; + HANDLE_CODE(ps_service_not_available.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ps_service_not_available.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -33420,29 +32907,6 @@ void ho_required_ies_container::to_json(json_writer& j) const j.end_obj(); } -// HandoverRequired ::= SEQUENCE -SRSASN_CODE ho_required_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ho_required_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ho_required_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // MMEPagingTarget ::= CHOICE void mme_paging_target_c::destroy_() { @@ -33678,7 +33142,7 @@ const char* recommended_enb_item_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 1, value, "recommended_enb_item_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // RecommendedENBsForPaging ::= SEQUENCE SRSASN_CODE recommended_enbs_for_paging_s::pack(bit_ref& bref) const @@ -34031,7 +33495,7 @@ const char* init_context_setup_fail_ies_o::value_c::types_opts::to_string() cons return convert_enum_idx(options, 4, value, "init_context_setup_fail_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; init_context_setup_fail_ies_container::init_context_setup_fail_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -34062,35 +33526,43 @@ SRSASN_CODE init_context_setup_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -34117,29 +33589,6 @@ void init_context_setup_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// InitialContextSetupFailure ::= SEQUENCE -SRSASN_CODE init_context_setup_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE init_context_setup_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void init_context_setup_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // AdditionalCSFallbackIndicator ::= ENUMERATED const char* add_cs_fallback_ind_opts::to_string() const { @@ -35495,7 +34944,7 @@ const char* init_context_setup_request_ies_o::value_c::types_opts::to_string() c return convert_enum_idx(options, 32, value, "init_context_setup_request_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; init_context_setup_request_ies_container::init_context_setup_request_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -35657,203 +35106,267 @@ SRSASN_CODE init_context_setup_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 6; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 66: + } + case 66: { nof_mandatory_ies--; - ueaggregate_maximum_bitrate.id = c.id; - ueaggregate_maximum_bitrate.crit = c.crit; - ueaggregate_maximum_bitrate.value = c.value.ueaggregate_maximum_bitrate(); + ueaggregate_maximum_bitrate.id = id; + HANDLE_CODE(ueaggregate_maximum_bitrate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ueaggregate_maximum_bitrate.value.unpack(bref)); break; - case 24: + } + case 24: { nof_mandatory_ies--; - erab_to_be_setup_list_ctxt_su_req.id = c.id; - erab_to_be_setup_list_ctxt_su_req.crit = c.crit; - erab_to_be_setup_list_ctxt_su_req.value = c.value.erab_to_be_setup_list_ctxt_su_req(); + erab_to_be_setup_list_ctxt_su_req.id = id; + HANDLE_CODE(erab_to_be_setup_list_ctxt_su_req.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_to_be_setup_list_ctxt_su_req.value.unpack(bref)); break; - case 107: + } + case 107: { nof_mandatory_ies--; - ue_security_cap.id = c.id; - ue_security_cap.crit = c.crit; - ue_security_cap.value = c.value.ue_security_cap(); + ue_security_cap.id = id; + HANDLE_CODE(ue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_security_cap.value.unpack(bref)); break; - case 73: + } + case 73: { nof_mandatory_ies--; - security_key.id = c.id; - security_key.crit = c.crit; - security_key.value = c.value.security_key(); + security_key.id = id; + HANDLE_CODE(security_key.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_key.value.unpack(bref)); break; - case 25: + } + case 25: { trace_activation_present = true; - trace_activation.id = c.id; - trace_activation.crit = c.crit; - trace_activation.value = c.value.trace_activation(); + trace_activation.id = id; + HANDLE_CODE(trace_activation.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(trace_activation.value.unpack(bref)); break; - case 41: + } + case 41: { ho_restrict_list_present = true; - ho_restrict_list.id = c.id; - ho_restrict_list.crit = c.crit; - ho_restrict_list.value = c.value.ho_restrict_list(); + ho_restrict_list.id = id; + HANDLE_CODE(ho_restrict_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ho_restrict_list.value.unpack(bref)); break; - case 74: + } + case 74: { ue_radio_cap_present = true; - ue_radio_cap.id = c.id; - ue_radio_cap.crit = c.crit; - ue_radio_cap.value = c.value.ue_radio_cap(); + ue_radio_cap.id = id; + HANDLE_CODE(ue_radio_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap.value.unpack(bref)); break; - case 106: + } + case 106: { subscriber_profile_idfor_rfp_present = true; - subscriber_profile_idfor_rfp.id = c.id; - subscriber_profile_idfor_rfp.crit = c.crit; - subscriber_profile_idfor_rfp.value = c.value.subscriber_profile_idfor_rfp(); + subscriber_profile_idfor_rfp.id = id; + HANDLE_CODE(subscriber_profile_idfor_rfp.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(subscriber_profile_idfor_rfp.value.unpack(bref)); break; - case 108: + } + case 108: { cs_fallback_ind_present = true; - cs_fallback_ind.id = c.id; - cs_fallback_ind.crit = c.crit; - cs_fallback_ind.value = c.value.cs_fallback_ind(); + cs_fallback_ind.id = id; + HANDLE_CODE(cs_fallback_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cs_fallback_ind.value.unpack(bref)); break; - case 124: + } + case 124: { srvcc_operation_possible_present = true; - srvcc_operation_possible.id = c.id; - srvcc_operation_possible.crit = c.crit; - srvcc_operation_possible.value = c.value.srvcc_operation_possible(); + srvcc_operation_possible.id = id; + HANDLE_CODE(srvcc_operation_possible.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(srvcc_operation_possible.value.unpack(bref)); break; - case 146: + } + case 146: { csg_membership_status_present = true; - csg_membership_status.id = c.id; - csg_membership_status.crit = c.crit; - csg_membership_status.value = c.value.csg_membership_status(); + csg_membership_status.id = id; + HANDLE_CODE(csg_membership_status.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_membership_status.value.unpack(bref)); break; - case 159: + } + case 159: { registered_lai_present = true; - registered_lai.id = c.id; - registered_lai.crit = c.crit; - registered_lai.value = c.value.registered_lai(); + registered_lai.id = id; + HANDLE_CODE(registered_lai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(registered_lai.value.unpack(bref)); break; - case 75: + } + case 75: { gummei_id_present = true; - gummei_id.id = c.id; - gummei_id.crit = c.crit; - gummei_id.value = c.value.gummei_id(); + gummei_id.id = id; + HANDLE_CODE(gummei_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(gummei_id.value.unpack(bref)); break; - case 158: + } + case 158: { mme_ue_s1ap_id_minus2_present = true; - mme_ue_s1ap_id_minus2.id = c.id; - mme_ue_s1ap_id_minus2.crit = c.crit; - mme_ue_s1ap_id_minus2.value = c.value.mme_ue_s1ap_id_minus2(); + mme_ue_s1ap_id_minus2.id = id; + HANDLE_CODE(mme_ue_s1ap_id_minus2.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id_minus2.value.unpack(bref)); break; - case 165: + } + case 165: { management_based_mdt_allowed_present = true; - management_based_mdt_allowed.id = c.id; - management_based_mdt_allowed.crit = c.crit; - management_based_mdt_allowed.value = c.value.management_based_mdt_allowed(); + management_based_mdt_allowed.id = id; + HANDLE_CODE(management_based_mdt_allowed.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(management_based_mdt_allowed.value.unpack(bref)); break; - case 177: + } + case 177: { management_based_mdtplmn_list_present = true; - management_based_mdtplmn_list.id = c.id; - management_based_mdtplmn_list.crit = c.crit; - management_based_mdtplmn_list.value = c.value.management_based_mdtplmn_list(); + management_based_mdtplmn_list.id = id; + HANDLE_CODE(management_based_mdtplmn_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(management_based_mdtplmn_list.value.unpack(bref)); break; - case 187: + } + case 187: { add_cs_fallback_ind_present = true; - add_cs_fallback_ind.id = c.id; - add_cs_fallback_ind.crit = c.crit; - add_cs_fallback_ind.value = c.value.add_cs_fallback_ind(); + add_cs_fallback_ind.id = id; + HANDLE_CODE(add_cs_fallback_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(add_cs_fallback_ind.value.unpack(bref)); break; - case 192: + } + case 192: { masked_imeisv_present = true; - masked_imeisv.id = c.id; - masked_imeisv.crit = c.crit; - masked_imeisv.value = c.value.masked_imeisv(); + masked_imeisv.id = id; + HANDLE_CODE(masked_imeisv.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(masked_imeisv.value.unpack(bref)); break; - case 196: + } + case 196: { expected_ue_behaviour_present = true; - expected_ue_behaviour.id = c.id; - expected_ue_behaviour.crit = c.crit; - expected_ue_behaviour.value = c.value.expected_ue_behaviour(); + expected_ue_behaviour.id = id; + HANDLE_CODE(expected_ue_behaviour.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(expected_ue_behaviour.value.unpack(bref)); break; - case 195: + } + case 195: { pro_se_authorized_present = true; - pro_se_authorized.id = c.id; - pro_se_authorized.crit = c.crit; - pro_se_authorized.value = c.value.pro_se_authorized(); + pro_se_authorized.id = id; + HANDLE_CODE(pro_se_authorized.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pro_se_authorized.value.unpack(bref)); break; - case 241: + } + case 241: { ueuser_plane_cio_tsupport_ind_present = true; - ueuser_plane_cio_tsupport_ind.id = c.id; - ueuser_plane_cio_tsupport_ind.crit = c.crit; - ueuser_plane_cio_tsupport_ind.value = c.value.ueuser_plane_cio_tsupport_ind(); + ueuser_plane_cio_tsupport_ind.id = id; + HANDLE_CODE(ueuser_plane_cio_tsupport_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ueuser_plane_cio_tsupport_ind.value.unpack(bref)); break; - case 240: + } + case 240: { v2xservices_authorized_present = true; - v2xservices_authorized.id = c.id; - v2xservices_authorized.crit = c.crit; - v2xservices_authorized.value = c.value.v2xservices_authorized(); + v2xservices_authorized.id = id; + HANDLE_CODE(v2xservices_authorized.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(v2xservices_authorized.value.unpack(bref)); break; - case 248: + } + case 248: { ue_sidelink_aggregate_maximum_bitrate_present = true; - ue_sidelink_aggregate_maximum_bitrate.id = c.id; - ue_sidelink_aggregate_maximum_bitrate.crit = c.crit; - ue_sidelink_aggregate_maximum_bitrate.value = c.value.ue_sidelink_aggregate_maximum_bitrate(); + ue_sidelink_aggregate_maximum_bitrate.id = id; + HANDLE_CODE(ue_sidelink_aggregate_maximum_bitrate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_sidelink_aggregate_maximum_bitrate.value.unpack(bref)); break; - case 251: + } + case 251: { enhanced_coverage_restricted_present = true; - enhanced_coverage_restricted.id = c.id; - enhanced_coverage_restricted.crit = c.crit; - enhanced_coverage_restricted.value = c.value.enhanced_coverage_restricted(); + enhanced_coverage_restricted.id = id; + HANDLE_CODE(enhanced_coverage_restricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enhanced_coverage_restricted.value.unpack(bref)); break; - case 269: + } + case 269: { nrue_security_cap_present = true; - nrue_security_cap.id = c.id; - nrue_security_cap.crit = c.crit; - nrue_security_cap.value = c.value.nrue_security_cap(); + nrue_security_cap.id = id; + HANDLE_CODE(nrue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrue_security_cap.value.unpack(bref)); break; - case 271: + } + case 271: { ce_mode_brestricted_present = true; - ce_mode_brestricted.id = c.id; - ce_mode_brestricted.crit = c.crit; - ce_mode_brestricted.value = c.value.ce_mode_brestricted(); + ce_mode_brestricted.id = id; + HANDLE_CODE(ce_mode_brestricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ce_mode_brestricted.value.unpack(bref)); break; - case 277: + } + case 277: { aerial_uesubscription_info_present = true; - aerial_uesubscription_info.id = c.id; - aerial_uesubscription_info.crit = c.crit; - aerial_uesubscription_info.value = c.value.aerial_uesubscription_info(); + aerial_uesubscription_info.id = id; + HANDLE_CODE(aerial_uesubscription_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(aerial_uesubscription_info.value.unpack(bref)); break; - case 283: + } + case 283: { pending_data_ind_present = true; - pending_data_ind.id = c.id; - pending_data_ind.crit = c.crit; - pending_data_ind.value = c.value.pending_data_ind(); + pending_data_ind.id = id; + HANDLE_CODE(pending_data_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pending_data_ind.value.unpack(bref)); break; - case 278: + } + case 278: { subscription_based_ue_differentiation_info_present = true; - subscription_based_ue_differentiation_info.id = c.id; - subscription_based_ue_differentiation_info.crit = c.crit; - subscription_based_ue_differentiation_info.value = c.value.subscription_based_ue_differentiation_info(); + subscription_based_ue_differentiation_info.id = id; + HANDLE_CODE(subscription_based_ue_differentiation_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(subscription_based_ue_differentiation_info.value.unpack(bref)); break; - case 299: + } + case 299: { add_rrm_prio_idx_present = true; - add_rrm_prio_idx.id = c.id; - add_rrm_prio_idx.crit = c.crit; - add_rrm_prio_idx.value = c.value.add_rrm_prio_idx(); + add_rrm_prio_idx.id = id; + HANDLE_CODE(add_rrm_prio_idx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(add_rrm_prio_idx.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -35986,29 +35499,6 @@ void init_context_setup_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// InitialContextSetupRequest ::= SEQUENCE -SRSASN_CODE init_context_setup_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE init_context_setup_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void init_context_setup_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // InitialContextSetupResponseIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t init_context_setup_resp_ies_o::idx_to_id(uint32_t idx) { @@ -36327,7 +35817,7 @@ const char* init_context_setup_resp_ies_o::value_c::types_opts::to_string() cons return convert_enum_idx(options, 5, value, "init_context_setup_resp_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; init_context_setup_resp_ies_container::init_context_setup_resp_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -36363,41 +35853,51 @@ SRSASN_CODE init_context_setup_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 51: + } + case 51: { nof_mandatory_ies--; - erab_setup_list_ctxt_su_res.id = c.id; - erab_setup_list_ctxt_su_res.crit = c.crit; - erab_setup_list_ctxt_su_res.value = c.value.erab_setup_list_ctxt_su_res(); + erab_setup_list_ctxt_su_res.id = id; + HANDLE_CODE(erab_setup_list_ctxt_su_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_setup_list_ctxt_su_res.value.unpack(bref)); break; - case 48: + } + case 48: { erab_failed_to_setup_list_ctxt_su_res_present = true; - erab_failed_to_setup_list_ctxt_su_res.id = c.id; - erab_failed_to_setup_list_ctxt_su_res.crit = c.crit; - erab_failed_to_setup_list_ctxt_su_res.value = c.value.erab_failed_to_setup_list_ctxt_su_res(); + erab_failed_to_setup_list_ctxt_su_res.id = id; + HANDLE_CODE(erab_failed_to_setup_list_ctxt_su_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_failed_to_setup_list_ctxt_su_res.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -36428,29 +35928,6 @@ void init_context_setup_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// InitialContextSetupResponse ::= SEQUENCE -SRSASN_CODE init_context_setup_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE init_context_setup_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void init_context_setup_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // Coverage-Level ::= ENUMERATED const char* coverage_level_opts::to_string() const { @@ -37447,7 +36924,7 @@ const char* init_ue_msg_ies_o::value_c::types_opts::to_string() const return convert_enum_idx(options, 22, value, "init_ue_msg_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; init_ue_msg_ies_container::init_ue_msg_ies_container() : enb_ue_s1ap_id(8, crit_e::reject), @@ -37562,143 +37039,187 @@ SRSASN_CODE init_ue_msg_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 5; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 8: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 26: + } + case 26: { nof_mandatory_ies--; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; - case 67: + } + case 67: { nof_mandatory_ies--; - tai.id = c.id; - tai.crit = c.crit; - tai.value = c.value.tai(); + tai.id = id; + HANDLE_CODE(tai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tai.value.unpack(bref)); break; - case 100: + } + case 100: { nof_mandatory_ies--; - eutran_cgi.id = c.id; - eutran_cgi.crit = c.crit; - eutran_cgi.value = c.value.eutran_cgi(); + eutran_cgi.id = id; + HANDLE_CODE(eutran_cgi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(eutran_cgi.value.unpack(bref)); break; - case 134: + } + case 134: { nof_mandatory_ies--; - rrc_establishment_cause.id = c.id; - rrc_establishment_cause.crit = c.crit; - rrc_establishment_cause.value = c.value.rrc_establishment_cause(); + rrc_establishment_cause.id = id; + HANDLE_CODE(rrc_establishment_cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(rrc_establishment_cause.value.unpack(bref)); break; - case 96: + } + case 96: { s_tmsi_present = true; - s_tmsi.id = c.id; - s_tmsi.crit = c.crit; - s_tmsi.value = c.value.s_tmsi(); + s_tmsi.id = id; + HANDLE_CODE(s_tmsi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(s_tmsi.value.unpack(bref)); break; - case 127: + } + case 127: { csg_id_present = true; - csg_id.id = c.id; - csg_id.crit = c.crit; - csg_id.value = c.value.csg_id(); + csg_id.id = id; + HANDLE_CODE(csg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_id.value.unpack(bref)); break; - case 75: + } + case 75: { gummei_id_present = true; - gummei_id.id = c.id; - gummei_id.crit = c.crit; - gummei_id.value = c.value.gummei_id(); + gummei_id.id = id; + HANDLE_CODE(gummei_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(gummei_id.value.unpack(bref)); break; - case 145: + } + case 145: { cell_access_mode_present = true; - cell_access_mode.id = c.id; - cell_access_mode.crit = c.crit; - cell_access_mode.value = c.value.cell_access_mode(); + cell_access_mode.id = id; + HANDLE_CODE(cell_access_mode.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cell_access_mode.value.unpack(bref)); break; - case 155: + } + case 155: { gw_transport_layer_address_present = true; - gw_transport_layer_address.id = c.id; - gw_transport_layer_address.crit = c.crit; - gw_transport_layer_address.value = c.value.gw_transport_layer_address(); + gw_transport_layer_address.id = id; + HANDLE_CODE(gw_transport_layer_address.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(gw_transport_layer_address.value.unpack(bref)); break; - case 160: + } + case 160: { relay_node_ind_present = true; - relay_node_ind.id = c.id; - relay_node_ind.crit = c.crit; - relay_node_ind.value = c.value.relay_node_ind(); + relay_node_ind.id = id; + HANDLE_CODE(relay_node_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(relay_node_ind.value.unpack(bref)); break; - case 170: + } + case 170: { gummei_type_present = true; - gummei_type.id = c.id; - gummei_type.crit = c.crit; - gummei_type.value = c.value.gummei_type(); + gummei_type.id = id; + HANDLE_CODE(gummei_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(gummei_type.value.unpack(bref)); break; - case 176: + } + case 176: { tunnel_info_for_bbf_present = true; - tunnel_info_for_bbf.id = c.id; - tunnel_info_for_bbf.crit = c.crit; - tunnel_info_for_bbf.value = c.value.tunnel_info_for_bbf(); + tunnel_info_for_bbf.id = id; + HANDLE_CODE(tunnel_info_for_bbf.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tunnel_info_for_bbf.value.unpack(bref)); break; - case 184: + } + case 184: { sipto_l_gw_transport_layer_address_present = true; - sipto_l_gw_transport_layer_address.id = c.id; - sipto_l_gw_transport_layer_address.crit = c.crit; - sipto_l_gw_transport_layer_address.value = c.value.sipto_l_gw_transport_layer_address(); + sipto_l_gw_transport_layer_address.id = id; + HANDLE_CODE(sipto_l_gw_transport_layer_address.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(sipto_l_gw_transport_layer_address.value.unpack(bref)); break; - case 186: + } + case 186: { lhn_id_present = true; - lhn_id.id = c.id; - lhn_id.crit = c.crit; - lhn_id.value = c.value.lhn_id(); + lhn_id.id = id; + HANDLE_CODE(lhn_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(lhn_id.value.unpack(bref)); break; - case 223: + } + case 223: { mme_group_id_present = true; - mme_group_id.id = c.id; - mme_group_id.crit = c.crit; - mme_group_id.value = c.value.mme_group_id(); + mme_group_id.id = id; + HANDLE_CODE(mme_group_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_group_id.value.unpack(bref)); break; - case 230: + } + case 230: { ue_usage_type_present = true; - ue_usage_type.id = c.id; - ue_usage_type.crit = c.crit; - ue_usage_type.value = c.value.ue_usage_type(); + ue_usage_type.id = id; + HANDLE_CODE(ue_usage_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_usage_type.value.unpack(bref)); break; - case 242: + } + case 242: { ce_mode_b_support_ind_present = true; - ce_mode_b_support_ind.id = c.id; - ce_mode_b_support_ind.crit = c.crit; - ce_mode_b_support_ind.value = c.value.ce_mode_b_support_ind(); + ce_mode_b_support_ind.id = id; + HANDLE_CODE(ce_mode_b_support_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ce_mode_b_support_ind.value.unpack(bref)); break; - case 246: + } + case 246: { dcn_id_present = true; - dcn_id.id = c.id; - dcn_id.crit = c.crit; - dcn_id.value = c.value.dcn_id(); + dcn_id.id = id; + HANDLE_CODE(dcn_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(dcn_id.value.unpack(bref)); break; - case 250: + } + case 250: { coverage_level_present = true; - coverage_level.id = c.id; - coverage_level.crit = c.crit; - coverage_level.value = c.value.coverage_level(); + coverage_level.id = id; + HANDLE_CODE(coverage_level.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(coverage_level.value.unpack(bref)); break; - case 263: + } + case 263: { ue_application_layer_meas_cap_present = true; - ue_application_layer_meas_cap.id = c.id; - ue_application_layer_meas_cap.crit = c.crit; - ue_application_layer_meas_cap.value = c.value.ue_application_layer_meas_cap(); + ue_application_layer_meas_cap.id = id; + HANDLE_CODE(ue_application_layer_meas_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_application_layer_meas_cap.value.unpack(bref)); break; - case 281: + } + case 281: { edt_session_present = true; - edt_session.id = c.id; - edt_session.crit = c.crit; - edt_session.value = c.value.edt_session(); + edt_session.id = id; + HANDLE_CODE(edt_session.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(edt_session.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -37793,37 +37314,6 @@ void init_ue_msg_ies_container::to_json(json_writer& j) const j.end_obj(); } -// InitialUEMessage ::= SEQUENCE -SRSASN_CODE init_ue_msg_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - bref.align_bytes_zero(); - - return SRSASN_SUCCESS; -} -SRSASN_CODE init_ue_msg_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - bref.align_bytes(); - - return SRSASN_SUCCESS; -} -void init_ue_msg_s::to_json(json_writer& j) const -{ - j.start_array(); - j.start_obj(); - j.start_obj("InitialUEMessage"); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); - j.end_obj(); - j.end_array(); -} - // UE-associatedLogicalS1-ConnectionItem ::= SEQUENCE SRSASN_CODE ue_associated_lc_s1_conn_item_s::pack(bit_ref& bref) const { @@ -38382,7 +37872,7 @@ uint8_t ue_associated_lc_s1_conn_item_res_ack_o::value_c::types_opts::to_number( return map_enum_number(options, 1, value, "ue_associated_lc_s1_conn_item_res_ack_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // CNDomain ::= ENUMERATED const char* cn_domain_opts::to_string() const @@ -38719,7 +38209,7 @@ const char* srvcc_operation_not_possible_opts::to_string() const return convert_enum_idx(options, 1, value, "srvcc_operation_not_possible_e"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // UE-RetentionInformation ::= ENUMERATED const char* ue_retention_info_opts::to_string() const @@ -38859,7 +38349,7 @@ const char* ue_s1ap_ids_c::types_opts::to_string() const return convert_enum_idx(options, 2, value, "ue_s1ap_ids_c::types"); } -template struct asn1::s1ap::protocol_ie_single_container_s; +template struct asn1::protocol_ie_single_container_s; // UEPagingID ::= CHOICE void ue_paging_id_c::destroy_() @@ -56080,7 +55570,7 @@ const char* write_replace_warning_resp_ies_o::value_c::types_opts::to_string() c return convert_enum_idx(options, 4, value, "write_replace_warning_resp_ies_o::value_c::types"); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; kill_request_ies_container::kill_request_ies_container() : msg_id(111, crit_e::reject), @@ -56114,35 +55604,43 @@ SRSASN_CODE kill_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 111: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 111: { nof_mandatory_ies--; - msg_id.id = c.id; - msg_id.crit = c.crit; - msg_id.value = c.value.msg_id(); + msg_id.id = id; + HANDLE_CODE(msg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(msg_id.value.unpack(bref)); break; - case 112: + } + case 112: { nof_mandatory_ies--; - serial_num.id = c.id; - serial_num.crit = c.crit; - serial_num.value = c.value.serial_num(); + serial_num.id = id; + HANDLE_CODE(serial_num.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(serial_num.value.unpack(bref)); break; - case 113: + } + case 113: { warning_area_list_present = true; - warning_area_list.id = c.id; - warning_area_list.crit = c.crit; - warning_area_list.value = c.value.warning_area_list(); + warning_area_list.id = id; + HANDLE_CODE(warning_area_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_area_list.value.unpack(bref)); break; - case 191: + } + case 191: { kill_all_warning_msgs_present = true; - kill_all_warning_msgs.id = c.id; - kill_all_warning_msgs.crit = c.crit; - kill_all_warning_msgs.value = c.value.kill_all_warning_msgs(); + kill_all_warning_msgs.id = id; + HANDLE_CODE(kill_all_warning_msgs.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(kill_all_warning_msgs.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -56171,30 +55669,7 @@ void kill_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// KillRequest ::= SEQUENCE -SRSASN_CODE kill_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE kill_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void kill_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; kill_resp_ies_container::kill_resp_ies_container() : msg_id(111, crit_e::reject), @@ -56228,35 +55703,43 @@ SRSASN_CODE kill_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 111: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 111: { nof_mandatory_ies--; - msg_id.id = c.id; - msg_id.crit = c.crit; - msg_id.value = c.value.msg_id(); + msg_id.id = id; + HANDLE_CODE(msg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(msg_id.value.unpack(bref)); break; - case 112: + } + case 112: { nof_mandatory_ies--; - serial_num.id = c.id; - serial_num.crit = c.crit; - serial_num.value = c.value.serial_num(); + serial_num.id = id; + HANDLE_CODE(serial_num.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(serial_num.value.unpack(bref)); break; - case 141: + } + case 141: { broadcast_cancelled_area_list_present = true; - broadcast_cancelled_area_list.id = c.id; - broadcast_cancelled_area_list.crit = c.crit; - broadcast_cancelled_area_list.value = c.value.broadcast_cancelled_area_list(); + broadcast_cancelled_area_list.id = id; + HANDLE_CODE(broadcast_cancelled_area_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(broadcast_cancelled_area_list.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -56285,30 +55768,7 @@ void kill_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// KillResponse ::= SEQUENCE -SRSASN_CODE kill_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE kill_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void kill_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; location_report_ies_container::location_report_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -56343,47 +55803,59 @@ SRSASN_CODE location_report_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 5; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 100: + } + case 100: { nof_mandatory_ies--; - eutran_cgi.id = c.id; - eutran_cgi.crit = c.crit; - eutran_cgi.value = c.value.eutran_cgi(); + eutran_cgi.id = id; + HANDLE_CODE(eutran_cgi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(eutran_cgi.value.unpack(bref)); break; - case 67: + } + case 67: { nof_mandatory_ies--; - tai.id = c.id; - tai.crit = c.crit; - tai.value = c.value.tai(); + tai.id = id; + HANDLE_CODE(tai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tai.value.unpack(bref)); break; - case 98: + } + case 98: { nof_mandatory_ies--; - request_type.id = c.id; - request_type.crit = c.crit; - request_type.value = c.value.request_type(); + request_type.id = id; + HANDLE_CODE(request_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(request_type.value.unpack(bref)); break; - case 288: + } + case 288: { ps_cell_info_present = true; - ps_cell_info.id = c.id; - ps_cell_info.crit = c.crit; - ps_cell_info.value = c.value.ps_cell_info(); + ps_cell_info.id = id; + HANDLE_CODE(ps_cell_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ps_cell_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -56414,30 +55886,7 @@ void location_report_ies_container::to_json(json_writer& j) const j.end_obj(); } -// LocationReport ::= SEQUENCE -SRSASN_CODE location_report_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE location_report_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void location_report_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; location_report_ctrl_ies_container::location_report_ctrl_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), enb_ue_s1ap_id(8, crit_e::reject), request_type(98, crit_e::ignore) @@ -56461,29 +55910,35 @@ SRSASN_CODE location_report_ctrl_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 98: + } + case 98: { nof_mandatory_ies--; - request_type.id = c.id; - request_type.crit = c.crit; - request_type.value = c.value.request_type(); + request_type.id = id; + HANDLE_CODE(request_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(request_type.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -56506,30 +55961,7 @@ void location_report_ctrl_ies_container::to_json(json_writer& j) const j.end_obj(); } -// LocationReportingControl ::= SEQUENCE -SRSASN_CODE location_report_ctrl_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE location_report_ctrl_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void location_report_ctrl_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; location_report_fail_ind_ies_container::location_report_fail_ind_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), enb_ue_s1ap_id(8, crit_e::reject), cause(2, crit_e::ignore) @@ -56553,29 +55985,35 @@ SRSASN_CODE location_report_fail_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -56598,30 +56036,7 @@ void location_report_fail_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// LocationReportingFailureIndication ::= SEQUENCE -SRSASN_CODE location_report_fail_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE location_report_fail_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void location_report_fail_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; mmecp_relocation_ind_ies_container::mmecp_relocation_ind_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), enb_ue_s1ap_id(8, crit_e::reject) @@ -56644,23 +56059,27 @@ SRSASN_CODE mmecp_relocation_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -56681,30 +56100,7 @@ void mmecp_relocation_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// MMECPRelocationIndication ::= SEQUENCE -SRSASN_CODE mmecp_relocation_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE mmecp_relocation_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void mmecp_relocation_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; mme_cfg_transfer_ies_container::mme_cfg_transfer_ies_container() : son_cfg_transfer_mct(130, crit_e::ignore), en_dcson_cfg_transfer_mct(295, crit_e::ignore) @@ -56731,23 +56127,27 @@ SRSASN_CODE mme_cfg_transfer_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 130: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 130: { son_cfg_transfer_mct_present = true; - son_cfg_transfer_mct.id = c.id; - son_cfg_transfer_mct.crit = c.crit; - son_cfg_transfer_mct.value = c.value.son_cfg_transfer_mct(); + son_cfg_transfer_mct.id = id; + HANDLE_CODE(son_cfg_transfer_mct.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(son_cfg_transfer_mct.value.unpack(bref)); break; - case 295: + } + case 295: { en_dcson_cfg_transfer_mct_present = true; - en_dcson_cfg_transfer_mct.id = c.id; - en_dcson_cfg_transfer_mct.crit = c.crit; - en_dcson_cfg_transfer_mct.value = c.value.en_dcson_cfg_transfer_mct(); + en_dcson_cfg_transfer_mct.id = id; + HANDLE_CODE(en_dcson_cfg_transfer_mct.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(en_dcson_cfg_transfer_mct.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -56768,30 +56168,7 @@ void mme_cfg_transfer_ies_container::to_json(json_writer& j) const j.end_obj(); } -// MMEConfigurationTransfer ::= SEQUENCE -SRSASN_CODE mme_cfg_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE mme_cfg_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void mme_cfg_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; mme_cfg_upd_ies_container::mme_cfg_upd_ies_container() : mm_ename(61, crit_e::ignore), @@ -56829,35 +56206,43 @@ SRSASN_CODE mme_cfg_upd_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 61: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 61: { mm_ename_present = true; - mm_ename.id = c.id; - mm_ename.crit = c.crit; - mm_ename.value = c.value.mm_ename(); + mm_ename.id = id; + HANDLE_CODE(mm_ename.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mm_ename.value.unpack(bref)); break; - case 105: + } + case 105: { served_gummeis_present = true; - served_gummeis.id = c.id; - served_gummeis.crit = c.crit; - served_gummeis.value = c.value.served_gummeis(); + served_gummeis.id = id; + HANDLE_CODE(served_gummeis.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(served_gummeis.value.unpack(bref)); break; - case 87: + } + case 87: { relative_mme_capacity_present = true; - relative_mme_capacity.id = c.id; - relative_mme_capacity.crit = c.crit; - relative_mme_capacity.value = c.value.relative_mme_capacity(); + relative_mme_capacity.id = id; + HANDLE_CODE(relative_mme_capacity.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(relative_mme_capacity.value.unpack(bref)); break; - case 247: + } + case 247: { served_dcns_present = true; - served_dcns.id = c.id; - served_dcns.crit = c.crit; - served_dcns.value = c.value.served_dcns(); + served_dcns.id = id; + HANDLE_CODE(served_dcns.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(served_dcns.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -56886,52 +56271,7 @@ void mme_cfg_upd_ies_container::to_json(json_writer& j) const j.end_obj(); } -// MMEConfigurationUpdate ::= SEQUENCE -SRSASN_CODE mme_cfg_upd_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE mme_cfg_upd_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void mme_cfg_upd_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -// MMEConfigurationUpdateAcknowledge ::= SEQUENCE -SRSASN_CODE mme_cfg_upd_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(pack_dyn_seq_of(bref, protocol_ies, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE mme_cfg_upd_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(unpack_dyn_seq_of(protocol_ies, bref, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -void mme_cfg_upd_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; mme_cfg_upd_fail_ies_container::mme_cfg_upd_fail_ies_container() : cause(2, crit_e::ignore), time_to_wait(65, crit_e::ignore), crit_diagnostics(58, crit_e::ignore) @@ -56961,29 +56301,35 @@ SRSASN_CODE mme_cfg_upd_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 1; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 2: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 65: + } + case 65: { time_to_wait_present = true; - time_to_wait.id = c.id; - time_to_wait.crit = c.crit; - time_to_wait.value = c.value.time_to_wait(); + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -57010,52 +56356,7 @@ void mme_cfg_upd_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// MMEConfigurationUpdateFailure ::= SEQUENCE -SRSASN_CODE mme_cfg_upd_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE mme_cfg_upd_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void mme_cfg_upd_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -// MMEDirectInformationTransfer ::= SEQUENCE -SRSASN_CODE mme_direct_info_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(pack_dyn_seq_of(bref, protocol_ies, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE mme_direct_info_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(unpack_dyn_seq_of(protocol_ies, bref, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -void mme_direct_info_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; mme_status_transfer_ies_container::mme_status_transfer_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -57081,29 +56382,35 @@ SRSASN_CODE mme_status_transfer_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 90: + } + case 90: { nof_mandatory_ies--; - enb_status_transfer_transparent_container.id = c.id; - enb_status_transfer_transparent_container.crit = c.crit; - enb_status_transfer_transparent_container.value = c.value.enb_status_transfer_transparent_container(); + enb_status_transfer_transparent_container.id = id; + HANDLE_CODE(enb_status_transfer_transparent_container.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_status_transfer_transparent_container.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -57126,30 +56433,7 @@ void mme_status_transfer_ies_container::to_json(json_writer& j) const j.end_obj(); } -// MMEStatusTransfer ::= SEQUENCE -SRSASN_CODE mme_status_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE mme_status_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void mme_status_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; nas_delivery_ind_ies_container::nas_delivery_ind_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), enb_ue_s1ap_id(8, crit_e::reject) @@ -57172,23 +56456,27 @@ SRSASN_CODE nas_delivery_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -57209,30 +56497,7 @@ void nas_delivery_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// NASDeliveryIndication ::= SEQUENCE -SRSASN_CODE nas_delivery_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE nas_delivery_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void nas_delivery_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; nas_non_delivery_ind_ies_container::nas_non_delivery_ind_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -57260,35 +56525,43 @@ SRSASN_CODE nas_non_delivery_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 26: + } + case 26: { nof_mandatory_ies--; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -57313,30 +56586,7 @@ void nas_non_delivery_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// NASNonDeliveryIndication ::= SEQUENCE -SRSASN_CODE nas_non_delivery_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE nas_non_delivery_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void nas_non_delivery_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; overload_start_ies_container::overload_start_ies_container() : overload_resp(101, crit_e::reject), gummei_list(154, crit_e::ignore), traffic_load_reduction_ind(161, crit_e::ignore) @@ -57366,29 +56616,35 @@ SRSASN_CODE overload_start_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 1; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 101: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 101: { nof_mandatory_ies--; - overload_resp.id = c.id; - overload_resp.crit = c.crit; - overload_resp.value = c.value.overload_resp(); + overload_resp.id = id; + HANDLE_CODE(overload_resp.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(overload_resp.value.unpack(bref)); break; - case 154: + } + case 154: { gummei_list_present = true; - gummei_list.id = c.id; - gummei_list.crit = c.crit; - gummei_list.value = c.value.gummei_list(); + gummei_list.id = id; + HANDLE_CODE(gummei_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(gummei_list.value.unpack(bref)); break; - case 161: + } + case 161: { traffic_load_reduction_ind_present = true; - traffic_load_reduction_ind.id = c.id; - traffic_load_reduction_ind.crit = c.crit; - traffic_load_reduction_ind.value = c.value.traffic_load_reduction_ind(); + traffic_load_reduction_ind.id = id; + HANDLE_CODE(traffic_load_reduction_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(traffic_load_reduction_ind.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -57415,52 +56671,7 @@ void overload_start_ies_container::to_json(json_writer& j) const j.end_obj(); } -// OverloadStart ::= SEQUENCE -SRSASN_CODE overload_start_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE overload_start_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void overload_start_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -// OverloadStop ::= SEQUENCE -SRSASN_CODE overload_stop_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(pack_dyn_seq_of(bref, protocol_ies, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE overload_stop_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(unpack_dyn_seq_of(protocol_ies, bref, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -void overload_stop_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pws_fail_ind_ies_container::pws_fail_ind_ies_container() : pw_sfailed_ecgi_list(222, crit_e::reject), global_enb_id(59, crit_e::reject) @@ -57483,23 +56694,27 @@ SRSASN_CODE pws_fail_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 222: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 222: { nof_mandatory_ies--; - pw_sfailed_ecgi_list.id = c.id; - pw_sfailed_ecgi_list.crit = c.crit; - pw_sfailed_ecgi_list.value = c.value.pw_sfailed_ecgi_list(); + pw_sfailed_ecgi_list.id = id; + HANDLE_CODE(pw_sfailed_ecgi_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pw_sfailed_ecgi_list.value.unpack(bref)); break; - case 59: + } + case 59: { nof_mandatory_ies--; - global_enb_id.id = c.id; - global_enb_id.crit = c.crit; - global_enb_id.value = c.value.global_enb_id(); + global_enb_id.id = id; + HANDLE_CODE(global_enb_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_enb_id.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -57520,30 +56735,7 @@ void pws_fail_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PWSFailureIndication ::= SEQUENCE -SRSASN_CODE pws_fail_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pws_fail_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pws_fail_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; pws_restart_ind_ies_container::pws_restart_ind_ies_container() : ecgi_list_for_restart(182, crit_e::reject), @@ -57574,35 +56766,43 @@ SRSASN_CODE pws_restart_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 182: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 182: { nof_mandatory_ies--; - ecgi_list_for_restart.id = c.id; - ecgi_list_for_restart.crit = c.crit; - ecgi_list_for_restart.value = c.value.ecgi_list_for_restart(); + ecgi_list_for_restart.id = id; + HANDLE_CODE(ecgi_list_for_restart.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ecgi_list_for_restart.value.unpack(bref)); break; - case 59: + } + case 59: { nof_mandatory_ies--; - global_enb_id.id = c.id; - global_enb_id.crit = c.crit; - global_enb_id.value = c.value.global_enb_id(); + global_enb_id.id = id; + HANDLE_CODE(global_enb_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_enb_id.value.unpack(bref)); break; - case 188: + } + case 188: { nof_mandatory_ies--; - tai_list_for_restart.id = c.id; - tai_list_for_restart.crit = c.crit; - tai_list_for_restart.value = c.value.tai_list_for_restart(); + tai_list_for_restart.id = id; + HANDLE_CODE(tai_list_for_restart.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tai_list_for_restart.value.unpack(bref)); break; - case 190: + } + case 190: { emergency_area_id_list_for_restart_present = true; - emergency_area_id_list_for_restart.id = c.id; - emergency_area_id_list_for_restart.crit = c.crit; - emergency_area_id_list_for_restart.value = c.value.emergency_area_id_list_for_restart(); + emergency_area_id_list_for_restart.id = id; + HANDLE_CODE(emergency_area_id_list_for_restart.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(emergency_area_id_list_for_restart.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -57629,30 +56829,7 @@ void pws_restart_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PWSRestartIndication ::= SEQUENCE -SRSASN_CODE pws_restart_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE pws_restart_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void pws_restart_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; paging_ies_container::paging_ies_container() : ue_id_idx_value(80, crit_e::ignore), @@ -57735,101 +56912,131 @@ SRSASN_CODE paging_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 80: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 80: { nof_mandatory_ies--; - ue_id_idx_value.id = c.id; - ue_id_idx_value.crit = c.crit; - ue_id_idx_value.value = c.value.ue_id_idx_value(); + ue_id_idx_value.id = id; + HANDLE_CODE(ue_id_idx_value.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_id_idx_value.value.unpack(bref)); break; - case 43: + } + case 43: { nof_mandatory_ies--; - ue_paging_id.id = c.id; - ue_paging_id.crit = c.crit; - ue_paging_id.value = c.value.ue_paging_id(); + ue_paging_id.id = id; + HANDLE_CODE(ue_paging_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_paging_id.value.unpack(bref)); break; - case 44: + } + case 44: { paging_drx_present = true; - paging_drx.id = c.id; - paging_drx.crit = c.crit; - paging_drx.value = c.value.paging_drx(); + paging_drx.id = id; + HANDLE_CODE(paging_drx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(paging_drx.value.unpack(bref)); break; - case 109: + } + case 109: { nof_mandatory_ies--; - cn_domain.id = c.id; - cn_domain.crit = c.crit; - cn_domain.value = c.value.cn_domain(); + cn_domain.id = id; + HANDLE_CODE(cn_domain.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cn_domain.value.unpack(bref)); break; - case 46: + } + case 46: { nof_mandatory_ies--; - tai_list.id = c.id; - tai_list.crit = c.crit; - tai_list.value = c.value.tai_list(); + tai_list.id = id; + HANDLE_CODE(tai_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tai_list.value.unpack(bref)); break; - case 128: + } + case 128: { csg_id_list_present = true; - csg_id_list.id = c.id; - csg_id_list.crit = c.crit; - csg_id_list.value = c.value.csg_id_list(); + csg_id_list.id = id; + HANDLE_CODE(csg_id_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_id_list.value.unpack(bref)); break; - case 151: + } + case 151: { paging_prio_present = true; - paging_prio.id = c.id; - paging_prio.crit = c.crit; - paging_prio.value = c.value.paging_prio(); + paging_prio.id = id; + HANDLE_CODE(paging_prio.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(paging_prio.value.unpack(bref)); break; - case 198: + } + case 198: { ue_radio_cap_for_paging_present = true; - ue_radio_cap_for_paging.id = c.id; - ue_radio_cap_for_paging.crit = c.crit; - ue_radio_cap_for_paging.value = c.value.ue_radio_cap_for_paging(); + ue_radio_cap_for_paging.id = id; + HANDLE_CODE(ue_radio_cap_for_paging.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap_for_paging.value.unpack(bref)); break; - case 211: + } + case 211: { assist_data_for_paging_present = true; - assist_data_for_paging.id = c.id; - assist_data_for_paging.crit = c.crit; - assist_data_for_paging.value = c.value.assist_data_for_paging(); + assist_data_for_paging.id = id; + HANDLE_CODE(assist_data_for_paging.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(assist_data_for_paging.value.unpack(bref)); break; - case 227: + } + case 227: { paging_e_drx_info_present = true; - paging_e_drx_info.id = c.id; - paging_e_drx_info.crit = c.crit; - paging_e_drx_info.value = c.value.paging_e_drx_info(); + paging_e_drx_info.id = id; + HANDLE_CODE(paging_e_drx_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(paging_e_drx_info.value.unpack(bref)); break; - case 231: + } + case 231: { extended_ue_id_idx_value_present = true; - extended_ue_id_idx_value.id = c.id; - extended_ue_id_idx_value.crit = c.crit; - extended_ue_id_idx_value.value = c.value.extended_ue_id_idx_value(); + extended_ue_id_idx_value.id = id; + HANDLE_CODE(extended_ue_id_idx_value.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(extended_ue_id_idx_value.value.unpack(bref)); break; - case 239: + } + case 239: { nb_io_t_paging_e_drx_info_present = true; - nb_io_t_paging_e_drx_info.id = c.id; - nb_io_t_paging_e_drx_info.crit = c.crit; - nb_io_t_paging_e_drx_info.value = c.value.nb_io_t_paging_e_drx_info(); + nb_io_t_paging_e_drx_info.id = id; + HANDLE_CODE(nb_io_t_paging_e_drx_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nb_io_t_paging_e_drx_info.value.unpack(bref)); break; - case 244: + } + case 244: { nb_io_t_ue_id_idx_value_present = true; - nb_io_t_ue_id_idx_value.id = c.id; - nb_io_t_ue_id_idx_value.crit = c.crit; - nb_io_t_ue_id_idx_value.value = c.value.nb_io_t_ue_id_idx_value(); + nb_io_t_ue_id_idx_value.id = id; + HANDLE_CODE(nb_io_t_ue_id_idx_value.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nb_io_t_ue_id_idx_value.value.unpack(bref)); break; - case 251: + } + case 251: { enhanced_coverage_restricted_present = true; - enhanced_coverage_restricted.id = c.id; - enhanced_coverage_restricted.crit = c.crit; - enhanced_coverage_restricted.value = c.value.enhanced_coverage_restricted(); + enhanced_coverage_restricted.id = id; + HANDLE_CODE(enhanced_coverage_restricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enhanced_coverage_restricted.value.unpack(bref)); break; - case 271: + } + case 271: { ce_mode_brestricted_present = true; - ce_mode_brestricted.id = c.id; - ce_mode_brestricted.crit = c.crit; - ce_mode_brestricted.value = c.value.ce_mode_brestricted(); + ce_mode_brestricted.id = id; + HANDLE_CODE(ce_mode_brestricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ce_mode_brestricted.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -57898,30 +57105,7 @@ void paging_ies_container::to_json(json_writer& j) const j.end_obj(); } -// Paging ::= SEQUENCE -SRSASN_CODE paging_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE paging_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void paging_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; path_switch_request_ies_container::path_switch_request_ies_container() : enb_ue_s1ap_id(8, crit_e::reject), @@ -57998,101 +57182,131 @@ SRSASN_CODE path_switch_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 6; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 8: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 22: + } + case 22: { nof_mandatory_ies--; - erab_to_be_switched_dl_list.id = c.id; - erab_to_be_switched_dl_list.crit = c.crit; - erab_to_be_switched_dl_list.value = c.value.erab_to_be_switched_dl_list(); + erab_to_be_switched_dl_list.id = id; + HANDLE_CODE(erab_to_be_switched_dl_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_to_be_switched_dl_list.value.unpack(bref)); break; - case 88: + } + case 88: { nof_mandatory_ies--; - source_mme_ue_s1ap_id.id = c.id; - source_mme_ue_s1ap_id.crit = c.crit; - source_mme_ue_s1ap_id.value = c.value.source_mme_ue_s1ap_id(); + source_mme_ue_s1ap_id.id = id; + HANDLE_CODE(source_mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(source_mme_ue_s1ap_id.value.unpack(bref)); break; - case 100: + } + case 100: { nof_mandatory_ies--; - eutran_cgi.id = c.id; - eutran_cgi.crit = c.crit; - eutran_cgi.value = c.value.eutran_cgi(); + eutran_cgi.id = id; + HANDLE_CODE(eutran_cgi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(eutran_cgi.value.unpack(bref)); break; - case 67: + } + case 67: { nof_mandatory_ies--; - tai.id = c.id; - tai.crit = c.crit; - tai.value = c.value.tai(); + tai.id = id; + HANDLE_CODE(tai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tai.value.unpack(bref)); break; - case 107: + } + case 107: { nof_mandatory_ies--; - ue_security_cap.id = c.id; - ue_security_cap.crit = c.crit; - ue_security_cap.value = c.value.ue_security_cap(); + ue_security_cap.id = id; + HANDLE_CODE(ue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_security_cap.value.unpack(bref)); break; - case 127: + } + case 127: { csg_id_present = true; - csg_id.id = c.id; - csg_id.crit = c.crit; - csg_id.value = c.value.csg_id(); + csg_id.id = id; + HANDLE_CODE(csg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_id.value.unpack(bref)); break; - case 145: + } + case 145: { cell_access_mode_present = true; - cell_access_mode.id = c.id; - cell_access_mode.crit = c.crit; - cell_access_mode.value = c.value.cell_access_mode(); + cell_access_mode.id = id; + HANDLE_CODE(cell_access_mode.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cell_access_mode.value.unpack(bref)); break; - case 157: + } + case 157: { source_mme_gummei_present = true; - source_mme_gummei.id = c.id; - source_mme_gummei.crit = c.crit; - source_mme_gummei.value = c.value.source_mme_gummei(); + source_mme_gummei.id = id; + HANDLE_CODE(source_mme_gummei.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(source_mme_gummei.value.unpack(bref)); break; - case 146: + } + case 146: { csg_membership_status_present = true; - csg_membership_status.id = c.id; - csg_membership_status.crit = c.crit; - csg_membership_status.value = c.value.csg_membership_status(); + csg_membership_status.id = id; + HANDLE_CODE(csg_membership_status.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_membership_status.value.unpack(bref)); break; - case 176: + } + case 176: { tunnel_info_for_bbf_present = true; - tunnel_info_for_bbf.id = c.id; - tunnel_info_for_bbf.crit = c.crit; - tunnel_info_for_bbf.value = c.value.tunnel_info_for_bbf(); + tunnel_info_for_bbf.id = id; + HANDLE_CODE(tunnel_info_for_bbf.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tunnel_info_for_bbf.value.unpack(bref)); break; - case 186: + } + case 186: { lhn_id_present = true; - lhn_id.id = c.id; - lhn_id.crit = c.crit; - lhn_id.value = c.value.lhn_id(); + lhn_id.id = id; + HANDLE_CODE(lhn_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(lhn_id.value.unpack(bref)); break; - case 245: + } + case 245: { rrc_resume_cause_present = true; - rrc_resume_cause.id = c.id; - rrc_resume_cause.crit = c.crit; - rrc_resume_cause.value = c.value.rrc_resume_cause(); + rrc_resume_cause.id = id; + HANDLE_CODE(rrc_resume_cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(rrc_resume_cause.value.unpack(bref)); break; - case 269: + } + case 269: { nrue_security_cap_present = true; - nrue_security_cap.id = c.id; - nrue_security_cap.crit = c.crit; - nrue_security_cap.value = c.value.nrue_security_cap(); + nrue_security_cap.id = id; + HANDLE_CODE(nrue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrue_security_cap.value.unpack(bref)); break; - case 288: + } + case 288: { ps_cell_info_present = true; - ps_cell_info.id = c.id; - ps_cell_info.crit = c.crit; - ps_cell_info.value = c.value.ps_cell_info(); + ps_cell_info.id = id; + HANDLE_CODE(ps_cell_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ps_cell_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -58157,30 +57371,7 @@ void path_switch_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PathSwitchRequest ::= SEQUENCE -SRSASN_CODE path_switch_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE path_switch_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void path_switch_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; path_switch_request_ack_ies_container::path_switch_request_ack_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -58296,137 +57487,179 @@ SRSASN_CODE path_switch_request_ack_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 66: + } + case 66: { ueaggregate_maximum_bitrate_present = true; - ueaggregate_maximum_bitrate.id = c.id; - ueaggregate_maximum_bitrate.crit = c.crit; - ueaggregate_maximum_bitrate.value = c.value.ueaggregate_maximum_bitrate(); + ueaggregate_maximum_bitrate.id = id; + HANDLE_CODE(ueaggregate_maximum_bitrate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ueaggregate_maximum_bitrate.value.unpack(bref)); break; - case 95: + } + case 95: { erab_to_be_switched_ul_list_present = true; - erab_to_be_switched_ul_list.id = c.id; - erab_to_be_switched_ul_list.crit = c.crit; - erab_to_be_switched_ul_list.value = c.value.erab_to_be_switched_ul_list(); + erab_to_be_switched_ul_list.id = id; + HANDLE_CODE(erab_to_be_switched_ul_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_to_be_switched_ul_list.value.unpack(bref)); break; - case 33: + } + case 33: { erab_to_be_released_list_present = true; - erab_to_be_released_list.id = c.id; - erab_to_be_released_list.crit = c.crit; - erab_to_be_released_list.value = c.value.erab_to_be_released_list(); + erab_to_be_released_list.id = id; + HANDLE_CODE(erab_to_be_released_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_to_be_released_list.value.unpack(bref)); break; - case 40: + } + case 40: { nof_mandatory_ies--; - security_context.id = c.id; - security_context.crit = c.crit; - security_context.value = c.value.security_context(); + security_context.id = id; + HANDLE_CODE(security_context.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_context.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 158: + } + case 158: { mme_ue_s1ap_id_minus2_present = true; - mme_ue_s1ap_id_minus2.id = c.id; - mme_ue_s1ap_id_minus2.crit = c.crit; - mme_ue_s1ap_id_minus2.value = c.value.mme_ue_s1ap_id_minus2(); + mme_ue_s1ap_id_minus2.id = id; + HANDLE_CODE(mme_ue_s1ap_id_minus2.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id_minus2.value.unpack(bref)); break; - case 146: + } + case 146: { csg_membership_status_present = true; - csg_membership_status.id = c.id; - csg_membership_status.crit = c.crit; - csg_membership_status.value = c.value.csg_membership_status(); + csg_membership_status.id = id; + HANDLE_CODE(csg_membership_status.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_membership_status.value.unpack(bref)); break; - case 195: + } + case 195: { pro_se_authorized_present = true; - pro_se_authorized.id = c.id; - pro_se_authorized.crit = c.crit; - pro_se_authorized.value = c.value.pro_se_authorized(); + pro_se_authorized.id = id; + HANDLE_CODE(pro_se_authorized.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pro_se_authorized.value.unpack(bref)); break; - case 241: + } + case 241: { ueuser_plane_cio_tsupport_ind_present = true; - ueuser_plane_cio_tsupport_ind.id = c.id; - ueuser_plane_cio_tsupport_ind.crit = c.crit; - ueuser_plane_cio_tsupport_ind.value = c.value.ueuser_plane_cio_tsupport_ind(); + ueuser_plane_cio_tsupport_ind.id = id; + HANDLE_CODE(ueuser_plane_cio_tsupport_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ueuser_plane_cio_tsupport_ind.value.unpack(bref)); break; - case 240: + } + case 240: { v2xservices_authorized_present = true; - v2xservices_authorized.id = c.id; - v2xservices_authorized.crit = c.crit; - v2xservices_authorized.value = c.value.v2xservices_authorized(); + v2xservices_authorized.id = id; + HANDLE_CODE(v2xservices_authorized.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(v2xservices_authorized.value.unpack(bref)); break; - case 248: + } + case 248: { ue_sidelink_aggregate_maximum_bitrate_present = true; - ue_sidelink_aggregate_maximum_bitrate.id = c.id; - ue_sidelink_aggregate_maximum_bitrate.crit = c.crit; - ue_sidelink_aggregate_maximum_bitrate.value = c.value.ue_sidelink_aggregate_maximum_bitrate(); + ue_sidelink_aggregate_maximum_bitrate.id = id; + HANDLE_CODE(ue_sidelink_aggregate_maximum_bitrate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_sidelink_aggregate_maximum_bitrate.value.unpack(bref)); break; - case 251: + } + case 251: { enhanced_coverage_restricted_present = true; - enhanced_coverage_restricted.id = c.id; - enhanced_coverage_restricted.crit = c.crit; - enhanced_coverage_restricted.value = c.value.enhanced_coverage_restricted(); + enhanced_coverage_restricted.id = id; + HANDLE_CODE(enhanced_coverage_restricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enhanced_coverage_restricted.value.unpack(bref)); break; - case 269: + } + case 269: { nrue_security_cap_present = true; - nrue_security_cap.id = c.id; - nrue_security_cap.crit = c.crit; - nrue_security_cap.value = c.value.nrue_security_cap(); + nrue_security_cap.id = id; + HANDLE_CODE(nrue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrue_security_cap.value.unpack(bref)); break; - case 271: + } + case 271: { ce_mode_brestricted_present = true; - ce_mode_brestricted.id = c.id; - ce_mode_brestricted.crit = c.crit; - ce_mode_brestricted.value = c.value.ce_mode_brestricted(); + ce_mode_brestricted.id = id; + HANDLE_CODE(ce_mode_brestricted.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ce_mode_brestricted.value.unpack(bref)); break; - case 277: + } + case 277: { aerial_uesubscription_info_present = true; - aerial_uesubscription_info.id = c.id; - aerial_uesubscription_info.crit = c.crit; - aerial_uesubscription_info.value = c.value.aerial_uesubscription_info(); + aerial_uesubscription_info.id = id; + HANDLE_CODE(aerial_uesubscription_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(aerial_uesubscription_info.value.unpack(bref)); break; - case 283: + } + case 283: { pending_data_ind_present = true; - pending_data_ind.id = c.id; - pending_data_ind.crit = c.crit; - pending_data_ind.value = c.value.pending_data_ind(); + pending_data_ind.id = id; + HANDLE_CODE(pending_data_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pending_data_ind.value.unpack(bref)); break; - case 278: + } + case 278: { subscription_based_ue_differentiation_info_present = true; - subscription_based_ue_differentiation_info.id = c.id; - subscription_based_ue_differentiation_info.crit = c.crit; - subscription_based_ue_differentiation_info.value = c.value.subscription_based_ue_differentiation_info(); + subscription_based_ue_differentiation_info.id = id; + HANDLE_CODE(subscription_based_ue_differentiation_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(subscription_based_ue_differentiation_info.value.unpack(bref)); break; - case 41: + } + case 41: { ho_restrict_list_present = true; - ho_restrict_list.id = c.id; - ho_restrict_list.crit = c.crit; - ho_restrict_list.value = c.value.ho_restrict_list(); + ho_restrict_list.id = id; + HANDLE_CODE(ho_restrict_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ho_restrict_list.value.unpack(bref)); break; - case 299: + } + case 299: { add_rrm_prio_idx_present = true; - add_rrm_prio_idx.id = c.id; - add_rrm_prio_idx.crit = c.crit; - add_rrm_prio_idx.value = c.value.add_rrm_prio_idx(); + add_rrm_prio_idx.id = id; + HANDLE_CODE(add_rrm_prio_idx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(add_rrm_prio_idx.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -58521,30 +57754,7 @@ void path_switch_request_ack_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PathSwitchRequestAcknowledge ::= SEQUENCE -SRSASN_CODE path_switch_request_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE path_switch_request_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void path_switch_request_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; path_switch_request_fail_ies_container::path_switch_request_fail_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -58575,35 +57785,43 @@ SRSASN_CODE path_switch_request_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -58630,29 +57848,6 @@ void path_switch_request_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// PathSwitchRequestFailure ::= SEQUENCE -SRSASN_CODE path_switch_request_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE path_switch_request_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void path_switch_request_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - template private_ie_container_item_s::private_ie_container_item_s(private_ie_id_c id_, crit_e crit_) : id(id_), crit(crit_) @@ -58743,7 +57938,7 @@ void private_msg_s::to_json(json_writer& j) const j.end_array(); } -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; reroute_nas_request_ies_container::reroute_nas_request_ies_container() : enb_ue_s1ap_id(8, crit_e::reject), @@ -58784,47 +57979,59 @@ SRSASN_CODE reroute_nas_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 8: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 0: + } + case 0: { mme_ue_s1ap_id_present = true; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 225: + } + case 225: { nof_mandatory_ies--; - s1_msg.id = c.id; - s1_msg.crit = c.crit; - s1_msg.value = c.value.s1_msg(); + s1_msg.id = id; + HANDLE_CODE(s1_msg.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(s1_msg.value.unpack(bref)); break; - case 223: + } + case 223: { nof_mandatory_ies--; - mme_group_id.id = c.id; - mme_group_id.crit = c.crit; - mme_group_id.value = c.value.mme_group_id(); + mme_group_id.id = id; + HANDLE_CODE(mme_group_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_group_id.value.unpack(bref)); break; - case 224: + } + case 224: { add_guti_present = true; - add_guti.id = c.id; - add_guti.crit = c.crit; - add_guti.value = c.value.add_guti(); + add_guti.id = id; + HANDLE_CODE(add_guti.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(add_guti.value.unpack(bref)); break; - case 230: + } + case 230: { ue_usage_type_present = true; - ue_usage_type.id = c.id; - ue_usage_type.crit = c.crit; - ue_usage_type.value = c.value.ue_usage_type(); + ue_usage_type.id = id; + HANDLE_CODE(ue_usage_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_usage_type.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -58859,30 +58066,7 @@ void reroute_nas_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// RerouteNASRequest ::= SEQUENCE -SRSASN_CODE reroute_nas_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE reroute_nas_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void reroute_nas_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; reset_ies_container::reset_ies_container() : cause(2, crit_e::ignore), reset_type(92, crit_e::reject) {} SRSASN_CODE reset_ies_container::pack(bit_ref& bref) const @@ -58903,23 +58087,27 @@ SRSASN_CODE reset_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 2: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 92: + } + case 92: { nof_mandatory_ies--; - reset_type.id = c.id; - reset_type.crit = c.crit; - reset_type.value = c.value.reset_type(); + reset_type.id = id; + HANDLE_CODE(reset_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(reset_type.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -58940,30 +58128,7 @@ void reset_ies_container::to_json(json_writer& j) const j.end_obj(); } -// Reset ::= SEQUENCE -SRSASN_CODE reset_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE reset_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void reset_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; reset_ack_ies_container::reset_ack_ies_container() : ue_associated_lc_s1_conn_list_res_ack(93, crit_e::ignore), crit_diagnostics(58, crit_e::ignore) @@ -58990,23 +58155,27 @@ SRSASN_CODE reset_ack_ies_container::unpack(cbit_ref& bref) unpack_length(nof_ies, bref, 0u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 93: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 93: { ue_associated_lc_s1_conn_list_res_ack_present = true; - ue_associated_lc_s1_conn_list_res_ack.id = c.id; - ue_associated_lc_s1_conn_list_res_ack.crit = c.crit; - ue_associated_lc_s1_conn_list_res_ack.value = c.value.ue_associated_lc_s1_conn_list_res_ack(); + ue_associated_lc_s1_conn_list_res_ack.id = id; + HANDLE_CODE(ue_associated_lc_s1_conn_list_res_ack.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_associated_lc_s1_conn_list_res_ack.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -59027,52 +58196,7 @@ void reset_ack_ies_container::to_json(json_writer& j) const j.end_obj(); } -// ResetAcknowledge ::= SEQUENCE -SRSASN_CODE reset_ack_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE reset_ack_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void reset_ack_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -// RetrieveUEInformation ::= SEQUENCE -SRSASN_CODE retrieve_ue_info_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(pack_dyn_seq_of(bref, protocol_ies, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE retrieve_ue_info_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(unpack_dyn_seq_of(protocol_ies, bref, 0, 65535, true)); - - return SRSASN_SUCCESS; -} -void retrieve_ue_info_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; s1_setup_fail_ies_container::s1_setup_fail_ies_container() : cause(2, crit_e::ignore), time_to_wait(65, crit_e::ignore), crit_diagnostics(58, crit_e::ignore) @@ -59102,29 +58226,35 @@ SRSASN_CODE s1_setup_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 1; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 2: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 65: + } + case 65: { time_to_wait_present = true; - time_to_wait.id = c.id; - time_to_wait.crit = c.crit; - time_to_wait.value = c.value.time_to_wait(); + time_to_wait.id = id; + HANDLE_CODE(time_to_wait.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_to_wait.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -59151,30 +58281,7 @@ void s1_setup_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// S1SetupFailure ::= SEQUENCE -SRSASN_CODE s1_setup_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE s1_setup_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void s1_setup_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; s1_setup_request_ies_container::s1_setup_request_ies_container() : global_enb_id(59, crit_e::reject), @@ -59225,59 +58332,75 @@ SRSASN_CODE s1_setup_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 59: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 59: { nof_mandatory_ies--; - global_enb_id.id = c.id; - global_enb_id.crit = c.crit; - global_enb_id.value = c.value.global_enb_id(); + global_enb_id.id = id; + HANDLE_CODE(global_enb_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(global_enb_id.value.unpack(bref)); break; - case 60: + } + case 60: { enbname_present = true; - enbname.id = c.id; - enbname.crit = c.crit; - enbname.value = c.value.enbname(); + enbname.id = id; + HANDLE_CODE(enbname.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enbname.value.unpack(bref)); break; - case 64: + } + case 64: { nof_mandatory_ies--; - supported_tas.id = c.id; - supported_tas.crit = c.crit; - supported_tas.value = c.value.supported_tas(); + supported_tas.id = id; + HANDLE_CODE(supported_tas.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(supported_tas.value.unpack(bref)); break; - case 137: + } + case 137: { nof_mandatory_ies--; - default_paging_drx.id = c.id; - default_paging_drx.crit = c.crit; - default_paging_drx.value = c.value.default_paging_drx(); + default_paging_drx.id = id; + HANDLE_CODE(default_paging_drx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(default_paging_drx.value.unpack(bref)); break; - case 128: + } + case 128: { csg_id_list_present = true; - csg_id_list.id = c.id; - csg_id_list.crit = c.crit; - csg_id_list.value = c.value.csg_id_list(); + csg_id_list.id = id; + HANDLE_CODE(csg_id_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_id_list.value.unpack(bref)); break; - case 228: + } + case 228: { ue_retention_info_present = true; - ue_retention_info.id = c.id; - ue_retention_info.crit = c.crit; - ue_retention_info.value = c.value.ue_retention_info(); + ue_retention_info.id = id; + HANDLE_CODE(ue_retention_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_retention_info.value.unpack(bref)); break; - case 234: + } + case 234: { nb_io_t_default_paging_drx_present = true; - nb_io_t_default_paging_drx.id = c.id; - nb_io_t_default_paging_drx.crit = c.crit; - nb_io_t_default_paging_drx.value = c.value.nb_io_t_default_paging_drx(); + nb_io_t_default_paging_drx.id = id; + HANDLE_CODE(nb_io_t_default_paging_drx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nb_io_t_default_paging_drx.value.unpack(bref)); break; - case 291: + } + case 291: { connectedeng_nb_list_present = true; - connectedeng_nb_list.id = c.id; - connectedeng_nb_list.crit = c.crit; - connectedeng_nb_list.value = c.value.connectedeng_nb_list(); + connectedeng_nb_list.id = id; + HANDLE_CODE(connectedeng_nb_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(connectedeng_nb_list.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -59320,30 +58443,7 @@ void s1_setup_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// S1SetupRequest ::= SEQUENCE -SRSASN_CODE s1_setup_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE s1_setup_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void s1_setup_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; s1_setup_resp_ies_container::s1_setup_resp_ies_container() : mm_ename(61, crit_e::ignore), @@ -59392,53 +58492,67 @@ SRSASN_CODE s1_setup_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 61: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 61: { mm_ename_present = true; - mm_ename.id = c.id; - mm_ename.crit = c.crit; - mm_ename.value = c.value.mm_ename(); + mm_ename.id = id; + HANDLE_CODE(mm_ename.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mm_ename.value.unpack(bref)); break; - case 105: + } + case 105: { nof_mandatory_ies--; - served_gummeis.id = c.id; - served_gummeis.crit = c.crit; - served_gummeis.value = c.value.served_gummeis(); + served_gummeis.id = id; + HANDLE_CODE(served_gummeis.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(served_gummeis.value.unpack(bref)); break; - case 87: + } + case 87: { nof_mandatory_ies--; - relative_mme_capacity.id = c.id; - relative_mme_capacity.crit = c.crit; - relative_mme_capacity.value = c.value.relative_mme_capacity(); + relative_mme_capacity.id = id; + HANDLE_CODE(relative_mme_capacity.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(relative_mme_capacity.value.unpack(bref)); break; - case 163: + } + case 163: { mme_relay_support_ind_present = true; - mme_relay_support_ind.id = c.id; - mme_relay_support_ind.crit = c.crit; - mme_relay_support_ind.value = c.value.mme_relay_support_ind(); + mme_relay_support_ind.id = id; + HANDLE_CODE(mme_relay_support_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_relay_support_ind.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 228: + } + case 228: { ue_retention_info_present = true; - ue_retention_info.id = c.id; - ue_retention_info.crit = c.crit; - ue_retention_info.value = c.value.ue_retention_info(); + ue_retention_info.id = id; + HANDLE_CODE(ue_retention_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_retention_info.value.unpack(bref)); break; - case 247: + } + case 247: { served_dcns_present = true; - served_dcns.id = c.id; - served_dcns.crit = c.crit; - served_dcns.value = c.value.served_dcns(); + served_dcns.id = id; + HANDLE_CODE(served_dcns.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(served_dcns.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -59479,30 +58593,7 @@ void s1_setup_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// S1SetupResponse ::= SEQUENCE -SRSASN_CODE s1_setup_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE s1_setup_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void s1_setup_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; secondary_rat_data_usage_report_ies_container::secondary_rat_data_usage_report_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -59543,47 +58634,59 @@ SRSASN_CODE secondary_rat_data_usage_report_ies_container::unpack(cbit_ref& bref uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 264: + } + case 264: { nof_mandatory_ies--; - secondary_rat_data_usage_report_list.id = c.id; - secondary_rat_data_usage_report_list.crit = c.crit; - secondary_rat_data_usage_report_list.value = c.value.secondary_rat_data_usage_report_list(); + secondary_rat_data_usage_report_list.id = id; + HANDLE_CODE(secondary_rat_data_usage_report_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(secondary_rat_data_usage_report_list.value.unpack(bref)); break; - case 266: + } + case 266: { ho_flag_present = true; - ho_flag.id = c.id; - ho_flag.crit = c.crit; - ho_flag.value = c.value.ho_flag(); + ho_flag.id = id; + HANDLE_CODE(ho_flag.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ho_flag.value.unpack(bref)); break; - case 189: + } + case 189: { user_location_info_present = true; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 297: + } + case 297: { time_since_secondary_node_release_present = true; - time_since_secondary_node_release.id = c.id; - time_since_secondary_node_release.crit = c.crit; - time_since_secondary_node_release.value = c.value.time_since_secondary_node_release(); + time_since_secondary_node_release.id = id; + HANDLE_CODE(time_since_secondary_node_release.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_since_secondary_node_release.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -59618,30 +58721,7 @@ void secondary_rat_data_usage_report_ies_container::to_json(json_writer& j) cons j.end_obj(); } -// SecondaryRATDataUsageReport ::= SEQUENCE -SRSASN_CODE secondary_rat_data_usage_report_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE secondary_rat_data_usage_report_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void secondary_rat_data_usage_report_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; trace_fail_ind_ies_container::trace_fail_ind_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -59669,35 +58749,43 @@ SRSASN_CODE trace_fail_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 86: + } + case 86: { nof_mandatory_ies--; - e_utran_trace_id.id = c.id; - e_utran_trace_id.crit = c.crit; - e_utran_trace_id.value = c.value.e_utran_trace_id(); + e_utran_trace_id.id = id; + HANDLE_CODE(e_utran_trace_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(e_utran_trace_id.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -59722,30 +58810,7 @@ void trace_fail_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// TraceFailureIndication ::= SEQUENCE -SRSASN_CODE trace_fail_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE trace_fail_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void trace_fail_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; trace_start_ies_container::trace_start_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), enb_ue_s1ap_id(8, crit_e::reject), trace_activation(25, crit_e::ignore) @@ -59769,29 +58834,35 @@ SRSASN_CODE trace_start_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 25: + } + case 25: { nof_mandatory_ies--; - trace_activation.id = c.id; - trace_activation.crit = c.crit; - trace_activation.value = c.value.trace_activation(); + trace_activation.id = id; + HANDLE_CODE(trace_activation.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(trace_activation.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -59814,30 +58885,7 @@ void trace_start_ies_container::to_json(json_writer& j) const j.end_obj(); } -// TraceStart ::= SEQUENCE -SRSASN_CODE trace_start_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE trace_start_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void trace_start_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_cap_info_ind_ies_container::ue_cap_info_ind_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -59878,47 +58926,59 @@ SRSASN_CODE ue_cap_info_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 74: + } + case 74: { nof_mandatory_ies--; - ue_radio_cap.id = c.id; - ue_radio_cap.crit = c.crit; - ue_radio_cap.value = c.value.ue_radio_cap(); + ue_radio_cap.id = id; + HANDLE_CODE(ue_radio_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap.value.unpack(bref)); break; - case 198: + } + case 198: { ue_radio_cap_for_paging_present = true; - ue_radio_cap_for_paging.id = c.id; - ue_radio_cap_for_paging.crit = c.crit; - ue_radio_cap_for_paging.value = c.value.ue_radio_cap_for_paging(); + ue_radio_cap_for_paging.id = id; + HANDLE_CODE(ue_radio_cap_for_paging.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap_for_paging.value.unpack(bref)); break; - case 263: + } + case 263: { ue_application_layer_meas_cap_present = true; - ue_application_layer_meas_cap.id = c.id; - ue_application_layer_meas_cap.crit = c.crit; - ue_application_layer_meas_cap.value = c.value.ue_application_layer_meas_cap(); + ue_application_layer_meas_cap.id = id; + HANDLE_CODE(ue_application_layer_meas_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_application_layer_meas_cap.value.unpack(bref)); break; - case 272: + } + case 272: { lte_m_ind_present = true; - lte_m_ind.id = c.id; - lte_m_ind.crit = c.crit; - lte_m_ind.value = c.value.lte_m_ind(); + lte_m_ind.id = id; + HANDLE_CODE(lte_m_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(lte_m_ind.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -59953,30 +59013,7 @@ void ue_cap_info_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UECapabilityInfoIndication ::= SEQUENCE -SRSASN_CODE ue_cap_info_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_cap_info_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_cap_info_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_mod_confirm_ies_container::ue_context_mod_confirm_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -60010,35 +59047,43 @@ SRSASN_CODE ue_context_mod_confirm_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 146: + } + case 146: { csg_membership_status_present = true; - csg_membership_status.id = c.id; - csg_membership_status.crit = c.crit; - csg_membership_status.value = c.value.csg_membership_status(); + csg_membership_status.id = id; + HANDLE_CODE(csg_membership_status.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_membership_status.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -60067,30 +59112,7 @@ void ue_context_mod_confirm_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextModificationConfirm ::= SEQUENCE -SRSASN_CODE ue_context_mod_confirm_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_mod_confirm_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_mod_confirm_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_mod_fail_ies_container::ue_context_mod_fail_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -60121,35 +59143,43 @@ SRSASN_CODE ue_context_mod_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -60176,30 +59206,7 @@ void ue_context_mod_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextModificationFailure ::= SEQUENCE -SRSASN_CODE ue_context_mod_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_mod_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_mod_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_mod_ind_ies_container::ue_context_mod_ind_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), enb_ue_s1ap_id(8, crit_e::reject), csg_membership_info(226, crit_e::reject) @@ -60226,29 +59233,35 @@ SRSASN_CODE ue_context_mod_ind_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 226: + } + case 226: { csg_membership_info_present = true; - csg_membership_info.id = c.id; - csg_membership_info.crit = c.crit; - csg_membership_info.value = c.value.csg_membership_info(); + csg_membership_info.id = id; + HANDLE_CODE(csg_membership_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_membership_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -60273,30 +59286,7 @@ void ue_context_mod_ind_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextModificationIndication ::= SEQUENCE -SRSASN_CODE ue_context_mod_ind_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_mod_ind_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_mod_ind_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_mod_request_ies_container::ue_context_mod_request_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -60400,119 +59390,155 @@ SRSASN_CODE ue_context_mod_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 73: + } + case 73: { security_key_present = true; - security_key.id = c.id; - security_key.crit = c.crit; - security_key.value = c.value.security_key(); + security_key.id = id; + HANDLE_CODE(security_key.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_key.value.unpack(bref)); break; - case 106: + } + case 106: { subscriber_profile_idfor_rfp_present = true; - subscriber_profile_idfor_rfp.id = c.id; - subscriber_profile_idfor_rfp.crit = c.crit; - subscriber_profile_idfor_rfp.value = c.value.subscriber_profile_idfor_rfp(); + subscriber_profile_idfor_rfp.id = id; + HANDLE_CODE(subscriber_profile_idfor_rfp.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(subscriber_profile_idfor_rfp.value.unpack(bref)); break; - case 66: + } + case 66: { ueaggregate_maximum_bitrate_present = true; - ueaggregate_maximum_bitrate.id = c.id; - ueaggregate_maximum_bitrate.crit = c.crit; - ueaggregate_maximum_bitrate.value = c.value.ueaggregate_maximum_bitrate(); + ueaggregate_maximum_bitrate.id = id; + HANDLE_CODE(ueaggregate_maximum_bitrate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ueaggregate_maximum_bitrate.value.unpack(bref)); break; - case 108: + } + case 108: { cs_fallback_ind_present = true; - cs_fallback_ind.id = c.id; - cs_fallback_ind.crit = c.crit; - cs_fallback_ind.value = c.value.cs_fallback_ind(); + cs_fallback_ind.id = id; + HANDLE_CODE(cs_fallback_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cs_fallback_ind.value.unpack(bref)); break; - case 107: + } + case 107: { ue_security_cap_present = true; - ue_security_cap.id = c.id; - ue_security_cap.crit = c.crit; - ue_security_cap.value = c.value.ue_security_cap(); + ue_security_cap.id = id; + HANDLE_CODE(ue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_security_cap.value.unpack(bref)); break; - case 146: + } + case 146: { csg_membership_status_present = true; - csg_membership_status.id = c.id; - csg_membership_status.crit = c.crit; - csg_membership_status.value = c.value.csg_membership_status(); + csg_membership_status.id = id; + HANDLE_CODE(csg_membership_status.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(csg_membership_status.value.unpack(bref)); break; - case 159: + } + case 159: { registered_lai_present = true; - registered_lai.id = c.id; - registered_lai.crit = c.crit; - registered_lai.value = c.value.registered_lai(); + registered_lai.id = id; + HANDLE_CODE(registered_lai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(registered_lai.value.unpack(bref)); break; - case 187: + } + case 187: { add_cs_fallback_ind_present = true; - add_cs_fallback_ind.id = c.id; - add_cs_fallback_ind.crit = c.crit; - add_cs_fallback_ind.value = c.value.add_cs_fallback_ind(); + add_cs_fallback_ind.id = id; + HANDLE_CODE(add_cs_fallback_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(add_cs_fallback_ind.value.unpack(bref)); break; - case 195: + } + case 195: { pro_se_authorized_present = true; - pro_se_authorized.id = c.id; - pro_se_authorized.crit = c.crit; - pro_se_authorized.value = c.value.pro_se_authorized(); + pro_se_authorized.id = id; + HANDLE_CODE(pro_se_authorized.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pro_se_authorized.value.unpack(bref)); break; - case 124: + } + case 124: { srvcc_operation_possible_present = true; - srvcc_operation_possible.id = c.id; - srvcc_operation_possible.crit = c.crit; - srvcc_operation_possible.value = c.value.srvcc_operation_possible(); + srvcc_operation_possible.id = id; + HANDLE_CODE(srvcc_operation_possible.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(srvcc_operation_possible.value.unpack(bref)); break; - case 243: + } + case 243: { srvcc_operation_not_possible_present = true; - srvcc_operation_not_possible.id = c.id; - srvcc_operation_not_possible.crit = c.crit; - srvcc_operation_not_possible.value = c.value.srvcc_operation_not_possible(); + srvcc_operation_not_possible.id = id; + HANDLE_CODE(srvcc_operation_not_possible.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(srvcc_operation_not_possible.value.unpack(bref)); break; - case 240: + } + case 240: { v2xservices_authorized_present = true; - v2xservices_authorized.id = c.id; - v2xservices_authorized.crit = c.crit; - v2xservices_authorized.value = c.value.v2xservices_authorized(); + v2xservices_authorized.id = id; + HANDLE_CODE(v2xservices_authorized.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(v2xservices_authorized.value.unpack(bref)); break; - case 248: + } + case 248: { ue_sidelink_aggregate_maximum_bitrate_present = true; - ue_sidelink_aggregate_maximum_bitrate.id = c.id; - ue_sidelink_aggregate_maximum_bitrate.crit = c.crit; - ue_sidelink_aggregate_maximum_bitrate.value = c.value.ue_sidelink_aggregate_maximum_bitrate(); + ue_sidelink_aggregate_maximum_bitrate.id = id; + HANDLE_CODE(ue_sidelink_aggregate_maximum_bitrate.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_sidelink_aggregate_maximum_bitrate.value.unpack(bref)); break; - case 269: + } + case 269: { nrue_security_cap_present = true; - nrue_security_cap.id = c.id; - nrue_security_cap.crit = c.crit; - nrue_security_cap.value = c.value.nrue_security_cap(); + nrue_security_cap.id = id; + HANDLE_CODE(nrue_security_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nrue_security_cap.value.unpack(bref)); break; - case 277: + } + case 277: { aerial_uesubscription_info_present = true; - aerial_uesubscription_info.id = c.id; - aerial_uesubscription_info.crit = c.crit; - aerial_uesubscription_info.value = c.value.aerial_uesubscription_info(); + aerial_uesubscription_info.id = id; + HANDLE_CODE(aerial_uesubscription_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(aerial_uesubscription_info.value.unpack(bref)); break; - case 299: + } + case 299: { add_rrm_prio_idx_present = true; - add_rrm_prio_idx.id = c.id; - add_rrm_prio_idx.crit = c.crit; - add_rrm_prio_idx.value = c.value.add_rrm_prio_idx(); + add_rrm_prio_idx.id = id; + HANDLE_CODE(add_rrm_prio_idx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(add_rrm_prio_idx.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -60597,30 +59623,7 @@ void ue_context_mod_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextModificationRequest ::= SEQUENCE -SRSASN_CODE ue_context_mod_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_mod_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_mod_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_mod_resp_ies_container::ue_context_mod_resp_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), enb_ue_s1ap_id(8, crit_e::ignore), crit_diagnostics(58, crit_e::ignore) @@ -60647,29 +59650,35 @@ SRSASN_CODE ue_context_mod_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -60694,30 +59703,7 @@ void ue_context_mod_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextModificationResponse ::= SEQUENCE -SRSASN_CODE ue_context_mod_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_mod_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_mod_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_release_cmd_ies_container::ue_context_release_cmd_ies_container() : ue_s1ap_ids(99, crit_e::reject), cause(2, crit_e::ignore) @@ -60740,23 +59726,27 @@ SRSASN_CODE ue_context_release_cmd_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 99: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 99: { nof_mandatory_ies--; - ue_s1ap_ids.id = c.id; - ue_s1ap_ids.crit = c.crit; - ue_s1ap_ids.value = c.value.ue_s1ap_ids(); + ue_s1ap_ids.id = id; + HANDLE_CODE(ue_s1ap_ids.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_s1ap_ids.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -60777,30 +59767,7 @@ void ue_context_release_cmd_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextReleaseCommand ::= SEQUENCE -SRSASN_CODE ue_context_release_cmd_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_release_cmd_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_release_cmd_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_release_complete_ies_container::ue_context_release_complete_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -60854,59 +59821,75 @@ SRSASN_CODE ue_context_release_complete_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 189: + } + case 189: { user_location_info_present = true; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 213: + } + case 213: { info_on_recommended_cells_and_enbs_for_paging_present = true; - info_on_recommended_cells_and_enbs_for_paging.id = c.id; - info_on_recommended_cells_and_enbs_for_paging.crit = c.crit; - info_on_recommended_cells_and_enbs_for_paging.value = c.value.info_on_recommended_cells_and_enbs_for_paging(); + info_on_recommended_cells_and_enbs_for_paging.id = id; + HANDLE_CODE(info_on_recommended_cells_and_enbs_for_paging.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(info_on_recommended_cells_and_enbs_for_paging.value.unpack(bref)); break; - case 212: + } + case 212: { cell_id_and_ce_level_for_ce_capable_ues_present = true; - cell_id_and_ce_level_for_ce_capable_ues.id = c.id; - cell_id_and_ce_level_for_ce_capable_ues.crit = c.crit; - cell_id_and_ce_level_for_ce_capable_ues.value = c.value.cell_id_and_ce_level_for_ce_capable_ues(); + cell_id_and_ce_level_for_ce_capable_ues.id = id; + HANDLE_CODE(cell_id_and_ce_level_for_ce_capable_ues.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cell_id_and_ce_level_for_ce_capable_ues.value.unpack(bref)); break; - case 264: + } + case 264: { secondary_rat_data_usage_report_list_present = true; - secondary_rat_data_usage_report_list.id = c.id; - secondary_rat_data_usage_report_list.crit = c.crit; - secondary_rat_data_usage_report_list.value = c.value.secondary_rat_data_usage_report_list(); + secondary_rat_data_usage_report_list.id = id; + HANDLE_CODE(secondary_rat_data_usage_report_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(secondary_rat_data_usage_report_list.value.unpack(bref)); break; - case 297: + } + case 297: { time_since_secondary_node_release_present = true; - time_since_secondary_node_release.id = c.id; - time_since_secondary_node_release.crit = c.crit; - time_since_secondary_node_release.value = c.value.time_since_secondary_node_release(); + time_since_secondary_node_release.id = id; + HANDLE_CODE(time_since_secondary_node_release.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_since_secondary_node_release.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -60951,30 +59934,7 @@ void ue_context_release_complete_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextReleaseComplete ::= SEQUENCE -SRSASN_CODE ue_context_release_complete_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_release_complete_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_release_complete_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_release_request_ies_container::ue_context_release_request_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -61010,41 +59970,51 @@ SRSASN_CODE ue_context_release_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 164: + } + case 164: { gw_context_release_ind_present = true; - gw_context_release_ind.id = c.id; - gw_context_release_ind.crit = c.crit; - gw_context_release_ind.value = c.value.gw_context_release_ind(); + gw_context_release_ind.id = id; + HANDLE_CODE(gw_context_release_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(gw_context_release_ind.value.unpack(bref)); break; - case 264: + } + case 264: { secondary_rat_data_usage_report_list_present = true; - secondary_rat_data_usage_report_list.id = c.id; - secondary_rat_data_usage_report_list.crit = c.crit; - secondary_rat_data_usage_report_list.value = c.value.secondary_rat_data_usage_report_list(); + secondary_rat_data_usage_report_list.id = id; + HANDLE_CODE(secondary_rat_data_usage_report_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(secondary_rat_data_usage_report_list.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -61075,30 +60045,7 @@ void ue_context_release_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextReleaseRequest ::= SEQUENCE -SRSASN_CODE ue_context_release_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_release_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_release_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_resume_fail_ies_container::ue_context_resume_fail_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -61129,35 +60076,43 @@ SRSASN_CODE ue_context_resume_fail_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 2: + } + case 2: { nof_mandatory_ies--; - cause.id = c.id; - cause.crit = c.crit; - cause.value = c.value.cause(); + cause.id = id; + HANDLE_CODE(cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cause.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -61184,30 +60139,7 @@ void ue_context_resume_fail_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextResumeFailure ::= SEQUENCE -SRSASN_CODE ue_context_resume_fail_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_resume_fail_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_resume_fail_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_resume_request_ies_container::ue_context_resume_request_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -61241,35 +60173,43 @@ SRSASN_CODE ue_context_resume_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 235: + } + case 235: { erab_failed_to_resume_list_resume_req_present = true; - erab_failed_to_resume_list_resume_req.id = c.id; - erab_failed_to_resume_list_resume_req.crit = c.crit; - erab_failed_to_resume_list_resume_req.value = c.value.erab_failed_to_resume_list_resume_req(); + erab_failed_to_resume_list_resume_req.id = id; + HANDLE_CODE(erab_failed_to_resume_list_resume_req.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_failed_to_resume_list_resume_req.value.unpack(bref)); break; - case 245: + } + case 245: { rrc_resume_cause_present = true; - rrc_resume_cause.id = c.id; - rrc_resume_cause.crit = c.crit; - rrc_resume_cause.value = c.value.rrc_resume_cause(); + rrc_resume_cause.id = id; + HANDLE_CODE(rrc_resume_cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(rrc_resume_cause.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -61298,30 +60238,7 @@ void ue_context_resume_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextResumeRequest ::= SEQUENCE -SRSASN_CODE ue_context_resume_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_resume_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_resume_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_resume_resp_ies_container::ue_context_resume_resp_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -61365,47 +60282,59 @@ SRSASN_CODE ue_context_resume_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 237: + } + case 237: { erab_failed_to_resume_list_resume_res_present = true; - erab_failed_to_resume_list_resume_res.id = c.id; - erab_failed_to_resume_list_resume_res.crit = c.crit; - erab_failed_to_resume_list_resume_res.value = c.value.erab_failed_to_resume_list_resume_res(); + erab_failed_to_resume_list_resume_res.id = id; + HANDLE_CODE(erab_failed_to_resume_list_resume_res.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(erab_failed_to_resume_list_resume_res.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 40: + } + case 40: { security_context_present = true; - security_context.id = c.id; - security_context.crit = c.crit; - security_context.value = c.value.security_context(); + security_context.id = id; + HANDLE_CODE(security_context.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_context.value.unpack(bref)); break; - case 283: + } + case 283: { pending_data_ind_present = true; - pending_data_ind.id = c.id; - pending_data_ind.crit = c.crit; - pending_data_ind.value = c.value.pending_data_ind(); + pending_data_ind.id = id; + HANDLE_CODE(pending_data_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pending_data_ind.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -61442,30 +60371,7 @@ void ue_context_resume_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextResumeResponse ::= SEQUENCE -SRSASN_CODE ue_context_resume_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_resume_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_resume_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_suspend_request_ies_container::ue_context_suspend_request_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -61514,53 +60420,67 @@ SRSASN_CODE ue_context_suspend_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 213: + } + case 213: { info_on_recommended_cells_and_enbs_for_paging_present = true; - info_on_recommended_cells_and_enbs_for_paging.id = c.id; - info_on_recommended_cells_and_enbs_for_paging.crit = c.crit; - info_on_recommended_cells_and_enbs_for_paging.value = c.value.info_on_recommended_cells_and_enbs_for_paging(); + info_on_recommended_cells_and_enbs_for_paging.id = id; + HANDLE_CODE(info_on_recommended_cells_and_enbs_for_paging.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(info_on_recommended_cells_and_enbs_for_paging.value.unpack(bref)); break; - case 212: + } + case 212: { cell_id_and_ce_level_for_ce_capable_ues_present = true; - cell_id_and_ce_level_for_ce_capable_ues.id = c.id; - cell_id_and_ce_level_for_ce_capable_ues.crit = c.crit; - cell_id_and_ce_level_for_ce_capable_ues.value = c.value.cell_id_and_ce_level_for_ce_capable_ues(); + cell_id_and_ce_level_for_ce_capable_ues.id = id; + HANDLE_CODE(cell_id_and_ce_level_for_ce_capable_ues.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cell_id_and_ce_level_for_ce_capable_ues.value.unpack(bref)); break; - case 264: + } + case 264: { secondary_rat_data_usage_report_list_present = true; - secondary_rat_data_usage_report_list.id = c.id; - secondary_rat_data_usage_report_list.crit = c.crit; - secondary_rat_data_usage_report_list.value = c.value.secondary_rat_data_usage_report_list(); + secondary_rat_data_usage_report_list.id = id; + HANDLE_CODE(secondary_rat_data_usage_report_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(secondary_rat_data_usage_report_list.value.unpack(bref)); break; - case 189: + } + case 189: { user_location_info_present = true; - user_location_info.id = c.id; - user_location_info.crit = c.crit; - user_location_info.value = c.value.user_location_info(); + user_location_info.id = id; + HANDLE_CODE(user_location_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(user_location_info.value.unpack(bref)); break; - case 297: + } + case 297: { time_since_secondary_node_release_present = true; - time_since_secondary_node_release.id = c.id; - time_since_secondary_node_release.crit = c.crit; - time_since_secondary_node_release.value = c.value.time_since_secondary_node_release(); + time_since_secondary_node_release.id = id; + HANDLE_CODE(time_since_secondary_node_release.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_since_secondary_node_release.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -61601,30 +60521,7 @@ void ue_context_suspend_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextSuspendRequest ::= SEQUENCE -SRSASN_CODE ue_context_suspend_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_suspend_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_suspend_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_context_suspend_resp_ies_container::ue_context_suspend_resp_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -61658,35 +60555,43 @@ SRSASN_CODE ue_context_suspend_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; - case 40: + } + case 40: { security_context_present = true; - security_context.id = c.id; - security_context.crit = c.crit; - security_context.value = c.value.security_context(); + security_context.id = id; + HANDLE_CODE(security_context.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(security_context.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -61715,30 +60620,7 @@ void ue_context_suspend_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEContextSuspendResponse ::= SEQUENCE -SRSASN_CODE ue_context_suspend_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_context_suspend_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_context_suspend_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_info_transfer_ies_container::ue_info_transfer_ies_container() : s_tmsi(96, crit_e::reject), @@ -61780,41 +60662,51 @@ SRSASN_CODE ue_info_transfer_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 1; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 96: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 96: { nof_mandatory_ies--; - s_tmsi.id = c.id; - s_tmsi.crit = c.crit; - s_tmsi.value = c.value.s_tmsi(); + s_tmsi.id = id; + HANDLE_CODE(s_tmsi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(s_tmsi.value.unpack(bref)); break; - case 252: + } + case 252: { ue_level_qos_params_present = true; - ue_level_qos_params.id = c.id; - ue_level_qos_params.crit = c.crit; - ue_level_qos_params.value = c.value.ue_level_qos_params(); + ue_level_qos_params.id = id; + HANDLE_CODE(ue_level_qos_params.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_level_qos_params.value.unpack(bref)); break; - case 74: + } + case 74: { ue_radio_cap_present = true; - ue_radio_cap.id = c.id; - ue_radio_cap.crit = c.crit; - ue_radio_cap.value = c.value.ue_radio_cap(); + ue_radio_cap.id = id; + HANDLE_CODE(ue_radio_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap.value.unpack(bref)); break; - case 278: + } + case 278: { subscription_based_ue_differentiation_info_present = true; - subscription_based_ue_differentiation_info.id = c.id; - subscription_based_ue_differentiation_info.crit = c.crit; - subscription_based_ue_differentiation_info.value = c.value.subscription_based_ue_differentiation_info(); + subscription_based_ue_differentiation_info.id = id; + HANDLE_CODE(subscription_based_ue_differentiation_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(subscription_based_ue_differentiation_info.value.unpack(bref)); break; - case 283: + } + case 283: { pending_data_ind_present = true; - pending_data_ind.id = c.id; - pending_data_ind.crit = c.crit; - pending_data_ind.value = c.value.pending_data_ind(); + pending_data_ind.id = id; + HANDLE_CODE(pending_data_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(pending_data_ind.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -61849,30 +60741,7 @@ void ue_info_transfer_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UEInformationTransfer ::= SEQUENCE -SRSASN_CODE ue_info_transfer_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_info_transfer_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_info_transfer_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_radio_cap_match_request_ies_container::ue_radio_cap_match_request_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), enb_ue_s1ap_id(8, crit_e::reject), ue_radio_cap(74, crit_e::ignore) @@ -61899,29 +60768,35 @@ SRSASN_CODE ue_radio_cap_match_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 74: + } + case 74: { ue_radio_cap_present = true; - ue_radio_cap.id = c.id; - ue_radio_cap.crit = c.crit; - ue_radio_cap.value = c.value.ue_radio_cap(); + ue_radio_cap.id = id; + HANDLE_CODE(ue_radio_cap.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_radio_cap.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -61946,30 +60821,7 @@ void ue_radio_cap_match_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UERadioCapabilityMatchRequest ::= SEQUENCE -SRSASN_CODE ue_radio_cap_match_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_radio_cap_match_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_radio_cap_match_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ue_radio_cap_match_resp_ies_container::ue_radio_cap_match_resp_ies_container() : mme_ue_s1ap_id(0, crit_e::ignore), @@ -62000,35 +60852,43 @@ SRSASN_CODE ue_radio_cap_match_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 3; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 169: + } + case 169: { nof_mandatory_ies--; - voice_support_match_ind.id = c.id; - voice_support_match_ind.crit = c.crit; - voice_support_match_ind.value = c.value.voice_support_match_ind(); + voice_support_match_ind.id = id; + HANDLE_CODE(voice_support_match_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(voice_support_match_ind.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -62055,30 +60915,7 @@ void ue_radio_cap_match_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UERadioCapabilityMatchResponse ::= SEQUENCE -SRSASN_CODE ue_radio_cap_match_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ue_radio_cap_match_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ue_radio_cap_match_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ul_nas_transport_ies_container::ul_nas_transport_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -62128,65 +60965,83 @@ SRSASN_CODE ul_nas_transport_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 5; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 26: + } + case 26: { nof_mandatory_ies--; - nas_pdu.id = c.id; - nas_pdu.crit = c.crit; - nas_pdu.value = c.value.nas_pdu(); + nas_pdu.id = id; + HANDLE_CODE(nas_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(nas_pdu.value.unpack(bref)); break; - case 100: + } + case 100: { nof_mandatory_ies--; - eutran_cgi.id = c.id; - eutran_cgi.crit = c.crit; - eutran_cgi.value = c.value.eutran_cgi(); + eutran_cgi.id = id; + HANDLE_CODE(eutran_cgi.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(eutran_cgi.value.unpack(bref)); break; - case 67: + } + case 67: { nof_mandatory_ies--; - tai.id = c.id; - tai.crit = c.crit; - tai.value = c.value.tai(); + tai.id = id; + HANDLE_CODE(tai.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(tai.value.unpack(bref)); break; - case 155: + } + case 155: { gw_transport_layer_address_present = true; - gw_transport_layer_address.id = c.id; - gw_transport_layer_address.crit = c.crit; - gw_transport_layer_address.value = c.value.gw_transport_layer_address(); + gw_transport_layer_address.id = id; + HANDLE_CODE(gw_transport_layer_address.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(gw_transport_layer_address.value.unpack(bref)); break; - case 184: + } + case 184: { sipto_l_gw_transport_layer_address_present = true; - sipto_l_gw_transport_layer_address.id = c.id; - sipto_l_gw_transport_layer_address.crit = c.crit; - sipto_l_gw_transport_layer_address.value = c.value.sipto_l_gw_transport_layer_address(); + sipto_l_gw_transport_layer_address.id = id; + HANDLE_CODE(sipto_l_gw_transport_layer_address.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(sipto_l_gw_transport_layer_address.value.unpack(bref)); break; - case 186: + } + case 186: { lhn_id_present = true; - lhn_id.id = c.id; - lhn_id.crit = c.crit; - lhn_id.value = c.value.lhn_id(); + lhn_id.id = id; + HANDLE_CODE(lhn_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(lhn_id.value.unpack(bref)); break; - case 288: + } + case 288: { ps_cell_info_present = true; - ps_cell_info.id = c.id; - ps_cell_info.crit = c.crit; - ps_cell_info.value = c.value.ps_cell_info(); + ps_cell_info.id = id; + HANDLE_CODE(ps_cell_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ps_cell_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -62229,30 +61084,7 @@ void ul_nas_transport_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UplinkNASTransport ::= SEQUENCE -SRSASN_CODE ul_nas_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ul_nas_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ul_nas_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ul_non_ueassociated_lp_pa_transport_ies_container::ul_non_ueassociated_lp_pa_transport_ies_container() : routing_id(148, crit_e::reject), lp_pa_pdu(147, crit_e::reject) @@ -62275,23 +61107,27 @@ SRSASN_CODE ul_non_ueassociated_lp_pa_transport_ies_container::unpack(cbit_ref& uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 148: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 148: { nof_mandatory_ies--; - routing_id.id = c.id; - routing_id.crit = c.crit; - routing_id.value = c.value.routing_id(); + routing_id.id = id; + HANDLE_CODE(routing_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(routing_id.value.unpack(bref)); break; - case 147: + } + case 147: { nof_mandatory_ies--; - lp_pa_pdu.id = c.id; - lp_pa_pdu.crit = c.crit; - lp_pa_pdu.value = c.value.lp_pa_pdu(); + lp_pa_pdu.id = id; + HANDLE_CODE(lp_pa_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(lp_pa_pdu.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -62312,30 +61148,7 @@ void ul_non_ueassociated_lp_pa_transport_ies_container::to_json(json_writer& j) j.end_obj(); } -// UplinkNonUEAssociatedLPPaTransport ::= SEQUENCE -SRSASN_CODE ul_non_ueassociated_lp_pa_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ul_non_ueassociated_lp_pa_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ul_non_ueassociated_lp_pa_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ul_s1cdma2000tunnelling_ies_container::ul_s1cdma2000tunnelling_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -62385,65 +61198,83 @@ SRSASN_CODE ul_s1cdma2000tunnelling_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 5; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 71: + } + case 71: { nof_mandatory_ies--; - cdma2000_rat_type.id = c.id; - cdma2000_rat_type.crit = c.crit; - cdma2000_rat_type.value = c.value.cdma2000_rat_type(); + cdma2000_rat_type.id = id; + HANDLE_CODE(cdma2000_rat_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cdma2000_rat_type.value.unpack(bref)); break; - case 72: + } + case 72: { nof_mandatory_ies--; - cdma2000_sector_id.id = c.id; - cdma2000_sector_id.crit = c.crit; - cdma2000_sector_id.value = c.value.cdma2000_sector_id(); + cdma2000_sector_id.id = id; + HANDLE_CODE(cdma2000_sector_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cdma2000_sector_id.value.unpack(bref)); break; - case 84: + } + case 84: { cdma2000_ho_required_ind_present = true; - cdma2000_ho_required_ind.id = c.id; - cdma2000_ho_required_ind.crit = c.crit; - cdma2000_ho_required_ind.value = c.value.cdma2000_ho_required_ind(); + cdma2000_ho_required_ind.id = id; + HANDLE_CODE(cdma2000_ho_required_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cdma2000_ho_required_ind.value.unpack(bref)); break; - case 102: + } + case 102: { cdma2000_one_xsrvcc_info_present = true; - cdma2000_one_xsrvcc_info.id = c.id; - cdma2000_one_xsrvcc_info.crit = c.crit; - cdma2000_one_xsrvcc_info.value = c.value.cdma2000_one_xsrvcc_info(); + cdma2000_one_xsrvcc_info.id = id; + HANDLE_CODE(cdma2000_one_xsrvcc_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cdma2000_one_xsrvcc_info.value.unpack(bref)); break; - case 97: + } + case 97: { cdma2000_one_xrand_present = true; - cdma2000_one_xrand.id = c.id; - cdma2000_one_xrand.crit = c.crit; - cdma2000_one_xrand.value = c.value.cdma2000_one_xrand(); + cdma2000_one_xrand.id = id; + HANDLE_CODE(cdma2000_one_xrand.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cdma2000_one_xrand.value.unpack(bref)); break; - case 70: + } + case 70: { nof_mandatory_ies--; - cdma2000_pdu.id = c.id; - cdma2000_pdu.crit = c.crit; - cdma2000_pdu.value = c.value.cdma2000_pdu(); + cdma2000_pdu.id = id; + HANDLE_CODE(cdma2000_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(cdma2000_pdu.value.unpack(bref)); break; - case 140: + } + case 140: { eutran_round_trip_delay_estimation_info_present = true; - eutran_round_trip_delay_estimation_info.id = c.id; - eutran_round_trip_delay_estimation_info.crit = c.crit; - eutran_round_trip_delay_estimation_info.value = c.value.eutran_round_trip_delay_estimation_info(); + eutran_round_trip_delay_estimation_info.id = id; + HANDLE_CODE(eutran_round_trip_delay_estimation_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(eutran_round_trip_delay_estimation_info.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -62486,30 +61317,7 @@ void ul_s1cdma2000tunnelling_ies_container::to_json(json_writer& j) const j.end_obj(); } -// UplinkS1cdma2000tunnelling ::= SEQUENCE -SRSASN_CODE ul_s1cdma2000tunnelling_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ul_s1cdma2000tunnelling_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ul_s1cdma2000tunnelling_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; ul_ueassociated_lp_pa_transport_ies_container::ul_ueassociated_lp_pa_transport_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), @@ -62537,35 +61345,43 @@ SRSASN_CODE ul_ueassociated_lp_pa_transport_ies_container::unpack(cbit_ref& bref uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 0: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 0: { nof_mandatory_ies--; - mme_ue_s1ap_id.id = c.id; - mme_ue_s1ap_id.crit = c.crit; - mme_ue_s1ap_id.value = c.value.mme_ue_s1ap_id(); + mme_ue_s1ap_id.id = id; + HANDLE_CODE(mme_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mme_ue_s1ap_id.value.unpack(bref)); break; - case 8: + } + case 8: { nof_mandatory_ies--; - enb_ue_s1ap_id.id = c.id; - enb_ue_s1ap_id.crit = c.crit; - enb_ue_s1ap_id.value = c.value.enb_ue_s1ap_id(); + enb_ue_s1ap_id.id = id; + HANDLE_CODE(enb_ue_s1ap_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(enb_ue_s1ap_id.value.unpack(bref)); break; - case 148: + } + case 148: { nof_mandatory_ies--; - routing_id.id = c.id; - routing_id.crit = c.crit; - routing_id.value = c.value.routing_id(); + routing_id.id = id; + HANDLE_CODE(routing_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(routing_id.value.unpack(bref)); break; - case 147: + } + case 147: { nof_mandatory_ies--; - lp_pa_pdu.id = c.id; - lp_pa_pdu.crit = c.crit; - lp_pa_pdu.value = c.value.lp_pa_pdu(); + lp_pa_pdu.id = id; + HANDLE_CODE(lp_pa_pdu.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(lp_pa_pdu.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -62590,30 +61406,7 @@ void ul_ueassociated_lp_pa_transport_ies_container::to_json(json_writer& j) cons j.end_obj(); } -// UplinkUEAssociatedLPPaTransport ::= SEQUENCE -SRSASN_CODE ul_ueassociated_lp_pa_transport_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE ul_ueassociated_lp_pa_transport_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void ul_ueassociated_lp_pa_transport_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; write_replace_warning_request_ies_container::write_replace_warning_request_ies_container() : msg_id(111, crit_e::reject), @@ -62681,83 +61474,107 @@ SRSASN_CODE write_replace_warning_request_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 4; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 111: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 111: { nof_mandatory_ies--; - msg_id.id = c.id; - msg_id.crit = c.crit; - msg_id.value = c.value.msg_id(); + msg_id.id = id; + HANDLE_CODE(msg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(msg_id.value.unpack(bref)); break; - case 112: + } + case 112: { nof_mandatory_ies--; - serial_num.id = c.id; - serial_num.crit = c.crit; - serial_num.value = c.value.serial_num(); + serial_num.id = id; + HANDLE_CODE(serial_num.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(serial_num.value.unpack(bref)); break; - case 113: + } + case 113: { warning_area_list_present = true; - warning_area_list.id = c.id; - warning_area_list.crit = c.crit; - warning_area_list.value = c.value.warning_area_list(); + warning_area_list.id = id; + HANDLE_CODE(warning_area_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_area_list.value.unpack(bref)); break; - case 114: + } + case 114: { nof_mandatory_ies--; - repeat_period.id = c.id; - repeat_period.crit = c.crit; - repeat_period.value = c.value.repeat_period(); + repeat_period.id = id; + HANDLE_CODE(repeat_period.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(repeat_period.value.unpack(bref)); break; - case 144: + } + case 144: { extended_repeat_period_present = true; - extended_repeat_period.id = c.id; - extended_repeat_period.crit = c.crit; - extended_repeat_period.value = c.value.extended_repeat_period(); + extended_repeat_period.id = id; + HANDLE_CODE(extended_repeat_period.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(extended_repeat_period.value.unpack(bref)); break; - case 115: + } + case 115: { nof_mandatory_ies--; - numof_broadcast_request.id = c.id; - numof_broadcast_request.crit = c.crit; - numof_broadcast_request.value = c.value.numof_broadcast_request(); + numof_broadcast_request.id = id; + HANDLE_CODE(numof_broadcast_request.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(numof_broadcast_request.value.unpack(bref)); break; - case 116: + } + case 116: { warning_type_present = true; - warning_type.id = c.id; - warning_type.crit = c.crit; - warning_type.value = c.value.warning_type(); + warning_type.id = id; + HANDLE_CODE(warning_type.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_type.value.unpack(bref)); break; - case 117: + } + case 117: { warning_security_info_present = true; - warning_security_info.id = c.id; - warning_security_info.crit = c.crit; - warning_security_info.value = c.value.warning_security_info(); + warning_security_info.id = id; + HANDLE_CODE(warning_security_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_security_info.value.unpack(bref)); break; - case 118: + } + case 118: { data_coding_scheme_present = true; - data_coding_scheme.id = c.id; - data_coding_scheme.crit = c.crit; - data_coding_scheme.value = c.value.data_coding_scheme(); + data_coding_scheme.id = id; + HANDLE_CODE(data_coding_scheme.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(data_coding_scheme.value.unpack(bref)); break; - case 119: + } + case 119: { warning_msg_contents_present = true; - warning_msg_contents.id = c.id; - warning_msg_contents.crit = c.crit; - warning_msg_contents.value = c.value.warning_msg_contents(); + warning_msg_contents.id = id; + HANDLE_CODE(warning_msg_contents.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_msg_contents.value.unpack(bref)); break; - case 142: + } + case 142: { concurrent_warning_msg_ind_present = true; - concurrent_warning_msg_ind.id = c.id; - concurrent_warning_msg_ind.crit = c.crit; - concurrent_warning_msg_ind.value = c.value.concurrent_warning_msg_ind(); + concurrent_warning_msg_ind.id = id; + HANDLE_CODE(concurrent_warning_msg_ind.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(concurrent_warning_msg_ind.value.unpack(bref)); break; - case 286: + } + case 286: { warning_area_coordinates_present = true; - warning_area_coordinates.id = c.id; - warning_area_coordinates.crit = c.crit; - warning_area_coordinates.value = c.value.warning_area_coordinates(); + warning_area_coordinates.id = id; + HANDLE_CODE(warning_area_coordinates.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(warning_area_coordinates.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -62814,30 +61631,7 @@ void write_replace_warning_request_ies_container::to_json(json_writer& j) const j.end_obj(); } -// WriteReplaceWarningRequest ::= SEQUENCE -SRSASN_CODE write_replace_warning_request_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE write_replace_warning_request_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void write_replace_warning_request_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - -template struct asn1::s1ap::protocol_ie_field_s; +template struct asn1::protocol_ie_field_s; write_replace_warning_resp_ies_container::write_replace_warning_resp_ies_container() : msg_id(111, crit_e::reject), @@ -62871,35 +61665,43 @@ SRSASN_CODE write_replace_warning_resp_ies_container::unpack(cbit_ref& bref) uint32_t nof_mandatory_ies = 2; for (; nof_ies > 0; --nof_ies) { - protocol_ie_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 111: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 111: { nof_mandatory_ies--; - msg_id.id = c.id; - msg_id.crit = c.crit; - msg_id.value = c.value.msg_id(); + msg_id.id = id; + HANDLE_CODE(msg_id.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(msg_id.value.unpack(bref)); break; - case 112: + } + case 112: { nof_mandatory_ies--; - serial_num.id = c.id; - serial_num.crit = c.crit; - serial_num.value = c.value.serial_num(); + serial_num.id = id; + HANDLE_CODE(serial_num.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(serial_num.value.unpack(bref)); break; - case 120: + } + case 120: { broadcast_completed_area_list_present = true; - broadcast_completed_area_list.id = c.id; - broadcast_completed_area_list.crit = c.crit; - broadcast_completed_area_list.value = c.value.broadcast_completed_area_list(); + broadcast_completed_area_list.id = id; + HANDLE_CODE(broadcast_completed_area_list.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(broadcast_completed_area_list.value.unpack(bref)); break; - case 58: + } + case 58: { crit_diagnostics_present = true; - crit_diagnostics.id = c.id; - crit_diagnostics.crit = c.crit; - crit_diagnostics.value = c.value.crit_diagnostics(); + crit_diagnostics.id = id; + HANDLE_CODE(crit_diagnostics.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(crit_diagnostics.value.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -62928,29 +61730,6 @@ void write_replace_warning_resp_ies_container::to_json(json_writer& j) const j.end_obj(); } -// WriteReplaceWarningResponse ::= SEQUENCE -SRSASN_CODE write_replace_warning_resp_s::pack(bit_ref& bref) const -{ - bref.pack(ext, 1); - HANDLE_CODE(protocol_ies.pack(bref)); - - return SRSASN_SUCCESS; -} -SRSASN_CODE write_replace_warning_resp_s::unpack(cbit_ref& bref) -{ - bref.unpack(ext, 1); - HANDLE_CODE(protocol_ies.unpack(bref)); - - return SRSASN_SUCCESS; -} -void write_replace_warning_resp_s::to_json(json_writer& j) const -{ - j.start_obj(); - j.write_fieldname("protocolIEs"); - protocol_ies.to_json(j); - j.end_obj(); -} - // S1AP-ELEMENTARY-PROCEDURES ::= OBJECT SET OF S1AP-ELEMENTARY-PROCEDURE uint16_t s1ap_elem_procs_o::idx_to_proc_code(uint32_t idx) { @@ -66039,7 +64818,7 @@ uint8_t last_visited_eutran_cell_info_ext_ies_o::ext_c::types_opts::to_number() return map_enum_number(options, 1, value, "last_visited_eutran_cell_info_ext_ies_o::ext_c::types"); } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; last_visited_eutran_cell_info_ext_ies_container::last_visited_eutran_cell_info_ext_ies_container() : time_ue_stayed_in_cell_enhanced_granularity(167, crit_e::ignore), ho_cause(168, crit_e::ignore) @@ -66066,23 +64845,27 @@ SRSASN_CODE last_visited_eutran_cell_info_ext_ies_container::unpack(cbit_ref& br unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 167: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 167: { time_ue_stayed_in_cell_enhanced_granularity_present = true; - time_ue_stayed_in_cell_enhanced_granularity.id = c.id; - time_ue_stayed_in_cell_enhanced_granularity.crit = c.crit; - time_ue_stayed_in_cell_enhanced_granularity.ext = c.ext_value.time_ue_stayed_in_cell_enhanced_granularity(); + time_ue_stayed_in_cell_enhanced_granularity.id = id; + HANDLE_CODE(time_ue_stayed_in_cell_enhanced_granularity.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(time_ue_stayed_in_cell_enhanced_granularity.ext.unpack(bref)); break; - case 168: + } + case 168: { ho_cause_present = true; - ho_cause.id = c.id; - ho_cause.crit = c.crit; - ho_cause.ext = c.ext_value.ho_cause(); + ho_cause.id = id; + HANDLE_CODE(ho_cause.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ho_cause.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } @@ -67979,7 +66762,7 @@ uint8_t sourceenb_to_targetenb_transparent_container_ext_ies_o::ext_c::types_opt return 0; } -template struct asn1::s1ap::protocol_ext_field_s; +template struct asn1::protocol_ext_field_s; sourceenb_to_targetenb_transparent_container_ext_ies_container:: sourceenb_to_targetenb_transparent_container_ext_ies_container() : @@ -68023,41 +66806,51 @@ SRSASN_CODE sourceenb_to_targetenb_transparent_container_ext_ies_container::unpa unpack_length(nof_ies, bref, 1u, 65535u, true); for (; nof_ies > 0; --nof_ies) { - protocol_ext_field_s c; - HANDLE_CODE(c.unpack(bref)); - switch (c.id) { - case 175: + uint32_t id; + HANDLE_CODE(unpack_integer(id, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); + switch (id) { + case 175: { mob_info_present = true; - mob_info.id = c.id; - mob_info.crit = c.crit; - mob_info.ext = c.ext_value.mob_info(); + mob_info.id = id; + HANDLE_CODE(mob_info.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(mob_info.ext.unpack(bref)); break; - case 194: + } + case 194: { ue_history_info_from_the_ue_present = true; - ue_history_info_from_the_ue.id = c.id; - ue_history_info_from_the_ue.crit = c.crit; - ue_history_info_from_the_ue.ext = c.ext_value.ue_history_info_from_the_ue(); + ue_history_info_from_the_ue.id = id; + HANDLE_CODE(ue_history_info_from_the_ue.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(ue_history_info_from_the_ue.ext.unpack(bref)); break; - case 296: + } + case 296: { im_svoice_ep_sfallbackfrom5_g_present = true; - im_svoice_ep_sfallbackfrom5_g.id = c.id; - im_svoice_ep_sfallbackfrom5_g.crit = c.crit; - im_svoice_ep_sfallbackfrom5_g.ext = c.ext_value.im_svoice_ep_sfallbackfrom5_g(); + im_svoice_ep_sfallbackfrom5_g.id = id; + HANDLE_CODE(im_svoice_ep_sfallbackfrom5_g.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(im_svoice_ep_sfallbackfrom5_g.ext.unpack(bref)); break; - case 299: + } + case 299: { add_rrm_prio_idx_present = true; - add_rrm_prio_idx.id = c.id; - add_rrm_prio_idx.crit = c.crit; - add_rrm_prio_idx.ext = c.ext_value.add_rrm_prio_idx(); + add_rrm_prio_idx.id = id; + HANDLE_CODE(add_rrm_prio_idx.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(add_rrm_prio_idx.ext.unpack(bref)); break; - case 300: + } + case 300: { contextat_source_present = true; - contextat_source.id = c.id; - contextat_source.crit = c.crit; - contextat_source.ext = c.ext_value.contextat_source(); + contextat_source.id = id; + HANDLE_CODE(contextat_source.crit.unpack(bref)); + varlength_field_unpack_guard varlen_scope(bref, true); + HANDLE_CODE(contextat_source.ext.unpack(bref)); break; + } default: - asn1::log_error("Unpacked object ID=%d is not recognized\n", c.id); + asn1::log_error("Unpacked object ID=%d is not recognized\n", id); return SRSASN_ERROR_DECODE_FAIL; } } diff --git a/lib/src/asn1/s1ap_utils.cc b/lib/src/asn1/s1ap_utils.cc index 9a121c6d64..01dbdc11bd 100644 --- a/lib/src/asn1/s1ap_utils.cc +++ b/lib/src/asn1/s1ap_utils.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -35,21 +35,21 @@ template <> uint32_t get_obj_id >( const protocol_ie_single_container_s& obj) { - return obj.value.erab_to_be_setup_item_ctxt_su_req().erab_id; + return obj->erab_to_be_setup_item_ctxt_su_req().erab_id; } template <> uint32_t get_obj_id >( const protocol_ie_single_container_s& obj) { - return obj.value.erab_to_be_setup_item_bearer_su_req().erab_id; + return obj->erab_to_be_setup_item_bearer_su_req().erab_id; } template <> uint32_t get_obj_id >( const protocol_ie_single_container_s& obj) { - return obj.value.erab_to_be_modified_item_bearer_mod_req().erab_id; + return obj->erab_to_be_modified_item_bearer_mod_req().erab_id; } } // namespace s1ap diff --git a/lib/src/common/CMakeLists.txt b/lib/src/common/CMakeLists.txt index e6c0b1282f..99200cf1e5 100644 --- a/lib/src/common/CMakeLists.txt +++ b/lib/src/common/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -39,6 +39,7 @@ set(SOURCES arch_select.cc rrc_common.cc rlc_pcap.cc s1ap_pcap.cc + ngap_pcap.cc security.cc standard_streams.cc thread_pool.cc @@ -62,6 +63,6 @@ target_include_directories(srsran_common PUBLIC ${SEC_INCLUDE_DIRS} ${CMAKE_SOUR target_link_libraries(srsran_common srsran_phy support srslog ${SEC_LIBRARIES} ${BACKWARD_LIBRARIES} ${SCTP_LIBRARIES}) target_compile_definitions(srsran_common PRIVATE ${BACKWARD_DEFINITIONS}) -INSTALL(TARGETS srsran_common DESTINATION ${LIBRARY_DIR}) +install(TARGETS srsran_common DESTINATION ${LIBRARY_DIR} OPTIONAL) add_subdirectory(test) diff --git a/lib/src/common/arch_select.cc b/lib/src/common/arch_select.cc index aa320f8300..29c7d330cc 100644 --- a/lib/src/common/arch_select.cc +++ b/lib/src/common/arch_select.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/backtrace.c b/lib/src/common/backtrace.c index 8452ad7049..9e94531b13 100644 --- a/lib/src/common/backtrace.c +++ b/lib/src/common/backtrace.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/band_helper.cc b/lib/src/common/band_helper.cc index d9c48ef98e..2e00797d77 100644 --- a/lib/src/common/band_helper.cc +++ b/lib/src/common/band_helper.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -142,23 +142,21 @@ double srsran_band_helper::get_abs_freq_point_a_from_center_freq(uint32_t nof_pr SRSRAN_NRE); } -uint32_t -srsran_band_helper::get_abs_freq_ssb_arfcn(uint16_t band, srsran_subcarrier_spacing_t scs, uint32_t freq_point_a_arfcn) +uint32_t srsran_band_helper::find_lower_bound_abs_freq_ssb(uint16_t band, + srsran_subcarrier_spacing_t scs, + uint32_t min_center_freq_hz) { sync_raster_t sync_raster = get_sync_raster(band, scs); if (!sync_raster.valid()) { return 0; } - // double abs_freq_ssb_hz = sync_raster.get_frequency(); - double freq_point_a_hz = nr_arfcn_to_freq(freq_point_a_arfcn); - double ssb_bw_hz = SRSRAN_SSB_BW_SUBC * SRSRAN_SUBC_SPACING_NR(scs); - + double ssb_bw_hz = SRSRAN_SSB_BW_SUBC * SRSRAN_SUBC_SPACING_NR(scs); while (!sync_raster.end()) { double abs_freq_ssb_hz = sync_raster.get_frequency(); - if ((abs_freq_ssb_hz > (freq_point_a_hz + ssb_bw_hz / 2)) and - ((uint32_t)std::round(abs_freq_ssb_hz - freq_point_a_hz) % SRSRAN_SUBC_SPACING_NR(scs) == 0)) { + if ((abs_freq_ssb_hz > min_center_freq_hz + ssb_bw_hz / 2) and + ((uint32_t)std::round(abs_freq_ssb_hz - min_center_freq_hz) % SRSRAN_SUBC_SPACING_NR(scs) == 0)) { return freq_to_nr_arfcn(abs_freq_ssb_hz); } @@ -167,7 +165,17 @@ srsran_band_helper::get_abs_freq_ssb_arfcn(uint16_t band, srsran_subcarrier_spac return 0; } -srsran_ssb_patern_t srsran_band_helper::get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs) const +uint32_t srsran_band_helper::get_abs_freq_ssb_arfcn(uint16_t band, + srsran_subcarrier_spacing_t scs, + uint32_t freq_point_a_arfcn, + uint32_t coreset0_offset_rb) +{ + double freq_point_a_hz = nr_arfcn_to_freq(freq_point_a_arfcn); + double coreset0_offset_hz = coreset0_offset_rb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(scs); + return find_lower_bound_abs_freq_ssb(band, scs, freq_point_a_hz + coreset0_offset_hz); +} + +srsran_ssb_pattern_t srsran_band_helper::get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs) { // Look for the given band and SCS for (const nr_band_ss_raster& ss_raster : nr_band_ss_raster_table) { diff --git a/lib/src/common/bearer_manager.cc b/lib/src/common/bearer_manager.cc index c088883c9f..47317da4f5 100644 --- a/lib/src/common/bearer_manager.cc +++ b/lib/src/common/bearer_manager.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -61,18 +61,28 @@ bool ue_bearer_manager_impl::has_active_radio_bearer(uint32_t eps_bearer_id) return bearers.count(eps_bearer_id) > 0; } -ue_bearer_manager_impl::radio_bearer_t ue_bearer_manager_impl::get_radio_bearer(uint32_t eps_bearer_id) +ue_bearer_manager_impl::radio_bearer_t ue_bearer_manager_impl::get_radio_bearer(uint32_t eps_bearer_id) const { auto it = bearers.find(eps_bearer_id); return it != bearers.end() ? it->second : invalid_rb; } -ue_bearer_manager_impl::radio_bearer_t ue_bearer_manager_impl::get_eps_bearer_id_for_lcid(uint32_t lcid) +ue_bearer_manager_impl::radio_bearer_t ue_bearer_manager_impl::get_eps_bearer_id_for_lcid(uint32_t lcid) const { auto lcid_it = lcid_to_eps_bearer_id.find(lcid); return lcid_it != lcid_to_eps_bearer_id.end() ? bearers.at(lcid_it->second) : invalid_rb; } +bool ue_bearer_manager_impl::set_five_qi(uint32_t eps_bearer_id, uint16_t five_qi) +{ + auto it = bearers.find(eps_bearer_id); + if (it == bearers.end()) { + return false; + } + it->second.five_qi = five_qi; + return true; +} + } // namespace detail } // namespace srsran @@ -95,7 +105,7 @@ void ue_bearer_manager::add_eps_bearer(uint8_t eps_bearer_id, srsran::srsran_rat logger.info( "Bearers: Registered EPS bearer ID %d for lcid=%d over %s-PDCP", eps_bearer_id, lcid, to_string(rat).c_str()); } else { - logger.error("Bearers: EPS bearer ID %d already registered", eps_bearer_id); + logger.warning("Bearers: EPS bearer ID %d already registered", eps_bearer_id); } } @@ -122,13 +132,15 @@ namespace srsenb { enb_bearer_manager::enb_bearer_manager() : logger(srslog::fetch_basic_logger("STCK", false)) {} +enb_bearer_manager::~enb_bearer_manager() {} + void enb_bearer_manager::add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid) { auto user_it = users_map.find(rnti); if (user_it == users_map.end()) { // add empty bearer map // users_map.emplace( ) returns pair - auto p = users_map.emplace( rnti, srsran::detail::ue_bearer_manager_impl{}); + auto p = users_map.emplace(rnti, srsran::detail::ue_bearer_manager_impl{}); if (!p.second) { logger.error("Bearers: Unable to add a new bearer map for rnti=0x%x", rnti); return; @@ -143,7 +155,7 @@ void enb_bearer_manager::add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, sr lcid, to_string(rat).c_str()); } else { - logger.error("Bearers: EPS bearer ID %d for rnti=0x%x already registered", eps_bearer_id, rnti); + logger.warning("Bearers: EPS bearer ID %d for rnti=0x%x already registered", eps_bearer_id, rnti); } } @@ -151,14 +163,14 @@ void enb_bearer_manager::remove_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id) { auto user_it = users_map.find(rnti); if (user_it == users_map.end()) { - logger.error("Bearers: No EPS bearer registered for rnti=0x%x", rnti); + logger.info("Bearers: No EPS bearer registered for rnti=0x%x", rnti); return; } if (user_it->second.remove_eps_bearer(eps_bearer_id)) { logger.info("Bearers: Removed mapping for EPS bearer ID %d for rnti=0x%x", eps_bearer_id, rnti); } else { - logger.error("Bearers: Can't remove EPS bearer ID %d, rnti=0x%x", eps_bearer_id, rnti); + logger.info("Bearers: Can't remove EPS bearer ID %d, rnti=0x%x", eps_bearer_id, rnti); } } @@ -166,7 +178,7 @@ void enb_bearer_manager::rem_user(uint16_t rnti) { auto user_it = users_map.find(rnti); if (user_it == users_map.end()) { - logger.error("Bearers: No EPS bearer registered for rnti=0x%x", rnti); + logger.info("Bearers: No EPS bearer registered for rnti=0x%x", rnti); return; } @@ -183,7 +195,7 @@ bool enb_bearer_manager::has_active_radio_bearer(uint16_t rnti, uint32_t eps_bea return user_it->second.has_active_radio_bearer(eps_bearer_id); } -enb_bearer_manager::radio_bearer_t enb_bearer_manager::get_lcid_bearer(uint16_t rnti, uint32_t lcid) +enb_bearer_manager::radio_bearer_t enb_bearer_manager::get_lcid_bearer(uint16_t rnti, uint32_t lcid) const { auto user_it = users_map.find(rnti); if (user_it == users_map.end()) { @@ -201,4 +213,13 @@ enb_bearer_manager::radio_bearer_t enb_bearer_manager::get_radio_bearer(uint16_t return user_it->second.get_radio_bearer(eps_bearer_id); } -} // namespace srsenb \ No newline at end of file +bool enb_bearer_manager::set_five_qi(uint16_t rnti, uint32_t eps_bearer_id, uint16_t five_qi) +{ + auto user_it = users_map.find(rnti); + if (user_it == users_map.end()) { + return false; + } + return user_it->second.set_five_qi(eps_bearer_id, five_qi); +} + +} // namespace srsenb diff --git a/lib/src/common/buffer_pool.cc b/lib/src/common/buffer_pool.cc index d4d6e12c07..e1dc2c6cf3 100644 --- a/lib/src/common/buffer_pool.cc +++ b/lib/src/common/buffer_pool.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/byte_buffer.cc b/lib/src/common/byte_buffer.cc index d6870a99e8..7378c16c2d 100644 --- a/lib/src/common/byte_buffer.cc +++ b/lib/src/common/byte_buffer.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/crash_handler.cc b/lib/src/common/crash_handler.cc index ec8ae8ad3c..054f5f4e76 100644 --- a/lib/src/common/crash_handler.cc +++ b/lib/src/common/crash_handler.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -31,44 +31,38 @@ using namespace backward; void srsran_debug_handle_crash(int argc, char** argv) { - backward::SignalHandling sh; + static backward::SignalHandling sh; } #else // HAVE_BACKWARD #include "srsran/common/backtrace.h" #include "srsran/version.h" -const static char crash_file_name[] = "./srsRAN.backtrace.crash"; -static int bt_argc; -static char** bt_argv; +static int bt_argc; +static char** bt_argv; static void crash_handler(int sig) { - FILE* f = fopen(crash_file_name, "a"); - if (!f) { - printf("srsRAN crashed... we could not save backtrace in '%s'...\n", crash_file_name); - } else { - time_t lnTime; - struct tm stTime; - char strdate[32]; + FILE* f = stderr; + time_t lnTime; + struct tm stTime; + char strdate[32]; - time(&lnTime); - gmtime_r(&lnTime, &stTime); + time(&lnTime); + gmtime_r(&lnTime, &stTime); - strftime(strdate, sizeof(strdate), "%d/%m/%Y %H:%M:%S", &stTime); + strftime(strdate, sizeof(strdate), "%d/%m/%Y %H:%M:%S", &stTime); - fprintf(f, "--- command='"); - for (int i = 0; i < bt_argc; i++) { - fprintf(f, "%s%s", (i == 0) ? "" : " ", bt_argv[i]); - } - fprintf(f, "' version=%s signal=%d date='%s' ---\n", SRSRAN_VERSION_STRING, sig, strdate); + fprintf(f, "--- command='"); + for (int i = 0; i < bt_argc; i++) { + fprintf(f, "%s%s", (i == 0) ? "" : " ", bt_argv[i]); + } + fprintf(f, "' version=%s signal=%d date='%s' ---\n", SRSRAN_VERSION_STRING, sig, strdate); - srsran_backtrace_print(f); - fprintf(f, "\n"); + srsran_backtrace_print(f); - printf("srsRAN crashed... backtrace saved in '%s'...\n", crash_file_name); - fclose(f); - } - printf("--- exiting ---\n"); + fprintf(f, "srsRAN crashed. Please send this backtrace to the developers ...\n"); + + fprintf(f, "--- exiting ---\n"); exit(1); } @@ -84,4 +78,4 @@ void srsran_debug_handle_crash(int argc, char** argv) signal(SIGPIPE, crash_handler); } -#endif // HAVE_BACKWARD \ No newline at end of file +#endif // HAVE_BACKWARD diff --git a/lib/src/common/enb_events.cc b/lib/src/common/enb_events.cc index ca50d8b3c9..6cee7439a8 100644 --- a/lib/src/common/enb_events.cc +++ b/lib/src/common/enb_events.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/gen_mch_tables.c b/lib/src/common/gen_mch_tables.c index f66d3a8b69..6a4c3d994b 100644 --- a/lib/src/common/gen_mch_tables.c +++ b/lib/src/common/gen_mch_tables.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/mac_pcap.cc b/lib/src/common/mac_pcap.cc index 6978705249..e46c1a5bb7 100644 --- a/lib/src/common/mac_pcap.cc +++ b/lib/src/common/mac_pcap.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/mac_pcap_base.cc b/lib/src/common/mac_pcap_base.cc index 8c1e49a2e1..bb36f10e21 100644 --- a/lib/src/common/mac_pcap_base.cc +++ b/lib/src/common/mac_pcap_base.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -35,10 +35,15 @@ static void emergency_cleanup_handler(void* data) mac_pcap_base::mac_pcap_base() : logger(srslog::fetch_basic_logger("MAC")), thread("PCAP_WRITER_MAC") { - add_emergency_cleanup_handler(emergency_cleanup_handler, this); + emergency_handler_id = add_emergency_cleanup_handler(emergency_cleanup_handler, this); } -mac_pcap_base::~mac_pcap_base() {} +mac_pcap_base::~mac_pcap_base() +{ + if (emergency_handler_id > 0) { + remove_emergency_cleanup_handler(emergency_handler_id); + } +} void mac_pcap_base::enable(bool enable_) { diff --git a/lib/src/common/mac_pcap_net.cc b/lib/src/common/mac_pcap_net.cc index 88d6b6a301..2187705333 100644 --- a/lib/src/common/mac_pcap_net.cc +++ b/lib/src/common/mac_pcap_net.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/nas_pcap.cc b/lib/src/common/nas_pcap.cc index 6c2031b868..484cb33bda 100644 --- a/lib/src/common/nas_pcap.cc +++ b/lib/src/common/nas_pcap.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,10 +22,29 @@ #include "srsran/common/nas_pcap.h" #include "srsran/common/pcap.h" #include "srsran/srsran.h" +#include "srsran/support/emergency_handlers.h" #include namespace srsran { +/// Try to flush the contents of the pcap class before the application is killed. +static void emergency_cleanup_handler(void* data) +{ + reinterpret_cast(data)->close(); +} + +nas_pcap::nas_pcap() +{ + emergency_handler_id = add_emergency_cleanup_handler(emergency_cleanup_handler, this); +} + +nas_pcap::~nas_pcap() +{ + if (emergency_handler_id > 0) { + remove_emergency_cleanup_handler(emergency_handler_id); + } +} + void nas_pcap::enable() { enable_write = true; @@ -51,6 +70,7 @@ void nas_pcap::close() { fprintf(stdout, "Saving NAS PCAP file (DLT=%d) to %s \n", NAS_LTE_DLT, filename.c_str()); DLT_PCAP_Close(pcap_file); + pcap_file = nullptr; } void nas_pcap::write_nas(uint8_t* pdu, uint32_t pdu_len_bytes) diff --git a/lib/src/common/network_utils.cc b/lib/src/common/network_utils.cc index 4b514f5740..6eb9e2b1d0 100644 --- a/lib/src/common/network_utils.cc +++ b/lib/src/common/network_utils.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -118,75 +118,7 @@ int open_socket(net_utils::addr_family ip_type, net_utils::socket_type socket_ty perror("Could not create socket\n"); return -1; } - - if (protocol == protocol_type::SCTP) { - // Sets the data_io_event to be able to use sendrecv_info - // Subscribes to the SCTP_SHUTDOWN event, to handle graceful shutdown - // Also subscribes to SCTP_PEER_ADDR_CHANGE, to handle ungraceful shutdown of the link. - struct sctp_event_subscribe evnts = {}; - evnts.sctp_data_io_event = 1; - evnts.sctp_shutdown_event = 1; - evnts.sctp_address_event = 1; - if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) != 0) { - srslog::fetch_basic_logger(LOGSERVICE).error("Failed to subscribe to SCTP_SHUTDOWN event: %s", strerror(errno)); - perror("Could not register socket to SCTP events\n"); - close(fd); - return -1; - } - - /* - * Modify SCTP default parameters for quicker detection of broken links. - * This includes changes to the SCTP_INITMSG parameters (to control the timeout of the connect() syscall) - * And changes to the maximum re-transmission timeout (rto_max), for quicker detection of broken links. - */ - // Set RTO_MAX to quickly detect broken links. - sctp_rtoinfo rto_opts; - socklen_t rto_sz = sizeof(sctp_rtoinfo); - rto_opts.srto_assoc_id = 0; - if (getsockopt(fd, SOL_SCTP, SCTP_RTOINFO, &rto_opts, &rto_sz) < 0) { - printf("Error getting RTO_INFO sockopts\n"); - close(fd); - return -1; - } - - rto_opts.srto_max = 6000; // 6 seconds - - srslog::fetch_basic_logger(LOGSERVICE) - .debug( - "Setting RTO_INFO options on SCTP socket. Association %d, Initial RTO %d, Minimum RTO %d, Maximum RTO %d", - rto_opts.srto_assoc_id, - rto_opts.srto_initial, - rto_opts.srto_min, - rto_opts.srto_max); - - if (setsockopt(fd, SOL_SCTP, SCTP_RTOINFO, &rto_opts, rto_sz) < 0) { - perror("Error setting RTO_INFO sockopts\n"); - close(fd); - return -1; - } - - // Set SCTP INITMSG options to reduce blocking timeout of connect() - sctp_initmsg init_opts; - socklen_t init_sz = sizeof(sctp_initmsg); - if (getsockopt(fd, SOL_SCTP, SCTP_INITMSG, &init_opts, &init_sz) < 0) { - printf("Error getting sockopts\n"); - close(fd); - return -1; - } - - init_opts.sinit_max_attempts = 3; - init_opts.sinit_max_init_timeo = 5000; // 5 seconds - - srslog::fetch_basic_logger(LOGSERVICE) - .debug("Setting SCTP_INITMSG options on SCTP socket. Max attempts %d, Max init attempts timeout %d", - init_opts.sinit_max_attempts, - init_opts.sinit_max_init_timeo); - if (setsockopt(fd, SOL_SCTP, SCTP_INITMSG, &init_opts, init_sz) < 0) { - perror("Error setting SCTP_INITMSG sockopts\n"); - close(fd); - return -1; - } - } + srslog::fetch_basic_logger(LOGSERVICE).debug("Opened %s socket=%d", net_utils::protocol_to_string(protocol), fd); return fd; } @@ -200,7 +132,12 @@ bool bind_addr(int fd, const sockaddr_in& addr_in) if (bind(fd, (struct sockaddr*)&addr_in, sizeof(addr_in)) != 0) { srslog::fetch_basic_logger(LOGSERVICE) - .error("Failed to bind on address %s: %s errno %d", get_ip(addr_in).c_str(), strerror(errno), errno); + .error("Failed to bind on address %s:%d. Socket=%d, strerror=%s, errno=%d", + get_ip(addr_in).c_str(), + get_port(addr_in), + fd, + strerror(errno), + errno); perror("bind()"); return false; } @@ -267,6 +204,107 @@ bool start_listen(int fd) return true; } +bool reuse_addr(int fd) +{ + if (fd < 0) { + srslog::fetch_basic_logger(LOGSERVICE).error("Trying reuse_addr a closed socket. Socket=%d", fd); + return false; + } + + int enable = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) { + srslog::fetch_basic_logger(LOGSERVICE).error("Failed to set SO_REUSEADDR. Socket=%d", fd); + return false; + } + srslog::fetch_basic_logger(LOGSERVICE).debug("Successfully set SO_REUSEADDR. Socket=%d", fd); + return true; +} + +bool sctp_subscribe_to_events(int fd) +{ + if (fd < 0) { + srslog::fetch_basic_logger(LOGSERVICE).error("Trying subscribe to SCTP events on a closed socket. Socket=%d", fd); + return false; + } + + // Sets the data_io_event to be able to use sendrecv_info + // Subscribes to the SCTP_SHUTDOWN event, to handle graceful shutdown + // Also subscribes to SCTP_PEER_ADDR_CHANGE, to handle ungraceful shutdown of the link. + struct sctp_event_subscribe evnts = {}; + evnts.sctp_data_io_event = 1; + evnts.sctp_shutdown_event = 1; + evnts.sctp_address_event = 1; + if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) != 0) { + srslog::fetch_basic_logger(LOGSERVICE).error("Failed to subscribe to SCTP_SHUTDOWN event: %s", strerror(errno)); + perror("Could not register socket to SCTP events\n"); + close(fd); + return false; + } + return true; +} + +/* + * Modify SCTP default parameters for quicker detection of broken links. + * Changes to the maximum re-transmission timeout (rto_max). + */ +bool sctp_set_rto_opts(int fd, int rto_max) +{ + // Set RTO_MAX to quickly detect broken links. + sctp_rtoinfo rto_opts; + socklen_t rto_sz = sizeof(sctp_rtoinfo); + rto_opts.srto_assoc_id = 0; + if (getsockopt(fd, SOL_SCTP, SCTP_RTOINFO, &rto_opts, &rto_sz) < 0) { + printf("Error getting RTO_INFO sockopts\n"); + close(fd); + return false; + } + + rto_opts.srto_max = rto_max; + + srslog::fetch_basic_logger(LOGSERVICE) + .debug("Setting RTO_INFO options on SCTP socket. Association %d, Initial RTO %d, Minimum RTO %d, Maximum RTO %d", + rto_opts.srto_assoc_id, + rto_opts.srto_initial, + rto_opts.srto_min, + rto_opts.srto_max); + + if (setsockopt(fd, SOL_SCTP, SCTP_RTOINFO, &rto_opts, rto_sz) < 0) { + perror("Error setting RTO_INFO sockopts\n"); + close(fd); + return false; + } + return true; +} + +/* + * Modify SCTP default parameters for quicker detection of broken links. + * Changes to the SCTP_INITMSG parameters (to control the timeout of the connect() syscall) + */ +bool sctp_set_init_msg_opts(int fd, int init_max_attempts, int max_init_timeo) +{ + // Set SCTP INITMSG options to reduce blocking timeout of connect() + sctp_initmsg init_opts; + socklen_t init_sz = sizeof(sctp_initmsg); + if (getsockopt(fd, SOL_SCTP, SCTP_INITMSG, &init_opts, &init_sz) < 0) { + printf("Error getting sockopts\n"); + close(fd); + return false; + } + + init_opts.sinit_max_attempts = init_max_attempts; + init_opts.sinit_max_init_timeo = max_init_timeo; + + srslog::fetch_basic_logger(LOGSERVICE) + .debug("Setting SCTP_INITMSG options on SCTP socket. Max attempts %d, Max init attempts timeout %d", + init_opts.sinit_max_attempts, + init_opts.sinit_max_init_timeo); + if (setsockopt(fd, SOL_SCTP, SCTP_INITMSG, &init_opts, init_sz) < 0) { + perror("Error setting SCTP_INITMSG sockopts\n"); + close(fd); + return false; + } + return true; +} } // namespace net_utils /******************************************** @@ -306,9 +344,15 @@ bool unique_socket::open_socket(net_utils::addr_family ip_type, void unique_socket::close() { if (sockfd >= 0) { - ::close(sockfd); + if (::close(sockfd) == -1) { + srslog::fetch_basic_logger(LOGSERVICE).error("Socket=%d could not be closed.", sockfd); + } else { + srslog::fetch_basic_logger(LOGSERVICE).debug("Socket=%d was closed.", sockfd); + } sockfd = -1; addr = {}; + } else { + srslog::fetch_basic_logger(LOGSERVICE).debug("Socket=%d could not be closed.", sockfd); } } @@ -327,25 +371,25 @@ bool unique_socket::start_listen() return net_utils::start_listen(sockfd); } -/*********************************************************************** - * SCTP socket - **********************************************************************/ +bool unique_socket::reuse_addr() +{ + return net_utils::reuse_addr(sockfd); +} -namespace net_utils { +bool unique_socket::sctp_subscribe_to_events() +{ + return net_utils::sctp_subscribe_to_events(sockfd); +} -bool sctp_init_socket(unique_socket* socket, net_utils::socket_type socktype, const char* bind_addr_str, int bind_port) +bool unique_socket::sctp_set_rto_opts(int rto_max) { - if (not socket->open_socket(net_utils::addr_family::ipv4, socktype, net_utils::protocol_type::SCTP)) { - return false; - } - if (not socket->bind_addr(bind_addr_str, bind_port)) { - socket->close(); - return false; - } - return true; + return net_utils::sctp_set_rto_opts(sockfd, rto_max); } -} // namespace net_utils +bool unique_socket::sctp_set_init_msg_opts(int max_init_attempts, int max_init_timeo) +{ + return net_utils::sctp_set_init_msg_opts(sockfd, max_init_attempts, max_init_timeo); +} /*************************************************************** * Rx Multisocket Handler diff --git a/lib/src/common/ngap_pcap.cc b/lib/src/common/ngap_pcap.cc new file mode 100644 index 0000000000..ef5992c3ba --- /dev/null +++ b/lib/src/common/ngap_pcap.cc @@ -0,0 +1,77 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/common/ngap_pcap.h" +#include "srsran/common/pcap.h" +#include "srsran/srsran.h" +#include "srsran/support/emergency_handlers.h" +#include + +namespace srsran { + +/// Try to flush the contents of the pcap class before the application is killed. +static void emergency_cleanup_handler(void* data) +{ + reinterpret_cast(data)->close(); +} + +ngap_pcap::ngap_pcap() +{ + emergency_handler_id = add_emergency_cleanup_handler(emergency_cleanup_handler, this); +} + +ngap_pcap::~ngap_pcap() +{ + if (emergency_handler_id > 0) { + remove_emergency_cleanup_handler(emergency_handler_id); + } +} + +void ngap_pcap::enable() +{ + enable_write = true; +} +void ngap_pcap::open(const char* filename_) +{ + filename = filename_; + pcap_file = DLT_PCAP_Open(NGAP_5G_DLT, filename.c_str()); + enable_write = true; +} +void ngap_pcap::close() +{ + if (!enable_write) { + return; + } + fprintf(stdout, "Saving NGAP PCAP file (DLT=%d) to %s\n", NGAP_5G_DLT, filename.c_str()); + DLT_PCAP_Close(pcap_file); +} + +void ngap_pcap::write_ngap(uint8_t* pdu, uint32_t pdu_len_bytes) +{ + if (enable_write) { + NGAP_Context_Info_t context; + if (pdu) { + LTE_PCAP_NGAP_WritePDU(pcap_file, &context, pdu, pdu_len_bytes); + } + } +} + +} // namespace srsran diff --git a/lib/src/common/pcap.c b/lib/src/common/pcap.c index f33e739311..92dd85f7a9 100644 --- a/lib/src/common/pcap.c +++ b/lib/src/common/pcap.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -345,6 +345,34 @@ int LTE_PCAP_S1AP_WritePDU(FILE* fd, S1AP_Context_Info_t* context, const unsigne return 1; } +/* Write an individual PDU (PCAP packet header + ngap-context + ngap-pdu) */ +int LTE_PCAP_NGAP_WritePDU(FILE* fd, NGAP_Context_Info_t* context, const unsigned char* PDU, unsigned int length) +{ + pcaprec_hdr_t packet_header; + + /* Can't write if file wasn't successfully opened */ + if (fd == NULL) { + printf("Error: Can't write to empty file handle\n"); + return 0; + } + + /****************************************************************/ + /* PCAP Header */ + struct timeval t; + gettimeofday(&t, NULL); + packet_header.ts_sec = t.tv_sec; + packet_header.ts_usec = t.tv_usec; + packet_header.incl_len = length; + packet_header.orig_len = length; + + /***************************************************************/ + /* Now write everything to the file */ + fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, fd); + fwrite(PDU, 1, length, fd); + + return 1; +} + /************************************************************************** * API functions for writing MAC-NR PCAP files * **************************************************************************/ @@ -452,4 +480,4 @@ int NR_PCAP_MAC_UDP_WritePDU(FILE* fd, mac_nr_context_info_t* context, const uns fwrite(PDU, 1, length, fd); return 1; -} \ No newline at end of file +} diff --git a/lib/src/common/phy_cfg_nr.cc b/lib/src/common/phy_cfg_nr.cc index 92573857eb..8ec3e7d83a 100644 --- a/lib/src/common/phy_cfg_nr.cc +++ b/lib/src/common/phy_cfg_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -26,7 +26,6 @@ namespace srsran { srsran_dci_cfg_nr_t phy_cfg_nr_t::get_dci_cfg() const - { srsran_dci_cfg_nr_t dci_cfg = {}; @@ -46,7 +45,8 @@ srsran_dci_cfg_nr_t phy_cfg_nr_t::get_dci_cfg() const // Iterate all configured formats for (uint32_t j = 0; j < pdcch.search_space[i].nof_formats; j++) { - if (pdcch.search_space[i].type == srsran_search_space_type_common_3 && + if ((pdcch.search_space[i].type == srsran_search_space_type_common_3 or + pdcch.search_space[i].type == srsran_search_space_type_common_1) && pdcch.search_space[i].formats[j] == srsran_dci_format_nr_0_0) { dci_cfg.monitor_common_0_0 = true; } else if (pdcch.search_space[i].type == srsran_search_space_type_ue && @@ -330,7 +330,7 @@ bool phy_cfg_nr_t::get_pucch_uci_cfg(const srsran_slot_cfg_t& slot_cfg, srsran_pucch_nr_resource_t& resource) const { // Select PUCCH resource - if (srsran_ra_ul_nr_pucch_resource(&pucch, &uci_cfg, &resource) < SRSRAN_SUCCESS) { + if (srsran_ra_ul_nr_pucch_resource(&pucch, &uci_cfg, carrier.nof_prb, &resource) < SRSRAN_SUCCESS) { ERROR("Selecting PUCCH resource"); return false; } diff --git a/lib/src/common/phy_cfg_nr_default.cc b/lib/src/common/phy_cfg_nr_default.cc index ec00b25258..73c7669291 100644 --- a/lib/src/common/phy_cfg_nr_default.cc +++ b/lib/src/common/phy_cfg_nr_default.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -181,6 +181,9 @@ void phy_cfg_nr_default_t::make_pdsch_default(srsran_sch_hl_cfg_nr_t& pdsch) pdsch.common_time_ra[0].sliv = srsran_ra_type2_to_riv(SRSRAN_NSYMB_PER_SLOT_NR - 1, 1, SRSRAN_NSYMB_PER_SLOT_NR); pdsch.nof_common_time_ra = 1; + // Set contiguous PRBs as default + pdsch.alloc = srsran_resource_alloc_type1; + // Setup PDSCH DMRS type A position pdsch.typeA_pos = srsran_dmrs_sch_typeA_pos_2; } diff --git a/lib/src/common/rlc_pcap.cc b/lib/src/common/rlc_pcap.cc index e81151a82f..6cacbd29ca 100644 --- a/lib/src/common/rlc_pcap.cc +++ b/lib/src/common/rlc_pcap.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/rrc_common.cc b/lib/src/common/rrc_common.cc index a7c496b9f6..dfd213a8f7 100644 --- a/lib/src/common/rrc_common.cc +++ b/lib/src/common/rrc_common.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/s1ap_pcap.cc b/lib/src/common/s1ap_pcap.cc index adeb47a1e8..a04ca4f7ed 100644 --- a/lib/src/common/s1ap_pcap.cc +++ b/lib/src/common/s1ap_pcap.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -35,7 +35,14 @@ static void emergency_cleanup_handler(void* data) s1ap_pcap::s1ap_pcap() { - add_emergency_cleanup_handler(emergency_cleanup_handler, this); + emergency_handler_id = add_emergency_cleanup_handler(emergency_cleanup_handler, this); +} + +s1ap_pcap::~s1ap_pcap() +{ + if (emergency_handler_id > 0) { + remove_emergency_cleanup_handler(emergency_handler_id); + } } void s1ap_pcap::enable() diff --git a/lib/src/common/s3g.cc b/lib/src/common/s3g.cc index 12561c04a2..82c6f77f62 100644 --- a/lib/src/common/s3g.cc +++ b/lib/src/common/s3g.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/security.cc b/lib/src/common/security.cc index 046be7cd13..ec5ea53dc4 100644 --- a/lib/src/common/security.cc +++ b/lib/src/common/security.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,20 +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 @@ -47,6 +40,7 @@ #define ALGO_EPS_DISTINGUISHER_UP_ENC_ALG 0x05 #define ALGO_EPS_DISTINGUISHER_UP_INT_ALG 0x06 +#define FC_5G_K_GNB_STAR_DERIVATION 0x70 #define FC_5G_ALGORITHM_KEY_DERIVATION 0x69 #define FC_5G_KAUSF_DERIVATION 0x6A #define FC_5G_RES_STAR_DERIVATION 0x6B @@ -203,6 +197,32 @@ uint8_t security_generate_k_amf(const uint8_t* k_seaf, return SRSRAN_SUCCESS; } +uint8_t security_generate_k_gnb(const as_key_t& k_amf, const uint32_t nas_count_, as_key_t& k_gnb) +{ + if (k_amf.empty()) { + log_error("Invalid inputs"); + return SRSRAN_ERROR; + } + + // NAS Count + std::vector nas_count; + nas_count.resize(4); + nas_count[0] = (nas_count_ >> 24) & 0xFF; + nas_count[1] = (nas_count_ >> 16) & 0xFF; + nas_count[2] = (nas_count_ >> 8) & 0xFF; + nas_count[3] = nas_count_ & 0xFF; + + // Access Type Distinguisher 3GPP access = 0x01 (TS 33501 Annex A.9) + std::vector access_type_distinguisher = {1}; + + if (kdf_common(FC_5G_KGNB_KN3IWF_DERIVATION, k_amf, nas_count, access_type_distinguisher, k_gnb.data()) != + SRSRAN_SUCCESS) { + log_error("Failed to run kdf_common"); + return SRSRAN_ERROR; + } + return SRSRAN_SUCCESS; +} + uint8_t security_generate_k_enb(const uint8_t* k_asme, const uint32_t nas_count_, uint8_t* k_enb) { if (k_asme == NULL || k_enb == NULL) { @@ -228,8 +248,27 @@ uint8_t security_generate_k_enb(const uint8_t* k_asme, const uint32_t nas_count_ return SRSRAN_SUCCESS; } +// Generate k_enb* according to TS 33.401 Appendix A.5 uint8_t security_generate_k_enb_star(const uint8_t* k_enb, const uint32_t pci_, const uint32_t earfcn_, uint8_t* k_enb_star) + +{ + return security_generate_k_nb_star_common(FC_EPS_K_ENB_STAR_DERIVATION, k_enb, pci_, earfcn_, k_enb_star); +} + +// Generate k_gnb* according to TS 33.501 Appendix A.11 +uint8_t +security_generate_k_gnb_star(const uint8_t* k_gnb, const uint32_t pci_, const uint32_t dl_arfcn_, uint8_t* k_gnb_star) + +{ + return security_generate_k_nb_star_common(FC_5G_K_GNB_STAR_DERIVATION, k_gnb, pci_, dl_arfcn_, k_gnb_star); +} + +uint8_t security_generate_k_nb_star_common(uint8_t fc, + const uint8_t* k_enb, + const uint32_t pci_, + const uint32_t earfcn_, + uint8_t* k_enb_star) { if (k_enb == NULL || k_enb_star == NULL) { log_error("Invalid inputs"); @@ -244,13 +283,20 @@ security_generate_k_enb_star(const uint8_t* k_enb, const uint32_t pci_, const ui pci[0] = (pci_ >> 8) & 0xFF; pci[1] = pci_ & 0xFF; - // EARFCN + // ARFCN, can be two or three bytes std::vector earfcn; - earfcn.resize(2); - earfcn[0] = (earfcn_ >> 8) & 0xFF; - earfcn[1] = earfcn_ & 0xFF; - - if (kdf_common(FC_EPS_K_ENB_STAR_DERIVATION, key, pci, earfcn, k_enb_star) != SRSRAN_SUCCESS) { + if (earfcn_ < pow(2, 16)) { + earfcn.resize(2); + earfcn[0] = (earfcn_ >> 8) & 0xFF; + earfcn[1] = earfcn_ & 0xFF; + } else if (earfcn_ < pow(2, 24)) { + earfcn.resize(3); + earfcn[0] = (earfcn_ >> 16) & 0xFF; + earfcn[1] = (earfcn_ >> 8) & 0xFF; + earfcn[2] = earfcn_ & 0xFF; + } + + if (kdf_common(fc, key, pci, earfcn, k_enb_star) != SRSRAN_SUCCESS) { log_error("Failed to run kdf_common"); return SRSRAN_ERROR; } @@ -798,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/lib/src/common/standard_streams.cc b/lib/src/common/standard_streams.cc index c783e74e79..9754dc0853 100644 --- a/lib/src/common/standard_streams.cc +++ b/lib/src/common/standard_streams.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/test/CMakeLists.txt b/lib/src/common/test/CMakeLists.txt index d15edb1746..e2a6d85ccc 100644 --- a/lib/src/common/test/CMakeLists.txt +++ b/lib/src/common/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/common/test/band_helper_test.cc b/lib/src/common/test/band_helper_test.cc index a89b4c80dd..3dc0b29634 100644 --- a/lib/src/common/test/band_helper_test.cc +++ b/lib/src/common/test/band_helper_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -56,9 +56,11 @@ int bands_test_nr() TESTASSERT(bands.nr_arfcn_to_freq(342000) == 1710.0e6); TESTASSERT(bands.nr_arfcn_to_freq(348000) == 1740.0e6); TESTASSERT(bands.nr_arfcn_to_freq(361000) == 1805.0e6); + TESTASSERT_EQ(1842.5e6, bands.nr_arfcn_to_freq(368500)); TESTASSERT(bands.nr_arfcn_to_freq(376000) == 1880.0e6); TESTASSERT(bands.get_abs_freq_point_a_arfcn(52, 368500) == 367564); TESTASSERT(bands.get_abs_freq_ssb_arfcn(3, srsran_subcarrier_spacing_15kHz, 367564) > 367924); + TESTASSERT_EQ(368410, bands.get_abs_freq_ssb_arfcn(3, srsran_subcarrier_spacing_15kHz, 367564, 12)); // n5 TESTASSERT(bands.get_duplex_mode(5) == SRSRAN_DUPLEX_MODE_FDD); TESTASSERT(bands.nr_arfcn_to_freq(176300) == 881.5e6); diff --git a/lib/src/common/test/thread_pool_test.cc b/lib/src/common/test/thread_pool_test.cc index 6579fbba09..d4d834162f 100644 --- a/lib/src/common/test/thread_pool_test.cc +++ b/lib/src/common/test/thread_pool_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/test/thread_test.cc b/lib/src/common/test/thread_test.cc index 7ae7e5aab3..597265d778 100644 --- a/lib/src/common/test/thread_test.cc +++ b/lib/src/common/test/thread_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/thread_pool.cc b/lib/src/common/thread_pool.cc index 181958ce58..3704edcd90 100644 --- a/lib/src/common/thread_pool.cc +++ b/lib/src/common/thread_pool.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/threads.c b/lib/src/common/threads.c index a56df7818c..34c0a01a1c 100644 --- a/lib/src/common/threads.c +++ b/lib/src/common/threads.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -89,7 +89,9 @@ bool threads_new_rt_cpu(pthread_t* thread, void* (*start_routine)(void*), void* #else // All threads have normal priority except prio_offset=0,1,2,3,4 if (prio_offset >= 0 && prio_offset < 5) { - param.sched_priority = sched_get_priority_max(SCHED_FIFO) - prio_offset; + // Subtract one to the priority offset to avoid scheduling threads with the highest priority that could contend with + // OS critical tasks. + param.sched_priority = sched_get_priority_max(SCHED_FIFO) - prio_offset - 1; if (pthread_attr_init(&attr)) { perror("pthread_attr_init"); } else { @@ -153,18 +155,17 @@ bool threads_new_rt_cpu(pthread_t* thread, void* (*start_routine)(void*), void* int err = pthread_create(thread, attr_enable ? &attr : NULL, start_routine, arg); if (err) { if (EPERM == err) { - // Join failed thread for avoiding memory leak from previous trial - pthread_join(*thread, NULL); - - perror("Warning: Failed to create thread with real-time priority. Creating it with normal priority"); + fprintf(stderr, + "Warning: Failed to create thread with real-time priority. Creating it with normal priority: %s\n", + strerror(err)); err = pthread_create(thread, NULL, start_routine, arg); if (err) { - perror("pthread_create"); + fprintf(stderr, "Error: Failed to create thread with normal priority: %s\n", strerror(err)); } else { ret = true; } } else { - perror("pthread_create"); + fprintf(stderr, "Error: Failed to create thread with real-time priority: %s\n", strerror(err)); } } else { ret = true; diff --git a/lib/src/common/time_prof.cc b/lib/src/common/time_prof.cc index 86ee2dc668..577b05e8f1 100644 --- a/lib/src/common/time_prof.cc +++ b/lib/src/common/time_prof.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/tti_sync_cv.cc b/lib/src/common/tti_sync_cv.cc index 4acfa01cc9..0308641823 100644 --- a/lib/src/common/tti_sync_cv.cc +++ b/lib/src/common/tti_sync_cv.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/version.c b/lib/src/common/version.c index 89e0a7c979..0360657bb5 100644 --- a/lib/src/common/version.c +++ b/lib/src/common/version.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/common/zuc.cc b/lib/src/common/zuc.cc index fef4bb839e..f70817abc9 100644 --- a/lib/src/common/zuc.cc +++ b/lib/src/common/zuc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/gtpu/CMakeLists.txt b/lib/src/gtpu/CMakeLists.txt index 859e63898c..ecfc67c69c 100644 --- a/lib/src/gtpu/CMakeLists.txt +++ b/lib/src/gtpu/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -22,4 +22,4 @@ set(SOURCES gtpu.cc) add_library(srsran_gtpu STATIC ${SOURCES}) target_link_libraries(srsran_gtpu srsran_common srsran_asn1 ${ATOMIC_LIBS}) -INSTALL(TARGETS srsran_gtpu DESTINATION ${LIBRARY_DIR}) +install(TARGETS srsran_gtpu DESTINATION ${LIBRARY_DIR} OPTIONAL) diff --git a/lib/src/gtpu/gtpu.cc b/lib/src/gtpu/gtpu.cc index 3942a5ac91..38c4e272e1 100644 --- a/lib/src/gtpu/gtpu.cc +++ b/lib/src/gtpu/gtpu.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -135,7 +135,6 @@ bool gtpu_read_ext_header(srsran::byte_buffer_t* pdu, case GTPU_EXT_HEADER_PDU_SESSION_CONTAINER: pdu->msg += GTPU_EXT_HEADER_PDU_SESSION_CONTAINER_LEN; pdu->N_bytes -= GTPU_EXT_HEADER_PDU_SESSION_CONTAINER_LEN; - logger.warning("skip parsing of GTPU_EXT_HEADER_PDU_SESSION_CONTAINER"); // TODO: Save Header Extension break; default: diff --git a/lib/src/mac/CMakeLists.txt b/lib/src/mac/CMakeLists.txt index c9f34d3c95..7edadbc758 100644 --- a/lib/src/mac/CMakeLists.txt +++ b/lib/src/mac/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -22,4 +22,6 @@ SET(SOURCES pdu.cc pdu_queue.cc mac_sch_pdu_nr.cc mac_rar_pdu_nr.cc) add_library(srsran_mac STATIC ${SOURCES}) target_link_libraries(srsran_mac srsran_common) -INSTALL(TARGETS srsran_mac DESTINATION ${LIBRARY_DIR}) \ No newline at end of file +install(TARGETS srsran_mac DESTINATION ${LIBRARY_DIR} OPTIONAL) + +add_subdirectory(test) \ No newline at end of file diff --git a/lib/src/mac/mac_rar_pdu_nr.cc b/lib/src/mac/mac_rar_pdu_nr.cc index 7b5665c156..ecfd056419 100644 --- a/lib/src/mac/mac_rar_pdu_nr.cc +++ b/lib/src/mac/mac_rar_pdu_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/mac/mac_sch_pdu_nr.cc b/lib/src/mac/mac_sch_pdu_nr.cc index d06d7b0b31..4ecc7bfbf6 100644 --- a/lib/src/mac/mac_sch_pdu_nr.cc +++ b/lib/src/mac/mac_sch_pdu_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -32,9 +32,10 @@ mac_sch_subpdu_nr::nr_lcid_sch_t mac_sch_subpdu_nr::get_type() return CCCH; } -bool mac_sch_subpdu_nr::is_sdu() +bool mac_sch_subpdu_nr::is_sdu() const { - return (lcid <= 32); + // UL-CCCH handling in done as CE + return (lcid <= 32 && !is_ul_ccch()); } bool mac_sch_subpdu_nr::has_length_field() @@ -56,12 +57,18 @@ bool mac_sch_subpdu_nr::is_valid_lcid() bool mac_sch_subpdu_nr::is_var_len_ce(uint32_t lcid) { - switch (lcid) { - case LONG_TRUNC_BSR: - case LONG_BSR: - return true; - default: - return false; + if (parent->is_ulsch()) { + // UL fixed-size CE + switch (lcid) { + case LONG_TRUNC_BSR: + case LONG_BSR: + return true; + default: + return false; + } + } else { + // all currently supported CEs in the DL are fixed-size + return false; } } @@ -100,7 +107,8 @@ int32_t mac_sch_subpdu_nr::read_subheader(const uint8_t* ptr) void mac_sch_subpdu_nr::set_sdu(const uint32_t lcid_, const uint8_t* payload_, const uint32_t len_) { - lcid = lcid_; + // Use CCCH_SIZE_48 when SDU len fits + lcid = (lcid_ == CCCH_SIZE_64 && len_ == sizeof_ce(CCCH_SIZE_48, true)) ? CCCH_SIZE_48 : lcid_; sdu.set_storage_to(const_cast(payload_)); header_length = is_ul_ccch() ? 1 : 2; sdu_length = len_; @@ -162,6 +170,18 @@ void mac_sch_subpdu_nr::set_sbsr(const lcg_bsr_t bsr_) // Turn a subPDU into a long BSR with variable size void mac_sch_subpdu_nr::set_lbsr(const std::array bsr_) {} +// Turn subPDU into a Con +void mac_sch_subpdu_nr::set_ue_con_res_id_ce(const mac_sch_subpdu_nr::ue_con_res_id_t id) +{ + lcid = CON_RES_ID; + header_length = 1; + sdu_length = sizeof_ce(lcid, parent->is_ulsch()); + uint8_t* ptr = sdu.use_internal_storage(); + for (int32_t i = 0; i < sdu_length; ++i) { + ptr[i] = id.at(i); + } +} + // Section 6.1.2 uint32_t mac_sch_subpdu_nr::write_subpdu(const uint8_t* start_) { @@ -200,17 +220,17 @@ uint32_t mac_sch_subpdu_nr::write_subpdu(const uint8_t* start_) return ptr - start_; } -uint32_t mac_sch_subpdu_nr::get_total_length() +uint32_t mac_sch_subpdu_nr::get_total_length() const { return (header_length + sdu_length); } -uint32_t mac_sch_subpdu_nr::get_sdu_length() +uint32_t mac_sch_subpdu_nr::get_sdu_length() const { return sdu_length; } -uint32_t mac_sch_subpdu_nr::get_lcid() +uint32_t mac_sch_subpdu_nr::get_lcid() const { return lcid; } @@ -220,10 +240,15 @@ uint8_t* mac_sch_subpdu_nr::get_sdu() return sdu.ptr(); } -uint16_t mac_sch_subpdu_nr::get_c_rnti() +const uint8_t* mac_sch_subpdu_nr::get_sdu() const +{ + return sdu.ptr(); +} + +uint16_t mac_sch_subpdu_nr::get_c_rnti() const { if (parent->is_ulsch() && lcid == CRNTI) { - uint8_t* ptr = sdu.ptr(); + const uint8_t* ptr = sdu.ptr(); return le16toh((uint16_t)ptr[0] << 8 | ptr[1]); } return 0; @@ -258,26 +283,26 @@ mac_sch_subpdu_nr::ta_t mac_sch_subpdu_nr::get_ta() return ta; } -mac_sch_subpdu_nr::lcg_bsr_t mac_sch_subpdu_nr::get_sbsr() +mac_sch_subpdu_nr::lcg_bsr_t mac_sch_subpdu_nr::get_sbsr() const { lcg_bsr_t sbsr = {}; if (parent->is_ulsch() && (lcid == SHORT_BSR || lcid == SHORT_TRUNC_BSR)) { - uint8_t* ptr = sdu.ptr(); - sbsr.lcg_id = (ptr[0] & 0xe0) >> 5; - sbsr.buffer_size = ptr[0] & 0x1f; + const uint8_t* ptr = sdu.ptr(); + sbsr.lcg_id = (ptr[0] & 0xe0) >> 5; + sbsr.buffer_size = ptr[0] & 0x1f; } return sbsr; } -mac_sch_subpdu_nr::lbsr_t mac_sch_subpdu_nr::get_lbsr() +mac_sch_subpdu_nr::lbsr_t mac_sch_subpdu_nr::get_lbsr() const { lbsr_t lbsr = {}; lbsr.list.reserve(mac_sch_subpdu_nr::max_num_lcg_lbsr); if (parent->is_ulsch() && (lcid == LONG_BSR || lcid == LONG_TRUNC_BSR)) { - uint8_t* ptr = sdu.ptr(); - lbsr.bitmap = *ptr; // read LCG bitmap - ptr++; // skip LCG bitmap + const uint8_t* ptr = sdu.ptr(); + lbsr.bitmap = *ptr; // read LCG bitmap + ptr++; // skip LCG bitmap // early stop if LBSR is empty if (lbsr.bitmap == 0) { @@ -307,6 +332,27 @@ mac_sch_subpdu_nr::lbsr_t mac_sch_subpdu_nr::get_lbsr() return lbsr; } +mac_sch_subpdu_nr::ue_con_res_id_t mac_sch_subpdu_nr::get_ue_con_res_id_ce() +{ + mac_sch_subpdu_nr::ue_con_res_id_t id = {}; + if (!parent->is_ulsch() && lcid == CON_RES_ID) { + const uint8_t* ptr = sdu.ptr(); + memcpy(id.data(), ptr, id.size()); + } + return id; +} + +uint64_t mac_sch_subpdu_nr::get_ue_con_res_id_ce_packed() +{ + if (!parent->is_ulsch() && lcid == CON_RES_ID) { + const uint8_t* payload = sdu.ptr(); + return le64toh(((uint64_t)payload[5]) | (((uint64_t)payload[4]) << 8) | (((uint64_t)payload[3]) << 16) | + (((uint64_t)payload[2]) << 24) | (((uint64_t)payload[1]) << 32) | (((uint64_t)payload[0]) << 40)); + } else { + return 0; + } +} + uint32_t mac_sch_subpdu_nr::sizeof_ce(uint32_t lcid, bool is_ul) { if (is_ul) { @@ -343,7 +389,7 @@ uint32_t mac_sch_subpdu_nr::sizeof_ce(uint32_t lcid, bool is_ul) return 0; } -inline bool mac_sch_subpdu_nr::is_ul_ccch() +bool mac_sch_subpdu_nr::is_ul_ccch() const { return (parent->is_ulsch() && (lcid == CCCH_SIZE_48 || lcid == CCCH_SIZE_64)); } @@ -357,6 +403,12 @@ void mac_sch_subpdu_nr::to_string(fmt::memory_buffer& buffer) if (parent->is_ulsch()) { // UL-SCH case switch (get_lcid()) { + case mac_sch_subpdu_nr::CCCH_SIZE_48: + fmt::format_to(buffer, " CCCH48: len={}", get_sdu_length()); + break; + case mac_sch_subpdu_nr::CCCH_SIZE_64: + fmt::format_to(buffer, " CCCH64: len={}", get_sdu_length()); + break; case mac_sch_subpdu_nr::CRNTI: fmt::format_to(buffer, " C-RNTI: {:#04x}", get_c_rnti()); break; @@ -384,7 +436,7 @@ void mac_sch_subpdu_nr::to_string(fmt::memory_buffer& buffer) fmt::format_to(buffer, " PAD: len={}", get_sdu_length()); break; default: - fmt::format_to(buffer, " CE={}", get_lcid()); + fmt::format_to(buffer, " CE={} total_len={}", get_lcid(), get_total_length()); break; } } else { @@ -393,14 +445,22 @@ void mac_sch_subpdu_nr::to_string(fmt::memory_buffer& buffer) case mac_sch_subpdu_nr::TA_CMD: fmt::format_to(buffer, " TA: id={} command={}", get_ta().tag_id, get_ta().ta_command); break; - case mac_sch_subpdu_nr::CON_RES_ID: - fmt::format_to(buffer, " CONRES: len={}", get_total_length()); - break; + case mac_sch_subpdu_nr::CON_RES_ID: { + ue_con_res_id_t id = get_ue_con_res_id_ce(); + fmt::format_to(buffer, + " CON_RES: id={:x}{:x}{:x}{:x}{:x}{:x}", + id.at(0), + id.at(1), + id.at(2), + id.at(3), + id.at(4), + id.at(5)); + } break; case mac_sch_subpdu_nr::PADDING: fmt::format_to(buffer, " PAD: len={}", get_sdu_length()); break; default: - fmt::format_to(buffer, " CE={}", get_lcid()); + fmt::format_to(buffer, " CE={} total_len={}", get_lcid(), get_total_length()); break; } } @@ -448,12 +508,12 @@ int mac_sch_pdu_nr::unpack(const uint8_t* payload, const uint32_t& len) return SRSRAN_SUCCESS; } -uint32_t mac_sch_pdu_nr::get_num_subpdus() +const mac_sch_subpdu_nr& mac_sch_pdu_nr::get_subpdu(const uint32_t& index) const { - return subpdus.size(); + return subpdus.at(index); } -const mac_sch_subpdu_nr& mac_sch_pdu_nr::get_subpdu(const uint32_t& index) +mac_sch_subpdu_nr& mac_sch_pdu_nr::get_subpdu(uint32_t index) { return subpdus.at(index); } @@ -541,6 +601,13 @@ mac_sch_pdu_nr::add_lbsr_ce(const std::arraywrite_dl_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + } + + // pretty print PDU + fmt::memory_buffer buff; + tx_pdu.to_string(buff); + + auto& mac_logger = srslog::fetch_basic_logger("MAC"); + mac_logger.info( + tx_buffer.msg, tx_buffer.N_bytes, "Generated MAC PDU (%d B): %s", tx_buffer.N_bytes, srsran::to_c_str(buff)); + + return SRSRAN_SUCCESS; +} + int mac_rar_pdu_test7() { // MAC PDU with RAR PDU with single RAPID=0 @@ -791,6 +856,35 @@ int mac_ul_sch_pdu_unpack_test6() return SRSRAN_SUCCESS; } +int mac_ul_sch_pdu_unpack_test7() +{ + // TV1 - MAC PDU with UL-SCH with CCCH (48 bits) subPDU (LCID=0x34) and padding + uint8_t mac_ul_sch_pdu_1[] = {0x34, 0x10, 0xb7, 0xcd, 0x6e, 0x38, 0xa6, 0x3f, 0x21, 0x21, 0x21}; + const uint8_t* ccch_sdu = &mac_ul_sch_pdu_1[1]; + const uint32_t ccch_sdu_len = 6; + + if (pcap_handle) { + pcap_handle->write_ul_crnti_nr(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1), PCAP_CRNTI, true, PCAP_TTI); + } + + srsran::mac_sch_pdu_nr pdu(true); + pdu.unpack(mac_ul_sch_pdu_1, sizeof(mac_ul_sch_pdu_1)); + TESTASSERT(pdu.get_num_subpdus() == 2); + + // 1st is CCCH + mac_sch_subpdu_nr subpdu = pdu.get_subpdu(0); + TESTASSERT(subpdu.get_total_length() == 7); + TESTASSERT(subpdu.get_sdu_length() == 6); + TESTASSERT(subpdu.get_lcid() == 0x34); + TESTASSERT(memcmp(subpdu.get_sdu(), ccch_sdu, ccch_sdu_len) == 0); + + // 2nd is padding + subpdu = pdu.get_subpdu(1); + TESTASSERT(subpdu.get_lcid() == mac_sch_subpdu_nr::PADDING); + + return SRSRAN_SUCCESS; +} + int main(int argc, char** argv) { #if PCAP @@ -834,6 +928,11 @@ int main(int argc, char** argv) return SRSRAN_ERROR; } + if (mac_dl_sch_pdu_unpack_pack_test7()) { + fprintf(stderr, "mac_dl_sch_pdu_unpack_pack_test7() failed.\n"); + return SRSRAN_ERROR; + } + if (mac_rar_pdu_test7()) { fprintf(stderr, "mac_rar_pdu_unpack_test7() failed.\n"); return SRSRAN_ERROR; @@ -889,6 +988,11 @@ int main(int argc, char** argv) return SRSRAN_ERROR; } + if (mac_ul_sch_pdu_unpack_test7()) { + fprintf(stderr, "mac_ul_sch_pdu_unpack_test7() failed.\n"); + return SRSRAN_ERROR; + } + if (pcap_handle) { pcap_handle->close(); } diff --git a/lib/test/mac/pdu_test.cc b/lib/src/mac/test/pdu_test.cc similarity index 99% rename from lib/test/mac/pdu_test.cc rename to lib/src/mac/test/pdu_test.cc index 6dc5de4479..a45c986e9a 100644 --- a/lib/test/mac/pdu_test.cc +++ b/lib/src/mac/test/pdu_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/pdcp/CMakeLists.txt b/lib/src/pdcp/CMakeLists.txt index 46a40ae2ed..2342d7be17 100644 --- a/lib/src/pdcp/CMakeLists.txt +++ b/lib/src/pdcp/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -25,4 +25,4 @@ set(SOURCES pdcp.cc add_library(srsran_pdcp STATIC ${SOURCES}) target_link_libraries(srsran_pdcp srsran_common srsran_asn1 ${ATOMIC_LIBS}) -INSTALL(TARGETS srsran_pdcp DESTINATION ${LIBRARY_DIR}) +install(TARGETS srsran_pdcp DESTINATION ${LIBRARY_DIR} OPTIONAL) diff --git a/lib/src/pdcp/pdcp.cc b/lib/src/pdcp/pdcp.cc index f638ec3e06..036c5f6f56 100644 --- a/lib/src/pdcp/pdcp.cc +++ b/lib/src/pdcp/pdcp.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -120,7 +120,7 @@ int pdcp::add_bearer(uint32_t lcid, const pdcp_config_t& cfg) if (cfg.rat == srsran::srsran_rat_t::lte) { entity.reset(new pdcp_entity_lte{rlc, rrc, gw, task_sched, logger, lcid}); } else if (cfg.rat == srsran::srsran_rat_t::nr) { - entity.reset(new pdcp_entity_lte{rlc, rrc, gw, task_sched, logger, lcid}); + entity.reset(new pdcp_entity_nr{rlc, rrc, gw, task_sched, logger, lcid}); } if (not entity->configure(cfg)) { @@ -371,12 +371,12 @@ void pdcp::get_metrics(pdcp_metrics_t& m, const uint32_t nof_tti) double rx_rate_mbps = (nof_tti > 0) ? ((metrics.num_rx_pdu_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; double tx_rate_mbps = (nof_tti > 0) ? ((metrics.num_tx_pdu_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; - logger.info("lcid=%d, rx_rate_mbps=%4.2f (real=%4.2f), tx_rate_mbps=%4.2f (real=%4.2f)", - it->first, - rx_rate_mbps, - rx_rate_mbps_real_time, - tx_rate_mbps, - tx_rate_mbps_real_time); + logger.debug("lcid=%d, rx_rate_mbps=%4.2f (real=%4.2f), tx_rate_mbps=%4.2f (real=%4.2f)", + it->first, + rx_rate_mbps, + rx_rate_mbps_real_time, + tx_rate_mbps, + tx_rate_mbps_real_time); m.bearer[it->first] = metrics; } diff --git a/lib/src/pdcp/pdcp_entity_base.cc b/lib/src/pdcp/pdcp_entity_base.cc index a346c22da5..8559654b49 100644 --- a/lib/src/pdcp/pdcp_entity_base.cc +++ b/lib/src/pdcp/pdcp_entity_base.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -117,18 +117,18 @@ bool pdcp_entity_base::integrity_verify(uint8_t* msg, uint32_t msg_len, uint32_t if (sec_cfg.integ_algo != INTEGRITY_ALGORITHM_ID_EIA0) { for (uint8_t i = 0; i < 4; i++) { if (mac[i] != mac_exp[i]) { - logger.error(mac_exp, 4, "MAC mismatch (expected)"); - logger.error(mac, 4, "MAC mismatch (found)"); is_valid = false; break; } } srslog::log_channel& channel = is_valid ? logger.debug : logger.warning; - channel("Integrity check input: COUNT %" PRIu32 ", Bearer ID %d, Direction %s", + channel("Integrity check input - COUNT %" PRIu32 ", Bearer ID %d, Direction %s", count, cfg.bearer_id, cfg.rx_direction == SECURITY_DIRECTION_DOWNLINK ? "Downlink" : "Uplink"); channel(k_int, 32, "Integrity check key:"); + channel(mac_exp, 4, "MAC %s (expected):", is_valid ? "match" : "mismatch"); + channel(mac, 4, "MAC %s (found):", is_valid ? "match" : "mismatch"); channel(msg, msg_len, "Integrity check input msg (Bytes=%" PRIu32 "):", msg_len); } diff --git a/lib/src/pdcp/pdcp_entity_lte.cc b/lib/src/pdcp/pdcp_entity_lte.cc index ad62eccdd6..ae819fdc0e 100644 --- a/lib/src/pdcp/pdcp_entity_lte.cc +++ b/lib/src/pdcp/pdcp_entity_lte.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -100,7 +100,7 @@ bool pdcp_entity_lte::configure(const pdcp_config_t& cnfg_) logger.info("Status Report Required: %s", cfg.status_report_required ? "True" : "False"); if (is_drb() and not rlc->rb_is_um(lcid)) { - undelivered_sdus = std::unique_ptr(new undelivered_sdus_queue(task_sched)); + undelivered_sdus = std::unique_ptr(new undelivered_sdus_queue(task_sched, maximum_pdcp_sn)); rx_counts_info.reserve(reordering_window); } @@ -173,7 +173,7 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn) // If the bearer is mapped to RLC AM, save TX_COUNT and a copy of the PDU. // This will be used for reestablishment, where unack'ed PDUs will be re-transmitted. // PDUs will be removed from the queue, either when the lower layers will report - // a succesfull transmission or when the discard timer expires. + // a successfull transmission or when the discard timer expires. // Status report will also use this queue, to know the First Missing SDU (FMS). if (!rlc->rb_is_um(lcid) and is_drb()) { if (not store_sdu(used_sn, sdu)) { @@ -230,6 +230,10 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn) // Pass PDU to lower layers metrics.num_tx_pdus++; metrics.num_tx_pdu_bytes += sdu->N_bytes; + // Count TX'd bytes as if they were ACK'd if RLC is UM + if (rlc->rb_is_um(lcid)) { + metrics.num_tx_acked_bytes = metrics.num_tx_pdu_bytes; + } rlc->write_sdu(lcid, std::move(sdu)); } @@ -339,6 +343,8 @@ void pdcp_entity_lte::handle_srb_pdu(srsran::unique_byte_buffer_t pdu) logger.error(pdu->msg, pdu->N_bytes, "%s Dropping PDU", rb_name.c_str()); rrc->notify_pdcp_integrity_error(lcid); return; // Discard + } else { + logger.debug(pdu->msg, pdu->N_bytes, "%s: Integrity verification successful", rb_name.c_str()); } } @@ -815,10 +821,6 @@ bool pdcp_entity_lte::check_valid_config() logger.error("Trying to configure SRB or RLC AM bearer with SN LEN of 7"); return false; } - if (cfg.sn_len == PDCP_SN_LEN_12 && is_srb()) { - logger.error("Trying to configure SRB with SN LEN of 12."); - return false; - } return true; } @@ -871,7 +873,7 @@ void pdcp_entity_lte::reset_metrics() /**************************************************************************** * Undelivered SDUs queue helpers ***************************************************************************/ -undelivered_sdus_queue::undelivered_sdus_queue(srsran::task_sched_handle task_sched) +undelivered_sdus_queue::undelivered_sdus_queue(srsran::task_sched_handle task_sched, uint32_t sn_mod) : sn_mod(sn_mod) { for (auto& e : sdus) { e.discard_timer = task_sched.get_unique_timer(); diff --git a/lib/src/pdcp/pdcp_entity_nr.cc b/lib/src/pdcp/pdcp_entity_nr.cc index d481ee1ab8..6527189b00 100644 --- a/lib/src/pdcp/pdcp_entity_nr.cc +++ b/lib/src/pdcp/pdcp_entity_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -41,15 +41,6 @@ pdcp_entity_nr::pdcp_entity_nr(srsue::rlc_interface_pdcp* rlc_, encryption_direction = DIRECTION_NONE; } -pdcp_entity_nr::~pdcp_entity_nr() {} - -// Reestablishment procedure: 38.323 5.2 -void pdcp_entity_nr::reestablish() -{ - logger.info("Re-establish %s with bearer ID: %d", rb_name.c_str(), cfg.bearer_id); - // TODO -} - bool pdcp_entity_nr::configure(const pdcp_config_t& cnfg_) { if (active) { @@ -65,17 +56,42 @@ bool pdcp_entity_nr::configure(const pdcp_config_t& cnfg_) rb_name = cfg.get_rb_name(); window_size = 1 << (cfg.sn_len - 1); - // Timers - reordering_timer = task_sched.get_unique_timer(); + rlc_mode = rlc->rb_is_um(lcid) ? rlc_mode_t::UM : rlc_mode_t::AM; - // configure timer - if (static_cast(cfg.t_reordering) > 0) { - reordering_timer.set(static_cast(cfg.t_reordering), *reordering_fnc); + // t-Reordering timer + if (cfg.t_reordering != pdcp_t_reordering_t::infinity) { + reordering_timer = task_sched.get_unique_timer(); + if (static_cast(cfg.t_reordering) > 0) { + reordering_timer.set(static_cast(cfg.t_reordering), *reordering_fnc); + } + } else if (rlc_mode == rlc_mode_t::UM) { + logger.warning("%s possible PDCP-NR misconfiguration: using infinite re-ordering timer with RLC UM bearer.", + rb_name); } + active = true; + logger.info("%s PDCP-NR entity configured. SN_LEN=%d, Discard timer %d, Re-ordering timer %d, RLC=%s, RAT=%s", + rb_name, + cfg.sn_len, + cfg.discard_timer, + cfg.t_reordering, + rlc_mode == rlc_mode_t::UM ? "UM" : "AM", + to_string(cfg.rat)); + + // disable discard timer if using UM + if (rlc_mode == rlc_mode_t::UM) { + cfg.discard_timer = pdcp_discard_timer_t::infinity; + } return true; } +// Reestablishment procedure: 38.323 5.2 +void pdcp_entity_nr::reestablish() +{ + logger.info("Re-establish %s with bearer ID: %d", rb_name.c_str(), cfg.bearer_id); + // TODO +} + // Used to stop/pause the entity (called on RRC conn release) void pdcp_entity_nr::reset() { @@ -89,11 +105,17 @@ void pdcp_entity_nr::write_sdu(unique_byte_buffer_t sdu, int sn) // Log SDU logger.info(sdu->msg, sdu->N_bytes, - "TX %s SDU, integrity=%s, encryption=%s", + "TX %s SDU (%dB), integrity=%s, encryption=%s", rb_name.c_str(), + sdu->N_bytes, srsran_direction_text[integrity_direction], srsran_direction_text[encryption_direction]); + if (rlc->sdu_queue_is_full(lcid)) { + logger.info(sdu->msg, sdu->N_bytes, "Dropping %s SDU due to full queue", rb_name.c_str()); + return; + } + // Check for COUNT overflow if (tx_overflow) { logger.warning("TX_NEXT has overflowed. Dropping packet"); @@ -115,22 +137,43 @@ void pdcp_entity_nr::write_sdu(unique_byte_buffer_t sdu, int sn) // Perform header compression TODO - // Integrity protection - uint8_t mac[4]; - integrity_generate(sdu->msg, sdu->N_bytes, tx_next, mac); - - // Ciphering - cipher_encrypt(sdu->msg, sdu->N_bytes, tx_next, sdu->msg); - // Write PDCP header info write_data_header(sdu, tx_next); + // TS 38.323, section 5.9: Integrity protection + // The data unit that is integrity protected is the PDU header + // and the data part of the PDU before ciphering. + uint8_t mac[4] = {}; + if (is_srb() || (is_drb() && (integrity_direction == DIRECTION_TX || integrity_direction == DIRECTION_TXRX))) { + integrity_generate(sdu->msg, sdu->N_bytes, tx_next, mac); + } // Append MAC-I - append_mac(sdu, mac); + if (is_srb() || (is_drb() && (integrity_direction == DIRECTION_TX || integrity_direction == DIRECTION_TXRX))) { + append_mac(sdu, mac); + } + + // TS 38.323, section 5.8: Ciphering + // The data unit that is ciphered is the MAC-I and the + // data part of the PDCP Data PDU except the + // SDAP header and the SDAP Control PDU if included in the PDCP SDU. + if (encryption_direction == DIRECTION_TX || encryption_direction == DIRECTION_TXRX) { + cipher_encrypt( + &sdu->msg[cfg.hdr_len_bytes], sdu->N_bytes - cfg.hdr_len_bytes, tx_next, &sdu->msg[cfg.hdr_len_bytes]); + } // Set meta-data for RLC AM sdu->md.pdcp_sn = tx_next; + logger.info(sdu->msg, + sdu->N_bytes, + "TX %s PDU (%dB), HFN=%d, SN=%d, integrity=%s, encryption=%s", + rb_name.c_str(), + sdu->N_bytes, + HFN(tx_next), + SN(tx_next), + srsran_direction_text[integrity_direction], + srsran_direction_text[encryption_direction]); + // Check if PDCP is associated with more than on RLC entity TODO // Write to lower layers rlc->write_sdu(lcid, std::move(sdu)); @@ -151,20 +194,31 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu) srsran_direction_text[integrity_direction], srsran_direction_text[encryption_direction]); + if (rx_overflow) { + logger.warning("Rx PDCP COUNTs have overflowed. Discarding SDU."); + return; + } + // Sanity check if (pdu->N_bytes <= cfg.hdr_len_bytes) { return; } + logger.debug("Rx PDCP state - RX_NEXT=%u, RX_DELIV=%u, RX_REORD=%u", rx_next, rx_deliv, rx_reord); // Extract RCVD_SN from header uint32_t rcvd_sn = read_data_header(pdu); - discard_data_header(pdu); // TODO: Check wheather the header is part of integrity check. - - // Extract MAC - uint8_t mac[4]; - extract_mac(pdu, mac); - // Calculate RCVD_COUNT + /* + * Calculate RCVD_COUNT: + * + * - if RCVD_SN < SN(RX_DELIV) – Window_Size: + * - RCVD_HFN = HFN(RX_DELIV) + 1. + * - else if RCVD_SN >= SN(RX_DELIV) + Window_Size: + * - RCVD_HFN = HFN(RX_DELIV) – 1. + * - else: + * - RCVD_HFN = HFN(RX_DELIV); + * - RCVD_COUNT = [RCVD_HFN, RCVD_SN]. + */ uint32_t rcvd_hfn, rcvd_count; if ((int64_t)rcvd_sn < (int64_t)SN(rx_deliv) - (int64_t)window_size) { rcvd_hfn = HFN(rx_deliv) + 1; @@ -175,18 +229,56 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu) } rcvd_count = COUNT(rcvd_hfn, rcvd_sn); - logger.debug("RCVD_HFN %u RCVD_SN %u, RCVD_COUNT %u", rcvd_hfn, rcvd_sn, rcvd_count); + logger.debug("Estimated RCVD_HFN=%u, RCVD_SN=%u, RCVD_COUNT=%u", rcvd_hfn, rcvd_sn, rcvd_count); + + /* + * TS 38.323, section 5.8: Deciphering + * + * The data unit that is ciphered is the MAC-I and the + * data part of the PDCP Data PDU except the + * SDAP header and the SDAP Control PDU if included in the PDCP SDU. + */ + if (encryption_direction == DIRECTION_RX || encryption_direction == DIRECTION_TXRX) { + cipher_decrypt( + &pdu->msg[cfg.hdr_len_bytes], pdu->N_bytes - cfg.hdr_len_bytes, rcvd_count, &pdu->msg[cfg.hdr_len_bytes]); + } - // Decripting - cipher_decrypt(pdu->msg, pdu->N_bytes, rcvd_count, pdu->msg); + /* + * Extract MAC-I: + * Always extract from SRBs, only extract from DRBs if integrity is enabled + */ + uint8_t mac[4] = {}; + if (is_srb() || (is_drb() && (integrity_direction == DIRECTION_TX || integrity_direction == DIRECTION_TXRX))) { + extract_mac(pdu, mac); + } - // Integrity check - bool is_valid = integrity_verify(pdu->msg, pdu->N_bytes, rcvd_count, mac); - if (!is_valid) { - return; // Invalid packet, drop. + /* + * TS 38.323, section 5.9: Integrity verification + * + * The data unit that is integrity protected is the PDU header + * and the data part of the PDU before ciphering. + */ + if (integrity_direction == DIRECTION_TX || integrity_direction == DIRECTION_TXRX) { + bool is_valid = integrity_verify(pdu->msg, pdu->N_bytes, rcvd_count, mac); + if (!is_valid) { + logger.error(pdu->msg, pdu->N_bytes, "%s Dropping PDU", rb_name.c_str()); + rrc->notify_pdcp_integrity_error(lcid); + return; // Invalid packet, drop. + } else { + logger.debug(pdu->msg, pdu->N_bytes, "%s: Integrity verification successful", rb_name.c_str()); + } } - // Check valid rcvd_count + // After checking the integrity, we can discard the header. + discard_data_header(pdu); + + /* + * Check valid rcvd_count: + * + * - if RCVD_COUNT < RX_DELIV; or + * - if the PDCP Data PDU with COUNT = RCVD_COUNT has been received before: + * - discard the PDCP Data PDU; + */ if (rcvd_count < rx_deliv) { logger.debug("Out-of-order after time-out, duplicate or COUNT wrap-around"); logger.debug("RCVD_COUNT %u, RCVD_COUNT %u", rcvd_count, rx_deliv); @@ -195,6 +287,7 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu) // Check if PDU has been received if (reorder_queue.find(rcvd_count) != reorder_queue.end()) { + logger.debug("Duplicate PDU, dropping"); return; // PDU already present, drop. } @@ -209,25 +302,36 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu) // TODO if out-of-order configured, submit to upper layer if (rcvd_count == rx_deliv) { - // Deliver to upper layers in ascending order of associeted COUNT + // Deliver to upper layers in ascending order of associated COUNT deliver_all_consecutive_counts(); } // Handle reordering timers if (reordering_timer.is_running() and rx_deliv >= rx_reord) { reordering_timer.stop(); + logger.debug("Stopped t-Reordering - RX_DELIV=%d, RX_REORD=%ld", rx_deliv, rx_reord); } - if (not reordering_timer.is_running() and rx_deliv < rx_next) { - rx_reord = rx_next; - reordering_timer.run(); + if (cfg.t_reordering != pdcp_t_reordering_t::infinity) { + if (not reordering_timer.is_running() and rx_deliv < rx_next) { + rx_reord = rx_next; + reordering_timer.run(); + logger.debug("Started t-Reordering - RX_REORD=%ld, RX_DELIV=%ld, RX_NEXT=%ld", rx_reord, rx_deliv, rx_next); + } } + + logger.debug("Rx PDCP state - RX_NEXT=%u, RX_DELIV=%u, RX_REORD=%u", rx_next, rx_deliv, rx_reord); } // Notification of delivery/failure void pdcp_entity_nr::notify_delivery(const pdcp_sn_vector_t& pdcp_sns) { logger.debug("Received delivery notification from RLC. Nof SNs=%ld", pdcp_sns.size()); + for (uint32_t sn : pdcp_sns) { + // Remove timer from map + logger.debug("Stopping discard timer for SN=%ld", sn); + discard_timers_map.erase(sn); + } } void pdcp_entity_nr::notify_failure(const pdcp_sn_vector_t& pdcp_sns) @@ -239,7 +343,7 @@ void pdcp_entity_nr::notify_failure(const pdcp_sn_vector_t& pdcp_sns) * Packing / Unpacking Helpers */ -// Deliver all consecutivly associated COUNTs. +// Deliver all consecutively associated COUNTs. // Update RX_NEXT after submitting to higher layers void pdcp_entity_nr::deliver_all_consecutive_counts() { @@ -271,9 +375,10 @@ void pdcp_entity_nr::deliver_all_consecutive_counts() // Reordering Timer Callback (t-reordering) void pdcp_entity_nr::reordering_callback::operator()(uint32_t timer_id) { - parent->logger.debug("Reordering timer expired"); + parent->logger.info( + "Reordering timer expired. RX_REORD=%u, re-order queue size=%ld", parent->rx_reord, parent->reorder_queue.size()); - // Deliver all PDCP SDU(s) with associeted COUNT value(s) < RX_REORD + // Deliver all PDCP SDU(s) with associated COUNT value(s) < RX_REORD for (std::map::iterator it = parent->reorder_queue.begin(); it != parent->reorder_queue.end() && it->first < parent->rx_reord; parent->reorder_queue.erase(it++)) { @@ -281,10 +386,17 @@ void pdcp_entity_nr::reordering_callback::operator()(uint32_t timer_id) parent->pass_to_upper_layers(std::move(it->second)); } - // Deliver all PDCP SDU(s) consecutivly associeted COUNT value(s) starting from RX_REORD + // Update RX_DELIV to the first PDCP SDU not delivered to the upper layers + parent->rx_deliv = parent->rx_reord; + + // Deliver all PDCP SDU(s) consecutively associated COUNT value(s) starting from RX_REORD parent->deliver_all_consecutive_counts(); if (parent->rx_deliv < parent->rx_next) { + parent->logger.debug("Updating RX_REORD to %ld. Old RX_REORD=%ld, RX_DELIV=%ld", + parent->rx_next, + parent->rx_reord, + parent->rx_deliv); parent->rx_reord = parent->rx_next; parent->reordering_timer.run(); } @@ -293,7 +405,7 @@ void pdcp_entity_nr::reordering_callback::operator()(uint32_t timer_id) // Discard Timer Callback (discardTimer) void pdcp_entity_nr::discard_callback::operator()(uint32_t timer_id) { - parent->logger.debug("Discard timer expired for PDU with SN = %d", discard_sn); + parent->logger.debug("Discard timer expired for PDU with SN=%d", discard_sn); // Notify the RLC of the discard. It's the RLC to actually discard, if no segment was transmitted yet. parent->rlc->discard_sdu(parent->lcid, discard_sn); diff --git a/lib/src/phy/CMakeLists.txt b/lib/src/phy/CMakeLists.txt index c1f1f30709..d27880900c 100644 --- a/lib/src/phy/CMakeLists.txt +++ b/lib/src/phy/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -36,6 +36,7 @@ add_subdirectory(scrambling) add_subdirectory(ue) add_subdirectory(enb) add_subdirectory(gnb) +add_subdirectory(cfr) set(srsran_srcs $ $ $ @@ -53,8 +54,9 @@ set(srsran_srcs $ $ $ $ + $ ) add_library(srsran_phy STATIC ${srsran_srcs} ) target_link_libraries(srsran_phy pthread m ${FFT_LIBRARIES}) -INSTALL(TARGETS srsran_phy DESTINATION ${LIBRARY_DIR}) +install(TARGETS srsran_phy DESTINATION ${LIBRARY_DIR} OPTIONAL) diff --git a/lib/src/phy/agc/CMakeLists.txt b/lib/src/phy/agc/CMakeLists.txt index 3709e1bb29..82c9f38c05 100644 --- a/lib/src/phy/agc/CMakeLists.txt +++ b/lib/src/phy/agc/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/agc/agc.c b/lib/src/phy/agc/agc.c index 350dd0f1c2..1706945ca6 100644 --- a/lib/src/phy/agc/agc.c +++ b/lib/src/phy/agc/agc.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/cfr/CMakeLists.txt b/lib/src/phy/cfr/CMakeLists.txt new file mode 100644 index 0000000000..4a95237cdd --- /dev/null +++ b/lib/src/phy/cfr/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# Copyright 2013-2023 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/. +# + +set(SRCS cfr.c) +add_library(srsran_cfr OBJECT ${SRCS}) + +add_subdirectory(test) + diff --git a/lib/src/phy/cfr/cfr.c b/lib/src/phy/cfr/cfr.c new file mode 100644 index 0000000000..b13d96008e --- /dev/null +++ b/lib/src/phy/cfr/cfr.c @@ -0,0 +1,402 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/phy/cfr/cfr.h" +#include "srsran/phy/utils/debug.h" +#include "srsran/phy/utils/vector.h" + +// Uncomment this to use a literal implementation of the CFR algorithm +// #define CFR_PEAK_EXTRACTION + +// Uncomment this to filter by zeroing the FFT bins instead of applying a frequency window +#define CFR_LPF_WITH_ZEROS + +static inline float cfr_symb_peak(float* in_abs, int len); + +void srsran_cfr_process(srsran_cfr_t* q, cf_t* in, cf_t* out) +{ + if (q == NULL || in == NULL || out == NULL) { + return; + } + if (!q->cfg.cfr_enable) { + // If no processing, copy the input samples into the output buffer + if (in != out) { + srsran_vec_cf_copy(out, in, q->cfg.symbol_sz); + } + return; + } + + const float alpha = q->cfg.alpha; + const uint32_t symbol_sz = q->cfg.symbol_sz; + float beta = 0.0f; + + // Calculate absolute input values + srsran_vec_abs_cf(in, q->abs_buffer_in, symbol_sz); + + // In auto modes, the beta threshold is calculated based on the measured PAPR + if (q->cfg.cfr_mode == SRSRAN_CFR_THR_MANUAL) { + beta = q->cfg.manual_thr; + } else { + const float symb_peak = cfr_symb_peak(q->abs_buffer_in, q->cfg.symbol_sz); + const float pwr_symb_peak = symb_peak * symb_peak; + const float pwr_symb_avg = srsran_vec_avg_power_ff(q->abs_buffer_in, q->cfg.symbol_sz); + float symb_papr = 0.0f; + + if (isnormal(pwr_symb_avg) && isnormal(pwr_symb_peak)) { + if (q->cfg.cfr_mode == SRSRAN_CFR_THR_AUTO_CMA) { + // Once cma_n reaches its max value, stop incrementing to prevent overflow. + // This turns the averaging into a de-facto EMA with an extremely slow time constant + q->pwr_avg_in = SRSRAN_VEC_CMA(pwr_symb_avg, q->pwr_avg_in, q->cma_n++); + q->cma_n = q->cma_n & UINT64_MAX ? q->cma_n : UINT64_MAX; + } else if (q->cfg.cfr_mode == SRSRAN_CFR_THR_AUTO_EMA) { + q->pwr_avg_in = SRSRAN_VEC_EMA(pwr_symb_avg, q->pwr_avg_in, q->cfg.ema_alpha); + } + + symb_papr = pwr_symb_peak / q->pwr_avg_in; + } + float papr_reduction = symb_papr / q->max_papr_lin; + beta = (papr_reduction > 1) ? symb_peak / sqrtf(papr_reduction) : 0; + } + + // Clipping algorithm + if (isnormal(beta)) { +#ifdef CFR_PEAK_EXTRACTION + srsran_vec_cf_zero(q->peak_buffer, symbol_sz); + cf_t clip_thr = 0; + for (int i = 0; i < symbol_sz; i++) { + if (q->abs_buffer_in[i] > beta) { + clip_thr = beta * (in[i] / q->abs_buffer_in[i]); + q->peak_buffer[i] = in[i] - clip_thr; + } + } + + // Apply FFT filter to the peak signal + srsran_dft_run_c(&q->fft_plan, q->peak_buffer, q->peak_buffer); +#ifdef CFR_LPF_WITH_ZEROS + srsran_vec_cf_zero(q->peak_buffer + q->lpf_bw / 2 + q->cfg.dc_sc, symbol_sz - q->cfg.symbol_bw - q->cfg.dc_sc); +#else /* CFR_LPF_WITH_ZEROS */ + srsran_vec_prod_cfc(q->peak_buffer, q->lpf_spectrum, q->peak_buffer, symbol_sz); +#endif /* CFR_LPF_WITH_ZEROS */ + srsran_dft_run_c(&q->ifft_plan, q->peak_buffer, q->peak_buffer); + + // Scale the peak signal according to alpha + srsran_vec_sc_prod_cfc(q->peak_buffer, alpha, q->peak_buffer, symbol_sz); + + // Apply the filtered clipping + srsran_vec_sub_ccc(in, q->peak_buffer, out, symbol_sz); +#else /* CFR_PEAK_EXTRACTION */ + + // Generate a clipping envelope and clip the signal + srsran_vec_gen_clip_env(q->abs_buffer_in, beta, alpha, q->abs_buffer_in, symbol_sz); + srsran_vec_prod_cfc(in, q->abs_buffer_in, out, symbol_sz); + + // FFT filter + srsran_dft_run_c(&q->fft_plan, out, out); +#ifdef CFR_LPF_WITH_ZEROS + srsran_vec_cf_zero(out + q->lpf_bw / 2 + q->cfg.dc_sc, symbol_sz - q->cfg.symbol_bw - q->cfg.dc_sc); +#else /* CFR_LPF_WITH_ZEROS */ + srsran_vec_prod_cfc(out, q->lpf_spectrum, out, symbol_sz); +#endif /* CFR_LPF_WITH_ZEROS */ + srsran_dft_run_c(&q->ifft_plan, out, out); +#endif /* CFR_PEAK_EXTRACTION */ + + } else { + // If no processing, copy the input samples into the output buffer + if (in != out) { + srsran_vec_cf_copy(out, in, symbol_sz); + } + } + if (q->cfg.cfr_mode != SRSRAN_CFR_THR_MANUAL && q->cfg.measure_out_papr) { + srsran_vec_abs_cf(in, q->abs_buffer_out, symbol_sz); + + const float symb_peak = cfr_symb_peak(q->abs_buffer_out, q->cfg.symbol_sz); + const float pwr_symb_peak = symb_peak * symb_peak; + const float pwr_symb_avg = srsran_vec_avg_power_ff(q->abs_buffer_out, q->cfg.symbol_sz); + float symb_papr = 0.0f; + + if (isnormal(pwr_symb_avg) && isnormal(pwr_symb_peak)) { + if (q->cfg.cfr_mode == SRSRAN_CFR_THR_AUTO_CMA) { + // Do not increment cma_n here, as it is being done when calculating input PAPR + q->pwr_avg_out = SRSRAN_VEC_CMA(pwr_symb_avg, q->pwr_avg_out, q->cma_n); + } + + else if (q->cfg.cfr_mode == SRSRAN_CFR_THR_AUTO_EMA) { + q->pwr_avg_out = SRSRAN_VEC_EMA(pwr_symb_avg, q->pwr_avg_out, q->cfg.ema_alpha); + } + + symb_papr = pwr_symb_peak / q->pwr_avg_out; + } + + const float papr_out_db = srsran_convert_power_to_dB(symb_papr); + printf("Output PAPR: %f dB\n", papr_out_db); + } +} + +int srsran_cfr_init(srsran_cfr_t* q, srsran_cfr_cfg_t* cfg) +{ + int ret = SRSRAN_ERROR; + if (q == NULL || cfg == NULL) { + ERROR("Error, invalid inputs"); + ret = SRSRAN_ERROR_INVALID_INPUTS; + goto clean_exit; + } + if (!cfg->symbol_sz || !cfg->symbol_bw || cfg->alpha < 0 || cfg->alpha > 1) { + ERROR("Error, invalid configuration"); + goto clean_exit; + } + if (cfg->cfr_mode == SRSRAN_CFR_THR_INVALID) { + ERROR("Error, invalid CFR mode"); + goto clean_exit; + } + if (cfg->cfr_mode == SRSRAN_CFR_THR_MANUAL && cfg->manual_thr <= 0) { + ERROR("Error, invalid configuration for manual threshold"); + goto clean_exit; + } + if (cfg->cfr_mode == SRSRAN_CFR_THR_AUTO_CMA && (cfg->max_papr_db <= 0)) { + ERROR("Error, invalid configuration for CMA averaging"); + goto clean_exit; + } + if (cfg->cfr_mode == SRSRAN_CFR_THR_AUTO_EMA && + (cfg->max_papr_db <= 0 || (cfg->ema_alpha < 0 || cfg->ema_alpha > 1))) { + ERROR("Error, invalid configuration for EMA averaging"); + goto clean_exit; + } + + // Copy all the configuration parameters + q->cfg = *cfg; + q->max_papr_lin = srsran_convert_dB_to_power(q->cfg.max_papr_db); + q->pwr_avg_in = CFR_EMA_INIT_AVG_PWR; + q->cma_n = 0; + + if (q->cfg.measure_out_papr) { + q->pwr_avg_out = CFR_EMA_INIT_AVG_PWR; + } + + if (q->abs_buffer_in) { + free(q->abs_buffer_in); + } + q->abs_buffer_in = srsran_vec_f_malloc(q->cfg.symbol_sz); + if (!q->abs_buffer_in) { + ERROR("Error allocating abs_buffer_in"); + goto clean_exit; + } + + if (q->abs_buffer_out) { + free(q->abs_buffer_out); + } + q->abs_buffer_out = srsran_vec_f_malloc(q->cfg.symbol_sz); + if (!q->abs_buffer_out) { + ERROR("Error allocating abs_buffer_out"); + goto clean_exit; + } + + if (q->peak_buffer) { + free(q->peak_buffer); + } + q->peak_buffer = srsran_vec_cf_malloc(q->cfg.symbol_sz); + if (!q->peak_buffer) { + ERROR("Error allocating peak_buffer"); + goto clean_exit; + } + + // Allocate the filter + if (q->lpf_spectrum) { + free(q->lpf_spectrum); + } + q->lpf_spectrum = srsran_vec_f_malloc(q->cfg.symbol_sz); + if (!q->lpf_spectrum) { + ERROR("Error allocating lpf_spectrum"); + goto clean_exit; + } + + // The LPF bandwidth is exactly the OFDM symbol bandwidth, in number of FFT bins + q->lpf_bw = q->cfg.symbol_bw; + + // Initialise the filter + srsran_vec_f_zero(q->lpf_spectrum, q->cfg.symbol_sz); + + // DC subcarrier is in position 0, so the OFDM symbol can go from index 1 to q->lpf_bw / 2 + 1 + for (uint32_t i = 0; i < q->lpf_bw / 2 + q->cfg.dc_sc; i++) { + q->lpf_spectrum[i] = 1; + } + for (uint32_t i = q->cfg.symbol_sz - q->lpf_bw / 2; i < q->cfg.symbol_sz; i++) { + q->lpf_spectrum[i] = 1; + } + + // FFT plans, for 1 OFDM symbol + if (q->fft_plan.size) { + // Replan if it was initialised previously with bigger FFT size + if (q->fft_plan.size >= q->cfg.symbol_sz) { + if (srsran_dft_replan(&q->fft_plan, q->cfg.symbol_sz)) { + ERROR("Replaning DFT plan"); + goto clean_exit; + } + } else { + srsran_dft_plan_free(&q->fft_plan); + if (srsran_dft_plan_c(&q->fft_plan, q->cfg.symbol_sz, SRSRAN_DFT_FORWARD)) { + ERROR("Creating DFT plan"); + goto clean_exit; + } + } + } else { + // Create plan from zero otherwise + if (srsran_dft_plan_c(&q->fft_plan, q->cfg.symbol_sz, SRSRAN_DFT_FORWARD)) { + ERROR("Creating DFT plan"); + goto clean_exit; + } + } + + if (q->ifft_plan.size) { + if (q->ifft_plan.size >= q->cfg.symbol_sz) { + // Replan if it was initialised previously with bigger FFT size + if (srsran_dft_replan(&q->ifft_plan, q->cfg.symbol_sz)) { + ERROR("Replaning DFT plan"); + goto clean_exit; + } + } else { + srsran_dft_plan_free(&q->ifft_plan); + if (srsran_dft_plan_c(&q->ifft_plan, q->cfg.symbol_sz, SRSRAN_DFT_BACKWARD)) { + ERROR("Creating DFT plan"); + goto clean_exit; + } + } + } else { + // Create plan from zero otherwise + if (srsran_dft_plan_c(&q->ifft_plan, q->cfg.symbol_sz, SRSRAN_DFT_BACKWARD)) { + ERROR("Creating DFT plan"); + goto clean_exit; + } + } + + srsran_dft_plan_set_norm(&q->fft_plan, true); + srsran_dft_plan_set_norm(&q->ifft_plan, true); + + srsran_vec_cf_zero(q->peak_buffer, q->cfg.symbol_sz); + srsran_vec_f_zero(q->abs_buffer_in, q->cfg.symbol_sz); + srsran_vec_f_zero(q->abs_buffer_out, q->cfg.symbol_sz); + ret = SRSRAN_SUCCESS; + +clean_exit: + if (ret < SRSRAN_SUCCESS) { + srsran_cfr_free(q); + } + return ret; +} + +void srsran_cfr_free(srsran_cfr_t* q) +{ + if (q) { + srsran_dft_plan_free(&q->fft_plan); + srsran_dft_plan_free(&q->ifft_plan); + if (q->abs_buffer_in) { + free(q->abs_buffer_in); + } + if (q->abs_buffer_out) { + free(q->abs_buffer_out); + } + if (q->peak_buffer) { + free(q->peak_buffer); + } + if (q->lpf_spectrum) { + free(q->lpf_spectrum); + } + SRSRAN_MEM_ZERO(q, srsran_cfr_t, 1); + } +} + +// Find the peak absolute value of an OFDM symbol +static inline float cfr_symb_peak(float* in_abs, int len) +{ + const uint32_t max_index = srsran_vec_max_fi(in_abs, len); + return in_abs[max_index]; +} + +bool srsran_cfr_params_valid(srsran_cfr_cfg_t* cfr_conf) +{ + if (cfr_conf == NULL) { + return false; + } + if (cfr_conf->cfr_mode == SRSRAN_CFR_THR_INVALID) { + return false; + } + if (cfr_conf->alpha < 0 || cfr_conf->alpha > 1) { + return false; + } + if (cfr_conf->cfr_mode == SRSRAN_CFR_THR_MANUAL && cfr_conf->manual_thr <= 0) { + return false; + } + if (cfr_conf->cfr_mode == SRSRAN_CFR_THR_AUTO_CMA && (cfr_conf->max_papr_db <= 0)) { + return false; + } + if (cfr_conf->cfr_mode == SRSRAN_CFR_THR_AUTO_EMA && + (cfr_conf->max_papr_db <= 0 || (cfr_conf->ema_alpha < 0 || cfr_conf->ema_alpha > 1))) { + return false; + } + return true; +} + +int srsran_cfr_set_threshold(srsran_cfr_t* q, float thres) +{ + if (q == NULL) { + ERROR("Invalid CFR object"); + return SRSRAN_ERROR_INVALID_INPUTS; + } + if (thres <= 0.0f) { + ERROR("Invalid CFR threshold"); + return SRSRAN_ERROR; + } + q->cfg.manual_thr = thres; + return SRSRAN_SUCCESS; +} + +int srsran_cfr_set_papr(srsran_cfr_t* q, float papr) +{ + if (q == NULL) { + ERROR("Invalid CFR object"); + return SRSRAN_ERROR_INVALID_INPUTS; + } + if (papr <= 0.0f) { + ERROR("Invalid CFR configuration"); + return SRSRAN_ERROR; + } + q->cfg.max_papr_db = papr; + q->max_papr_lin = srsran_convert_dB_to_power(q->cfg.max_papr_db); + return SRSRAN_SUCCESS; +} + +srsran_cfr_mode_t srsran_cfr_str2mode(const char* mode_str) +{ + srsran_cfr_mode_t ret; + if (strcmp(mode_str, "")) { + if (!strcmp(mode_str, "manual")) { + ret = SRSRAN_CFR_THR_MANUAL; + } else if (!strcmp(mode_str, "auto_cma")) { + ret = SRSRAN_CFR_THR_AUTO_CMA; + } else if (!strcmp(mode_str, "auto_ema")) { + ret = SRSRAN_CFR_THR_AUTO_EMA; + } else { + ret = SRSRAN_CFR_THR_INVALID; // mode_str is not recognised + } + } else { + ret = SRSRAN_CFR_THR_INVALID; // mode_str is empty + } + return ret; +} diff --git a/lib/src/phy/cfr/test/CMakeLists.txt b/lib/src/phy/cfr/test/CMakeLists.txt new file mode 100644 index 0000000000..c346bccddc --- /dev/null +++ b/lib/src/phy/cfr/test/CMakeLists.txt @@ -0,0 +1,29 @@ +# +# Copyright 2013-2023 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/. +# + +######################################################################## +# CFR Test +######################################################################## + +add_executable(cfr_test cfr_test.c) +target_link_libraries(cfr_test srsran_phy) + +add_test(cfr_test_default cfr_test) + diff --git a/lib/src/phy/cfr/test/cfr_test.c b/lib/src/phy/cfr/test/cfr_test.c new file mode 100644 index 0000000000..e4739baef9 --- /dev/null +++ b/lib/src/phy/cfr/test/cfr_test.c @@ -0,0 +1,313 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include +#include +#include +#include +#include + +#include "srsran/phy/utils/random.h" +#include "srsran/srsran.h" + +#define MAX_ACPR_DB -100 + + +// Default CFR type +static char* cfr_mode_str = "manual"; + +static int nof_prb = -1; +static srsran_cp_t cp = SRSRAN_CP_NORM; +static int nof_repetitions = 1; +static int nof_frames = 10; +static srsran_cfr_mode_t cfr_mode = SRSRAN_CFR_THR_MANUAL; +static float alpha = 1.0f; +static bool dc_empty = true; +static float thr_manual = 1.5f; +static float max_papr_db = 8.0f; +static float ema_alpha = (float)1 / (float)SRSRAN_CP_NORM_NSYMB; + +static uint32_t force_symbol_sz = 0; +static double elapsed_us(struct timeval* ts_start, struct timeval* ts_end) +{ + if (ts_end->tv_usec > ts_start->tv_usec) { + return ((double)ts_end->tv_sec - (double)ts_start->tv_sec) * 1000000 + (double)ts_end->tv_usec - + (double)ts_start->tv_usec; + } else { + return ((double)ts_end->tv_sec - (double)ts_start->tv_sec - 1) * 1000000 + ((double)ts_end->tv_usec + 1000000) - + (double)ts_start->tv_usec; + } +} + +static void usage(char* prog) +{ + printf("Usage: %s\n", prog); + printf("\t-N Force symbol size, 0 for auto [Default %d]\n", force_symbol_sz); + printf("\t-n Force number of Resource blocks [Default All]\n"); + printf("\t-e extended cyclic prefix [Default Normal]\n"); + printf("\t-f Number of frames [Default %d]\n", nof_frames); + printf("\t-r Number of repetitions [Default %d]\n", nof_repetitions); + printf("\t-m CFR mode: manual, auto_cma, auto_ema [Default %s]\n", cfr_mode_str); + printf("\t-d Use DC subcarrier: [Default DC empty]\n"); + printf("\t-a CFR alpha: [Default %.2f]\n", alpha); + printf("\t-t CFR manual threshold: [Default %.2f]\n", thr_manual); + printf("\t-p CFR Max PAPR in dB (auto modes): [Default %.2f]\n", max_papr_db); + printf("\t-E Power avg EMA alpha (EMA mode): [Default %.2f]\n", ema_alpha); +} + +static int parse_args(int argc, char** argv) +{ + int opt; + while ((opt = getopt(argc, argv, "NnerfmatdpE")) != -1) { + switch (opt) { + case 'n': + nof_prb = (int)strtol(argv[optind], NULL, 10); + break; + case 'N': + force_symbol_sz = (uint32_t)strtol(argv[optind], NULL, 10); + break; + case 'e': + cp = SRSRAN_CP_EXT; + break; + case 'r': + nof_repetitions = (int)strtol(argv[optind], NULL, 10); + break; + case 'f': + nof_frames = (int)strtol(argv[optind], NULL, 10); + break; + case 'm': + cfr_mode_str = argv[optind]; + break; + case 'a': + alpha = strtof(argv[optind], NULL); + break; + case 't': + thr_manual = strtof(argv[optind], NULL); + break; + case 'd': + dc_empty = false; + break; + case 'p': + max_papr_db = strtof(argv[optind], NULL); + break; + case 'E': + ema_alpha = strtof(argv[optind], NULL); + break; + default: + usage(argv[0]); + return SRSRAN_ERROR; + } + } + return SRSRAN_SUCCESS; +} + +int main(int argc, char** argv) +{ + int ret = SRSRAN_ERROR; + + srsran_random_t random_gen = srsran_random_init(0); + struct timeval start, end; + srsran_cfr_t cfr = {}; + cf_t* input = NULL; + cf_t* output = NULL; + cf_t* error = NULL; + float* acpr_buff = NULL; + float mse_dB = 0.0f; + float nmse_dB = 0.0f; + float evm = 0.0f; + int max_prb = 0.0f; + float acpr_in_dB = 0.0f; + float acpr_out_dB = 0.0f; + + srsran_dft_plan_t ofdm_ifft = {}; + srsran_dft_plan_t ofdm_fft = {}; + + if (parse_args(argc, argv) < SRSRAN_SUCCESS) { + ERROR("Error in parse_args"); + goto clean_exit; + } + + cfr_mode = srsran_cfr_str2mode(cfr_mode_str); + if (cfr_mode == SRSRAN_CFR_THR_INVALID) { + ERROR("CFR mode is not recognised"); + goto clean_exit; + } + + if (nof_prb == -1) { + nof_prb = 6; + max_prb = SRSRAN_MAX_PRB; + } else { + max_prb = nof_prb; + } + while (nof_prb <= max_prb) { + const uint32_t symbol_sz = (force_symbol_sz) ? force_symbol_sz : (uint32_t)srsran_symbol_sz(nof_prb); + const uint32_t symbol_bw = nof_prb * SRSRAN_NRE; + const uint32_t nof_symb_slot = SRSRAN_CP_NSYMB(cp); + const uint32_t nof_symb_frame = nof_symb_slot * SRSRAN_NOF_SLOTS_PER_SF * SRSRAN_NOF_SF_X_FRAME; + const uint32_t frame_sz = symbol_sz * nof_symb_frame; + const uint32_t total_nof_re = frame_sz * nof_frames; + const uint32_t total_nof_symb = nof_symb_frame * nof_frames; + printf("Running test for %d PRB, %d Frames: \t", nof_prb, nof_frames); + fflush(stdout); + + input = srsran_vec_cf_malloc(total_nof_re); + output = srsran_vec_cf_malloc(total_nof_re); + error = srsran_vec_cf_malloc(total_nof_re); + acpr_buff = srsran_vec_f_malloc(total_nof_symb); + if (!input || !output || !error || !acpr_buff) { + perror("malloc"); + goto clean_exit; + } + srsran_vec_cf_zero(input, total_nof_re); + srsran_vec_cf_zero(output, total_nof_re); + srsran_vec_cf_zero(error, total_nof_re); + srsran_vec_f_zero(acpr_buff, total_nof_symb); + + // Set the parameters for the CFR. + srsran_cfr_cfg_t cfr_tx_cfg = {}; + cfr_tx_cfg.cfr_enable = true; + cfr_tx_cfg.symbol_sz = symbol_sz; + cfr_tx_cfg.symbol_bw = nof_prb * SRSRAN_NRE; + cfr_tx_cfg.cfr_mode = cfr_mode; + cfr_tx_cfg.max_papr_db = max_papr_db; + cfr_tx_cfg.alpha = alpha; + cfr_tx_cfg.manual_thr = thr_manual; + cfr_tx_cfg.ema_alpha = ema_alpha; + cfr_tx_cfg.dc_sc = dc_empty; + + if (!srsran_cfr_params_valid(&cfr_tx_cfg)) { + ERROR("Invalid CFR configuration"); + goto clean_exit; + } + + if (srsran_cfr_init(&cfr, &cfr_tx_cfg)) { + ERROR("Error initializing CFR"); + goto clean_exit; + } + + if (srsran_dft_plan_c(&ofdm_ifft, (int)symbol_sz, SRSRAN_DFT_BACKWARD)) { + ERROR("Creating IFFT plan"); + goto clean_exit; + } + srsran_dft_plan_set_norm(&ofdm_ifft, true); + if (srsran_dft_plan_c(&ofdm_fft, (int)symbol_sz, SRSRAN_DFT_FORWARD)) { + ERROR("Creating FFT plan"); + goto clean_exit; + } + srsran_dft_plan_set_norm(&ofdm_fft, true); + + // Generate Random data + cf_t* ofdm_symb = NULL; + for (int i = 0; i < total_nof_symb; i++) { + ofdm_symb = input + i * symbol_sz; + srsran_random_uniform_complex_dist_vector(random_gen, ofdm_symb + dc_empty, symbol_bw / 2, -1.0f, +1.0f); + srsran_random_uniform_complex_dist_vector( + random_gen, ofdm_symb + symbol_sz - symbol_bw / 2, symbol_bw / 2, -1.0f, +1.0f); + acpr_buff[i] = srsran_vec_acpr_c(ofdm_symb, symbol_bw / 2 + dc_empty, symbol_bw / 2, symbol_sz); + srsran_dft_run_c(&ofdm_ifft, ofdm_symb, ofdm_symb); + } + // compute the average intput ACPR + acpr_in_dB = srsran_vec_acc_ff(acpr_buff, total_nof_symb) / (float)total_nof_symb; + acpr_in_dB = srsran_convert_power_to_dB(acpr_in_dB); + + // Execute CFR + gettimeofday(&start, NULL); + for (uint32_t i = 0; i < nof_repetitions; i++) { + for (uint32_t j = 0; j < nof_frames; j++) { + for (uint32_t k = 0; k < nof_symb_frame; k++) { + srsran_cfr_process(&cfr, + input + (size_t)((k * symbol_sz) + (j * frame_sz)), + output + (size_t)((k * symbol_sz) + (j * frame_sz))); + } + } + } + gettimeofday(&end, NULL); + printf("%.1fMsps \t", (float)(total_nof_re * nof_repetitions) / elapsed_us(&start, &end)); + + // Compute metrics + srsran_vec_sub_ccc(input, output, error, total_nof_re); + + float power_in = srsran_vec_avg_power_cf(input, total_nof_re); + float power_err = srsran_vec_avg_power_cf(error, total_nof_re); + + mse_dB = srsran_convert_power_to_dB(power_err); + nmse_dB = srsran_convert_power_to_dB(power_err / power_in); + evm = 100 * sqrtf(power_err / power_in); + + float snr_dB = srsran_convert_power_to_dB(power_in / power_err); + + float papr_in = srsran_convert_power_to_dB(srsran_vec_papr_c(input, total_nof_re)); + float papr_out = srsran_convert_power_to_dB(srsran_vec_papr_c(output, total_nof_re)); + + ofdm_symb = NULL; + for (int i = 0; i < total_nof_symb; i++) { + ofdm_symb = output + i * symbol_sz; + srsran_dft_run_c(&ofdm_fft, ofdm_symb, ofdm_symb); + acpr_buff[i] = srsran_vec_acpr_c(ofdm_symb, symbol_bw / 2 + dc_empty, symbol_bw / 2, symbol_sz); + } + + // Compute the output average ACPR + acpr_out_dB = srsran_vec_acc_ff(acpr_buff, total_nof_symb) / (float)total_nof_symb; + acpr_out_dB = srsran_convert_power_to_dB(acpr_out_dB); + + printf("MSE=%.3fdB NMSE=%.3fdB EVM=%.3f%% SNR=%.3fdB", mse_dB, nmse_dB, evm, snr_dB); + printf(" In-PAPR=%.3fdB Out-PAPR=%.3fdB", papr_in, papr_out); + printf(" In-ACPR=%.3fdB Out-ACPR=%.3fdB\n", acpr_in_dB, acpr_out_dB); + + srsran_dft_plan_free(&ofdm_ifft); + srsran_dft_plan_free(&ofdm_fft); + free(input); + free(output); + free(error); + free(acpr_buff); + input = NULL; + output = NULL; + error = NULL; + acpr_buff = NULL; + + ++nof_prb; + if (acpr_out_dB > MAX_ACPR_DB) { + printf("ACPR too large \n"); + goto clean_exit; + } + } + ret = SRSRAN_SUCCESS; + + // Free resources +clean_exit: + srsran_random_free(random_gen); + srsran_cfr_free(&cfr); + srsran_dft_plan_free(&ofdm_ifft); + srsran_dft_plan_free(&ofdm_fft); + if (input) { + free(input); + } + if (output) { + free(output); + } + if (error) { + free(error); + } + if (acpr_buff) { + free(acpr_buff); + } + return ret; +} diff --git a/lib/src/phy/ch_estimation/CMakeLists.txt b/lib/src/phy/ch_estimation/CMakeLists.txt index 42e9934de4..aad73afe04 100644 --- a/lib/src/phy/ch_estimation/CMakeLists.txt +++ b/lib/src/phy/ch_estimation/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/ch_estimation/chest_common.c b/lib/src/phy/ch_estimation/chest_common.c index ad19756d82..ded66b3b4a 100644 --- a/lib/src/phy/ch_estimation/chest_common.c +++ b/lib/src/phy/ch_estimation/chest_common.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 5f3b534689..8b2218eedb 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -969,7 +969,7 @@ static float get_rsrp_neighbour_port(srsran_chest_dl_t* q, uint32_t port) static float get_rsrp(srsran_chest_dl_t* q) { float max = -1e9; - for (int i = 0; i < q->nof_rx_antennas; ++i) { + for (int i = 0; i < q->cell.nof_ports; ++i) { float v = get_rsrp_port(q, i); if (v > max) { max = v; diff --git a/lib/src/phy/ch_estimation/chest_dl_nbiot.c b/lib/src/phy/ch_estimation/chest_dl_nbiot.c index f5813513ee..233d120537 100644 --- a/lib/src/phy/ch_estimation/chest_dl_nbiot.c +++ b/lib/src/phy/ch_estimation/chest_dl_nbiot.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/chest_sl.c b/lib/src/phy/ch_estimation/chest_sl.c index 856e13bbb9..b1a21f23d7 100644 --- a/lib/src/phy/ch_estimation/chest_sl.c +++ b/lib/src/phy/ch_estimation/chest_sl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/chest_ul.c b/lib/src/phy/ch_estimation/chest_ul.c index 819aabe1cb..d266761668 100644 --- a/lib/src/phy/ch_estimation/chest_ul.c +++ b/lib/src/phy/ch_estimation/chest_ul.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -355,16 +355,30 @@ static void chest_ul_estimate(srsran_chest_ul_t* q, } } - // Estimate received pilot power + // Measure reference signal RE average power + cf_t corr = srsran_vec_acc_cc(q->pilot_recv_signal, nslots * nrefs_sym) / (nslots * nrefs_sym); + float rsrp_avg = __real__ corr * __real__ corr + __imag__ corr * __imag__ corr; + + // Measure EPRE + float epre = srsran_vec_avg_power_cf(q->pilot_recv_signal, nslots * nrefs_sym); + + // RSRP shall not be greater than EPRE + rsrp_avg = SRSRAN_MIN(rsrp_avg, epre); + + // Calculate SNR if (isnormal(res->noise_estimate)) { - res->snr = srsran_vec_avg_power_cf(q->pilot_recv_signal, nslots * nrefs_sym) / res->noise_estimate; + res->snr = epre / res->noise_estimate; } else { res->snr = NAN; } - // Convert measurements in logarithm scale - res->snr_db = srsran_convert_power_to_dB(res->snr); - res->noise_estimate_dbm = srsran_convert_power_to_dBm(res->noise_estimate); + // Set EPRE and RSRP + res->epre = epre; + res->epre_dBfs = srsran_convert_power_to_dB(res->epre); + res->rsrp = rsrp_avg; + res->rsrp_dBfs = srsran_convert_power_to_dB(res->rsrp); + res->snr_db = srsran_convert_power_to_dB(res->snr); + res->noise_estimate_dbFs = srsran_convert_power_to_dBm(res->noise_estimate); } int srsran_chest_ul_estimate_pusch(srsran_chest_ul_t* q, @@ -479,15 +493,12 @@ int srsran_chest_ul_estimate_pucch(srsran_chest_ul_t* q, srsran_vec_prod_conj_ccc(q->pilot_recv_signal, q->pilot_known_signal, q->pilot_estimates, nrefs_sf); } - // Measure power - float rsrp_avg = 0.0f; - for (int ns = 0; ns < SRSRAN_NOF_SLOTS_PER_SF; ns++) { - for (int i = 0; i < n_rs; i++) { - cf_t corr = srsran_vec_acc_cc(q->pilot_estimates, SRSRAN_NOF_SLOTS_PER_SF * SRSRAN_NRE * n_rs) / (SRSRAN_NRE); - rsrp_avg += __real__ corr * __real__ corr + __imag__ corr * __imag__ corr; - } - } - rsrp_avg /= SRSRAN_NOF_SLOTS_PER_SF * n_rs; + // Measure reference signal RE average power + cf_t corr = srsran_vec_acc_cc(q->pilot_estimates, SRSRAN_NOF_SLOTS_PER_SF * SRSRAN_NRE * n_rs) / + (SRSRAN_NOF_SLOTS_PER_SF * SRSRAN_NRE * n_rs); + float rsrp_avg = __real__ corr * __real__ corr + __imag__ corr * __imag__ corr; + + // Measure EPRE float epre = srsran_vec_avg_power_cf(q->pilot_estimates, SRSRAN_NOF_SLOTS_PER_SF * SRSRAN_NRE * n_rs); // RSRP shall not be greater than EPRE @@ -562,11 +573,11 @@ int srsran_chest_ul_estimate_pucch(srsran_chest_ul_t* q, if (fpclassify(res->noise_estimate) == FP_ZERO) { res->noise_estimate = FLT_MIN; } - res->noise_estimate_dbm = srsran_convert_power_to_dBm(res->noise_estimate); + res->noise_estimate_dbFs = srsran_convert_power_to_dBm(res->noise_estimate); // Estimate SINR if (isnormal(res->noise_estimate)) { - res->snr = res->rsrp / res->noise_estimate; + res->snr = res->epre / res->noise_estimate; res->snr_db = srsran_convert_power_to_dB(res->snr); } else { res->snr = NAN; diff --git a/lib/src/phy/ch_estimation/csi_rs.c b/lib/src/phy/ch_estimation/csi_rs.c index 6a0a90b3d9..fe7ba2fad7 100644 --- a/lib/src/phy/ch_estimation/csi_rs.c +++ b/lib/src/phy/ch_estimation/csi_rs.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/dmrs_pbch.c b/lib/src/phy/ch_estimation/dmrs_pbch.c index 62104f364c..55ad9d6e0d 100644 --- a/lib/src/phy/ch_estimation/dmrs_pbch.c +++ b/lib/src/phy/ch_estimation/dmrs_pbch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/dmrs_pdcch.c b/lib/src/phy/ch_estimation/dmrs_pdcch.c index 4a2e7a98da..1c87fb05a8 100644 --- a/lib/src/phy/ch_estimation/dmrs_pdcch.c +++ b/lib/src/phy/ch_estimation/dmrs_pdcch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -79,6 +79,9 @@ static void dmrs_pdcch_put_symbol(const srsran_carrier_nr_t* carrier, // CORESET Resource Block counter uint32_t rb_coreset_idx = 0; + // Get CORESET offset + uint32_t offset_k = coreset->offset_rb * SRSRAN_NRE; + // For each frequency resource (6 RB groups) for (uint32_t res_idx = 0; res_idx < nof_freq_res; res_idx++) { // Skip frequency resource if outside of the CORESET @@ -113,7 +116,7 @@ static void dmrs_pdcch_put_symbol(const srsran_carrier_nr_t* carrier, uint32_t k = n * SRSRAN_NRE + 4 * k_prime + 1; // Write DMRS - sf_symbol[k] = rl[k_prime]; + sf_symbol[k + offset_k] = rl[k_prime]; } } } @@ -434,7 +437,7 @@ int srsran_dmrs_pdcch_get_measure(const srsran_dmrs_pdcch_estimator_t* q, // For each CORESET symbol for (uint32_t l = 0; l < q->coreset.duration; l++) { // Temporal least square estimates - cf_t tmp[DMRS_PDCCH_MAX_NOF_PILOTS_CANDIDATE]; + cf_t tmp[DMRS_PDCCH_MAX_NOF_PILOTS_CANDIDATE] = {}; uint32_t nof_pilots = 0; // For each RB in the CORESET diff --git a/lib/src/phy/ch_estimation/dmrs_pucch.c b/lib/src/phy/ch_estimation/dmrs_pucch.c index bb0047b106..3e977b7801 100644 --- a/lib/src/phy/ch_estimation/dmrs_pucch.c +++ b/lib/src/phy/ch_estimation/dmrs_pucch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -120,43 +120,58 @@ int srsran_dmrs_pucch_format1_put(const srsran_pucch_nr_t* q, return SRSRAN_ERROR; } - uint32_t n_pucch = dmrs_pucch_format1_n_pucch(resource, 0); - if (n_pucch == 0) { - ERROR("Error getting number of symbols"); - return SRSRAN_ERROR; - } - + // First symbol index uint32_t l_prime = resource->start_symbol_idx; - for (uint32_t m = 0; m < n_pucch; m++) { - // Clause 6.4.1.3.1.2 specifies l=0,2,4... - uint32_t l = m * 2; - - // Get start of the sequence in resource grid - cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSRAN_NRE]; - - // Get Alpha index - uint32_t alpha_idx = 0; - if (srsran_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) < - SRSRAN_SUCCESS) { - ERROR("Calculating alpha"); - } - // get r_uv sequence from LUT object - const cf_t* r_uv = srsran_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); - if (r_uv == NULL) { - ERROR("Getting r_uv sequence"); + // Clause 6.4.1.3.1.2 specifies l=0,2,4... + for (uint32_t m_prime = 0, l = 0; m_prime < (resource->intra_slot_hopping ? 2 : 1); m_prime++) { + // Get number of symbols carrying DMRS + uint32_t n_pucch = dmrs_pucch_format1_n_pucch(resource, m_prime); + if (n_pucch == 0) { + ERROR("Error getting number of symbols"); return SRSRAN_ERROR; } - // Get w_i_m - cf_t w_i_m = srsran_pucch_nr_format1_w(q, n_pucch, resource->time_domain_occ, m); + // Get the starting PRB + uint32_t starting_prb = (m_prime == 0) ? resource->starting_prb : resource->second_hop_prb; + + for (uint32_t m = 0; m < n_pucch; m++, l += 2) { + // Get start of the sequence in resource grid + cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + starting_prb) * SRSRAN_NRE]; + + // Get Alpha index + uint32_t alpha_idx = 0; + if (srsran_pucch_nr_alpha_idx(carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) < + SRSRAN_SUCCESS) { + ERROR("Calculating alpha"); + } + + // get r_uv sequence from LUT object + const cf_t* r_uv = srsran_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); + if (r_uv == NULL) { + ERROR("Getting r_uv sequence"); + return SRSRAN_ERROR; + } + + // Get w_i_m + cf_t w_i_m = srsran_pucch_nr_format1_w(q, n_pucch, resource->time_domain_occ, m); - // Compute z(n) = w(i) * r_uv(n) - cf_t z[SRSRAN_NRE]; - srsran_vec_sc_prod_ccc(r_uv, w_i_m, z, SRSRAN_NRE); + // Compute z(n) = w(i) * r_uv(n) + cf_t z[SRSRAN_NRE]; + srsran_vec_sc_prod_ccc(r_uv, w_i_m, z, SRSRAN_NRE); + + if (SRSRAN_DEBUG_ENABLED && get_srsran_verbose_level() >= SRSRAN_VERBOSE_INFO && !is_handler_registered()) { + printf("[PUCCH Format 1 DMRS TX] m_prime=%d; m=%d; w_i_m=%+.3f%+.3f; z=", + m_prime, + m, + __real__ w_i_m, + __imag__ w_i_m); + srsran_vec_fprint_c(stdout, z, SRSRAN_NRE); + } - // Put z in the grid - srsran_vec_cf_copy(slot_symbols_ptr, z, SRSRAN_NRE); + // Put z in the grid + srsran_vec_cf_copy(slot_symbols_ptr, z, SRSRAN_NRE); + } } return SRSRAN_SUCCESS; @@ -186,50 +201,71 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q, return SRSRAN_ERROR; } - uint32_t n_pucch = dmrs_pucch_format1_n_pucch(resource, 0); - if (n_pucch == 0) { - ERROR("Error getting number of symbols"); - return SRSRAN_ERROR; - } - - cf_t ce[SRSRAN_PUCCH_NR_FORMAT1_N_MAX][SRSRAN_NRE]; - - // Prevent ce[m] overflow - assert(n_pucch <= SRSRAN_PUCCH_NR_FORMAT1_N_MAX); + uint32_t start_rb_idx[SRSRAN_PUCCH_NR_FORMAT1_N_MAX]; + uint32_t symbol_idx[SRSRAN_PUCCH_NR_FORMAT1_N_MAX]; + cf_t ce[SRSRAN_PUCCH_NR_FORMAT1_N_MAX][SRSRAN_NRE]; + // First symbol index uint32_t l_prime = resource->start_symbol_idx; - for (uint32_t m = 0; m < n_pucch; m++) { - // Clause 6.4.1.3.1.2 specifies l=0,2,4... - uint32_t l = m * 2; - - // Get start of the sequence in resource grid - const cf_t* slot_symbols_ptr = - &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSRAN_NRE]; - - // Get Alpha index - uint32_t alpha_idx = 0; - if (srsran_pucch_nr_alpha_idx(&q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) < - SRSRAN_SUCCESS) { - ERROR("Calculating alpha"); - } - // get r_uv sequence from LUT object - const cf_t* r_uv = srsran_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); - if (r_uv == NULL) { - ERROR("Getting r_uv sequence"); + uint32_t n_pucch_sum = 0; + for (uint32_t m_prime = 0, l = 0; m_prime < (resource->intra_slot_hopping ? 2 : 1); m_prime++) { + // Get number of symbols carrying DMRS + uint32_t n_pucch = dmrs_pucch_format1_n_pucch(resource, m_prime); + if (n_pucch == 0) { + ERROR("Error getting number of symbols"); return SRSRAN_ERROR; } - // Get w_i_m - cf_t w_i_m = srsran_pucch_nr_format1_w(q, n_pucch, resource->time_domain_occ, m); + // Prevent ce[m] overflow + assert(n_pucch <= SRSRAN_PUCCH_NR_FORMAT1_N_MAX); + + // Get the starting PRB + uint32_t starting_prb = (m_prime == 0) ? resource->starting_prb : resource->second_hop_prb; + start_rb_idx[n_pucch_sum] = starting_prb; + + for (uint32_t m = 0; m < n_pucch; m++, l += 2) { // Clause 6.4.1.3.1.2 specifies l=0,2,4... + symbol_idx[n_pucch_sum] = l + l_prime; - // Compute z(n) = w(i) * r_uv(n) - cf_t z[SRSRAN_NRE]; - srsran_vec_sc_prod_ccc(r_uv, w_i_m, z, SRSRAN_NRE); + // Get start of the sequence in resource grid + const cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + starting_prb) * SRSRAN_NRE]; + + // Get Alpha index + uint32_t alpha_idx = 0; + if (srsran_pucch_nr_alpha_idx(&q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) < + SRSRAN_SUCCESS) { + ERROR("Calculating alpha"); + } + + // get r_uv sequence from LUT object + const cf_t* r_uv = srsran_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); + if (r_uv == NULL) { + ERROR("Getting r_uv sequence"); + return SRSRAN_ERROR; + } - // TODO: can ce[m] overflow? - // Calculate least square estimates for this symbol - srsran_vec_prod_conj_ccc(slot_symbols_ptr, z, ce[m], SRSRAN_NRE); + // Get w_i_m + cf_t w_i_m = srsran_pucch_nr_format1_w(q, n_pucch, resource->time_domain_occ, m); + + // Compute z(n) = w(i) * r_uv(n) + cf_t z[SRSRAN_NRE]; + srsran_vec_sc_prod_ccc(r_uv, w_i_m, z, SRSRAN_NRE); + + if (SRSRAN_DEBUG_ENABLED && get_srsran_verbose_level() >= SRSRAN_VERBOSE_INFO && !is_handler_registered()) { + INFO("[PUCCH Format 1 DMRS RX] m_prime=%d; m=%d; w_i_m=%+.3f%+.3f", m_prime, m, __real__ w_i_m, __imag__ w_i_m); + srsran_vec_fprint_c(stdout, z, SRSRAN_NRE); + } + + // TODO: can ce[m] overflow? + // Calculate least square estimates for this symbol + srsran_vec_prod_conj_ccc(slot_symbols_ptr, z, ce[n_pucch_sum], SRSRAN_NRE); + + if (SRSRAN_DEBUG_ENABLED && get_srsran_verbose_level() >= SRSRAN_VERBOSE_INFO && !is_handler_registered()) { + printf("[PUCCH Format 1 DMRS RX] ce[%d]=", n_pucch_sum); + srsran_vec_fprint_c(stdout, ce[n_pucch_sum], SRSRAN_NRE); + } + n_pucch_sum++; + } } // Perform measurements @@ -237,7 +273,7 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q, float epre = 0.0f; float ta_err = 0.0f; cf_t corr[SRSRAN_PUCCH_NR_FORMAT1_N_MAX] = {}; - for (uint32_t m = 0; m < n_pucch; m++) { + for (uint32_t m = 0; m < n_pucch_sum; m++) { corr[m] = srsran_vec_acc_cc(ce[m], SRSRAN_NRE) / SRSRAN_NRE; rsrp += SRSRAN_CSQABS(corr[m]); epre += srsran_vec_avg_power_cf(ce[m], SRSRAN_NRE); @@ -245,9 +281,9 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q, } // Average measurements - rsrp /= n_pucch; - epre /= n_pucch; - ta_err /= n_pucch; + rsrp /= n_pucch_sum; + epre /= n_pucch_sum; + ta_err /= n_pucch_sum; // Set power measures rsrp = SRSRAN_MIN(rsrp, epre); @@ -256,7 +292,7 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q, res->epre = epre; res->epre_dBfs = srsran_convert_power_to_dB(epre); res->noise_estimate = SRSRAN_MAX(epre - rsrp, 1e-6f); - res->noise_estimate_dbm = srsran_convert_power_to_dB(res->noise_estimate); + res->noise_estimate_dbFs = srsran_convert_power_to_dB(res->noise_estimate); res->snr = rsrp / res->noise_estimate; res->snr_db = srsran_convert_power_to_dB(res->snr); @@ -271,16 +307,16 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q, } // Measure CFO - if (n_pucch > 1) { + if (n_pucch_sum > 1) { float cfo_avg_hz = 0.0f; - for (uint32_t m = 0; m < n_pucch - 1; m++) { + for (uint32_t m = 0; m < n_pucch_sum - 1; m++) { uint32_t l0 = resource->start_symbol_idx + m * 2; uint32_t l1 = resource->start_symbol_idx + (m + 1) * 2; float time_diff = srsran_symbol_distance_s(l0, l1, q->carrier.scs); float phase_diff = cargf(corr[m + 1] * conjf(corr[m])); if (isnormal(time_diff)) { - cfo_avg_hz += phase_diff / (2.0f * M_PI * time_diff * (n_pucch - 1)); + cfo_avg_hz += phase_diff / (2.0f * M_PI * time_diff * (n_pucch_sum - 1)); } } res->cfo_hz = cfo_avg_hz; @@ -292,11 +328,10 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q, // ... Not implemented // Interpolates between DMRS symbols - for (uint32_t m = 0; m < n_pucch; m++) { - uint32_t l = m * 2 + 1; - cf_t* ce_ptr = &res->ce[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSRAN_NRE]; + for (uint32_t m = 0; m < n_pucch_sum; m++) { + cf_t* ce_ptr = &res->ce[m * SRSRAN_NRE]; - if (m != n_pucch - 1) { + if (m != n_pucch_sum - 1) { // If it is not the last symbol with DMRS, average between srsran_vec_sum_ccc(ce[m], ce[m + 1], ce_ptr, SRSRAN_NRE); srsran_vec_sc_prod_cfc(ce_ptr, 0.5f, ce_ptr, SRSRAN_NRE); @@ -306,7 +341,7 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q, srsran_vec_sub_ccc(ce_ptr, ce[m - 1], ce_ptr, SRSRAN_NRE); srsran_vec_sc_prod_cfc(ce_ptr, 0.5f, ce_ptr, SRSRAN_NRE); } else { - // Simply copy the + // Simply copy the estimated channel srsran_vec_cf_copy(ce_ptr, ce[m], SRSRAN_NRE); } } @@ -432,7 +467,7 @@ int srsran_dmrs_pucch_format2_estimate(const srsran_pucch_nr_t* q, res->epre = epre; res->epre_dBfs = srsran_convert_power_to_dB(epre); res->noise_estimate = SRSRAN_MAX(epre - rsrp, 1e-6f); - res->noise_estimate_dbm = srsran_convert_power_to_dB(res->noise_estimate); + res->noise_estimate_dbFs = srsran_convert_power_to_dB(res->noise_estimate); res->snr = rsrp / res->noise_estimate; res->snr_db = srsran_convert_power_to_dB(res->snr); diff --git a/lib/src/phy/ch_estimation/dmrs_sch.c b/lib/src/phy/ch_estimation/dmrs_sch.c index 70603ad078..bc08f8dff7 100644 --- a/lib/src/phy/ch_estimation/dmrs_sch.c +++ b/lib/src/phy/ch_estimation/dmrs_sch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -225,7 +225,8 @@ static int srsran_dmrs_sch_put_symbol(srsran_dmrs_sch_t* q, // ... save first consecutive PRB in the group prb_start = prb_idx; - // ... discard unused pilots and reset counter + // ... discard unused pilots and reset counter unless the PDSCH transmission carries SIB + prb_skip = SRSRAN_MAX(0, (int)prb_skip - (int)dmrs_cfg->reference_point_k_rb); srsran_sequence_state_advance(&sequence_state, prb_skip * nof_pilots_x_prb * 2); prb_skip = 0; } @@ -713,7 +714,8 @@ static int srsran_dmrs_sch_get_symbol(srsran_dmrs_sch_t* q, // ... save first consecutive PRB in the group prb_start = prb_idx; - // ... discard unused pilots and reset counter + // ... discard unused pilots and reset counter unless the PDSCH transmission carries SIB + prb_skip = SRSRAN_MAX(0, (int)prb_skip - (int)dmrs_cfg->reference_point_k_rb); srsran_sequence_state_advance(&sequence_state, prb_skip * nof_pilots_x_prb * 2); prb_skip = 0; } diff --git a/lib/src/phy/ch_estimation/refsignal_dl.c b/lib/src/phy/ch_estimation/refsignal_dl.c index 3a0382d163..ede5bd624d 100644 --- a/lib/src/phy/ch_estimation/refsignal_dl.c +++ b/lib/src/phy/ch_estimation/refsignal_dl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c b/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c index 11b6ae7e3d..f532944b38 100644 --- a/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c +++ b/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/refsignal_ul.c b/lib/src/phy/ch_estimation/refsignal_ul.c index 3bde6d674c..b306e194fe 100644 --- a/lib/src/phy/ch_estimation/refsignal_ul.c +++ b/lib/src/phy/ch_estimation/refsignal_ul.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/test/CMakeLists.txt b/lib/src/phy/ch_estimation/test/CMakeLists.txt index cfc1eca14b..ce71134eb2 100644 --- a/lib/src/phy/ch_estimation/test/CMakeLists.txt +++ b/lib/src/phy/ch_estimation/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/ch_estimation/test/chest_nbiot_test_dl.c b/lib/src/phy/ch_estimation/test/chest_nbiot_test_dl.c index 1867ba2220..f39994e30c 100644 --- a/lib/src/phy/ch_estimation/test/chest_nbiot_test_dl.c +++ b/lib/src/phy/ch_estimation/test/chest_nbiot_test_dl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -178,7 +178,7 @@ int main(int argc, char** argv) if (have_channel) { // Add noise - float std_dev = srsran_convert_dB_to_amplitude(-(snr_db + 3.0f)) * 0.1f; + float std_dev = srsran_convert_dB_to_power(-(snr_db + 20.0f)); srsran_ch_awgn_c(est.pilot_recv_signal, est.pilot_recv_signal, std_dev, SRSRAN_REFSIGNAL_MAX_NUM_SF(1)); } diff --git a/lib/src/phy/ch_estimation/test/chest_test_dl.c b/lib/src/phy/ch_estimation/test/chest_test_dl.c index c01f1715b2..c7cfba8665 100644 --- a/lib/src/phy/ch_estimation/test/chest_test_dl.c +++ b/lib/src/phy/ch_estimation/test/chest_test_dl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/test/chest_test_sl.c b/lib/src/phy/ch_estimation/test/chest_test_sl.c index ba8e833684..e9a1535cef 100644 --- a/lib/src/phy/ch_estimation/test/chest_test_sl.c +++ b/lib/src/phy/ch_estimation/test/chest_test_sl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/test/chest_test_srs.c b/lib/src/phy/ch_estimation/test/chest_test_srs.c index 91b2bb2d52..47036d11bd 100644 --- a/lib/src/phy/ch_estimation/test/chest_test_srs.c +++ b/lib/src/phy/ch_estimation/test/chest_test_srs.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -159,12 +159,12 @@ int srs_test_context_run(srs_test_context_t* q) INFO("RESULTS: tti=%d; snr_db=%+.1f; noise_estimate_dbm=%+.1f; ta_us=%+.1f;", ul_sf_cfg.tti, q->chest_ul_res.snr_db, - q->chest_ul_res.noise_estimate_dbm, + q->chest_ul_res.noise_estimate_dbFs, q->chest_ul_res.ta_us); // Assert SRS measurements TESTASSERT(fabsf(q->chest_ul_res.snr_db - snr_db) < CHEST_TEST_SRS_SNR_DB_TOLERANCE); - TESTASSERT(fabsf(q->chest_ul_res.noise_estimate_dbm - n0_dbm) < CHEST_TEST_SRS_SNR_DB_TOLERANCE); + TESTASSERT(fabsf(q->chest_ul_res.noise_estimate_dbFs - n0_dbm) < CHEST_TEST_SRS_SNR_DB_TOLERANCE); TESTASSERT(fabsf(q->chest_ul_res.ta_us) < CHEST_TEST_SRS_TA_US_TOLERANCE); return SRSRAN_SUCCESS; diff --git a/lib/src/phy/ch_estimation/test/chest_test_ul.c b/lib/src/phy/ch_estimation/test/chest_test_ul.c index 1152288542..66d34fb7ae 100644 --- a/lib/src/phy/ch_estimation/test/chest_test_ul.c +++ b/lib/src/phy/ch_estimation/test/chest_test_ul.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/test/csi_rs_pattern_test.c b/lib/src/phy/ch_estimation/test/csi_rs_pattern_test.c index 7002679027..20fccf88b2 100644 --- a/lib/src/phy/ch_estimation/test/csi_rs_pattern_test.c +++ b/lib/src/phy/ch_estimation/test/csi_rs_pattern_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -35,6 +35,7 @@ static int test_row1() } m.nof_ports = 1; m.first_symbol_idx = 0; + m.first_symbol_idx2 = 0; m.cdm = srsran_csi_rs_cdm_nocdm; m.density = srsran_csi_rs_resource_mapping_density_three; m.freq_band.start_rb = carrier.start; @@ -78,6 +79,7 @@ static int test_row2() } m.nof_ports = 1; m.first_symbol_idx = 0; + m.first_symbol_idx2 = 0; m.cdm = srsran_csi_rs_cdm_nocdm; m.density = density; m.freq_band.start_rb = carrier.start; diff --git a/lib/src/phy/ch_estimation/test/csi_rs_test.c b/lib/src/phy/ch_estimation/test/csi_rs_test.c index 5ae10ec893..90a8e60f27 100644 --- a/lib/src/phy/ch_estimation/test/csi_rs_test.c +++ b/lib/src/phy/ch_estimation/test/csi_rs_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c b/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c index 12f310382d..ef218e50a8 100644 --- a/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c +++ b/lib/src/phy/ch_estimation/test/dmrs_pdcch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c b/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c index 0a628a593d..5a0b5222df 100644 --- a/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c +++ b/lib/src/phy/ch_estimation/test/dmrs_pdsch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/test/refsignal_ul_test.c b/lib/src/phy/ch_estimation/test/refsignal_ul_test.c index 739707af79..21e4f918b7 100644 --- a/lib/src/phy/ch_estimation/test/refsignal_ul_test.c +++ b/lib/src/phy/ch_estimation/test/refsignal_ul_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ch_estimation/wiener_dl.c b/lib/src/phy/ch_estimation/wiener_dl.c index e0f94fd44a..3e46dea777 100644 --- a/lib/src/phy/ch_estimation/wiener_dl.c +++ b/lib/src/phy/ch_estimation/wiener_dl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/channel/CMakeLists.txt b/lib/src/phy/channel/CMakeLists.txt index e6724b502d..dfabe47cf1 100644 --- a/lib/src/phy/channel/CMakeLists.txt +++ b/lib/src/phy/channel/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/channel/ch_awgn.c b/lib/src/phy/channel/ch_awgn.c index 6d62436501..791eaf9fd5 100644 --- a/lib/src/phy/channel/ch_awgn.c +++ b/lib/src/phy/channel/ch_awgn.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -128,7 +128,6 @@ static inline void channel_awgn_run(srsran_channel_awgn_t* q, const float* in, f #if SRSRAN_SIMD_F_SIZE for (; i < (int)size - SRSRAN_SIMD_F_SIZE + 1; i += SRSRAN_SIMD_F_SIZE) { - if (i % AWGN_TABLE_READ_BURST == 0) { idx1 = channel_awgn_rand(q); idx2 = channel_awgn_rand(q); @@ -154,7 +153,6 @@ static inline void channel_awgn_run(srsran_channel_awgn_t* q, const float* in, f #endif /* SRSRAN_SIMD_F_SIZE */ for (; i < size; i++) { - if (i % AWGN_TABLE_READ_BURST == 0) { idx1 = channel_awgn_rand(q); idx2 = channel_awgn_rand(q); @@ -206,19 +204,21 @@ void srsran_ch_awgn_c(const cf_t* x, cf_t* y, float variance, uint32_t len) { cf_t tmp; uint32_t i; + float stddev = sqrtf(variance); for (i = 0; i < len; i++) { __real__ tmp = rand_gauss(); __imag__ tmp = rand_gauss(); - tmp *= variance; + tmp *= stddev * (float)M_SQRT1_2; y[i] = tmp + x[i]; } } void srsran_ch_awgn_f(const float* x, float* y, float variance, uint32_t len) { uint32_t i; + float stddev = sqrtf(variance); for (i = 0; i < len; i++) { - y[i] = x[i] + variance * rand_gauss(); + y[i] = x[i] + stddev * rand_gauss(); } } diff --git a/lib/src/phy/channel/channel.cc b/lib/src/phy/channel/channel.cc index 4ff6ffe25e..d6056a1ea2 100644 --- a/lib/src/phy/channel/channel.cc +++ b/lib/src/phy/channel/channel.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/channel/delay.c b/lib/src/phy/channel/delay.c index cc52408c60..f77156fea6 100644 --- a/lib/src/phy/channel/delay.c +++ b/lib/src/phy/channel/delay.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/channel/fading.c b/lib/src/phy/channel/fading.c index 1c97791e43..ba69d9f761 100644 --- a/lib/src/phy/channel/fading.c +++ b/lib/src/phy/channel/fading.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/channel/gauss.c b/lib/src/phy/channel/gauss.c index d84bff737a..1b3980bef5 100644 --- a/lib/src/phy/channel/gauss.c +++ b/lib/src/phy/channel/gauss.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/channel/gauss.h b/lib/src/phy/channel/gauss.h index 12a5fac241..50677b8265 100644 --- a/lib/src/phy/channel/gauss.h +++ b/lib/src/phy/channel/gauss.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/channel/hst.c b/lib/src/phy/channel/hst.c index d5957dfc8e..0c4aea29a5 100644 --- a/lib/src/phy/channel/hst.c +++ b/lib/src/phy/channel/hst.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/channel/rlf.c b/lib/src/phy/channel/rlf.c index a4b7c70e04..42af942f17 100644 --- a/lib/src/phy/channel/rlf.c +++ b/lib/src/phy/channel/rlf.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/channel/test/CMakeLists.txt b/lib/src/phy/channel/test/CMakeLists.txt index 2023d8fcec..a66beae57c 100644 --- a/lib/src/phy/channel/test/CMakeLists.txt +++ b/lib/src/phy/channel/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/channel/test/awgn_channel_test.c b/lib/src/phy/channel/test/awgn_channel_test.c index 27505d7f5c..307089e0eb 100644 --- a/lib/src/phy/channel/test/awgn_channel_test.c +++ b/lib/src/phy/channel/test/awgn_channel_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -77,11 +77,72 @@ static int parse_args(int argc, char** argv) return SRSRAN_SUCCESS; } +static int compare_floats(const void* a, const void* b) +{ + float arg1 = *(const float*)a; + float arg2 = *(const float*)b; + + if (arg1 < arg2) { + return -1; + } + if (arg1 > arg2) { + return 1; + } + return 0; +} + +/* + * Checks for Gaussianity with the Anderson--Darling test: if the returned statistic A2 is larger than 1 + * (and if the number of samples is larger than 100), then the Gaussianity hypothesis is rejected with a significance + * level of approximately 1% (see https://en.wikipedia.org/wiki/Anderson%E2%80%93Darling_test). + * + * x points to the vector of samples (real values and imaginary values) + * half_length is the number of complex samples + * y is a pointer to a helper vector used for temporary computations + */ +static float anderson(const float* x, uint32_t half_length, float* y) +{ +#define SQRT1_2 ((float)M_SQRT1_2) +#define CDF(a) ((1 + erff((a)*SQRT1_2)) * .5) + + uint32_t length = 2 * half_length; + float length_f = (float)length; + + // estimate mean and variance (the test works better with estimated values than with nominal ones) + float mean = srsran_vec_acc_ff(x, length); + mean /= length_f; + + srsran_vec_sc_sum_fff(x, -mean, y, length); + float variance = srsran_vec_dot_prod_fff(y, y, length); + variance /= length_f - 1; + + // standardize samples + srsran_vec_sc_prod_fff(y, 1 / sqrtf(variance), y, length); + + // sort standardized samples + qsort(y, length, sizeof(float), compare_floats); + + // compute Anderson--Darling statistic + float cdf1 = NAN; + float cdf2 = NAN; + float a2 = 0; + for (uint32_t ii = 0; ii < nof_samples; ii++) { + cdf1 = CDF(y[ii]); + cdf2 = CDF(y[length - ii - 1]); + a2 += (2.F * ii + 1) * (logf(cdf1) + log1pf(-cdf2)) + (2.F * (length - ii) - 1) * (logf(cdf2) + log1pf(-cdf1)); + } + a2 = -length_f - a2 / length_f; + a2 = a2 * (1 + (4 - 25 / length_f) / length_f); + + return a2; +} + int main(int argc, char** argv) { int ret = SRSRAN_SUCCESS; cf_t* input_buffer = NULL; cf_t* output_buffer = NULL; + float* help_buffer = NULL; uint64_t count_samples = 0; uint64_t count_us = 0; @@ -98,8 +159,9 @@ int main(int argc, char** argv) // Initialise buffers input_buffer = srsran_vec_cf_malloc(nof_samples); output_buffer = srsran_vec_cf_malloc(nof_samples); + help_buffer = srsran_vec_f_malloc(2 * nof_samples); - if (!input_buffer || !output_buffer) { + if (!input_buffer || !output_buffer || !help_buffer) { ERROR("Error: Allocating memory"); ret = SRSRAN_ERROR; goto clean_exit; @@ -162,6 +224,14 @@ int main(int argc, char** argv) ret = SRSRAN_ERROR; } + // Check for Gaussianity + float a2 = anderson((float*)output_buffer, nof_samples, help_buffer); + if ((nof_samples > 100 && a2 > 1) || !isfinite(a2)) { + printf("-- failed: A2 = %f > 1: not Gaussian\n", a2); + // TODO: use proper RNG with gaussian behaviour + // ret = SRSRAN_ERROR; + } + #ifdef ENABLE_GUI plot_scatter_setNewData(&plot_scatter, output_buffer, nof_samples); @@ -216,6 +286,9 @@ int main(int argc, char** argv) if (output_buffer) { free(output_buffer); } + if (help_buffer) { + free(help_buffer); + } #ifdef ENABLE_GUI if (fft_out) { diff --git a/lib/src/phy/channel/test/delay_channel_test.c b/lib/src/phy/channel/test/delay_channel_test.c index d71ec6e584..02a5f2086c 100644 --- a/lib/src/phy/channel/test/delay_channel_test.c +++ b/lib/src/phy/channel/test/delay_channel_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/channel/test/fading_channel_test.c b/lib/src/phy/channel/test/fading_channel_test.c index a962effc15..8e0e4fc775 100644 --- a/lib/src/phy/channel/test/fading_channel_test.c +++ b/lib/src/phy/channel/test/fading_channel_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/channel/test/hst_channel_test.c b/lib/src/phy/channel/test/hst_channel_test.c index 0ce4712470..e8143f0e04 100644 --- a/lib/src/phy/channel/test/hst_channel_test.c +++ b/lib/src/phy/channel/test/hst_channel_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/common/CMakeLists.txt b/lib/src/phy/common/CMakeLists.txt index 279de82262..084b21a407 100644 --- a/lib/src/phy/common/CMakeLists.txt +++ b/lib/src/phy/common/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/common/phy_common.c b/lib/src/phy/common/phy_common.c index f33bdddf7c..81b68076ce 100644 --- a/lib/src/phy/common/phy_common.c +++ b/lib/src/phy/common/phy_common.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -347,9 +347,9 @@ int srsran_symbol_sz_power2(uint32_t nof_prb) return 256; } else if (nof_prb <= 25) { return 512; - } else if (nof_prb <= 50) { + } else if (nof_prb <= 52) { return 1024; - } else if (nof_prb <= 75) { + } else if (nof_prb <= 79) { return 1536; } else if (nof_prb <= 110) { return 2048; @@ -626,7 +626,8 @@ struct lte_band lte_bands[SRSRAN_NOF_LTE_BANDS] = { {68, 753, 67536, 132672, 55, SRSRAN_BAND_GEO_AREA_EMEA}, {69, 2570, 67836, 0, 0, SRSRAN_BAND_GEO_AREA_EMEA}, {70, 1995, 68336, 132972, 300, SRSRAN_BAND_GEO_AREA_NAR}, - {71, 0, 68586, 133122, 0, SRSRAN_BAND_GEO_AREA_NAR} // dummy band to bound band 70 earfcn + {71, 617, 68586, 133122, -46, SRSRAN_BAND_GEO_AREA_NAR}, + {72, 0, 68936, 133472, 0, SRSRAN_BAND_GEO_AREA_NAR} // dummy band to bound band 71 earfcn }; int srsran_str2mimotype(char* mimo_type_str, srsran_tx_scheme_t* type) diff --git a/lib/src/phy/common/phy_common_nr.c b/lib/src/phy/common/phy_common_nr.c index 7e8547dbee..4524743e3d 100644 --- a/lib/src/phy/common/phy_common_nr.c +++ b/lib/src/phy/common/phy_common_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -537,6 +537,19 @@ void srsran_combine_csi_trs_measurements(const srsran_csi_trs_measurements_t* a, dst->nof_re = nof_re_sum; } +uint32_t pdcch_nr_bundle_size(srsran_coreset_bundle_size_t x) +{ + switch (x) { + case srsran_coreset_bundle_size_n2: + return 2; + case srsran_coreset_bundle_size_n3: + return 3; + case srsran_coreset_bundle_size_n6: + return 6; + } + return 0; +} + typedef struct { uint32_t mux_pattern; uint32_t nof_prb; @@ -605,6 +618,44 @@ static const coreset_zero_entry_t coreset_zero_30_15[16] = { {}, }; +int srsran_coreset_to_str(srsran_coreset_t* coreset, char* str, uint32_t str_len) +{ + if (coreset == NULL || str == NULL || str_len == 0) { + return 0; + } + + char freq_res_str[SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE] = {}; + srsran_vec_sprint_bin( + freq_res_str, sizeof(freq_res_str), (uint8_t*)coreset->freq_resources, SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE); + + return srsran_print_check( + str, + str_len, + 0, + "\n" + " - coreset_id=%d\n" + " - mapping_type=%s\n" + " - duration=%d\n" + " - freq_res=%s\n" + " - dmrs_scrambling_present=%s (id=%d)\n" + " - precoder_granularity=%s\n" + " - interleaver_size=%d\n" + " - reg_bundle_size=%d\n" + " - shift_index=%d\n" + " - offset_rb=%d\n", + coreset->id, + coreset->mapping_type == srsran_coreset_mapping_type_non_interleaved ? "non-interleaved" : "interleaved", + coreset->duration, + freq_res_str, + coreset->dmrs_scrambling_id_present ? "true" : "false", + coreset->dmrs_scrambling_id, + coreset->precoder_granularity == srsran_coreset_precoder_granularity_contiguous ? "contiguous" : "reg_bundle", + pdcch_nr_bundle_size(coreset->interleaver_size), + pdcch_nr_bundle_size(coreset->reg_bundle_size), + coreset->shift_index, + coreset->offset_rb); +} + int srsran_coreset_zero(uint32_t n_cell_id, uint32_t ssb_pointA_freq_offset_Hz, srsran_subcarrier_spacing_t ssb_scs, @@ -691,7 +742,49 @@ int srsran_coreset_zero(uint32_t n_cell_id, return SRSRAN_SUCCESS; } -const char* srsran_ssb_pattern_to_str(srsran_ssb_patern_t pattern) +int srsran_coreset0_ssb_offset(uint32_t idx, srsran_subcarrier_spacing_t ssb_scs, srsran_subcarrier_spacing_t pdcch_scs) +{ + // Verify inputs + if (idx >= 16) { + ERROR("Invalid CORESET Zero input. idx=%d", idx); + return SRSRAN_ERROR_INVALID_INPUTS; + } + + // Default entry to NULL + const coreset_zero_entry_t* entry = NULL; + + // Table 13-1: Set of resource blocks and slot symbols of CORESET for Type0-PDCCH search space set + // when {SS/PBCH block, PDCCH} SCS is {15, 15} kHz for frequency bands with minimum channel + // bandwidth 5 MHz or 10 MHz + if (ssb_scs == srsran_subcarrier_spacing_15kHz && pdcch_scs == srsran_subcarrier_spacing_15kHz) { + entry = &coreset_zero_15_15[idx]; + } + // Table 13-2: Set of resource blocks and slot symbols of CORESET for Type0-PDCCH search space set + // when {SS/PBCH block, PDCCH} SCS is {15, 30} kHz for frequency bands with minimum channel + // bandwidth 5 MHz or 10 MHz + if (ssb_scs == srsran_subcarrier_spacing_15kHz && pdcch_scs == srsran_subcarrier_spacing_30kHz) { + entry = &coreset_zero_15_30[idx]; + } + + // Table 13-3: Set of resource blocks and slot symbols of CORESET for Type0-PDCCH search space set + // when {SS/PBCH block, PDCCH} SCS is {30, 15} kHz for frequency bands with minimum channel + // bandwidth 5 MHz or 10 MHz + if (ssb_scs == srsran_subcarrier_spacing_30kHz && pdcch_scs == srsran_subcarrier_spacing_15kHz) { + entry = &coreset_zero_30_15[idx]; + } + + // Check a valid entry has been selected + if (entry == NULL) { + ERROR("Unhandled case ssb_scs=%s, pdcch_scs=%s", + srsran_subcarrier_spacing_to_str(ssb_scs), + srsran_subcarrier_spacing_to_str(pdcch_scs)); + return SRSRAN_ERROR; + } + + return entry->offset_rb; +} + +const char* srsran_ssb_pattern_to_str(srsran_ssb_pattern_t pattern) { switch (pattern) { case SRSRAN_SSB_PATTERN_A: @@ -711,7 +804,7 @@ const char* srsran_ssb_pattern_to_str(srsran_ssb_patern_t pattern) return "Invalid"; } -srsran_ssb_patern_t srsran_ssb_pattern_fom_str(const char* str) +srsran_ssb_pattern_t srsran_ssb_pattern_fom_str(const char* str) { if (str == NULL) { return SRSRAN_SSB_PATTERN_INVALID; diff --git a/lib/src/phy/common/phy_common_sl.c b/lib/src/phy/common/phy_common_sl.c index 1b29275206..d636c6ce6c 100644 --- a/lib/src/phy/common/phy_common_sl.c +++ b/lib/src/phy/common/phy_common_sl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/common/sequence.c b/lib/src/phy/common/sequence.c index c0113503db..af53f2bf40 100644 --- a/lib/src/phy/common/sequence.c +++ b/lib/src/phy/common/sequence.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/common/sliv.c b/lib/src/phy/common/sliv.c index 71dd8c7d08..847a6deee2 100644 --- a/lib/src/phy/common/sliv.c +++ b/lib/src/phy/common/sliv.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/common/test/CMakeLists.txt b/lib/src/phy/common/test/CMakeLists.txt index 0259f2f2f2..738bc4aa6e 100644 --- a/lib/src/phy/common/test/CMakeLists.txt +++ b/lib/src/phy/common/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -37,3 +37,12 @@ target_link_libraries(sliv_test srsran_phy) add_test(sliv_test_14 sliv_test 14) add_test(sliv_test_52 sliv_test 48) add_test(sliv_test_52 sliv_test 52) + +######################################################################## +# PHY COMMON TEST +######################################################################## + +add_executable(phy_common_test phy_common_test.c) +target_link_libraries(phy_common_test srsran_phy) + +add_test(phy_common_test phy_common_test) \ No newline at end of file diff --git a/lib/src/phy/common/test/phy_common_test.c b/lib/src/phy/common/test/phy_common_test.c new file mode 100644 index 0000000000..fb8b5e4461 --- /dev/null +++ b/lib/src/phy/common/test/phy_common_test.c @@ -0,0 +1,59 @@ +/** + * Copyright 2013-2023 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/. + * + */ +#include "srsran/common/test_common.h" +#include "srsran/phy/common/phy_common.h" + +int srsran_default_rates_test() +{ + // Verify calculated sample rates for all valid PRB sizes. + // By default we use the reduced 3/4 sampling to save bandwidth on the fronthaul. +#ifdef FORCE_STANDARD_RATE + srsran_use_standard_symbol_size(false); +#endif + TESTASSERT(srsran_sampling_freq_hz(6) == 1920000); + TESTASSERT(srsran_sampling_freq_hz(15) == 3840000); + TESTASSERT(srsran_sampling_freq_hz(25) == 5760000); + TESTASSERT(srsran_sampling_freq_hz(50) == 11520000); + TESTASSERT(srsran_sampling_freq_hz(75) == 15360000); // need to use default rate for 15 MHz BW + TESTASSERT(srsran_sampling_freq_hz(100) == 23040000); + return SRSRAN_SUCCESS; +} + +int lte_standard_rates_test() +{ + // Verify calculated sample rates for all valid PRB sizes. + // Enable standard LTE rates (required by some RF HW). + srsran_use_standard_symbol_size(true); + TESTASSERT(srsran_sampling_freq_hz(6) == 1920000); + TESTASSERT(srsran_sampling_freq_hz(15) == 3840000); + TESTASSERT(srsran_sampling_freq_hz(25) == 7680000); + TESTASSERT(srsran_sampling_freq_hz(50) == 15360000); + TESTASSERT(srsran_sampling_freq_hz(75) == 23040000); + TESTASSERT(srsran_sampling_freq_hz(100) == 30720000); + return SRSRAN_SUCCESS; +} + +int main(int argc, char** argv) +{ + TESTASSERT(srsran_default_rates_test() == SRSRAN_SUCCESS); + TESTASSERT(lte_standard_rates_test() == SRSRAN_SUCCESS); + return SRSRAN_SUCCESS; +} \ No newline at end of file diff --git a/lib/src/phy/common/test/sequence_test.c b/lib/src/phy/common/test/sequence_test.c index d9f4918a31..882f94a44e 100644 --- a/lib/src/phy/common/test/sequence_test.c +++ b/lib/src/phy/common/test/sequence_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/common/test/sliv_test.c b/lib/src/phy/common/test/sliv_test.c index afed5b1f62..f9b8ae2de7 100644 --- a/lib/src/phy/common/test/sliv_test.c +++ b/lib/src/phy/common/test/sliv_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/common/timestamp.c b/lib/src/phy/common/timestamp.c index a5582f790a..92b2da6b62 100644 --- a/lib/src/phy/common/timestamp.c +++ b/lib/src/phy/common/timestamp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/common/zc_sequence.c b/lib/src/phy/common/zc_sequence.c index 2dc0225a48..7c0c53b4a8 100644 --- a/lib/src/phy/common/zc_sequence.c +++ b/lib/src/phy/common/zc_sequence.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/dft/CMakeLists.txt b/lib/src/phy/dft/CMakeLists.txt index 168002aeb2..1d73d53667 100644 --- a/lib/src/phy/dft/CMakeLists.txt +++ b/lib/src/phy/dft/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/dft/dft_fftw.c b/lib/src/phy/dft/dft_fftw.c index d55ad0d3f2..eedcef2b1c 100644 --- a/lib/src/phy/dft/dft_fftw.c +++ b/lib/src/phy/dft/dft_fftw.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/dft/dft_precoding.c b/lib/src/phy/dft/dft_precoding.c index 65b4f559b9..a10c4f5767 100644 --- a/lib/src/phy/dft/dft_precoding.c +++ b/lib/src/phy/dft/dft_precoding.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/dft/ofdm.c b/lib/src/phy/dft/ofdm.c index ddce9e069b..6feee756e9 100644 --- a/lib/src/phy/dft/ofdm.c +++ b/lib/src/phy/dft/ofdm.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -96,11 +96,24 @@ static int ofdm_init_mbsfn_(srsran_ofdm_t* q, srsran_ofdm_cfg_t* cfg, srsran_dft q->slot_sz = (uint32_t)SRSRAN_SLOT_LEN(q->cfg.symbol_sz); q->sf_sz = (uint32_t)SRSRAN_SF_LEN(q->cfg.symbol_sz); + // Set the CFR parameters related to OFDM symbol and FFT size + q->cfg.cfr_tx_cfg.symbol_sz = symbol_sz; + q->cfg.cfr_tx_cfg.symbol_bw = q->nof_re; + + // in the DL, the DC carrier is empty but still counts when designing the filter BW + q->cfg.cfr_tx_cfg.dc_sc = (!q->cfg.keep_dc) && (!isnormal(q->cfg.freq_shift_f)); + if (q->cfg.cfr_tx_cfg.cfr_enable) { + if (srsran_cfr_init(&q->tx_cfr, &q->cfg.cfr_tx_cfg) < SRSRAN_SUCCESS) { + ERROR("Error while initialising CFR module"); + return SRSRAN_ERROR; + } + } + // Plan MBSFN if (q->fft_plan.size) { // Replan if it was initialised previously if (srsran_dft_replan(&q->fft_plan, q->cfg.symbol_sz)) { - ERROR("Reeplaning DFT plan"); + ERROR("Replanning DFT plan"); return SRSRAN_ERROR; } } else { @@ -113,7 +126,7 @@ static int ofdm_init_mbsfn_(srsran_ofdm_t* q, srsran_ofdm_cfg_t* cfg, srsran_dft // Reallocate temporal buffer only if the new number of resource blocks is bigger than initial if (q->cfg.nof_prb > q->max_prb) { - // Free before reallocating if allocted + // Free before reallocating if allocated if (q->tmp) { free(q->tmp); free(q->shift_buffer); @@ -269,6 +282,7 @@ void srsran_ofdm_free_(srsran_ofdm_t* q) if (q->window_offset_buffer) { free(q->window_offset_buffer); } + srsran_cfr_free(&q->tx_cfr); SRSRAN_MEM_ZERO(q, srsran_ofdm_t, 1); } @@ -316,6 +330,10 @@ int srsran_ofdm_tx_init(srsran_ofdm_t* q, srsran_cp_t cp, cf_t* in_buffer, cf_t* int srsran_ofdm_tx_init_cfg(srsran_ofdm_t* q, srsran_ofdm_cfg_t* cfg) { + if (q == NULL || cfg == NULL) { + ERROR("Error, invalid inputs"); + return SRSRAN_ERROR_INVALID_INPUTS; + } return ofdm_init_mbsfn_(q, cfg, SRSRAN_DFT_BACKWARD); } @@ -607,7 +625,7 @@ void srsran_ofdm_rx_sf_ng(srsran_ofdm_t* q, cf_t* input, cf_t* output) } /* Transforms input OFDM symbols into output samples. - * Performs FFT on a each symbol and adds CP. + * Performs the FFT on each symbol and adds CP. */ static void ofdm_tx_slot(srsran_ofdm_t* q, int slot_in_sf) { @@ -664,6 +682,11 @@ static void ofdm_tx_slot(srsran_ofdm_t* q, int slot_in_sf) srsran_vec_sc_prod_cfc(&output[cp_len], norm, &output[cp_len], symbol_sz); } + // CFR: Process the time-domain signal without the CP + if (q->cfg.cfr_tx_cfg.cfr_enable) { + srsran_cfr_process(&q->tx_cfr, output + cp_len, output + cp_len); + } + /* add CP */ srsran_vec_cf_copy(output, &output[symbol_sz], cp_len); output += symbol_sz + cp_len; @@ -710,3 +733,38 @@ void srsran_ofdm_tx_sf(srsran_ofdm_t* q) srsran_vec_prod_ccc(q->cfg.out_buffer, q->shift_buffer, q->cfg.out_buffer, q->sf_sz); } } + +int srsran_ofdm_set_cfr(srsran_ofdm_t* q, srsran_cfr_cfg_t* cfr) +{ + if (q == NULL || cfr == NULL) { + ERROR("Error, invalid inputs"); + return SRSRAN_ERROR_INVALID_INPUTS; + } + if (!q->max_prb) { + ERROR("Error, ofdm object not initialised"); + return SRSRAN_ERROR; + } + // Check if there is nothing to configure + if (memcmp(&q->cfg.cfr_tx_cfg, cfr, sizeof(srsran_cfr_cfg_t)) == 0) { + return SRSRAN_SUCCESS; + } + + // Copy the CFR config into the OFDM object + q->cfg.cfr_tx_cfg = *cfr; + + // Set the CFR parameters related to OFDM symbol and FFT size + q->cfg.cfr_tx_cfg.symbol_sz = q->cfg.symbol_sz; + q->cfg.cfr_tx_cfg.symbol_bw = q->nof_re; + + // in the LTE DL, the DC carrier is empty but still counts when designing the filter BW + // in the LTE UL, the DC carrier is used + q->cfg.cfr_tx_cfg.dc_sc = (!q->cfg.keep_dc) && (!isnormal(q->cfg.freq_shift_f)); + if (q->cfg.cfr_tx_cfg.cfr_enable) { + if (srsran_cfr_init(&q->tx_cfr, &q->cfg.cfr_tx_cfg) < SRSRAN_SUCCESS) { + ERROR("Error while initialising CFR module"); + return SRSRAN_ERROR; + } + } + + return SRSRAN_SUCCESS; +} diff --git a/lib/src/phy/dft/test/CMakeLists.txt b/lib/src/phy/dft/test/CMakeLists.txt index db935c4664..2866c23685 100644 --- a/lib/src/phy/dft/test/CMakeLists.txt +++ b/lib/src/phy/dft/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/dft/test/ofdm_test.c b/lib/src/phy/dft/test/ofdm_test.c index 822300c8f3..c730fb793b 100644 --- a/lib/src/phy/dft/test/ofdm_test.c +++ b/lib/src/phy/dft/test/ofdm_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/enb/CMakeLists.txt b/lib/src/phy/enb/CMakeLists.txt index a254c328c6..ba639fff2d 100644 --- a/lib/src/phy/enb/CMakeLists.txt +++ b/lib/src/phy/enb/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/enb/enb_dl.c b/lib/src/phy/enb/enb_dl.c index 8a9c87b653..5231ad3e24 100644 --- a/lib/src/phy/enb/enb_dl.c +++ b/lib/src/phy/enb/enb_dl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -58,9 +58,9 @@ int srsran_enb_dl_init(srsran_enb_dl_t* q, cf_t* out_buffer[SRSRAN_MAX_PORTS], u ofdm_cfg.nof_prb = max_prb; ofdm_cfg.cp = SRSRAN_CP_EXT; ofdm_cfg.normalize = false; - ofdm_cfg.in_buffer = q->sf_symbols[0]; - ofdm_cfg.out_buffer = out_buffer[0]; - ofdm_cfg.sf_type = SRSRAN_SF_MBSFN; + ofdm_cfg.in_buffer = q->sf_symbols[0]; + ofdm_cfg.out_buffer = out_buffer[0]; + ofdm_cfg.sf_type = SRSRAN_SF_MBSFN; if (srsran_ofdm_tx_init_cfg(&q->ifft_mbsfn, &ofdm_cfg)) { ERROR("Error initiating FFT"); goto clean_exit; @@ -151,7 +151,7 @@ int srsran_enb_dl_set_cell(srsran_enb_dl_t* q, srsran_cell_t cell) if (q->cell.nof_prb != 0) { srsran_regs_free(&q->regs); } - q->cell = cell; + q->cell = cell; srsran_ofdm_cfg_t ofdm_cfg = {}; ofdm_cfg.nof_prb = q->cell.nof_prb; ofdm_cfg.cp = cell.cp; @@ -160,6 +160,7 @@ int srsran_enb_dl_set_cell(srsran_enb_dl_t* q, srsran_cell_t cell) ofdm_cfg.in_buffer = q->sf_symbols[i]; ofdm_cfg.out_buffer = q->out_buffer[i]; ofdm_cfg.sf_type = SRSRAN_SF_NORM; + ofdm_cfg.cfr_tx_cfg = q->cfr_config; if (srsran_ofdm_tx_init_cfg(&q->ifft[i], &ofdm_cfg)) { ERROR("Error initiating FFT (%d)", i); return SRSRAN_ERROR; @@ -238,6 +239,31 @@ int srsran_enb_dl_set_cell(srsran_enb_dl_t* q, srsran_cell_t cell) return ret; } +int srsran_enb_dl_set_cfr(srsran_enb_dl_t* q, const srsran_cfr_cfg_t* cfr) +{ + if (q == NULL || cfr == NULL) { + ERROR("Error, invalid inputs"); + return SRSRAN_ERROR_INVALID_INPUTS; + } + + // Copy the cfr config into the eNB + q->cfr_config = *cfr; + + // Set the cfr for the ifft's + if (srsran_ofdm_set_cfr(&q->ifft_mbsfn, &q->cfr_config) < SRSRAN_SUCCESS) { + ERROR("Error setting the CFR for ifft_mbsfn"); + return SRSRAN_ERROR; + } + for (int i = 0; i < SRSRAN_MAX_PORTS; i++) { + if (srsran_ofdm_set_cfr(&q->ifft[i], &q->cfr_config) < SRSRAN_SUCCESS) { + ERROR("Error setting the CFR for the IFFT (%d)", i); + return SRSRAN_ERROR; + } + } + + return SRSRAN_SUCCESS; +} + #ifdef resolve void srsran_enb_dl_apply_power_allocation(srsran_enb_dl_t* q) { @@ -419,22 +445,22 @@ int srsran_enb_dl_put_pmch(srsran_enb_dl_t* q, srsran_pmch_cfg_t* pmch_cfg, uint void srsran_enb_dl_gen_signal(srsran_enb_dl_t* q) { - // TODO: PAPR control float norm_factor = enb_dl_get_norm_factor(q->cell.nof_prb); + // First apply the amplitude normalization, then perform the IFFT and optional CFR reduction if (q->dl_sf.sf_type == SRSRAN_SF_MBSFN) { - srsran_ofdm_tx_sf(&q->ifft_mbsfn); - srsran_vec_sc_prod_cfc(q->ifft_mbsfn.cfg.out_buffer, + srsran_vec_sc_prod_cfc(q->ifft_mbsfn.cfg.in_buffer, norm_factor, - q->ifft_mbsfn.cfg.out_buffer, - (uint32_t)SRSRAN_SF_LEN_PRB(q->cell.nof_prb)); + q->ifft_mbsfn.cfg.in_buffer, + SRSRAN_NOF_SLOTS_PER_SF * q->cell.nof_prb * SRSRAN_NRE * SRSRAN_CP_NSYMB(q->cell.cp)); + srsran_ofdm_tx_sf(&q->ifft_mbsfn); } else { for (int i = 0; i < q->cell.nof_ports; i++) { - srsran_ofdm_tx_sf(&q->ifft[i]); - srsran_vec_sc_prod_cfc(q->ifft[i].cfg.out_buffer, + srsran_vec_sc_prod_cfc(q->ifft[i].cfg.in_buffer, norm_factor, - q->ifft[i].cfg.out_buffer, - (uint32_t)SRSRAN_SF_LEN_PRB(q->cell.nof_prb)); + q->ifft[i].cfg.in_buffer, + SRSRAN_NOF_SLOTS_PER_SF * q->cell.nof_prb * SRSRAN_NRE * SRSRAN_CP_NSYMB(q->cell.cp)); + srsran_ofdm_tx_sf(&q->ifft[i]); } } } diff --git a/lib/src/phy/enb/enb_ul.c b/lib/src/phy/enb/enb_ul.c index 054253c102..8d5c44be13 100644 --- a/lib/src/phy/enb/enb_ul.c +++ b/lib/src/phy/enb/enb_ul.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -193,7 +193,9 @@ static int get_pucch(srsran_enb_ul_t* q, srsran_ul_sf_cfg_t* ul_sf, srsran_pucch ERROR("Error estimating PUCCH DMRS"); return SRSRAN_ERROR; } - pucch_res.snr_db = q->chest_res.snr_db; + pucch_res.snr_db = q->chest_res.snr_db; + pucch_res.rssi_dbFs = q->chest_res.epre_dBfs; + pucch_res.ni_dbFs = q->chest_res.noise_estimate_dbFs; ret = srsran_pucch_decode(&q->pucch, ul_sf, cfg, &q->chest_res, q->sf_symbols, &pucch_res); if (ret < SRSRAN_SUCCESS) { @@ -214,7 +216,7 @@ static int get_pucch(srsran_enb_ul_t* q, srsran_ul_sf_cfg_t* ul_sf, srsran_pucch // Compares correlation value, it stores the PUCCH result with the greatest correlation if (i == 0 || pucch_res.correlation > res->correlation) { - // Copy measurements only if PUCCH was decoded succesfully + // Copy measurements only if PUCCH was decoded successfully if (cfg->meas_ta_en) { pucch_res.ta_valid = !(isnan(q->chest_res.ta_us) || isinf(q->chest_res.ta_us)); pucch_res.ta_us = q->chest_res.ta_us; diff --git a/lib/src/phy/fec/CMakeLists.txt b/lib/src/phy/fec/CMakeLists.txt index 5e4e596129..7f1d3d1c1c 100644 --- a/lib/src/phy/fec/CMakeLists.txt +++ b/lib/src/phy/fec/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/fec/block/CMakeLists.txt b/lib/src/phy/fec/block/CMakeLists.txt index e6385c799d..91317e9ae3 100644 --- a/lib/src/phy/fec/block/CMakeLists.txt +++ b/lib/src/phy/fec/block/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/fec/block/block.c b/lib/src/phy/fec/block/block.c index bde59aad24..5dd155b47a 100644 --- a/lib/src/phy/fec/block/block.c +++ b/lib/src/phy/fec/block/block.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/block/test/CMakeLists.txt b/lib/src/phy/fec/block/test/CMakeLists.txt index 074430b5db..f302c649b8 100644 --- a/lib/src/phy/fec/block/test/CMakeLists.txt +++ b/lib/src/phy/fec/block/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/fec/block/test/block_test.c b/lib/src/phy/fec/block/test/block_test.c index a6b8226ac1..5725e5afe1 100644 --- a/lib/src/phy/fec/block/test/block_test.c +++ b/lib/src/phy/fec/block/test/block_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/cbsegm.c b/lib/src/phy/fec/cbsegm.c index bdf1f63f65..3cdbf6a060 100644 --- a/lib/src/phy/fec/cbsegm.c +++ b/lib/src/phy/fec/cbsegm.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/convolutional/CMakeLists.txt b/lib/src/phy/fec/convolutional/CMakeLists.txt index a4d3dc7cd8..7b5f07597b 100644 --- a/lib/src/phy/fec/convolutional/CMakeLists.txt +++ b/lib/src/phy/fec/convolutional/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/fec/convolutional/convcoder.c b/lib/src/phy/fec/convolutional/convcoder.c index bbb6d10ba3..2d3e34b627 100644 --- a/lib/src/phy/fec/convolutional/convcoder.c +++ b/lib/src/phy/fec/convolutional/convcoder.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/convolutional/parity.c b/lib/src/phy/fec/convolutional/parity.c index 14aa7dc97a..3497318603 100644 --- a/lib/src/phy/fec/convolutional/parity.c +++ b/lib/src/phy/fec/convolutional/parity.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/convolutional/parity.h b/lib/src/phy/fec/convolutional/parity.h index 7e53999752..1274ca8d3d 100644 --- a/lib/src/phy/fec/convolutional/parity.h +++ b/lib/src/phy/fec/convolutional/parity.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/convolutional/test/CMakeLists.txt b/lib/src/phy/fec/convolutional/test/CMakeLists.txt index 61bc8a5ab1..d2016cf87b 100644 --- a/lib/src/phy/fec/convolutional/test/CMakeLists.txt +++ b/lib/src/phy/fec/convolutional/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -30,7 +30,11 @@ add_test(viterbi_40_2 viterbi_test -n 1000 -s 1 -l 40 -t -e 2.0) add_test(viterbi_40_3 viterbi_test -n 1000 -s 1 -l 40 -t -e 3.0) add_test(viterbi_40_4 viterbi_test -n 1000 -s 1 -l 40 -t -e 4.5) -add_test(viterbi_1000_0 viterbi_test -n 100 -s 1 -l 1000 -t -e 0.0) +if (HAVE_AVX2) + # The accuracy of the 8-bit implementation of the Viterbi decoder used on + # non-AVX2 machines falls below the theoretical accuracy at 0dB. + add_test(viterbi_1000_0 viterbi_test -n 100 -s 1 -l 1000 -t -e 0.0) +endif() add_test(viterbi_1000_2 viterbi_test -n 100 -s 1 -l 1000 -t -e 2.0) add_test(viterbi_1000_3 viterbi_test -n 100 -s 1 -l 1000 -t -e 3.0) add_test(viterbi_1000_4 viterbi_test -n 100 -s 1 -l 1000 -t -e 4.5) diff --git a/lib/src/phy/fec/convolutional/test/viterbi_test.c b/lib/src/phy/fec/convolutional/test/viterbi_test.c index bc28c64c4c..0b5d63cf86 100644 --- a/lib/src/phy/fec/convolutional/test/viterbi_test.c +++ b/lib/src/phy/fec/convolutional/test/viterbi_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -193,13 +193,13 @@ int main(int argc, char** argv) for (uint32_t i = 0; i < snr_points; i++) { ebno_db = SNR_MIN + i * ebno_inc; esno_db = ebno_db + srsran_convert_power_to_dB(1.0f / 3.0f); - var[i] = srsran_convert_dB_to_amplitude(esno_db); - varunc[i] = srsran_convert_dB_to_amplitude(ebno_db); + var[i] = srsran_convert_dB_to_power(-esno_db); + varunc[i] = srsran_convert_dB_to_power(-ebno_db); } } else { esno_db = ebno_db + srsran_convert_power_to_dB(1.0f / 3.0f); - var[0] = srsran_convert_dB_to_amplitude(esno_db); - varunc[0] = srsran_convert_dB_to_amplitude(ebno_db); + var[0] = srsran_convert_dB_to_power(-esno_db); + varunc[0] = srsran_convert_dB_to_power(-ebno_db); snr_points = 1; } diff --git a/lib/src/phy/fec/convolutional/test/viterbi_test.h b/lib/src/phy/fec/convolutional/test/viterbi_test.h index c14c76de8a..5ce2050744 100644 --- a/lib/src/phy/fec/convolutional/test/viterbi_test.h +++ b/lib/src/phy/fec/convolutional/test/viterbi_test.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -62,7 +62,7 @@ static expected_errors_t expected_errors[] = {{1000, 1, 40, true, 0.0, 7282}, {1000, 1, 56, true, 3.0, 176}, {1000, 1, 56, true, 4.5, 24}, - {100, 1, 1000, true, 0.0, 13208}, + {100, 1, 1000, true, 0.0, 16000}, {100, 1, 1000, true, 2.0, 939}, {100, 1, 1000, true, 3.0, 110}, {100, 1, 1000, true, 4.5, 5}, diff --git a/lib/src/phy/fec/convolutional/viterbi.c b/lib/src/phy/fec/convolutional/viterbi.c index c2ac751d9f..c892bc9481 100644 --- a/lib/src/phy/fec/convolutional/viterbi.c +++ b/lib/src/phy/fec/convolutional/viterbi.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/convolutional/viterbi37.h b/lib/src/phy/fec/convolutional/viterbi37.h index 57867679a7..ecc0391aa0 100644 --- a/lib/src/phy/fec/convolutional/viterbi37.h +++ b/lib/src/phy/fec/convolutional/viterbi37.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/crc.c b/lib/src/phy/fec/crc.c index 58086f1683..29a9e0a882 100644 --- a/lib/src/phy/fec/crc.c +++ b/lib/src/phy/fec/crc.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/CMakeLists.txt b/lib/src/phy/fec/ldpc/CMakeLists.txt index ceba4e9d4c..c6a9e9ad6f 100644 --- a/lib/src/phy/fec/ldpc/CMakeLists.txt +++ b/lib/src/phy/fec/ldpc/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/fec/ldpc/base_graph.c b/lib/src/phy/fec/ldpc/base_graph.c index c6a0474218..d40f38ce43 100644 --- a/lib/src/phy/fec/ldpc/base_graph.c +++ b/lib/src/phy/fec/ldpc/base_graph.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_avx2_consts.h b/lib/src/phy/fec/ldpc/ldpc_avx2_consts.h index 1b33e1c28d..be969fb566 100644 --- a/lib/src/phy/fec/ldpc/ldpc_avx2_consts.h +++ b/lib/src/phy/fec/ldpc/ldpc_avx2_consts.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_avx512_consts.h b/lib/src/phy/fec/ldpc/ldpc_avx512_consts.h index e8dc4da6d9..3e0e67cd4c 100644 --- a/lib/src/phy/fec/ldpc/ldpc_avx512_consts.h +++ b/lib/src/phy/fec/ldpc/ldpc_avx512_consts.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_all.h b/lib/src/phy/fec/ldpc/ldpc_dec_all.h index 87c85e3550..5a7b5558fb 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_all.h +++ b/lib/src/phy/fec/ldpc/ldpc_dec_all.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c.c b/lib/src/phy/fec/ldpc/ldpc_dec_c.c index 2127501a6e..a41e016168 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2.c index 0b08ff2bf8..2f5845eb43 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2_flood.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2_flood.c index 9da695c025..a7bbdce1c9 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2_flood.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2_flood.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long.c index d7c15db7ca..37fe698485 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long_flood.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long_flood.c index 156baec071..81e6e68ca1 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long_flood.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx2long_flood.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512.c index 90c4833477..be63eab873 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long.c index 3676b45021..a8beb17d41 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long_flood.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long_flood.c index 7c38d109b8..7cdf70e768 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long_flood.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_avx512long_flood.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_c_flood.c b/lib/src/phy/fec/ldpc/ldpc_dec_c_flood.c index 7ef1381647..ca92ef71b8 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_c_flood.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_c_flood.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_f.c b/lib/src/phy/fec/ldpc/ldpc_dec_f.c index bb51ee346a..9e77abb9f2 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_f.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_f.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_dec_s.c b/lib/src/phy/fec/ldpc/ldpc_dec_s.c index 361530c679..4425e604e7 100644 --- a/lib/src/phy/fec/ldpc/ldpc_dec_s.c +++ b/lib/src/phy/fec/ldpc/ldpc_dec_s.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_decoder.c b/lib/src/phy/fec/ldpc/ldpc_decoder.c index a84c2e4b71..e7ac6d79f1 100644 --- a/lib/src/phy/fec/ldpc/ldpc_decoder.c +++ b/lib/src/phy/fec/ldpc/ldpc_decoder.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_enc_all.h b/lib/src/phy/fec/ldpc/ldpc_enc_all.h index 4bf323459c..d398398ec2 100644 --- a/lib/src/phy/fec/ldpc/ldpc_enc_all.h +++ b/lib/src/phy/fec/ldpc/ldpc_enc_all.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_enc_avx2.c b/lib/src/phy/fec/ldpc/ldpc_enc_avx2.c index 735e6fa416..0f4d6fc506 100644 --- a/lib/src/phy/fec/ldpc/ldpc_enc_avx2.c +++ b/lib/src/phy/fec/ldpc/ldpc_enc_avx2.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_enc_avx2long.c b/lib/src/phy/fec/ldpc/ldpc_enc_avx2long.c index 2b86a01c3a..067c38117d 100644 --- a/lib/src/phy/fec/ldpc/ldpc_enc_avx2long.c +++ b/lib/src/phy/fec/ldpc/ldpc_enc_avx2long.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_enc_avx512.c b/lib/src/phy/fec/ldpc/ldpc_enc_avx512.c index da1867cd7b..7ba41a34e2 100644 --- a/lib/src/phy/fec/ldpc/ldpc_enc_avx512.c +++ b/lib/src/phy/fec/ldpc/ldpc_enc_avx512.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_enc_avx512long.c b/lib/src/phy/fec/ldpc/ldpc_enc_avx512long.c index c5b096e2d5..55c62cadeb 100644 --- a/lib/src/phy/fec/ldpc/ldpc_enc_avx512long.c +++ b/lib/src/phy/fec/ldpc/ldpc_enc_avx512long.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_enc_c.c b/lib/src/phy/fec/ldpc/ldpc_enc_c.c index 0fd0ade901..2675fc83d4 100644 --- a/lib/src/phy/fec/ldpc/ldpc_enc_c.c +++ b/lib/src/phy/fec/ldpc/ldpc_enc_c.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_encoder.c b/lib/src/phy/fec/ldpc/ldpc_encoder.c index 909f8f293b..1f07f5d5e1 100644 --- a/lib/src/phy/fec/ldpc/ldpc_encoder.c +++ b/lib/src/phy/fec/ldpc/ldpc_encoder.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/ldpc_rm.c b/lib/src/phy/fec/ldpc/ldpc_rm.c index 40738099b4..6bcc91f9c4 100644 --- a/lib/src/phy/fec/ldpc/ldpc_rm.c +++ b/lib/src/phy/fec/ldpc/ldpc_rm.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/test/CMakeLists.txt b/lib/src/phy/fec/ldpc/test/CMakeLists.txt index d3e0b05e27..6b931670ec 100644 --- a/lib/src/phy/fec/ldpc/test/CMakeLists.txt +++ b/lib/src/phy/fec/ldpc/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/fec/ldpc/test/ldpc_chain_test.c b/lib/src/phy/fec/ldpc/test/ldpc_chain_test.c index 3e0e339024..bdbe949a35 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_chain_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_chain_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -323,6 +323,7 @@ int main(int argc, char** argv) int n_error_words_avx512_flood = 0; #endif // lV_HAVE_AVX512 + float noise_var = srsran_convert_dB_to_power(-snr); float noise_std_dev = srsran_convert_dB_to_amplitude(-snr); int16_t inf15 = (1U << 14U) - 1; @@ -380,12 +381,12 @@ int main(int argc, char** argv) } // Apply AWGN - srsran_ch_awgn_f(symbols_rm, symbols_rm, noise_std_dev, batch_size * (rm_length + F)); + srsran_ch_awgn_f(symbols_rm, symbols_rm, noise_var, batch_size * (rm_length + F)); // Convert symbols into LLRs for (i = 0; i < batch_size; i++) { for (j = 0; j < rm_length + F; j++) { //+F because we have already considered fillerbits when modulating. - symbols[i * finalN + j] = symbols_rm[i * (rm_length + F) + j] * 2 / (noise_std_dev * noise_std_dev); + symbols[i * finalN + j] = symbols_rm[i * (rm_length + F) + j] * 2 / noise_var; } // the rest of symbols are undetermined, set LLR to 0 for (; j < finalN; j++) { diff --git a/lib/src/phy/fec/ldpc/test/ldpc_dec_avx2_test.c b/lib/src/phy/fec/ldpc/test/ldpc_dec_avx2_test.c index 9e6d156867..29c6bdc735 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_dec_avx2_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_dec_avx2_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/test/ldpc_dec_avx512_test.c b/lib/src/phy/fec/ldpc/test/ldpc_dec_avx512_test.c index a04b46d024..c3a43e8045 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_dec_avx512_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_dec_avx512_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/test/ldpc_dec_c_test.c b/lib/src/phy/fec/ldpc/test/ldpc_dec_c_test.c index 9169ee2227..9b2adf31f1 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_dec_c_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_dec_c_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/test/ldpc_dec_s_test.c b/lib/src/phy/fec/ldpc/test/ldpc_dec_s_test.c index 0e58882299..abc32c49a3 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_dec_s_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_dec_s_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/test/ldpc_dec_test.c b/lib/src/phy/fec/ldpc/test/ldpc_dec_test.c index 588c24933b..4aee09fecf 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_dec_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_dec_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/test/ldpc_enc_avx2_test.c b/lib/src/phy/fec/ldpc/test/ldpc_enc_avx2_test.c index 32ab1b78bb..f5de88dec0 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_enc_avx2_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_enc_avx2_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/test/ldpc_enc_avx512_test.c b/lib/src/phy/fec/ldpc/test/ldpc_enc_avx512_test.c index 386c7f2fe3..1fff5f5567 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_enc_avx512_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_enc_avx512_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/test/ldpc_enc_test.c b/lib/src/phy/fec/ldpc/test/ldpc_enc_test.c index 606dcb3176..b90d9d5b5a 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_enc_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_enc_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c b/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c index 66a1c467f4..6fda935c13 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_rm_chain_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -418,6 +418,7 @@ int main(int argc, char** argv) int n_error_words_avx512_flood = 0; #endif // LV_HAVE_AVX512 + float noise_var = srsran_convert_dB_to_power(-snr); float noise_std_dev = srsran_convert_dB_to_amplitude(-snr); int16_t inf15 = (1U << 14U) - 1; @@ -487,12 +488,12 @@ int main(int argc, char** argv) } // Apply AWGN - srsran_ch_awgn_f(rm_symbols, rm_symbols, noise_std_dev, batch_size * rm_length); + srsran_ch_awgn_f(rm_symbols, rm_symbols, noise_var, batch_size * rm_length); // Convert symbols into LLRs for (i = 0; i < batch_size; i++) { for (j = 0; j < rm_length; j++) { - rm_symbols[i * rm_length + j] = rm_symbols[i * rm_length + j] * 2 / (noise_std_dev * noise_std_dev); + rm_symbols[i * rm_length + j] = rm_symbols[i * rm_length + j] * 2 / noise_var; } } diff --git a/lib/src/phy/fec/ldpc/test/ldpc_rm_test.c b/lib/src/phy/fec/ldpc/test/ldpc_rm_test.c index f528d4da79..7667b6331a 100644 --- a/lib/src/phy/fec/ldpc/test/ldpc_rm_test.c +++ b/lib/src/phy/fec/ldpc/test/ldpc_rm_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/CMakeLists.txt b/lib/src/phy/fec/polar/CMakeLists.txt index 26842c863e..768d9d8fdc 100644 --- a/lib/src/phy/fec/polar/CMakeLists.txt +++ b/lib/src/phy/fec/polar/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/fec/polar/polar_chanalloc.c b/lib/src/phy/fec/polar/polar_chanalloc.c index b1701f76a1..61da5ca3da 100644 --- a/lib/src/phy/fec/polar/polar_chanalloc.c +++ b/lib/src/phy/fec/polar/polar_chanalloc.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_code.c b/lib/src/phy/fec/polar/polar_code.c index be28964bf9..842cdb2a0c 100644 --- a/lib/src/phy/fec/polar/polar_code.c +++ b/lib/src/phy/fec/polar/polar_code.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder.c b/lib/src/phy/fec/polar/polar_decoder.c index 2e5f66d596..c33fbf1acf 100644 --- a/lib/src/phy/fec/polar/polar_decoder.c +++ b/lib/src/phy/fec/polar/polar_decoder.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_ssc_all.c b/lib/src/phy/fec/polar/polar_decoder_ssc_all.c index 6f18fbd3cd..63ea1d708e 100644 --- a/lib/src/phy/fec/polar/polar_decoder_ssc_all.c +++ b/lib/src/phy/fec/polar/polar_decoder_ssc_all.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_ssc_all.h b/lib/src/phy/fec/polar/polar_decoder_ssc_all.h index df875b222b..6f3ff49ea3 100644 --- a/lib/src/phy/fec/polar/polar_decoder_ssc_all.h +++ b/lib/src/phy/fec/polar/polar_decoder_ssc_all.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_ssc_c.c b/lib/src/phy/fec/polar/polar_decoder_ssc_c.c index 952309733e..06b0a455c6 100644 --- a/lib/src/phy/fec/polar/polar_decoder_ssc_c.c +++ b/lib/src/phy/fec/polar/polar_decoder_ssc_c.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_ssc_c.h b/lib/src/phy/fec/polar/polar_decoder_ssc_c.h index 8b3d79b2b2..e7b10200fb 100644 --- a/lib/src/phy/fec/polar/polar_decoder_ssc_c.h +++ b/lib/src/phy/fec/polar/polar_decoder_ssc_c.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_ssc_c_avx2.c b/lib/src/phy/fec/polar/polar_decoder_ssc_c_avx2.c index 0a1baabcaa..3de294ed68 100644 --- a/lib/src/phy/fec/polar/polar_decoder_ssc_c_avx2.c +++ b/lib/src/phy/fec/polar/polar_decoder_ssc_c_avx2.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_ssc_c_avx2.h b/lib/src/phy/fec/polar/polar_decoder_ssc_c_avx2.h index 509ebc85f9..38f1d9e488 100644 --- a/lib/src/phy/fec/polar/polar_decoder_ssc_c_avx2.h +++ b/lib/src/phy/fec/polar/polar_decoder_ssc_c_avx2.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_ssc_f.c b/lib/src/phy/fec/polar/polar_decoder_ssc_f.c index 348e39aea4..84e0070098 100644 --- a/lib/src/phy/fec/polar/polar_decoder_ssc_f.c +++ b/lib/src/phy/fec/polar/polar_decoder_ssc_f.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_ssc_f.h b/lib/src/phy/fec/polar/polar_decoder_ssc_f.h index 5beba9cf7a..dea40972de 100644 --- a/lib/src/phy/fec/polar/polar_decoder_ssc_f.h +++ b/lib/src/phy/fec/polar/polar_decoder_ssc_f.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_ssc_s.c b/lib/src/phy/fec/polar/polar_decoder_ssc_s.c index 0706bb1433..60092a97df 100644 --- a/lib/src/phy/fec/polar/polar_decoder_ssc_s.c +++ b/lib/src/phy/fec/polar/polar_decoder_ssc_s.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_ssc_s.h b/lib/src/phy/fec/polar/polar_decoder_ssc_s.h index cb87ef41b2..76355a59f6 100644 --- a/lib/src/phy/fec/polar/polar_decoder_ssc_s.h +++ b/lib/src/phy/fec/polar/polar_decoder_ssc_s.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_vector.c b/lib/src/phy/fec/polar/polar_decoder_vector.c index 99058b950a..8613c9a0f2 100644 --- a/lib/src/phy/fec/polar/polar_decoder_vector.c +++ b/lib/src/phy/fec/polar/polar_decoder_vector.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_vector.h b/lib/src/phy/fec/polar/polar_decoder_vector.h index 88bd59a93b..cd98230272 100644 --- a/lib/src/phy/fec/polar/polar_decoder_vector.h +++ b/lib/src/phy/fec/polar/polar_decoder_vector.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_vector_avx2.c b/lib/src/phy/fec/polar/polar_decoder_vector_avx2.c index 48d6c9baf0..245d57cef7 100644 --- a/lib/src/phy/fec/polar/polar_decoder_vector_avx2.c +++ b/lib/src/phy/fec/polar/polar_decoder_vector_avx2.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_decoder_vector_avx2.h b/lib/src/phy/fec/polar/polar_decoder_vector_avx2.h index 1e2bd55ff4..f3786b86a1 100644 --- a/lib/src/phy/fec/polar/polar_decoder_vector_avx2.h +++ b/lib/src/phy/fec/polar/polar_decoder_vector_avx2.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_encoder.c b/lib/src/phy/fec/polar/polar_encoder.c index f6b96197f6..9430168d74 100644 --- a/lib/src/phy/fec/polar/polar_encoder.c +++ b/lib/src/phy/fec/polar/polar_encoder.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_encoder_avx2.c b/lib/src/phy/fec/polar/polar_encoder_avx2.c index 11b7c8ed5c..3e84e615e5 100644 --- a/lib/src/phy/fec/polar/polar_encoder_avx2.c +++ b/lib/src/phy/fec/polar/polar_encoder_avx2.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_encoder_avx2.h b/lib/src/phy/fec/polar/polar_encoder_avx2.h index 163153125a..1557c11cb5 100644 --- a/lib/src/phy/fec/polar/polar_encoder_avx2.h +++ b/lib/src/phy/fec/polar/polar_encoder_avx2.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_encoder_pipelined.c b/lib/src/phy/fec/polar/polar_encoder_pipelined.c index 5b3c9bca14..12d8694192 100644 --- a/lib/src/phy/fec/polar/polar_encoder_pipelined.c +++ b/lib/src/phy/fec/polar/polar_encoder_pipelined.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_encoder_pipelined.h b/lib/src/phy/fec/polar/polar_encoder_pipelined.h index 2bef6d3969..d88600bb2c 100644 --- a/lib/src/phy/fec/polar/polar_encoder_pipelined.h +++ b/lib/src/phy/fec/polar/polar_encoder_pipelined.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_interleaver.c b/lib/src/phy/fec/polar/polar_interleaver.c index 116a40df90..41106736b3 100644 --- a/lib/src/phy/fec/polar/polar_interleaver.c +++ b/lib/src/phy/fec/polar/polar_interleaver.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/polar_rm.c b/lib/src/phy/fec/polar/polar_rm.c index cc1d13fb43..2bf0a30490 100644 --- a/lib/src/phy/fec/polar/polar_rm.c +++ b/lib/src/phy/fec/polar/polar_rm.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/test/CMakeLists.txt b/lib/src/phy/fec/polar/test/CMakeLists.txt index fd6ccc6e4a..95645b5a47 100644 --- a/lib/src/phy/fec/polar/test/CMakeLists.txt +++ b/lib/src/phy/fec/polar/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/fec/polar/test/polar_chain_test.c b/lib/src/phy/fec/polar/test/polar_chain_test.c index a0d9b8fc7a..51753f6d83 100644 --- a/lib/src/phy/fec/polar/test/polar_chain_test.c +++ b/lib/src/phy/fec/polar/test/polar_chain_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -193,9 +193,9 @@ int main(int argc, char** argv) int j = 0; int snr_points = 0; - int errors_symb = 0; - int errors_symb_s = 0; - int errors_symb_c = 0; + int errors_symb = 0; + int errors_symb_s = 0; + int errors_symb_c = 0; #ifdef LV_HAVE_AVX2 int errors_symb_c_avx2 = 0; #endif @@ -217,12 +217,12 @@ int main(int argc, char** argv) double elapsed_time_enc_avx2[SNR_POINTS + 1]; // 16-bit quantizer - int16_t inf16 = (1U << 15U) - 1; - int8_t inf8 = (1U << 7U) - 1; - float gain_s = NAN; - float gain_c = NAN; + int16_t inf16 = (1U << 15U) - 1; + int8_t inf8 = (1U << 7U) - 1; + float gain_s = NAN; + float gain_c = NAN; #ifdef LV_HAVE_AVX2 - float gain_c_avx2 = NAN; + float gain_c_avx2 = NAN; #endif srsran_polar_code_t code; @@ -328,13 +328,13 @@ int main(int argc, char** argv) for (int i = 0; i < snr_points; i++) { snr_db = SNR_MIN + i * snr_inc; snr_db_vec[i] = snr_db; - var[i] = srsran_convert_dB_to_amplitude(-snr_db); + var[i] = srsran_convert_dB_to_power(-snr_db); } snr_db_vec[snr_points] = 101; // include the no noise case snr_points++; } else { snr_db_vec[0] = snr_db; - var[0] = srsran_convert_dB_to_amplitude(-snr_db); + var[0] = srsran_convert_dB_to_power(-snr_db); snr_points = 1; } diff --git a/lib/src/phy/fec/polar/test/polar_interleaver_gold.h b/lib/src/phy/fec/polar/test/polar_interleaver_gold.h index 3eddee7ffe..57bdd81a0c 100644 --- a/lib/src/phy/fec/polar/test/polar_interleaver_gold.h +++ b/lib/src/phy/fec/polar/test/polar_interleaver_gold.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/test/polar_interleaver_test.c b/lib/src/phy/fec/polar/test/polar_interleaver_test.c index 5e807b838a..73d54987ef 100644 --- a/lib/src/phy/fec/polar/test/polar_interleaver_test.c +++ b/lib/src/phy/fec/polar/test/polar_interleaver_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/test/polar_sets.c b/lib/src/phy/fec/polar/test/polar_sets.c index fb9bdedd7b..c51295da23 100644 --- a/lib/src/phy/fec/polar/test/polar_sets.c +++ b/lib/src/phy/fec/polar/test/polar_sets.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/test/polar_sets.h b/lib/src/phy/fec/polar/test/polar_sets.h index ccdbc8c4ba..c387c550ee 100644 --- a/lib/src/phy/fec/polar/test/polar_sets.h +++ b/lib/src/phy/fec/polar/test/polar_sets.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/test/subchannel_allocation.c b/lib/src/phy/fec/polar/test/subchannel_allocation.c index b82c9ae2e5..687bfc3e46 100644 --- a/lib/src/phy/fec/polar/test/subchannel_allocation.c +++ b/lib/src/phy/fec/polar/test/subchannel_allocation.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/polar/test/subchannel_allocation.h b/lib/src/phy/fec/polar/test/subchannel_allocation.h index efac019b3c..1580488b00 100644 --- a/lib/src/phy/fec/polar/test/subchannel_allocation.h +++ b/lib/src/phy/fec/polar/test/subchannel_allocation.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/softbuffer.c b/lib/src/phy/fec/softbuffer.c index f5c58d45a9..18d2ae30c3 100644 --- a/lib/src/phy/fec/softbuffer.c +++ b/lib/src/phy/fec/softbuffer.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/test/CMakeLists.txt b/lib/src/phy/fec/test/CMakeLists.txt index 65e8262647..6758bdad45 100644 --- a/lib/src/phy/fec/test/CMakeLists.txt +++ b/lib/src/phy/fec/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/fec/test/crc_test.c b/lib/src/phy/fec/test/crc_test.c index 321760c7cf..ee6d0058ff 100644 --- a/lib/src/phy/fec/test/crc_test.c +++ b/lib/src/phy/fec/test/crc_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/test/crc_test.h b/lib/src/phy/fec/test/crc_test.h index 1f5ee48fc0..ee651b6b49 100644 --- a/lib/src/phy/fec/test/crc_test.h +++ b/lib/src/phy/fec/test/crc_test.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/CMakeLists.txt b/lib/src/phy/fec/turbo/CMakeLists.txt index 6f295dbda4..b95f55f2e0 100644 --- a/lib/src/phy/fec/turbo/CMakeLists.txt +++ b/lib/src/phy/fec/turbo/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/fec/turbo/rm_conv.c b/lib/src/phy/fec/turbo/rm_conv.c index d274c4a49f..c17fce6ac0 100644 --- a/lib/src/phy/fec/turbo/rm_conv.c +++ b/lib/src/phy/fec/turbo/rm_conv.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/rm_turbo.c b/lib/src/phy/fec/turbo/rm_turbo.c index 3a7ba9f101..89800a9183 100644 --- a/lib/src/phy/fec/turbo/rm_turbo.c +++ b/lib/src/phy/fec/turbo/rm_turbo.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/tc_interl_lte.c b/lib/src/phy/fec/turbo/tc_interl_lte.c index 7c0b03d1c2..dac431b454 100644 --- a/lib/src/phy/fec/turbo/tc_interl_lte.c +++ b/lib/src/phy/fec/turbo/tc_interl_lte.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/tc_interl_umts.c b/lib/src/phy/fec/turbo/tc_interl_umts.c index 571b6efdcf..437768a955 100644 --- a/lib/src/phy/fec/turbo/tc_interl_umts.c +++ b/lib/src/phy/fec/turbo/tc_interl_umts.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/test/CMakeLists.txt b/lib/src/phy/fec/turbo/test/CMakeLists.txt index e55c825057..ec55d08b28 100644 --- a/lib/src/phy/fec/turbo/test/CMakeLists.txt +++ b/lib/src/phy/fec/turbo/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/fec/turbo/test/rm_conv_test.c b/lib/src/phy/fec/turbo/test/rm_conv_test.c index 4fec942a28..4a5d19b25f 100644 --- a/lib/src/phy/fec/turbo/test/rm_conv_test.c +++ b/lib/src/phy/fec/turbo/test/rm_conv_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/test/rm_turbo_test.c b/lib/src/phy/fec/turbo/test/rm_turbo_test.c index f1f85b5f3d..9d5722836d 100644 --- a/lib/src/phy/fec/turbo/test/rm_turbo_test.c +++ b/lib/src/phy/fec/turbo/test/rm_turbo_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/test/turbocoder_test.c b/lib/src/phy/fec/turbo/test/turbocoder_test.c index da26433997..83966ce2dc 100644 --- a/lib/src/phy/fec/turbo/test/turbocoder_test.c +++ b/lib/src/phy/fec/turbo/test/turbocoder_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/test/turbodecoder_test.c b/lib/src/phy/fec/turbo/test/turbodecoder_test.c index 731385955a..5ba7f24f3c 100644 --- a/lib/src/phy/fec/turbo/test/turbodecoder_test.c +++ b/lib/src/phy/fec/turbo/test/turbodecoder_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -215,11 +215,11 @@ int main(int argc, char** argv) for (uint32_t i = 0; i < snr_points; i++) { ebno_db = SNR_MIN + i * ebno_inc; esno_db = ebno_db + srsran_convert_power_to_dB(1.0f / 3.0f); - var[i] = srsran_convert_dB_to_amplitude(-esno_db); + var[i] = srsran_convert_dB_to_power(-esno_db); } } else { esno_db = ebno_db + srsran_convert_power_to_dB(1.0f / 3.0f); - var[0] = srsran_convert_dB_to_amplitude(-esno_db); + var[0] = srsran_convert_dB_to_power(-esno_db); snr_points = 1; } for (uint32_t i = 0; i < snr_points; i++) { diff --git a/lib/src/phy/fec/turbo/test/turbodecoder_test.h b/lib/src/phy/fec/turbo/test/turbodecoder_test.h index 918b2fa268..0d7611ca67 100644 --- a/lib/src/phy/fec/turbo/test/turbodecoder_test.h +++ b/lib/src/phy/fec/turbo/test/turbodecoder_test.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/turbocoder.c b/lib/src/phy/fec/turbo/turbocoder.c index 5a06826439..dafc3fc4d1 100644 --- a/lib/src/phy/fec/turbo/turbocoder.c +++ b/lib/src/phy/fec/turbo/turbocoder.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/turbodecoder.c b/lib/src/phy/fec/turbo/turbodecoder.c index f3e743b97e..42ec7aabad 100644 --- a/lib/src/phy/fec/turbo/turbodecoder.c +++ b/lib/src/phy/fec/turbo/turbodecoder.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/turbodecoder_gen.c b/lib/src/phy/fec/turbo/turbodecoder_gen.c index 9b42982d9d..ffeb6ec686 100644 --- a/lib/src/phy/fec/turbo/turbodecoder_gen.c +++ b/lib/src/phy/fec/turbo/turbodecoder_gen.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/turbo/turbodecoder_sse.c b/lib/src/phy/fec/turbo/turbodecoder_sse.c index 765b81bd9d..224151af4d 100644 --- a/lib/src/phy/fec/turbo/turbodecoder_sse.c +++ b/lib/src/phy/fec/turbo/turbodecoder_sse.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/utils_avx2.h b/lib/src/phy/fec/utils_avx2.h index 40275c276d..e6cc801131 100644 --- a/lib/src/phy/fec/utils_avx2.h +++ b/lib/src/phy/fec/utils_avx2.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/fec/utils_avx512.h b/lib/src/phy/fec/utils_avx512.h index b8c6b69482..f703adbc6a 100644 --- a/lib/src/phy/fec/utils_avx512.h +++ b/lib/src/phy/fec/utils_avx512.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/gnb/CMakeLists.txt b/lib/src/phy/gnb/CMakeLists.txt index fa74ce527a..27b7b40a2b 100644 --- a/lib/src/phy/gnb/CMakeLists.txt +++ b/lib/src/phy/gnb/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/gnb/gnb_dl.c b/lib/src/phy/gnb/gnb_dl.c index 53e82912a7..c15efb7476 100644 --- a/lib/src/phy/gnb/gnb_dl.c +++ b/lib/src/phy/gnb/gnb_dl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -70,7 +70,7 @@ int srsran_gnb_dl_init(srsran_gnb_dl_t* q, cf_t* output[SRSRAN_MAX_PORTS], const return SRSRAN_ERROR; } - // Check symbol size is vlid + // Check symbol size is valid int symbol_sz = srsran_symbol_sz_from_srate(args->srate_hz, args->scs); if (symbol_sz <= 0) { ERROR("Error calculating symbol size from sampling rate of %.2f MHz and subcarrier spacing %s", diff --git a/lib/src/phy/gnb/gnb_ul.c b/lib/src/phy/gnb/gnb_ul.c index 3d12fbe12d..f4fe89c37f 100644 --- a/lib/src/phy/gnb/gnb_ul.c +++ b/lib/src/phy/gnb/gnb_ul.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -317,7 +317,7 @@ int srsran_gnb_ul_get_pucch(srsran_gnb_ul_t* q, meas->epre = q->chest_pucch.epre; meas->epre_dB = q->chest_pucch.epre_dBfs; meas->n0 = q->chest_pucch.noise_estimate; - meas->n0_dB = q->chest_pucch.noise_estimate_dbm; + meas->n0_dB = q->chest_pucch.noise_estimate_dbFs; meas->snr_dB = q->chest_pucch.snr_db; meas->cfo_hz = q->chest_pucch.cfo_hz; meas->cfo_hz_max = NAN; // Unavailable @@ -368,4 +368,4 @@ uint32_t srsran_gnb_ul_pusch_info(srsran_gnb_ul_t* q, len += srsran_csi_meas_info_short(&q->dmrs.csi, &str[len], str_len - len); return len; -} \ No newline at end of file +} diff --git a/lib/src/phy/io/CMakeLists.txt b/lib/src/phy/io/CMakeLists.txt index 7d69e0f7fc..155159b4a1 100644 --- a/lib/src/phy/io/CMakeLists.txt +++ b/lib/src/phy/io/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/io/binsource.c b/lib/src/phy/io/binsource.c index f25f990f71..dce8b5f528 100644 --- a/lib/src/phy/io/binsource.c +++ b/lib/src/phy/io/binsource.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/io/filesink.c b/lib/src/phy/io/filesink.c index f2d3eb51ee..0b2c5ace2c 100644 --- a/lib/src/phy/io/filesink.c +++ b/lib/src/phy/io/filesink.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -141,7 +141,13 @@ int srsran_filesink_write_multi(srsran_filesink_t* q, void** buffer, int nsample uint32_t count = 0; for (i = 0; i < nsamples; i++) { for (j = 0; j < nchannels; j++) { - count += fwrite(&cbuf[j][i], size, 1, q->f); + if (q->type == SRSRAN_FLOAT_BIN) { + count += fwrite(&fbuf[j][i], size, 1, q->f); + } else if (q->type == SRSRAN_COMPLEX_FLOAT_BIN) { + count += fwrite(&cbuf[j][i], size, 1, q->f); + } else if (q->type == SRSRAN_COMPLEX_SHORT_BIN) { + count += fwrite(&sbuf[j][i], size, 1, q->f); + } } } return count; diff --git a/lib/src/phy/io/filesource.c b/lib/src/phy/io/filesource.c index 0db76b97d2..be07cd8c4b 100644 --- a/lib/src/phy/io/filesource.c +++ b/lib/src/phy/io/filesource.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/io/netsink.c b/lib/src/phy/io/netsink.c index 424f4aedb6..1cc599b41a 100644 --- a/lib/src/phy/io/netsink.c +++ b/lib/src/phy/io/netsink.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/io/netsource.c b/lib/src/phy/io/netsource.c index b8914062ac..b772af0b9c 100644 --- a/lib/src/phy/io/netsource.c +++ b/lib/src/phy/io/netsource.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/mimo/CMakeLists.txt b/lib/src/phy/mimo/CMakeLists.txt index ce1425e94e..8ee39beb58 100644 --- a/lib/src/phy/mimo/CMakeLists.txt +++ b/lib/src/phy/mimo/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/mimo/layermap.c b/lib/src/phy/mimo/layermap.c index d2100084c0..e46cca8ccc 100644 --- a/lib/src/phy/mimo/layermap.c +++ b/lib/src/phy/mimo/layermap.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/mimo/precoding.c b/lib/src/phy/mimo/precoding.c index 2b047d0865..ba04f2f7f2 100644 --- a/lib/src/phy/mimo/precoding.c +++ b/lib/src/phy/mimo/precoding.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/mimo/test/CMakeLists.txt b/lib/src/phy/mimo/test/CMakeLists.txt index aff7c90275..d496ffd7fb 100644 --- a/lib/src/phy/mimo/test/CMakeLists.txt +++ b/lib/src/phy/mimo/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/mimo/test/layermap_test.c b/lib/src/phy/mimo/test/layermap_test.c index 55e4456e4f..e720f66d83 100644 --- a/lib/src/phy/mimo/test/layermap_test.c +++ b/lib/src/phy/mimo/test/layermap_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/mimo/test/pmi_select_test.c b/lib/src/phy/mimo/test/pmi_select_test.c index f09792ec17..9fa4513c44 100644 --- a/lib/src/phy/mimo/test/pmi_select_test.c +++ b/lib/src/phy/mimo/test/pmi_select_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/mimo/test/pmi_select_test.h b/lib/src/phy/mimo/test/pmi_select_test.h index 1d3fbc9894..e5260a4519 100644 --- a/lib/src/phy/mimo/test/pmi_select_test.h +++ b/lib/src/phy/mimo/test/pmi_select_test.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/mimo/test/precoder_test.c b/lib/src/phy/mimo/test/precoder_test.c index 2dfea7006f..b7f5b1105f 100644 --- a/lib/src/phy/mimo/test/precoder_test.c +++ b/lib/src/phy/mimo/test/precoder_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -163,10 +163,10 @@ void populate_channel(srsran_tx_scheme_t type, cf_t* h[SRSRAN_MAX_PORTS][SRSRAN_ static void awgn(cf_t* y[SRSRAN_MAX_PORTS], uint32_t n, float snr) { int i; - float std_dev = srsran_convert_dB_to_amplitude(-(snr + 3.0f)) * scaling; + float var = srsran_convert_dB_to_power(-snr) * scaling * scaling; for (i = 0; i < nof_rx_ports; i++) { - srsran_ch_awgn_c(y[i], y[i], std_dev, n); + srsran_ch_awgn_c(y[i], y[i], var, n); } } diff --git a/lib/src/phy/modem/CMakeLists.txt b/lib/src/phy/modem/CMakeLists.txt index 1df22ed145..312855051e 100644 --- a/lib/src/phy/modem/CMakeLists.txt +++ b/lib/src/phy/modem/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/modem/demod_hard.c b/lib/src/phy/modem/demod_hard.c index 8a654bec30..283b8780a7 100644 --- a/lib/src/phy/modem/demod_hard.c +++ b/lib/src/phy/modem/demod_hard.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/modem/demod_soft.c b/lib/src/phy/modem/demod_soft.c index 524392ab12..8004db3c69 100644 --- a/lib/src/phy/modem/demod_soft.c +++ b/lib/src/phy/modem/demod_soft.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/modem/hard_demod_lte.c b/lib/src/phy/modem/hard_demod_lte.c index 8f50795d87..3fad5636f9 100644 --- a/lib/src/phy/modem/hard_demod_lte.c +++ b/lib/src/phy/modem/hard_demod_lte.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/modem/hard_demod_lte.h b/lib/src/phy/modem/hard_demod_lte.h index f13bdc6a10..b603319c27 100644 --- a/lib/src/phy/modem/hard_demod_lte.h +++ b/lib/src/phy/modem/hard_demod_lte.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/modem/lte_tables.c b/lib/src/phy/modem/lte_tables.c index ff022e61b1..8bc6555980 100644 --- a/lib/src/phy/modem/lte_tables.c +++ b/lib/src/phy/modem/lte_tables.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/modem/lte_tables.h b/lib/src/phy/modem/lte_tables.h index 436865983b..6af9103da3 100644 --- a/lib/src/phy/modem/lte_tables.h +++ b/lib/src/phy/modem/lte_tables.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/modem/mod.c b/lib/src/phy/modem/mod.c index d88c69f4a1..d804ca68da 100644 --- a/lib/src/phy/modem/mod.c +++ b/lib/src/phy/modem/mod.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/modem/modem_table.c b/lib/src/phy/modem/modem_table.c index 6a9f92d680..f234cf33d4 100644 --- a/lib/src/phy/modem/modem_table.c +++ b/lib/src/phy/modem/modem_table.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/modem/test/CMakeLists.txt b/lib/src/phy/modem/test/CMakeLists.txt index a543c10ede..93f06eb8cf 100644 --- a/lib/src/phy/modem/test/CMakeLists.txt +++ b/lib/src/phy/modem/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/modem/test/modem_test.c b/lib/src/phy/modem/test/modem_test.c index 62d05e8147..a4d26b3d4c 100644 --- a/lib/src/phy/modem/test/modem_test.c +++ b/lib/src/phy/modem/test/modem_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/modem/test/soft_demod_test.c b/lib/src/phy/modem/test/soft_demod_test.c index 74ba3b9725..e2cd5d7647 100644 --- a/lib/src/phy/modem/test/soft_demod_test.c +++ b/lib/src/phy/modem/test/soft_demod_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/CMakeLists.txt b/lib/src/phy/phch/CMakeLists.txt index 194bb1acfc..5f6d09e061 100644 --- a/lib/src/phy/phch/CMakeLists.txt +++ b/lib/src/phy/phch/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/phch/cqi.c b/lib/src/phy/phch/cqi.c index dac0e8c793..8b74fe73d7 100644 --- a/lib/src/phy/phch/cqi.c +++ b/lib/src/phy/phch/cqi.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/csi.c b/lib/src/phy/phch/csi.c index b0793c014b..408d9cd494 100644 --- a/lib/src/phy/phch/csi.c +++ b/lib/src/phy/phch/csi.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/dci.c b/lib/src/phy/phch/dci.c index 9efd082ae6..39a716b7f2 100644 --- a/lib/src/phy/phch/dci.c +++ b/lib/src/phy/phch/dci.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -705,7 +705,7 @@ static int dci_format1_unpack(srsran_cell_t* cell, /* Packs DCI format 1A for compact scheduling of PDSCH words according to 36.212 5.3.3.1.3 * - * TODO: RA procedure initiated by PDCCH, TPC commands + * TODO: TPC commands */ static int dci_format1As_pack(srsran_cell_t* cell, srsran_dl_sf_cfg_t* sf, @@ -723,49 +723,64 @@ static int dci_format1As_pack(srsran_cell_t* cell, *y++ = 1; // format differentiation - if (dci->alloc_type != SRSRAN_RA_ALLOC_TYPE2) { - ERROR("Format 1A accepts type2 resource allocation only"); - return SRSRAN_ERROR; - } + // random access procedure initiated by a PDCCH order + if (dci->is_pdcch_order) { + *y++ = 0; // localized or distributed VRB assignment is always 0 for PDCCH order - *y++ = dci->type2_alloc.mode; // localized or distributed VRB assignment + // RIV values all set to 1 for PDCCH order + int nof_bits = riv_nbits(cell->nof_prb); + int i = 0; + while (i < nof_bits) { + *y++ = 1; + i++; + } - /* pack RIV according to 7.1.6.3 of 36.213 */ - uint32_t riv = dci->type2_alloc.riv; - uint32_t nb_gap = 0; - if (SRSRAN_RNTI_ISUSER(dci->rnti) && dci->type2_alloc.mode == SRSRAN_RA_TYPE2_DIST && nof_prb >= 50) { - nb_gap = 1; - *y++ = dci->type2_alloc.n_gap; - } - srsran_bit_unpack(riv, &y, riv_nbits(nof_prb) - nb_gap); + srsran_bit_unpack(dci->preamble_idx, &y, 6); // preamble index + srsran_bit_unpack(dci->prach_mask_idx, &y, 4); // PRACH mask index + } else { + if (dci->alloc_type != SRSRAN_RA_ALLOC_TYPE2) { + ERROR("Format 1A accepts type2 resource allocation only"); + return SRSRAN_ERROR; + } - // in format1A, MCS = TBS according to 7.1.7.2 of 36.213 - srsran_bit_unpack(dci->tb[0].mcs_idx, &y, 5); + *y++ = dci->type2_alloc.mode; // localized or distributed VRB assignment - srsran_bit_unpack(dci->pid, &y, HARQ_PID_LEN); + /* pack RIV according to 7.1.6.3 of 36.213 */ + uint32_t riv = dci->type2_alloc.riv; + uint32_t nb_gap = 0; + if (SRSRAN_RNTI_ISUSER(dci->rnti) && dci->type2_alloc.mode == SRSRAN_RA_TYPE2_DIST && nof_prb >= 50) { + nb_gap = 1; + *y++ = dci->type2_alloc.n_gap; + } + srsran_bit_unpack(riv, &y, riv_nbits(nof_prb) - nb_gap); + + // in format1A, MCS = TBS according to 7.1.7.2 of 36.213 + srsran_bit_unpack(dci->tb[0].mcs_idx, &y, 5); + + srsran_bit_unpack(dci->pid, &y, HARQ_PID_LEN); - if (!SRSRAN_RNTI_ISUSER(dci->rnti)) { - if (nof_prb >= 50 && dci->type2_alloc.mode == SRSRAN_RA_TYPE2_DIST) { - *y++ = dci->type2_alloc.n_gap; + if (!SRSRAN_RNTI_ISUSER(dci->rnti)) { + if (nof_prb >= 50 && dci->type2_alloc.mode == SRSRAN_RA_TYPE2_DIST) { + *y++ = dci->type2_alloc.n_gap; + } else { + y++; // bit reserved + } } else { - y++; // bit reserved + *y++ = dci->tb[0].ndi; } - } else { - *y++ = dci->tb[0].ndi; - } - // rv version - srsran_bit_unpack(dci->tb[0].rv, &y, 2); + // rv version + srsran_bit_unpack(dci->tb[0].rv, &y, 2); - if (SRSRAN_RNTI_ISUSER(dci->rnti)) { - // TPC not implemented - *y++ = 0; - *y++ = 0; - } else { - y++; // MSB of TPC is reserved - *y++ = dci->type2_alloc.n_prb1a; // LSB indicates N_prb_1a for TBS + if (SRSRAN_RNTI_ISUSER(dci->rnti)) { + // TPC not implemented + *y++ = 0; + *y++ = 0; + } else { + y++; // MSB of TPC is reserved + *y++ = dci->type2_alloc.n_prb1a; // LSB indicates N_prb_1a for TBS + } } - // Padding with zeros uint32_t n = srsran_dci_format_sizeof(cell, sf, cfg, SRSRAN_DCI_FORMAT1A); while (y - msg->payload < n) { @@ -819,16 +834,16 @@ static int dci_format1As_unpack(srsran_cell_t* cell, // This is a Random access order y += 1 + nof_bits; - dci->is_ra_order = true; - dci->ra_preamble = srsran_bit_pack(&y, 6); - dci->ra_mask_idx = srsran_bit_pack(&y, 4); + dci->is_pdcch_order = true; + dci->preamble_idx = srsran_bit_pack(&y, 6); + dci->prach_mask_idx = srsran_bit_pack(&y, 4); return SRSRAN_SUCCESS; } } } - dci->is_ra_order = false; + dci->is_pdcch_order = false; dci->alloc_type = SRSRAN_RA_ALLOC_TYPE2; dci->type2_alloc.mode = *y++; @@ -1553,36 +1568,46 @@ static char* freq_hop_fl_string(int freq_hop) void srsran_dci_dl_fprint(FILE* f, srsran_dci_dl_t* dci, uint32_t nof_prb) { - fprintf(f, " - Resource Allocation Type:\t\t%s\n", ra_type_string(dci->alloc_type)); - switch (dci->alloc_type) { - case SRSRAN_RA_ALLOC_TYPE0: - fprintf(f, " + Resource Block Group Size:\t\t%d\n", srsran_ra_type0_P(nof_prb)); - fprintf(f, " + RBG Bitmap:\t\t\t0x%x\n", dci->type0_alloc.rbg_bitmask); - break; - case SRSRAN_RA_ALLOC_TYPE1: - fprintf(f, " + Resource Block Group Size:\t\t%d\n", srsran_ra_type0_P(nof_prb)); - fprintf(f, " + RBG Bitmap:\t\t\t0x%x\n", dci->type1_alloc.vrb_bitmask); - fprintf(f, " + RBG Subset:\t\t\t%d\n", dci->type1_alloc.rbg_subset); - fprintf(f, " + RBG Shift:\t\t\t\t%s\n", dci->type1_alloc.shift ? "Yes" : "No"); - break; - case SRSRAN_RA_ALLOC_TYPE2: - fprintf(f, " + Type:\t\t\t\t%s\n", dci->type2_alloc.mode == SRSRAN_RA_TYPE2_LOC ? "Localized" : "Distributed"); - fprintf(f, " + Resource Indicator Value:\t\t%d\n", dci->type2_alloc.riv); - break; - } - if (dci->cif_present) { - fprintf(f, " - Carrier idx:\t\t\t\t%d\n", dci->cif); - } - fprintf(f, " - HARQ process:\t\t\t%d\n", dci->pid); - fprintf(f, " - TPC command for PUCCH:\t\t--\n"); - fprintf(f, " - Transport blocks swapped:\t\t%s\n", (dci->tb_cw_swap) ? "true" : "false"); + if (dci->is_pdcch_order) { + fprintf(f, "PDCCH order:\n"); + if (dci->cif_present) { + fprintf(f, " - Carrier idx:\t\t\t\t%d\n", dci->cif); + } + fprintf(f, " - Preamble index:\t\t%d\n", dci->preamble_idx); + fprintf(f, " - PRACH mask index:\t\t%d\n", dci->prach_mask_idx); + } else { + fprintf(f, " - Resource Allocation Type:\t\t%s\n", ra_type_string(dci->alloc_type)); + switch (dci->alloc_type) { + case SRSRAN_RA_ALLOC_TYPE0: + fprintf(f, " + Resource Block Group Size:\t\t%d\n", srsran_ra_type0_P(nof_prb)); + fprintf(f, " + RBG Bitmap:\t\t\t0x%x\n", dci->type0_alloc.rbg_bitmask); + break; + case SRSRAN_RA_ALLOC_TYPE1: + fprintf(f, " + Resource Block Group Size:\t\t%d\n", srsran_ra_type0_P(nof_prb)); + fprintf(f, " + RBG Bitmap:\t\t\t0x%x\n", dci->type1_alloc.vrb_bitmask); + fprintf(f, " + RBG Subset:\t\t\t%d\n", dci->type1_alloc.rbg_subset); + fprintf(f, " + RBG Shift:\t\t\t\t%s\n", dci->type1_alloc.shift ? "Yes" : "No"); + break; + case SRSRAN_RA_ALLOC_TYPE2: + fprintf( + f, " + Type:\t\t\t\t%s\n", dci->type2_alloc.mode == SRSRAN_RA_TYPE2_LOC ? "Localized" : "Distributed"); + fprintf(f, " + Resource Indicator Value:\t\t%d\n", dci->type2_alloc.riv); + break; + } + if (dci->cif_present) { + fprintf(f, " - Carrier idx:\t\t\t\t%d\n", dci->cif); + } + fprintf(f, " - HARQ process:\t\t\t%d\n", dci->pid); + fprintf(f, " - TPC command for PUCCH:\t\t--\n"); + fprintf(f, " - Transport blocks swapped:\t\t%s\n", (dci->tb_cw_swap) ? "true" : "false"); - for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { - fprintf(f, " - Transport block %d enabled:\t\t%s\n", i, SRSRAN_DCI_IS_TB_EN(dci->tb[i]) ? "true" : "false"); - if (SRSRAN_DCI_IS_TB_EN(dci->tb[i])) { - fprintf(f, " + Modulation and coding scheme index:\t%d\n", dci->tb[i].mcs_idx); - fprintf(f, " + New data indicator:\t\t\t%s\n", dci->tb[i].ndi ? "Yes" : "No"); - fprintf(f, " + Redundancy version:\t\t\t%d\n", dci->tb[i].rv); + for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { + fprintf(f, " - Transport block %d enabled:\t\t%s\n", i, SRSRAN_DCI_IS_TB_EN(dci->tb[i]) ? "true" : "false"); + if (SRSRAN_DCI_IS_TB_EN(dci->tb[i])) { + fprintf(f, " + Modulation and coding scheme index:\t%d\n", dci->tb[i].mcs_idx); + fprintf(f, " + New data indicator:\t\t\t%s\n", dci->tb[i].ndi ? "Yes" : "No"); + fprintf(f, " + Redundancy version:\t\t\t%d\n", dci->tb[i].rv); + } } } } @@ -1627,46 +1652,51 @@ uint32_t srsran_dci_dl_info(const srsran_dci_dl_t* dci_dl, char* info_str, uint3 n = srsran_print_check(info_str, len, n, ", cif=%d", dci_dl->cif); } - switch (dci_dl->alloc_type) { - case SRSRAN_RA_ALLOC_TYPE0: - n = srsran_print_check(info_str, len, n, ", rbg=0x%x", dci_dl->type0_alloc.rbg_bitmask); - break; - case SRSRAN_RA_ALLOC_TYPE1: - n = srsran_print_check(info_str, - len, - n, - ", vrb=0x%x, rbg_s=%d, sh=%d", - dci_dl->type1_alloc.vrb_bitmask, - dci_dl->type1_alloc.rbg_subset, - dci_dl->type1_alloc.shift); - break; - case SRSRAN_RA_ALLOC_TYPE2: - n = srsran_print_check(info_str, len, n, ", riv=%d", dci_dl->type2_alloc.riv); - break; - } + if (dci_dl->is_pdcch_order) { + n = srsran_print_check(info_str, len, n, ", preamb_idx=%d", dci_dl->preamble_idx); + n = srsran_print_check(info_str, len, n, ", prach_mask_idx=%d", dci_dl->prach_mask_idx); + } else { + switch (dci_dl->alloc_type) { + case SRSRAN_RA_ALLOC_TYPE0: + n = srsran_print_check(info_str, len, n, ", rbg=0x%x", dci_dl->type0_alloc.rbg_bitmask); + break; + case SRSRAN_RA_ALLOC_TYPE1: + n = srsran_print_check(info_str, + len, + n, + ", vrb=0x%x, rbg_s=%d, sh=%d", + dci_dl->type1_alloc.vrb_bitmask, + dci_dl->type1_alloc.rbg_subset, + dci_dl->type1_alloc.shift); + break; + case SRSRAN_RA_ALLOC_TYPE2: + n = srsran_print_check(info_str, len, n, ", riv=%d", dci_dl->type2_alloc.riv); + break; + } - n = srsran_print_check(info_str, len, n, ", pid=%d", dci_dl->pid); + n = srsran_print_check(info_str, len, n, ", pid=%d", dci_dl->pid); - n = srsran_print_check(info_str, len, n, ", mcs={"); - n = print_multi(info_str, n, len, dci_dl, 0); - n = srsran_print_check(info_str, len, n, "}"); - n = srsran_print_check(info_str, len, n, ", ndi={"); - n = print_multi(info_str, n, len, dci_dl, 2); - n = srsran_print_check(info_str, len, n, "}"); + n = srsran_print_check(info_str, len, n, ", mcs={"); + n = print_multi(info_str, n, len, dci_dl, 0); + n = srsran_print_check(info_str, len, n, "}"); + n = srsran_print_check(info_str, len, n, ", ndi={"); + n = print_multi(info_str, n, len, dci_dl, 2); + n = srsran_print_check(info_str, len, n, "}"); - if (dci_dl->format == SRSRAN_DCI_FORMAT1 || dci_dl->format == SRSRAN_DCI_FORMAT1A || - dci_dl->format == SRSRAN_DCI_FORMAT1B || dci_dl->format == SRSRAN_DCI_FORMAT2 || - dci_dl->format == SRSRAN_DCI_FORMAT2A || dci_dl->format == SRSRAN_DCI_FORMAT2B) { - n = srsran_print_check(info_str, len, n, ", tpc_pucch=%d", dci_dl->tpc_pucch); - } + if (dci_dl->format == SRSRAN_DCI_FORMAT1 || dci_dl->format == SRSRAN_DCI_FORMAT1A || + dci_dl->format == SRSRAN_DCI_FORMAT1B || dci_dl->format == SRSRAN_DCI_FORMAT2 || + dci_dl->format == SRSRAN_DCI_FORMAT2A || dci_dl->format == SRSRAN_DCI_FORMAT2B) { + n = srsran_print_check(info_str, len, n, ", tpc_pucch=%d", dci_dl->tpc_pucch); + } - if (dci_dl->is_tdd) { - n = srsran_print_check(info_str, len, n, ", dai=%d", dci_dl->dai); - } + if (dci_dl->is_tdd) { + n = srsran_print_check(info_str, len, n, ", dai=%d", dci_dl->dai); + } - if (dci_dl->format == SRSRAN_DCI_FORMAT2 || dci_dl->format == SRSRAN_DCI_FORMAT2A || - dci_dl->format == SRSRAN_DCI_FORMAT2B) { - n = srsran_print_check(info_str, len, n, ", tb_sw=%d, pinfo=%d", dci_dl->tb_cw_swap, dci_dl->pinfo); + if (dci_dl->format == SRSRAN_DCI_FORMAT2 || dci_dl->format == SRSRAN_DCI_FORMAT2A || + dci_dl->format == SRSRAN_DCI_FORMAT2B) { + n = srsran_print_check(info_str, len, n, ", tb_sw=%d, pinfo=%d", dci_dl->tb_cw_swap, dci_dl->pinfo); + } } #if SRSRAN_DCI_HEXDEBUG diff --git a/lib/src/phy/phch/dci_nbiot.c b/lib/src/phy/phch/dci_nbiot.c index 2b7d941c67..8ec4ca9c75 100644 --- a/lib/src/phy/phch/dci_nbiot.c +++ b/lib/src/phy/phch/dci_nbiot.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/dci_nr.c b/lib/src/phy/phch/dci_nr.c index 5646d7557b..6c9fb0ad27 100644 --- a/lib/src/phy/phch/dci_nr.c +++ b/lib/src/phy/phch/dci_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -1282,6 +1282,7 @@ static uint32_t dci_nr_format_1_0_to_str(const srsran_dci_dl_nr_t* dci, char* st // System information indicator – 1 bit if (rnti_type == srsran_rnti_type_si) { len = srsran_print_check(str, str_len, len, "sii=%d ", dci->sii); + len = srsran_print_check(str, str_len, len, "coreset0_bw=%d ", dci->coreset0_bw); } // Downlink assignment index – 2 bits @@ -2079,7 +2080,7 @@ uint32_t srsran_dci_ctx_to_str(const srsran_dci_ctx_t* ctx, char* str, uint32_t len = srsran_print_check(str, str_len, len, - "%s-rnti=%04x dci=%s ss=%s ", + "%s-rnti=0x%04x dci=%s ss=%s ", srsran_rnti_type_str_short(ctx->rnti_type), ctx->rnti, srsran_dci_format_nr_string(ctx->format), diff --git a/lib/src/phy/phch/harq_ack.c b/lib/src/phy/phch/harq_ack.c index 4751e32e5f..32aa8ab436 100644 --- a/lib/src/phy/phch/harq_ack.c +++ b/lib/src/phy/phch/harq_ack.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -88,6 +88,7 @@ static int harq_ack_gen_ack_type2(const srsran_harq_ack_cfg_hl_t* cfg, if (ack->present) { // Load ACK resource data into UCI info uci_cfg->pucch.resource_id = ack_info->cc[c].m[m].resource.pucch_resource_id; + uci_cfg->pucch.n_cce_0 = ack_info->cc[c].m[m].resource.n_cce; uci_cfg->pucch.rnti = ack_info->cc[c].m[m].resource.rnti; if (V_DL_CDAI <= V_temp) { @@ -183,6 +184,7 @@ int srsran_harq_ack_resource(const srsran_harq_ack_cfg_hl_t* cfg, pdsch_ack_resource->v_dai_dl = dci_dl->dai; pdsch_ack_resource->rnti = dci_dl->ctx.rnti; pdsch_ack_resource->pucch_resource_id = dci_dl->pucch_resource; + pdsch_ack_resource->n_cce = dci_dl->ctx.location.ncce; pdsch_ack_resource->pid = dci_dl->pid; return SRSRAN_SUCCESS; diff --git a/lib/src/phy/phch/mib_sl.c b/lib/src/phy/phch/mib_sl.c index 89496dbdc5..cca8852cb8 100644 --- a/lib/src/phy/phch/mib_sl.c +++ b/lib/src/phy/phch/mib_sl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/npbch.c b/lib/src/phy/phch/npbch.c index 32f9be103f..23df742e1f 100644 --- a/lib/src/phy/phch/npbch.c +++ b/lib/src/phy/phch/npbch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/npdcch.c b/lib/src/phy/phch/npdcch.c index 0fd4da5241..70f9332f81 100644 --- a/lib/src/phy/phch/npdcch.c +++ b/lib/src/phy/phch/npdcch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/npdsch.c b/lib/src/phy/phch/npdsch.c index e0379f3b86..c1ca63da3d 100644 --- a/lib/src/phy/phch/npdsch.c +++ b/lib/src/phy/phch/npdsch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pbch.c b/lib/src/phy/phch/pbch.c index 59a9cb0cd7..9783728447 100644 --- a/lib/src/phy/phch/pbch.c +++ b/lib/src/phy/phch/pbch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pbch_msg_nr.c b/lib/src/phy/phch/pbch_msg_nr.c index bef169f41c..1e57c29012 100644 --- a/lib/src/phy/phch/pbch_msg_nr.c +++ b/lib/src/phy/phch/pbch_msg_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pbch_nr.c b/lib/src/phy/phch/pbch_nr.c index 4aaf2b294b..df397d98ac 100644 --- a/lib/src/phy/phch/pbch_nr.c +++ b/lib/src/phy/phch/pbch_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -637,10 +637,23 @@ int srsran_pbch_nr_decode(srsran_pbch_nr_t* q, return SRSRAN_ERROR; } + // Avoid NAN getting into the demodulator + for (uint32_t i = 0; i < PBCH_NR_M; i++) { + if (isnan(__real__ symbols[i]) || isnan(__imag__ symbols[i])) { + symbols[i] = 0.0f; + } + } + // 7.3.3.2 Modulation int8_t llr[PBCH_NR_E]; srsran_demod_soft_demodulate_b(SRSRAN_MOD_QPSK, symbols, llr, PBCH_NR_M); + // If all LLR are zero, no message could be received + if (srsran_vec_avg_power_bf(llr, PBCH_NR_E) == 0) { + SRSRAN_MEM_ZERO(msg, srsran_pbch_msg_nr_t, 1); + return SRSRAN_SUCCESS; + } + // TS 38.211 7.3.3 Physical broadcast channel // 7.3.3.1 Scrambling pbch_nr_scramble_rx(cfg, cfg->ssb_idx, llr, llr); diff --git a/lib/src/phy/phch/pcfich.c b/lib/src/phy/phch/pcfich.c index da32a45d3a..308dd0cc64 100644 --- a/lib/src/phy/phch/pcfich.c +++ b/lib/src/phy/phch/pcfich.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pdcch.c b/lib/src/phy/phch/pdcch.c index adbeebb5d8..0272b20e8a 100644 --- a/lib/src/phy/phch/pdcch.c +++ b/lib/src/phy/phch/pdcch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pdcch_nr.c b/lib/src/phy/phch/pdcch_nr.c index e8f6afc932..846c0f462d 100644 --- a/lib/src/phy/phch/pdcch_nr.c +++ b/lib/src/phy/phch/pdcch_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -313,19 +313,6 @@ int srsran_pdcch_nr_set_carrier(srsran_pdcch_nr_t* q, return SRSRAN_SUCCESS; } -static uint32_t pdcch_nr_bundle_size(srsran_coreset_bundle_size_t x) -{ - switch (x) { - case srsran_coreset_bundle_size_n2: - return 2; - case srsran_coreset_bundle_size_n3: - return 3; - case srsran_coreset_bundle_size_n6: - return 6; - } - return 0; -} - static int pdcch_nr_cce_to_reg_mapping_non_interleaved(const srsran_coreset_t* coreset, const srsran_dci_location_t* dci_location, bool rb_mask[SRSRAN_MAX_PRB_NR]) diff --git a/lib/src/phy/phch/pdsch.c b/lib/src/phy/phch/pdsch.c index ee7845bf85..56eb005f1f 100644 --- a/lib/src/phy/phch/pdsch.c +++ b/lib/src/phy/phch/pdsch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pdsch_nr.c b/lib/src/phy/phch/pdsch_nr.c index 9762e6bdc7..9fc0be4fab 100644 --- a/lib/src/phy/phch/pdsch_nr.c +++ b/lib/src/phy/phch/pdsch_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/phch_cfg_nr.c b/lib/src/phy/phch/phch_cfg_nr.c index 8c14c2b39b..22580892ec 100644 --- a/lib/src/phy/phch/phch_cfg_nr.c +++ b/lib/src/phy/phch/phch_cfg_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -260,7 +260,7 @@ uint32_t srsran_sch_cfg_nr_info(const srsran_sch_cfg_nr_t* sch_cfg, char* str, u // Append SCH information len += phch_cfg_sch_to_str(&sch_cfg->sch_cfg, &str[len], str_len - len); - // Append SCH information + // Append reserved RE information len += phch_cfg_rvd_to_str(&sch_cfg->rvd_re, &str[len], str_len - len); // UCI configuration diff --git a/lib/src/phy/phch/phich.c b/lib/src/phy/phch/phich.c index 3efdc91700..e08b42b15b 100644 --- a/lib/src/phy/phch/phich.c +++ b/lib/src/phy/phch/phich.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pmch.c b/lib/src/phy/phch/pmch.c index ec4c62f93c..638d999818 100644 --- a/lib/src/phy/phch/pmch.c +++ b/lib/src/phy/phch/pmch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/prach.c b/lib/src/phy/phch/prach.c index 956820a640..0c3bdbe7d1 100644 --- a/lib/src/phy/phch/prach.c +++ b/lib/src/phy/phch/prach.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/prach_tables.h b/lib/src/phy/phch/prach_tables.h index de89cec394..e7ec9b21cd 100644 --- a/lib/src/phy/phch/prach_tables.h +++ b/lib/src/phy/phch/prach_tables.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/prb_dl.c b/lib/src/phy/phch/prb_dl.c index 025149b922..3c7e5b725b 100644 --- a/lib/src/phy/phch/prb_dl.c +++ b/lib/src/phy/phch/prb_dl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/prb_dl.h b/lib/src/phy/phch/prb_dl.h index 3002ec2063..f949ae4e0b 100644 --- a/lib/src/phy/phch/prb_dl.h +++ b/lib/src/phy/phch/prb_dl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/psbch.c b/lib/src/phy/phch/psbch.c index 2702607758..81d948ff21 100644 --- a/lib/src/phy/phch/psbch.c +++ b/lib/src/phy/phch/psbch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pscch.c b/lib/src/phy/phch/pscch.c index 8148abddbe..9d2c476648 100644 --- a/lib/src/phy/phch/pscch.c +++ b/lib/src/phy/phch/pscch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pssch.c b/lib/src/phy/phch/pssch.c index 8a6594c552..3120187919 100644 --- a/lib/src/phy/phch/pssch.c +++ b/lib/src/phy/phch/pssch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pucch.c b/lib/src/phy/phch/pucch.c index 6edcddc5d4..1d21b6c7bc 100644 --- a/lib/src/phy/phch/pucch.c +++ b/lib/src/phy/phch/pucch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pucch_cfg_nr.c b/lib/src/phy/phch/pucch_cfg_nr.c index c554461261..4d12889aca 100644 --- a/lib/src/phy/phch/pucch_cfg_nr.c +++ b/lib/src/phy/phch/pucch_cfg_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -169,7 +169,8 @@ int srsran_pucch_nr_cfg_resource_valid(const srsran_pucch_nr_resource_t* resourc return SRSRAN_ERROR; } - if (resource->intra_slot_hopping) { + // Frequency hopping is only possible with Format 1 + if (resource->intra_slot_hopping && resource->format != SRSRAN_PUCCH_NR_FORMAT_1) { ERROR("Intra-slot hopping is not implemented"); return SRSRAN_ERROR; } diff --git a/lib/src/phy/phch/pucch_nr.c b/lib/src/phy/phch/pucch_nr.c index 920eec721d..c45ea14b2d 100644 --- a/lib/src/phy/phch/pucch_nr.c +++ b/lib/src/phy/phch/pucch_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -406,6 +406,8 @@ int srsran_pucch_nr_format1_encode(const srsran_pucch_nr_t* q, srsran_mod_modulate(&q->qpsk, b, d, 2); } + INFO("[PUCCH Format 1 Data TX] d=%+.3f%+.3f", __real__ d[0], __imag__ d[0]); + // Get group sequence uint32_t u = 0; uint32_t v = 0; @@ -414,41 +416,60 @@ int srsran_pucch_nr_format1_encode(const srsran_pucch_nr_t* q, return SRSRAN_ERROR; } - // Calculate number of symbols carrying PUCCH (No DMRS) - uint32_t n_pucch = pucch_nr_format1_n_pucch(resource, 0); - + // First symbol of this PUCCH transmission uint32_t l_prime = resource->start_symbol_idx; - for (uint32_t l = 1, m = 0; l < resource->nof_symbols; l += 2, m++) { - // Get start of the sequence in resource grid - cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSRAN_NRE]; - // Get Alpha index - uint32_t alpha_idx = 0; - if (srsran_pucch_nr_alpha_idx(&q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) < - SRSRAN_SUCCESS) { - return SRSRAN_ERROR; - } + // For each hop + for (uint32_t m_prime = 0, l = 1; m_prime < (resource->intra_slot_hopping ? 2 : 1); m_prime++) { + // Calculate number of symbols carrying PUCCH (No DMRS) + uint32_t n_pucch = pucch_nr_format1_n_pucch(resource, m_prime); - // get r_uv sequence from LUT object - const cf_t* r_uv = srsran_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); - if (r_uv == NULL) { - ERROR("Getting r_uv sequence"); - return SRSRAN_ERROR; - } + // Get the starting PRB + uint32_t starting_prb = (m_prime == 0) ? resource->starting_prb : resource->second_hop_prb; - // Compute y = d(0) * r_uv - cf_t y[SRSRAN_NRE]; - srsran_vec_sc_prod_ccc(r_uv, d[0], y, SRSRAN_NRE); + // For each symbol carrying PUCCH data + for (uint32_t m = 0; m < n_pucch; m++, l += 2) { + // Get start of the sequence in resource grid + cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + starting_prb) * SRSRAN_NRE]; - // Get w_i_m - cf_t w_i_m = srsran_pucch_nr_format1_w(q, n_pucch, resource->time_domain_occ, m); + // Get Alpha index + uint32_t alpha_idx = 0; + if (srsran_pucch_nr_alpha_idx(&q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, 0, &alpha_idx) < + SRSRAN_SUCCESS) { + return SRSRAN_ERROR; + } + + // get r_uv sequence from LUT object + const cf_t* r_uv = srsran_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); + if (r_uv == NULL) { + ERROR("Getting r_uv sequence"); + return SRSRAN_ERROR; + } + + // Get w_i_m + cf_t w_i_m = srsran_pucch_nr_format1_w(q, n_pucch, resource->time_domain_occ, m); - // Compute z(n) = w(i) * y(n) - cf_t z[SRSRAN_NRE]; - srsran_vec_sc_prod_ccc(y, w_i_m, z, SRSRAN_NRE); + // Compute z(n) = w(i) * r_uv(n) + cf_t z[SRSRAN_NRE]; + srsran_vec_sc_prod_ccc(r_uv, w_i_m, z, SRSRAN_NRE); - // Put z in the grid - srsran_vec_cf_copy(slot_symbols_ptr, z, SRSRAN_NRE); + if (SRSRAN_DEBUG_ENABLED && get_srsran_verbose_level() >= SRSRAN_VERBOSE_INFO && !is_handler_registered()) { + printf("[PUCCH Format 1 Data TX] m_prime=%d; m=%d; w_i_m=%+.3f%+.3f z=", + m_prime, + m, + __real__ w_i_m, + __imag__ w_i_m); + srsran_vec_fprint_c(stdout, z, SRSRAN_NRE); + } + + // Put z in the grid + srsran_vec_sc_prod_ccc(z, d[0], slot_symbols_ptr, SRSRAN_NRE); + + if (SRSRAN_DEBUG_ENABLED && get_srsran_verbose_level() >= SRSRAN_VERBOSE_INFO && !is_handler_registered()) { + printf("[PUCCH Format 1 TX] l=%d; x=", l + l_prime); + srsran_vec_fprint_c(stdout, slot_symbols_ptr, SRSRAN_NRE); + } + } } return SRSRAN_SUCCESS; @@ -493,46 +514,79 @@ int srsran_pucch_nr_format1_decode(srsran_pucch_nr_t* q, return SRSRAN_ERROR; } - // Calculate number of symbols carrying PUCCH (No DMRS) - uint32_t n_pucch = pucch_nr_format1_n_pucch(resource, 0); - + // First symbol of this PUCCH transmission uint32_t l_prime = resource->start_symbol_idx; - for (uint32_t l = 1, m = 0; l < resource->nof_symbols; l += 2, m++) { - // Get start of the sequence in resource grid - cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSRAN_NRE]; - cf_t* ce_ptr = &chest_res->ce[(q->carrier.nof_prb * (l + l_prime) + resource->starting_prb) * SRSRAN_NRE]; - // Equalise x = w(i) * d' * r_uv(n) - cf_t x[SRSRAN_NRE]; - srsran_predecoding_single(slot_symbols_ptr, ce_ptr, x, NULL, SRSRAN_NRE, 1.0f, chest_res->noise_estimate); + // For each hop + uint32_t n_pucch_sum = 0; + for (uint32_t m_prime = 0, l = 1; m_prime < (resource->intra_slot_hopping ? 2 : 1); m_prime++) { + // Calculate number of symbols carrying PUCCH (No DMRS) + uint32_t n_pucch = pucch_nr_format1_n_pucch(resource, m_prime); + + // Get the starting PRB + uint32_t starting_prb = (m_prime == 0) ? resource->starting_prb : resource->second_hop_prb; + + // For each symbol carrying PUCCH data + for (uint32_t m = 0; m < n_pucch; m++, l += 2) { + // Get start of the sequence in resource grid + cf_t* slot_symbols_ptr = &slot_symbols[(q->carrier.nof_prb * (l + l_prime) + starting_prb) * SRSRAN_NRE]; + cf_t* ce_ptr = &chest_res->ce[SRSRAN_NRE * n_pucch_sum]; + n_pucch_sum++; + + if (SRSRAN_DEBUG_ENABLED && get_srsran_verbose_level() >= SRSRAN_VERBOSE_INFO && !is_handler_registered()) { + printf("[PUCCH Format 1 CE RX] ce="); + srsran_vec_fprint_c(stdout, ce_ptr, SRSRAN_NRE); + } - // Get Alpha index - uint32_t alpha_idx = 0; - if (srsran_pucch_nr_alpha_idx( - &q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < SRSRAN_SUCCESS) { - return SRSRAN_ERROR; - } + // Equalise x = w(i) * d' * r_uv(n) + cf_t x[SRSRAN_NRE]; + srsran_predecoding_single(slot_symbols_ptr, ce_ptr, x, NULL, SRSRAN_NRE, 1.0f, chest_res->noise_estimate); - // get r_uv sequence from LUT object - const cf_t* r_uv = srsran_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); - if (r_uv == NULL) { - ERROR("Getting r_uv sequence"); - return SRSRAN_ERROR; - } - // Get w_i_m - cf_t w_i_m = srsran_pucch_nr_format1_w(q, n_pucch, resource->time_domain_occ, m); + if (SRSRAN_DEBUG_ENABLED && get_srsran_verbose_level() >= SRSRAN_VERBOSE_INFO && !is_handler_registered()) { + printf("[PUCCH Format 1 RX] l=%d; x=", l + l_prime); + srsran_vec_fprint_c(stdout, x, SRSRAN_NRE); + } - // Compute z(n) = w(i) * r_uv(n) - cf_t z[SRSRAN_NRE]; - srsran_vec_sc_prod_ccc(r_uv, w_i_m, z, SRSRAN_NRE); + // Get Alpha index + uint32_t alpha_idx = 0; + if (srsran_pucch_nr_alpha_idx( + &q->carrier, cfg, slot, l, l_prime, resource->initial_cyclic_shift, m_cs, &alpha_idx) < SRSRAN_SUCCESS) { + return SRSRAN_ERROR; + } + + // get r_uv sequence from LUT object + const cf_t* r_uv = srsran_zc_sequence_lut_get(&q->r_uv_1prb, u, v, alpha_idx); + if (r_uv == NULL) { + ERROR("Getting r_uv sequence"); + return SRSRAN_ERROR; + } - // Compute d = sum(x * conj(w(i) * r_uv(n))) = sum(w(i) * d' * r_uv(n) * conj(w(i) * r_uv(n))) = d' - d += srsran_vec_dot_prod_conj_ccc(x, z, SRSRAN_NRE) / SRSRAN_NRE; + // Get w_i_m + cf_t w_i_m = srsran_pucch_nr_format1_w(q, n_pucch, resource->time_domain_occ, m); - // Compute and accumulate average symbol power - pwr_acc += srsran_vec_avg_power_cf(x, SRSRAN_NRE); + // Compute z(n) = w(i) * r_uv(n) + cf_t z[SRSRAN_NRE]; + srsran_vec_sc_prod_ccc(r_uv, w_i_m, z, SRSRAN_NRE); + + if (SRSRAN_DEBUG_ENABLED && get_srsran_verbose_level() >= SRSRAN_VERBOSE_INFO && !is_handler_registered()) { + printf("[PUCCH Format 1 Data RX] m_prime=%d; m=%d; w_i_m=%+.3f%+.3f z=", + m_prime, + m, + __real__ w_i_m, + __imag__ w_i_m); + srsran_vec_fprint_c(stdout, z, SRSRAN_NRE); + } + + // Compute d = sum(x * conj(w(i) * r_uv(n))) = sum(w(i) * d' * r_uv(n) * conj(w(i) * r_uv(n))) = d' + d += srsran_vec_dot_prod_conj_ccc(x, z, SRSRAN_NRE) / SRSRAN_NRE; + + // Compute and accumulate average symbol power + pwr_acc += srsran_vec_avg_power_cf(x, SRSRAN_NRE); + } } + INFO("[PUCCH Format 1 Data RX] d=%+.3f%+.3f", __real__ d, __imag__ d); + // Demodulate d float llr[SRSRAN_PUCCH_NR_FORMAT1_MAX_NOF_BITS]; srsran_demod_soft_demodulate((nof_bits == 1) ? SRSRAN_MOD_BPSK : SRSRAN_MOD_QPSK, &d, llr, 1); diff --git a/lib/src/phy/phch/pucch_proc.c b/lib/src/phy/phch/pucch_proc.c index fb0e457e7b..2f294e2aba 100644 --- a/lib/src/phy/phch/pucch_proc.c +++ b/lib/src/phy/phch/pucch_proc.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pusch.c b/lib/src/phy/phch/pusch.c index 9740c4f93c..df89996ea3 100644 --- a/lib/src/phy/phch/pusch.c +++ b/lib/src/phy/phch/pusch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index 6cea465d68..8dc0ee928d 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -734,7 +734,7 @@ int srsran_pusch_nr_encode(srsran_pusch_nr_t* q, return SRSRAN_ERROR; } - // 7.3.1.1 and 7.3.1.2 + // 6.3.1.1 and 6.3.1.2 uint32_t nof_cw = 0; for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) { nof_cw += grant->tb[tb].enabled ? 1 : 0; @@ -746,20 +746,23 @@ int srsran_pusch_nr_encode(srsran_pusch_nr_t* q, } } - // 7.3.1.3 Layer mapping + // 6.3.1.3 Layer mapping cf_t** x = q->d; if (grant->nof_layers > 1) { x = q->x; srsran_layermap_nr(q->d, nof_cw, x, grant->nof_layers, grant->nof_layers); } - // 7.3.1.4 Antenna port mapping + // 6.3.1.4 Transform precoding // ... Not implemented - // 7.3.1.5 Mapping to virtual resource blocks + // 6.3.1.5 Precoding // ... Not implemented - // 7.3.1.6 Mapping from virtual to physical resource blocks + // 6.3.1.6 Mapping to virtual resource blocks + // ... Not implemented + + // 6.3.1.7 Mapping from virtual to physical resource blocks int n = pusch_nr_put(q, cfg, grant, x[0], sf_symbols[0]); if (n < SRSRAN_SUCCESS) { ERROR("Putting NR PUSCH resources"); diff --git a/lib/src/phy/phch/ra.c b/lib/src/phy/phch/ra.c index e0fa51dbea..cca6855c75 100644 --- a/lib/src/phy/phch/ra.c +++ b/lib/src/phy/phch/ra.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/ra_dl.c b/lib/src/phy/phch/ra_dl.c index f9c881eb0f..ed5c95fac4 100644 --- a/lib/src/phy/phch/ra_dl.c +++ b/lib/src/phy/phch/ra_dl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/ra_dl_nr.c b/lib/src/phy/phch/ra_dl_nr.c index 2f8bcd1d8b..675fbe30e6 100644 --- a/lib/src/phy/phch/ra_dl_nr.c +++ b/lib/src/phy/phch/ra_dl_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -149,7 +149,8 @@ int srsran_ra_dl_nr_time(const srsran_sch_hl_cfg_nr_t* cfg, // Determine which PDSCH Time domain RA configuration to apply (TS 38.214 Table 5.1.2.1.1-1) if (rnti_type == srsran_rnti_type_si && ss_type == srsran_search_space_type_common_0) { // Row 1 - ERROR("Row not implemented"); + // Note: Only Default A is supported, which corresponds SS/PBCH block and coreset mux pattern 1 + srsran_ra_dl_nr_time_default_A(m, cfg->typeA_pos, grant); } else if (rnti_type == srsran_rnti_type_si && ss_type == srsran_search_space_type_common_0A) { // Row 2 ERROR("Row not implemented"); diff --git a/lib/src/phy/phch/ra_helper.h b/lib/src/phy/phch/ra_helper.h index 4c3be544d6..b105f4fa6f 100644 --- a/lib/src/phy/phch/ra_helper.h +++ b/lib/src/phy/phch/ra_helper.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/ra_nbiot.c b/lib/src/phy/phch/ra_nbiot.c index 8e75a06b97..644651acd6 100644 --- a/lib/src/phy/phch/ra_nbiot.c +++ b/lib/src/phy/phch/ra_nbiot.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/ra_nr.c b/lib/src/phy/phch/ra_nr.c index 35680f3c36..9aa22c5d8e 100644 --- a/lib/src/phy/phch/ra_nr.c +++ b/lib/src/phy/phch/ra_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -28,6 +28,7 @@ #include "srsran/phy/phch/ra_ul_nr.h" #include "srsran/phy/phch/uci_nr.h" #include "srsran/phy/utils/debug.h" +#include /* floor */ typedef struct { srsran_mod_t modulation; @@ -39,6 +40,7 @@ typedef struct { #define RA_NR_MCS_SIZE_TABLE2 28 #define RA_NR_MCS_SIZE_TABLE3 29 #define RA_NR_TBS_SIZE_TABLE 93 +#define RA_NR_CQI_TABLE_SIZE 16 #define RA_NR_BETA_OFFSET_HARQACK_SIZE 32 #define RA_NR_BETA_OFFSET_CSI_SIZE 32 @@ -140,12 +142,99 @@ static const float ra_nr_beta_offset_csi_table[RA_NR_BETA_OFFSET_CSI_SIZE] = { 4.000f, 5.000f, 6.250f, 8.000f, 10.000f, 12.625f, 15.875f, 20.000f, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN}; -typedef enum { ra_nr_table_1 = 0, ra_nr_table_2, ra_nr_table_3 } ra_nr_table_t; +typedef enum { ra_nr_table_idx_1 = 0, ra_nr_table_idx_2, ra_nr_table_idx_3 } ra_nr_table_idx_t; -static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srsran_mcs_table_t mcs_table, - srsran_dci_format_nr_t dci_format, - srsran_search_space_type_t search_space_type, - srsran_rnti_type_t rnti_type) +/** + * The table below performs the mapping of the CQI into the closest MCS, based on the corresponding spectral efficiency. + * The mapping works as follows: + * - select spectral efficiency from the CQI from tables Table 5.2.2.1-2, Table 5.2.2.1-3, or Table 5.2.2.1-4, + * TS 38.214 V15.14.0 + * - select MCS corresponding to same spectral efficiency from Table 5.1.3.1-1, Table 5.1.3.1-2, or Table 5.1.3.1-3, + * TS 38.214 V15.14.0 + * + * The array ra_nr_cqi_to_mcs_table[CQI_table_idx][MCS_table_idx][CQI] contains the MCS corresponding to CQI, based on + * the given CQI_table_idx and MCS_table_idx tables + * CQI_table_idx: 1 -> Table 5.2.2.1-2; 2 -> Table 5.2.2.1-3, 3 -> Table 5.2.2.1-4 + * MCS_table_idx: 1 -> Table 5.1.3.1-1; 2 -> Table 5.1.3.1-2; 3 -> Table 5.1.3.1-3 + */ + +static const int ra_nr_cqi_to_mcs_table[3][3][RA_NR_CQI_TABLE_SIZE] = { + /* ROW 1 - CQI Table 1 */ + {/* MCS Table 1 */ {-1, 0, 0, 2, 4, 6, 8, 11, 13, 15, 18, 20, 22, 24, 26, 28}, + /* MCS Table 2 */ {-1, 0, 0, 1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19, 21}, + /* MCS Table 3 */ {-1, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 28, 28}}, + /* ROW 2 - CQI Table 2 */ + {/* MCS Table 1 */ {-1, 0, 2, 6, 11, 13, 15, 18, 20, 22, 24, 26, 28, 28, 28, 28}, + /* MCS Table 2 */ {-1, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27}, + /* MCS Table 3 */ {-1, 4, 8, 12, 16, 18, 20, 22, 24, 26, 28, 28, 28, 28, 28, 28}}, + /* ROW 3 - CQI Table 3 */ + {/* MCS Table 1 */ {-1, 0, 0, 0, 0, 2, 4, 6, 8, 11, 13, 15, 18, 20, 22, 24}, + /* MCS Table 2 */ {-1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17}, + /* MCS Table 3 */ {-1, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28}}}; + +/** + * The CQI to Spectral efficiency table. + * The array ra_nr_cqi_to_se_table[CQI_table_idx][CQI] contains the Spectral Efficiency corresponding to CQI, based on + * the given CQI_table_idx: + * CQI_table_idx: 1 -> Table 5.2.2.1-2; 2 -> Table 5.2.2.1-3, 3 -> Table 5.2.2.1-4 + */ +static const double ra_nr_cqi_to_se_table[3][RA_NR_CQI_TABLE_SIZE] = { + /* ROW 1 - CQI Table 1 */ + {-1, + 0.1523, + 0.2344, + 0.3770, + 0.6016, + 0.8770, + 1.1758, + 1.4766, + 1.9141, + 2.4063, + 2.7305, + 3.3223, + 3.9023, + 4.5234, + 5.1152, + 5.5547}, + /* ROW 2 - CQI Table 2 */ + {-1, + 0.1523, + 0.3770, + 0.8770, + 1.4766, + 1.9141, + 2.4063, + 2.7305, + 3.3223, + 3.9023, + 4.5234, + 5.1152, + 5.5547, + 6.2266, + 6.9141, + 7.4063}, + /* ROW 3 - CQI Table 3 */ + {-1, + 0.0586, + 0.0977, + 0.1523, + 0.2344, + 0.3770, + 0.6016, + 0.8770, + 1.1758, + 1.4766, + 1.9141, + 2.4063, + 2.7305, + 3.3223, + 3.9023, + 4.5234}}; + +static ra_nr_table_idx_t ra_nr_select_table_pusch_noprecoding(srsran_mcs_table_t mcs_table, + srsran_dci_format_nr_t dci_format, + srsran_search_space_type_t search_space_type, + srsran_rnti_type_t rnti_type) { // Non-implemented parameters bool mcs_c_rnti = false; @@ -155,7 +244,7 @@ static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srsran_mcs_table_t // - CRC scrambled by C-RNTI or SP-CSI-RNTI, if (mcs_table == srsran_mcs_table_256qam && dci_format == srsran_dci_format_nr_0_1 && (rnti_type == srsran_rnti_type_c || rnti_type == srsran_rnti_type_sp_csi)) { - return ra_nr_table_2; + return ra_nr_table_idx_2; } // - the UE is not configured with MCS-C-RNTI, @@ -165,14 +254,14 @@ static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srsran_mcs_table_t if (!mcs_c_rnti && mcs_table == srsran_mcs_table_qam64LowSE && dci_format != srsran_dci_format_nr_rar && search_space_type == srsran_search_space_type_ue && (rnti_type == srsran_rnti_type_c || rnti_type == srsran_rnti_type_sp_csi)) { - return ra_nr_table_3; + return ra_nr_table_idx_3; } // - the UE is configured with MCS-C-RNTI, and // - the PUSCH is scheduled by a PDCCH with // - CRC scrambled by MCS-C-RNTI, // if (mcs_c_rnti && dci_format != srsran_dci_format_nr_rar && rnti_type == srsran_rnti_type_mcs_c) { - // return ra_nr_table_3; + // return ra_nr_table_idx_3; // } // - mcs-Table in configuredGrantConfig is set to 'qam256', @@ -180,7 +269,7 @@ static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srsran_mcs_table_t // - if PUSCH is transmitted with configured grant // if (configured_grant_table == srsran_mcs_table_256qam && // (rnti_type == srsran_rnti_type_cs || dci_format == srsran_dci_format_nr_cg)) { - // return ra_nr_table_2; + // return ra_nr_table_idx_2; // } // - mcs-Table in configuredGrantConfig is set to 'qam64LowSE' @@ -188,23 +277,23 @@ static ra_nr_table_t ra_nr_select_table_pusch_noprecoding(srsran_mcs_table_t // - if PUSCH is transmitted with configured grant, // if (configured_grant_table == srsran_mcs_table_qam64LowSE && // (rnti_type == srsran_rnti_type_cs || dci_format == srsran_dci_format_nr_cg)) { - // return ra_nr_table_3; + // return ra_nr_table_idx_3; // } - return ra_nr_table_1; + return ra_nr_table_idx_1; } -static ra_nr_table_t ra_nr_select_table_pdsch(srsran_mcs_table_t mcs_table, - srsran_dci_format_nr_t dci_format, - srsran_search_space_type_t search_space_type, - srsran_rnti_type_t rnti_type) +static ra_nr_table_idx_t ra_nr_select_table_pdsch(srsran_mcs_table_t mcs_table, + srsran_dci_format_nr_t dci_format, + srsran_search_space_type_t search_space_type, + srsran_rnti_type_t rnti_type) { // - the higher layer parameter mcs-Table given by PDSCH-Config is set to 'qam256', and // - the PDSCH is scheduled by a PDCCH with DCI format 1_1 with // - CRC scrambled by C-RNTI if (mcs_table == srsran_mcs_table_256qam && dci_format == srsran_dci_format_nr_1_1 && rnti_type == srsran_rnti_type_c) { - return ra_nr_table_2; + return ra_nr_table_idx_2; } // the UE is not configured with MCS-C-RNTI, @@ -213,7 +302,7 @@ static ra_nr_table_t ra_nr_select_table_pdsch(srsran_mcs_table_t mcs_tab // CRC scrambled by C - RNTI if (mcs_table == srsran_mcs_table_qam64LowSE && search_space_type == srsran_search_space_type_ue && rnti_type == srsran_rnti_type_c) { - return ra_nr_table_3; + return ra_nr_table_idx_3; } // - the UE is not configured with the higher layer parameter mcs-Table given by SPS-Config, @@ -222,7 +311,7 @@ static ra_nr_table_t ra_nr_select_table_pdsch(srsran_mcs_table_t mcs_tab // - if the PDSCH is scheduled without corresponding PDCCH transmission using SPS-Config, // if (!sps_config_mcs_table_present && mcs_table == srsran_mcs_table_256qam && // ((dci_format == srsran_dci_format_nr_1_1 && rnti_type == srsran_rnti_type_cs) || (!is_pdcch_sps))) { - // return ra_nr_table_2; + // return ra_nr_table_idx_2; // } // - the UE is configured with the higher layer parameter mcs-Table given by SPS-Config set to 'qam64LowSE' @@ -230,17 +319,17 @@ static ra_nr_table_t ra_nr_select_table_pdsch(srsran_mcs_table_t mcs_tab // - if the PDSCH is scheduled without corresponding PDCCH transmission using SPS-Config, // if (sps_config_mcs_table_present && sps_config_mcs_table == srsran_mcs_table_qam64LowSE && // (rnti_type == srsran_rnti_type_cs || is_pdcch_sps)) { - // return ra_nr_table_3; + // return ra_nr_table_idx_3; // } // else - return ra_nr_table_1; + return ra_nr_table_idx_1; } -static ra_nr_table_t ra_nr_select_table(srsran_mcs_table_t mcs_table, - srsran_dci_format_nr_t dci_format, - srsran_search_space_type_t search_space_type, - srsran_rnti_type_t rnti_type) +static ra_nr_table_idx_t ra_nr_select_table(srsran_mcs_table_t mcs_table, + srsran_dci_format_nr_t dci_format, + srsran_search_space_type_t search_space_type, + srsran_rnti_type_t rnti_type) { // Check if it is a PUSCH transmission if (dci_format == srsran_dci_format_nr_0_0 || dci_format == srsran_dci_format_nr_0_1 || @@ -278,14 +367,14 @@ double srsran_ra_nr_R_from_mcs(srsran_mcs_table_t mcs_table, srsran_rnti_type_t rnti_type, uint32_t mcs_idx) { - ra_nr_table_t table = ra_nr_select_table(mcs_table, dci_format, search_space_type, rnti_type); + ra_nr_table_idx_t table = ra_nr_select_table(mcs_table, dci_format, search_space_type, rnti_type); switch (table) { - case ra_nr_table_1: + case ra_nr_table_idx_1: return srsran_ra_nr_R_from_mcs_table1(mcs_idx) / 1024.0; - case ra_nr_table_2: + case ra_nr_table_idx_2: return srsran_ra_nr_R_from_mcs_table2(mcs_idx) / 1024.0; - case ra_nr_table_3: + case ra_nr_table_idx_3: return srsran_ra_nr_R_from_mcs_table3(mcs_idx) / 1024.0; default: ERROR("Invalid table %d", table); @@ -300,14 +389,14 @@ srsran_mod_t srsran_ra_nr_mod_from_mcs(srsran_mcs_table_t mcs_table, srsran_rnti_type_t rnti_type, uint32_t mcs_idx) { - ra_nr_table_t table = ra_nr_select_table(mcs_table, dci_format, search_space_type, rnti_type); + ra_nr_table_idx_t table = ra_nr_select_table(mcs_table, dci_format, search_space_type, rnti_type); switch (table) { - case ra_nr_table_1: + case ra_nr_table_idx_1: return srsran_ra_nr_modulation_from_mcs_table1(mcs_idx); - case ra_nr_table_2: + case ra_nr_table_idx_2: return srsran_ra_nr_modulation_from_mcs_table2(mcs_idx); - case ra_nr_table_3: + case ra_nr_table_idx_3: return srsran_ra_nr_modulation_from_mcs_table3(mcs_idx); default: ERROR("Invalid table %d", table); @@ -546,6 +635,7 @@ int srsran_ra_nr_fill_tb(const srsran_sch_cfg_nr_t* pdsch_cfg, uint32_t N_re_rvd = srsran_re_pattern_list_count(&pdsch_cfg->rvd_re, grant->S, grant->S + grant->L, grant->prb_idx); // Steps 2,3,4 + tb->mcs = mcs_idx; tb->tbs = (int)srsran_ra_nr_tbs(N_re, S, R, Qm, tb->N_L); tb->R = R; tb->mod = m; @@ -568,6 +658,14 @@ static int ra_dl_dmrs(const srsran_sch_hl_cfg_nr_t* hl_cfg, const srsran_dci_dl_ (cfg->grant.mapping == srsran_sch_mapping_type_A) ? hl_cfg->dmrs_typeA.present : hl_cfg->dmrs_typeB.present; if (dci->ctx.format == srsran_dci_format_nr_1_0 || !dedicated_dmrs_present) { + // The reference point for k is + // - for PDSCH transmission carrying SIB1, subcarrier 0 of the lowest-numbered common resource block in the + // CORESET configured by the PBCH + //- otherwise, subcarrier 0 in common resource block 0 + if (dci->ctx.rnti_type == srsran_rnti_type_si) { + cfg->dmrs.reference_point_k_rb = dci->ctx.coreset_start_rb; + } + if (cfg->grant.mapping == srsran_sch_mapping_type_A) { // Absent default values are defined is TS 38.331 - DMRS-DownlinkConfig cfg->dmrs.additional_pos = srsran_dmrs_sch_add_pos_2; @@ -1085,3 +1183,114 @@ int srsran_ra_ul_set_grant_uci_nr(const srsran_carrier_nr_t* carrier, return SRSRAN_SUCCESS; } + +int srsran_ra_nr_cqi_to_mcs(uint8_t cqi, + srsran_csi_cqi_table_t cqi_table_idx, + srsran_mcs_table_t mcs_table, + srsran_dci_format_nr_t dci_format, + srsran_search_space_type_t search_space_type, + srsran_rnti_type_t rnti_type) +{ + if (cqi >= RA_NR_CQI_TABLE_SIZE) { + ERROR("Invalid CQI (%u)", cqi); + return -1; + } + + ra_nr_table_idx_t mcs_table_idx = ra_nr_select_table_pdsch(mcs_table, dci_format, search_space_type, rnti_type); + + return ra_nr_cqi_to_mcs_table[cqi_table_idx][mcs_table_idx][cqi]; +} + +double srsran_ra_nr_cqi_to_se(uint8_t cqi, srsran_csi_cqi_table_t cqi_table_idx) +{ + if (cqi >= RA_NR_CQI_TABLE_SIZE) { + ERROR("Invalid CQI (%u)", cqi); + return -1; + } + + return ra_nr_cqi_to_se_table[cqi_table_idx][cqi]; +} + +int srsran_ra_nr_se_to_mcs(double se_target, + srsran_mcs_table_t mcs_table, + srsran_dci_format_nr_t dci_format, + srsran_search_space_type_t search_space_type, + srsran_rnti_type_t rnti_type) +{ + // Get MCS table index to be used + ra_nr_table_idx_t mcs_table_idx = ra_nr_select_table_pdsch(mcs_table, dci_format, search_space_type, rnti_type); + + // Get MCS table and size based on mcs_table_idx + const mcs_entry_t* mcs_se_table; + size_t mcs_table_size; + switch (mcs_table_idx) { + case ra_nr_table_idx_1: + mcs_se_table = ra_nr_table1; + mcs_table_size = RA_NR_MCS_SIZE_TABLE1; + break; + case ra_nr_table_idx_2: + mcs_se_table = ra_nr_table2; + mcs_table_size = RA_NR_MCS_SIZE_TABLE2; + break; + case ra_nr_table_idx_3: + mcs_se_table = ra_nr_table3; + mcs_table_size = RA_NR_MCS_SIZE_TABLE3; + break; + default: + ERROR("Invalid MCS table index (%u)", mcs_table_idx); + return -1; + } + + // if SE is lower than min possible value, return min MCS + if (se_target <= mcs_se_table[0].S) { + return 0; + } + // if SE is greater than max possible value, return max MCS + else if (se_target >= mcs_se_table[mcs_table_size - 1].S) { + return mcs_table_size - 1; + } + + // handle monotonicity oddity between MCS 16 and 17 for MCS table 1 + if (mcs_table_idx == ra_nr_table_idx_1) { + if (se_target == mcs_se_table[17].S) { + return 17; + } else if (se_target <= mcs_se_table[16].S && se_target > mcs_se_table[17].S) { + return 16; + } + } + + /* In the following, we search for the greatest MCS value such that MCS(SE) <= target SE, where the target SE is the + * value provided as an input argument. The MCS is the vector index, the content of the vector is the SE. + * The search is performed by means of a binary-search like algorithm. At each iteration, we look for the SE in the + * left or right half of the vector, depending on the target SE. + * We stop when the lower-bound (lb) and upper-bound (ub) are two consecutive MCS values and we return the + * lower-bound, which approximates the greatest MCS value such that MCS(SE) <= target SE + * */ + size_t lb = 0; // lower-bound of MCS-to-SE vector where to perform binary search + size_t ub = mcs_table_size - 1; // upper-bound of MCS-to-SE vector where to perform binary search + while (ub > lb + 1) { + size_t mid_point = (size_t)floor(((double)(lb + ub)) / 2); + // break out of loop is there is an exact match + if (mcs_se_table[mid_point].S == se_target) { + return (int)mid_point; + } + // restrict the search to the left half of the vector + else if (se_target < mcs_se_table[mid_point].S) { + ub = mid_point; + // handle monotonicity oddity between MCS 16 and 17 for MCS table 1 + if (mcs_table_idx == ra_nr_table_idx_1 && ub == 17) { + ub = 16; + } + } + // restrict the search to the right half of the vector + else { /* se_target > mcs_se_table[mid_point].S ) */ + lb = mid_point; + // handle monotonicity oddity between MCS 16 and 17 for MCS table 1 + if (mcs_table_idx == ra_nr_table_idx_1 && lb == 16) { + lb = 17; + } + } + } + + return (int)lb; +} diff --git a/lib/src/phy/phch/ra_sl.c b/lib/src/phy/phch/ra_sl.c index bbb116b387..70bc92e54b 100644 --- a/lib/src/phy/phch/ra_sl.c +++ b/lib/src/phy/phch/ra_sl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/ra_ul.c b/lib/src/phy/phch/ra_ul.c index 6a0c62df22..8ca825f54a 100644 --- a/lib/src/phy/phch/ra_ul.c +++ b/lib/src/phy/phch/ra_ul.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/ra_ul_nr.c b/lib/src/phy/phch/ra_ul_nr.c index 4fe51f4de1..206dd622c0 100644 --- a/lib/src/phy/phch/ra_ul_nr.c +++ b/lib/src/phy/phch/ra_ul_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -479,11 +479,89 @@ int srsran_ra_ul_nr_freq(const srsran_carrier_nr_t* carrier, return SRSRAN_ERROR; } +typedef struct { + srsran_pucch_nr_format_t format; + uint32_t start_symbol; + uint32_t rb_offset; + uint32_t N_cs; +} pucch_res_common_cfg_t; + +// Table 9.2.1-1 +#define PUCCH_RES_COMMON_CFG_IDX_MAX 15 +static pucch_res_common_cfg_t pucch_res_common_cfg[PUCCH_RES_COMMON_CFG_IDX_MAX + 1] = { + {SRSRAN_PUCCH_NR_FORMAT_0, 12, 0, 2}, + {SRSRAN_PUCCH_NR_FORMAT_0, 12, 0, 3}, + {SRSRAN_PUCCH_NR_FORMAT_0, 12, 3, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 10, 0, 2}, + {SRSRAN_PUCCH_NR_FORMAT_1, 10, 0, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 10, 2, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 10, 4, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 4, 0, 2}, + {SRSRAN_PUCCH_NR_FORMAT_1, 4, 0, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 4, 2, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 4, 4, 3}, + {SRSRAN_PUCCH_NR_FORMAT_1, 0, 0, 2}, + {SRSRAN_PUCCH_NR_FORMAT_1, 0, 0, 4}, + {SRSRAN_PUCCH_NR_FORMAT_1, 0, 2, 4}, + {SRSRAN_PUCCH_NR_FORMAT_1, 0, 4, 4}, + {SRSRAN_PUCCH_NR_FORMAT_1, 0, 0, 4}}; + // Implements TS 38.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration -static int ra_ul_nr_pucch_resource_default(uint32_t r_pucch, srsran_pucch_nr_resource_t* resource) +static int ra_ul_nr_pucch_resource_default(uint32_t pucch_res_common_idx, + uint32_t N_size_bwp, + uint32_t r_pucch, + srsran_pucch_nr_resource_t* resource) { - ERROR("Not implemented"); - return SRSRAN_ERROR; + if (pucch_res_common_idx > PUCCH_RES_COMMON_CFG_IDX_MAX) { + ERROR("Invalid pucch_res_common_idx value (%d)\n", pucch_res_common_idx); + return SRSRAN_ERROR; + } + + uint32_t cs_v_2[2] = {0, 6}; + uint32_t cs_v_3[3] = {0, 4, 8}; + uint32_t cs_v_4[4] = {0, 3, 6, 9}; + + // Table 9.2.1-1 + resource->format = pucch_res_common_cfg[pucch_res_common_idx].format; + resource->start_symbol_idx = pucch_res_common_cfg[pucch_res_common_idx].start_symbol; + resource->nof_symbols = 14 - resource->start_symbol_idx; + uint32_t rb_offset_bwp = pucch_res_common_cfg[pucch_res_common_idx].rb_offset; + uint32_t N_cs = pucch_res_common_cfg[pucch_res_common_idx].N_cs; + + // Special case for cs_v_2 value + if (pucch_res_common_idx == 0) { + cs_v_2[1] = 3; + } + + // Special case for rb_offset + if (pucch_res_common_idx == 15) { + rb_offset_bwp = N_size_bwp / 4; + } + + uint32_t csv_idx = 0; + if (r_pucch / 8 == 0) { + resource->starting_prb = rb_offset_bwp + SRSRAN_FLOOR(r_pucch, N_cs); + resource->second_hop_prb = N_size_bwp - 1 - resource->starting_prb; + csv_idx = r_pucch % N_cs; + } else { + resource->second_hop_prb = rb_offset_bwp + SRSRAN_FLOOR(r_pucch - 8, N_cs); + resource->starting_prb = N_size_bwp - 1 - resource->second_hop_prb; + csv_idx = (r_pucch - 8) % N_cs; + } + + switch (N_cs) { + case 2: + resource->initial_cyclic_shift = cs_v_2[csv_idx]; + break; + case 3: + resource->initial_cyclic_shift = cs_v_3[csv_idx]; + break; + case 4: + resource->initial_cyclic_shift = cs_v_4[csv_idx]; + break; + } + + return SRSRAN_SUCCESS; } static int ra_ul_nr_pucch_resource_hl(const srsran_pucch_nr_hl_cfg_t* cfg, @@ -531,6 +609,7 @@ static int ra_ul_nr_pucch_resource_hl(const srsran_pucch_nr_hl_cfg_t* cfg, int srsran_ra_ul_nr_pucch_resource(const srsran_pucch_nr_hl_cfg_t* pucch_cfg, const srsran_uci_cfg_nr_t* uci_cfg, + uint32_t N_bwp_sz, srsran_pucch_nr_resource_t* resource) { if (pucch_cfg == NULL || uci_cfg == NULL || resource == NULL) { @@ -632,8 +711,9 @@ int srsran_ra_ul_nr_pucch_resource(const srsran_pucch_nr_hl_cfg_t* pucch_cfg, // a PUCCH resource set is provided by pucch-ResourceCommon through an index to a row of Table 9.2.1-1 for size // transmission of HARQ-ACK information on PUCCH in an initial UL BWP of N BWP PRBs. if (!pucch_cfg->enabled) { - uint32_t r_pucch = (2 * uci_cfg->pucch.n_cce_0) + 2 * uci_cfg->pucch.resource_id; - return ra_ul_nr_pucch_resource_default(r_pucch, resource); + uint32_t N_cce = SRSRAN_FLOOR(N_bwp_sz, 6); + uint32_t r_pucch = ((2 * uci_cfg->pucch.n_cce_0) / N_cce) + 2 * uci_cfg->pucch.resource_id; + return ra_ul_nr_pucch_resource_default(pucch_cfg->common.resource_common, N_bwp_sz, r_pucch, resource); } return ra_ul_nr_pucch_resource_hl(pucch_cfg, uci_cfg, uci_cfg->pucch.resource_id, resource); } diff --git a/lib/src/phy/phch/regs.c b/lib/src/phy/phch/regs.c index 5e152277c1..c3bdf6feeb 100644 --- a/lib/src/phy/phch/regs.c +++ b/lib/src/phy/phch/regs.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/sch.c b/lib/src/phy/phch/sch.c index b0527ab096..28d7d64644 100644 --- a/lib/src/phy/phch/sch.c +++ b/lib/src/phy/phch/sch.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/sch_nr.c b/lib/src/phy/phch/sch_nr.c index 48aa14a75f..cab53cd490 100644 --- a/lib/src/phy/phch/sch_nr.c +++ b/lib/src/phy/phch/sch_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -605,6 +605,7 @@ static int sch_nr_decode(srsran_sch_nr_t* q, // Counter of code blocks that have matched CRC uint32_t cb_ok = 0; + res->crc = false; // For each code block... uint32_t j = 0; diff --git a/lib/src/phy/phch/sci.c b/lib/src/phy/phch/sci.c index 3af1b7cd48..30885a052d 100644 --- a/lib/src/phy/phch/sci.c +++ b/lib/src/phy/phch/sci.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/sequences.c b/lib/src/phy/phch/sequences.c index afcae0f894..c0ea8f20bc 100644 --- a/lib/src/phy/phch/sequences.c +++ b/lib/src/phy/phch/sequences.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/tbs_tables.h b/lib/src/phy/phch/tbs_tables.h index 32d1fb4e61..e0a06d1172 100644 --- a/lib/src/phy/phch/tbs_tables.h +++ b/lib/src/phy/phch/tbs_tables.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/tbs_tables_nbiot.h b/lib/src/phy/phch/tbs_tables_nbiot.h index 47af10f83e..56f1a21889 100644 --- a/lib/src/phy/phch/tbs_tables_nbiot.h +++ b/lib/src/phy/phch/tbs_tables_nbiot.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/CMakeLists.txt b/lib/src/phy/phch/test/CMakeLists.txt index f6ad6934aa..5a83594787 100644 --- a/lib/src/phy/phch/test/CMakeLists.txt +++ b/lib/src/phy/phch/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -21,7 +21,7 @@ set(CTEST_LABELS "lib;phy;phch") ######################################################################## -# PBCH TEST +# PBCH TEST ######################################################################## add_executable(pbch_test pbch_test.c) @@ -57,15 +57,15 @@ add_executable(psbch_file_test psbch_file_test.c) target_link_libraries(psbch_file_test srsran_phy) # TM2 file tests -add_lte_test(psbch_file_test_ideal_tm2_p6_c0 psbch_file_test -p 6 -c 0 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p6_c0_s1.92e6.dat) -add_lte_test(psbch_file_test_ideal_tm2_p15_c84 psbch_file_test -p 15 -c 84 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p15_c84_s3.84e6.dat) -add_lte_test(psbch_file_test_ideal_tm2_p25_c168 psbch_file_test -p 25 -c 168 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p25_c168_s7.68e6.dat) -add_lte_test(psbch_file_test_ideal_tm2_p50_c252 psbch_file_test -p 50 -c 252 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6.dat) -add_lte_test(psbch_file_test_ideal_tm2_p100_c335 psbch_file_test -p 100 -c 335 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) -add_lte_test(psbch_file_test_ideal_tm2_p50_c252_ext psbch_file_test -p 50 -c 252 -e -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6_ext.dat) +add_lte_test(psbch_file_test_ideal_tm2_p6_c0 psbch_file_test -p 6 -c 0 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_ideal_tm2_p6_c0_s1.92e6.dat) +add_lte_test(psbch_file_test_ideal_tm2_p15_c84 psbch_file_test -p 15 -c 84 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_ideal_tm2_p15_c84_s3.84e6.dat) +add_lte_test(psbch_file_test_ideal_tm2_p25_c168 psbch_file_test -p 25 -c 168 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_ideal_tm2_p25_c168_s7.68e6.dat) +add_lte_test(psbch_file_test_ideal_tm2_p50_c252 psbch_file_test -p 50 -c 252 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_ideal_tm2_p50_c252_s15.36e6.dat) +add_lte_test(psbch_file_test_ideal_tm2_p100_c335 psbch_file_test -p 100 -c 335 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) +add_lte_test(psbch_file_test_ideal_tm2_p50_c252_ext psbch_file_test -p 50 -c 252 -e -d -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_ideal_tm2_p50_c252_s15.36e6_ext.dat) # TM4 file tests -add_lte_test(psbch_file_test_cmw_tm4_p50_c169 psbch_file_test -p 50 -c 169 -t 4 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_cmw500_f5.92e9_s11.52e6_50prb_slss_id169.dat) +add_lte_test(psbch_file_test_cmw_tm4_p50_c169 psbch_file_test -p 50 -c 169 -t 4 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_cmw500_f5.92e9_s11.52e6_50prb_slss_id169.dat) ######################################################################## # PSCCH TEST @@ -123,38 +123,38 @@ add_executable(pssch_pscch_file_test pssch_pscch_file_test.c) target_link_libraries(pssch_pscch_file_test srsran_phy) # TM2 file tests -add_lte_test(pssch_pscch_file_test_ideal_tm2_p100 pssch_pscch_file_test -p 100 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) +add_lte_test(pssch_pscch_file_test_ideal_tm2_p100 pssch_pscch_file_test -p 100 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) set_property(TEST pssch_pscch_file_test_ideal_tm2_p100 PROPERTY PASS_REGULAR_EXPRESSION "num_decoded_sci=[2,3] num_decoded_tb=1") # TM4 file tests (first SF is sf_idx = 6 such that the PSSCH sf_idx=0) -add_lte_test(pssch_pscch_file_test_ideal_tm4_p100 pssch_pscch_file_test -p 100 -t 4 -s 10 -n 10 -d -m 6 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm4_p100_c335_size10_num10_cshift0_s30.72e6.dat) +add_lte_test(pssch_pscch_file_test_ideal_tm4_p100 pssch_pscch_file_test -p 100 -t 4 -s 10 -n 10 -d -m 6 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_ideal_tm4_p100_c335_size10_num10_cshift0_s30.72e6.dat) set_property(TEST pssch_pscch_file_test_ideal_tm4_p100 PROPERTY PASS_REGULAR_EXPRESSION "num_decoded_sci=1") -add_lte_test(pssch_pscch_test_tm4_p50_qc pssch_pscch_file_test -p 50 -t 4 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_qc9150_f5.92e9_s15.36e6_50prb_20offset.dat) +add_lte_test(pssch_pscch_test_tm4_p50_qc pssch_pscch_file_test -p 50 -t 4 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_qc9150_f5.92e9_s15.36e6_50prb_20offset.dat) set_property(TEST pssch_pscch_test_tm4_p50_qc PROPERTY PASS_REGULAR_EXPRESSION "num_decoded_sci=1 num_decoded_tb=1") # Capture has a SFO offset of ~64 samples, but offsetting by 20 is enough to decode it -add_lte_test(pssch_pscch_test_tm4_p50_cmw pssch_pscch_file_test -p 50 -t 4 -o 20 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_cmw500_f5.92e9_s11.52e6_50prb_0offset_1ms.dat) +add_lte_test(pssch_pscch_test_tm4_p50_cmw pssch_pscch_file_test -p 50 -t 4 -o 20 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_cmw500_f5.92e9_s11.52e6_50prb_0offset_1ms.dat) set_property(TEST pssch_pscch_test_tm4_p50_cmw PROPERTY PASS_REGULAR_EXPRESSION "num_decoded_sci=1 num_decoded_tb=1") # With PHY retransmission (3 TTI offset) first SF at sf_idx=5 -add_lte_test(pssch_pscch_test_tm4_p50_huawei pssch_pscch_file_test -p 50 -t 4 -m 5 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_huawei_s11.52e6_50prb_10prb_offset_with_retx.dat) +add_lte_test(pssch_pscch_test_tm4_p50_huawei pssch_pscch_file_test -p 50 -t 4 -m 5 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_huawei_s11.52e6_50prb_10prb_offset_with_retx.dat) set_property(TEST pssch_pscch_test_tm4_p50_huawei PROPERTY PASS_REGULAR_EXPRESSION "num_decoded_sci=2 num_decoded_tb=2") # With PHY ReTx (0 TTI offset?) -add_lte_test(pssch_pscch_test_tm4_p50_uxm1 pssch_pscch_file_test -p 50 -d -t 4 -s 5 -n 10 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s15.36e6_50prb_0prb_offset_mcs12.dat) +add_lte_test(pssch_pscch_test_tm4_p50_uxm1 pssch_pscch_file_test -p 50 -d -t 4 -s 5 -n 10 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_uxm_s15.36e6_50prb_0prb_offset_mcs12.dat) set_property(TEST pssch_pscch_test_tm4_p50_uxm1 PROPERTY PASS_REGULAR_EXPRESSION "mcs=12.*num_decoded_sci=2 num_decoded_tb=2") # 100 PRB startOffset 1 MCS12 MAC padding, first SF is index 0 -add_lte_test(pssch_pscch_test_tm4_p100_uxm2 pssch_pscch_file_test -p 100 -t 4 -s 10 -n 10 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s23.04e6_100prb_1prb_offset_mcs12_padding.dat) +add_lte_test(pssch_pscch_test_tm4_p100_uxm2 pssch_pscch_file_test -p 100 -t 4 -s 10 -n 10 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_uxm_s23.04e6_100prb_1prb_offset_mcs12_padding.dat) set_property(TEST pssch_pscch_test_tm4_p100_uxm2 PROPERTY PASS_REGULAR_EXPRESSION "mcs=12.*num_decoded_sci=4") # 100 PRB LTE sampling rate, startOffset1 MCS12 ITS data, first SF is index 6 -add_lte_test(pssch_pscch_test_tm4_p100_uxm3 pssch_pscch_file_test -p 100 -d -t 4 -s 10 -n 10 -m 6 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s30.72e6_100prb_1prb_offset_mcs12_its.dat) +add_lte_test(pssch_pscch_test_tm4_p100_uxm3 pssch_pscch_file_test -p 100 -d -t 4 -s 10 -n 10 -m 6 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_uxm_s30.72e6_100prb_1prb_offset_mcs12_its.dat) set_property(TEST pssch_pscch_test_tm4_p100_uxm3 PROPERTY PASS_REGULAR_EXPRESSION "mcs=12.*num_decoded_sci=1") # 50 PRB LTE sampling rate, startOffset0 MCS28 MAC padding, first SF is index 1 -add_lte_test(pssch_pscch_test_tm4_p50_uxm4 pssch_pscch_file_test -p 50 -d -t 4 -s 5 -n 10 -m 1 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_uxm_s15.36e6_50prb_0prb_offset_mcs28_padding_5ms.dat) +add_lte_test(pssch_pscch_test_tm4_p50_uxm4 pssch_pscch_file_test -p 50 -d -t 4 -s 5 -n 10 -m 1 -i ${CMAKE_CURRENT_SOURCE_DIR}/signal_sidelink_uxm_s15.36e6_50prb_0prb_offset_mcs28_padding_5ms.dat) set_property(TEST pssch_pscch_test_tm4_p50_uxm4 PROPERTY PASS_REGULAR_EXPRESSION "mcs=28.*num_decoded_sci=5") ######################################################################## @@ -211,8 +211,9 @@ add_executable(pdcch_test pdcch_test.c) target_link_libraries(pdcch_test srsran_phy) foreach (nof_prb 6 15 25 50 75 100) - # Currently, the ARM platforms srsRAN has been tested are not capable of running 100PRB. So, skip 100 PRB in ARM - if (HAVE_NEON AND (${nof_prb} EQUAL 100)) + # Currently, the ARM and SSE platforms srsRAN has been tested are not capable of running 100PRB. So, skip 100 PRB in + # ARM and SSE. + if ((HAVE_NEON OR NOT HAVE_AVX2) AND (${nof_prb} EQUAL 100)) continue() endif () foreach (nof_ports 1 2) @@ -235,6 +236,14 @@ foreach (nof_prb 6 15 25 50 75 100) endforeach () endforeach () +######################################################################## +# DCI TEST +######################################################################## + +add_executable(dci_test dci_test.c) +target_link_libraries(dci_test srsran_phy) +add_test(dci_test dci_test) + ######################################################################## # PDSCH TEST ######################################################################## @@ -633,6 +642,10 @@ if(RF_FOUND) target_link_libraries(prach_test_usrp srsran_rf srsran_phy pthread) endif(RF_FOUND) +add_executable(prach_nr_test_perf EXCLUDE_FROM_ALL prach_nr_test_perf.c) +target_link_libraries(prach_nr_test_perf srsran_phy) +# this is just for performance evaluation, not for unit testing + ######################################################################## # NR ######################################################################## @@ -678,6 +691,9 @@ add_nr_test(pusch_nr_ack2_csi4_test pusch_nr_test -p 50 -m 20 -A 2 -C 4) add_nr_test(pusch_nr_ack4_csi4_test pusch_nr_test -p 50 -m 20 -A 4 -C 4) add_nr_test(pusch_nr_ack20_csi4_test pusch_nr_test -p 50 -m 20 -A 20 -C 4) +add_executable(pusch_nr_bler_test EXCLUDE_FROM_ALL pusch_nr_bler_test.c) +target_link_libraries(pusch_nr_bler_test srsran_phy) +# this is just for performance evaluation, not for unit testing add_executable(pdcch_nr_test pdcch_nr_test.c) target_link_libraries(pdcch_nr_test srsran_phy) diff --git a/lib/src/phy/phch/test/dci_nbiot_test.c b/lib/src/phy/phch/test/dci_nbiot_test.c index e178f712c3..a3a7078548 100644 --- a/lib/src/phy/phch/test/dci_nbiot_test.c +++ b/lib/src/phy/phch/test/dci_nbiot_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/dci_nr_test.c b/lib/src/phy/phch/test/dci_nr_test.c index 3e34954686..fa755f3073 100644 --- a/lib/src/phy/phch/test/dci_nr_test.c +++ b/lib/src/phy/phch/test/dci_nr_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -100,8 +100,10 @@ static int test_52prb_base() TESTASSERT(srsran_dci_nr_size(&dci, srsran_search_space_type_ue, srsran_dci_format_nr_0_1) == 36); TESTASSERT(srsran_dci_nr_size(&dci, srsran_search_space_type_ue, srsran_dci_format_nr_1_1) == 41); TESTASSERT(srsran_dci_nr_size(&dci, srsran_search_space_type_rar, srsran_dci_format_nr_rar) == 27); + TESTASSERT(srsran_dci_nr_size(&dci, srsran_search_space_type_common_0, srsran_dci_format_nr_1_0) == 39); srsran_dci_ctx_t ctx = {}; + ctx.rnti = 0x1234; ctx.ss_type = srsran_search_space_type_common_3; ctx.rnti_type = srsran_rnti_type_c; @@ -358,6 +360,43 @@ static int test_52prb_base() TESTASSERT(memcmp(&dci_tx, &dci_rx, sizeof(srsran_dci_dl_nr_t)) == 0); } + // Test DL DCI 1_0 Packing/Unpacking and info for SI-RNTI + ctx.format = srsran_dci_format_nr_1_0; + ctx.rnti = 0xffff; + ctx.ss_type = srsran_search_space_type_common_0; + ctx.rnti_type = srsran_rnti_type_si; + dci.cfg.coreset0_bw = 48; + + for (uint32_t i = 0; i < nof_repetitions; i++) { + srsran_dci_dl_nr_t dci_tx = {}; + dci_tx.ctx = ctx; + dci_tx.freq_domain_assigment = 0x120; + dci_tx.time_domain_assigment = 0; + dci_tx.vrb_to_prb_mapping = 0; + dci_tx.mcs = srsran_random_uniform_int_dist(random_gen, 0, 31); + dci_tx.rv = srsran_random_uniform_int_dist(random_gen, 0, 3); + dci_tx.sii = 1; // bit set to 1 indicates SI message other than SIB1 + dci_tx.coreset0_bw = 48; + + // Pack + srsran_dci_msg_nr_t dci_msg = {}; + TESTASSERT(srsran_dci_nr_dl_pack(&dci, &dci_tx, &dci_msg) == SRSRAN_SUCCESS); + + // Unpack + srsran_dci_dl_nr_t dci_rx = {}; + TESTASSERT(srsran_dci_nr_dl_unpack(&dci, &dci_msg, &dci_rx) == SRSRAN_SUCCESS); + + // To string + char str[512]; + TESTASSERT(srsran_dci_dl_nr_to_str(&dci, &dci_tx, str, (uint32_t)sizeof(str)) != 0); + INFO("Tx: %s", str); + TESTASSERT(srsran_dci_dl_nr_to_str(&dci, &dci_rx, str, (uint32_t)sizeof(str)) != 0); + INFO("Rx: %s", str); + + // Assert + TESTASSERT(memcmp(&dci_tx, &dci_rx, sizeof(srsran_dci_dl_nr_t)) == 0); + } + return SRSRAN_SUCCESS; } diff --git a/lib/src/phy/phch/test/dci_test.c b/lib/src/phy/phch/test/dci_test.c new file mode 100644 index 0000000000..64336347e2 --- /dev/null +++ b/lib/src/phy/phch/test/dci_test.c @@ -0,0 +1,117 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/phy/phch/dci.h" +#include "srsran/phy/utils/debug.h" +#include "srsran/phy/utils/random.h" +#include "srsran/srsran.h" +#include "srsran/support/srsran_test.h" +#include + +#define UE_CRNTI 0x1234 + +static int test_pdcch_orders() +{ + static srsran_cell_t cell = { + 52, // nof_prb + 1, // nof_ports + 0, // cell_id + SRSRAN_CP_NORM, // cyclic prefix + SRSRAN_PHICH_NORM, // PHICH length + SRSRAN_PHICH_R_1, // PHICH resources + SRSRAN_FDD, + }; + + srsran_dl_sf_cfg_t dl_sf; + ZERO_OBJECT(dl_sf); + + srsran_dci_location_t locations[SRSRAN_NOF_SF_X_FRAME][30]; + static uint32_t cfi = 2; + + static srsran_pdcch_t pdcch; + static srsran_regs_t regs; + + if (srsran_regs_init(®s, cell)) { + ERROR("Error initiating regs"); + exit(-1); + } + + if (srsran_pdcch_init_enb(&pdcch, cell.nof_prb)) { + ERROR("Error creating PDCCH object"); + exit(-1); + } + if (srsran_pdcch_set_cell(&pdcch, ®s, cell)) { + ERROR("Error creating PDCCH object"); + exit(-1); + } + + /* Initiate valid DCI locations */ + for (int i = 0; i < SRSRAN_NOF_SF_X_FRAME; i++) { + dl_sf.cfi = cfi; + dl_sf.tti = i; + srsran_pdcch_ue_locations(&pdcch, &dl_sf, locations[i], 30, UE_CRNTI); + } + + srsran_dci_dl_t dci_tx; + bzero(&dci_tx, sizeof(srsran_dci_dl_t)); + dci_tx.rnti = UE_CRNTI; + dci_tx.location = locations[1][0]; + dci_tx.format = SRSRAN_DCI_FORMAT1A; + dci_tx.cif_present = false; + dci_tx.is_pdcch_order = true; + dci_tx.preamble_idx = 0; + dci_tx.prach_mask_idx = 0; + + srsran_dci_cfg_t cfg = {}; + cfg.cif_enabled = false; + cfg.srs_request_enabled = false; + + // Pack + srsran_dci_msg_t dci_msg = {}; + TESTASSERT(srsran_dci_msg_pack_pdsch(&cell, &dl_sf, &cfg, &dci_tx, &dci_msg) == SRSRAN_SUCCESS); + + // Unpack + srsran_dci_dl_t dci_rx = {}; + TESTASSERT(srsran_dci_msg_unpack_pdsch(&cell, &dl_sf, &cfg, &dci_msg, &dci_rx) == SRSRAN_SUCCESS); + + // To string + char str[128]; + srsran_dci_dl_info(&dci_tx, str, sizeof(str)); + printf("Tx: %s\n", str); + srsran_dci_dl_info(&dci_rx, str, sizeof(str)); + printf("Rx: %s\n", str); + + // Assert + TESTASSERT(memcmp(&dci_tx, &dci_rx, srsran_dci_format_sizeof(&cell, &dl_sf, &cfg, dci_tx.format)) == 0); + + return SRSRAN_SUCCESS; +} + +int main(int argc, char** argv) +{ + if (test_pdcch_orders() != SRSRAN_SUCCESS) { + return SRSRAN_ERROR; + } + + printf("Success!\n"); + + return SRSRAN_SUCCESS; +} \ No newline at end of file diff --git a/lib/src/phy/phch/test/mib_nr_test.c b/lib/src/phy/phch/test/mib_nr_test.c index b6e320fc17..246420d14b 100644 --- a/lib/src/phy/phch/test/mib_nr_test.c +++ b/lib/src/phy/phch/test/mib_nr_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/npbch_file_test.c b/lib/src/phy/phch/test/npbch_file_test.c index 99a05a8199..3671b4f2a1 100644 --- a/lib/src/phy/phch/test/npbch_file_test.c +++ b/lib/src/phy/phch/test/npbch_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/npbch_test.c b/lib/src/phy/phch/test/npbch_test.c index 187f0e9aeb..a0e2d864fb 100644 --- a/lib/src/phy/phch/test/npbch_test.c +++ b/lib/src/phy/phch/test/npbch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/npdcch_file_test.c b/lib/src/phy/phch/test/npdcch_file_test.c index 61e209fb9c..9514d2ba0b 100644 --- a/lib/src/phy/phch/test/npdcch_file_test.c +++ b/lib/src/phy/phch/test/npdcch_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/npdcch_test.c b/lib/src/phy/phch/test/npdcch_test.c index 7f81e535d7..25235b481b 100644 --- a/lib/src/phy/phch/test/npdcch_test.c +++ b/lib/src/phy/phch/test/npdcch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/npdsch_npdcch_file_test.c b/lib/src/phy/phch/test/npdsch_npdcch_file_test.c index 71a31f49db..61efc9b8a6 100644 --- a/lib/src/phy/phch/test/npdsch_npdcch_file_test.c +++ b/lib/src/phy/phch/test/npdsch_npdcch_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -222,8 +222,8 @@ int main(int argc, char** argv) // add some noise to the signal if (snr != -1.0) { - float nstd = powf(10.0f, -snr / 20.0f); - srsran_ch_awgn_c(buff_ptrs[0], buff_ptrs[0], nstd, nread); + float var = srsran_convert_dB_to_power(-snr); + srsran_ch_awgn_c(buff_ptrs[0], buff_ptrs[0], var, nread); } // try to decode diff --git a/lib/src/phy/phch/test/npdsch_test.c b/lib/src/phy/phch/test/npdsch_test.c index c12af21465..45b1ff89f4 100644 --- a/lib/src/phy/phch/test/npdsch_test.c +++ b/lib/src/phy/phch/test/npdsch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pbch_file_test.c b/lib/src/phy/phch/test/pbch_file_test.c index 283ac82f53..3286a2ebb3 100644 --- a/lib/src/phy/phch/test/pbch_file_test.c +++ b/lib/src/phy/phch/test/pbch_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pbch_test.c b/lib/src/phy/phch/test/pbch_test.c index 5410408ee2..95a70c1ecf 100644 --- a/lib/src/phy/phch/test/pbch_test.c +++ b/lib/src/phy/phch/test/pbch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pcfich_file_test.c b/lib/src/phy/phch/test/pcfich_file_test.c index 32ddfc4fc6..314ee090e7 100644 --- a/lib/src/phy/phch/test/pcfich_file_test.c +++ b/lib/src/phy/phch/test/pcfich_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pcfich_test.c b/lib/src/phy/phch/test/pcfich_test.c index fc95ef10a8..5b20260252 100644 --- a/lib/src/phy/phch/test/pcfich_test.c +++ b/lib/src/phy/phch/test/pcfich_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pdcch_file_test.c b/lib/src/phy/phch/test/pdcch_file_test.c index e5852dfb12..01d315b8fb 100644 --- a/lib/src/phy/phch/test/pdcch_file_test.c +++ b/lib/src/phy/phch/test/pdcch_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pdcch_nr_test.c b/lib/src/phy/phch/test/pdcch_nr_test.c index 9ffe6043d5..0a8306df5b 100644 --- a/lib/src/phy/phch/test/pdcch_nr_test.c +++ b/lib/src/phy/phch/test/pdcch_nr_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pdcch_test.c b/lib/src/phy/phch/test/pdcch_test.c index 4bf39c8dfa..ea8774c9ba 100644 --- a/lib/src/phy/phch/test/pdcch_test.c +++ b/lib/src/phy/phch/test/pdcch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pdsch_nr_test.c b/lib/src/phy/phch/test/pdsch_nr_test.c index 419900f57c..57cb3956dc 100644 --- a/lib/src/phy/phch/test/pdsch_nr_test.c +++ b/lib/src/phy/phch/test/pdsch_nr_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pdsch_pdcch_file_test.c b/lib/src/phy/phch/test/pdsch_pdcch_file_test.c index 10756efded..d9b0143c4b 100644 --- a/lib/src/phy/phch/test/pdsch_pdcch_file_test.c +++ b/lib/src/phy/phch/test/pdsch_pdcch_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pdsch_test.c b/lib/src/phy/phch/test/pdsch_test.c index fed09fc39d..4bb79b9c96 100644 --- a/lib/src/phy/phch/test/pdsch_test.c +++ b/lib/src/phy/phch/test/pdsch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/phich_file_test.c b/lib/src/phy/phch/test/phich_file_test.c index 0d520fe9c6..c9d437f4f6 100644 --- a/lib/src/phy/phch/test/phich_file_test.c +++ b/lib/src/phy/phch/test/phich_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/phich_test.c b/lib/src/phy/phch/test/phich_test.c index 64a33d4b37..73cbbb5e6a 100644 --- a/lib/src/phy/phch/test/phich_test.c +++ b/lib/src/phy/phch/test/phich_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pmch_file_test.c b/lib/src/phy/phch/test/pmch_file_test.c index 5266f5cff8..1d2fe4b7c9 100644 --- a/lib/src/phy/phch/test/pmch_file_test.c +++ b/lib/src/phy/phch/test/pmch_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pmch_test.c b/lib/src/phy/phch/test/pmch_test.c index e20f2e8950..e32ccaba71 100644 --- a/lib/src/phy/phch/test/pmch_test.c +++ b/lib/src/phy/phch/test/pmch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -143,7 +143,8 @@ int main(int argc, char** argv) srsran_chest_dl_res_t chest_dl_res; srsran_pmch_t pmch; srsran_pmch_cfg_t pmch_cfg; - srsran_ofdm_t ifft_mbsfn[SRSRAN_MAX_PORTS], fft_mbsfn[SRSRAN_MAX_PORTS]; + srsran_ofdm_t ifft_mbsfn[SRSRAN_MAX_PORTS] = {}; + srsran_ofdm_t fft_mbsfn[SRSRAN_MAX_PORTS] = {}; parse_args(argc, argv); /* Initialise to zeros */ diff --git a/lib/src/phy/phch/test/prach_nr_test_perf.c b/lib/src/phy/phch/test/prach_nr_test_perf.c new file mode 100644 index 0000000000..5c4d6788d0 --- /dev/null +++ b/lib/src/phy/phch/test/prach_nr_test_perf.c @@ -0,0 +1,263 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +/** + * \file prach_nr_test_perf.c + * \brief Performance test for PRACH NR. + * + * This program simulates several PRACH preamble transmissions (so far, burst format 0 only) + * to estimate the probability of detection and of false alarm. The probability of detection + * is the conditional probability of detecting the preamble when the preamble is present. + * An error consists in detecting no preambles, detecting only preambles different from the + * reference one, or detecting the correct preamble with a timing error beyond tolerance. + * The probability of false alarm is the probability of detecting any preamble when input + * is only noise. + * + * The simulation setup can be controlled by means of the following arguments. + * - -N num: sets the number of experiments to \c num. + * - -n num: sets the total number of UL PRBs to \c num. + * - -f num: sets the preamble format to \c num (for now, format 0 only). + * - -s val: sets the nominal SNR to \c val dB. + * - -v : activates verbose output. + * + * Example: + * \code{.cpp} + * prach_nr_test_perf -n 52 -s -14.6 + * \endcode + * + * \todo Restricted preamble formats not implemented yet. Fading channel and SIMO. + */ + +#include +#include +#include +#include +#include + +#include "srsran/srsran.h" + +#define MAX_LEN 70176 + +static uint32_t nof_prb = 52; +static uint32_t config_idx = 0; +static int nof_runs = 100; +static float snr_dB = -14.5F; +static bool is_verbose = false; + +static void usage(char* prog) +{ + printf("Usage: %s\n", prog); + printf("\t-N Number of experiments [Default %d]\n", nof_runs); + printf("\t-n Uplink number of PRB [Default %d]\n", nof_prb); + printf("\t-f Preamble format [Default %d]\n", config_idx); + printf("\t-s SNR in dB [Default %.2f]\n", snr_dB); + printf("\t-v Activate verbose output [Default %s]\n", is_verbose ? "true" : "false"); +} + +static void parse_args(int argc, char** argv) +{ + int opt = 0; + while ((opt = getopt(argc, argv, "N:n:f:s:v")) != -1) { + switch (opt) { + case 'N': + nof_runs = (int)strtol(optarg, NULL, 10); + break; + case 'n': + nof_prb = (uint32_t)strtol(optarg, NULL, 10); + break; + case 'f': + config_idx = (uint32_t)strtol(optarg, NULL, 10); + break; + case 's': + snr_dB = strtof(optarg, NULL); + break; + case 'v': + is_verbose = true; + break; + default: + usage(argv[0]); + exit(-1); + } + } +} + +int main(int argc, char** argv) +{ + parse_args(argc, argv); + if (config_idx != 0) { + ERROR("Preamble format not yet implemented"); + return SRSRAN_ERROR; + } + srsran_prach_t prach; + + const int fft_size = srsran_symbol_sz(nof_prb); + const float main_scs_kHz = 15; // UL subcarrier spacing (i.e., Delta f) + const float sampling_time_us = 1000.0F / (main_scs_kHz * (float)fft_size); + const int slot_length = 15 * fft_size; // number of samples in a slot + + if (srsran_prach_init(&prach, fft_size)) { + ERROR("Initializing PRACH"); + srsran_prach_free(&prach); + return SRSRAN_ERROR; + } + + cf_t preamble[MAX_LEN]; + srsran_vec_cf_zero(preamble, MAX_LEN); + + srsran_prach_cfg_t prach_cfg; + ZERO_OBJECT(prach_cfg); + + // Setup according to TS38.104 Section 8.4 + prach_cfg.is_nr = true; + prach_cfg.config_idx = 0; // preamble format 0 + prach_cfg.hs_flag = false; // no high speed + prach_cfg.freq_offset = 0; + prach_cfg.root_seq_idx = 22; // logical (root sequence) index i + prach_cfg.zero_corr_zone = 1; // zero correlation zone -> implies Ncs = 13 + prach_cfg.num_ra_preambles = 0; // use default + const uint32_t seq_index = 32; // sequence index "v" + const float prach_scs_kHz = 1.25F; // PRACH subcarrier spacing (i.e., Delta f^RA) + const float max_time_error_us = 1.04F; // time error tolerance + const int nof_offset_steps = 10; + + if (srsran_prach_set_cfg(&prach, &prach_cfg, nof_prb)) { + ERROR("Error initiating PRACH object"); + srsran_prach_free(&prach); + return SRSRAN_ERROR; + } + + if (srsran_prach_gen(&prach, seq_index, 0, preamble) < SRSRAN_SUCCESS) { + ERROR("Generating PRACH preamble"); + srsran_prach_free(&prach); + return SRSRAN_ERROR; + } + + const uint32_t preamble_length = prach.N_seq; + + float prach_pwr_sqrt = sqrtf(srsran_vec_avg_power_cf(preamble, preamble_length)); + if (!isnormal(prach_pwr_sqrt)) { + ERROR("PRACH preamble power is not a finite, nonzero value"); + srsran_prach_free(&prach); + return SRSRAN_ERROR; + } + srsran_vec_sc_prod_cfc(preamble, 1.0F / prach_pwr_sqrt, preamble, preamble_length); + + int vector_length = 2 * slot_length; + cf_t symbols[vector_length]; + cf_t noise_vec[vector_length]; + + uint32_t indices[64] = {0}; + float offset_est[64] = {0}; + uint32_t n_indices = 0; + + float time_offset_us = 0; + int offset_samples = 0; + float noise_var = srsran_convert_dB_to_power(-snr_dB); + int ok_detection = 0; + int missed_detection = 0; + int false_detection_signal_tmp = 0; + int false_detection_signal = 0; + int false_detection_noise = 0; + int offset_est_error = 0; + + // Timing offset base value is equivalent to N_cs/2 + const uint32_t ZC_length = prach.N_zc; // Zadoff-Chu sequence length (i.e., L_RA) + const float base_time_offset_us = (float)prach.N_cs * 1000 / (2.0F * (float)ZC_length * prach_scs_kHz); + + int step = SRSRAN_MAX(nof_runs / 100, 1); + for (int i_run = 0; i_run < nof_runs; i_run++) { + // show we are doing something + if (i_run % (20 * step) == 0) { + printf("\n"); + } + if (i_run % step == 0) { + printf("*"); + fflush(stdout); + } + + srsran_vec_cf_zero(noise_vec, vector_length); + srsran_ch_awgn_c(noise_vec, noise_vec, noise_var, vector_length); + if (is_verbose) { + float prach_pwr = srsran_vec_avg_power_cf(preamble, preamble_length); + float noise_pwr = srsran_vec_avg_power_cf(noise_vec, vector_length); + printf(" Tx power: %.3f\n", prach_pwr); + printf(" Noise power: %.3f\n", noise_pwr); + printf(" Target/measured SNR: %.3f / %.3f dB\n", snr_dB, srsran_convert_power_to_dB(prach_pwr / noise_pwr)); + } + // Cycle timing offset with a 0.1-us step starting from the base value + for (int i = 0; i < nof_offset_steps; i++) { + time_offset_us = base_time_offset_us + (float)i * 0.1F; + offset_samples = (int)roundf(time_offset_us / sampling_time_us); + srsran_vec_cf_copy(symbols, noise_vec, vector_length); + srsran_vec_sum_ccc(&symbols[offset_samples], preamble, &symbols[offset_samples], preamble_length); + + srsran_prach_detect_offset(&prach, 0, &symbols[prach.N_cp], slot_length, indices, offset_est, NULL, &n_indices); + false_detection_signal_tmp = 0; + for (int j = 0; j < n_indices; j++) { + if (indices[j] != seq_index) { + false_detection_signal_tmp++; + } else if (fabsf(offset_est[j] * 1.0e6F - time_offset_us) > max_time_error_us) { + offset_est_error++; + } else { + ok_detection++; + } + } + false_detection_signal += (n_indices > 1 || false_detection_signal_tmp == 1); + // Missed detection if no preamble was detected or no detected preamble is the right one + missed_detection += (n_indices == 0 || n_indices == false_detection_signal_tmp); + } + + srsran_prach_detect_offset(&prach, 0, &noise_vec[prach.N_cp], slot_length, indices, offset_est, NULL, &n_indices); + false_detection_noise += (n_indices > 0); + } + int total_runs = nof_offset_steps * nof_runs; + if (missed_detection + ok_detection + offset_est_error != total_runs) { + srsran_prach_free(&prach); + ERROR("Counting detection errors"); + return SRSRAN_ERROR; + } + + printf("\n\nPRACH performance test: format 0, %d PRB, AWGN channel, SNR=%.1f dB\n", nof_prb, snr_dB); + printf("\nMissed detection probability: %.3e (%d out of %d)\n", + (float)missed_detection / (float)total_runs, + missed_detection, + total_runs); + printf("Probability of timing error: %.3e (%d out of %d)\n", + (float)offset_est_error / (float)total_runs, + offset_est_error, + total_runs); + printf("Probability of OK detection: %.3e (%d out of %d)\n", + (float)ok_detection / (float)total_runs, + ok_detection, + total_runs); + printf("\nProbability of false detection with preamble: %.3e (%d out of %d)\n", + (float)false_detection_signal / (float)total_runs, + false_detection_signal, + total_runs); + printf("Probability of false detection without preamble: %.3e (%d out of %d)\n", + (float)false_detection_noise / (float)nof_runs, + false_detection_noise, + nof_runs); + + srsran_prach_free(&prach); + + printf("Done\n"); +} diff --git a/lib/src/phy/phch/test/prach_test.c b/lib/src/phy/phch/test/prach_test.c index d569c3b7c6..0d0dd4cc6a 100644 --- a/lib/src/phy/phch/test/prach_test.c +++ b/lib/src/phy/phch/test/prach_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/prach_test_multi.c b/lib/src/phy/phch/test/prach_test_multi.c index 4aad361522..a07472aeee 100644 --- a/lib/src/phy/phch/test/prach_test_multi.c +++ b/lib/src/phy/phch/test/prach_test_multi.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/prach_test_usrp.c b/lib/src/phy/phch/test/prach_test_usrp.c index a50111bcf4..200733cbdb 100644 --- a/lib/src/phy/phch/test/prach_test_usrp.c +++ b/lib/src/phy/phch/test/prach_test_usrp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/psbch_file_test.c b/lib/src/phy/phch/test/psbch_file_test.c index 85ce4b90d7..c0ec667b4b 100644 --- a/lib/src/phy/phch/test/psbch_file_test.c +++ b/lib/src/phy/phch/test/psbch_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/psbch_test.c b/lib/src/phy/phch/test/psbch_test.c index ed3e07a593..0e75c0676a 100644 --- a/lib/src/phy/phch/test/psbch_test.c +++ b/lib/src/phy/phch/test/psbch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pscch_test.c b/lib/src/phy/phch/test/pscch_test.c index 5e9c8c4a0c..2b843187b1 100644 --- a/lib/src/phy/phch/test/pscch_test.c +++ b/lib/src/phy/phch/test/pscch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pssch_pscch_file_test.c b/lib/src/phy/phch/test/pssch_pscch_file_test.c index 38364e105e..bfd962c467 100644 --- a/lib/src/phy/phch/test/pssch_pscch_file_test.c +++ b/lib/src/phy/phch/test/pssch_pscch_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pssch_test.c b/lib/src/phy/phch/test/pssch_test.c index 3c9ec1e2cc..164eafb114 100644 --- a/lib/src/phy/phch/test/pssch_test.c +++ b/lib/src/phy/phch/test/pssch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pucch_nr_test.c b/lib/src/phy/phch/test/pucch_nr_test.c index 5b843f6df2..0f70a1e60d 100644 --- a/lib/src/phy/phch/test/pucch_nr_test.c +++ b/lib/src/phy/phch/test/pucch_nr_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -88,63 +88,71 @@ static int test_pucch_format0(srsran_pucch_nr_t* pucch, const srsran_pucch_nr_co static int test_pucch_format1(srsran_pucch_nr_t* pucch, const srsran_pucch_nr_common_cfg_t* cfg, srsran_chest_ul_res_t* chest_res, - cf_t* slot_symbols) + cf_t* slot_symbols, + bool enable_intra_slot_hopping) { srsran_slot_cfg_t slot = {}; srsran_pucch_nr_resource_t resource = {}; resource.format = SRSRAN_PUCCH_NR_FORMAT_1; + resource.intra_slot_hopping = enable_intra_slot_hopping; for (slot.idx = 0; slot.idx < SRSRAN_NSLOTS_PER_FRAME_NR(carrier.scs); slot.idx++) { for (resource.starting_prb = 0; resource.starting_prb < carrier.nof_prb; resource.starting_prb += starting_prb_stride) { - for (resource.nof_symbols = SRSRAN_PUCCH_NR_FORMAT1_MIN_NSYMB; - resource.nof_symbols <= SRSRAN_PUCCH_NR_FORMAT1_MAX_NSYMB; - resource.nof_symbols++) { - for (resource.start_symbol_idx = 0; - resource.start_symbol_idx <= - SRSRAN_MIN(SRSRAN_PUCCH_NR_FORMAT1_MAX_STARTSYMB, SRSRAN_NSYMB_PER_SLOT_NR - resource.nof_symbols); - resource.start_symbol_idx += starting_symbol_stride) { - for (resource.time_domain_occ = 0; resource.time_domain_occ <= SRSRAN_PUCCH_NR_FORMAT1_MAX_TOCC; - resource.time_domain_occ++) { - for (resource.initial_cyclic_shift = 0; resource.initial_cyclic_shift <= SRSRAN_PUCCH_NR_FORMAT1_MAX_CS; - resource.initial_cyclic_shift++) { - for (uint32_t nof_bits = 1; nof_bits <= SRSRAN_PUCCH_NR_FORMAT1_MAX_NOF_BITS; nof_bits++) { - for (uint32_t word = 0; word < (1U << nof_bits); word++) { - // Generate bits - uint8_t b[SRSRAN_PUCCH_NR_FORMAT1_MAX_NOF_BITS] = {}; - for (uint32_t i = 0; i < nof_bits; i++) { - b[i] = (word >> i) & 1U; - } - - // Encode PUCCH - TESTASSERT(srsran_pucch_nr_format1_encode(pucch, cfg, &slot, &resource, b, nof_bits, slot_symbols) == - SRSRAN_SUCCESS); - - // Put DMRS - TESTASSERT(srsran_dmrs_pucch_format1_put(pucch, &carrier, cfg, &slot, &resource, slot_symbols) == - SRSRAN_SUCCESS); - - // Apply AWGN - srsran_channel_awgn_run_c( - &awgn, slot_symbols, slot_symbols, carrier.nof_prb * SRSRAN_NRE * SRSRAN_NSYMB_PER_SLOT_NR); - - // Estimate channel - TESTASSERT(srsran_dmrs_pucch_format1_estimate( - pucch, cfg, &slot, &resource, slot_symbols, chest_res) == SRSRAN_SUCCESS); - - TESTASSERT(fabsf(chest_res->rsrp_dBfs - 0.0f) < 3.0f); - TESTASSERT(fabsf(chest_res->epre_dBfs - 0.0f) < 3.0f); - TESTASSERT(fabsf(chest_res->snr_db - snr_db) < 10.0f); - - // Decode PUCCH - uint8_t b_rx[SRSRAN_PUCCH_NR_FORMAT1_MAX_NOF_BITS]; - TESTASSERT(srsran_pucch_nr_format1_decode( - pucch, cfg, &slot, &resource, chest_res, slot_symbols, b_rx, nof_bits, NULL) == - SRSRAN_SUCCESS); - - // Check received bits - for (uint32_t i = 0; i < nof_bits; i++) { - TESTASSERT(b[i] == b_rx[i]); + for (resource.second_hop_prb = 0; resource.second_hop_prb < (enable_intra_slot_hopping) ? carrier.nof_prb : 0; + resource.second_hop_prb += starting_prb_stride) { + for (resource.nof_symbols = SRSRAN_PUCCH_NR_FORMAT1_MIN_NSYMB; + resource.nof_symbols <= SRSRAN_PUCCH_NR_FORMAT1_MAX_NSYMB; + resource.nof_symbols++) { + for (resource.start_symbol_idx = 0; + resource.start_symbol_idx <= + SRSRAN_MIN(SRSRAN_PUCCH_NR_FORMAT1_MAX_STARTSYMB, SRSRAN_NSYMB_PER_SLOT_NR - resource.nof_symbols); + resource.start_symbol_idx += starting_symbol_stride) { + for (resource.time_domain_occ = 0; resource.time_domain_occ <= SRSRAN_PUCCH_NR_FORMAT1_MAX_TOCC; + resource.time_domain_occ++) { + for (resource.initial_cyclic_shift = 0; resource.initial_cyclic_shift <= SRSRAN_PUCCH_NR_FORMAT1_MAX_CS; + resource.initial_cyclic_shift++) { + for (uint32_t nof_bits = 1; nof_bits <= SRSRAN_PUCCH_NR_FORMAT1_MAX_NOF_BITS; nof_bits++) { + for (uint32_t word = 0; word < (1U << nof_bits); word++) { + // Generate bits + uint8_t b[SRSRAN_PUCCH_NR_FORMAT1_MAX_NOF_BITS] = {}; + for (uint32_t i = 0; i < nof_bits; i++) { + b[i] = (word >> i) & 1U; + } + + // Encode PUCCH + TESTASSERT(srsran_pucch_nr_format1_encode( + pucch, cfg, &slot, &resource, b, nof_bits, slot_symbols) == SRSRAN_SUCCESS); + + // Put DMRS + TESTASSERT(srsran_dmrs_pucch_format1_put(pucch, &carrier, cfg, &slot, &resource, slot_symbols) == + SRSRAN_SUCCESS); + + // Apply AWGN + srsran_channel_awgn_run_c( + &awgn, slot_symbols, slot_symbols, carrier.nof_prb * SRSRAN_NRE * SRSRAN_NSYMB_PER_SLOT_NR); + + // Estimate channel + TESTASSERT(srsran_dmrs_pucch_format1_estimate( + pucch, cfg, &slot, &resource, slot_symbols, chest_res) == SRSRAN_SUCCESS); + + TESTASSERT(fabsf(chest_res->rsrp_dBfs - 0.0f) < 3.0f); + TESTASSERT(fabsf(chest_res->epre_dBfs - 0.0f) < 3.0f); + TESTASSERT(fabsf(chest_res->snr_db - snr_db) < 10.0f); + + // Decode PUCCH + uint8_t b_rx[SRSRAN_PUCCH_NR_FORMAT1_MAX_NOF_BITS]; + TESTASSERT(srsran_pucch_nr_format1_decode( + pucch, cfg, &slot, &resource, chest_res, slot_symbols, b_rx, nof_bits, NULL) == + SRSRAN_SUCCESS); + + // Check received bits + for (uint32_t i = 0; i < nof_bits; i++) { + if (b[i] != b_rx[i]) { + printf("aaa"); + } + TESTASSERT(b[i] == b_rx[i]); + } } } } @@ -345,9 +353,13 @@ int main(int argc, char** argv) } } - // Test Format 1 + // Test Format 1 with and without intra slot frequency hopping if (format < 0 || format == 1) { - if (test_pucch_format1(&pucch, &common_cfg, &chest_res, slot_symb) < SRSRAN_SUCCESS) { + if (test_pucch_format1(&pucch, &common_cfg, &chest_res, slot_symb, false) < SRSRAN_SUCCESS) { + ERROR("Failed PUCCH format 1"); + goto clean_exit; + } + if (test_pucch_format1(&pucch, &common_cfg, &chest_res, slot_symb, true) < SRSRAN_SUCCESS) { ERROR("Failed PUCCH format 1"); goto clean_exit; } diff --git a/lib/src/phy/phch/test/pucch_test.c b/lib/src/phy/phch/test/pucch_test.c index fcd98b3757..70654b633b 100644 --- a/lib/src/phy/phch/test/pucch_test.c +++ b/lib/src/phy/phch/test/pucch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/pusch_nr_bler_test.c b/lib/src/phy/phch/test/pusch_nr_bler_test.c new file mode 100644 index 0000000000..b2c97cf44c --- /dev/null +++ b/lib/src/phy/phch/test/pusch_nr_bler_test.c @@ -0,0 +1,438 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +/** + * \file pusch_nr_bler_test.c + * \brief BLER and throughput test for PUSCH NR. + * + * This program simulates several PUSCH transmissions in order to estimate its performance in terms of the receiver BLER + * and throughput (expressed as a percentage of the transmitted one). Specifically, the simulation runs until 100 + * transmissions fail (or after 2,000,000 transmitted transport blocks). Failures are detected by CRC verification. + * + * The simulation setup can be controlled by means of the following arguments. + * - -p num: sets the number of granted PUSCH PRBs to \c num. + * - -T tab: sets the modulation and coding scheme table (valid options: \c 64qam, \c 256qam, \c 64qamLowSE). + * - -m mcs: sets the modulation and coding scheme index to \c mcs. + * - -L num: sets the number of transmission layers to \c num. + * - -A num: sets the number of HARQ-ACK bits to \c num. + * - -C num: sets the number of CSI bits to \c num. + * - -N num: sets the maximum number of simulated transport blocks to \c num. + * - -s val: sets the nominal SNR to \c val (in dB). + * - -f : activates full BLER simulations (Tx--Rx comparison as opposed to CRC-verification only). + * - -v : activates verbose output. + * + * Example: + * \code{.cpp} + * pusch_nr_bler_test -p 52 -m 2 -T 64qam -s -1.8 -f + * \endcode + * + */ + +#include "srsran/phy/channel/ch_awgn.h" +#include "srsran/phy/phch/pusch_nr.h" +#include "srsran/phy/phch/ra_nr.h" +#include "srsran/phy/phch/ra_ul_nr.h" +#include "srsran/phy/utils/debug.h" +#include "srsran/phy/utils/random.h" +#include "srsran/phy/utils/vector.h" +#include + +static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR; +static uint32_t n_prb = 0; +static uint32_t mcs = 30; +static srsran_sch_cfg_nr_t pusch_cfg = {}; +static uint16_t rnti = 0x1234; +static uint32_t nof_ack_bits = 0; +static uint32_t nof_csi_bits = 0; +static uint32_t max_blocks = 2e6; // max number of simulated transport blocks +static float snr = 10; +static bool full_check = false; + +void usage(char* prog) +{ + printf("Usage: %s [pmTLACNsfv] \n", prog); + printf("\t-p Number of grant PRB [Default %d]\n", n_prb); + printf("\t-m MCS PRB [Default %d]\n", mcs); + printf("\t-T Provide MCS table (64qam, 256qam, 64qamLowSE) [Default %s]\n", + srsran_mcs_table_to_str(pusch_cfg.sch_cfg.mcs_table)); + printf("\t-L Provide number of layers [Default %d]\n", carrier.max_mimo_layers); + printf("\t-A Provide a number of HARQ-ACK bits [Default %d]\n", nof_ack_bits); + printf("\t-C Provide a number of CSI bits [Default %d]\n", nof_csi_bits); + printf("\t-N Maximum number of simulated transport blocks [Default %d]\n", max_blocks); + printf("\t-s Signal-to-Noise Ratio in dB [Default %.1f]\n", snr); + printf("\t-f Perform full BLER check instead of CRC only [Default %s]\n", full_check ? "true" : "false"); + printf("\t-v [set srsran_verbose to debug, default none]\n"); +} + +int parse_args(int argc, char** argv) +{ + int opt = 0; + while ((opt = getopt(argc, argv, "p:m:T:L:A:C:N:s:fv")) != -1) { + switch (opt) { + case 'p': + n_prb = (uint32_t)strtol(optarg, NULL, 10); + break; + case 'm': + mcs = (uint32_t)strtol(optarg, NULL, 10); + break; + case 'T': + pusch_cfg.sch_cfg.mcs_table = srsran_mcs_table_from_str(optarg); + break; + case 'L': + carrier.max_mimo_layers = (uint32_t)strtol(optarg, NULL, 10); + break; + case 'A': + nof_ack_bits = (uint32_t)strtol(optarg, NULL, 10); + break; + case 'C': + nof_csi_bits = (uint32_t)strtol(optarg, NULL, 10); + break; + case 'N': + max_blocks = (uint32_t)strtol(optarg, NULL, 10); + break; + case 's': + snr = strtof(optarg, NULL); + break; + case 'f': + full_check = true; + break; + case 'v': + increase_srsran_verbose_level(); + break; + default: + usage(argv[0]); + return SRSRAN_ERROR; + } + } + + return SRSRAN_SUCCESS; +} + +int main(int argc, char** argv) +{ + int ret = SRSRAN_ERROR; + srsran_pusch_nr_t pusch_tx = {}; + srsran_pusch_nr_t pusch_rx = {}; + srsran_chest_dl_res_t chest = {}; + srsran_random_t rand_gen = srsran_random_init(1234); + + srsran_pusch_data_nr_t data_tx = {}; + srsran_pusch_res_nr_t data_rx = {}; + cf_t* sf_symbols_tx[SRSRAN_MAX_LAYERS_NR] = {}; + cf_t* sf_symbols_rx[SRSRAN_MAX_LAYERS_NR] = {}; + + // Set default PUSCH configuration + pusch_cfg.sch_cfg.mcs_table = srsran_mcs_table_64qam; + + if (parse_args(argc, argv) < SRSRAN_SUCCESS) { + goto clean_exit; + } + + srsran_pusch_nr_args_t pusch_args = {}; + pusch_args.sch.disable_simd = false; + pusch_args.measure_evm = true; + + if (srsran_pusch_nr_init_ue(&pusch_tx, &pusch_args) < SRSRAN_SUCCESS) { + ERROR("Error initiating PUSCH for Tx"); + goto clean_exit; + } + + if (srsran_pusch_nr_init_gnb(&pusch_rx, &pusch_args) < SRSRAN_SUCCESS) { + ERROR("Error initiating SCH NR for Rx"); + goto clean_exit; + } + + if (srsran_pusch_nr_set_carrier(&pusch_tx, &carrier)) { + ERROR("Error setting SCH NR carrier"); + goto clean_exit; + } + + if (srsran_pusch_nr_set_carrier(&pusch_rx, &carrier)) { + ERROR("Error setting SCH NR carrier"); + goto clean_exit; + } + + uint32_t slot_length = SRSRAN_SLOT_LEN_RE_NR(carrier.nof_prb); + for (uint32_t i = 0; i < carrier.max_mimo_layers; i++) { + sf_symbols_tx[i] = srsran_vec_cf_malloc(slot_length); + sf_symbols_rx[i] = srsran_vec_cf_malloc(slot_length); + if (sf_symbols_tx[i] == NULL || sf_symbols_rx[i] == NULL) { + ERROR("Error malloc"); + goto clean_exit; + } + } + + for (uint32_t i = 0; i < pusch_tx.max_cw; i++) { + data_tx.payload[i] = srsran_vec_u8_malloc(SRSRAN_SLOT_MAX_NOF_BITS_NR); + data_rx.tb[i].payload = srsran_vec_u8_malloc(SRSRAN_SLOT_MAX_NOF_BITS_NR); + if (data_tx.payload[i] == NULL || data_rx.tb[i].payload == NULL) { + ERROR("Error malloc"); + goto clean_exit; + } + } + + srsran_softbuffer_tx_t softbuffer_tx = {}; + srsran_softbuffer_rx_t softbuffer_rx = {}; + + if (srsran_softbuffer_tx_init_guru(&softbuffer_tx, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < + SRSRAN_SUCCESS) { + ERROR("Error init soft-buffer"); + goto clean_exit; + } + + if (srsran_softbuffer_rx_init_guru(&softbuffer_rx, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < + SRSRAN_SUCCESS) { + ERROR("Error init soft-buffer"); + goto clean_exit; + } + + // Use grant default A time resources with m=0 + if (srsran_ra_ul_nr_pusch_time_resource_default_A(carrier.scs, 0, &pusch_cfg.grant) < SRSRAN_SUCCESS) { + ERROR("Error loading default grant"); + goto clean_exit; + } + + // Set PUSCH grant without considering any procedure + pusch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1; // No need for MIMO + pusch_cfg.grant.nof_layers = carrier.max_mimo_layers; + pusch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; + pusch_cfg.grant.rnti = rnti; + + // Check input: PRB + if (n_prb > carrier.nof_prb) { + ERROR("Invalid number of PRB"); + goto clean_exit; + } + + // Check input: MCS + uint32_t mcs_end = pusch_cfg.sch_cfg.mcs_table == srsran_mcs_table_256qam ? 28 : 29; + if (mcs > mcs_end) { + ERROR("Invalid MCS"); + goto clean_exit; + } + + srsran_sch_hl_cfg_nr_t sch_hl_cfg = {}; + sch_hl_cfg.scaling = 1.0F; + sch_hl_cfg.beta_offsets.fix_ack = 12.625F; + sch_hl_cfg.beta_offsets.fix_csi1 = 2.25F; + sch_hl_cfg.beta_offsets.fix_csi2 = 2.25F; + + if (srsran_chest_dl_res_init(&chest, carrier.nof_prb) < SRSRAN_SUCCESS) { + ERROR("Initiating chest"); + goto clean_exit; + } + + for (uint32_t n = 0; n < SRSRAN_MAX_PRB_NR; n++) { + pusch_cfg.grant.prb_idx[n] = (n < n_prb); + } + pusch_cfg.grant.nof_prb = n_prb; + + pusch_cfg.grant.dci_format = srsran_dci_format_nr_0_0; + pusch_cfg.grant.nof_dmrs_cdm_groups_without_data = 2; + pusch_cfg.dmrs.type = srsran_dmrs_sch_type_1; + pusch_cfg.dmrs.length = srsran_dmrs_sch_len_1; + pusch_cfg.dmrs.additional_pos = srsran_dmrs_sch_add_pos_2; + if (srsran_ra_nr_fill_tb(&pusch_cfg, &pusch_cfg.grant, mcs, &pusch_cfg.grant.tb[0]) < SRSRAN_SUCCESS) { + ERROR("Error filling tb"); + goto clean_exit; + } + + uint32_t n_blocks = 0; + uint32_t n_errors = 0; + uint32_t crc_false_pos = 0; + uint32_t crc_false_neg = 0; + float evm = 0; + for (; n_blocks < max_blocks && n_errors < 100; n_blocks++) { + // Generate SCH payload + for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) { + // Skip TB if no allocated + if (data_tx.payload[tb] == NULL) { + continue; + } + + // load payload with bytes + for (uint32_t i = 0; i < pusch_cfg.grant.tb[tb].tbs / 8 + 1; i++) { + data_tx.payload[tb][i] = (uint8_t)srsran_random_uniform_int_dist(rand_gen, 0, UINT8_MAX); + } + pusch_cfg.grant.tb[tb].softbuffer.tx = &softbuffer_tx; + } + + // Generate HARQ ACK bits + if (nof_ack_bits > 0) { + pusch_cfg.uci.ack.count = nof_ack_bits; + for (uint32_t i = 0; i < nof_ack_bits; i++) { + data_tx.uci.ack[i] = (uint8_t)srsran_random_uniform_int_dist(rand_gen, 0, 1); + } + } + + // Generate CSI report bits + uint8_t csi_report_tx[SRSRAN_UCI_NR_MAX_CSI1_BITS] = {}; + uint8_t csi_report_rx[SRSRAN_UCI_NR_MAX_CSI1_BITS] = {}; + if (nof_csi_bits > 0) { + pusch_cfg.uci.csi[0].cfg.quantity = SRSRAN_CSI_REPORT_QUANTITY_NONE; + pusch_cfg.uci.csi[0].K_csi_rs = nof_csi_bits; + pusch_cfg.uci.nof_csi = 1; + data_tx.uci.csi[0].none = csi_report_tx; + for (uint32_t i = 0; i < nof_csi_bits; i++) { + csi_report_tx[i] = (uint8_t)srsran_random_uniform_int_dist(rand_gen, 0, 1); + } + + data_rx.uci.csi[0].none = csi_report_rx; + } + + if (srsran_ra_ul_set_grant_uci_nr(&carrier, &sch_hl_cfg, &pusch_cfg.uci, &pusch_cfg) < SRSRAN_SUCCESS) { + ERROR("Setting UCI"); + goto clean_exit; + } + + if (srsran_pusch_nr_encode(&pusch_tx, &pusch_cfg, &pusch_cfg.grant, &data_tx, sf_symbols_tx) < SRSRAN_SUCCESS) { + ERROR("Error encoding"); + goto clean_exit; + } + + float noise_var = srsran_convert_dB_to_power(-snr); + for (uint32_t i = 0; i < carrier.max_mimo_layers; i++) { + srsran_ch_awgn_c(sf_symbols_tx[i], sf_symbols_rx[i], noise_var, slot_length); + // memcpy(sf_symbols_rx[i], sf_symbols_tx[i], slot_length * sizeof(cf_t)); + } + + if (get_srsran_verbose_level() >= SRSRAN_VERBOSE_INFO) { + uint32_t nof_re_total = carrier.nof_prb * SRSRAN_NRE; + uint32_t nof_re_used = pusch_cfg.grant.nof_prb * SRSRAN_NRE; + for (int i_layer = 0; i_layer < carrier.max_mimo_layers; i_layer++) { + INFO("Layer %d", i_layer); + float tx_power = 0; + float rx_power = 0; + uint8_t n_symbols = 0; + for (int i = 0; i < SRSRAN_NSYMB_PER_SLOT_NR; i++) { + if (!pusch_tx.dmrs_re_pattern.symbol[i]) { + n_symbols++; + tx_power += srsran_vec_avg_power_cf(sf_symbols_tx[0] + i * nof_re_total, nof_re_total); + rx_power += srsran_vec_avg_power_cf(sf_symbols_rx[0] + i * nof_re_total, nof_re_total); + } + } + tx_power *= (float)nof_re_total / nof_re_used; // compensate for unused REs + INFO(" Tx power: %.3f", tx_power / n_symbols); + INFO(" Rx power: %.3f", rx_power / n_symbols); + INFO(" SNR: %.3f dB", srsran_convert_power_to_dB(tx_power / (rx_power - tx_power))); + } + } + + for (uint32_t tb = 0; tb < SRSRAN_MAX_TB; tb++) { + pusch_cfg.grant.tb[tb].softbuffer.rx = &softbuffer_rx; + srsran_softbuffer_rx_reset(pusch_cfg.grant.tb[tb].softbuffer.rx); + } + + // assume perfect channel estimation (including noise variance) + for (uint32_t i = 0; i < pusch_cfg.grant.tb->nof_re; i++) { + chest.ce[0][0][i] = 1.0F; + } + chest.nof_re = pusch_cfg.grant.tb->nof_re; + chest.noise_estimate = 2 * noise_var; + + if (srsran_pusch_nr_decode(&pusch_rx, &pusch_cfg, &pusch_cfg.grant, &chest, sf_symbols_rx, &data_rx) < + SRSRAN_SUCCESS) { + ERROR("Error decoding"); + goto clean_exit; + } + + evm += data_rx.evm[0]; + // Validate UL-SCH CRC check + if (!data_rx.tb[0].crc) { + n_errors++; + printf("*"); + fflush(stdout); + if (n_errors % 20 == 0) { + printf("\n"); + } + } + + if (full_check) { + // Validate by comparing payload (recall, payload is represented in bytes) + if ((memcmp(data_rx.tb[0].payload, data_tx.payload[0], pusch_cfg.grant.tb[0].tbs * sizeof(uint8_t) / 8) == 0) && + !data_rx.tb[0].crc) { + printf("\nWARNING! Codeword OK but CRC KO!\n"); + crc_false_pos++; + } else if ((memcmp(data_rx.tb[0].payload, data_tx.payload[0], pusch_cfg.grant.tb[0].tbs * sizeof(uint8_t) / 8) != + 0) && + data_rx.tb[0].crc) { + printf("\nWarning! Codeword KO but CRC OK!\n"); + crc_false_neg++; + } + } + } + char str[512]; + srsran_pusch_nr_rx_info(&pusch_rx, &pusch_cfg, &pusch_cfg.grant, &data_rx, str, (uint32_t)sizeof(str)); + + char str_extra[2048]; + srsran_sch_cfg_nr_info(&pusch_cfg, str_extra, (uint32_t)sizeof(str_extra)); + printf("\nPUSCH: %s\n%s", str, str_extra); + + printf("\nNominal SNR: %.1f dB\n", snr); + printf("Average EVM: %.3f\n", evm / n_blocks); + + printf("BLER: %.3e (%d errors out of %d blocks)\n", (double)n_errors / n_blocks, n_errors, n_blocks); + printf("Tx Throughput: %.3e Mbps -- Rx Throughput: %.3e Mbps (%.2f%%)\n", + pusch_cfg.grant.tb[0].tbs / 1e3, + (n_blocks - n_errors) / 1e3 * pusch_cfg.grant.tb[0].tbs / n_blocks, + 100.0F * (n_blocks - n_errors) / n_blocks); + + if (full_check) { + uint32_t true_errors = n_errors + crc_false_neg - crc_false_pos; + printf("CRC: missed detection/Type I err. %.2f%% (%d out of %d)", + 100.0F * crc_false_neg / true_errors, + crc_false_neg, + true_errors); + printf(" -- false alarm %.2f%% (%d out of %d)", 100.0F * crc_false_pos / n_errors, crc_false_pos, n_errors); + printf(" -- Type II err. %.2f%% (%d out of %d)\n", + 100.0F * crc_false_pos / (n_blocks - true_errors), + crc_false_pos, + n_blocks - true_errors); + } + + ret = SRSRAN_SUCCESS; + +clean_exit: + srsran_chest_dl_res_free(&chest); + srsran_random_free(rand_gen); + srsran_pusch_nr_free(&pusch_tx); + srsran_pusch_nr_free(&pusch_rx); + for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { + if (data_tx.payload[i]) { + free(data_tx.payload[i]); + } + if (data_rx.tb[i].payload) { + free(data_rx.tb[i].payload); + } + } + for (uint32_t i = 0; i < SRSRAN_MAX_LAYERS_NR; i++) { + if (sf_symbols_tx[i]) { + free(sf_symbols_tx[i]); + } + if (sf_symbols_rx[i]) { + free(sf_symbols_rx[i]); + } + } + srsran_softbuffer_tx_free(&softbuffer_tx); + srsran_softbuffer_rx_free(&softbuffer_rx); + + return ret; +} diff --git a/lib/src/phy/phch/test/pusch_nr_test.c b/lib/src/phy/phch/test/pusch_nr_test.c index 5fe20ecba0..f1ece41192 100644 --- a/lib/src/phy/phch/test/pusch_nr_test.c +++ b/lib/src/phy/phch/test/pusch_nr_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -165,7 +165,7 @@ int main(int argc, char** argv) goto clean_exit; } - // Set PDSCH grant without considering any procedure + // Set PUSCH grant without considering any procedure pusch_cfg.grant.nof_dmrs_cdm_groups_without_data = 1; // No need for MIMO pusch_cfg.grant.nof_layers = carrier.max_mimo_layers; pusch_cfg.grant.dci_format = srsran_dci_format_nr_1_0; @@ -205,7 +205,7 @@ int main(int argc, char** argv) pusch_cfg.grant.dci_format = srsran_dci_format_nr_0_0; if (srsran_ra_nr_fill_tb(&pusch_cfg, &pusch_cfg.grant, mcs, &pusch_cfg.grant.tb[0]) < SRSRAN_SUCCESS) { - ERROR("Error filing tb"); + ERROR("Error filling tb"); goto clean_exit; } @@ -279,10 +279,12 @@ int main(int argc, char** argv) // Check symbols Mean Square Error (MSE) uint32_t nof_re = srsran_ra_dl_nr_slot_nof_re(&pusch_cfg, &pusch_cfg.grant); if (nof_re * pusch_cfg.grant.nof_layers > 0) { - float mse = 0.0f; + float mse = 0.0f; + float mse_tmp = 0.0f; for (uint32_t i = 0; i < pusch_cfg.grant.nof_layers; i++) { for (uint32_t j = 0; j < nof_re; j++) { - mse += cabsf(pusch_tx.d[i][j] - pusch_rx.d[i][j]); + mse_tmp = cabsf(pusch_tx.d[i][j] - pusch_rx.d[i][j]); + mse += mse_tmp * mse_tmp; } } mse = mse / (nof_re * pusch_cfg.grant.nof_layers); diff --git a/lib/src/phy/phch/test/pusch_test.c b/lib/src/phy/phch/test/pusch_test.c index 6beabb2384..8ceca173d4 100644 --- a/lib/src/phy/phch/test/pusch_test.c +++ b/lib/src/phy/phch/test/pusch_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -182,17 +182,17 @@ void parse_args(int argc, char** argv) int main(int argc, char** argv) { srsran_random_t random_h = srsran_random_init(0); - srsran_chest_ul_res_t chest_res; - srsran_pusch_t pusch_tx; - srsran_pusch_t pusch_rx; + srsran_chest_ul_res_t chest_res = {}; + srsran_pusch_t pusch_tx = {}; + srsran_pusch_t pusch_rx = {}; uint8_t* data = NULL; uint8_t* data_rx = NULL; cf_t* sf_symbols = NULL; int ret = -1; struct timeval t[3]; - srsran_pusch_cfg_t cfg; - srsran_softbuffer_tx_t softbuffer_tx; - srsran_softbuffer_rx_t softbuffer_rx; + srsran_pusch_cfg_t cfg = {}; + srsran_softbuffer_tx_t softbuffer_tx = {}; + srsran_softbuffer_rx_t softbuffer_rx = {}; srsran_crc_t crc_tb; ZERO_OBJECT(uci_data_tx); diff --git a/lib/src/phy/phch/test/ra_nr_test.c b/lib/src/phy/phch/test/ra_nr_test.c index b089d56c0f..894a724f16 100644 --- a/lib/src/phy/phch/test/ra_nr_test.c +++ b/lib/src/phy/phch/test/ra_nr_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/test/sch_nr_test.c b/lib/src/phy/phch/test/sch_nr_test.c index 41c2c1254d..516c383d1c 100644 --- a/lib/src/phy/phch/test/sch_nr_test.c +++ b/lib/src/phy/phch/test/sch_nr_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/uci.c b/lib/src/phy/phch/uci.c index 0128f39681..2a3014a58f 100644 --- a/lib/src/phy/phch/uci.c +++ b/lib/src/phy/phch/uci.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/phch/uci_nr.c b/lib/src/phy/phch/uci_nr.c index b071734c7c..aa7edc074a 100644 --- a/lib/src/phy/phch/uci_nr.c +++ b/lib/src/phy/phch/uci_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/resampling/CMakeLists.txt b/lib/src/phy/resampling/CMakeLists.txt index f6a43d6e97..0ab511ab45 100644 --- a/lib/src/phy/resampling/CMakeLists.txt +++ b/lib/src/phy/resampling/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/resampling/decim.c b/lib/src/phy/resampling/decim.c index 92a4fd579a..122f433537 100644 --- a/lib/src/phy/resampling/decim.c +++ b/lib/src/phy/resampling/decim.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/resampling/interp.c b/lib/src/phy/resampling/interp.c index 31a0134319..52f642d512 100644 --- a/lib/src/phy/resampling/interp.c +++ b/lib/src/phy/resampling/interp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/resampling/resample_arb.c b/lib/src/phy/resampling/resample_arb.c index 6bd4d8fafa..f3434624ee 100644 --- a/lib/src/phy/resampling/resample_arb.c +++ b/lib/src/phy/resampling/resample_arb.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/resampling/resampler.c b/lib/src/phy/resampling/resampler.c index c63d1b385e..6573022920 100644 --- a/lib/src/phy/resampling/resampler.c +++ b/lib/src/phy/resampling/resampler.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/resampling/test/CMakeLists.txt b/lib/src/phy/resampling/test/CMakeLists.txt index 9347759c8d..fa736f4a16 100644 --- a/lib/src/phy/resampling/test/CMakeLists.txt +++ b/lib/src/phy/resampling/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/resampling/test/resample_arb_bench.c b/lib/src/phy/resampling/test/resample_arb_bench.c index 2083925400..49a8252e09 100644 --- a/lib/src/phy/resampling/test/resample_arb_bench.c +++ b/lib/src/phy/resampling/test/resample_arb_bench.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/resampling/test/resample_arb_test.c b/lib/src/phy/resampling/test/resample_arb_test.c index 3100e9c971..a5737fa3a7 100644 --- a/lib/src/phy/resampling/test/resample_arb_test.c +++ b/lib/src/phy/resampling/test/resample_arb_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/resampling/test/resampler_test.c b/lib/src/phy/resampling/test/resampler_test.c index b06de4b6d1..da569cbea7 100644 --- a/lib/src/phy/resampling/test/resampler_test.c +++ b/lib/src/phy/resampling/test/resampler_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/rf/CMakeLists.txt b/lib/src/phy/rf/CMakeLists.txt index 8bd3f899b6..54fb879a54 100644 --- a/lib/src/phy/rf/CMakeLists.txt +++ b/lib/src/phy/rf/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -23,13 +23,32 @@ if(RF_FOUND) add_library(srsran_rf_utils STATIC rf_utils.c) target_link_libraries(srsran_rf_utils srsran_phy) - # Include common RF files + # Top-level RF library sources set(SOURCES_RF "") list(APPEND SOURCES_RF rf_imp.c) - if (UHD_FOUND) + # Lists of static (builtin) and dynamic RF plugins + set(STATIC_PLUGINS "") + set(DYNAMIC_PLUGINS "") + + if (ENABLE_RF_PLUGINS) + add_definitions(-DENABLE_RF_PLUGINS) + endif (ENABLE_RF_PLUGINS) + + # RF plugins + if (UHD_FOUND AND ENABLE_UHD) add_definitions(-DENABLE_UHD) - list(APPEND SOURCES_RF rf_uhd_imp.cc) + set(SOURCES_UHD rf_uhd_imp.cc) + if (ENABLE_RF_PLUGINS) + add_library(srsran_rf_uhd SHARED ${SOURCES_UHD}) + set_target_properties(srsran_rf_uhd PROPERTIES VERSION ${SRSRAN_VERSION_STRING} SOVERSION ${SRSRAN_SOVERSION}) + list(APPEND DYNAMIC_PLUGINS srsran_rf_uhd) + else (ENABLE_RF_PLUGINS) + add_library(srsran_rf_uhd STATIC ${SOURCES_UHD}) + list(APPEND STATIC_PLUGINS srsran_rf_uhd) + endif (ENABLE_RF_PLUGINS) + target_link_libraries(srsran_rf_uhd srsran_rf_utils srsran_phy ${UHD_LIBRARIES} ${Boost_LIBRARIES}) + install(TARGETS srsran_rf_uhd DESTINATION ${LIBRARY_DIR} OPTIONAL) # If found, add a macro to inform the UHD driver about the available feature if (UHD_ENABLE_X300_FW_RESET) @@ -41,62 +60,123 @@ if(RF_FOUND) if (UHD_ENABLE_CUSTOM_RFNOC) add_definitions(-DUHD_ENABLE_CUSTOM_RFNOC) endif(UHD_ENABLE_CUSTOM_RFNOC) - endif (UHD_FOUND) - - if (UHD_FOUND AND UHD_ENABLE_CUSTOM_RFNOC) - add_executable(rfnoc_test rfnoc_test.cc) - target_link_libraries(rfnoc_test srsran_rf ${UHD_LIBRARIES} ${Boost_LIBRARIES} /usr/lib/x86_64-linux-gnu/libboost_system.so) - message(info ${Boost_LIBRARIES}) - endif (UHD_FOUND AND UHD_ENABLE_CUSTOM_RFNOC) + endif (UHD_FOUND AND ENABLE_UHD) - if (BLADERF_FOUND) + if (BLADERF_FOUND AND ENABLE_BLADERF) add_definitions(-DENABLE_BLADERF) - list(APPEND SOURCES_RF rf_blade_imp.c) - endif (BLADERF_FOUND) + set(SOURCES_BLADE rf_blade_imp.c) + if (ENABLE_RF_PLUGINS) + add_library(srsran_rf_blade SHARED ${SOURCES_BLADE}) + set_target_properties(srsran_rf_blade PROPERTIES VERSION ${SRSRAN_VERSION_STRING} SOVERSION ${SRSRAN_SOVERSION}) + list(APPEND DYNAMIC_PLUGINS srsran_rf_blade) + else (ENABLE_RF_PLUGINS) + add_library(srsran_rf_blade STATIC ${SOURCES_BLADE}) + list(APPEND STATIC_PLUGINS srsran_rf_blade) + endif (ENABLE_RF_PLUGINS) + target_link_libraries(srsran_rf_blade srsran_rf_utils srsran_phy ${BLADERF_LIBRARIES}) + install(TARGETS srsran_rf_blade DESTINATION ${LIBRARY_DIR} OPTIONAL) + endif (BLADERF_FOUND AND ENABLE_BLADERF) if (SOAPYSDR_FOUND AND ENABLE_SOAPYSDR) add_definitions(-DENABLE_SOAPYSDR) - list(APPEND SOURCES_RF rf_soapy_imp.c) + set(SOURCES_SOAPY rf_soapy_imp.c) + if (ENABLE_RF_PLUGINS) + add_library(srsran_rf_soapy SHARED ${SOURCES_SOAPY}) + set_target_properties(srsran_rf_soapy PROPERTIES VERSION ${SRSRAN_VERSION_STRING} SOVERSION ${SRSRAN_SOVERSION}) + list(APPEND DYNAMIC_PLUGINS srsran_rf_soapy) + else (ENABLE_RF_PLUGINS) + add_library(srsran_rf_soapy STATIC ${SOURCES_SOAPY}) + list(APPEND STATIC_PLUGINS srsran_rf_soapy) + endif (ENABLE_RF_PLUGINS) + target_link_libraries(srsran_rf_soapy srsran_rf_utils srsran_phy ${SOAPYSDR_LIBRARIES}) + install(TARGETS srsran_rf_soapy DESTINATION ${LIBRARY_DIR} OPTIONAL) endif (SOAPYSDR_FOUND AND ENABLE_SOAPYSDR) - if(SKIQ_FOUND) + if(SKIQ_FOUND AND ENABLE_SKIQ) add_executable(skiq_pps_test skiq_pps_test.c) target_link_libraries(skiq_pps_test ${SKIQ_LIBRARIES} rt pthread m) add_definitions(-DENABLE_SIDEKIQ) - list(APPEND SOURCES_RF rf_skiq_imp.c rf_skiq_imp_card.c rf_skiq_imp_port.c) - endif(SKIQ_FOUND) + set(SOURCES_SKIQ rf_skiq_imp.c rf_skiq_imp_card.c rf_skiq_imp_port.c) + if (ENABLE_RF_PLUGINS) + add_library(srsran_rf_skiq SHARED ${SOURCES_SKIQ}) + set_target_properties(srsran_rf_skiq PROPERTIES VERSION ${SRSRAN_VERSION_STRING} SOVERSION ${SRSRAN_SOVERSION}) + list(APPEND DYNAMIC_PLUGINS srsran_rf_skiq) + else (ENABLE_RF_PLUGINS) + add_library(srsran_rf_skiq STATIC ${SOURCES_SKIQ}) + list(APPEND STATIC_PLUGINS srsran_rf_skiq) + endif (ENABLE_RF_PLUGINS) + target_link_libraries(srsran_rf_skiq srsran_rf_utils srsran_phy ${SKIQ_LIBRARIES} rt) + install(TARGETS srsran_rf_skiq DESTINATION ${LIBRARY_DIR} OPTIONAL) + endif(SKIQ_FOUND AND ENABLE_SKIQ) - if (ZEROMQ_FOUND) + if (ZEROMQ_FOUND AND ENABLE_ZEROMQ) add_definitions(-DENABLE_ZEROMQ) - list(APPEND SOURCES_RF rf_zmq_imp.c rf_zmq_imp_tx.c rf_zmq_imp_rx.c) - endif (ZEROMQ_FOUND) + set(SOURCES_ZMQ rf_zmq_imp.c rf_zmq_imp_tx.c rf_zmq_imp_rx.c) + if (ENABLE_RF_PLUGINS) + add_library(srsran_rf_zmq SHARED ${SOURCES_ZMQ}) + set_target_properties(srsran_rf_zmq PROPERTIES VERSION ${SRSRAN_VERSION_STRING} SOVERSION ${SRSRAN_SOVERSION}) + list(APPEND DYNAMIC_PLUGINS srsran_rf_zmq) + else (ENABLE_RF_PLUGINS) + add_library(srsran_rf_zmq STATIC ${SOURCES_ZMQ}) + list(APPEND STATIC_PLUGINS srsran_rf_zmq) + endif (ENABLE_RF_PLUGINS) + target_link_libraries(srsran_rf_zmq srsran_rf_utils srsran_phy ${ZEROMQ_LIBRARIES}) + install(TARGETS srsran_rf_zmq DESTINATION ${LIBRARY_DIR} OPTIONAL) + endif (ZEROMQ_FOUND AND ENABLE_ZEROMQ) - add_library(srsran_rf SHARED ${SOURCES_RF}) - target_link_libraries(srsran_rf srsran_rf_utils srsran_phy) - set_target_properties(srsran_rf PROPERTIES VERSION ${SRSRAN_VERSION_STRING} SOVERSION ${SRSRAN_SOVERSION}) - - if (UHD_FOUND) - target_link_libraries(srsran_rf ${UHD_LIBRARIES}) - endif (UHD_FOUND) + # Add sources of file-based RF directly to the RF library (not as a plugin) + list(APPEND SOURCES_RF rf_file_imp.c rf_file_imp_tx.c rf_file_imp_rx.c) - if (BLADERF_FOUND) - target_link_libraries(srsran_rf ${BLADERF_LIBRARIES}) - endif (BLADERF_FOUND) + # Top-level RF library + add_library(srsran_rf_object OBJECT ${SOURCES_RF}) + set_property(TARGET srsran_rf_object PROPERTY POSITION_INDEPENDENT_CODE 1) + set(TOP_RF_LIBS) + if (ENABLE_RF_PLUGINS) + # Build as shared library with optional RF plugins (optional dependencies) + if (DYNAMIC_PLUGINS) + add_dependencies(srsran_rf_object ${DYNAMIC_PLUGINS}) + endif (DYNAMIC_PLUGINS) + add_library(srsran_rf SHARED $) + target_link_libraries(srsran_rf dl) + list(APPEND TOP_RF_LIBS srsran_rf) - if (SOAPYSDR_FOUND AND ENABLE_SOAPYSDR) - target_link_libraries(srsran_rf ${SOAPYSDR_LIBRARIES}) - endif (SOAPYSDR_FOUND AND ENABLE_SOAPYSDR) + # Add $ORIGIN (i.e. current location of this library) to rpath of srsran_rf. + # This ensures that it will find the plugins that reside in the same directory as the library + set_target_properties(srsran_rf PROPERTIES BUILD_RPATH "\$ORIGIN/") + set_target_properties(srsran_rf PROPERTIES INSTALL_RPATH "\$ORIGIN/") + else (ENABLE_RF_PLUGINS) + # Build as static library with built-in RF plugins (mandatory dependencies) + add_library(srsran_rf STATIC $) + target_link_libraries(srsran_rf ${STATIC_PLUGINS}) + list(APPEND TOP_RF_LIBS srsran_rf) + + # Also build as shared library with built-in RF plugins (mandatory dependencies) + add_library(srsran_rf_shared SHARED $) + target_link_libraries(srsran_rf_shared ${STATIC_PLUGINS}) + list(APPEND TOP_RF_LIBS srsran_rf_shared) + set_target_properties(srsran_rf_shared PROPERTIES OUTPUT_NAME srsran_rf) + endif (ENABLE_RF_PLUGINS) - if(SKIQ_FOUND) - target_link_libraries(srsran_rf ${SKIQ_LIBRARIES} rt) - endif(SKIQ_FOUND) + foreach (TOP_RF_LIB ${TOP_RF_LIBS}) + target_link_libraries(${TOP_RF_LIB} srsran_rf_utils srsran_phy) + set_target_properties(${TOP_RF_LIB} PROPERTIES VERSION ${SRSRAN_VERSION_STRING} SOVERSION ${SRSRAN_SOVERSION}) + install(TARGETS ${TOP_RF_LIB} DESTINATION ${LIBRARY_DIR} OPTIONAL) + endforeach () + + # Tests + if (UHD_FOUND AND UHD_ENABLE_CUSTOM_RFNOC) + add_executable(rfnoc_test rfnoc_test.cc) + target_link_libraries(rfnoc_test srsran_rf ${UHD_LIBRARIES} ${Boost_LIBRARIES} /usr/lib/x86_64-linux-gnu/libboost_system.so) + message(info ${Boost_LIBRARIES}) + endif (UHD_FOUND AND UHD_ENABLE_CUSTOM_RFNOC) if (ZEROMQ_FOUND) - target_link_libraries(srsran_rf ${ZEROMQ_LIBRARIES}) add_executable(rf_zmq_test rf_zmq_test.c) target_link_libraries(rf_zmq_test srsran_rf) #add_test(rf_zmq_test rf_zmq_test) endif (ZEROMQ_FOUND) - INSTALL(TARGETS srsran_rf DESTINATION ${LIBRARY_DIR}) + add_executable(rf_file_test rf_file_test.c) + target_link_libraries(rf_file_test srsran_rf) + add_test(rf_file_test rf_file_test) endif(RF_FOUND) diff --git a/lib/src/phy/rf/rf_blade_imp.c b/lib/src/phy/rf/rf_blade_imp.c index 52cdbc8b7f..16c2f6cd25 100644 --- a/lib/src/phy/rf/rf_blade_imp.c +++ b/lib/src/phy/rf/rf_blade_imp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,6 +24,7 @@ #include #include "rf_blade_imp.h" +#include "rf_plugin.h" #include "srsran/phy/common/timestamp.h" #include "srsran/phy/utils/debug.h" #include "srsran/phy/utils/vector.h" @@ -544,3 +545,44 @@ int rf_blade_send_timed(void* h, return nsamples; } + +rf_dev_t srsran_rf_dev_blade = {"bladeRF", + rf_blade_devname, + rf_blade_start_rx_stream, + rf_blade_stop_rx_stream, + rf_blade_flush_buffer, + rf_blade_has_rssi, + rf_blade_get_rssi, + rf_blade_suppress_stdout, + rf_blade_register_error_handler, + rf_blade_open, + .srsran_rf_open_multi = rf_blade_open_multi, + rf_blade_close, + rf_blade_set_rx_srate, + rf_blade_set_rx_gain, + rf_blade_set_rx_gain_ch, + rf_blade_set_tx_gain, + rf_blade_set_tx_gain_ch, + rf_blade_get_rx_gain, + rf_blade_get_tx_gain, + rf_blade_get_info, + rf_blade_set_rx_freq, + rf_blade_set_tx_srate, + rf_blade_set_tx_freq, + rf_blade_get_time, + NULL, + rf_blade_recv_with_time, + rf_blade_recv_with_time_multi, + rf_blade_send_timed, + .srsran_rf_send_timed_multi = rf_blade_send_timed_multi}; + +#ifdef ENABLE_RF_PLUGINS +int register_plugin(rf_dev_t** rf_api) +{ + if (rf_api == NULL) { + return SRSRAN_ERROR; + } + *rf_api = &srsran_rf_dev_blade; + return SRSRAN_SUCCESS; +} +#endif /* ENABLE_RF_PLUGINS */ diff --git a/lib/src/phy/rf/rf_blade_imp.h b/lib/src/phy/rf/rf_blade_imp.h index e20a7b0bb4..4c0c760155 100644 --- a/lib/src/phy/rf/rf_blade_imp.h +++ b/lib/src/phy/rf/rf_blade_imp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,11 +19,16 @@ * */ +#ifndef SRSRAN_RF_BLADE_IMP_H_ +#define SRSRAN_RF_BLADE_IMP_H_ + #include "srsran/config.h" #include "srsran/phy/rf/rf.h" #define DEVNAME "bladerf" +extern rf_dev_t srsran_rf_dev_blade; + SRSRAN_API int rf_blade_open(char* args, void** handler); SRSRAN_API int rf_blade_open_multi(char* args, void** handler, uint32_t nof_channels); @@ -99,3 +104,5 @@ SRSRAN_API int rf_blade_send_timed(void* h, bool blocking, bool is_start_of_burst, bool is_end_of_burst); + +#endif /* SRSRAN_RF_BLADE_IMP_H_ */ diff --git a/lib/src/phy/rf/rf_dev.h b/lib/src/phy/rf/rf_dev.h index ef136b8949..c2737ba3a5 100644 --- a/lib/src/phy/rf/rf_dev.h +++ b/lib/src/phy/rf/rf_dev.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,242 +22,58 @@ #include "srsran/phy/rf/rf.h" #include -/* RF frontend API */ -typedef struct { - const char* name; - const char* (*srsran_rf_devname)(void* h); - int (*srsran_rf_start_rx_stream)(void* h, bool now); - int (*srsran_rf_stop_rx_stream)(void* h); - void (*srsran_rf_flush_buffer)(void* h); - bool (*srsran_rf_has_rssi)(void* h); - float (*srsran_rf_get_rssi)(void* h); - void (*srsran_rf_suppress_stdout)(void* h); - void (*srsran_rf_register_error_handler)(void* h, srsran_rf_error_handler_t error_handler, void* arg); - int (*srsran_rf_open)(char* args, void** h); - int (*srsran_rf_open_multi)(char* args, void** h, uint32_t nof_channels); - int (*srsran_rf_close)(void* h); - double (*srsran_rf_set_rx_srate)(void* h, double freq); - int (*srsran_rf_set_rx_gain)(void* h, double gain); - int (*srsran_rf_set_rx_gain_ch)(void* h, uint32_t ch, double gain); - int (*srsran_rf_set_tx_gain)(void* h, double gain); - int (*srsran_rf_set_tx_gain_ch)(void* h, uint32_t ch, double gain); - double (*srsran_rf_get_rx_gain)(void* h); - double (*srsran_rf_get_tx_gain)(void* h); - srsran_rf_info_t* (*srsran_rf_get_info)(void* h); - double (*srsran_rf_set_rx_freq)(void* h, uint32_t ch, double freq); - double (*srsran_rf_set_tx_srate)(void* h, double freq); - double (*srsran_rf_set_tx_freq)(void* h, uint32_t ch, double freq); - void (*srsran_rf_get_time)(void* h, time_t* secs, double* frac_secs); - void (*srsran_rf_sync_pps)(void* h); - int (*srsran_rf_recv_with_time)(void* h, - void* data, - uint32_t nsamples, - bool blocking, - time_t* secs, - double* frac_secs); - int (*srsran_rf_recv_with_time_multi)(void* h, - void** data, - uint32_t nsamples, - bool blocking, - time_t* secs, - double* frac_secs); - int (*srsran_rf_send_timed)(void* h, - void* data, - int nsamples, - time_t secs, - double frac_secs, - bool has_time_spec, - bool blocking, - bool is_start_of_burst, - bool is_end_of_burst); - int (*srsran_rf_send_timed_multi)(void* h, - void** data, - int nsamples, - time_t secs, - double frac_secs, - bool has_time_spec, - bool blocking, - bool is_start_of_burst, - bool is_end_of_burst); -} rf_dev_t; - /* Define implementation for UHD */ #ifdef ENABLE_UHD - +#ifdef ENABLE_RF_PLUGINS +static srsran_rf_plugin_t plugin_uhd = {"libsrsran_rf_uhd.so", NULL, NULL}; +#else #include "rf_uhd_imp.h" - -static rf_dev_t dev_uhd = {"UHD", - rf_uhd_devname, - rf_uhd_start_rx_stream, - rf_uhd_stop_rx_stream, - rf_uhd_flush_buffer, - rf_uhd_has_rssi, - rf_uhd_get_rssi, - rf_uhd_suppress_stdout, - rf_uhd_register_error_handler, - rf_uhd_open, - .srsran_rf_open_multi = rf_uhd_open_multi, - rf_uhd_close, - rf_uhd_set_rx_srate, - rf_uhd_set_rx_gain, - rf_uhd_set_rx_gain_ch, - rf_uhd_set_tx_gain, - rf_uhd_set_tx_gain_ch, - rf_uhd_get_rx_gain, - rf_uhd_get_tx_gain, - rf_uhd_get_info, - rf_uhd_set_rx_freq, - rf_uhd_set_tx_srate, - rf_uhd_set_tx_freq, - rf_uhd_get_time, - rf_uhd_sync_pps, - rf_uhd_recv_with_time, - rf_uhd_recv_with_time_multi, - rf_uhd_send_timed, - .srsran_rf_send_timed_multi = rf_uhd_send_timed_multi}; +static srsran_rf_plugin_t plugin_uhd = {"", NULL, &srsran_rf_dev_uhd}; +#endif #endif /* Define implementation for bladeRF */ #ifdef ENABLE_BLADERF - +#ifdef ENABLE_RF_PLUGINS +static srsran_rf_plugin_t plugin_blade = {"libsrsran_rf_blade.so", NULL, NULL}; +#else #include "rf_blade_imp.h" - -static rf_dev_t dev_blade = {"bladeRF", - rf_blade_devname, - rf_blade_start_rx_stream, - rf_blade_stop_rx_stream, - rf_blade_flush_buffer, - rf_blade_has_rssi, - rf_blade_get_rssi, - rf_blade_suppress_stdout, - rf_blade_register_error_handler, - rf_blade_open, - .srsran_rf_open_multi = rf_blade_open_multi, - rf_blade_close, - rf_blade_set_rx_srate, - rf_blade_set_rx_gain, - rf_blade_set_rx_gain_ch, - rf_blade_set_tx_gain, - rf_blade_set_tx_gain_ch, - rf_blade_get_rx_gain, - rf_blade_get_tx_gain, - rf_blade_get_info, - rf_blade_set_rx_freq, - rf_blade_set_tx_srate, - rf_blade_set_tx_freq, - rf_blade_get_time, - NULL, - rf_blade_recv_with_time, - rf_blade_recv_with_time_multi, - rf_blade_send_timed, - .srsran_rf_send_timed_multi = rf_blade_send_timed_multi}; +static srsran_rf_plugin_t plugin_blade = {"", NULL, &srsran_rf_dev_blade}; +#endif #endif +/* Define implementation for SoapySDR */ #ifdef ENABLE_SOAPYSDR - +#ifdef ENABLE_RF_PLUGINS +static srsran_rf_plugin_t plugin_soapy = {"libsrsran_rf_soapy.so", NULL, NULL}; +#else #include "rf_soapy_imp.h" - -static rf_dev_t dev_soapy = {"soapy", - rf_soapy_devname, - rf_soapy_start_rx_stream, - rf_soapy_stop_rx_stream, - rf_soapy_flush_buffer, - rf_soapy_has_rssi, - rf_soapy_get_rssi, - rf_soapy_suppress_stdout, - rf_soapy_register_error_handler, - rf_soapy_open, - rf_soapy_open_multi, - rf_soapy_close, - rf_soapy_set_rx_srate, - rf_soapy_set_rx_gain, - rf_soapy_set_rx_gain_ch, - rf_soapy_set_tx_gain, - rf_soapy_set_tx_gain_ch, - rf_soapy_get_rx_gain, - rf_soapy_get_tx_gain, - rf_soapy_get_info, - rf_soapy_set_rx_freq, - rf_soapy_set_tx_srate, - rf_soapy_set_tx_freq, - rf_soapy_get_time, - NULL, - rf_soapy_recv_with_time, - rf_soapy_recv_with_time_multi, - rf_soapy_send_timed, - .srsran_rf_send_timed_multi = rf_soapy_send_timed_multi}; - +static srsran_rf_plugin_t plugin_soapy = {"", NULL, &srsran_rf_dev_soapy}; +#endif #endif -/* Define implementation for UHD */ +/* Define implementation for ZeroMQ */ #ifdef ENABLE_ZEROMQ - +#ifdef ENABLE_RF_PLUGINS +static srsran_rf_plugin_t plugin_zmq = {"libsrsran_rf_zmq.so", NULL, NULL}; +#else #include "rf_zmq_imp.h" - -static rf_dev_t dev_zmq = {"zmq", - rf_zmq_devname, - rf_zmq_start_rx_stream, - rf_zmq_stop_rx_stream, - rf_zmq_flush_buffer, - rf_zmq_has_rssi, - rf_zmq_get_rssi, - rf_zmq_suppress_stdout, - rf_zmq_register_error_handler, - rf_zmq_open, - .srsran_rf_open_multi = rf_zmq_open_multi, - rf_zmq_close, - rf_zmq_set_rx_srate, - rf_zmq_set_rx_gain, - rf_zmq_set_rx_gain_ch, - rf_zmq_set_tx_gain, - rf_zmq_set_tx_gain_ch, - rf_zmq_get_rx_gain, - rf_zmq_get_tx_gain, - rf_zmq_get_info, - rf_zmq_set_rx_freq, - rf_zmq_set_tx_srate, - rf_zmq_set_tx_freq, - rf_zmq_get_time, - NULL, - rf_zmq_recv_with_time, - rf_zmq_recv_with_time_multi, - rf_zmq_send_timed, - .srsran_rf_send_timed_multi = rf_zmq_send_timed_multi}; +static srsran_rf_plugin_t plugin_zmq = {"", NULL, &srsran_rf_dev_zmq}; #endif +#endif + +/* Define implementation for file-based RF */ +#include "rf_file_imp.h" +static srsran_rf_plugin_t plugin_file = {"", NULL, &srsran_rf_dev_file}; /* Define implementation for Sidekiq */ #ifdef ENABLE_SIDEKIQ - +#ifdef ENABLE_RF_PLUGINS +static srsran_rf_plugin_t plugin_skiq = {"libsrsran_rf_skiq.so", NULL, NULL}; +#else #include "rf_skiq_imp.h" - -static rf_dev_t dev_skiq = {.name = "Sidekiq", - .srsran_rf_devname = rf_skiq_devname, - .srsran_rf_start_rx_stream = rf_skiq_start_rx_stream, - .srsran_rf_stop_rx_stream = rf_skiq_stop_rx_stream, - .srsran_rf_flush_buffer = rf_skiq_flush_buffer, - .srsran_rf_has_rssi = rf_skiq_has_rssi, - .srsran_rf_get_rssi = rf_skiq_get_rssi, - .srsran_rf_suppress_stdout = rf_skiq_suppress_stdout, - .srsran_rf_register_error_handler = rf_skiq_register_error_handler, - .srsran_rf_open = rf_skiq_open, - .srsran_rf_open_multi = rf_skiq_open_multi, - .srsran_rf_close = rf_skiq_close, - .srsran_rf_set_rx_srate = rf_skiq_set_rx_srate, - .srsran_rf_set_tx_srate = rf_skiq_set_tx_srate, - .srsran_rf_set_rx_gain = rf_skiq_set_rx_gain, - .srsran_rf_set_tx_gain = rf_skiq_set_tx_gain, - .srsran_rf_set_tx_gain_ch = rf_skiq_set_tx_gain_ch, - .srsran_rf_set_rx_gain_ch = rf_skiq_set_rx_gain_ch, - .srsran_rf_get_rx_gain = rf_skiq_get_rx_gain, - .srsran_rf_get_tx_gain = rf_skiq_get_tx_gain, - .srsran_rf_get_info = rf_skiq_get_info, - .srsran_rf_set_rx_freq = rf_skiq_set_rx_freq, - .srsran_rf_set_tx_freq = rf_skiq_set_tx_freq, - .srsran_rf_get_time = rf_skiq_get_time, - .srsran_rf_recv_with_time = rf_skiq_recv_with_time, - .srsran_rf_recv_with_time_multi = rf_skiq_recv_with_time_multi, - .srsran_rf_send_timed = rf_skiq_send_timed, - .srsran_rf_send_timed_multi = rf_skiq_send_timed_multi}; +static srsran_rf_plugin_t plugin_skiq = {"", NULL, &srsran_rf_dev_skiq}; +#endif #endif //#define ENABLE_DUMMY_DEV @@ -270,30 +86,36 @@ int dummy_rcv() } void dummy_fnc() {} -static rf_dev_t dev_dummy = {"dummy", dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, - dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, - dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_rcv, - dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc}; +static rf_dev_t srsran_rf_dev_dummy = { + "dummy", dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, + dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, + dummy_fnc, dummy_fnc, dummy_fnc, dummy_rcv, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc, dummy_fnc}; +static srsran_rf_plugin_t plugin_dummy = {"", NULL, &srsran_rf_dev_dummy}; + #endif -static rf_dev_t* available_devices[] = { +/** + * Collection of all currently available RF plugins + */ +static srsran_rf_plugin_t* rf_plugins[] = { #ifdef ENABLE_UHD - &dev_uhd, + &plugin_uhd, #endif #ifdef ENABLE_SOAPYSDR - &dev_soapy, + &plugin_soapy, #endif #ifdef ENABLE_BLADERF - &dev_blade, + &plugin_blade, #endif #ifdef ENABLE_ZEROMQ - &dev_zmq, + &plugin_zmq, #endif #ifdef ENABLE_SIDEKIQ - &dev_skiq, + &plugin_skiq, #endif #ifdef ENABLE_DUMMY_DEV - &dev_dummy, + &plugin_dummy, #endif + &plugin_file, NULL}; diff --git a/lib/src/phy/rf/rf_file_imp.c b/lib/src/phy/rf/rf_file_imp.c new file mode 100644 index 0000000000..5a0536839c --- /dev/null +++ b/lib/src/phy/rf/rf_file_imp.c @@ -0,0 +1,893 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "rf_file_imp.h" +#include "rf_file_imp_trx.h" +#include "rf_helper.h" +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + // Common attributes + char* devname; + srsran_rf_info_t info; + uint32_t nof_channels; + + // RF State + uint32_t srate; // radio rate configured by upper layers + uint32_t base_srate; + uint32_t decim_factor; // decimation factor between base_srate used on transport on radio's rate + double rx_gain; + uint32_t tx_freq_mhz[SRSRAN_MAX_CHANNELS]; + uint32_t rx_freq_mhz[SRSRAN_MAX_CHANNELS]; + bool tx_off; + char id[RF_PARAM_LEN]; + + // FILEs + rf_file_tx_t transmitter[SRSRAN_MAX_CHANNELS]; + rf_file_rx_t receiver[SRSRAN_MAX_CHANNELS]; + bool close_files; + + // Various sample buffers + cf_t* buffer_decimation[SRSRAN_MAX_CHANNELS]; + cf_t* buffer_tx; + + // Rx timestamp + uint64_t next_rx_ts; + + pthread_mutex_t tx_config_mutex; + pthread_mutex_t rx_config_mutex; + pthread_mutex_t decim_mutex; + pthread_mutex_t rx_gain_mutex; +} rf_file_handler_t; + +/* + * Static methods + */ + +static void update_rates(rf_file_handler_t* handler, double srate); + +void rf_file_info(char* id, const char* format, ...) +{ +#if VERBOSE + struct timeval t; + gettimeofday(&t, NULL); + va_list args; + va_start(args, format); + printf("[%s@%02ld.%06ld] ", id ? id : "file", t.tv_sec % 10, t.tv_usec); + vprintf(format, args); + va_end(args); +#else /* VERBOSE */ + // Do nothing +#endif /* VERBOSE */ +} + +void rf_file_error(char* id, const char* format, ...) +{ + struct timeval t; + gettimeofday(&t, NULL); + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); +} + +static inline int update_ts(void* h, uint64_t* ts, int nsamples, const char* dir) +{ + int ret = SRSRAN_ERROR; + + if (h && nsamples > 0) { + rf_file_handler_t* handler = (rf_file_handler_t*)h; + + (*ts) += nsamples; + + srsran_timestamp_t _ts = {}; + srsran_timestamp_init_uint64(&_ts, *ts, handler->base_srate); + rf_file_info( + handler->id, " -> next %s time after %d samples: %d + %.3f\n", dir, nsamples, _ts.full_secs, _ts.frac_secs); + + ret = SRSRAN_SUCCESS; + } + + return ret; +} + +int rf_file_handle_error(char* id, const char* text) +{ + // Not implemented + return SRSRAN_ERROR; +} + +/* + * Public methods + */ + +const char* rf_file_devname(void* h) +{ + return DEVNAME_FILE; +} + +int rf_file_start_rx_stream(void* h, bool now) +{ + return SRSRAN_SUCCESS; +} + +int rf_file_stop_rx_stream(void* h) +{ + return SRSRAN_SUCCESS; +} + +void rf_file_flush_buffer(void* h) +{ + printf("%s\n", __FUNCTION__); +} + +bool rf_file_has_rssi(void* h) +{ + return false; +} + +float rf_file_get_rssi(void* h) +{ + return 0.0; +} + +void rf_file_suppress_stdout(void* h) +{ + // do nothing +} + +void rf_file_register_error_handler(void* h, srsran_rf_error_handler_t error_handler, void* arg) +{ + // do nothing +} + +int rf_file_open(char* args, void** h) +{ + return rf_file_open_multi(args, h, 1); +} + +int rf_file_open_multi(char* args, void** h, uint32_t nof_channels) +{ + int ret = SRSRAN_ERROR; + + FILE* rx_files[SRSRAN_MAX_CHANNELS] = {NULL}; + FILE* tx_files[SRSRAN_MAX_CHANNELS] = {NULL}; + + if (h && nof_channels <= SRSRAN_MAX_CHANNELS) { + uint32_t base_srate = FILE_BASERATE_DEFAULT_HZ; + + // parse args + if (args && strlen(args)) { + // base_srate + parse_uint32(args, "base_srate", -1, &base_srate); + } else { + fprintf(stderr, "[file] Error: RF device args are required for file-based no-RF module\n"); + goto clean_exit; + } + + for (int i = 0; i < nof_channels; i++) { + // rx_file + char rx_file[RF_PARAM_LEN] = {}; + parse_string(args, "rx_file", i, rx_file); + + // tx_file + char tx_file[RF_PARAM_LEN] = {}; + parse_string(args, "tx_file", i, tx_file); + + // initialize transmitter + if (strlen(tx_file) != 0) { + tx_files[i] = fopen(tx_file, "wb"); + if (tx_files[i] == NULL) { + fprintf(stderr, "[file] Error: opening tx_file%d: %s; %s\n", i, tx_file, strerror(errno)); + goto clean_exit; + } + } + + // initialize receiver + if (strlen(rx_file) != 0) { + rx_files[i] = fopen(rx_file, "rb"); + if (rx_files[i] == NULL) { + fprintf(stderr, "[file] Error: opening rx_file%d: %s; %s\n", i, rx_file, strerror(errno)); + goto clean_exit; + } + } + } + + // defer further initialization to open_file method + ret = rf_file_open_file(h, rx_files, tx_files, nof_channels, base_srate); + if (ret != SRSRAN_SUCCESS) { + goto clean_exit; + } + + // add flag to close all files when closing device + rf_file_handler_t* handler = (rf_file_handler_t*)(*h); + handler->close_files = true; + return ret; + } + +clean_exit: + for (int i = 0; i < nof_channels; i++) { + if (rx_files[i] != NULL) { + fclose(rx_files[i]); + } + if (tx_files[i] != NULL) { + fclose(tx_files[i]); + } + } + return ret; +} + +int rf_file_open_file(void** h, FILE** rx_files, FILE** tx_files, uint32_t nof_channels, uint32_t base_srate) +{ + int ret = SRSRAN_ERROR; + + if (h) { + *h = NULL; + + rf_file_handler_t* handler = (rf_file_handler_t*)malloc(sizeof(rf_file_handler_t)); + if (!handler) { + fprintf(stderr, "malloc: %s\n", strerror(errno)); + return SRSRAN_ERROR; + } + memset(handler, 0, sizeof(rf_file_handler_t)); + *h = handler; + handler->base_srate = base_srate; + handler->info.max_rx_gain = FILE_MAX_GAIN_DB; + handler->info.min_rx_gain = FILE_MIN_GAIN_DB; + handler->info.max_tx_gain = FILE_MAX_GAIN_DB; + handler->info.min_tx_gain = FILE_MIN_GAIN_DB; + handler->nof_channels = nof_channels; + strcpy(handler->id, "file\0"); + + rf_file_opts_t rx_opts = {}; + rf_file_opts_t tx_opts = {}; + tx_opts.id = handler->id; + rx_opts.id = handler->id; + + if (pthread_mutex_init(&handler->tx_config_mutex, NULL)) { + fprintf(stderr, "Mutex init: %s\n", strerror(errno)); + } + if (pthread_mutex_init(&handler->rx_config_mutex, NULL)) { + fprintf(stderr, "Mutex init: %s\n", strerror(errno)); + } + if (pthread_mutex_init(&handler->decim_mutex, NULL)) { + fprintf(stderr, "Mutex init: %s\n", strerror(errno)); + } + if (pthread_mutex_init(&handler->rx_gain_mutex, NULL)) { + fprintf(stderr, "Mutex init: %s\n", strerror(errno)); + } + + pthread_mutex_lock(&handler->rx_gain_mutex); + handler->rx_gain = 0.0; + pthread_mutex_unlock(&handler->rx_gain_mutex); + + // id + // TODO: set some meaningful ID in handler->id + + // rx_format, tx_format + // TODO: add other formats + rx_opts.sample_format = FILERF_TYPE_FC32; + tx_opts.sample_format = FILERF_TYPE_FC32; + + update_rates(handler, 1.92e6); + + // Create channels + for (int i = 0; i < handler->nof_channels; i++) { + if (rx_files != NULL && rx_files[i] != NULL) { + rx_opts.file = rx_files[i]; + if (rf_file_rx_open(&handler->receiver[i], rx_opts) != SRSRAN_SUCCESS) { + fprintf(stderr, "[file] Error: opening receiver\n"); + goto clean_exit; + } + } else { + // no rx_files provided + fprintf(stdout, "[file] %s rx channel %d not specified. Disabling receiver.\n", handler->id, i); + } + if (tx_files != NULL && tx_files[i] != NULL) { + tx_opts.file = tx_files[i]; + if (rf_file_tx_open(&handler->transmitter[i], tx_opts) != SRSRAN_SUCCESS) { + fprintf(stderr, "[file] Error: opening transmitter\n"); + goto clean_exit; + } + } else { + // no tx_files provided + fprintf(stdout, "[file] %s tx channel %d not specified. Disabling transmitter.\n", handler->id, i); + handler->tx_off = true; + } + + if (!handler->transmitter[i].running && !handler->receiver[i].running) { + fprintf(stderr, "[file] Error: Neither tx nor rx specificed for channel %d.\n", i); + goto clean_exit; + } + } + + // Create decimation and overflow buffer + for (uint32_t i = 0; i < handler->nof_channels; i++) { + handler->buffer_decimation[i] = srsran_vec_malloc(FILE_MAX_BUFFER_SIZE); + if (!handler->buffer_decimation[i]) { + fprintf(stderr, "Error: allocating decimation buffer\n"); + goto clean_exit; + } + } + + handler->buffer_tx = srsran_vec_malloc(FILE_MAX_BUFFER_SIZE); + if (!handler->buffer_tx) { + fprintf(stderr, "Error: allocating tx buffer\n"); + goto clean_exit; + } + + ret = SRSRAN_SUCCESS; + + clean_exit: + if (ret) { + rf_file_close(handler); + } + } + return ret; +} + +int rf_file_close(void* h) +{ + rf_file_handler_t* handler = (rf_file_handler_t*)h; + + rf_file_info(handler->id, "Closing ...\n"); + + // close receiver+transmitter and release related resources (except for the file handles) + for (int i = 0; i < handler->nof_channels; i++) { + rf_file_tx_close(&handler->transmitter[i]); + rf_file_rx_close(&handler->receiver[i]); + } + + // release other resources + for (uint32_t i = 0; i < handler->nof_channels; i++) { + if (handler->buffer_decimation[i]) { + free(handler->buffer_decimation[i]); + } + } + + if (handler->buffer_tx) { + free(handler->buffer_tx); + } + + pthread_mutex_destroy(&handler->tx_config_mutex); + pthread_mutex_destroy(&handler->rx_config_mutex); + pthread_mutex_destroy(&handler->decim_mutex); + pthread_mutex_destroy(&handler->rx_gain_mutex); + + // now close the files if we opened them ourselves + if (handler->close_files) { + for (int i = 0; i < handler->nof_channels; i++) { + if (handler->receiver[i].file != NULL) { + fclose(handler->receiver[i].file); + } + if (handler->transmitter[i].file != NULL) { + fclose(handler->transmitter[i].file); + } + } + } + + // Free all + free(handler); + + return SRSRAN_SUCCESS; +} + +void update_rates(rf_file_handler_t* handler, double srate) +{ + pthread_mutex_lock(&handler->decim_mutex); + if (handler) { + // Decimation must be full integer + if (((uint64_t)handler->base_srate % (uint64_t)srate) == 0) { + handler->srate = (uint32_t)srate; + handler->decim_factor = handler->base_srate / handler->srate; + } else { + fprintf(stderr, + "Error: couldn't update sample rate. %.2f is not divisible by %.2f\n", + srate / 1e6, + handler->base_srate / 1e6); + } + printf("Current sample rate is %.2f MHz with a base rate of %.2f MHz (x%d decimation)\n", + handler->srate / 1e6, + handler->base_srate / 1e6, + handler->decim_factor); + } + pthread_mutex_unlock(&handler->decim_mutex); +} + +double rf_file_set_rx_srate(void* h, double srate) +{ + double ret = 0.0; + if (h) { + rf_file_handler_t* handler = (rf_file_handler_t*)h; + update_rates(handler, srate); + ret = handler->srate; + } + return ret; +} + +int rf_file_set_rx_gain(void* h, double gain) +{ + double ret = 0.0; + if (h) { + rf_file_handler_t* handler = (rf_file_handler_t*)h; + handler->rx_gain = gain; + ret = gain; + } + return ret; +} + +int rf_file_set_rx_gain_ch(void* h, uint32_t ch, double gain) +{ + return rf_file_set_rx_gain(h, gain); +} + +int rf_file_set_tx_gain(void* h, double gain) +{ + return 0.0; +} + +int rf_file_set_tx_gain_ch(void* h, uint32_t ch, double gain) +{ + return rf_file_set_tx_gain(h, gain); +} + +double rf_file_get_rx_gain(void* h) +{ + double ret = 0.0; + if (h) { + rf_file_handler_t* handler = (rf_file_handler_t*)h; + ret = handler->rx_gain; + } + return ret; +} + +double rf_file_get_tx_gain(void* h) +{ + return 0.0; +} + +srsran_rf_info_t* rf_file_get_info(void* h) +{ + srsran_rf_info_t* info = NULL; + if (h) { + rf_file_handler_t* handler = (rf_file_handler_t*)h; + info = &handler->info; + } + return info; +} + +double rf_file_set_rx_freq(void* h, uint32_t ch, double freq) +{ + double ret = NAN; + if (h) { + rf_file_handler_t* handler = (rf_file_handler_t*)h; + pthread_mutex_lock(&handler->rx_config_mutex); + if (ch < handler->nof_channels && isnormal(freq) && freq > 0.0) { + handler->rx_freq_mhz[ch] = (uint32_t)(freq / 1e6); + ret = freq; + } + pthread_mutex_unlock(&handler->rx_config_mutex); + } + return ret; +} + +double rf_file_set_tx_srate(void* h, double srate) +{ + double ret = 0.0; + if (h) { + rf_file_handler_t* handler = (rf_file_handler_t*)h; + update_rates(handler, srate); + ret = srate; + } + return ret; +} + +double rf_file_set_tx_freq(void* h, uint32_t ch, double freq) +{ + double ret = NAN; + if (h) { + rf_file_handler_t* handler = (rf_file_handler_t*)h; + pthread_mutex_lock(&handler->tx_config_mutex); + if (ch < handler->nof_channels && isnormal(freq) && freq > 0.0) { + handler->tx_freq_mhz[ch] = (uint32_t)(freq / 1e6); + ret = freq; + } + pthread_mutex_unlock(&handler->tx_config_mutex); + } + return ret; +} + +void rf_file_get_time(void* h, time_t* secs, double* frac_secs) +{ + if (h) { + if (secs) { + *secs = 0; + } + + if (frac_secs) { + *frac_secs = 0; + } + } +} + +int rf_file_recv_with_time(void* h, void* data, uint32_t nsamples, bool blocking, time_t* secs, double* frac_secs) +{ + return rf_file_recv_with_time_multi(h, &data, nsamples, blocking, secs, frac_secs); +} + +int rf_file_recv_with_time_multi(void* h, + void** data, + uint32_t nsamples, + bool blocking, + time_t* secs, + double* frac_secs) +{ + int ret = SRSRAN_ERROR; + + if (h) { + rf_file_handler_t* handler = (rf_file_handler_t*)h; + + // Map ports to data buffers according to the selected frequencies + pthread_mutex_lock(&handler->rx_config_mutex); + bool mapped[SRSRAN_MAX_CHANNELS] = {}; // Mapped mask, set to true when the physical channel is used + cf_t* buffers[SRSRAN_MAX_CHANNELS] = {}; // Buffer pointers, NULL if unmatched + + // For each logical channel... + for (uint32_t logical = 0; logical < handler->nof_channels; logical++) { + bool unmatched = true; + + // For each physical channel... + for (uint32_t physical = 0; physical < handler->nof_channels; physical++) { + // Consider a match if the physical channel is NOT mapped and the frequency match + if (!mapped[physical] && rf_file_rx_match_freq(&handler->receiver[physical], handler->rx_freq_mhz[logical])) { + // Not mapped and matched frequency with receiver + buffers[physical] = (cf_t*)data[logical]; + mapped[physical] = true; + unmatched = false; + break; + } + } + + // If no matching frequency found; set data to zeros + if (unmatched) { + srsran_vec_zero(data[logical], nsamples); + } + } + pthread_mutex_unlock(&handler->rx_config_mutex); + + // Protect the access to decim_factor since is a shared variable + pthread_mutex_lock(&handler->decim_mutex); + uint32_t decim_factor = handler->decim_factor; + pthread_mutex_unlock(&handler->decim_mutex); + + uint32_t nbytes = NSAMPLES2NBYTES(nsamples * decim_factor); + uint32_t nsamples_baserate = nsamples * decim_factor; + + rf_file_info(handler->id, "Rx %d samples (%d B)\n", nsamples, nbytes); + + // set timestamp for this reception + if (secs != NULL && frac_secs != NULL) { + srsran_timestamp_t ts = {}; + srsran_timestamp_init_uint64(&ts, handler->next_rx_ts, handler->base_srate); + *secs = ts.full_secs; + *frac_secs = ts.frac_secs; + } + + // return if receiver is turned off + if (!handler->receiver[0].running) { + update_ts(handler, &handler->next_rx_ts, nsamples_baserate, "rx"); + return nsamples; + } + + // Check available buffer size + if (nbytes > FILE_MAX_BUFFER_SIZE) { + fprintf(stderr, + "[file] Error: Trying to receive %d B but buffer is only %zu B at channel %d.\n", + nbytes, + FILE_MAX_BUFFER_SIZE, + 0); + goto clean_exit; + } + + // receive samples + srsran_timestamp_t ts_tx = {}, ts_rx = {}; + srsran_timestamp_init_uint64(&ts_tx, handler->transmitter[0].nsamples, handler->base_srate); + srsran_timestamp_init_uint64(&ts_rx, handler->next_rx_ts, handler->base_srate); + rf_file_info(handler->id, " - next rx time: %d + %.3f\n", ts_rx.full_secs, ts_rx.frac_secs); + rf_file_info(handler->id, " - next tx time: %d + %.3f\n", ts_tx.full_secs, ts_tx.frac_secs); + + // check for tx gap if we're also transmitting on this radio + for (int i = 0; i < handler->nof_channels; i++) { + if (handler->transmitter[i].running) { + rf_file_tx_align(&handler->transmitter[i], handler->next_rx_ts + nsamples_baserate); + } + } + + // copy from rx buffer as many samples as requested into provided buffer + bool completed = false; + int32_t count[SRSRAN_MAX_CHANNELS] = {}; + while (!completed) { + uint32_t completed_count = 0; + + // Iterate channels + for (uint32_t i = 0; i < handler->nof_channels; i++) { + cf_t* ptr = (decim_factor != 1 || buffers[i] == NULL) ? handler->buffer_decimation[i] : buffers[i]; + + // Completed condition + if (count[i] < nsamples_baserate && handler->receiver[i].running) { + // Keep receiving + int32_t n = rf_file_rx_baseband(&handler->receiver[i], &ptr[count[i]], nsamples_baserate - count[i]); + if (n > 0) { + // No error + count[i] += n; + } else { + if (n != SRSRAN_ERROR_RX_EOF) { + // Other error, exit + fprintf(stderr, "Error: receiving data.\n"); + } + ret = n; + goto clean_exit; + } + } else { + // Completed, count it + completed_count++; + } + } + + // Check if all channels are completed + completed = (completed_count == handler->nof_channels); + } + rf_file_info(handler->id, " - read %d samples.\n", NBYTES2NSAMPLES(nbytes)); + + // decimate if needed + if (decim_factor != 1) { + for (uint32_t c = 0; c < handler->nof_channels; c++) { + // skip if buffer is not available + if (buffers[c]) { + cf_t* dst = buffers[c]; + cf_t* ptr = handler->buffer_decimation[c]; + + for (uint32_t i = 0, n = 0; i < nsamples; i++) { + // Averaging decimation + cf_t avg = 0.0f; + for (int j = 0; j < decim_factor; j++, n++) { + avg += ptr[n]; + } + dst[i] = avg; // divide by decim_factor later via scale + } + + rf_file_info(handler->id, + " - re-adjust bytes due to %dx decimation %d --> %d samples)\n", + decim_factor, + nsamples_baserate, + nsamples); + } + } + } + + // Set gain + pthread_mutex_lock(&handler->rx_gain_mutex); + float scale = srsran_convert_dB_to_amplitude(handler->rx_gain); + pthread_mutex_unlock(&handler->rx_gain_mutex); + // scale shall also incorporate decim_factor + scale = scale / decim_factor; + for (uint32_t c = 0; c < handler->nof_channels; c++) { + if (buffers[c]) { + srsran_vec_sc_prod_cfc(buffers[c], scale, buffers[c], nsamples); + } + } + + // update rx time + update_ts(handler, &handler->next_rx_ts, nsamples_baserate, "rx"); + } + + ret = nsamples; + +clean_exit: + + return ret; +} + +int rf_file_send_timed(void* h, + void* data, + int nsamples, + time_t secs, + double frac_secs, + bool has_time_spec, + bool blocking, + bool is_start_of_burst, + bool is_end_of_burst) +{ + void* _data[4] = {data, NULL, NULL, NULL}; + + return rf_file_send_timed_multi( + h, _data, nsamples, secs, frac_secs, has_time_spec, blocking, is_start_of_burst, is_end_of_burst); +} + +int rf_file_send_timed_multi(void* h, + void* data[4], + int nsamples, + time_t secs, + double frac_secs, + bool has_time_spec, + bool blocking, + bool is_start_of_burst, + bool is_end_of_burst) +{ + int ret = SRSRAN_ERROR; + + if (h && data && nsamples > 0) { + rf_file_handler_t* handler = (rf_file_handler_t*)h; + + // Map ports to data buffers according to the selected frequencies + pthread_mutex_lock(&handler->tx_config_mutex); + bool mapped[SRSRAN_MAX_CHANNELS] = {}; // Mapped mask, set to true when the physical channel is used + cf_t* buffers[SRSRAN_MAX_CHANNELS] = {}; // Buffer pointers, NULL if unmatched or zero transmission + + // For each logical channel... + for (uint32_t logical = 0; logical < handler->nof_channels; logical++) { + // For each physical channel... + for (uint32_t physical = 0; physical < handler->nof_channels; physical++) { + // Consider a match if the physical channel is NOT mapped and the frequency match + if (!mapped[physical] && + rf_file_tx_match_freq(&handler->transmitter[physical], handler->tx_freq_mhz[logical])) { + // Not mapped and matched frequency with receiver + buffers[physical] = (cf_t*)data[logical]; + mapped[physical] = true; + break; + } + } + } + pthread_mutex_unlock(&handler->tx_config_mutex); + + // Protect the access to decim_factor since is a shared variable + pthread_mutex_lock(&handler->decim_mutex); + uint32_t decim_factor = handler->decim_factor; + pthread_mutex_unlock(&handler->decim_mutex); + + uint32_t nbytes = NSAMPLES2NBYTES(nsamples); + uint32_t nsamples_baseband = nsamples * decim_factor; + uint32_t nbytes_baseband = NSAMPLES2NBYTES(nsamples_baseband); + if (nbytes_baseband > FILE_MAX_BUFFER_SIZE) { + fprintf(stderr, "Error: trying to transmit too many samples (%d > %zu).\n", nbytes, FILE_MAX_BUFFER_SIZE); + goto clean_exit; + } + + rf_file_info(handler->id, "Tx %d samples (%d B)\n", nsamples, nbytes); + + // return if transmitter is switched off + if (handler->tx_off) { + return SRSRAN_SUCCESS; + } + + // check if this is a tx in the future + if (has_time_spec) { + rf_file_info(handler->id, " - tx time: %d + %.3f\n", secs, frac_secs); + + srsran_timestamp_t ts = {}; + srsran_timestamp_init(&ts, secs, frac_secs); + uint64_t tx_ts = srsran_timestamp_uint64(&ts, handler->base_srate); + int num_tx_gap_samples = 0; + + for (int i = 0; i < handler->nof_channels; i++) { + if (handler->transmitter[i].running) { + num_tx_gap_samples = rf_file_tx_align(&handler->transmitter[i], tx_ts); + } + } + + if (num_tx_gap_samples < 0) { + fprintf(stderr, + "[file] Error: tx time is %.3f ms in the past (%" PRIu64 " < %" PRIu64 ")\n", + -1000.0 * num_tx_gap_samples / handler->base_srate, + tx_ts, + handler->transmitter[0].nsamples); + goto clean_exit; + } + } + + // Send base-band samples + for (int i = 0; i < handler->nof_channels; i++) { + if (buffers[i] != NULL) { + // Select buffer pointer depending on interpolation + cf_t* buf = (decim_factor != 1) ? handler->buffer_tx : buffers[i]; + + // Interpolate if required + if (decim_factor != 1) { + rf_file_info(handler->id, + " - re-adjust bytes due to %dx interpolation %d --> %d samples)\n", + decim_factor, + nsamples, + nsamples_baseband); + + int n = 0; + cf_t* src = buffers[i]; + for (int k = 0; k < nsamples; k++) { + // perform zero order hold + for (int j = 0; j < decim_factor; j++, n++) { + buf[n] = src[k]; + } + } + + if (nsamples_baseband != n) { + fprintf(stderr, + "Number of tx samples (%d) does not match with number of interpolated samples (%d)\n", + nsamples_baseband, + n); + goto clean_exit; + } + } + + int n = rf_file_tx_baseband(&handler->transmitter[i], buf, nsamples_baseband); + if (n == SRSRAN_ERROR) { + goto clean_exit; + } + } else { + int n = rf_file_tx_zeros(&handler->transmitter[i], nsamples_baseband); + if (n == SRSRAN_ERROR) { + goto clean_exit; + } + } + } + } + + ret = SRSRAN_SUCCESS; + +clean_exit: + + return ret; +} + +rf_dev_t srsran_rf_dev_file = {"file", + rf_file_devname, + rf_file_start_rx_stream, + rf_file_stop_rx_stream, + rf_file_flush_buffer, + rf_file_has_rssi, + rf_file_get_rssi, + rf_file_suppress_stdout, + rf_file_register_error_handler, + rf_file_open, + .srsran_rf_open_multi = rf_file_open_multi, + rf_file_close, + rf_file_set_rx_srate, + rf_file_set_rx_gain, + rf_file_set_rx_gain_ch, + rf_file_set_tx_gain, + rf_file_set_tx_gain_ch, + rf_file_get_rx_gain, + rf_file_get_tx_gain, + rf_file_get_info, + rf_file_set_rx_freq, + rf_file_set_tx_srate, + rf_file_set_tx_freq, + rf_file_get_time, + NULL, + rf_file_recv_with_time, + rf_file_recv_with_time_multi, + rf_file_send_timed, + .srsran_rf_send_timed_multi = rf_file_send_timed_multi}; diff --git a/lib/src/phy/rf/rf_file_imp.h b/lib/src/phy/rf/rf_file_imp.h new file mode 100644 index 0000000000..8b683c4bcd --- /dev/null +++ b/lib/src/phy/rf/rf_file_imp.h @@ -0,0 +1,144 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_RF_FILE_IMP_H +#define SRSRAN_RF_FILE_IMP_H + +#include + +#include "srsran/config.h" +#include "srsran/phy/common/phy_common.h" +#include "srsran/phy/rf/rf.h" + +#define DEVNAME_FILE "file" +#define PARAM_LEN (128) +#define PARAM_LEN_SHORT (PARAM_LEN / 2) + +extern rf_dev_t srsran_rf_dev_file; + +SRSRAN_API const char* rf_file_devname(void* h); + +SRSRAN_API int rf_file_start_rx_stream(void* h, bool now); + +// SRSRAN_API int rf_file_start_rx_stream_nsamples(void* h, uint32_t nsamples); + +SRSRAN_API int rf_file_stop_rx_stream(void* h); + +SRSRAN_API void rf_file_flush_buffer(void* h); + +SRSRAN_API bool rf_file_has_rssi(void* h); + +SRSRAN_API float rf_file_get_rssi(void* h); + +SRSRAN_API void rf_file_suppress_stdout(void* h); + +SRSRAN_API void rf_file_register_error_handler(void* h, srsran_rf_error_handler_t error_handler, void* arg); + +/** + * @brief This function is not supported for file-based RF abstraction + * + * Use @c rf_file_open_file() to open this device + * + * @param args not used + * @param h not used + * @return SRSRAN_ERROR_INVALID_COMMAND + */ +SRSRAN_API int rf_file_open(char* args, void** h); + +/** + * @brief This function is not supported for file-based RF abstraction + * + * Use @c rf_file_open_file() to open this device + * + * @param args not used + * @param h not used + * @param nof_channels not used + * @return SRSRAN_ERROR_INVALID_COMMAND + */ +SRSRAN_API int rf_file_open_multi(char* args, void** h, uint32_t nof_channels); + +SRSRAN_API int rf_file_close(void* h); + +SRSRAN_API double rf_file_set_rx_srate(void* h, double srate); + +SRSRAN_API int rf_file_set_rx_gain(void* h, double gain); + +SRSRAN_API int rf_file_set_rx_gain_ch(void* h, uint32_t ch, double gain); + +SRSRAN_API int rf_file_set_tx_gain(void* h, double gain); + +SRSRAN_API int rf_file_set_tx_gain_ch(void* h, uint32_t ch, double gain); + +SRSRAN_API double rf_file_get_rx_gain(void* h); + +SRSRAN_API double rf_file_get_tx_gain(void* h); + +SRSRAN_API srsran_rf_info_t* rf_file_get_info(void* h); + +SRSRAN_API double rf_file_set_rx_freq(void* h, uint32_t ch, double freq); + +SRSRAN_API double rf_file_set_tx_srate(void* h, double srate); + +SRSRAN_API double rf_file_set_tx_freq(void* h, uint32_t ch, double freq); + +SRSRAN_API void rf_file_get_time(void* h, time_t* secs, double* frac_secs); + +// srsran_rf_sync_pps + +SRSRAN_API int +rf_file_recv_with_time(void* h, void* data, uint32_t nsamples, bool blocking, time_t* secs, double* frac_secs); + +SRSRAN_API int +rf_file_recv_with_time_multi(void* h, void** data, uint32_t nsamples, bool blocking, time_t* secs, double* frac_secs); + +SRSRAN_API int rf_file_send_timed(void* h, + void* data, + int nsamples, + time_t secs, + double frac_secs, + bool has_time_spec, + bool blocking, + bool is_start_of_burst, + bool is_end_of_burst); + +SRSRAN_API int rf_file_send_timed_multi(void* h, + void* data[4], + int nsamples, + time_t secs, + double frac_secs, + bool has_time_spec, + bool blocking, + bool is_start_of_burst, + bool is_end_of_burst); + +/** + * @brief Dedicated function to open a file-based RF abstraction + * @param[out] h Resulting object handle + * @param[in] rx_files List of pre-opened FILE* for each RX channel; NULL to disable + * @param[in] tx_files List of pre-opened FILE* for each TX channel; NULL to disable + * @param[in] nof_channels Number of channels per direction + * @param[in] base_srate Sample rate of RX and TX files + * @return SRSRAN_SUCCESS on success, otherwise error code + */ +SRSRAN_API int +rf_file_open_file(void** h, FILE** rx_files, FILE** tx_files, uint32_t nof_channels, uint32_t base_srate); + +#endif // SRSRAN_RF_FILE_IMP_H diff --git a/lib/src/phy/rf/rf_file_imp_rx.c b/lib/src/phy/rf/rf_file_imp_rx.c new file mode 100644 index 0000000000..f239213182 --- /dev/null +++ b/lib/src/phy/rf/rf_file_imp_rx.c @@ -0,0 +1,107 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "rf_file_imp_trx.h" +#include +#include +#include + +int rf_file_rx_open(rf_file_rx_t* q, rf_file_opts_t opts) +{ + int ret = SRSRAN_ERROR; + + if (q) { + // Zero object + memset(q, 0, sizeof(rf_file_rx_t)); + + // Copy id + strncpy(q->id, opts.id, FILE_ID_STRLEN - 1); + q->id[FILE_ID_STRLEN - 1] = '\0'; + + // Assign file + q->file = opts.file; + + // Configure formats + q->sample_format = opts.sample_format; + q->frequency_mhz = opts.frequency_mhz; + + q->temp_buffer = srsran_vec_malloc(FILE_MAX_BUFFER_SIZE); + if (!q->temp_buffer) { + fprintf(stderr, "Error: allocating rx buffer\n"); + goto clean_exit; + } + + q->temp_buffer_convert = srsran_vec_malloc(FILE_MAX_BUFFER_SIZE); + if (!q->temp_buffer_convert) { + fprintf(stderr, "Error: allocating rx buffer\n"); + goto clean_exit; + } + + if (pthread_mutex_init(&q->mutex, NULL)) { + fprintf(stderr, "Error: creating mutex\n"); + goto clean_exit; + } + + q->running = true; + + ret = SRSRAN_SUCCESS; + } + +clean_exit: + return ret; +} + +int rf_file_rx_baseband(rf_file_rx_t* q, cf_t* buffer, uint32_t nsamples) +{ + uint32_t sample_sz = sizeof(cf_t); + + int ret = fread(buffer, sample_sz, nsamples, q->file); + if (ret > 0) { + return ret; + } else { + return SRSRAN_ERROR_RX_EOF; + } +} + +bool rf_file_rx_match_freq(rf_file_rx_t* q, uint32_t freq_hz) +{ + bool ret = false; + if (q) { + ret = (q->frequency_mhz == 0 || q->frequency_mhz == freq_hz); + } + return ret; +} + +void rf_file_rx_close(rf_file_rx_t* q) +{ + rf_file_info(q->id, "Closing ...\n"); + q->running = false; + + if (q->temp_buffer) { + free(q->temp_buffer); + } + + if (q->temp_buffer_convert) { + free(q->temp_buffer_convert); + } + + // not touching q->file as we don't know if we need to close it ourselves +} diff --git a/lib/src/phy/rf/rf_file_imp_trx.h b/lib/src/phy/rf/rf_file_imp_trx.h new file mode 100644 index 0000000000..c73ef21743 --- /dev/null +++ b/lib/src/phy/rf/rf_file_imp_trx.h @@ -0,0 +1,115 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_RF_FILE_IMP_TRX_H +#define SRSRAN_RF_FILE_IMP_TRX_H + +#include "srsran/config.h" +#include +#include +#include +#include +#include + +/* Definitions */ +#define VERBOSE (0) +#define NSAMPLES2NBYTES(X) (((uint32_t)(X)) * sizeof(cf_t)) +#define NBYTES2NSAMPLES(X) ((X) / sizeof(cf_t)) +#define FILE_MAX_BUFFER_SIZE (NSAMPLES2NBYTES(3072000)) // 10 subframes at 20 MHz +#define FILE_TIMEOUT_MS (1000) +#define FILE_BASERATE_DEFAULT_HZ (23040000) +#define FILE_ID_STRLEN 16 +#define FILE_MAX_GAIN_DB (30.0f) +#define FILE_MIN_GAIN_DB (0.0f) + +typedef enum { FILERF_TYPE_FC32 = 0, FILERF_TYPE_SC16 } rf_file_format_t; + +typedef struct { + char id[FILE_ID_STRLEN]; + rf_file_format_t sample_format; + FILE* file; + uint64_t nsamples; + bool running; + pthread_mutex_t mutex; + cf_t* zeros; + void* temp_buffer_convert; + uint32_t frequency_mhz; + int32_t sample_offset; +} rf_file_tx_t; + +typedef struct { + char id[FILE_ID_STRLEN]; + rf_file_format_t sample_format; + FILE* file; + uint64_t nsamples; + bool running; + pthread_t thread; + pthread_mutex_t mutex; + cf_t* temp_buffer; + void* temp_buffer_convert; + uint32_t frequency_mhz; +} rf_file_rx_t; + +typedef struct { + const char* id; + rf_file_format_t sample_format; + FILE* file; + uint32_t frequency_mhz; +} rf_file_opts_t; + +/* + * Common functions + */ +SRSRAN_API void rf_file_info(char* id, const char* format, ...); + +SRSRAN_API void rf_file_error(char* id, const char* format, ...); + +SRSRAN_API int rf_file_handle_error(char* id, const char* text); + +/* + * Transmitter functions + */ +SRSRAN_API int rf_file_tx_open(rf_file_tx_t* q, rf_file_opts_t opts); + +SRSRAN_API int rf_file_tx_align(rf_file_tx_t* q, uint64_t ts); + +SRSRAN_API int rf_file_tx_baseband(rf_file_tx_t* q, cf_t* buffer, uint32_t nsamples); + +SRSRAN_API int rf_file_tx_get_nsamples(rf_file_tx_t* q); + +SRSRAN_API int rf_file_tx_zeros(rf_file_tx_t* q, uint32_t nsamples); + +SRSRAN_API bool rf_file_tx_match_freq(rf_file_tx_t* q, uint32_t freq_hz); + +SRSRAN_API void rf_file_tx_close(rf_file_tx_t* q); + +/* + * Receiver functions + */ +SRSRAN_API int rf_file_rx_open(rf_file_rx_t* q, rf_file_opts_t opts); + +SRSRAN_API int rf_file_rx_baseband(rf_file_rx_t* q, cf_t* buffer, uint32_t nsamples); + +SRSRAN_API bool rf_file_rx_match_freq(rf_file_rx_t* q, uint32_t freq_hz); + +SRSRAN_API void rf_file_rx_close(rf_file_rx_t* q); + +#endif // SRSRAN_RF_FILE_IMP_TRX_H diff --git a/lib/src/phy/rf/rf_file_imp_tx.c b/lib/src/phy/rf/rf_file_imp_tx.c new file mode 100644 index 0000000000..6af247f7ab --- /dev/null +++ b/lib/src/phy/rf/rf_file_imp_tx.c @@ -0,0 +1,198 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "rf_file_imp_trx.h" +#include +#include +#include +#include +#include +#include + +int rf_file_tx_open(rf_file_tx_t* q, rf_file_opts_t opts) +{ + int ret = SRSRAN_ERROR; + + if (q) { + // Zero object + memset(q, 0, sizeof(rf_file_tx_t)); + + // Copy id + strncpy(q->id, opts.id, FILE_ID_STRLEN - 1); + q->id[FILE_ID_STRLEN - 1] = '\0'; + + // Assign file + q->file = opts.file; + + // Configure formats + q->sample_format = opts.sample_format; + q->frequency_mhz = opts.frequency_mhz; + + q->temp_buffer_convert = srsran_vec_malloc(FILE_MAX_BUFFER_SIZE); + if (!q->temp_buffer_convert) { + fprintf(stderr, "Error: allocating tx buffer\n"); + goto clean_exit; + } + + if (pthread_mutex_init(&q->mutex, NULL)) { + fprintf(stderr, "Error: creating mutex\n"); + goto clean_exit; + } + + q->zeros = srsran_vec_malloc(FILE_MAX_BUFFER_SIZE); + if (!q->zeros) { + fprintf(stderr, "Error: allocating zeros\n"); + goto clean_exit; + } + memset(q->zeros, 0, FILE_MAX_BUFFER_SIZE); + + q->running = true; + + ret = SRSRAN_SUCCESS; + } + +clean_exit: + return ret; +} + +static int _rf_file_tx_baseband(rf_file_tx_t* q, cf_t* buffer, uint32_t nsamples) +{ + int n = SRSRAN_ERROR; + + // convert samples if necessary + void* buf = (buffer) ? buffer : q->zeros; + uint32_t sample_sz = sizeof(cf_t); + + if (q->sample_format == FILERF_TYPE_SC16) { + buf = q->temp_buffer_convert; + sample_sz = 2 * sizeof(short); + srsran_vec_convert_fi((float*)buffer, INT16_MAX, (short*)q->temp_buffer_convert, 2 * nsamples); + } + + size_t ret = fwrite(buf, (size_t)sample_sz, (size_t)nsamples, q->file); + if (ret < (size_t)nsamples) { + rf_file_error(q->id, + "[file] Error: transmitter expected %d bytes and sent %zd. %s.\n", + NSAMPLES2NBYTES(nsamples), + ret, + strerror(errno)); + n = SRSRAN_ERROR; + goto clean_exit; + } + + // Increment sample counter + q->nsamples += nsamples; + n = nsamples; + +clean_exit: + return n; +} + +int rf_file_tx_align(rf_file_tx_t* q, uint64_t ts) +{ + pthread_mutex_lock(&q->mutex); + + int64_t nsamples = (int64_t)ts - (int64_t)q->nsamples; + + if (nsamples > 0) { + rf_file_info(q->id, " - Detected Tx gap of %d samples.\n", nsamples); + _rf_file_tx_baseband(q, q->zeros, (uint32_t)nsamples); + } + + pthread_mutex_unlock(&q->mutex); + + return (int)nsamples; +} + +int rf_file_tx_baseband(rf_file_tx_t* q, cf_t* buffer, uint32_t nsamples) +{ + int n; + + pthread_mutex_lock(&q->mutex); + + if (q->sample_offset > 0) { + _rf_file_tx_baseband(q, q->zeros, (uint32_t)q->sample_offset); + q->sample_offset = 0; + } else if (q->sample_offset < 0) { + n = SRSRAN_MIN(-q->sample_offset, nsamples); + buffer += n; + nsamples -= n; + q->sample_offset += n; + if (nsamples == 0) { + return n; + } + } + + n = _rf_file_tx_baseband(q, buffer, nsamples); + + pthread_mutex_unlock(&q->mutex); + + return n; +} + +int rf_file_tx_get_nsamples(rf_file_tx_t* q) +{ + pthread_mutex_lock(&q->mutex); + int ret = q->nsamples; + pthread_mutex_unlock(&q->mutex); + return ret; +} + +int rf_file_tx_zeros(rf_file_tx_t* q, uint32_t nsamples) +{ + pthread_mutex_lock(&q->mutex); + + rf_file_info(q->id, " - Tx %d Zeros.\n", nsamples); + _rf_file_tx_baseband(q, q->zeros, (uint32_t)nsamples); + + pthread_mutex_unlock(&q->mutex); + + return (int)nsamples; +} + +bool rf_file_tx_match_freq(rf_file_tx_t* q, uint32_t freq_hz) +{ + bool ret = false; + if (q) { + ret = (q->frequency_mhz == 0 || q->frequency_mhz == freq_hz); + } + return ret; +} + +void rf_file_tx_close(rf_file_tx_t* q) +{ + rf_file_info(q->id, "Closing ...\n"); + pthread_mutex_lock(&q->mutex); + q->running = false; + pthread_mutex_unlock(&q->mutex); + + pthread_mutex_destroy(&q->mutex); + + if (q->zeros) { + free(q->zeros); + } + + if (q->temp_buffer_convert) { + free(q->temp_buffer_convert); + } + + // not touching q->file as we don't know if we need to close it ourselves +} diff --git a/lib/src/phy/rf/rf_file_test.c b/lib/src/phy/rf/rf_file_test.c new file mode 100644 index 0000000000..903e3c3652 --- /dev/null +++ b/lib/src/phy/rf/rf_file_test.c @@ -0,0 +1,336 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "rf_file_imp.h" +#include "srsran/common/tsan_options.h" +#include "srsran/phy/common/timestamp.h" +#include "srsran/phy/utils/debug.h" +#include +#include +#include +#include +#include + +#define PRINT_SAMPLES 0 +#define COMPARE_BITS 0 +#define COMPARE_EPSILON (1e-6f) +#define NOF_RX_ANT 4 +#define NUM_SF (500) +#define SF_LEN (1920) +#define RF_BUFFER_SIZE (SF_LEN * NUM_SF) +#define TX_OFFSET_MS (4) + +static cf_t ue_rx_buffer[NOF_RX_ANT][RF_BUFFER_SIZE]; +static cf_t enb_tx_buffer[NOF_RX_ANT][RF_BUFFER_SIZE]; +static cf_t enb_rx_buffer[NOF_RX_ANT][RF_BUFFER_SIZE]; + +static srsran_rf_t ue_radio, enb_radio; +pthread_t rx_thread; + +void* ue_rx_thread_function(void* args) +{ + char rf_args[RF_PARAM_LEN]; + strncpy(rf_args, (char*)args, RF_PARAM_LEN - 1); + rf_args[RF_PARAM_LEN - 1] = 0; + + // sleep(1); + + printf("opening rx device with args=%s\n", rf_args); + if (srsran_rf_open_devname(&ue_radio, "file", rf_args, NOF_RX_ANT)) { + fprintf(stderr, "Error opening rf\n"); + exit(-1); + } + + // receive 5 subframes at once (i.e. mimic initial rx that receives one slot) + uint32_t num_slots = NUM_SF / 5; + uint32_t num_samps_per_slot = SF_LEN * 5; + uint32_t num_rxed_samps = 0; + for (uint32_t i = 0; i < num_slots; ++i) { + void* data_ptr[SRSRAN_MAX_PORTS] = {NULL}; + for (uint32_t c = 0; c < NOF_RX_ANT; c++) { + data_ptr[c] = &ue_rx_buffer[c][i * num_samps_per_slot]; + } + num_rxed_samps += srsran_rf_recv_with_time_multi(&ue_radio, data_ptr, num_samps_per_slot, true, NULL, NULL); + } + + printf("received %d samples.\n", num_rxed_samps); + + printf("closing ue rx device\n"); + srsran_rf_close(&ue_radio); + + return NULL; +} + +void enb_tx_function(const char* tx_args, bool timed_tx) +{ + char rf_args[RF_PARAM_LEN]; + strncpy(rf_args, tx_args, RF_PARAM_LEN - 1); + rf_args[RF_PARAM_LEN - 1] = 0; + + printf("opening tx device with args=%s\n", rf_args); + if (srsran_rf_open_devname(&enb_radio, "file", rf_args, NOF_RX_ANT)) { + fprintf(stderr, "Error opening rf\n"); + exit(-1); + } + + // generate random tx data + for (int c = 0; c < NOF_RX_ANT; c++) { + for (int i = 0; i < RF_BUFFER_SIZE; i++) { + enb_tx_buffer[c][i] = ((float)rand() / (float)RAND_MAX) + _Complex_I * ((float)rand() / (float)RAND_MAX); + } + } + + // send data subframe per subframe + uint32_t num_txed_samples = 0; + + // initial transmission without ts + void* data_ptr[SRSRAN_MAX_PORTS] = {NULL}; + for (int c = 0; c < NOF_RX_ANT; c++) { + data_ptr[c] = &enb_tx_buffer[c][num_txed_samples]; + } + int ret = srsran_rf_send_multi(&enb_radio, (void**)data_ptr, SF_LEN, true, true, false); + num_txed_samples += SF_LEN; + + // from here on, all transmissions are timed relative to the last rx time + srsran_timestamp_t rx_time, tx_time; + + for (uint32_t i = 0; i < NUM_SF - ((timed_tx) ? TX_OFFSET_MS : 1); ++i) { + // first recv samples + for (int c = 0; c < NOF_RX_ANT; c++) { + data_ptr[c] = enb_rx_buffer[c]; + } + srsran_rf_recv_with_time_multi(&enb_radio, data_ptr, SF_LEN, true, &rx_time.full_secs, &rx_time.frac_secs); + + // prepare data buffer + for (int c = 0; c < NOF_RX_ANT; c++) { + data_ptr[c] = &enb_tx_buffer[c][num_txed_samples]; + } + + if (timed_tx) { + // timed tx relative to receive time (this will cause a cap in the rx'ed samples at the UE resulting in 3 zero + // subframes) + srsran_timestamp_copy(&tx_time, &rx_time); + srsran_timestamp_add(&tx_time, 0, TX_OFFSET_MS * 1e-3); + ret = srsran_rf_send_timed_multi( + &enb_radio, (void**)data_ptr, SF_LEN, tx_time.full_secs, tx_time.frac_secs, true, true, false); + } else { + // normal tx + ret = srsran_rf_send_multi(&enb_radio, (void**)data_ptr, SF_LEN, true, true, false); + } + if (ret != SRSRAN_SUCCESS) { + fprintf(stderr, "Error sending data\n"); + exit(-1); + } + + num_txed_samples += SF_LEN; + } + + printf("transmitted %d samples in %d subframes\n", num_txed_samples, NUM_SF); + + printf("closing tx device\n"); + srsran_rf_close(&enb_radio); +} + +int run_test(const char* rx_args, const char* tx_args, bool timed_tx) +{ + int ret = SRSRAN_ERROR; + + // make sure we can receive in slots + if (NUM_SF % 5 != 0) { + fprintf(stderr, "number of subframes must be multiple of 5\n"); + goto exit; + } + + // write to file(s) + enb_tx_function(tx_args, timed_tx); + + // read from file(s) + ue_rx_thread_function((void*)rx_args); + + // channel-wise comparison + for (int c = 0; c < NOF_RX_ANT; c++) { + // subframe-wise compare tx'ed and rx'ed data (stop 3 subframes earlier for timed tx) + for (uint32_t i = 0; i < NUM_SF - (timed_tx ? 3 : 0); ++i) { + uint32_t sf_offet = 0; + if (timed_tx && i >= 1) { + // for timed transmission, the enb inserts 3 zero subframes after the first untimed tx + sf_offet = (TX_OFFSET_MS - 1) * SF_LEN; + } + +#if PRINT_SAMPLES + // print first 10 samples for each SF + printf("enb_tx_buffer sf%d:\n", i); + srsran_vec_fprint_c(stdout, &enb_tx_buffer[c][i * SF_LEN], 10); + printf("ue_rx_buffer sf%d:\n", i); + srsran_vec_fprint_c(stdout, &ue_rx_buffer[c][sf_offet + i * SF_LEN], 10); +#endif + +#if COMPARE_BITS + int d = memcmp(&ue_rx_buffer[sf_offet + i * SF_LEN], &enb_tx_buffer[i * SF_LEN], SF_LEN); + if (d) { + d = d > 0 ? d : -d; + fprintf(stderr, "data mismatch in subframe %d, sample %d\n", i, d); + printf("enb_tx_buffer sf%d:\n", i); + srsran_vec_fprint_c(stdout, &enb_tx_buffer[i * SF_LEN + d], 10); + printf("ue_rx_buffer sf%d:\n", i); + srsran_vec_fprint_c(stdout, &ue_rx_buffer[sf_offet + i * SF_LEN + d], 10); + goto exit; + } +#else + srsran_vec_sub_ccc(&ue_rx_buffer[c][sf_offet + i * SF_LEN], + &enb_tx_buffer[c][i * SF_LEN], + &ue_rx_buffer[c][sf_offet + i * SF_LEN], + SF_LEN); + uint32_t max_ix = srsran_vec_max_abs_ci(&ue_rx_buffer[c][sf_offet + i * SF_LEN], SF_LEN); + if (cabsf(ue_rx_buffer[c][sf_offet + i * SF_LEN + max_ix]) > COMPARE_EPSILON) { + fprintf(stderr, "data mismatch in subframe %d\n", i); + goto exit; + } +#endif + } + } + + ret = SRSRAN_SUCCESS; + +exit: + return ret; +} + +int param_test(const char* args_param, const int num_channels) +{ + char rf_args[RF_PARAM_LEN] = {}; + strncpy(rf_args, (char*)args_param, RF_PARAM_LEN - 1); + rf_args[RF_PARAM_LEN - 1] = 0; + + printf("opening tx device with args=%s\n", rf_args); + if (srsran_rf_open_devname(&enb_radio, "file", rf_args, num_channels)) { + fprintf(stderr, "Error opening rf\n"); + return SRSRAN_ERROR; + } + + srsran_rf_close(&enb_radio); + + return SRSRAN_SUCCESS; +} + +void create_file(const char* filename) +{ + FILE* f = fopen(filename, "w"); + fclose(f); +} + +void remove_file(const char* filename) +{ + remove(filename); +} + +int main() +{ + // create files for testing + create_file("rx_file0"); + create_file("rx_file1"); + create_file("rx_file2"); + create_file("rx_file3"); + + // two RX files + if (param_test("rx_file=rx_file0," + "rx_file1=rx_file1", + 2)) { + fprintf(stderr, "Param test failed!\n"); + return SRSRAN_ERROR; + } + + // multiple RX files, no channel index provided + if (param_test("rx_file=rx_file0," + "rx_file=rx_file1," + "rx_file=rx_file2," + "rx_file=rx_file3," + "base_srate=1.92e6", + 4)) { + fprintf(stderr, "Param test failed!\n"); + return SRSRAN_ERROR; + } + + // one RX, one TX and all generic options + if (param_test("rx_file0=rx_file0," + "tx_file0=tx_file0," + "base_srate=1.92e6", + 1)) { + fprintf(stderr, "Param test failed!\n"); + return SRSRAN_ERROR; + } + + // two RX, two TX + if (param_test("rx_file0=rx_file0," + "rx_file1=rx_file1," + "tx_file0=tx_file0," + "tx_file1=tx_file1", + 2)) { + fprintf(stderr, "Param test failed!\n"); + return SRSRAN_ERROR; + } + +#if NOF_RX_ANT == 1 + // single tx, single rx with continuous transmissions (no decimation, no timed tx) + if (run_test("rx_file=tx_file0,base_srate=1.92e6", "tx_file=tx_file0,base_srate=1.92e6", false) != SRSRAN_SUCCESS) { + fprintf(stderr, "Single tx, single rx test failed (no decimation, no timed tx)!\n"); + return -1; + } +#endif + + // up to 4 trx radios with continous tx (no decimation, no timed tx) + if (run_test("rx_file=tx_file0,rx_file=tx_file1,rx_file=tx_file2,rx_file=tx_file3,base_srate=1.92e6", + "tx_file=tx_file0,tx_file=tx_file1,tx_file=tx_file2,tx_file=tx_file3,base_srate=1.92e6", + false) != SRSRAN_SUCCESS) { + fprintf(stderr, "Multi TRx radio test failed (no decimation, no timed tx)!\n"); + return -1; + } + + // up to 4 trx radios with continous tx (with decimation, no timed tx) + if (run_test("rx_file=tx_file0,rx_file=tx_file1,rx_file=tx_file2,rx_file=tx_file3", + "tx_file=tx_file0,tx_file=tx_file1,tx_file=tx_file2,tx_file=tx_file3", + false) != SRSRAN_SUCCESS) { + fprintf(stderr, "Multi TRx radio test failed (with decimation, no timed tx)!\n"); + return -1; + } + + // up to 4 trx radios with continous tx (with decimation, timed tx) + if (run_test("rx_file=tx_file0,rx_file=tx_file1,rx_file=tx_file2,rx_file=tx_file3", + "tx_file=tx_file0,tx_file=tx_file1,tx_file=tx_file2,tx_file=tx_file3", + true) != SRSRAN_SUCCESS) { + fprintf(stderr, "Two TRx radio test failed (with decimation, timed tx)!\n"); + return -1; + } + + // clean workspace + remove_file("rx_file0"); + remove_file("rx_file1"); + remove_file("rx_file2"); + remove_file("rx_file3"); + remove_file("tx_file0"); + remove_file("tx_file1"); + remove_file("tx_file2"); + remove_file("tx_file3"); + + fprintf(stdout, "Test passed!\n"); + + return SRSRAN_SUCCESS; +} diff --git a/lib/src/phy/rf/rf_helper.h b/lib/src/phy/rf/rf_helper.h index 1926f4b08f..cbed387a93 100644 --- a/lib/src/phy/rf/rf_helper.h +++ b/lib/src/phy/rf/rf_helper.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/rf/rf_imp.c b/lib/src/phy/rf/rf_imp.c index 4cbc6b4ca4..e4a751dc89 100644 --- a/lib/src/phy/rf/rf_imp.c +++ b/lib/src/phy/rf/rf_imp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,17 +19,19 @@ * */ -#include - #include "rf_dev.h" #include "srsran/phy/rf/rf.h" #include "srsran/phy/utils/debug.h" +#include +#include int rf_get_available_devices(char** devnames, int max_strlen) { int i = 0; - while (available_devices[i]->name) { - strncpy(devnames[i], available_devices[i]->name, max_strlen); + while (rf_plugins[i] != NULL) { + if (rf_plugins[i]->rf_api != NULL) { + strncpy(devnames[i], rf_plugins[i]->rf_api->name, max_strlen); + } i++; } return i; @@ -104,20 +106,22 @@ int srsran_rf_open_devname(srsran_rf_t* rf, const char* devname, char* args, uin rf->thread_gain_run = false; bool no_rf_devs_detected = true; - printf("Available RF device list:"); - for (unsigned int i = 0; available_devices[i]; i++) { + printf("Supported RF device list:"); + for (unsigned int i = 0; rf_plugins[i] && rf_plugins[i]->rf_api; i++) { no_rf_devs_detected = false; - printf(" %s ", available_devices[i]->name); + printf(" %s", rf_plugins[i]->rf_api->name); } printf("%s\n", no_rf_devs_detected ? " " : ""); // Try to open the device if name is provided if (devname && devname[0] != '\0') { int i = 0; - while (available_devices[i] != NULL) { - if (!strcasecmp(available_devices[i]->name, devname)) { - rf->dev = available_devices[i]; - return available_devices[i]->srsran_rf_open_multi(args, &rf->handler, nof_channels); + while (rf_plugins[i] != NULL) { + if (rf_plugins[i]->rf_api) { + if (!strcasecmp(rf_plugins[i]->rf_api->name, devname)) { + rf->dev = rf_plugins[i]->rf_api; + return rf_plugins[i]->rf_api->srsran_rf_open_multi(args, &rf->handler, nof_channels); + } } i++; } @@ -129,16 +133,16 @@ int srsran_rf_open_devname(srsran_rf_t* rf, const char* devname, char* args, uin return SRSRAN_ERROR; } - // auto-mode, try to open in order of apperance in available_devices[] array + // auto-mode, try to open in order of apperance in rf_plugins[] array int i = 0; - while (available_devices[i] != NULL) { - printf("Trying to open RF device '%s'\n", available_devices[i]->name); - if (!available_devices[i]->srsran_rf_open_multi(args, &rf->handler, nof_channels)) { - rf->dev = available_devices[i]; - printf("RF device '%s' successfully opened\n", available_devices[i]->name); + while (rf_plugins[i] != NULL && rf_plugins[i]->rf_api != NULL) { + printf("Trying to open RF device '%s'\n", rf_plugins[i]->rf_api->name); + if (!rf_plugins[i]->rf_api->srsran_rf_open_multi(args, &rf->handler, nof_channels)) { + rf->dev = rf_plugins[i]->rf_api; + printf("RF device '%s' successfully opened\n", rf_plugins[i]->rf_api->name); return SRSRAN_SUCCESS; } - printf("Unable to open RF device '%s'\n", available_devices[i]->name); + printf("Unable to open RF device '%s'\n", rf_plugins[i]->rf_api->name); i++; } @@ -148,6 +152,14 @@ int srsran_rf_open_devname(srsran_rf_t* rf, const char* devname, char* args, uin return SRSRAN_ERROR; } +int srsran_rf_open_file(srsran_rf_t* rf, FILE** rx_files, FILE** tx_files, uint32_t nof_channels, uint32_t base_srate) +{ + rf->dev = &srsran_rf_dev_file; + + // file abstraction has custom "open" function with file-related args + return rf_file_open_file(&rf->handler, rx_files, tx_files, nof_channels, base_srate); +} + const char* srsran_rf_name(srsran_rf_t* rf) { return ((rf_dev_t*)rf->dev)->srsran_rf_devname(rf->handler); @@ -392,3 +404,94 @@ int srsran_rf_send_timed2(srsran_rf_t* rf, { return srsran_rf_send_timed3(rf, data, nsamples, secs, frac_secs, true, true, is_start_of_burst, is_end_of_burst); } + +#ifdef ENABLE_RF_PLUGINS +static void unload_plugin(srsran_rf_plugin_t* rf_plugin) +{ + if (rf_plugin == NULL) { + return; + } + if (rf_plugin->dl_handle != NULL) { + rf_plugin->rf_api = NULL; + dlclose(rf_plugin->dl_handle); + rf_plugin->dl_handle = NULL; + } +} + +static int load_plugin(srsran_rf_plugin_t* rf_plugin) +{ + if (rf_plugin->rf_api != NULL) { + // already loaded + return SRSRAN_SUCCESS; + } + + rf_plugin->dl_handle = dlopen(rf_plugin->plugin_name, RTLD_NOW); + if (rf_plugin->dl_handle == NULL) { + // Not an error, if loading failed due to missing dependencies. + // Flag this plugin as not available and return SUCCESS. + // Note: as this function is called before log-level is configured, use plain printf for any messages < ERROR + printf("Skipping RF plugin %s: %s\n", rf_plugin->plugin_name, dlerror()); + rf_plugin->rf_api = NULL; + return SRSRAN_SUCCESS; + } + + // clear errors + dlerror(); + char* err = NULL; + + // load symbols + int (*register_plugin)(rf_dev_t * *rf_api) = dlsym(rf_plugin->dl_handle, "register_plugin"); + if ((err = dlerror()) != NULL) { + ERROR("Error loading symbol '%s': %s", "register_plugin", err); + goto clean_exit; + } + + // register plugin + int ret = register_plugin(&rf_plugin->rf_api); + if (ret != SRSRAN_SUCCESS) { + ERROR("Failed to register RF API for plugin %s", rf_plugin->plugin_name); + goto clean_exit; + } + return SRSRAN_SUCCESS; +clean_exit: + unload_plugin(rf_plugin); + return SRSRAN_ERROR; +} +#endif /* ENABLE_RF_PLUGINS */ + +int srsran_rf_load_plugins() +{ +#ifdef ENABLE_RF_PLUGINS + for (unsigned int i = 0; rf_plugins[i]; i++) { + if (load_plugin(rf_plugins[i]) != SRSRAN_SUCCESS) { + return SRSRAN_ERROR; + } + } + + printf("Active RF plugins:"); + for (unsigned int i = 0; rf_plugins[i]; i++) { + if (rf_plugins[i]->dl_handle != NULL) { + printf(" %s", rf_plugins[i]->plugin_name); + } + } + printf("\n"); + + printf("Inactive RF plugins:"); + for (unsigned int i = 0; rf_plugins[i]; i++) { + if (rf_plugins[i]->dl_handle == NULL) { + printf(" %s", rf_plugins[i]->plugin_name); + } + } + printf("\n"); + +#endif /* ENABLE_RF_PLUGINS */ + return SRSRAN_SUCCESS; +} + +// Search and load plugins when this library is loaded (shared) or right before main (static) +void __attribute__((constructor)) init() +{ + if (srsran_rf_load_plugins() != SRSRAN_SUCCESS) { + ERROR("Failed to load RF plugins"); + } +} diff --git a/srsenb/hdr/stack/rrc/nr/cell_asn1_config.h b/lib/src/phy/rf/rf_plugin.h similarity index 68% rename from srsenb/hdr/stack/rrc/nr/cell_asn1_config.h rename to lib/src/phy/rf/rf_plugin.h index 68a69c5c4c..cea843a971 100644 --- a/srsenb/hdr/stack/rrc/nr/cell_asn1_config.h +++ b/lib/src/phy/rf/rf_plugin.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,16 +19,19 @@ * */ -#ifndef SRSRAN_CELL_ASN1_CONFIG_H -#define SRSRAN_CELL_ASN1_CONFIG_H +#ifndef SRSRAN_RF_PLUGIN_H +#define SRSRAN_RF_PLUGIN_H -#include "rrc_config_nr.h" -#include "srsran/asn1/rrc_nr.h" +#include "srsran/phy/rf/rf.h" -namespace srsenb { +#ifdef __cplusplus +extern "C" { +#endif -int fill_sp_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::sp_cell_cfg_s& sp_cell); +SRSRAN_API int register_plugin(rf_dev_t** rf_api); +#ifdef __cplusplus } +#endif -#endif // SRSRAN_CELL_ASN1_CONFIG_H +#endif /* SRSRAN_RF_PLUGIN_H */ diff --git a/lib/src/phy/rf/rf_skiq_imp.c b/lib/src/phy/rf/rf_skiq_imp.c index d4187aa9c8..4f8acd2e40 100644 --- a/lib/src/phy/rf/rf_skiq_imp.c +++ b/lib/src/phy/rf/rf_skiq_imp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,6 +24,7 @@ #include #include "rf_helper.h" +#include "rf_plugin.h" #include "rf_skiq_imp.h" #include "rf_skiq_imp_card.h" @@ -592,10 +593,6 @@ int rf_skiq_set_rx_gain_ch(void* h_, uint32_t ch, double rx_gain) rx_gain = rf_skiq_card_set_rx_gain_db(&h->cards[card_idx], port_idx, rx_gain); - if (ch == 0) { - h->cur_tx_gain = rx_gain; - } - return SRSRAN_SUCCESS; } @@ -620,12 +617,10 @@ srsran_rf_info_t* rf_skiq_get_info(void* h_) if (h != NULL) { ret = &h->info; - rf_skiq_card_update_gain_table(&h->cards[0]); - ret->min_tx_gain = 0.25 * (double)h->cards[0].param.tx_param->atten_quarter_db_max; ret->max_tx_gain = 0.25 * (double)h->cards[0].param.tx_param->atten_quarter_db_min; - ret->min_rx_gain = h->cards[0].rx_gain_table_db[h->cards[0].param.rx_param[0].gain_index_min]; - ret->max_rx_gain = h->cards[0].rx_gain_table_db[h->cards[0].param.rx_param[0].gain_index_max]; + ret->min_rx_gain = h->cards[0].param.rx_param[0].gain_index_min; + ret->max_rx_gain = h->cards[0].param.rx_param[0].gain_index_max; } return ret; @@ -891,7 +886,7 @@ int rf_skiq_send_timed(void* h, } int rf_skiq_send_timed_multi(void* h_, - void** data_, + void* data_[SRSRAN_MAX_PORTS], int nsamples, time_t secs, double frac_secs, @@ -954,3 +949,43 @@ int rf_skiq_send_timed_multi(void* h_, return (int)rpm; } + +rf_dev_t srsran_rf_dev_skiq = {.name = "Sidekiq", + .srsran_rf_devname = rf_skiq_devname, + .srsran_rf_start_rx_stream = rf_skiq_start_rx_stream, + .srsran_rf_stop_rx_stream = rf_skiq_stop_rx_stream, + .srsran_rf_flush_buffer = rf_skiq_flush_buffer, + .srsran_rf_has_rssi = rf_skiq_has_rssi, + .srsran_rf_get_rssi = rf_skiq_get_rssi, + .srsran_rf_suppress_stdout = rf_skiq_suppress_stdout, + .srsran_rf_register_error_handler = rf_skiq_register_error_handler, + .srsran_rf_open = rf_skiq_open, + .srsran_rf_open_multi = rf_skiq_open_multi, + .srsran_rf_close = rf_skiq_close, + .srsran_rf_set_rx_srate = rf_skiq_set_rx_srate, + .srsran_rf_set_tx_srate = rf_skiq_set_tx_srate, + .srsran_rf_set_rx_gain = rf_skiq_set_rx_gain, + .srsran_rf_set_tx_gain = rf_skiq_set_tx_gain, + .srsran_rf_set_tx_gain_ch = rf_skiq_set_tx_gain_ch, + .srsran_rf_set_rx_gain_ch = rf_skiq_set_rx_gain_ch, + .srsran_rf_get_rx_gain = rf_skiq_get_rx_gain, + .srsran_rf_get_tx_gain = rf_skiq_get_tx_gain, + .srsran_rf_get_info = rf_skiq_get_info, + .srsran_rf_set_rx_freq = rf_skiq_set_rx_freq, + .srsran_rf_set_tx_freq = rf_skiq_set_tx_freq, + .srsran_rf_get_time = rf_skiq_get_time, + .srsran_rf_recv_with_time = rf_skiq_recv_with_time, + .srsran_rf_recv_with_time_multi = rf_skiq_recv_with_time_multi, + .srsran_rf_send_timed = rf_skiq_send_timed, + .srsran_rf_send_timed_multi = rf_skiq_send_timed_multi}; + +#ifdef ENABLE_RF_PLUGINS +int register_plugin(rf_dev_t** rf_api) +{ + if (rf_api == NULL) { + return SRSRAN_ERROR; + } + *rf_api = &srsran_rf_dev_skiq; + return SRSRAN_SUCCESS; +} +#endif /* ENABLE_RF_PLUGINS */ diff --git a/lib/src/phy/rf/rf_skiq_imp.h b/lib/src/phy/rf/rf_skiq_imp.h index 97a5a983df..1c31bfe20c 100644 --- a/lib/src/phy/rf/rf_skiq_imp.h +++ b/lib/src/phy/rf/rf_skiq_imp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -25,6 +25,8 @@ #include "srsran/config.h" #include "srsran/phy/rf/rf.h" +extern rf_dev_t srsran_rf_dev_skiq; + SRSRAN_API int rf_skiq_open(char* args, void** handler); SRSRAN_API int rf_skiq_open_multi(char* args, void** handler, uint32_t nof_rx_antennas); diff --git a/lib/src/phy/rf/rf_skiq_imp_card.c b/lib/src/phy/rf/rf_skiq_imp_card.c index 749a53c559..750f53237b 100644 --- a/lib/src/phy/rf/rf_skiq_imp_card.c +++ b/lib/src/phy/rf/rf_skiq_imp_card.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -49,21 +49,6 @@ static void* reader_thread(void* arg) switch (rx_status) { case skiq_rx_status_success: - // Check Rx index boundary - if (p_rx_block->rfic_control >= q->param.rx_param->gain_index_min && - p_rx_block->rfic_control <= q->param.rx_param->gain_index_max) { - double new_rx_gain = q->rx_gain_table_db[p_rx_block->rfic_control]; - - // If the Rx index has changed, update gain - if (new_rx_gain != q->cur_rx_gain_db) { - SKIQ_RF_DEBUG("card %d index=%d; gain=%.2f/%.2f dB;\n", - q->card, - p_rx_block->rfic_control, - q->rx_gain_table_db[p_rx_block->rfic_control], - q->cur_rx_gain_db); - q->cur_rx_gain_db = new_rx_gain; - } - } if (curr_rx_hdl < q->nof_ports && p_rx_block != NULL && len > SKIQ_RX_HEADER_SIZE_IN_BYTES) { // Convert number of bytes into samples uint32_t nsamples = len / 4 - SKIQ_RX_HEADER_SIZE_IN_WORDS; @@ -103,17 +88,6 @@ static void* reader_thread(void* arg) return NULL; } -int rf_skiq_card_update_gain_table(rf_skiq_card_t* q) -{ - for (uint8_t i = q->param.rx_param->gain_index_min; i <= q->param.rx_param->gain_index_max; i++) { - if (skiq_read_rx_cal_offset_by_gain_index(q->card, skiq_rx_hdl_A1, i, &q->rx_gain_table_db[i])) { - ERROR("Reading calibrated Rx gain index %d", i); - return SRSRAN_ERROR; - } - } - return SRSRAN_SUCCESS; -} - int rf_skiq_card_init(rf_skiq_card_t* q, uint8_t card, uint8_t nof_ports, const rf_skiq_port_opts_t* opts) { q->card = card; @@ -218,7 +192,13 @@ int rf_skiq_card_init(rf_skiq_card_t* q, uint8_t card, uint8_t nof_ports, const // Launch thread if (pthread_create(&q->thread, &attr, reader_thread, q)) { ERROR("Error creating reader thread with attributes (Did you miss sudo?). Trying without attributes.\n"); - return SRSRAN_ERROR; + + // try to create thread without attributes + pthread_attr_destroy(&attr); + if (pthread_create(&q->thread, NULL, reader_thread, q)) { + ERROR("Error creating reader thread, even without thread attributes. Exiting.\n"); + return SRSRAN_ERROR; + } } // Rename thread @@ -286,32 +266,39 @@ double rf_skiq_card_set_tx_gain_db(rf_skiq_card_t* q, uint32_t port_idx, double double rf_skiq_card_set_rx_gain_db(rf_skiq_card_t* q, uint32_t port_idx, double gain_db) { - // Find the nearest gain index in the table - int gain_idx = -1; - double gain_min_diff = INFINITY; - for (int i = q->param.rx_param->gain_index_min; i <= q->param.rx_param->gain_index_max; i++) { - double gain_diff = fabs(q->rx_gain_table_db[i] - gain_db); - if (gain_diff < gain_min_diff) { - gain_min_diff = gain_diff; - gain_idx = i; - } + // From Sidekiq API doc: + // + // For Sidekiq mPCIe (skiq_mpcie), Sidekiq M.2 (skiq_m2), Sidekiq Stretch (skiq_m2_2280), Sidekiq Z2 + //(skiq_z2), and Matchstiq Z3u (skiq_z3u) each increment of the gain index value results in approxi- + // mately 1 dB of gain, with approximately 76 dB of total gain available. For details on the gain table, + // refer to p. 37 of AD9361 Reference Manual UG-570 + + // Check gain range + if (gain_db < q->param.rx_param->gain_index_min || gain_db > q->param.rx_param->gain_index_max) { + ERROR("Error port %d:%d the selected gain (%.2f dB) is out of range (%d to %d dB).\n", + q->card, + port_idx, + gain_db, + q->param.rx_param->gain_index_min, + q->param.rx_param->gain_index_max); } - if (gain_idx >= 0) { - gain_db = q->rx_gain_table_db[gain_idx]; - if (port_idx < q->nof_ports) { - // Set single port gain - q->issued_rx_gain_db[port_idx] = gain_db; - skiq_write_rx_gain(q->card, (skiq_rx_hdl_t)port_idx, gain_idx); - } else { - // Set all gains - for (int i = 0; i < q->nof_ports; i++) { - q->issued_rx_gain_db[i] = gain_db; - skiq_write_rx_gain(q->card, (skiq_rx_hdl_t)i, gain_idx); - } + // Calculate attenuation index + uint16_t gain_idx = (uint16_t)floor(gain_db); + + if (port_idx < q->nof_ports) { + // Set single port gain + skiq_write_rx_gain(q->card, (skiq_rx_hdl_t)port_idx, gain_idx); + } else { + // Set all gains + for (int i = 0; i < q->nof_ports; i++) { + skiq_write_rx_gain(q->card, (skiq_rx_hdl_t)i, gain_idx); } } + // Update current rx_gain + q->cur_rx_gain_db = gain_db; + return gain_db; } @@ -514,16 +501,6 @@ double rf_skiq_card_set_rx_freq_hz(rf_skiq_card_t* q, uint32_t port_idx, double q->suspend = true; rf_skiq_rx_port_set_lo(&q->rx_ports[port_idx], (uint64_t)freq_hz); q->suspend = false; - - // Update gains for only port 0 - if (port_idx == 0) { - // Update gain table - rf_skiq_card_update_gain_table(q); - - // Set previous issued gain in dB for the new tables - rf_skiq_card_set_rx_gain_db(q, q->nof_ports, q->issued_rx_gain_db[port_idx]); - } - return freq_hz; } diff --git a/lib/src/phy/rf/rf_skiq_imp_card.h b/lib/src/phy/rf/rf_skiq_imp_card.h index 71e19e94e0..67ced83540 100644 --- a/lib/src/phy/rf/rf_skiq_imp_card.h +++ b/lib/src/phy/rf/rf_skiq_imp_card.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -32,9 +32,7 @@ typedef struct { rf_skiq_tx_port_t tx_ports[RF_SKIQ_MAX_PORTS_CARD]; rf_skiq_rx_port_t rx_ports[RF_SKIQ_MAX_PORTS_CARD]; - double rx_gain_table_db[UINT8_MAX + 1]; double cur_rx_gain_db; - double issued_rx_gain_db[SRSRAN_MAX_PORTS]; bool suspend; uint64_t start_rx_stream_ts; @@ -49,8 +47,6 @@ int rf_skiq_card_init(rf_skiq_card_t* q, uint8_t card, uint8_t nof_ports, const void rf_skiq_card_set_error_handler(rf_skiq_card_t* q, srsran_rf_error_handler_t error_handler, void* arg); -int rf_skiq_card_update_gain_table(rf_skiq_card_t* q); - double rf_skiq_card_set_tx_gain_db(rf_skiq_card_t* q, uint32_t port_idx, double gain_db); double rf_skiq_card_set_rx_gain_db(rf_skiq_card_t* q, uint32_t port_idx, double gain_db); diff --git a/lib/src/phy/rf/rf_skiq_imp_cfg.h b/lib/src/phy/rf/rf_skiq_imp_cfg.h index 923b8b5009..8d14a443a3 100644 --- a/lib/src/phy/rf/rf_skiq_imp_cfg.h +++ b/lib/src/phy/rf/rf_skiq_imp_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/rf/rf_skiq_imp_port.c b/lib/src/phy/rf/rf_skiq_imp_port.c index 41b438d61e..24a614467d 100644 --- a/lib/src/phy/rf/rf_skiq_imp_port.c +++ b/lib/src/phy/rf/rf_skiq_imp_port.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -231,7 +231,13 @@ int rf_skiq_tx_port_init(rf_skiq_tx_port_t* q, uint8_t card, skiq_tx_hdl_t hdl, // Launch thread if (pthread_create(&q->thread, &attr, writer_thread, q)) { ERROR("Error creating writer thread with attributes (Did you miss sudo?). Trying without attributes.\n"); - return SRSRAN_ERROR; + + // try to create thread without attributes + pthread_attr_destroy(&attr); + if (pthread_create(&q->thread, NULL, writer_thread, q)) { + ERROR("Error creating writer thread, even without thread attributes. Exiting.\n"); + return SRSRAN_ERROR; + } } // Rename thread diff --git a/lib/src/phy/rf/rf_skiq_imp_port.h b/lib/src/phy/rf/rf_skiq_imp_port.h index e19b0af299..474a2f2480 100644 --- a/lib/src/phy/rf/rf_skiq_imp_port.h +++ b/lib/src/phy/rf/rf_skiq_imp_port.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 1c613dcf04..642e07a29f 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -25,6 +25,7 @@ #include #include "rf_helper.h" +#include "rf_plugin.h" #include "rf_soapy_imp.h" #include "srsran/phy/common/phy_common.h" #include "srsran/phy/utils/debug.h" @@ -34,8 +35,8 @@ #include #include #include -#include #include +#include #define HAVE_ASYNC_THREAD 0 @@ -862,7 +863,7 @@ int rf_soapy_recv_with_time_multi(void* h, int rf_soapy_recv_with_time(void* h, void* data, uint32_t nsamples, bool blocking, time_t* secs, double* frac_secs) { void* data_multi[SRSRAN_MAX_PORTS] = {NULL}; - data_multi[0] = data; + data_multi[0] = data; return rf_soapy_recv_with_time_multi(h, data_multi, nsamples, blocking, secs, frac_secs); } @@ -1003,3 +1004,44 @@ int rf_soapy_send_timed_multi(void* h, return n; } + +rf_dev_t srsran_rf_dev_soapy = {"soapy", + rf_soapy_devname, + rf_soapy_start_rx_stream, + rf_soapy_stop_rx_stream, + rf_soapy_flush_buffer, + rf_soapy_has_rssi, + rf_soapy_get_rssi, + rf_soapy_suppress_stdout, + rf_soapy_register_error_handler, + rf_soapy_open, + rf_soapy_open_multi, + rf_soapy_close, + rf_soapy_set_rx_srate, + rf_soapy_set_rx_gain, + rf_soapy_set_rx_gain_ch, + rf_soapy_set_tx_gain, + rf_soapy_set_tx_gain_ch, + rf_soapy_get_rx_gain, + rf_soapy_get_tx_gain, + rf_soapy_get_info, + rf_soapy_set_rx_freq, + rf_soapy_set_tx_srate, + rf_soapy_set_tx_freq, + rf_soapy_get_time, + NULL, + rf_soapy_recv_with_time, + rf_soapy_recv_with_time_multi, + rf_soapy_send_timed, + .srsran_rf_send_timed_multi = rf_soapy_send_timed_multi}; + +#ifdef ENABLE_RF_PLUGINS +int register_plugin(rf_dev_t** rf_api) +{ + if (rf_api == NULL) { + return SRSRAN_ERROR; + } + *rf_api = &srsran_rf_dev_soapy; + return SRSRAN_SUCCESS; +} +#endif /* ENABLE_RF_PLUGINS */ diff --git a/lib/src/phy/rf/rf_soapy_imp.h b/lib/src/phy/rf/rf_soapy_imp.h index bbaa381356..0426023d86 100644 --- a/lib/src/phy/rf/rf_soapy_imp.h +++ b/lib/src/phy/rf/rf_soapy_imp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,6 +29,8 @@ #include #define DEVNAME_SOAPY "soapy" +extern rf_dev_t srsran_rf_dev_soapy; + SRSRAN_API int rf_soapy_open(char* args, void** handler); SRSRAN_API int rf_soapy_open_multi(char* args, void** handler, uint32_t num_requested_channels); diff --git a/lib/src/phy/rf/rf_uhd_generic.h b/lib/src/phy/rf/rf_uhd_generic.h index d8fdf4b7ca..92303d1c3c 100644 --- a/lib/src/phy/rf/rf_uhd_generic.h +++ b/lib/src/phy/rf/rf_uhd_generic.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/rf/rf_uhd_imp.cc b/lib/src/phy/rf/rf_uhd_imp.cc index d0d232be69..ea95a26af9 100644 --- a/lib/src/phy/rf/rf_uhd_imp.cc +++ b/lib/src/phy/rf/rf_uhd_imp.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,6 +29,7 @@ #include #include "rf_helper.h" +#include "rf_plugin.h" #include "srsran/phy/utils/debug.h" #include "srsran/phy/utils/vector.h" @@ -150,6 +151,7 @@ struct rf_uhd_handler_t { uint32_t nof_tx_channels = 0; std::array tx_freq = {}; std::array rx_freq = {}; + double cur_rx_gain_ch0 = 0; std::mutex tx_gain_mutex; std::array, SRSRAN_MAX_CHANNELS> tx_gain_db = {}; @@ -826,7 +828,7 @@ static int uhd_init(rf_uhd_handler_t* handler, char* args, uint32_t nof_channels if (clock_src != "internal") { // blocks until clock source is locked int error = wait_sensor_locked(handler, sensor_name, true, 300, is_locked); - // Print Not lock error if the return was succesful, wait_sensor_locked prints the error before returning + // Print Not lock error if the return was successful, wait_sensor_locked prints the error before returning if (not is_locked and error == SRSRAN_SUCCESS) { ERROR( "Could not lock reference clock source. Sensor: %s=%s\n", sensor_name.c_str(), is_locked ? "true" : "false"); @@ -1111,6 +1113,9 @@ int rf_uhd_set_rx_gain_ch(void* h, uint32_t ch, double gain) if (handler->uhd->set_rx_gain(ch, gain) != UHD_ERROR_NONE) { return SRSRAN_ERROR; } + if (ch == 0) { + handler->cur_rx_gain_ch0 = gain; + } return SRSRAN_SUCCESS; } @@ -1155,13 +1160,7 @@ int rf_uhd_set_tx_gain_ch(void* h, uint32_t ch, double gain) double rf_uhd_get_rx_gain(void* h) { rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; - double gain = 0.0; - - if (handler->uhd->get_rx_gain(gain) != UHD_ERROR_NONE) { - return SRSRAN_ERROR; - } - - return gain; + return handler->cur_rx_gain_ch0; } double rf_uhd_get_tx_gain(void* h) @@ -1546,3 +1545,44 @@ int rf_uhd_send_timed_multi(void* h, return nsamples; } + +rf_dev_t srsran_rf_dev_uhd = {"UHD", + rf_uhd_devname, + rf_uhd_start_rx_stream, + rf_uhd_stop_rx_stream, + rf_uhd_flush_buffer, + rf_uhd_has_rssi, + rf_uhd_get_rssi, + rf_uhd_suppress_stdout, + rf_uhd_register_error_handler, + rf_uhd_open, + rf_uhd_open_multi, + rf_uhd_close, + rf_uhd_set_rx_srate, + rf_uhd_set_rx_gain, + rf_uhd_set_rx_gain_ch, + rf_uhd_set_tx_gain, + rf_uhd_set_tx_gain_ch, + rf_uhd_get_rx_gain, + rf_uhd_get_tx_gain, + rf_uhd_get_info, + rf_uhd_set_rx_freq, + rf_uhd_set_tx_srate, + rf_uhd_set_tx_freq, + rf_uhd_get_time, + rf_uhd_sync_pps, + rf_uhd_recv_with_time, + rf_uhd_recv_with_time_multi, + rf_uhd_send_timed, + rf_uhd_send_timed_multi}; + +#ifdef ENABLE_RF_PLUGINS +int register_plugin(rf_dev_t** rf_api) +{ + if (rf_api == NULL) { + return SRSRAN_ERROR; + } + *rf_api = &srsran_rf_dev_uhd; + return SRSRAN_SUCCESS; +} +#endif /* ENABLE_RF_PLUGINS */ diff --git a/lib/src/phy/rf/rf_uhd_imp.h b/lib/src/phy/rf/rf_uhd_imp.h index 925a5d7875..34f8093855 100644 --- a/lib/src/phy/rf/rf_uhd_imp.h +++ b/lib/src/phy/rf/rf_uhd_imp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -38,6 +38,8 @@ extern "C" { #define DEVNAME_E3X0 "uhd_e3x0" #define DEVNAME_UNKNOWN "uhd_unknown" +extern rf_dev_t srsran_rf_dev_uhd; + SRSRAN_API int rf_uhd_open(char* args, void** handler); SRSRAN_API int rf_uhd_open_multi(char* args, void** handler, uint32_t nof_channels); diff --git a/lib/src/phy/rf/rf_uhd_rfnoc.h b/lib/src/phy/rf/rf_uhd_rfnoc.h index be40698cda..f114e482e5 100644 --- a/lib/src/phy/rf/rf_uhd_rfnoc.h +++ b/lib/src/phy/rf/rf_uhd_rfnoc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/rf/rf_uhd_safe.h b/lib/src/phy/rf/rf_uhd_safe.h index d09dfc7f49..fe27a69827 100644 --- a/lib/src/phy/rf/rf_uhd_safe.h +++ b/lib/src/phy/rf/rf_uhd_safe.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/rf/rf_utils.c b/lib/src/phy/rf/rf_utils.c index 0ac08cdd84..6fbd7389d9 100644 --- a/lib/src/phy/rf/rf_utils.c +++ b/lib/src/phy/rf/rf_utils.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/rf/rf_zmq_imp.c b/lib/src/phy/rf/rf_zmq_imp.c index 555f00cdaa..9761598901 100644 --- a/lib/src/phy/rf/rf_zmq_imp.c +++ b/lib/src/phy/rf/rf_zmq_imp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,6 +21,7 @@ #include "rf_zmq_imp.h" #include "rf_helper.h" +#include "rf_plugin.h" #include "rf_zmq_imp_trx.h" #include #include @@ -66,7 +67,7 @@ typedef struct { pthread_mutex_t rx_gain_mutex; } rf_zmq_handler_t; -void update_rates(rf_zmq_handler_t* handler, double srate); +static void update_rates(rf_zmq_handler_t* handler, double srate); /* * Static Atributes @@ -794,7 +795,7 @@ int rf_zmq_recv_with_time_multi(void* h, void** data, uint32_t nsamples, bool bl for (int j = 0; j < decim_factor; j++, n++) { avg += ptr[n]; } - dst[i] = avg; + dst[i] = avg; // divide by decim_factor later via scale } rf_zmq_info(handler->id, @@ -810,6 +811,10 @@ int rf_zmq_recv_with_time_multi(void* h, void** data, uint32_t nsamples, bool bl pthread_mutex_lock(&handler->rx_gain_mutex); float scale = srsran_convert_dB_to_amplitude(handler->rx_gain); pthread_mutex_unlock(&handler->rx_gain_mutex); + // scale shall also incorporate decim_factor + if (decim_factor > 0) { + scale = scale / decim_factor; + } for (uint32_t c = 0; c < handler->nof_channels; c++) { if (buffers[c]) { srsran_vec_sc_prod_cfc(buffers[c], scale, buffers[c], nsamples); @@ -966,8 +971,7 @@ int rf_zmq_send_timed_multi(void* h, } // Scale according to current gain - // TODO: document baseband scaling for ZMQ with gain settings, etc. before enabling - // srsran_vec_sc_prod_cfc(buf, tx_gain, buf, nsamples_baseband); + srsran_vec_sc_prod_cfc(buf, tx_gain, buf, nsamples_baseband); // Finally, transmit baseband int n = rf_zmq_tx_baseband(&handler->transmitter[i], buf, nsamples_baseband); @@ -989,3 +993,44 @@ int rf_zmq_send_timed_multi(void* h, return ret; } + +rf_dev_t srsran_rf_dev_zmq = {"zmq", + rf_zmq_devname, + rf_zmq_start_rx_stream, + rf_zmq_stop_rx_stream, + rf_zmq_flush_buffer, + rf_zmq_has_rssi, + rf_zmq_get_rssi, + rf_zmq_suppress_stdout, + rf_zmq_register_error_handler, + rf_zmq_open, + .srsran_rf_open_multi = rf_zmq_open_multi, + rf_zmq_close, + rf_zmq_set_rx_srate, + rf_zmq_set_rx_gain, + rf_zmq_set_rx_gain_ch, + rf_zmq_set_tx_gain, + rf_zmq_set_tx_gain_ch, + rf_zmq_get_rx_gain, + rf_zmq_get_tx_gain, + rf_zmq_get_info, + rf_zmq_set_rx_freq, + rf_zmq_set_tx_srate, + rf_zmq_set_tx_freq, + rf_zmq_get_time, + NULL, + rf_zmq_recv_with_time, + rf_zmq_recv_with_time_multi, + rf_zmq_send_timed, + .srsran_rf_send_timed_multi = rf_zmq_send_timed_multi}; + +#ifdef ENABLE_RF_PLUGINS +int register_plugin(rf_dev_t** rf_api) +{ + if (rf_api == NULL) { + return SRSRAN_ERROR; + } + *rf_api = &srsran_rf_dev_zmq; + return SRSRAN_SUCCESS; +} +#endif /* ENABLE_RF_PLUGINS */ diff --git a/lib/src/phy/rf/rf_zmq_imp.h b/lib/src/phy/rf/rf_zmq_imp.h index 0df0da8721..786c85df67 100644 --- a/lib/src/phy/rf/rf_zmq_imp.h +++ b/lib/src/phy/rf/rf_zmq_imp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -30,6 +30,8 @@ #define DEVNAME_ZMQ "ZeroMQ" +extern rf_dev_t srsran_rf_dev_zmq; + SRSRAN_API int rf_zmq_open(char* args, void** handler); SRSRAN_API int rf_zmq_open_multi(char* args, void** handler, uint32_t nof_channels); diff --git a/lib/src/phy/rf/rf_zmq_imp_rx.c b/lib/src/phy/rf/rf_zmq_imp_rx.c index 2d2fae3907..657733f011 100644 --- a/lib/src/phy/rf/rf_zmq_imp_rx.c +++ b/lib/src/phy/rf/rf_zmq_imp_rx.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/rf/rf_zmq_imp_trx.h b/lib/src/phy/rf/rf_zmq_imp_trx.h index 7e94ee9ab4..71b2a39e40 100644 --- a/lib/src/phy/rf/rf_zmq_imp_trx.h +++ b/lib/src/phy/rf/rf_zmq_imp_trx.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/rf/rf_zmq_imp_tx.c b/lib/src/phy/rf/rf_zmq_imp_tx.c index b4250bcb57..43f94f26db 100644 --- a/lib/src/phy/rf/rf_zmq_imp_tx.c +++ b/lib/src/phy/rf/rf_zmq_imp_tx.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/rf/rf_zmq_test.c b/lib/src/phy/rf/rf_zmq_test.c index 3e763e573d..79605e0464 100644 --- a/lib/src/phy/rf/rf_zmq_test.c +++ b/lib/src/phy/rf/rf_zmq_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -26,18 +26,22 @@ #include #include #include +#include #include #include -#define NOF_RX_ANT 1 +#define PRINT_SAMPLES 1 +#define COMPARE_BITS 0 +#define COMPARE_EPSILON (1e-6f) +#define NOF_RX_ANT 4 #define NUM_SF (500) #define SF_LEN (1920) #define RF_BUFFER_SIZE (SF_LEN * NUM_SF) #define TX_OFFSET_MS (4) -static cf_t ue_rx_buffer[RF_BUFFER_SIZE]; -static cf_t enb_tx_buffer[RF_BUFFER_SIZE]; -static cf_t enb_rx_buffer[RF_BUFFER_SIZE]; +static cf_t ue_rx_buffer[NOF_RX_ANT][RF_BUFFER_SIZE]; +static cf_t enb_tx_buffer[NOF_RX_ANT][RF_BUFFER_SIZE]; +static cf_t enb_rx_buffer[NOF_RX_ANT][RF_BUFFER_SIZE]; static srsran_rf_t ue_radio, enb_radio; pthread_t rx_thread; @@ -62,13 +66,15 @@ void* ue_rx_thread_function(void* args) uint32_t num_rxed_samps = 0; for (uint32_t i = 0; i < num_slots; ++i) { void* data_ptr[SRSRAN_MAX_PORTS] = {NULL}; - data_ptr[0] = &ue_rx_buffer[i * num_samps_per_slot]; + for (uint32_t c = 0; c < NOF_RX_ANT; c++) { + data_ptr[c] = &ue_rx_buffer[c][i * num_samps_per_slot]; + } num_rxed_samps += srsran_rf_recv_with_time_multi(&ue_radio, data_ptr, num_samps_per_slot, true, NULL, NULL); } printf("received %d samples.\n", num_rxed_samps); - printf("closing ue norf device\n"); + printf("closing ue zmq device\n"); srsran_rf_close(&ue_radio); return NULL; @@ -87,8 +93,10 @@ void enb_tx_function(const char* tx_args, bool timed_tx) } // generate random tx data - for (int i = 0; i < RF_BUFFER_SIZE; i++) { - enb_tx_buffer[i] = ((float)rand() / (float)RAND_MAX) + _Complex_I * ((float)rand() / (float)RAND_MAX); + for (int c = 0; c < NOF_RX_ANT; c++) { + for (int i = 0; i < RF_BUFFER_SIZE; i++) { + enb_tx_buffer[c][i] = ((float)rand() / (float)RAND_MAX) + _Complex_I * ((float)rand() / (float)RAND_MAX); + } } // send data subframe per subframe @@ -96,8 +104,12 @@ void enb_tx_function(const char* tx_args, bool timed_tx) // initial transmission without ts void* data_ptr[SRSRAN_MAX_PORTS] = {NULL}; - data_ptr[0] = &enb_tx_buffer[num_txed_samples]; - int ret = srsran_rf_send_multi(&enb_radio, (void**)data_ptr, SF_LEN, true, true, false); + cf_t tx_buffer[NOF_RX_ANT][SF_LEN]; + for (int c = 0; c < NOF_RX_ANT; c++) { + memcpy(&tx_buffer[c], &enb_tx_buffer[c][num_txed_samples], SF_LEN * sizeof(cf_t)); + data_ptr[c] = &tx_buffer[c][0]; + } + int ret = srsran_rf_send_multi(&enb_radio, (void**)data_ptr, SF_LEN, true, true, false); num_txed_samples += SF_LEN; // from here on, all transmissions are timed relative to the last rx time @@ -105,11 +117,16 @@ void enb_tx_function(const char* tx_args, bool timed_tx) for (uint32_t i = 0; i < NUM_SF - ((timed_tx) ? TX_OFFSET_MS : 1); ++i) { // first recv samples - data_ptr[0] = enb_rx_buffer; + for (int c = 0; c < NOF_RX_ANT; c++) { + data_ptr[c] = enb_rx_buffer[c]; + } srsran_rf_recv_with_time_multi(&enb_radio, data_ptr, SF_LEN, true, &rx_time.full_secs, &rx_time.frac_secs); // prepare data buffer - data_ptr[0] = &enb_tx_buffer[num_txed_samples]; + for (int c = 0; c < NOF_RX_ANT; c++) { + memcpy(&tx_buffer[c], &enb_tx_buffer[c][num_txed_samples], SF_LEN * sizeof(cf_t)); + data_ptr[c] = &tx_buffer[c][0]; + } if (timed_tx) { // timed tx relative to receive time (this will cause a cap in the rx'ed samples at the UE resulting in 3 zero @@ -157,25 +174,46 @@ int run_test(const char* rx_args, const char* tx_args, bool timed_tx) // wait for rx thread pthread_join(rx_thread, NULL); - // subframe-wise compare tx'ed and rx'ed data (stop 3 subframes earlier for timed tx) - for (uint32_t i = 0; i < NUM_SF - (timed_tx ? 3 : 0); ++i) { - uint32_t sf_offet = 0; - if (timed_tx && i >= 1) { - // for timed transmission, the enb inserts 3 zero subframes after the first untimed tx - sf_offet = (TX_OFFSET_MS - 1) * SF_LEN; - } - -#if 0 - // print first 3 samples for each SF - printf("enb_tx_buffer sf%d:\n", i); - srsran_vec_fprint_c(stdout, &enb_tx_buffer[i * SF_LEN], 3); - printf("ue_rx_buffer sf%d:\n", i); - srsran_vec_fprint_c(stdout, &ue_rx_buffer[sf_offet + i * SF_LEN], 3); + // channel-wise comparison + for (int c = 0; c < NOF_RX_ANT; c++) { + // subframe-wise compare tx'ed and rx'ed data (stop 3 subframes earlier for timed tx) + for (uint32_t i = 0; i < NUM_SF - (timed_tx ? 3 : 0); ++i) { + uint32_t sf_offet = 0; + if (timed_tx && i >= 1) { + // for timed transmission, the enb inserts 3 zero subframes after the first untimed tx + sf_offet = (TX_OFFSET_MS - 1) * SF_LEN; + } + +#if PRINT_SAMPLES + // print first 10 samples for each SF + printf("enb_tx_buffer sf%d:\n", i); + srsran_vec_fprint_c(stdout, &enb_tx_buffer[c][i * SF_LEN], 10); + printf("ue_rx_buffer sf%d:\n", i); + srsran_vec_fprint_c(stdout, &ue_rx_buffer[c][sf_offet + i * SF_LEN], 10); #endif - if (memcmp(&ue_rx_buffer[sf_offet + i * SF_LEN], &enb_tx_buffer[i * SF_LEN], SF_LEN) != 0) { - fprintf(stderr, "data mismatch in subframe %d\n", i); - goto exit; +#if COMPARE_BITS + int d = memcmp(&ue_rx_buffer[sf_offet + i * SF_LEN], &enb_tx_buffer[i * SF_LEN], SF_LEN); + if (d) { + d = d > 0 ? d : -d; + fprintf(stderr, "data mismatch in subframe %d, sample %d\n", i, d); + printf("enb_tx_buffer sf%d:\n", i); + srsran_vec_fprint_c(stdout, &enb_tx_buffer[i * SF_LEN + d], 10); + printf("ue_rx_buffer sf%d:\n", i); + srsran_vec_fprint_c(stdout, &ue_rx_buffer[sf_offet + i * SF_LEN + d], 10); + goto exit; + } +#else + srsran_vec_sub_ccc(&ue_rx_buffer[c][sf_offet + i * SF_LEN], + &enb_tx_buffer[c][i * SF_LEN], + &ue_rx_buffer[c][sf_offet + i * SF_LEN], + SF_LEN); + uint32_t max_ix = srsran_vec_max_abs_ci(&ue_rx_buffer[c][sf_offet + i * SF_LEN], SF_LEN); + if (cabsf(ue_rx_buffer[c][sf_offet + i * SF_LEN + max_ix]) > COMPARE_EPSILON) { + fprintf(stderr, "data mismatch in subframe %d\n", i); + goto exit; + } +#endif } } @@ -204,56 +242,76 @@ int param_test(const char* args_param, const int num_channels) int main() { - // two Rx ports - if (param_test("rx_port=ipc://dl0,rx_port1=ipc://dl1", 2)) { - fprintf(stderr, "Param test failed!\n"); - return SRSRAN_ERROR; - } - - // multiple rx ports, no channel index provided - if (param_test("rx_port=ipc://dl0,rx_port=ipc://dl1,rx_port=ipc://dl2,rx_port=ipc://dl3,base_srate=1.92e6", 4)) { - fprintf(stderr, "Param test failed!\n"); - return SRSRAN_ERROR; - } - - // One Rx, one Tx and all generic options - if (param_test("rx_port0=tcp://" - "localhost:2000,rx_format=sc16,tx_format=sc16,tx_type=pub,rx_type=sub,base_srate=1.92e6,id=test", - 1)) { - fprintf(stderr, "Param test failed!\n"); - return SRSRAN_ERROR; - } - - // 1 port, 2 antennas, MIMO freq config - if (param_test( - "tx_port0=tcp://*:2001,tx_port1=tcp://*:2003,rx_port0=tcp://localhost:2000,rx_port1=tcp://" - "localhost:2002,id=ue,base_srate=23.04e6,tx_freq0=2510e6,tx_freq1=2510e6,rx_freq0=2630e6,,rx_freq1=2630e6", - 2)) { - fprintf(stderr, "Param test failed!\n"); - return SRSRAN_ERROR; - } - + // // two Rx ports + // if (param_test("rx_port=ipc://dl0,rx_port1=ipc://dl1", 2)) { + // fprintf(stderr, "Param test failed!\n"); + // return SRSRAN_ERROR; + // } + + // // multiple rx ports, no channel index provided + // if (param_test("rx_port=ipc://dl0,rx_port=ipc://dl1,rx_port=ipc://dl2,rx_port=ipc://dl3,base_srate=1.92e6", 4)) { + // fprintf(stderr, "Param test failed!\n"); + // return SRSRAN_ERROR; + // } + + // // One Rx, one Tx and all generic options + // if (param_test("rx_port0=tcp://" + // "localhost:2000,rx_format=sc16,tx_format=sc16,tx_type=pub,rx_type=sub,base_srate=1.92e6,id=test", + // 1)) { + // fprintf(stderr, "Param test failed!\n"); + // return SRSRAN_ERROR; + // } + + // // 1 port, 2 antennas, MIMO freq config + // if (param_test( + // "tx_port0=tcp://*:2001,tx_port1=tcp://*:2003,rx_port0=tcp://localhost:2000,rx_port1=tcp://" + // "localhost:2002,id=ue,base_srate=23.04e6,tx_freq0=2510e6,tx_freq1=2510e6,rx_freq0=2630e6,,rx_freq1=2630e6", + // 2)) { + // fprintf(stderr, "Param test failed!\n"); + // return SRSRAN_ERROR; + // } + +#if NOF_RX_ANT == 1 // single tx, single rx with continuous transmissions (no timed tx) using IPC transport if (run_test("rx_port=ipc://link1,id=ue,base_srate=1.92e6", "tx_port=ipc://link1,id=enb,base_srate=1.92e6", false) != SRSRAN_SUCCESS) { fprintf(stderr, "Single tx, single rx test failed!\n"); return -1; } +#endif - // two trx radios with continous tx (no timed tx) using TCP transport for both directions - if (run_test("tx_port=tcp://*:5554,rx_port=tcp://" - "localhost:5555,id=ue,base_srate=1.92e6,log_trx_timeout=true,trx_timeout_ms=1000", - "rx_port=tcp://localhost:5554,tx_port=tcp://*:5555,id=enb,base_srate=1.92e6", + // up to 4 trx radios with continous tx (no decimation, no timed tx) + if (run_test("tx_port=tcp://*:5554,tx_port=tcp://*:5556,tx_port=tcp://*:5558,tx_port=tcp://*:5560,rx_port=tcp://" + "localhost:5555,rx_port=tcp://localhost:5557,rx_port=tcp://localhost:5559,rx_port=tcp://" + "localhost:5561,id=ue,base_srate=1.92e6,log_trx_timeout=true,trx_timeout_ms=1000", + "rx_port=tcp://localhost:5554,rx_port=tcp://localhost:5556,rx_port=tcp://localhost:5558,rx_port=tcp://" + "localhost:5560,tx_port=tcp://*:5555,tx_port=tcp://*:5557,tx_port=tcp://*:5559,tx_port=tcp://" + "*:5561,id=enb,base_srate=1.92e6", false) != SRSRAN_SUCCESS) { - fprintf(stderr, "Two TRx radio test failed!\n"); + fprintf(stderr, "Multi TRx radio test failed!\n"); + return -1; + } + + // up to 4 trx radios with continous tx (timed tx) using TCP for UL (UE tx) and IPC for eNB DL (eNB tx) + if (run_test("tx_port=tcp://*:5554,tx_port=tcp://*:5556,tx_port=tcp://*:5558,tx_port=tcp://*:5560,rx_port=ipc://" + "dl0,rx_port=ipc://dl1,rx_port=ipc://dl2,rx_port=ipc://dl3,id=ue,base_srate=1.92e6", + "rx_port=tcp://localhost:5554,rx_port=tcp://localhost:5556,rx_port=tcp://localhost:5558,rx_port=tcp://" + "localhost:5560,tx_port=ipc://dl0,tx_port=ipc://dl1,tx_port=ipc://dl2,tx_port=ipc://" + "dl3,id=enb,base_srate=1.92e6", + true) != SRSRAN_SUCCESS) { + fprintf(stderr, "Multi TRx radio test with timed tx failed!\n"); return -1; } - // two trx radios with continous tx (no timed tx) using TCP for UL (UE tx) and IPC for eNB DL (eNB tx) - if (run_test("tx_port=tcp://*:5554,rx_port=ipc://dl,id=ue,base_srate=1.92e6", - "rx_port=tcp://localhost:5554,tx_port=ipc://dl,id=enb,base_srate=1.92e6", + // up to 4 trx radios with continous tx (timed tx) using TCP for UL (UE tx) and IPC for eNB DL (eNB tx) + // with decimation 23.04e6 <-> 1.92e6 + if (run_test("tx_port=tcp://*:5554,tx_port=tcp://*:5556,tx_port=tcp://*:5558,tx_port=tcp://*:5560,rx_port=ipc://" + "dl0,rx_port=ipc://dl1,rx_port=ipc://dl2,rx_port=ipc://dl3,id=ue,base_srate=23.04e6", + "rx_port=tcp://localhost:5554,rx_port=tcp://localhost:5556,rx_port=tcp://localhost:5558,rx_port=tcp://" + "localhost:5560,tx_port=ipc://dl0,tx_port=ipc://dl1,tx_port=ipc://dl2,tx_port=ipc://" + "dl3,id=enb,base_srate=23.04e6", true) != SRSRAN_SUCCESS) { - fprintf(stderr, "Two TRx radio test with timed tx failed!\n"); + fprintf(stderr, "Multi TRx radio test with timed tx and decimation failed!\n"); return -1; } diff --git a/lib/src/phy/rf/skiq_pps_test.c b/lib/src/phy/rf/skiq_pps_test.c index aeec4db9ef..b28b8efa74 100644 --- a/lib/src/phy/rf/skiq_pps_test.c +++ b/lib/src/phy/rf/skiq_pps_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/scrambling/CMakeLists.txt b/lib/src/phy/scrambling/CMakeLists.txt index 63c4a13160..56566041e2 100644 --- a/lib/src/phy/scrambling/CMakeLists.txt +++ b/lib/src/phy/scrambling/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/scrambling/scrambling.c b/lib/src/phy/scrambling/scrambling.c index 7a008b66fb..402b970baf 100644 --- a/lib/src/phy/scrambling/scrambling.c +++ b/lib/src/phy/scrambling/scrambling.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/scrambling/test/CMakeLists.txt b/lib/src/phy/scrambling/test/CMakeLists.txt index a363669442..ab0672f099 100644 --- a/lib/src/phy/scrambling/test/CMakeLists.txt +++ b/lib/src/phy/scrambling/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/scrambling/test/scrambling_test.c b/lib/src/phy/scrambling/test/scrambling_test.c index cf8111beb8..03c6714ec5 100644 --- a/lib/src/phy/scrambling/test/scrambling_test.c +++ b/lib/src/phy/scrambling/test/scrambling_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/CMakeLists.txt b/lib/src/phy/sync/CMakeLists.txt index 2a1d54ca88..e5d95c30f9 100644 --- a/lib/src/phy/sync/CMakeLists.txt +++ b/lib/src/phy/sync/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/sync/cfo.c b/lib/src/phy/sync/cfo.c index bbfec37daa..b8360ac5b3 100644 --- a/lib/src/phy/sync/cfo.c +++ b/lib/src/phy/sync/cfo.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/cp.c b/lib/src/phy/sync/cp.c index 0b0928e845..1b670dd4b3 100644 --- a/lib/src/phy/sync/cp.c +++ b/lib/src/phy/sync/cp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/find_sss.c b/lib/src/phy/sync/find_sss.c index 272500ed1c..ffb696c91a 100644 --- a/lib/src/phy/sync/find_sss.c +++ b/lib/src/phy/sync/find_sss.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/gen_sss.c b/lib/src/phy/sync/gen_sss.c index 36922507ef..18f6c5a82a 100644 --- a/lib/src/phy/sync/gen_sss.c +++ b/lib/src/phy/sync/gen_sss.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/npss.c b/lib/src/phy/sync/npss.c index 8fbfc3b1cd..91548a8cdb 100644 --- a/lib/src/phy/sync/npss.c +++ b/lib/src/phy/sync/npss.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/nsss.c b/lib/src/phy/sync/nsss.c index eb2d98f522..794d84dc4d 100644 --- a/lib/src/phy/sync/nsss.c +++ b/lib/src/phy/sync/nsss.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/pss.c b/lib/src/phy/sync/pss.c index 368379c5c7..02241fb6d6 100644 --- a/lib/src/phy/sync/pss.c +++ b/lib/src/phy/sync/pss.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/pss_nr.c b/lib/src/phy/sync/pss_nr.c index 0dddd95f17..36288119f3 100644 --- a/lib/src/phy/sync/pss_nr.c +++ b/lib/src/phy/sync/pss_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/psss.c b/lib/src/phy/sync/psss.c index c6cc0462b5..9a3e486fa7 100644 --- a/lib/src/phy/sync/psss.c +++ b/lib/src/phy/sync/psss.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/refsignal_dl_sync.c b/lib/src/phy/sync/refsignal_dl_sync.c index 6b134d5382..b2455239f3 100644 --- a/lib/src/phy/sync/refsignal_dl_sync.c +++ b/lib/src/phy/sync/refsignal_dl_sync.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/sfo.c b/lib/src/phy/sync/sfo.c index de8096285a..a2553ba552 100644 --- a/lib/src/phy/sync/sfo.c +++ b/lib/src/phy/sync/sfo.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/ssb.c b/lib/src/phy/sync/ssb.c index d01f3157c6..0102f8c060 100644 --- a/lib/src/phy/sync/ssb.c +++ b/lib/src/phy/sync/ssb.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -46,7 +46,7 @@ /* * Default NR-PBCH DMRS normalised correlation (RSRP/EPRE) threshold */ -#define SSB_PBCH_DMRS_DEFAULT_CORR_THR 0.6f +#define SSB_PBCH_DMRS_DEFAULT_CORR_THR 0.5f static int ssb_init_corr(srsran_ssb_t* q) { @@ -536,21 +536,10 @@ bool srsran_ssb_send(srsran_ssb_t* q, uint32_t sf_idx) return (sf_idx % q->cfg.periodicity_ms == 0); } -int srsran_ssb_add(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* msg, const cf_t* in, cf_t* out) +static int ssb_encode(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* msg, cf_t ssb_grid[SRSRAN_SSB_NOF_RE]) { - // Verify input parameters - if (q == NULL || N_id >= SRSRAN_NOF_NID_NR || msg == NULL || in == NULL || out == NULL) { - return SRSRAN_ERROR_INVALID_INPUTS; - } - - if (!q->args.enable_encode) { - ERROR("SSB is not configured for encode"); - return SRSRAN_ERROR; - } - - uint32_t N_id_1 = SRSRAN_NID_1_NR(N_id); - uint32_t N_id_2 = SRSRAN_NID_2_NR(N_id); - cf_t ssb_grid[SRSRAN_SSB_NOF_RE] = {}; + uint32_t N_id_1 = SRSRAN_NID_1_NR(N_id); + uint32_t N_id_2 = SRSRAN_NID_2_NR(N_id); // Put PSS if (srsran_pss_nr_put(ssb_grid, N_id_2, q->cfg.beta_pss) < SRSRAN_SUCCESS) { @@ -589,6 +578,64 @@ int srsran_ssb_add(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* m return SRSRAN_ERROR; } + return SRSRAN_SUCCESS; +} + +SRSRAN_API int +srsran_ssb_put_grid(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* msg, cf_t* re_grid, uint32_t grid_bw_sc) +{ + // Verify input parameters + if (q == NULL || N_id >= SRSRAN_NOF_NID_NR || msg == NULL || re_grid == NULL || + grid_bw_sc * SRSRAN_NRE < SRSRAN_SSB_BW_SUBC) { + return SRSRAN_ERROR_INVALID_INPUTS; + } + + if (!q->args.enable_encode) { + ERROR("SSB is not configured for encode"); + return SRSRAN_ERROR; + } + + // Put signals in SSB grid + cf_t ssb_grid[SRSRAN_SSB_NOF_RE] = {}; + if (ssb_encode(q, N_id, msg, ssb_grid) < SRSRAN_SUCCESS) { + ERROR("Putting SSB in grid"); + return SRSRAN_ERROR; + } + + // First symbol in the half frame + uint32_t l_first = q->l_first[msg->ssb_idx]; + + // Frequency offset fom the bottom of the grid + uint32_t f_offset = grid_bw_sc / 2 + q->f_offset - SRSRAN_SSB_BW_SUBC / 2; + + // Put SSB grid in the actual resource grid + for (uint32_t l = 0; l < SRSRAN_SSB_DURATION_NSYMB; l++) { + srsran_vec_cf_copy( + &re_grid[grid_bw_sc * (l_first + l) + f_offset], &ssb_grid[SRSRAN_SSB_BW_SUBC * l], SRSRAN_SSB_BW_SUBC); + } + + return SRSRAN_SUCCESS; +} + +int srsran_ssb_add(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* msg, const cf_t* in, cf_t* out) +{ + // Verify input parameters + if (q == NULL || N_id >= SRSRAN_NOF_NID_NR || msg == NULL || in == NULL || out == NULL) { + return SRSRAN_ERROR_INVALID_INPUTS; + } + + if (!q->args.enable_encode) { + ERROR("SSB is not configured for encode"); + return SRSRAN_ERROR; + } + + // Put signals in SSB grid + cf_t ssb_grid[SRSRAN_SSB_NOF_RE] = {}; + if (ssb_encode(q, N_id, msg, ssb_grid) < SRSRAN_SUCCESS) { + ERROR("Putting SSB in grid"); + return SRSRAN_ERROR; + } + // Select start symbol from SSB candidate index int t_offset = ssb_get_t_offset(q, msg->ssb_idx); if (t_offset < SRSRAN_SUCCESS) { @@ -624,7 +671,11 @@ int srsran_ssb_add(srsran_ssb_t* q, uint32_t N_id, const srsran_pbch_msg_nr_t* m return SRSRAN_SUCCESS; } -static int ssb_demodulate(srsran_ssb_t* q, const cf_t* in, uint32_t t_offset, cf_t ssb_grid[SRSRAN_SSB_NOF_RE]) +static int ssb_demodulate(srsran_ssb_t* q, + const cf_t* in, + uint32_t t_offset, + float coarse_cfo_hz, + cf_t ssb_grid[SRSRAN_SSB_NOF_RE]) { const cf_t* in_ptr = &in[t_offset]; for (uint32_t l = 0; l < SRSRAN_SSB_DURATION_NSYMB; l++) { @@ -632,11 +683,16 @@ static int ssb_demodulate(srsran_ssb_t* q, const cf_t* in, uint32_t t_offset, cf in_ptr += SRSRAN_FLOOR(q->cp_sz, 2); // Copy FFT window in temporal time domain buffer - srsran_vec_cf_copy(q->tmp_time, in_ptr, q->symbol_sz); + if (isnormal(coarse_cfo_hz)) { + srsran_vec_apply_cfo(in_ptr, (float)(-coarse_cfo_hz / q->cfg.srate_hz), q->tmp_time, q->symbol_sz); + } else { + srsran_vec_cf_copy(q->tmp_time, in_ptr, q->symbol_sz); + } in_ptr += q->symbol_sz + SRSRAN_CEIL(q->cp_sz, 2); // Phase compensation - cf_t phase_compensation = (cf_t)cexp(-I * 2.0 * M_PI * q->cfg.center_freq_hz * (double)t_offset / q->cfg.srate_hz); + cf_t phase_compensation = + (cf_t)cexp(-I * 2.0 * M_PI * (q->cfg.center_freq_hz - coarse_cfo_hz) * (double)t_offset / q->cfg.srate_hz); t_offset += q->symbol_sz + q->cp_sz; // Convert to frequency domain @@ -727,18 +783,25 @@ ssb_measure(srsran_ssb_t* q, const cf_t ssb_grid[SRSRAN_SSB_NOF_RE], uint32_t N_ float rsrp_sss = SRSRAN_CSQABS(corr_sss); float rsrp = (rsrp_pss + rsrp_sss) / 2.0f; - // avoid taking log of 0 (NaN) - if (rsrp == 0.0) { - rsrp = 1.0; + // Avoid taking log of 0 or another abnormal value + if (!isnormal(rsrp)) { + rsrp = 1e-9f; } - // Compute Noise - float n0_pss = 1e-9; // Almost 0 - float n0_sss = 1e-9; // Almost 0 - if (epre_pss > rsrp_pss) { + // Estimate Noise: + // - Infinite (1e9), if the EPRE or RSRP is zero + // - EPRE-RSRP if EPRE > RSRP + // - zero (1e-9), otherwise + float n0_pss = 1e-9f; + if (!isnormal(epre_pss) || !isnormal(rsrp_pss)) { + n0_pss = 1e9f; + } else if (epre_pss > rsrp_pss) { n0_pss = epre - rsrp_pss; } - if (epre_sss > rsrp_sss) { + float n0_sss = 1e-9f; + if (!isnormal(epre_sss) || !isnormal(rsrp_sss)) { + n0_sss = 1e9f; + } else if (epre_sss > rsrp_sss) { n0_sss = epre - rsrp_sss; } float n0 = (n0_pss + n0_sss) / 2.0f; @@ -759,18 +822,60 @@ ssb_measure(srsran_ssb_t* q, const cf_t ssb_grid[SRSRAN_SSB_NOF_RE], uint32_t N_ return SRSRAN_SUCCESS; } -static int -ssb_pss_search(srsran_ssb_t* q, const cf_t* in, uint32_t nof_samples, uint32_t* found_N_id_2, uint32_t* found_delay) +static void ssb_vec_prod_conj_circ_shift(const cf_t* a, const cf_t* b, cf_t* c, uint32_t n, int shift) +{ + uint32_t offset = (uint32_t)abs(shift); + + // Avoid negative number of samples + if (offset > n) { + srsran_vec_cf_zero(c, n); + return; + } + + // Shift is negative + if (shift < 0) { + srsran_vec_prod_conj_ccc(&a[offset], &b[0], &c[0], n - offset); + srsran_vec_prod_conj_ccc(&a[0], &b[n - offset], &c[n - offset], offset); + return; + } + + // Shift is positive + if (shift > 0) { + srsran_vec_prod_conj_ccc(&a[0], &b[offset], &c[0], n - offset); + srsran_vec_prod_conj_ccc(&a[n - offset], &b[0], &c[n - offset], offset); + return; + } + + // Shift is zero + srsran_vec_prod_conj_ccc(a, b, c, n); +} + +static int ssb_pss_search(srsran_ssb_t* q, + const cf_t* in, + uint32_t nof_samples, + uint32_t* found_N_id_2, + uint32_t* found_delay, + float* coarse_cfo_hz) { // verify it is initialised if (q->corr_sz == 0) { return SRSRAN_ERROR; } + // Calculate correlation CFO coarse precision + double coarse_cfo_ref_hz = (q->cfg.srate_hz / q->corr_sz); + + // Calculate shift integer range to detect the signal with a maximum CFO equal to the SSB subcarrier spacing + int shift_range = (int)ceil(SRSRAN_SUBC_SPACING_NR(q->cfg.scs) / coarse_cfo_ref_hz); + + // Calculate the coarse shift increment for half of the subcarrier spacing + int shift_coarse_inc = shift_range / 2; + // Correlation best sequence float best_corr = 0; uint32_t best_delay = 0; uint32_t best_N_id_2 = 0; + int best_shift = 0; // Delay in correlation window uint32_t t_offset = 0; @@ -796,39 +901,84 @@ ssb_pss_search(srsran_ssb_t* q, const cf_t* in, uint32_t nof_samples, uint32_t* // Try each N_id_2 sequence for (uint32_t N_id_2 = 0; N_id_2 < SRSRAN_NOF_NID_2_NR; N_id_2++) { - // Actual correlation in frequency domain - srsran_vec_prod_conj_ccc(q->tmp_freq, q->pss_seq[N_id_2], q->tmp_corr, q->corr_sz); + // Steer coarse frequency offset + for (int shift = -shift_range; shift <= shift_range; shift += shift_coarse_inc) { + // Actual correlation in frequency domain + ssb_vec_prod_conj_circ_shift(q->tmp_freq, q->pss_seq[N_id_2], q->tmp_corr, q->corr_sz, shift); + + // Convert to time domain + srsran_dft_run_guru_c(&q->ifft_corr); + + // Find maximum + uint32_t peak_idx = srsran_vec_max_abs_ci(q->tmp_time, q->corr_window); + + // Average power, take total power of the frequency domain signal after filtering, skip correlation window if + // value is invalid (0.0, nan or inf) + float avg_pwr_corr = srsran_vec_avg_power_cf(q->tmp_corr, q->corr_sz); + if (!isnormal(avg_pwr_corr)) { + continue; + } + + // Normalise correlation + float corr = SRSRAN_CSQABS(q->tmp_time[peak_idx]) / avg_pwr_corr / sqrtf(SRSRAN_PSS_NR_LEN); + + // Update if the correlation is better than the current best + if (best_corr < corr) { + best_corr = corr; + best_delay = peak_idx + t_offset; + best_N_id_2 = N_id_2; + best_shift = shift; + } + } + } - // Convert to time domain - srsran_dft_run_guru_c(&q->ifft_corr); + // Advance time + t_offset += q->corr_window; + } - // Find maximum - uint32_t peak_idx = srsran_vec_max_abs_ci(q->tmp_time, q->corr_window); + // From the best sequence correlate in frequency domain + { + // Reset best correlation + best_corr = 0.0f; - // Average power, skip window if value is invalid (0.0, nan or inf) - float avg_pwr_corr = srsran_vec_avg_power_cf(&q->tmp_time[peak_idx], q->symbol_sz); - if (!isnormal(avg_pwr_corr)) { - continue; - } + // Number of samples taken in this iteration + uint32_t n = q->corr_sz; - // Normalise correlation - float corr = SRSRAN_CSQABS(q->tmp_time[peak_idx]) / avg_pwr_corr / sqrtf(SRSRAN_PSS_NR_LEN); + // Detect if the correlation input exceeds the input length, take the maximum amount of samples + if (best_delay + q->corr_sz > nof_samples) { + n = nof_samples - best_delay; + } + + // Copy the amount of samples + srsran_vec_cf_copy(q->tmp_time, &in[best_delay], n); + + // Append zeros if there is space left + if (n < q->corr_sz) { + srsran_vec_cf_zero(&q->tmp_time[n], q->corr_sz - n); + } + + // Convert to frequency domain + srsran_dft_run_guru_c(&q->fft_corr); + + for (int shift = -shift_range; shift <= shift_range; shift++) { + // Actual correlation in frequency domain + ssb_vec_prod_conj_circ_shift(q->tmp_freq, q->pss_seq[best_N_id_2], q->tmp_corr, q->corr_sz, shift); + + // Calculate correlation assuming the peak is in the first sample + float corr = SRSRAN_CSQABS(srsran_vec_acc_cc(q->tmp_corr, q->corr_sz)); // Update if the correlation is better than the current best if (best_corr < corr) { - best_corr = corr; - best_delay = peak_idx + t_offset; - best_N_id_2 = N_id_2; + best_corr = corr; + best_shift = shift; } } - - // Advance time - t_offset += q->corr_window; } // Save findings - *found_delay = best_delay; - *found_N_id_2 = best_N_id_2; + *found_delay = best_delay; + *found_N_id_2 = best_N_id_2; + *coarse_cfo_hz = -(float)best_shift * coarse_cfo_ref_hz; return SRSRAN_SUCCESS; } @@ -857,9 +1007,10 @@ int srsran_ssb_csi_search(srsran_ssb_t* q, nof_samples -= (q->symbol_sz + q->cp_sz) * SRSRAN_SSB_DURATION_NSYMB; // Search for PSS in time domain - uint32_t N_id_2 = 0; - uint32_t t_offset = 0; - if (ssb_pss_search(q, in, nof_samples, &N_id_2, &t_offset) < SRSRAN_SUCCESS) { + uint32_t N_id_2 = 0; + uint32_t t_offset = 0; + float coarse_cfo_hz = 0.0f; + if (ssb_pss_search(q, in, nof_samples, &N_id_2, &t_offset, &coarse_cfo_hz) < SRSRAN_SUCCESS) { ERROR("Error searching for N_id_2"); return SRSRAN_ERROR; } @@ -871,9 +1022,14 @@ int srsran_ssb_csi_search(srsran_ssb_t* q, t_offset = 0; } + // Make sure SSB time offset is in bounded in the input buffer + if (t_offset + q->ssb_sz > nof_samples) { + return SRSRAN_SUCCESS; + } + // Demodulate cf_t ssb_grid[SRSRAN_SSB_NOF_RE] = {}; - if (ssb_demodulate(q, in, t_offset, ssb_grid) < SRSRAN_SUCCESS) { + if (ssb_demodulate(q, in, t_offset, coarse_cfo_hz, ssb_grid) < SRSRAN_SUCCESS) { ERROR("Error demodulating"); return SRSRAN_ERROR; } @@ -897,6 +1053,7 @@ int srsran_ssb_csi_search(srsran_ssb_t* q, // Add delay to measure meas->delay_us += (float)(1e6 * t_offset / q->cfg.srate_hz); + meas->cfo_hz -= coarse_cfo_hz; return SRSRAN_SUCCESS; } @@ -925,7 +1082,7 @@ int srsran_ssb_csi_measure(srsran_ssb_t* q, // Demodulate cf_t ssb_grid[SRSRAN_SSB_NOF_RE] = {}; - if (ssb_demodulate(q, in, (uint32_t)t_offset, ssb_grid) < SRSRAN_SUCCESS) { + if (ssb_demodulate(q, in, (uint32_t)t_offset, 0.0f, ssb_grid) < SRSRAN_SUCCESS) { ERROR("Error demodulating"); return SRSRAN_ERROR; } @@ -939,11 +1096,12 @@ int srsran_ssb_csi_measure(srsran_ssb_t* q, return SRSRAN_SUCCESS; } -static int ssb_select_pbch(srsran_ssb_t* q, - uint32_t N_id, - const cf_t ssb_grid[SRSRAN_SSB_NOF_RE], - uint32_t* found_n_hf, - uint32_t* found_ssb_idx_4lsb) +static int ssb_select_pbch(srsran_ssb_t* q, + uint32_t N_id, + const cf_t ssb_grid[SRSRAN_SSB_NOF_RE], + uint32_t* found_n_hf, + uint32_t* found_ssb_idx_4lsb, + srsran_dmrs_pbch_meas_t* pbch_meas) { // Prepare PBCH DMRS configuration srsran_dmrs_pbch_cfg_t pbch_dmrs_cfg = {}; @@ -985,6 +1143,7 @@ static int ssb_select_pbch(srsran_ssb_t* q, // Save findings *found_n_hf = best_n_hf; *found_ssb_idx_4lsb = best_ssb_idx; + *pbch_meas = best_meas; return SRSRAN_SUCCESS; } @@ -1029,6 +1188,46 @@ static int ssb_decode_pbch(srsran_ssb_t* q, return SRSRAN_SUCCESS; } +int srsran_ssb_decode_grid(srsran_ssb_t* q, + uint32_t N_id, + uint32_t n_hf, + uint32_t ssb_idx, + const cf_t* re_grid, + uint32_t grid_bw_sc, + srsran_pbch_msg_nr_t* msg) +{ + // Verify input parameters + if (q == NULL || N_id >= SRSRAN_NOF_NID_NR || msg == NULL || re_grid == NULL || grid_bw_sc < SRSRAN_SSB_BW_SUBC) { + return SRSRAN_ERROR_INVALID_INPUTS; + } + + if (!q->args.enable_encode) { + ERROR("SSB is not configured for encode"); + return SRSRAN_ERROR; + } + + // First symbol in the half frame + uint32_t l_first = q->l_first[ssb_idx]; + + // Frequency offset fom the bottom of the grid + uint32_t f_offset = grid_bw_sc / 2 + q->f_offset - SRSRAN_SSB_BW_SUBC / 2; + + // Get SSB grid from resource grid + cf_t ssb_grid[SRSRAN_SSB_NOF_RE] = {}; + for (uint32_t l = 0; l < SRSRAN_SSB_DURATION_NSYMB; l++) { + srsran_vec_cf_copy( + &ssb_grid[SRSRAN_SSB_BW_SUBC * l], &re_grid[grid_bw_sc * (l_first + l) + f_offset], SRSRAN_SSB_BW_SUBC); + } + + // Decode PBCH + if (ssb_decode_pbch(q, N_id, n_hf, ssb_idx, ssb_grid, msg) < SRSRAN_SUCCESS) { + ERROR("Error decoding"); + return SRSRAN_ERROR; + } + + return SRSRAN_SUCCESS; +} + int srsran_ssb_decode_pbch(srsran_ssb_t* q, uint32_t N_id, uint32_t n_hf, @@ -1054,7 +1253,7 @@ int srsran_ssb_decode_pbch(srsran_ssb_t* q, // Demodulate cf_t ssb_grid[SRSRAN_SSB_NOF_RE] = {}; - if (ssb_demodulate(q, in, (uint32_t)t_offset, ssb_grid) < SRSRAN_SUCCESS) { + if (ssb_demodulate(q, in, (uint32_t)t_offset, 0.0f, ssb_grid) < SRSRAN_SUCCESS) { ERROR("Error demodulating"); return SRSRAN_ERROR; } @@ -1082,10 +1281,14 @@ int srsran_ssb_search(srsran_ssb_t* q, const cf_t* in, uint32_t nof_samples, srs return SRSRAN_ERROR; } + // Set the SSB search result with default value with PBCH CRC unmatched, meaning no cell is found + SRSRAN_MEM_ZERO(res, srsran_ssb_search_res_t, 1); + // Search for PSS in time domain - uint32_t N_id_2 = 0; - uint32_t t_offset = 0; - if (ssb_pss_search(q, in, nof_samples, &N_id_2, &t_offset) < SRSRAN_SUCCESS) { + uint32_t N_id_2 = 0; + uint32_t t_offset = 0; + float coarse_cfo_hz = 0.0f; + if (ssb_pss_search(q, in, nof_samples, &N_id_2, &t_offset, &coarse_cfo_hz) < SRSRAN_SUCCESS) { ERROR("Error searching for N_id_2"); return SRSRAN_ERROR; } @@ -1097,9 +1300,14 @@ int srsran_ssb_search(srsran_ssb_t* q, const cf_t* in, uint32_t nof_samples, srs t_offset = 0; } + // Make sure SSB time offset is in bounded in the input buffer + if (t_offset + q->ssb_sz > nof_samples) { + return SRSRAN_SUCCESS; + } + // Demodulate cf_t ssb_grid[SRSRAN_SSB_NOF_RE] = {}; - if (ssb_demodulate(q, in, t_offset, ssb_grid) < SRSRAN_SUCCESS) { + if (ssb_demodulate(q, in, t_offset, coarse_cfo_hz, ssb_grid) < SRSRAN_SUCCESS) { ERROR("Error demodulating"); return SRSRAN_ERROR; } @@ -1116,24 +1324,44 @@ int srsran_ssb_search(srsran_ssb_t* q, const cf_t* in, uint32_t nof_samples, srs uint32_t N_id = SRSRAN_NID_NR(N_id_1, N_id_2); // Select the most suitable SSB candidate - uint32_t n_hf = 0; - uint32_t ssb_idx = 0; - if (ssb_select_pbch(q, N_id, ssb_grid, &n_hf, &ssb_idx) < SRSRAN_SUCCESS) { + uint32_t n_hf = 0; + uint32_t ssb_idx = 0; + srsran_dmrs_pbch_meas_t pbch_meas = {}; + if (ssb_select_pbch(q, N_id, ssb_grid, &n_hf, &ssb_idx, &pbch_meas) < SRSRAN_SUCCESS) { ERROR("Error selecting PBCH"); return SRSRAN_ERROR; } - // Compute PBCH channel estimates + // Avoid decoding if the selected PBCH DMRS do not reach the minimum threshold + if (pbch_meas.corr < q->args.pbch_dmrs_thr) { + return SRSRAN_SUCCESS; + } + + // Decode PBCH srsran_pbch_msg_nr_t pbch_msg = {}; if (ssb_decode_pbch(q, N_id, n_hf, ssb_idx, ssb_grid, &pbch_msg) < SRSRAN_SUCCESS) { ERROR("Error decoding PBCH"); return SRSRAN_ERROR; } + // If PBCH was not decoded, skip measurements + if (!pbch_msg.crc) { + return SRSRAN_SUCCESS; + } + + // Perform measurements from PSS and SSS + srsran_csi_trs_measurements_t measurements = {}; + if (ssb_measure(q, ssb_grid, N_id, &measurements) < SRSRAN_SUCCESS) { + ERROR("Error measuring"); + return SRSRAN_ERROR; + } + // Save result - res->N_id = N_id; - res->t_offset = t_offset; - res->pbch_msg = pbch_msg; + res->N_id = N_id; + res->t_offset = t_offset; + res->pbch_msg = pbch_msg; + res->measurements = measurements; + res->measurements.cfo_hz += coarse_cfo_hz; return SRSRAN_SUCCESS; } @@ -1183,6 +1411,8 @@ static int ssb_pss_find(srsran_ssb_t* q, const cf_t* in, uint32_t nof_samples, u // Average power, skip window if value is invalid (0.0, nan or inf) float avg_pwr_corr = srsran_vec_avg_power_cf(&q->tmp_time[peak_idx], q->symbol_sz); if (!isnormal(avg_pwr_corr)) { + // Advance time + t_offset += q->corr_window; continue; } @@ -1221,6 +1451,9 @@ int srsran_ssb_find(srsran_ssb_t* q, return SRSRAN_ERROR; } + // Set the PBCH message result with default value (CRC unmatched), meaning no cell is found + SRSRAN_MEM_ZERO(pbch_msg, srsran_pbch_msg_nr_t, 1); + // Copy tail from previous execution into the start of this srsran_vec_cf_copy(q->sf_buffer, &q->sf_buffer[q->sf_sz], q->ssb_sz); @@ -1241,9 +1474,14 @@ int srsran_ssb_find(srsran_ssb_t* q, t_offset = 0; } + // Make sure SSB time offset is in bounded in the input buffer + if (t_offset > q->sf_sz) { + return SRSRAN_SUCCESS; + } + // Demodulate cf_t ssb_grid[SRSRAN_SSB_NOF_RE] = {}; - if (ssb_demodulate(q, q->sf_buffer, t_offset, ssb_grid) < SRSRAN_SUCCESS) { + if (ssb_demodulate(q, q->sf_buffer, t_offset, 0.0f, ssb_grid) < SRSRAN_SUCCESS) { ERROR("Error demodulating"); return SRSRAN_ERROR; } @@ -1255,13 +1493,19 @@ int srsran_ssb_find(srsran_ssb_t* q, } // Select the most suitable SSB candidate - uint32_t n_hf = 0; - uint32_t ssb_idx = 0; // SSB candidate index - if (ssb_select_pbch(q, N_id, ssb_grid, &n_hf, &ssb_idx) < SRSRAN_SUCCESS) { + uint32_t n_hf = 0; + uint32_t ssb_idx = 0; // SSB candidate index + srsran_dmrs_pbch_meas_t pbch_meas = {}; + if (ssb_select_pbch(q, N_id, ssb_grid, &n_hf, &ssb_idx, &pbch_meas) < SRSRAN_SUCCESS) { ERROR("Error selecting PBCH"); return SRSRAN_ERROR; } + // Avoid decoding if the selected PBCH DMRS do not reach the minimum threshold + if (pbch_meas.corr < q->args.pbch_dmrs_thr) { + return SRSRAN_SUCCESS; + } + // Calculate the SSB offset in the subframe uint32_t ssb_offset = srsran_ssb_candidate_sf_offset(q, ssb_idx); @@ -1303,7 +1547,7 @@ int srsran_ssb_track(srsran_ssb_t* q, // Demodulate cf_t ssb_grid[SRSRAN_SSB_NOF_RE] = {}; - if (ssb_demodulate(q, sf_buffer, t_offset, ssb_grid) < SRSRAN_SUCCESS) { + if (ssb_demodulate(q, sf_buffer, t_offset, 0.0f, ssb_grid) < SRSRAN_SUCCESS) { ERROR("Error demodulating"); return SRSRAN_ERROR; } @@ -1347,3 +1591,25 @@ uint32_t srsran_ssb_candidate_sf_offset(const srsran_ssb_t* q, uint32_t ssb_idx) return cp_sz_0 + l * (q->symbol_sz + q->cp_sz); } + +uint32_t srsran_ssb_cfg_to_str(const srsran_ssb_cfg_t* cfg, char* str, uint32_t str_len) +{ + uint32_t n = 0; + + n = srsran_print_check(str, + str_len, + n, + "srate=%.2f MHz; c-freq=%.3f MHz; ss-freq=%.3f MHz; scs=%s; pattern=%s; duplex=%s;", + cfg->srate_hz / 1e6, + cfg->center_freq_hz / 1e6, + cfg->ssb_freq_hz / 1e6, + srsran_subcarrier_spacing_to_str(cfg->scs), + srsran_ssb_pattern_to_str(cfg->pattern), + cfg->duplex_mode == SRSRAN_DUPLEX_MODE_FDD ? "fdd" : "tdd"); + + if (cfg->periodicity_ms > 0) { + n = srsran_print_check(str, str_len, n, " period=%d ms;", cfg->periodicity_ms); + } + + return n; +} diff --git a/lib/src/phy/sync/sss.c b/lib/src/phy/sync/sss.c index 02b8272766..882099c9f1 100644 --- a/lib/src/phy/sync/sss.c +++ b/lib/src/phy/sync/sss.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/sss_nr.c b/lib/src/phy/sync/sss_nr.c index a5450b1465..21832e0001 100644 --- a/lib/src/phy/sync/sss_nr.c +++ b/lib/src/phy/sync/sss_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/ssss.c b/lib/src/phy/sync/ssss.c index d00075258d..bb653a1a2f 100644 --- a/lib/src/phy/sync/ssss.c +++ b/lib/src/phy/sync/ssss.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/sync.c b/lib/src/phy/sync/sync.c index 022185cb16..0ce454062a 100644 --- a/lib/src/phy/sync/sync.c +++ b/lib/src/phy/sync/sync.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -330,7 +330,7 @@ int srsran_sync_set_N_id_1(srsran_sync_t* q, uint32_t N_id_1) generate_freq_sss(q, N_id_1); return SRSRAN_SUCCESS; } else { - ERROR("Invalid N_id_2=%d", N_id_1); + ERROR("Invalid N_id_1=%d", N_id_1); return SRSRAN_ERROR_INVALID_INPUTS; } } diff --git a/lib/src/phy/sync/sync_nbiot.c b/lib/src/phy/sync/sync_nbiot.c index 603c8c585a..086a939f2f 100644 --- a/lib/src/phy/sync/sync_nbiot.c +++ b/lib/src/phy/sync/sync_nbiot.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/test/CMakeLists.txt b/lib/src/phy/sync/test/CMakeLists.txt index 331e7b4458..352de783dc 100644 --- a/lib/src/phy/sync/test/CMakeLists.txt +++ b/lib/src/phy/sync/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -95,13 +95,13 @@ add_executable(psss_file_test psss_file_test.c) target_link_libraries(psss_file_test srsran_phy) # SL TM 2 -add_test(sync_sl_test_tm2_p6_c_0 sync_sl_test -p 6 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p6_c0_s1.92e6.dat) -add_test(sync_sl_test_tm2_p15_c_84 sync_sl_test -p 15 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p15_c84_s3.84e6.dat) -add_test(sync_sl_test_tm2_p25_c_168 sync_sl_test -p 25 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p25_c168_s7.68e6.dat) -add_test(sync_sl_test_tm2_p50_c_252 sync_sl_test -p 50 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6.dat) -add_test(sync_sl_test_tm2_p100_c_335 sync_sl_test -p 100 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) +add_test(sync_sl_test_tm2_p6_c_0 sync_sl_test -p 6 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm2_p6_c0_s1.92e6.dat) +add_test(sync_sl_test_tm2_p15_c_84 sync_sl_test -p 15 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm2_p15_c84_s3.84e6.dat) +add_test(sync_sl_test_tm2_p25_c_168 sync_sl_test -p 25 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm2_p25_c168_s7.68e6.dat) +add_test(sync_sl_test_tm2_p50_c_252 sync_sl_test -p 50 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm2_p50_c252_s15.36e6.dat) +add_test(sync_sl_test_tm2_p100_c_335 sync_sl_test -p 100 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm2_p100_c335_s30.72e6.dat) # Sample offset -add_test(sync_sl_test_tm2_p25_c_168_so sync_sl_test -p 25 -d -o 300 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm2_p25_c168_s7.68e6.dat) +add_test(sync_sl_test_tm2_p25_c_168_so sync_sl_test -p 25 -d -o 300 -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm2_p25_c168_s7.68e6.dat) # Self-test add_test(sync_sl_test_tm2_self_test_p25_c_168 sync_sl_test -p 25 -c 168 -d) # Self-test with frequency offset @@ -110,13 +110,13 @@ add_test(sync_sl_test_tm2_self_test_p25_c_168_fo sync_sl_test -p 25 -c 168 -d -f add_test(sync_sl_test_tm2_self_test_p25_c_168_fo_so sync_sl_test -p 25 -c 168 -d -f 100 -o 3600) # SL TM 4 -add_test(sync_sl_test_tm4_p6_c_0 sync_sl_test -p 6 -t 4 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm4_p6_c0_size6_num1_cshift0_s1.92e6.dat) -add_test(sync_sl_test_tm4_p15_c_84 sync_sl_test -p 15 -t 4 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm4_p15_c84_size5_num3_cshift0_s3.84e6.dat) -add_test(sync_sl_test_tm4_p25_c_168 sync_sl_test -p 25 -t 4 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm4_p25_c168_size5_num5_cshift0_s7.68e6.dat) -add_test(sync_sl_test_tm4_p50_c_252 sync_sl_test -p 50 -t 4 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm4_p50_c252_size10_num5_cshift0_s15.36e6.dat) -#add_test(sync_sl_test_tm4_p100_c_335 sync_sl_test -p 100 -t 4 -d -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm4_p100_c335_size10_num10_cshift0_s30.72e6.dat) +add_test(sync_sl_test_tm4_p6_c_0 sync_sl_test -p 6 -t 4 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm4_p6_c0_size6_num1_cshift0_s1.92e6.dat) +add_test(sync_sl_test_tm4_p15_c_84 sync_sl_test -p 15 -t 4 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm4_p15_c84_size5_num3_cshift0_s3.84e6.dat) +add_test(sync_sl_test_tm4_p25_c_168 sync_sl_test -p 25 -t 4 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm4_p25_c168_size5_num5_cshift0_s7.68e6.dat) +add_test(sync_sl_test_tm4_p50_c_252 sync_sl_test -p 50 -t 4 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm4_p50_c252_size10_num5_cshift0_s15.36e6.dat) +#add_test(sync_sl_test_tm4_p100_c_335 sync_sl_test -p 100 -t 4 -d -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm4_p100_c335_size10_num10_cshift0_s30.72e6.dat) # Sample offset -add_test(sync_sl_test_tm4_p25_c_168_so sync_sl_test -p 25 -t 4 -d -o 300 -i ${CMAKE_HOME_DIRECTORY}/lib/src/phy/phch/test/signal_sidelink_ideal_tm4_p25_c168_size5_num5_cshift0_s7.68e6.dat ) +add_test(sync_sl_test_tm4_p25_c_168_so sync_sl_test -p 25 -t 4 -d -o 300 -i ${CMAKE_CURRENT_SOURCE_DIR}/../../phch/test/signal_sidelink_ideal_tm4_p25_c168_size5_num5_cshift0_s7.68e6.dat ) # Self-test add_test(sync_sl_test_self_test_tm4_p25_c_168 sync_sl_test -p 25 -t 4 -c 168 -d) # Self-test with frequency offset @@ -145,6 +145,9 @@ target_link_libraries(ssb_measure_test srsran_phy) add_executable(ssb_decode_test ssb_decode_test.c) target_link_libraries(ssb_decode_test srsran_phy) +add_executable(ssb_grid_test ssb_grid_test.c) +target_link_libraries(ssb_grid_test srsran_phy) + # For 1.0 GHz and 3.5 GHz Center frequencies foreach (CELL_FREQ 1000000 3500000) # For each supported Cell/Carrier subcarrier spacing @@ -165,6 +168,10 @@ foreach (CELL_FREQ 1000000 3500000) # Test SSB PBCH decoding add_nr_test(ssb_decode_test_${CELL_FREQ}000_${CELL_SCS}_${SSB_FREQ}000_${SSB_SCS}_${SSB_PATTERN} ssb_decode_test -F ${CELL_FREQ}000 -S ${CELL_SCS} -f ${SSB_FREQ}000 -s ${SSB_SCS} -P ${SSB_PATTERN}) + + # Test SSB grid put/get decoding + add_nr_test(ssb_grid_test_${CELL_FREQ}000_${CELL_SCS}_${SSB_FREQ}000_${SSB_SCS}_${SSB_PATTERN} ssb_grid_test + -F ${CELL_FREQ}000 -S ${CELL_SCS} -f ${SSB_FREQ}000 -s ${SSB_SCS} -P ${SSB_PATTERN}) endforeach () endforeach () endforeach () @@ -176,4 +183,6 @@ target_link_libraries(ssb_file_test srsran_phy) # File test 1 # Captured with command: lib/examples/usrp_capture -a type=x300,clock=external,sampling_rate=46.08e6,rx_subdev_spec=B:0 -g 20 -r 46.08e6 -n 460800 -f 3502.8e6 -o /tmp/n78.fo35028.fs2304M.data -add_nr_test(ssb_file_test ssb_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/n78.fo35028.fs4608M.data -v -r 46.08e6 -f 3502.8e6 -F 3512.64e6 -n 460800 -A 500 357802 2 0 1 0) +add_nr_test(ssb_file_test_tdd ssb_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/n78.fo35028.fs4608M.data -v -r 46.08e6 -f 3502.8e6 -F 3512.64e6 -n 460800 -A 500 357802 2 0 1 0) +# Capture with third-party gNB on band n3 (FDD) 15kHz SSB SCS, f_s=15.36e6, f_c=1842.5e6, f_c_ssb=1842.05e6, PCI=500 +add_nr_test(ssb_file_test_fdd ssb_file_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../../ue/test/ue_dl_nr_pci500_rb52_si_coreset0_idx6_s15.36e6.dat -v -r 15.36e6 -f 1842.5e6 -F 1842.05e6 -n 15360 -d fdd -s 15 -A 500 2200 0 0 0 0) diff --git a/lib/src/phy/sync/test/cfo_test.c b/lib/src/phy/sync/test/cfo_test.c index 446bdc8205..4c9a831413 100644 --- a/lib/src/phy/sync/test/cfo_test.c +++ b/lib/src/phy/sync/test/cfo_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/test/npss_file.c b/lib/src/phy/sync/test/npss_file.c index 35163ed7da..d7c5ad6382 100644 --- a/lib/src/phy/sync/test/npss_file.c +++ b/lib/src/phy/sync/test/npss_file.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/test/npss_test.c b/lib/src/phy/sync/test/npss_test.c index b1a5105dd1..6bb2c168d9 100644 --- a/lib/src/phy/sync/test/npss_test.c +++ b/lib/src/phy/sync/test/npss_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/test/npss_usrp.c b/lib/src/phy/sync/test/npss_usrp.c index 3fcf8f484c..3b5454b3bd 100644 --- a/lib/src/phy/sync/test/npss_usrp.c +++ b/lib/src/phy/sync/test/npss_usrp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/test/nsss_test.c b/lib/src/phy/sync/test/nsss_test.c index 4404baec36..4ecaa64087 100644 --- a/lib/src/phy/sync/test/nsss_test.c +++ b/lib/src/phy/sync/test/nsss_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/test/nsss_usrp.c b/lib/src/phy/sync/test/nsss_usrp.c index e8c3f32e31..748b127c43 100644 --- a/lib/src/phy/sync/test/nsss_usrp.c +++ b/lib/src/phy/sync/test/nsss_usrp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/test/pss_file.c b/lib/src/phy/sync/test/pss_file.c index f51878fba7..1f59860268 100644 --- a/lib/src/phy/sync/test/pss_file.c +++ b/lib/src/phy/sync/test/pss_file.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/test/pss_usrp.c b/lib/src/phy/sync/test/pss_usrp.c index 562f732e2c..998828398a 100644 --- a/lib/src/phy/sync/test/pss_usrp.c +++ b/lib/src/phy/sync/test/pss_usrp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/test/psss_file_test.c b/lib/src/phy/sync/test/psss_file_test.c index e0f19ab716..4e1938d474 100644 --- a/lib/src/phy/sync/test/psss_file_test.c +++ b/lib/src/phy/sync/test/psss_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/sync/test/ssb_decode_test.c b/lib/src/phy/sync/test/ssb_decode_test.c index 9fdf9032c5..f266d67c37 100644 --- a/lib/src/phy/sync/test/ssb_decode_test.c +++ b/lib/src/phy/sync/test/ssb_decode_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,13 +29,16 @@ #include #include +#define SSB_DECODE_TEST_PCI_STRIDE 53 +#define SSB_DECODE_TEST_SSB_STRIDE 3 + // NR parameters static uint32_t carrier_nof_prb = 52; static srsran_subcarrier_spacing_t carrier_scs = srsran_subcarrier_spacing_15kHz; static double carrier_freq_hz = 3.5e9 + 960e3; static srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_30kHz; static double ssb_freq_hz = 3.5e9; -static srsran_ssb_patern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; +static srsran_ssb_pattern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; // Channel parameters static cf_t wideband_gain = 1.0f + 0.5 * I; @@ -128,7 +131,7 @@ static void gen_pbch_msg(srsran_pbch_msg_nr_t* pbch_msg, uint32_t ssb_idx) pbch_msg->crc = true; } -static int test_case_1(srsran_ssb_t* ssb) +static int test_case_true(srsran_ssb_t* ssb) { // For benchmarking purposes uint64_t t_encode_usec = 0; @@ -147,8 +150,8 @@ static int test_case_1(srsran_ssb_t* ssb) // For each PCI... uint64_t count = 0; - for (uint32_t pci = 0; pci < SRSRAN_NOF_NID_NR; pci += 23) { - for (uint32_t ssb_idx = 0; ssb_idx < ssb->Lmax; ssb_idx++, count++) { + for (uint32_t pci = 0; pci < SRSRAN_NOF_NID_NR; pci += SSB_DECODE_TEST_PCI_STRIDE) { + for (uint32_t ssb_idx = 0; ssb_idx < ssb->Lmax; ssb_idx += SSB_DECODE_TEST_SSB_STRIDE, count++) { struct timeval t[3] = {}; // Build PBCH message @@ -158,7 +161,7 @@ static int test_case_1(srsran_ssb_t* ssb) // Print encoded PBCH message char str[512] = {}; srsran_pbch_msg_info(&pbch_msg_tx, str, sizeof(str)); - INFO("test_case_1 - encoded pci=%d %s", pci, str); + INFO("test_case_true - encoded pci=%d %s", pci, str); // Initialise baseband srsran_vec_cf_zero(buffer, hf_len); @@ -184,7 +187,7 @@ static int test_case_1(srsran_ssb_t* ssb) // Print decoded PBCH message srsran_pbch_msg_info(&pbch_msg_rx, str, sizeof(str)); - INFO("test_case_1 - decoded pci=%d %s crc=%s", pci, str, pbch_msg_rx.crc ? "OK" : "KO"); + INFO("test_case_true - decoded pci=%d %s crc=%s", pci, str, pbch_msg_rx.crc ? "OK" : "KO"); // Assert PBCH message CRC TESTASSERT(pbch_msg_rx.crc); @@ -200,7 +203,7 @@ static int test_case_1(srsran_ssb_t* ssb) // Print decoded PBCH message srsran_pbch_msg_info(&res.pbch_msg, str, sizeof(str)); - INFO("test_case_1 - found pci=%d %s crc=%s", res.N_id, str, res.pbch_msg.crc ? "OK" : "KO"); + INFO("test_case_true - found pci=%d %s crc=%s", res.N_id, str, res.pbch_msg.crc ? "OK" : "KO"); // Assert PBCH message CRC TESTASSERT(res.pbch_msg.crc); @@ -209,11 +212,11 @@ static int test_case_1(srsran_ssb_t* ssb) } if (!count) { - ERROR("Error in test case 1: undefined division"); + ERROR("Error in test case true: undefined division"); return SRSRAN_ERROR; } - INFO("test_case_1 - %.1f usec/encode; %.1f usec/decode; %.1f usec/decode;", + INFO("test_case_true - %.1f usec/encode; %.1f usec/decode; %.1f usec/decode;", (double)t_encode_usec / (double)(count), (double)t_decode_usec / (double)(count), (double)t_search_usec / (double)(count)); @@ -221,6 +224,77 @@ static int test_case_1(srsran_ssb_t* ssb) return SRSRAN_SUCCESS; } +static int test_case_false(srsran_ssb_t* ssb) +{ + // For benchmarking purposes + uint64_t t_decode_usec = 0; + uint64_t t_search_usec = 0; + + // SSB configuration + srsran_ssb_cfg_t ssb_cfg = {}; + ssb_cfg.srate_hz = srate_hz; + ssb_cfg.center_freq_hz = carrier_freq_hz; + ssb_cfg.ssb_freq_hz = ssb_freq_hz; + ssb_cfg.scs = ssb_scs; + ssb_cfg.pattern = ssb_pattern; + + TESTASSERT(srsran_ssb_set_cfg(ssb, &ssb_cfg) == SRSRAN_SUCCESS); + + // For each PCI... + uint32_t count = 0; + for (uint32_t pci = 0; pci < SRSRAN_NOF_NID_NR; pci += SSB_DECODE_TEST_PCI_STRIDE, count++) { + struct timeval t[3] = {}; + + // Initialise baseband + srsran_vec_cf_zero(buffer, hf_len); + + // Channel, as it is zero it only adds noise + srsran_channel_awgn_run_c(&awgn, buffer, buffer, hf_len); + + // Decode + gettimeofday(&t[1], NULL); + srsran_pbch_msg_nr_t pbch_msg_rx = {}; + TESTASSERT(srsran_ssb_decode_pbch(ssb, pci, false, 0, buffer, &pbch_msg_rx) == SRSRAN_SUCCESS); + gettimeofday(&t[2], NULL); + get_time_interval(t); + t_decode_usec += t[0].tv_usec + t[0].tv_sec * 1000000UL; + + // Print decoded PBCH message + char str[512] = {}; + srsran_pbch_msg_info(&pbch_msg_rx, str, sizeof(str)); + INFO("test_case_false - decoded pci=%d %s crc=%s", pci, str, pbch_msg_rx.crc ? "OK" : "KO"); + + // Assert PBCH message CRC is not okay + TESTASSERT(!pbch_msg_rx.crc); + + // Search + srsran_ssb_search_res_t res = {}; + gettimeofday(&t[1], NULL); + TESTASSERT(srsran_ssb_search(ssb, buffer, hf_len, &res) == SRSRAN_SUCCESS); + gettimeofday(&t[2], NULL); + get_time_interval(t); + t_search_usec += t[0].tv_usec + t[0].tv_sec * 1000000UL; + + // Print decoded PBCH message + srsran_pbch_msg_info(&res.pbch_msg, str, sizeof(str)); + INFO("test_case_false - false found pci=%d %s crc=%s", res.N_id, str, res.pbch_msg.crc ? "OK" : "KO"); + + // Assert PBCH message CRC + TESTASSERT(!res.pbch_msg.crc); + } + + if (!count) { + ERROR("Error in test case true: undefined division"); + return SRSRAN_ERROR; + } + + INFO("test_case_false - %.1f usec/decode; %.1f usec/decode;", + (double)t_decode_usec / (double)(count), + (double)t_search_usec / (double)(count)); + + return SRSRAN_SUCCESS; +} + int main(int argc, char** argv) { int ret = SRSRAN_ERROR; @@ -257,7 +331,12 @@ int main(int argc, char** argv) goto clean_exit; } - if (test_case_1(&ssb) != SRSRAN_SUCCESS) { + if (test_case_true(&ssb) != SRSRAN_SUCCESS) { + ERROR("test case failed"); + goto clean_exit; + } + + if (test_case_false(&ssb) != SRSRAN_SUCCESS) { ERROR("test case failed"); goto clean_exit; } diff --git a/lib/src/phy/sync/test/ssb_file_test.c b/lib/src/phy/sync/test/ssb_file_test.c index de34c90a90..e853498c4d 100644 --- a/lib/src/phy/sync/test/ssb_file_test.c +++ b/lib/src/phy/sync/test/ssb_file_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,7 +29,7 @@ #include // NR parameters -static srsran_ssb_patern_t ssb_pattern = SRSRAN_SSB_PATTERN_C; +static srsran_ssb_pattern_t ssb_pattern = SRSRAN_SSB_PATTERN_C; static srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_30kHz; static srsran_duplex_mode_t duplex_mode = SRSRAN_DUPLEX_MODE_TDD; @@ -38,7 +38,7 @@ static char* filename = NULL; static double srate_hz = 23.04e6; // Base-band sampling rate in Hz static double center_freq_hz = NAN; // Center frequency in Hz static double ssb_freq_hz = NAN; // SSB frequency in Hz -static uint32_t nof_samples = 0; // Number of half-frames +static uint32_t nof_samples = 0; // Number of samples // Assertion static bool assert = false; @@ -53,9 +53,11 @@ static void usage(char* prog) { printf("Usage: %s -i filename [rv]\n", prog); printf("\t-r sampling rate in Hz [Default %.2f MHz]\n", srate_hz / 1e6); + printf("\t-n number of samples [Default %d]\n", nof_samples); + printf("\t-s SSB subcarrier spacing (15, 30) [Default %s]\n", srsran_subcarrier_spacing_to_str(ssb_scs)); + printf("\t-d duplex mode [Default %s]\n", duplex_mode == SRSRAN_DUPLEX_MODE_FDD ? "FDD" : "TDD"); printf("\t-f absolute baseband center frequency in Hz [Default %.2f MHz]\n", center_freq_hz / 1e3); printf("\t-F absolute SSB center freuqency in Hz [Default %.2f MHz]\n", ssb_freq_hz / 1e3); - printf("\t-F absolute SSB center freuqency in Hz [Default %.2f MHz]\n", ssb_freq_hz / 1e3); printf("\t-A Assert: PCI t_offset sfn_lsb ssb_idx ssb_k hrf"); printf("\t-v [set srsran_verbose to debug, default none]\n"); } @@ -63,7 +65,7 @@ static void usage(char* prog) static void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "inrfFAv")) != -1) { + while ((opt = getopt(argc, argv, "insdrfFAv")) != -1) { switch (opt) { case 'i': filename = argv[optind]; @@ -71,6 +73,24 @@ static void parse_args(int argc, char** argv) case 'n': nof_samples = (uint32_t)strtol(argv[optind], NULL, 10); break; + case 's': + if ((uint32_t)strtol(argv[optind], NULL, 10) == 15) { + ssb_scs = srsran_subcarrier_spacing_15kHz; + } else { + ssb_scs = srsran_subcarrier_spacing_30kHz; + } + break; + case 'd': + if (strcmp(argv[optind], "tdd") == 0) { + duplex_mode = SRSRAN_DUPLEX_MODE_TDD; + } else if (strcmp(argv[optind], "fdd") == 0) { + duplex_mode = SRSRAN_DUPLEX_MODE_FDD; + } else { + printf("Invalid duplex mode '%s'\n", argv[optind]); + usage(argv[0]); + exit(-1); + } + break; case 'r': srate_hz = strtod(argv[optind], NULL); break; @@ -204,6 +224,17 @@ int main(int argc, char** argv) str, search_res.pbch_msg.crc ? "OK" : "KO"); + // unpack MIB + srsran_mib_nr_t mib = {}; + if (srsran_pbch_msg_nr_mib_unpack(&search_res.pbch_msg, &mib) < SRSRAN_SUCCESS) { + ERROR("Error unpacking PBCH-MIB"); + goto clean_exit; + } + + char mib_info[512] = {}; + srsran_pbch_msg_nr_mib_info(&mib, mib_info, sizeof(mib_info)); + INFO("PBCH-MIB: %s", mib_info); + // Assert search if (assert) { if (assert_search(&search_res)) { diff --git a/lib/src/phy/sync/test/ssb_grid_test.c b/lib/src/phy/sync/test/ssb_grid_test.c new file mode 100644 index 0000000000..49400239be --- /dev/null +++ b/lib/src/phy/sync/test/ssb_grid_test.c @@ -0,0 +1,189 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/common/test_common.h" +#include "srsran/phy/channel/ch_awgn.h" +#include "srsran/phy/sync/ssb.h" +#include "srsran/phy/utils/debug.h" +#include "srsran/phy/utils/vector.h" +#include +#include +#include +#include + +// NR parameters +static srsran_subcarrier_spacing_t carrier_scs = srsran_subcarrier_spacing_15kHz; +static double carrier_freq_hz = 3.5e9 + 960e3; +static srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_30kHz; +static double ssb_freq_hz = 3.5e9; +static srsran_ssb_pattern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; +static uint32_t ssb_idx = 0; // SSB candidate index to test +static uint32_t pci = 123; // N_id + +// Test context +static srsran_random_t random_gen = NULL; +static double srate_hz = 0.0f; // Base-band sampling rate +static cf_t* grid = NULL; // Resource grid +static uint32_t grid_bw_sc = 52 * SRSRAN_NRE; // Resource grid bandwidth in subcarriers + +static void usage(char* prog) +{ + printf("Usage: %s [v]\n", prog); + printf("\t-s SSB subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(ssb_scs)); + printf("\t-f SSB center frequency [default, %.3f MHz]\n", ssb_freq_hz / 1e6); + printf("\t-S cell/carrier subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(carrier_scs)); + printf("\t-F cell/carrier center frequency in Hz [default, %.3f MHz]\n", carrier_freq_hz / 1e6); + printf("\t-P SSB pattern [default, %s]\n", srsran_ssb_pattern_to_str(ssb_pattern)); + printf("\t-v [set srsran_verbose to debug, default none]\n"); +} + +static void parse_args(int argc, char** argv) +{ + int opt; + while ((opt = getopt(argc, argv, "SsFfPv")) != -1) { + switch (opt) { + case 's': + ssb_scs = srsran_subcarrier_spacing_from_str(argv[optind]); + if (ssb_scs == srsran_subcarrier_spacing_invalid) { + ERROR("Invalid SSB subcarrier spacing %s\n", argv[optind]); + exit(-1); + } + break; + case 'f': + ssb_freq_hz = strtod(argv[optind], NULL); + break; + case 'S': + carrier_scs = srsran_subcarrier_spacing_from_str(argv[optind]); + if (carrier_scs == srsran_subcarrier_spacing_invalid) { + ERROR("Invalid Cell/Carrier subcarrier spacing %s\n", argv[optind]); + exit(-1); + } + break; + case 'F': + carrier_freq_hz = strtod(argv[optind], NULL); + break; + case 'P': + ssb_pattern = srsran_ssb_pattern_fom_str(argv[optind]); + break; + case 'v': + increase_srsran_verbose_level(); + break; + default: + usage(argv[0]); + exit(-1); + } + } +} + +static void gen_pbch_msg(srsran_pbch_msg_nr_t* pbch_msg) +{ + // Default all to zero + SRSRAN_MEM_ZERO(pbch_msg, srsran_pbch_msg_nr_t, 1); + + // Generate payload + srsran_random_bit_vector(random_gen, pbch_msg->payload, SRSRAN_PBCH_MSG_NR_SZ); + + pbch_msg->ssb_idx = ssb_idx; + pbch_msg->crc = true; +} + +static int test_case(srsran_ssb_t* ssb) +{ + // SSB configuration + srsran_ssb_cfg_t ssb_cfg = {}; + ssb_cfg.srate_hz = srate_hz; + ssb_cfg.center_freq_hz = carrier_freq_hz; + ssb_cfg.ssb_freq_hz = ssb_freq_hz; + ssb_cfg.scs = ssb_scs; + ssb_cfg.pattern = ssb_pattern; + + TESTASSERT(srsran_ssb_set_cfg(ssb, &ssb_cfg) == SRSRAN_SUCCESS); + + // Build PBCH message + srsran_pbch_msg_nr_t pbch_msg_tx = {}; + gen_pbch_msg(&pbch_msg_tx); + + // Print encoded PBCH message + char str[512] = {}; + srsran_pbch_msg_info(&pbch_msg_tx, str, sizeof(str)); + INFO("test_case - encoded pci=%d %s", pci, str); + + // Add the SSB base-band + TESTASSERT(srsran_ssb_put_grid(ssb, pci, &pbch_msg_tx, grid, grid_bw_sc) == SRSRAN_SUCCESS); + + // Decode + srsran_pbch_msg_nr_t pbch_msg_rx = {}; + TESTASSERT(srsran_ssb_decode_grid(ssb, pci, pbch_msg_tx.hrf, pbch_msg_tx.ssb_idx, grid, grid_bw_sc, &pbch_msg_rx) == + SRSRAN_SUCCESS); + + // Print decoded PBCH message + srsran_pbch_msg_info(&pbch_msg_rx, str, sizeof(str)); + INFO("test_case - decoded pci=%d %s crc=%s", pci, str, pbch_msg_rx.crc ? "OK" : "KO"); + + // Assert PBCH message CRC + TESTASSERT(pbch_msg_rx.crc); + TESTASSERT(memcmp(&pbch_msg_rx, &pbch_msg_tx, sizeof(srsran_pbch_msg_nr_t)) == 0); + + return SRSRAN_SUCCESS; +} + +int main(int argc, char** argv) +{ + int ret = SRSRAN_ERROR; + parse_args(argc, argv); + + random_gen = srsran_random_init(1234); + srate_hz = (double)SRSRAN_SUBC_SPACING_NR(carrier_scs) * srsran_min_symbol_sz_rb(grid_bw_sc / SRSRAN_NRE); + grid = srsran_vec_cf_malloc(grid_bw_sc * SRSRAN_NSYMB_PER_SLOT_NR); + + srsran_ssb_t ssb = {}; + srsran_ssb_args_t ssb_args = {}; + ssb_args.enable_encode = true; + ssb_args.enable_decode = true; + ssb_args.enable_search = true; + + if (grid == NULL) { + ERROR("Malloc"); + goto clean_exit; + } + + if (srsran_ssb_init(&ssb, &ssb_args) < SRSRAN_SUCCESS) { + ERROR("Init"); + goto clean_exit; + } + + if (test_case(&ssb) != SRSRAN_SUCCESS) { + ERROR("test case failed"); + goto clean_exit; + } + + ret = SRSRAN_SUCCESS; + +clean_exit: + srsran_random_free(random_gen); + srsran_ssb_free(&ssb); + + if (grid) { + free(grid); + } + + return ret; +} \ No newline at end of file diff --git a/lib/src/phy/sync/test/ssb_measure_test.c b/lib/src/phy/sync/test/ssb_measure_test.c index d8acadbc71..7fdb39dc37 100644 --- a/lib/src/phy/sync/test/ssb_measure_test.c +++ b/lib/src/phy/sync/test/ssb_measure_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -33,7 +33,7 @@ static srsran_subcarrier_spacing_t carrier_scs = srsran_subcarrier_spacing_1 static double carrier_freq_hz = 3.5e9 + 960e3; static srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_30kHz; static double ssb_freq_hz = 3.5e9; -static srsran_ssb_patern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; +static srsran_ssb_pattern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; // Channel parameters static int32_t delay_n = 2; diff --git a/lib/src/phy/sync/test/sync_nbiot_test.c b/lib/src/phy/sync/test/sync_nbiot_test.c index 40c3838410..ff46977175 100644 --- a/lib/src/phy/sync/test/sync_nbiot_test.c +++ b/lib/src/phy/sync/test/sync_nbiot_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -184,8 +184,8 @@ int main(int argc, char** argv) if (snr != -1.0) { snr -= 10.0; printf("Adding AWGN with target SNR: %.2fdB\n", snr); - float nstd = srsran_convert_dB_to_amplitude(-snr); - srsran_ch_awgn_c(fft_buffer, fft_buffer, nstd, SFLEN); + float var = srsran_convert_dB_to_power(-snr); + srsran_ch_awgn_c(fft_buffer, fft_buffer, var, SFLEN); } // look for NPSS signal diff --git a/lib/src/phy/sync/test/sync_sl_test.c b/lib/src/phy/sync/test/sync_sl_test.c index 4754c2e597..51c28e7089 100644 --- a/lib/src/phy/sync/test/sync_sl_test.c +++ b/lib/src/phy/sync/test/sync_sl_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -175,8 +175,8 @@ int main(int argc, char** argv) // ADD CHANNEL NOISE if (snr < 50) { - float std_dev = powf(10.0f, -(snr + 3.0f) / 20.0f); - srsran_ch_awgn_c(output_buffer, output_buffer, std_dev, output_buffer_len); + float var = srsran_convert_dB_to_power(-snr); + srsran_ch_awgn_c(output_buffer, output_buffer, var, output_buffer_len); } // ADD FREQUENCY OFFSET diff --git a/lib/src/phy/sync/test/sync_test.c b/lib/src/phy/sync/test/sync_test.c index 4deedd76a6..d6d5aa6505 100644 --- a/lib/src/phy/sync/test/sync_test.c +++ b/lib/src/phy/sync/test/sync_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/CMakeLists.txt b/lib/src/phy/ue/CMakeLists.txt index c50dfad0c6..1f01a4a514 100644 --- a/lib/src/phy/ue/CMakeLists.txt +++ b/lib/src/phy/ue/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/ue/test/CMakeLists.txt b/lib/src/phy/ue/test/CMakeLists.txt index 7c6c43959c..66fbe47c46 100644 --- a/lib/src/phy/ue/test/CMakeLists.txt +++ b/lib/src/phy/ue/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -56,14 +56,18 @@ if(RF_FOUND) endif(SRSGUI_FOUND) endif(RF_FOUND) -add_executable(ue_dl_nr_file_test ue_dl_nr_file_test.c) -target_link_libraries(ue_dl_nr_file_test srsran_phy pthread) +add_executable(ue_dl_nr_file_test ue_dl_nr_file_test.cc) +target_link_libraries(ue_dl_nr_file_test srsran_phy srsran_common pthread) foreach (n RANGE 0 9) - add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234) - add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234) - add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234) - add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234) - add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234) - add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234) + #add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234 -l 2) + #add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234 -l 2) + #add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234 -l 2) + #add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234 -l 2) + #add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234 -l 2) + #add_test(ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci1_rb25_n${n}_common_L1_ncce0.dat -i 1 -P 25 -n ${n} -R 1234 -l 2) endforeach () -add_test(ue_dl_nr_pci500_rb52_n4_ra_L2_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci500_rb52_n4_ra_L2_ncce0.dat -i 1 -P 52 -n 4 -R 7f) +#add_test(ue_dl_nr_pci500_rb52_n4_ra_L2_ncce0 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci500_rb52_n4_ra_L2_ncce0.dat -i 1 -P 52 -n 4 -R 7f) +add_test(ue_dl_nr_pci500_rb52_si_coreset0_idx6 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci500_rb52_si_coreset0_idx6_s15.36e6.dat -S -i 500 -P 52 -n 0 -R ffff -T si -c 6 -s common0 -A 368500 -a 368410) +#add_test(ue_dl_nr_pci500_rb52_si_coreset0_idx7 ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci500_rb52_si_coreset0_idx7_s15.36e6.dat -S -i 500 -P 52 -n 0 -R ffff -T si -c 7 -s common0 -A 161200 -a 161290) +add_test(ue_dl_nr_pci500_rb52_pdsch ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci500_rb52_rnti0x100_s15.36e6.dat -S -i 500 -P 52 -N 48 -n 1 -R 0x100 -T c -s common3 -o 1 -A 368500 -a 368410 -I -t 1 13) +add_test(ue_dl_nr_pci500_rb52_rar ue_dl_nr_file_test -f ${CMAKE_CURRENT_SOURCE_DIR}/ue_dl_nr_pci500_rb52_rar_s15.36e6.dat -i 500 -P 52 -n 5 -R f -T ra -c 6 -S -s common1 -A 368500 -a 368410) diff --git a/lib/src/phy/ue/test/gen_ack_nr_test.c b/lib/src/phy/ue/test/gen_ack_nr_test.c index 71316c9488..ee06bfe1a4 100644 --- a/lib/src/phy/ue/test/gen_ack_nr_test.c +++ b/lib/src/phy/ue/test/gen_ack_nr_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/test/gen_ack_test.c b/lib/src/phy/ue/test/gen_ack_test.c index dc24ba0438..6975f9fff6 100644 --- a/lib/src/phy/ue/test/gen_ack_test.c +++ b/lib/src/phy/ue/test/gen_ack_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -47,7 +47,7 @@ int fdd_tests(uint32_t max_cc) ue_dl.cell.frame_type = SRSRAN_FDD; for (uint32_t nof_cc = 1; nof_cc <= max_cc; nof_cc++) { - for (uint32_t nof_tb = 1; nof_tb <= SRSRAN_MAX_CODEWORDS; nof_tb++) { + for (uint8_t nof_tb = 1; nof_tb <= SRSRAN_MAX_CODEWORDS; nof_tb++) { for (uint32_t nof_active_cc = 1; nof_active_cc <= nof_cc; nof_active_cc++) { for (uint32_t nof_active_tb = 1; nof_active_tb <= nof_tb; nof_active_tb++) { srsran_pdsch_ack_t ack_info = {}; @@ -62,7 +62,7 @@ int fdd_tests(uint32_t max_cc) ack_info.cc[cc_idx].m[0].present = cc_idx < nof_active_cc; ack_info.cc[cc_idx].m[0].resource.n_cce = cc_idx + 1; if (ack_info.cc[cc_idx].m[0].present) { - for (uint32_t j = 0; j < nof_tb; j++) { + for (uint8_t j = 0; j < nof_tb; j++) { ack_info.cc[cc_idx].m[0].value[j] = j < nof_active_tb ? 1 : 2; } } else { diff --git a/lib/src/phy/ue/test/pucch_resource_test.c b/lib/src/phy/ue/test/pucch_resource_test.c index 1e9545eb93..fe5448dcb9 100644 --- a/lib/src/phy/ue/test/pucch_resource_test.c +++ b/lib/src/phy/ue/test/pucch_resource_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/test/ue_dl_nbiot_test.c b/lib/src/phy/ue/test/ue_dl_nbiot_test.c index 7a61bb3fc4..d7ac3773a8 100644 --- a/lib/src/phy/ue/test/ue_dl_nbiot_test.c +++ b/lib/src/phy/ue/test/ue_dl_nbiot_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/test/ue_dl_nr_file_test.c b/lib/src/phy/ue/test/ue_dl_nr_file_test.c deleted file mode 100644 index f52c53cf73..0000000000 --- a/lib/src/phy/ue/test/ue_dl_nr_file_test.c +++ /dev/null @@ -1,287 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsran/phy/io/filesource.h" -#include "srsran/phy/phch/ra_nr.h" -#include "srsran/phy/ue/ue_dl_nr.h" -#include "srsran/phy/utils/debug.h" -#include - -static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR; - -static char* filename = NULL; -static srsran_pdcch_cfg_nr_t pdcch_cfg = {}; -static srsran_sch_hl_cfg_nr_t pdsch_hl_cfg = {}; -static uint16_t rnti = 0x1234; -static srsran_rnti_type_t rnti_type = srsran_rnti_type_c; -static srsran_slot_cfg_t slot_cfg = {}; - -static srsran_softbuffer_rx_t softbuffer = {}; -static uint8_t* data = NULL; - -static void usage(char* prog) -{ - printf("Usage: %s [pTLR] \n", prog); - printf("\t-f File name [Default none]\n"); - printf("\t-P Number of BWP (Carrier) PRB [Default %d]\n", carrier.nof_prb); - printf("\t-i Physical cell identifier [Default %d]\n", carrier.pci); - printf("\t-n Slot index [Default %d]\n", slot_cfg.idx); - printf("\t-R RNTI in hexadecimal [Default 0x%x]\n", rnti); - printf("\t-T RNTI type (c, ra) [Default %s]\n", srsran_rnti_type_str(rnti_type)); - printf("\t-S Use standard rates [Default %s]\n", srsran_symbol_size_is_standard() ? "yes" : "no"); - - printf("\t-v [set srsran_verbose to debug, default none]\n"); -} - -static int parse_args(int argc, char** argv) -{ - int opt; - while ((opt = getopt(argc, argv, "fPivnSRT")) != -1) { - switch (opt) { - case 'f': - filename = argv[optind]; - break; - case 'P': - carrier.nof_prb = (uint32_t)strtol(argv[optind], NULL, 10); - break; - case 'i': - carrier.pci = (uint32_t)strtol(argv[optind], NULL, 10); - break; - case 'v': - increase_srsran_verbose_level(); - break; - case 'n': - slot_cfg.idx = (uint32_t)strtol(argv[optind], NULL, 10); - break; - case 'R': - rnti = (uint16_t)strtol(argv[optind], NULL, 16); - break; - case 'T': - if (strcmp(argv[optind], "c") == 0) { - rnti_type = srsran_rnti_type_c; - } else if (strcmp(argv[optind], "ra") == 0) { - rnti_type = srsran_rnti_type_ra; - } else { - printf("Invalid RNTI type '%s'\n", argv[optind]); - usage(argv[0]); - return SRSRAN_ERROR; - } - break; - case 'S': - srsran_use_standard_symbol_size(true); - break; - default: - usage(argv[0]); - return SRSRAN_ERROR; - } - } - - return SRSRAN_SUCCESS; -} - -static int work_ue_dl(srsran_ue_dl_nr_t* ue_dl, srsran_slot_cfg_t* slot) -{ - // Run FFT - srsran_ue_dl_nr_estimate_fft(ue_dl, slot); - - // Blind search - srsran_dci_dl_nr_t dci_dl_rx = {}; - int nof_found_dci = srsran_ue_dl_nr_find_dl_dci(ue_dl, slot, rnti, rnti_type, &dci_dl_rx, 1); - if (nof_found_dci < SRSRAN_SUCCESS) { - ERROR("Error in blind search"); - return SRSRAN_ERROR; - } - - // Print PDCCH blind search candidates - for (uint32_t i = 0; i < ue_dl->pdcch_info_count; i++) { - const srsran_ue_dl_nr_pdcch_info_t* info = &ue_dl->pdcch_info[i]; - INFO("PDCCH: %s-rnti=0x%x, crst_id=%d, ss_type=%s, ncce=%d, al=%d, EPRE=%+.2f, RSRP=%+.2f, corr=%.3f; " - "nof_bits=%d; crc=%s;", - srsran_rnti_type_str_short(info->dci_ctx.rnti_type), - info->dci_ctx.rnti, - info->dci_ctx.coreset_id, - srsran_ss_type_str(info->dci_ctx.ss_type), - info->dci_ctx.location.ncce, - info->dci_ctx.location.L, - info->measure.epre_dBfs, - info->measure.rsrp_dBfs, - info->measure.norm_corr, - info->nof_bits, - info->result.crc ? "OK" : "KO"); - } - - if (nof_found_dci < 1) { - printf("No DCI found :'(\n"); - return SRSRAN_SUCCESS; - } - - char str[1024] = {}; - srsran_dci_dl_nr_to_str(&ue_dl->dci, &dci_dl_rx, str, (uint32_t)sizeof(str)); - printf("Found DCI: %s\n", str); - - // Convert DCI to PDSCH transmission - srsran_sch_cfg_nr_t pdsch_cfg = {}; - if (srsran_ra_dl_dci_to_grant_nr(&carrier, slot, &pdsch_hl_cfg, &dci_dl_rx, &pdsch_cfg, &pdsch_cfg.grant) < - SRSRAN_SUCCESS) { - ERROR("Error decoding PDSCH search"); - return SRSRAN_ERROR; - } - - srsran_sch_cfg_nr_info(&pdsch_cfg, str, (uint32_t)sizeof(str)); - printf("PDSCH: %s\n", str); - - // Set softbuffer - pdsch_cfg.grant.tb[0].softbuffer.rx = &softbuffer; - - // Prepare PDSCH result - srsran_pdsch_res_nr_t pdsch_res = {}; - pdsch_res.tb[0].payload = data; - - // Decode PDSCH - if (srsran_ue_dl_nr_decode_pdsch(ue_dl, slot, &pdsch_cfg, &pdsch_res) < SRSRAN_SUCCESS) { - ERROR("Error decoding PDSCH search"); - return SRSRAN_ERROR; - } - - return SRSRAN_SUCCESS; -} - -int main(int argc, char** argv) -{ - int ret = SRSRAN_ERROR; - srsran_ue_dl_nr_t ue_dl = {}; - cf_t* buffer[SRSRAN_MAX_PORTS] = {}; - - uint32_t sf_len = SRSRAN_SF_LEN_PRB(carrier.nof_prb); - buffer[0] = srsran_vec_cf_malloc(sf_len); - if (buffer[0] == NULL) { - ERROR("Error malloc"); - goto clean_exit; - } - - if (srsran_softbuffer_rx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < - SRSRAN_SUCCESS) { - ERROR("Error init soft-buffer"); - goto clean_exit; - } - - data = srsran_vec_u8_malloc(SRSRAN_SLOT_MAX_NOF_BITS_NR); - if (data == NULL) { - ERROR("Error malloc"); - goto clean_exit; - } - - srsran_ue_dl_nr_args_t ue_dl_args = {}; - ue_dl_args.nof_rx_antennas = 1; - ue_dl_args.pdsch.sch.disable_simd = false; - ue_dl_args.pdsch.sch.decoder_use_flooded = false; - ue_dl_args.pdsch.measure_evm = true; - ue_dl_args.pdcch.disable_simd = false; - ue_dl_args.pdcch.measure_evm = true; - ue_dl_args.nof_max_prb = carrier.nof_prb; - - // Set default PDSCH configuration - if (parse_args(argc, argv) < SRSRAN_SUCCESS) { - goto clean_exit; - } - - // Check for filename - if (filename == NULL) { - ERROR("Filename was not provided"); - goto clean_exit; - } - - // Open filesource - srsran_filesource_t filesource = {}; - if (srsran_filesource_init(&filesource, filename, SRSRAN_COMPLEX_FLOAT_BIN) < SRSRAN_SUCCESS) { - ERROR("Error opening filesource"); - goto clean_exit; - } - - // Configure CORESET - srsran_coreset_t* coreset = &pdcch_cfg.coreset[1]; - pdcch_cfg.coreset_present[1] = true; - coreset->duration = 2; - for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { - coreset->freq_resources[i] = i < carrier.nof_prb / 6; - } - - // Configure Search Space - srsran_search_space_t* search_space = &pdcch_cfg.search_space[0]; - pdcch_cfg.search_space_present[0] = true; - search_space->id = 0; - search_space->coreset_id = 1; - search_space->type = srsran_search_space_type_common_3; - search_space->formats[0] = srsran_dci_format_nr_0_0; - search_space->formats[1] = srsran_dci_format_nr_1_0; - search_space->nof_formats = 2; - for (uint32_t L = 0; L < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) { - search_space->nof_candidates[L] = srsran_pdcch_nr_max_candidates_coreset(coreset, L); - } - - // Configure RA search space - pdcch_cfg.ra_search_space_present = true; - pdcch_cfg.ra_search_space = *search_space; - pdcch_cfg.ra_search_space.type = srsran_search_space_type_common_1; - - if (srsran_ue_dl_nr_init(&ue_dl, buffer, &ue_dl_args)) { - ERROR("Error UE DL"); - goto clean_exit; - } - - if (srsran_ue_dl_nr_set_carrier(&ue_dl, &carrier)) { - ERROR("Error setting SCH NR carrier"); - goto clean_exit; - } - - // Read baseband from file - if (srsran_filesource_read(&filesource, buffer[0], (int)ue_dl.fft->sf_sz) < SRSRAN_SUCCESS) { - ERROR("Error reading baseband"); - goto clean_exit; - } - - srsran_dci_cfg_nr_t dci_cfg = {}; - dci_cfg.bwp_dl_initial_bw = carrier.nof_prb; - dci_cfg.bwp_ul_initial_bw = carrier.nof_prb; - dci_cfg.monitor_common_0_0 = true; - if (srsran_ue_dl_nr_set_pdcch_config(&ue_dl, &pdcch_cfg, &dci_cfg)) { - ERROR("Error setting CORESET"); - goto clean_exit; - } - - // Actual decode - work_ue_dl(&ue_dl, &slot_cfg); - - ret = SRSRAN_SUCCESS; - -clean_exit: - if (buffer[0] != NULL) { - free(buffer[0]); - } - if (data != NULL) { - free(data); - } - srsran_ue_dl_nr_free(&ue_dl); - srsran_filesource_free(&filesource); - srsran_softbuffer_rx_free(&softbuffer); - - return ret; -} diff --git a/lib/src/phy/ue/test/ue_dl_nr_file_test.cc b/lib/src/phy/ue/test/ue_dl_nr_file_test.cc new file mode 100644 index 0000000000..879de12026 --- /dev/null +++ b/lib/src/phy/ue/test/ue_dl_nr_file_test.cc @@ -0,0 +1,466 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifdef __cplusplus +#include +extern "C" { +#include "srsran/phy/io/filesource.h" +#include "srsran/phy/phch/ra_nr.h" +#include "srsran/phy/ue/ue_dl_nr.h" +#include "srsran/phy/utils/debug.h" +#include +} +#endif // __cplusplus + +#include "srsran/common/band_helper.h" +#include + +static srsran_carrier_nr_t carrier = SRSRAN_DEFAULT_CARRIER_NR; + +static char* filename = NULL; +static srsran_pdcch_cfg_nr_t pdcch_cfg = {}; +static srsran_sch_hl_cfg_nr_t pdsch_hl_cfg = {}; +static uint16_t rnti = 0x1234; +static srsran_rnti_type_t rnti_type = srsran_rnti_type_c; +static srsran_slot_cfg_t slot_cfg = {}; + +static srsran_filesource_t filesource = {}; +static srsran_ue_dl_nr_t ue_dl = {}; +static cf_t* buffer[SRSRAN_MAX_PORTS] = {}; +static srsran_softbuffer_rx_t softbuffer = {}; +static uint8_t* data = NULL; +static int pdsch_time_ra_start = -1; +static int pdsch_time_ra_length = -1; + +static uint32_t coreset0_idx = 0; // if ss_type=si coreset0 is used and this is the index +static uint32_t coreset_offset_rb = 0; +static bool interleaved_pdcch = false; +static uint32_t dl_arfcn = 161200; // center of the NR carrier (default at 806e6 Hz) +static uint32_t ssb_arfcn = 161290; // center of the SSB within the carrier (default at 806.45e6) + +static uint32_t coreset_n_rb = 48; +static uint32_t coreset_len = 1; +static srsran_search_space_type_t ss_type = srsran_search_space_type_common_0; + +static void usage(char* prog) +{ + printf("Usage: %s [fPivnSRTscoNlAaIt] \n", prog); + printf("\t-f File name [Default none]\n"); + printf("\t-P Number of BWP (Carrier) PRB [Default %d]\n", carrier.nof_prb); + printf("\t-i Physical cell identifier [Default %d]\n", carrier.pci); + printf("\t-n Slot index [Default %d]\n", slot_cfg.idx); + printf("\t-R RNTI in hexadecimal [Default 0x%x]\n", rnti); + printf("\t-T RNTI type (c, ra, si) [Default %s]\n", srsran_rnti_type_str(rnti_type)); + printf("\t-s Search space type (common0, common3, ue) [Default %s]\n", srsran_ss_type_str(ss_type)); + printf("\t-c Coreset0 index (only used if SS type is common0 for SIB) [Default %d]\n", coreset0_idx); + printf("\t-o Coreset RB offset [Default %d]\n", coreset_offset_rb); + printf("\t-N Coreset N_RB [Default %d]\n", coreset_n_rb); + printf("\t-l Coreset duration in symbols [Default %d]\n", coreset_len); + printf("\t-I Enable interleaved CCE-to-REG [Default %s]\n", interleaved_pdcch ? "Enabled" : "Disabled"); + printf("\t-t PDSCH time resource allocation [start symbol] [length]\n"); + printf("\t-A ARFCN of the NR carrier (center) [Default %d]\n", dl_arfcn); + printf("\t-a center of the SSB within the carrier [Default %d]\n", ssb_arfcn); + + printf("\t-S Use standard rates [Default %s]\n", srsran_symbol_size_is_standard() ? "yes" : "no"); + + printf("\t-v [set srsran_verbose to debug, default none]\n"); +} + +static int parse_args(int argc, char** argv) +{ + int opt; + while ((opt = getopt(argc, argv, "fPivnSRTscoNlAaIt")) != -1) { + switch (opt) { + case 'f': + filename = argv[optind]; + break; + case 'P': + carrier.nof_prb = (uint32_t)strtol(argv[optind], NULL, 10); + break; + case 'i': + carrier.pci = (uint32_t)strtol(argv[optind], NULL, 10); + break; + case 'v': + increase_srsran_verbose_level(); + break; + case 'n': + slot_cfg.idx = (uint32_t)strtol(argv[optind], NULL, 10); + break; + case 'R': + rnti = (uint16_t)strtol(argv[optind], NULL, 16); + break; + case 't': + pdsch_time_ra_start = (int)strtol(argv[optind++], NULL, 10); + pdsch_time_ra_length = (int)strtol(argv[optind], NULL, 10); + break; + case 'T': + if (strcmp(argv[optind], "c") == 0) { + rnti_type = srsran_rnti_type_c; + } else if (strcmp(argv[optind], "ra") == 0) { + rnti_type = srsran_rnti_type_ra; + } else if (strcmp(argv[optind], "si") == 0) { + rnti_type = srsran_rnti_type_si; + } else { + printf("Invalid RNTI type '%s'\n", argv[optind]); + usage(argv[0]); + return SRSRAN_ERROR; + } + break; + case 's': + if (strcmp(argv[optind], "common0") == 0) { + ss_type = srsran_search_space_type_common_0; + } else if (strcmp(argv[optind], "common1") == 0) { + ss_type = srsran_search_space_type_common_1; + } else if (strcmp(argv[optind], "common3") == 0) { + ss_type = srsran_search_space_type_common_3; + } else if (strcmp(argv[optind], "ue") == 0) { + ss_type = srsran_search_space_type_ue; + } else { + printf("Invalid SS type '%s'\n", argv[optind]); + usage(argv[0]); + return SRSRAN_ERROR; + } + break; + case 'I': + interleaved_pdcch ^= true; + break; + case 'c': + coreset0_idx = (uint16_t)strtol(argv[optind], NULL, 10); + break; + case 'o': + coreset_offset_rb = (uint16_t)strtol(argv[optind], NULL, 10); + break; + case 'N': + coreset_n_rb = (uint16_t)strtol(argv[optind], NULL, 10); + break; + case 'l': + coreset_len = (uint16_t)strtol(argv[optind], NULL, 10); + break; + case 'A': + dl_arfcn = (uint32_t)strtol(argv[optind], NULL, 10); + break; + case 'a': + ssb_arfcn = (uint32_t)strtol(argv[optind], NULL, 10); + break; + case 'S': + srsran_use_standard_symbol_size(true); + break; + default: + usage(argv[0]); + return SRSRAN_ERROR; + } + } + + return SRSRAN_SUCCESS; +} + +static int work_ue_dl(srsran_ue_dl_nr_t* ue_dl, srsran_slot_cfg_t* slot) +{ + // Run FFT + srsran_ue_dl_nr_estimate_fft(ue_dl, slot); + + // Blind search + srsran_dci_dl_nr_t dci_dl_rx = {}; + int nof_found_dci = srsran_ue_dl_nr_find_dl_dci(ue_dl, slot, rnti, rnti_type, &dci_dl_rx, 1); + if (nof_found_dci < SRSRAN_SUCCESS) { + ERROR("Error in blind search"); + return SRSRAN_ERROR; + } + + // Print PDCCH blind search candidates + for (uint32_t i = 0; i < ue_dl->pdcch_info_count; i++) { + const srsran_ue_dl_nr_pdcch_info_t* info = &ue_dl->pdcch_info[i]; + INFO("PDCCH: %s-rnti=0x%x, crst_id=%d, ss_type=%s, ncce=%d, al=%d, EPRE=%+.2f, RSRP=%+.2f, corr=%.3f; " + "nof_bits=%d; crc=%s;", + srsran_rnti_type_str_short(info->dci_ctx.rnti_type), + info->dci_ctx.rnti, + info->dci_ctx.coreset_id, + srsran_ss_type_str(info->dci_ctx.ss_type), + info->dci_ctx.location.ncce, + info->dci_ctx.location.L, + info->measure.epre_dBfs, + info->measure.rsrp_dBfs, + info->measure.norm_corr, + info->nof_bits, + info->result.crc ? "OK" : "KO"); + } + + if (nof_found_dci < 1) { + printf("No DCI found :'(\n"); + return SRSRAN_ERROR; + } + + char str[1024] = {}; + srsran_dci_dl_nr_to_str(&ue_dl->dci, &dci_dl_rx, str, (uint32_t)sizeof(str)); + printf("Found DCI: %s\n", str); + + // Convert DCI to PDSCH transmission + srsran_sch_cfg_nr_t pdsch_cfg = {}; + if (rnti_type == srsran_rnti_type_ra) { + pdsch_hl_cfg.common_time_ra[0].k = 0; + pdsch_hl_cfg.common_time_ra[0].mapping_type = srsran_sch_mapping_type_A; + pdsch_hl_cfg.common_time_ra[0].sliv = + srsran_ra_type2_to_riv(SRSRAN_NSYMB_PER_SLOT_NR - 1, 1, SRSRAN_NSYMB_PER_SLOT_NR); + pdsch_hl_cfg.nof_common_time_ra = 1; + } + if (srsran_ra_dl_dci_to_grant_nr(&carrier, slot, &pdsch_hl_cfg, &dci_dl_rx, &pdsch_cfg, &pdsch_cfg.grant) < + SRSRAN_SUCCESS) { + ERROR("Error decoding PDSCH search"); + return SRSRAN_ERROR; + } + + srsran_sch_cfg_nr_info(&pdsch_cfg, str, (uint32_t)sizeof(str)); + printf("PDSCH: %s\n", str); + + // Set softbuffer + pdsch_cfg.grant.tb[0].softbuffer.rx = &softbuffer; + + // Prepare PDSCH result + srsran_pdsch_res_nr_t pdsch_res = {}; + pdsch_res.tb[0].payload = data; + + // Decode PDSCH + if (srsran_ue_dl_nr_decode_pdsch(ue_dl, slot, &pdsch_cfg, &pdsch_res) < SRSRAN_SUCCESS) { + ERROR("Error decoding PDSCH search"); + return SRSRAN_ERROR; + } + + if (!pdsch_res.tb[0].crc) { + ERROR("Error decoding PDSCH"); + return SRSRAN_ERROR; + } + + printf("Decoded PDSCH (%d B)\n", pdsch_cfg.grant.tb[0].tbs / 8); + srsran_vec_fprint_byte(stdout, pdsch_res.tb[0].payload, pdsch_cfg.grant.tb[0].tbs / 8); + + // check payload is not all null + bool all_zero = true; + for (int i = 0; i < pdsch_cfg.grant.tb[0].tbs / 8; ++i) { + if (pdsch_res.tb[0].payload[i] != 0x0) { + all_zero = false; + break; + } + } + if (all_zero) { + ERROR("PDSCH payload is all zeros"); + return SRSRAN_ERROR; + } + + return SRSRAN_SUCCESS; +} + +// helper to avoid goto in C++ +int clean_exit(int ret) +{ + if (buffer[0] != NULL) { + free(buffer[0]); + } + if (data != NULL) { + free(data); + } + srsran_ue_dl_nr_free(&ue_dl); + srsran_filesource_free(&filesource); + srsran_softbuffer_rx_free(&softbuffer); + return ret; +} + +int main(int argc, char** argv) +{ + int ret = SRSRAN_ERROR; + + // parse args + if (parse_args(argc, argv) < SRSRAN_SUCCESS) { + return clean_exit(ret); + } + + uint32_t sf_len = SRSRAN_SF_LEN_PRB(carrier.nof_prb); + buffer[0] = srsran_vec_cf_malloc(sf_len); + if (buffer[0] == NULL) { + ERROR("Error malloc"); + return clean_exit(ret); + } + + if (srsran_softbuffer_rx_init_guru(&softbuffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB) < + SRSRAN_SUCCESS) { + ERROR("Error init soft-buffer"); + return clean_exit(ret); + } + + data = srsran_vec_u8_malloc(SRSRAN_SLOT_MAX_NOF_BITS_NR); + if (data == NULL) { + ERROR("Error malloc"); + return clean_exit(ret); + } + + // Set default PDSCH configuration + srsran_ue_dl_nr_args_t ue_dl_args = {}; + ue_dl_args.nof_rx_antennas = 1; + ue_dl_args.pdsch.sch.disable_simd = false; + ue_dl_args.pdsch.sch.decoder_use_flooded = false; + ue_dl_args.pdsch.measure_evm = true; + ue_dl_args.pdcch.disable_simd = false; + ue_dl_args.pdcch.measure_evm = true; + ue_dl_args.nof_max_prb = carrier.nof_prb; + + // Check for filename + if (filename == NULL) { + ERROR("Filename was not provided"); + return clean_exit(ret); + } + + // Open filesource + if (srsran_filesource_init(&filesource, filename, SRSRAN_COMPLEX_FLOAT_BIN) < SRSRAN_SUCCESS) { + ERROR("Error opening filesource"); + return clean_exit(ret); + } + + // initial DCI config + srsran_dci_cfg_nr_t dci_cfg = {}; + dci_cfg.bwp_dl_initial_bw = carrier.nof_prb; + dci_cfg.bwp_ul_initial_bw = carrier.nof_prb; + dci_cfg.bwp_dl_active_bw = carrier.nof_prb; + dci_cfg.bwp_ul_active_bw = carrier.nof_prb; + dci_cfg.monitor_common_0_0 = true; + dci_cfg.monitor_0_0_and_1_0 = true; + + + // derive absolute frequencies from ARFCNs + srsran::srsran_band_helper band_helper; + carrier.ssb_center_freq_hz = band_helper.nr_arfcn_to_freq(ssb_arfcn); + carrier.dl_center_frequency_hz = band_helper.nr_arfcn_to_freq(dl_arfcn); + + srsran_coreset_t* coreset = NULL; + + // Configure CORESET + if (rnti_type == srsran_rnti_type_si || rnti_type == srsran_rnti_type_ra) { + // configure to use coreset0 + coreset = &pdcch_cfg.coreset[0]; + pdcch_cfg.coreset_present[0] = true; + + // Get pointA and SSB absolute frequencies + double pointA_abs_freq_Hz = + carrier.dl_center_frequency_hz - carrier.nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(carrier.scs) / 2; + double ssb_abs_freq_Hz = carrier.ssb_center_freq_hz; + // Calculate integer SSB to pointA frequency offset in Hz + uint32_t ssb_pointA_freq_offset_Hz = + (ssb_abs_freq_Hz > pointA_abs_freq_Hz) ? (uint32_t)(ssb_abs_freq_Hz - pointA_abs_freq_Hz) : 0; + + // derive coreset0 parameters + if (srsran_coreset_zero(carrier.pci, ssb_pointA_freq_offset_Hz, carrier.scs, carrier.scs, coreset0_idx, coreset) != + SRSRAN_SUCCESS) { + printf("Not possible to create CORESET Zero (ssb_scs=%s, pdcch_scs=%s, idx=%d)", + srsran_subcarrier_spacing_to_str(carrier.scs), + srsran_subcarrier_spacing_to_str(carrier.scs), + coreset0_idx); + return clean_exit(ret); + } + + // Setup PDSCH DMRS (also signaled through MIB) + pdsch_hl_cfg.typeA_pos = srsran_dmrs_sch_typeA_pos_2; + + // set coreset0 bandwidth + dci_cfg.coreset0_bw = srsran_coreset_get_bw(coreset); + } else { + // configure to use coreset1 + coreset = &pdcch_cfg.coreset[1]; + coreset->id = 1; + pdcch_cfg.coreset_present[1] = true; + coreset->duration = coreset_len; + coreset->offset_rb = coreset_offset_rb; + for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { + coreset->freq_resources[i] = i < coreset_n_rb / 6; + } + if (interleaved_pdcch) { + coreset->mapping_type = srsran_coreset_mapping_type_interleaved; + coreset->reg_bundle_size = srsran_coreset_bundle_size_n6; + coreset->interleaver_size = srsran_coreset_bundle_size_n2; + coreset->precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle; + coreset->shift_index = carrier.pci; + } + // set coreset0 bandwidth (it is used in RA when ss_type = common3) + dci_cfg.coreset0_bw = coreset_n_rb; + + // SCH configuration parameters + if (pdsch_time_ra_start >= 0 && pdsch_time_ra_length >= 0) { + auto last_pdsch_symbol = (uint16_t)(pdsch_time_ra_start + pdsch_time_ra_length); + + if (last_pdsch_symbol > SRSRAN_NSYMB_PER_SLOT_NR) { + ERROR("incorrect PDSCH start symbol or length provided"); + return clean_exit(ret); + } + uint32_t sliv = srsran_ra_nr_type1_riv(SRSRAN_NSYMB_PER_SLOT_NR, pdsch_time_ra_start, pdsch_time_ra_length); + + pdsch_hl_cfg.nof_dedicated_time_ra = 1; + pdsch_hl_cfg.dedicated_time_ra[0].mapping_type = srsran_sch_mapping_type_A; + pdsch_hl_cfg.dedicated_time_ra[0].k = 0; + pdsch_hl_cfg.dedicated_time_ra[0].sliv = sliv; + } + } + + char coreset_info[512] = {}; + srsran_coreset_to_str(coreset, coreset_info, sizeof(coreset_info)); + INFO("Coreset parameter: %s", coreset_info); + + // Configure Search Space + srsran_search_space_t* search_space = &pdcch_cfg.search_space[0]; + pdcch_cfg.search_space_present[0] = true; + search_space->id = 0; + search_space->coreset_id = (rnti_type == srsran_rnti_type_si || rnti_type == srsran_rnti_type_ra) ? 0 : 1; + search_space->type = ss_type; + search_space->formats[0] = srsran_dci_format_nr_0_0; + search_space->formats[1] = srsran_dci_format_nr_1_0; + search_space->nof_formats = 2; + for (uint32_t L = 0; L < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) { + search_space->nof_candidates[L] = srsran_pdcch_nr_max_candidates_coreset(coreset, L); + } + + // Configure RA search space + pdcch_cfg.ra_search_space_present = true; + pdcch_cfg.ra_search_space = *search_space; + pdcch_cfg.ra_search_space.type = srsran_search_space_type_common_1; + + if (srsran_ue_dl_nr_init(&ue_dl, buffer, &ue_dl_args)) { + ERROR("Error UE DL"); + return clean_exit(ret); + } + + if (srsran_ue_dl_nr_set_carrier(&ue_dl, &carrier)) { + ERROR("Error setting SCH NR carrier"); + return clean_exit(ret); + } + + // Read baseband from file + if (srsran_filesource_read(&filesource, buffer[0], (int)ue_dl.fft->sf_sz) < SRSRAN_SUCCESS) { + ERROR("Error reading baseband"); + return clean_exit(ret); + } + + if (srsran_ue_dl_nr_set_pdcch_config(&ue_dl, &pdcch_cfg, &dci_cfg)) { + ERROR("Error setting CORESET"); + return clean_exit(ret); + } + + // Actual decode + ret = work_ue_dl(&ue_dl, &slot_cfg); + + // free memory and return last value of ret + return clean_exit(ret); +} diff --git a/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_rar_s15.36e6.dat b/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_rar_s15.36e6.dat new file mode 100644 index 0000000000..3b96f83070 Binary files /dev/null and b/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_rar_s15.36e6.dat differ diff --git a/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_rnti0x100_s15.36e6.dat b/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_rnti0x100_s15.36e6.dat new file mode 100644 index 0000000000..daff675324 Binary files /dev/null and b/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_rnti0x100_s15.36e6.dat differ diff --git a/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_si_coreset0_idx6_s15.36e6.dat b/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_si_coreset0_idx6_s15.36e6.dat new file mode 100644 index 0000000000..9c35a565f3 Binary files /dev/null and b/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_si_coreset0_idx6_s15.36e6.dat differ diff --git a/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_si_coreset0_idx7_s15.36e6.dat b/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_si_coreset0_idx7_s15.36e6.dat new file mode 100644 index 0000000000..e7afecae3b Binary files /dev/null and b/lib/src/phy/ue/test/ue_dl_nr_pci500_rb52_si_coreset0_idx7_s15.36e6.dat differ diff --git a/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c b/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c index 0b71b8b040..d68cbde2dc 100644 --- a/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c +++ b/lib/src/phy/ue/test/ue_mib_sync_test_nbiot_usrp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/test/ue_sync_nr_test.c b/lib/src/phy/ue/test/ue_sync_nr_test.c index 7e9b5c63e4..1ccabcae58 100644 --- a/lib/src/phy/ue/test/ue_sync_nr_test.c +++ b/lib/src/phy/ue/test/ue_sync_nr_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -30,10 +30,14 @@ #include // NR parameters -static uint32_t pci = 1; // Physical Cell Identifier -static uint32_t carrier_nof_prb = 52; // Carrier bandwidth -static srsran_subcarrier_spacing_t carrier_scs = srsran_subcarrier_spacing_15kHz; -static srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_30kHz; +static uint32_t pci = 500; // Physical Cell Identifier +static uint32_t carrier_nof_prb = 52; // Carrier bandwidth +static srsran_subcarrier_spacing_t carrier_scs = srsran_subcarrier_spacing_15kHz; +static double center_frequency_hz = 3.5e9; +static srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_15kHz; +static double ssb_frequency_hz = 3.5e9 - 960e3; +static srsran_ssb_pattern_t ssb_pattern = SRSRAN_SSB_PATTERN_C; +static srsran_duplex_mode_t duplex_mode = SRSRAN_DUPLEX_MODE_TDD; // Test and channel parameters static uint32_t nof_sf = 1000; // Number of subframes to test @@ -44,7 +48,7 @@ static float delay_max_us = 1000.0f; // Maximum dynamic delay in microsecon static float delay_period_s = 60.0f; // Delay period in seconds // Test context -static double srate_hz = 0.0f; // Base-band sampling rate +static double srate_hz = 0.0; // Base-band sampling rate static uint32_t sf_len = 0; // Subframe length static cf_t* buffer = NULL; // Base-band buffer static cf_t* buffer2 = NULL; // Base-band buffer @@ -108,7 +112,7 @@ static int test_context_init(test_context_t* ctx) srsran_ssb_args_t ssb_args = {}; ssb_args.max_srate_hz = srate_hz; - ssb_args.min_scs = carrier_scs; + ssb_args.min_scs = ssb_scs; ssb_args.enable_encode = true; if (srsran_ssb_init(&ctx->ssb, &ssb_args) < SRSRAN_SUCCESS) { return SRSRAN_ERROR; @@ -117,10 +121,11 @@ static int test_context_init(test_context_t* ctx) srsran_ssb_cfg_t ssb_cfg = {}; ssb_cfg.srate_hz = srate_hz; ssb_cfg.srate_hz = srate_hz; - ssb_cfg.center_freq_hz = 3.5e9; - ssb_cfg.ssb_freq_hz = 3.5e9 - 960e3; + ssb_cfg.center_freq_hz = center_frequency_hz; + ssb_cfg.ssb_freq_hz = ssb_frequency_hz; ssb_cfg.scs = ssb_scs; - ssb_cfg.pattern = SRSRAN_SSB_PATTERN_C; + ssb_cfg.pattern = ssb_pattern; + ssb_cfg.duplex_mode = duplex_mode; if (srsran_ssb_set_cfg(&ctx->ssb, &ssb_cfg) < SRSRAN_SUCCESS) { return SRSRAN_ERROR; } @@ -250,10 +255,12 @@ int main(int argc, char** argv) int ret = SRSRAN_ERROR; parse_args(argc, argv); - srate_hz = (double)SRSRAN_SUBC_SPACING_NR(carrier_scs) * srsran_min_symbol_sz_rb(carrier_nof_prb); - sf_len = (uint32_t)ceil(srate_hz / 1000.0); - buffer = srsran_vec_cf_malloc(sf_len); - buffer2 = srsran_vec_cf_malloc(sf_len); + if (!isnormal(srate_hz)) { + srate_hz = (double)SRSRAN_SUBC_SPACING_NR(carrier_scs) * srsran_min_symbol_sz_rb(carrier_nof_prb); + } + sf_len = (uint32_t)ceil(srate_hz / 1000.0); + buffer = srsran_vec_cf_malloc(sf_len); + buffer2 = srsran_vec_cf_malloc(sf_len); test_context_t ctx = {}; srsran_ue_sync_nr_t ue_sync = {}; @@ -273,7 +280,7 @@ int main(int argc, char** argv) ue_sync_args.min_scs = carrier_scs; ue_sync_args.recv_obj = &ctx; ue_sync_args.recv_callback = &recv_callback; - ue_sync_args.disable_cfo = false; + ue_sync_args.disable_cfo = true; if (srsran_ue_sync_nr_init(&ue_sync, &ue_sync_args) < SRSRAN_SUCCESS) { ERROR("Init"); goto clean_exit; @@ -281,10 +288,11 @@ int main(int argc, char** argv) srsran_ue_sync_nr_cfg_t ue_sync_cfg = {}; ue_sync_cfg.ssb.srate_hz = srate_hz; - ue_sync_cfg.ssb.center_freq_hz = 3.5e9; - ue_sync_cfg.ssb.ssb_freq_hz = 3.5e9 - 960e3; + ue_sync_cfg.ssb.center_freq_hz = center_frequency_hz; + ue_sync_cfg.ssb.ssb_freq_hz = ssb_frequency_hz; ue_sync_cfg.ssb.scs = ssb_scs; - ue_sync_cfg.ssb.pattern = SRSRAN_SSB_PATTERN_C; + ue_sync_cfg.ssb.pattern = ssb_pattern; + ue_sync_cfg.ssb.duplex_mode = duplex_mode; ue_sync_cfg.N_id = pci; if (srsran_ue_sync_nr_set_cfg(&ue_sync, &ue_sync_cfg) < SRSRAN_SUCCESS) { ERROR("Init"); @@ -316,4 +324,4 @@ int main(int argc, char** argv) test_context_free(&ctx); return ret; -} \ No newline at end of file +} diff --git a/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c b/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c index 8b65e7c20e..2dc90bd11f 100644 --- a/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c +++ b/lib/src/phy/ue/test/ue_sync_test_nbiot_usrp.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/ue_cell_search.c b/lib/src/phy/ue/ue_cell_search.c index e6ab7f31d1..c5ce94c45c 100644 --- a/lib/src/phy/ue/ue_cell_search.c +++ b/lib/src/phy/ue/ue_cell_search.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/ue_cell_search_nbiot.c b/lib/src/phy/ue/ue_cell_search_nbiot.c index 6822dc7e87..19598f5184 100644 --- a/lib/src/phy/ue/ue_cell_search_nbiot.c +++ b/lib/src/phy/ue/ue_cell_search_nbiot.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/ue_dl.c b/lib/src/phy/ue/ue_dl.c index 17cbdfe547..f10ee745b3 100644 --- a/lib/src/phy/ue/ue_dl.c +++ b/lib/src/phy/ue/ue_dl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/ue_dl_nbiot.c b/lib/src/phy/ue/ue_dl_nbiot.c index edf3cb5270..e3207c672b 100644 --- a/lib/src/phy/ue/ue_dl_nbiot.c +++ b/lib/src/phy/ue/ue_dl_nbiot.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -400,7 +400,7 @@ void srsran_nbiot_ue_dl_decode_sib1(srsran_nbiot_ue_dl_t* q, uint32_t current_sf // activate SIB1 grant and configure NPDSCH INFO( "%d.x: Activated SIB1 decoding in sfn=%d\n", current_sfn, srsran_nbiot_ue_dl_get_next_sib1_start(q, current_sfn)); - srsran_ra_nbiot_dl_grant_t grant; + srsran_ra_nbiot_dl_grant_t grant = {}; srsran_nbiot_ue_dl_get_sib1_grant(q, current_sfn, &grant); srsran_nbiot_ue_dl_set_grant(q, &grant); } @@ -419,7 +419,7 @@ void srsran_nbiot_ue_dl_decode_sib(srsran_nbiot_ue_dl_t* q, if (type == SRSRAN_NBIOT_SI_TYPE_SIB2) { assert(params.n == 1); // calculate SIB2 params - srsran_ra_nbiot_dl_grant_t grant; + srsran_ra_nbiot_dl_grant_t grant = {}; srsran_nbiot_ue_dl_get_sib_grant(q, hfn, sfn, params, &grant); srsran_nbiot_ue_dl_set_grant(q, &grant); INFO("%d.x: Activated SIB2 reception in hfn=%d, sfn=%d", diff --git a/lib/src/phy/ue/ue_dl_nr.c b/lib/src/phy/ue/ue_dl_nr.c index 3752cf1b69..ecf9807eb7 100644 --- a/lib/src/phy/ue/ue_dl_nr.c +++ b/lib/src/phy/ue/ue_dl_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -302,6 +302,16 @@ static int ue_dl_nr_find_dci_ncce(srsran_ue_dl_nr_t* q, return SRSRAN_ERROR; } +#if 0 + static uint32_t num_pdcch = 0; + char tmpstr[64]; + snprintf(tmpstr, 64, "pdcch_symbols%d.dat", num_pdcch); + printf("save %d syms to %s\n", q->pdcch.M / 4, tmpstr); + srsran_vec_save_file(tmpstr, q->pdcch.symbols, q->pdcch.M / 4 * sizeof(cf_t)); + // srsran_vec_fprint_c(stdout, q->pdcch.symbols, q->pdcch.M/4); + num_pdcch++; +#endif + // Save information pdcch_info->result = *pdcch_res; diff --git a/lib/src/phy/ue/ue_mib.c b/lib/src/phy/ue/ue_mib.c index f3f1425fc8..85f37cfd17 100644 --- a/lib/src/phy/ue/ue_mib.c +++ b/lib/src/phy/ue/ue_mib.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/ue_mib_nbiot.c b/lib/src/phy/ue/ue_mib_nbiot.c index 87207fe2f0..b8dc8c4249 100644 --- a/lib/src/phy/ue/ue_mib_nbiot.c +++ b/lib/src/phy/ue/ue_mib_nbiot.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/ue_mib_sl.c b/lib/src/phy/ue/ue_mib_sl.c index 694d2051ef..135f6c0681 100644 --- a/lib/src/phy/ue/ue_mib_sl.c +++ b/lib/src/phy/ue/ue_mib_sl.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/ue_sync.c b/lib/src/phy/ue/ue_sync.c index 36558b9e6b..a53f480f2d 100644 --- a/lib/src/phy/ue/ue_sync.c +++ b/lib/src/phy/ue/ue_sync.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -343,8 +343,7 @@ int srsran_ue_sync_set_cell(srsran_ue_sync_t* q, srsran_cell_t cell) q->fft_size = srsran_symbol_sz(q->cell.nof_prb); } q->sf_len = SRSRAN_SF_LEN(q->fft_size); - srsran_sync_set_cp(&q->sfind, q->cell.cp); - srsran_sync_set_cp(&q->strack, q->cell.cp); + if (cell.id == 1000) { /* If the cell is unkown, we search PSS/SSS in 5 ms */ q->nof_recv_sf = 5; @@ -385,6 +384,10 @@ int srsran_ue_sync_set_cell(srsran_ue_sync_t* q, srsran_cell_t cell) } } + // Set CP for find and track objects + srsran_sync_set_cp(&q->sfind, cell.cp); + srsran_sync_set_cp(&q->strack, cell.cp); + // When Cell ID is 1000, ue_sync receives nof_avg_find_frames frames in find state and does not go to tracking // state and is used to search a cell if (cell.id == 1000) { @@ -402,9 +405,6 @@ int srsran_ue_sync_set_cell(srsran_ue_sync_t* q, srsran_cell_t cell) srsran_sync_set_cfo_ema_alpha(&q->strack, 0.1); } else { - q->sfind.cp = cell.cp; - q->strack.cp = cell.cp; - srsran_sync_set_frame_type(&q->sfind, cell.frame_type); srsran_sync_set_frame_type(&q->strack, cell.frame_type); diff --git a/lib/src/phy/ue/ue_sync_nbiot.c b/lib/src/phy/ue/ue_sync_nbiot.c index ac6357e495..630677b036 100644 --- a/lib/src/phy/ue/ue_sync_nbiot.c +++ b/lib/src/phy/ue/ue_sync_nbiot.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/ue/ue_sync_nr.c b/lib/src/phy/ue/ue_sync_nr.c index ec1db7a197..bbd308afac 100644 --- a/lib/src/phy/ue/ue_sync_nr.c +++ b/lib/src/phy/ue/ue_sync_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -129,19 +129,12 @@ static void ue_sync_nr_apply_feedback(srsran_ue_sync_nr_t* q) ue_sync_nr_reset_feedback(q); } -static int ue_sync_nr_run_find(srsran_ue_sync_nr_t* q, cf_t* buffer) +static int ue_sync_nr_update_ssb(srsran_ue_sync_nr_t* q, + const srsran_csi_trs_measurements_t* measurements, + const srsran_pbch_msg_nr_t* pbch_msg) { - srsran_csi_trs_measurements_t measurements = {}; - srsran_pbch_msg_nr_t pbch_msg = {}; - - // Find SSB, measure PSS/SSS and decode PBCH - if (srsran_ssb_find(&q->ssb, buffer, q->N_id, &measurements, &pbch_msg) < SRSRAN_SUCCESS) { - ERROR("Error finding SSB"); - return SRSRAN_ERROR; - } - - // If the PBCH message was NOT decoded, early return - if (!pbch_msg.crc) { + srsran_mib_nr_t mib = {}; + if (srsran_pbch_msg_nr_mib_unpack(pbch_msg, &mib) != SRSRAN_SUCCESS) { return SRSRAN_SUCCESS; } @@ -149,24 +142,43 @@ static int ue_sync_nr_run_find(srsran_ue_sync_nr_t* q, cf_t* buffer) ue_sync_nr_reset_feedback(q); // Set feedback measurement - srsran_combine_csi_trs_measurements(&q->feedback, &measurements, &q->feedback); + srsran_combine_csi_trs_measurements(&q->feedback, measurements, &q->feedback); // Apply feedback ue_sync_nr_apply_feedback(q); // Setup context - q->ssb_idx = pbch_msg.ssb_idx; - q->sf_idx = srsran_ssb_candidate_sf_idx(&q->ssb, pbch_msg.ssb_idx, pbch_msg.hrf); - q->sfn = pbch_msg.sfn_4lsb; + q->ssb_idx = pbch_msg->ssb_idx; + q->sf_idx = srsran_ssb_candidate_sf_idx(&q->ssb, pbch_msg->ssb_idx, pbch_msg->hrf); + q->sfn = mib.sfn; // Transition to track only if the measured delay is below 2.4 microseconds - if (measurements.delay_us < 2.4f) { + if (measurements->delay_us < 2.4f) { q->state = SRSRAN_UE_SYNC_NR_STATE_TRACK; } return SRSRAN_SUCCESS; } +static int ue_sync_nr_run_find(srsran_ue_sync_nr_t* q, cf_t* buffer) +{ + srsran_csi_trs_measurements_t measurements = {}; + srsran_pbch_msg_nr_t pbch_msg = {}; + + // Find SSB, measure PSS/SSS and decode PBCH + if (srsran_ssb_find(&q->ssb, buffer, q->N_id, &measurements, &pbch_msg) < SRSRAN_SUCCESS) { + ERROR("Error finding SSB"); + return SRSRAN_ERROR; + } + + // If the PBCH message was NOT decoded, early return + if (!pbch_msg.crc) { + return SRSRAN_SUCCESS; + } + + return ue_sync_nr_update_ssb(q, &measurements, &pbch_msg); +} + static int ue_sync_nr_run_track(srsran_ue_sync_nr_t* q, cf_t* buffer) { srsran_csi_trs_measurements_t measurements = {}; @@ -176,28 +188,29 @@ static int ue_sync_nr_run_track(srsran_ue_sync_nr_t* q, cf_t* buffer) // Check if the SSB selected candidate index shall be received in this subframe bool is_ssb_opportunity = (q->sf_idx == srsran_ssb_candidate_sf_idx(&q->ssb, q->ssb_idx, half_frame > 0)); - // If - if (is_ssb_opportunity) { - // Measure PSS/SSS and decode PBCH - if (srsran_ssb_track(&q->ssb, buffer, q->N_id, q->ssb_idx, half_frame, &measurements, &pbch_msg) < SRSRAN_SUCCESS) { - ERROR("Error finding SSB"); - return SRSRAN_ERROR; - } + // Use SSB periodicity + if (q->ssb.cfg.periodicity_ms >= 10) { + // SFN match with the periodicity + is_ssb_opportunity = is_ssb_opportunity && (half_frame == 0) && (q->sfn % q->ssb.cfg.periodicity_ms / 10 == 0); + } - // If the PBCH message was NOT decoded, transition to track - if (!pbch_msg.crc) { - q->state = SRSRAN_UE_SYNC_NR_STATE_FIND; - return SRSRAN_SUCCESS; - } + if (!is_ssb_opportunity) { + return SRSRAN_SUCCESS; + } - // Otherwise feedback measurements and apply - srsran_combine_csi_trs_measurements(&q->feedback, &measurements, &q->feedback); + // Measure PSS/SSS and decode PBCH + if (srsran_ssb_track(&q->ssb, buffer, q->N_id, q->ssb_idx, half_frame, &measurements, &pbch_msg) < SRSRAN_SUCCESS) { + ERROR("Error finding SSB"); + return SRSRAN_ERROR; } - // Apply accumulated feedback - ue_sync_nr_apply_feedback(q); + // If the PBCH message was NOT decoded, transition to find + if (!pbch_msg.crc) { + q->state = SRSRAN_UE_SYNC_NR_STATE_FIND; + return SRSRAN_SUCCESS; + } - return SRSRAN_SUCCESS; + return ue_sync_nr_update_ssb(q, &measurements, &pbch_msg); } static int ue_sync_nr_recv(srsran_ue_sync_nr_t* q, cf_t** buffer, srsran_timestamp_t* timestamp) @@ -247,7 +260,7 @@ static int ue_sync_nr_recv(srsran_ue_sync_nr_t* q, cf_t** buffer, srsran_timesta // Compensate CFO for (uint32_t chan = 0; chan < q->nof_rx_channels; chan++) { if (buffer[chan] != 0 && !q->disable_cfo) { - srsran_vec_apply_cfo(buffer[chan], q->cfo_hz / q->srate_hz, buffer[chan], (int)q->sf_sz); + srsran_vec_apply_cfo(buffer[chan], -q->cfo_hz / q->srate_hz, buffer[chan], (int)q->sf_sz); } } diff --git a/lib/src/phy/ue/ue_ul.c b/lib/src/phy/ue/ue_ul.c index 9594388401..f85f16adac 100644 --- a/lib/src/phy/ue/ue_ul.c +++ b/lib/src/phy/ue/ue_ul.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -174,6 +174,25 @@ int srsran_ue_ul_set_cell(srsran_ue_ul_t* q, srsran_cell_t cell) return ret; } +int srsran_ue_ul_set_cfr(srsran_ue_ul_t* q, const srsran_cfr_cfg_t* cfr) +{ + if (q == NULL || cfr == NULL) { + ERROR("Error, invalid inputs"); + return SRSRAN_ERROR_INVALID_INPUTS; + } + + // Copy the cfr config into the UE + q->cfr_config = *cfr; + + // Set the cfr for the fft's + if (srsran_ofdm_set_cfr(&q->fft, &q->cfr_config) < SRSRAN_SUCCESS) { + ERROR("Error setting the CFR for the fft"); + return SRSRAN_ERROR; + } + + return SRSRAN_SUCCESS; +} + int srsran_ue_ul_pregen_signals(srsran_ue_ul_t* q, srsran_ue_ul_cfg_t* cfg) { if (q->signals_pregenerated) { diff --git a/lib/src/phy/ue/ue_ul_nr.c b/lib/src/phy/ue/ue_ul_nr.c index e49509b960..983d4cae67 100644 --- a/lib/src/phy/ue/ue_ul_nr.c +++ b/lib/src/phy/ue/ue_ul_nr.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/CMakeLists.txt b/lib/src/phy/utils/CMakeLists.txt index da8c239f19..039170cd81 100644 --- a/lib/src/phy/utils/CMakeLists.txt +++ b/lib/src/phy/utils/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/utils/bit.c b/lib/src/phy/utils/bit.c index 7a79ba3515..b98b0e63a1 100644 --- a/lib/src/phy/utils/bit.c +++ b/lib/src/phy/utils/bit.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/cexptab.c b/lib/src/phy/utils/cexptab.c index a4c017418b..89c4a787d9 100644 --- a/lib/src/phy/utils/cexptab.c +++ b/lib/src/phy/utils/cexptab.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/convolution.c b/lib/src/phy/utils/convolution.c index 691819ecf8..737b37d541 100644 --- a/lib/src/phy/utils/convolution.c +++ b/lib/src/phy/utils/convolution.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/debug.c b/lib/src/phy/utils/debug.c index 6b2de95275..53bd24ef95 100644 --- a/lib/src/phy/utils/debug.c +++ b/lib/src/phy/utils/debug.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/filter.c b/lib/src/phy/utils/filter.c index 957bd814b8..cda38d4871 100644 --- a/lib/src/phy/utils/filter.c +++ b/lib/src/phy/utils/filter.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/mat.c b/lib/src/phy/utils/mat.c index 0659810d86..a2ee0b9a04 100644 --- a/lib/src/phy/utils/mat.c +++ b/lib/src/phy/utils/mat.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/phy_logger.c b/lib/src/phy/utils/phy_logger.c index e3a5713cce..920b4ddc69 100644 --- a/lib/src/phy/utils/phy_logger.c +++ b/lib/src/phy/utils/phy_logger.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/primes.c b/lib/src/phy/utils/primes.c index b61794a242..b5e6eab48c 100644 --- a/lib/src/phy/utils/primes.c +++ b/lib/src/phy/utils/primes.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/random.cpp b/lib/src/phy/utils/random.cpp index d77982acdc..05428e4f30 100644 --- a/lib/src/phy/utils/random.cpp +++ b/lib/src/phy/utils/random.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/re_pattern.c b/lib/src/phy/utils/re_pattern.c index 32a7ea7445..0c57322fd0 100644 --- a/lib/src/phy/utils/re_pattern.c +++ b/lib/src/phy/utils/re_pattern.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/ringbuffer.c b/lib/src/phy/utils/ringbuffer.c index f49f14f63d..dc4846d606 100644 --- a/lib/src/phy/utils/ringbuffer.c +++ b/lib/src/phy/utils/ringbuffer.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/test/CMakeLists.txt b/lib/src/phy/utils/test/CMakeLists.txt index ff819ec087..f33cd17a79 100644 --- a/lib/src/phy/utils/test/CMakeLists.txt +++ b/lib/src/phy/utils/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/phy/utils/test/dft_test.c b/lib/src/phy/utils/test/dft_test.c index fc99148c18..5dabe4f97d 100644 --- a/lib/src/phy/utils/test/dft_test.c +++ b/lib/src/phy/utils/test/dft_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/test/mat_test.c b/lib/src/phy/utils/test/mat_test.c index a02dc627f0..cdc2379e01 100644 --- a/lib/src/phy/utils/test/mat_test.c +++ b/lib/src/phy/utils/test/mat_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/test/re_pattern_test.c b/lib/src/phy/utils/test/re_pattern_test.c index 8c3e58c3c1..71c6f1cd97 100644 --- a/lib/src/phy/utils/test/re_pattern_test.c +++ b/lib/src/phy/utils/test/re_pattern_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/test/ring_buffer_test.c b/lib/src/phy/utils/test/ring_buffer_test.c index 9cf30fd510..73e9113a50 100644 --- a/lib/src/phy/utils/test/ring_buffer_test.c +++ b/lib/src/phy/utils/test/ring_buffer_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/phy/utils/test/vector_test.c b/lib/src/phy/utils/test/vector_test.c index b666bd40c3..6c712e06af 100644 --- a/lib/src/phy/utils/test/vector_test.c +++ b/lib/src/phy/utils/test/vector_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -845,6 +845,38 @@ TEST( free(z); srsran_cfo_free(&srsran_cfo);) +// This test compares the clipping method used for the CFR module in its default configuration to the original CFR +// algorithm. The original algorithm can still be used by defining CFR_PEAK_EXTRACTION in the CFR module. +TEST( + srsran_vec_gen_clip_env, MALLOC(cf_t, x); MALLOC(float, x_abs); MALLOC(float, env); float thres = 0.5f; + float alpha = 0.5f; + cf_t gold = 0.0f; + + for (int i = 0; i < block_size; i++) { + x[i] = RANDOM_F(); + env[i] = 0.0f; + x_abs[i] = cabsf(x[i]); + } + + // current implementation generates an amplitude envelope which is then multiplied with the signal + TEST_CALL(srsran_vec_gen_clip_env(x_abs, thres, alpha, env, block_size)) + + // Recreates the original method for clipping the signal, skipping the low-pass filtering + for (int i = 0; i < block_size; i++) { + if (x_abs[i] <= thres) { + gold = x[i]; + } else { + cf_t peak = x[i] - (thres * x[i] / x_abs[i]); // extract the peak + gold = x[i] - alpha * peak; // subtract the peak from the signal, scaled by alpha + } + // Compare the two clipping methods by applying the envelope to x and determining the error + mse += cabsf(gold - env[i] * x[i]); + } if (isnormal(mse)) { mse /= block_size; } + + free(x); + free(x_abs); + free(env);) + int main(int argc, char** argv) { char func_names[MAX_FUNCTIONS][32]; @@ -1023,6 +1055,10 @@ int main(int argc, char** argv) test_srsran_cfo_correct_change(func_names[func_count], &timmings[func_count][size_count], block_size); func_count++; + passed[func_count][size_count] = + test_srsran_vec_gen_clip_env(func_names[func_count], &timmings[func_count][size_count], block_size); + func_count++; + sizes[size_count] = block_size; size_count++; } diff --git a/lib/src/phy/utils/vector.c b/lib/src/phy/utils/vector.c index 0c1c692547..e9641ff016 100644 --- a/lib/src/phy/utils/vector.c +++ b/lib/src/phy/utils/vector.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -62,6 +62,12 @@ void srsran_vec_sub_bbb(const int8_t* x, const int8_t* y, int8_t* z, const uint3 srsran_vec_sub_bbb_simd(x, y, z, len); } +/* sum a scalar to all elements of a vector */ +void srsran_vec_sc_sum_fff(const float* x, float h, float* z, uint32_t len) +{ + srsran_vec_sc_sum_fff_simd(x, h, z, len); +} + // Noise estimation in chest_dl, interpolation void srsran_vec_sub_ccc(const cf_t* x, const cf_t* y, cf_t* z, const uint32_t len) { @@ -583,7 +589,11 @@ int32_t srsran_vec_dot_prod_sss(const int16_t* x, const int16_t* y, const uint32 float srsran_vec_avg_power_cf(const cf_t* x, const uint32_t len) { - return crealf(srsran_vec_dot_prod_conj_ccc(x, x, len)) / len; + if (!len) { + return 0; + } else { + return crealf(srsran_vec_dot_prod_conj_ccc(x, x, len)) / len; + } } float srsran_vec_avg_power_sf(const int16_t* x, const uint32_t len) @@ -630,6 +640,17 @@ float srsran_vec_avg_power_bf(const int8_t* x, const uint32_t len) return acc; } +float srsran_vec_avg_power_ff(const float* x, const uint32_t len) +{ + if (!len) { + return 0; + } else { + float pwr_symb_avg = srsran_vec_dot_prod_fff(x, x, len); + pwr_symb_avg /= (float)len; + return pwr_symb_avg; + } +} + // Correlation assumes zero-mean x and y float srsran_vec_corr_ccc(const cf_t* x, cf_t* y, const uint32_t len) { @@ -840,3 +861,38 @@ float srsran_vec_estimate_frequency(const cf_t* x, int len) { return srsran_vec_estimate_frequency_simd(x, len); } + +// TODO: implement with SIMD +void srsran_vec_gen_clip_env(const float* x_abs, const float thres, const float alpha, float* env, const int len) +{ + for (int i = 0; i < len; i++) { + env[i] = (x_abs[i] > thres) ? (1 - alpha) + alpha * thres / x_abs[i] : 1; + } +} + +float srsran_vec_papr_c(const cf_t* in, const int len) +{ + uint32_t max = srsran_vec_max_abs_ci(in, len); + float peak = SRSRAN_CSQABS(in[max]); + return peak / srsran_vec_avg_power_cf(in, len); +} + +float srsran_vec_acpr_c(const cf_t* x_f, const uint32_t win_pos_len, const uint32_t win_neg_len, const uint32_t len) +{ + // The adjacent channel cannot extend beyond the FFT len + const uint32_t ch_len = win_pos_len + win_neg_len; + const uint32_t adj_ch_len = ch_len > len / 2 ? len - ch_len : ch_len; + + // Integrate positive half of the signal power spectrum + float signal_pwr = srsran_vec_dot_prod_conj_ccc(x_f, x_f, win_pos_len); + // Integrate negative halt of the signal power spectrum + signal_pwr += srsran_vec_dot_prod_conj_ccc(x_f + len - win_neg_len, x_f + len - win_neg_len, win_neg_len); + + const float adj_ch_pwr = srsran_vec_dot_prod_conj_ccc(x_f + win_pos_len, x_f + win_pos_len, adj_ch_len); + + if (isnormal(signal_pwr)) { + return adj_ch_pwr / signal_pwr; + } else { + return 0; + } +} diff --git a/lib/src/phy/utils/vector_simd.c b/lib/src/phy/utils/vector_simd.c index 418c7293ad..d9783ff53d 100644 --- a/lib/src/phy/utils/vector_simd.c +++ b/lib/src/phy/utils/vector_simd.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -721,6 +721,36 @@ void srsran_vec_sub_fff_simd(const float* x, const float* y, float* z, const int } } +void srsran_vec_sc_sum_fff_simd(const float* x, float h, float* z, int len) +{ + int i = 0; + +#if SRSRAN_SIMD_F_SIZE + const simd_f_t hh = srsran_simd_f_set1(h); + if (SRSRAN_IS_ALIGNED(x) && SRSRAN_IS_ALIGNED(z)) { + for (; i < len - SRSRAN_SIMD_F_SIZE + 1; i += SRSRAN_SIMD_F_SIZE) { + simd_f_t xx = srsran_simd_f_load(&x[i]); + + simd_f_t zz = srsran_simd_f_add(xx, hh); + + srsran_simd_f_store(&z[i], zz); + } + } else { + for (; i < len - SRSRAN_SIMD_F_SIZE + 1; i += SRSRAN_SIMD_F_SIZE) { + simd_f_t xx = srsran_simd_f_loadu(&x[i]); + + simd_f_t zz = srsran_simd_f_add(xx, hh); + + srsran_simd_f_storeu(&z[i], zz); + } + } +#endif + + for (; i < len; i++) { + z[i] = x[i] + h; + } +} + cf_t srsran_vec_dot_prod_ccc_simd(const cf_t* x, const cf_t* y, const int len) { int i = 0; diff --git a/lib/src/radio/CMakeLists.txt b/lib/src/radio/CMakeLists.txt index 77b6570ca1..c8e214edf3 100644 --- a/lib/src/radio/CMakeLists.txt +++ b/lib/src/radio/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -21,7 +21,7 @@ if(RF_FOUND) add_library(srsran_radio STATIC radio.cc channel_mapping.cc) target_link_libraries(srsran_radio srsran_rf srsran_common) - INSTALL(TARGETS srsran_radio DESTINATION ${LIBRARY_DIR}) + install(TARGETS srsran_radio DESTINATION ${LIBRARY_DIR} OPTIONAL) endif(RF_FOUND) add_subdirectory(test) diff --git a/lib/src/radio/channel_mapping.cc b/lib/src/radio/channel_mapping.cc index a27d6df2c9..1c0c1aa128 100644 --- a/lib/src/radio/channel_mapping.cc +++ b/lib/src/radio/channel_mapping.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index f45bc6b106..8124185e65 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -112,11 +112,30 @@ int radio::init(const rf_args_t& args, phy_interface_radio* phy_) rx_channel_mapping.set_config(nof_channels_x_dev, nof_antennas); // Init and start Radios - for (uint32_t device_idx = 0; device_idx < (uint32_t)device_args_list.size(); device_idx++) { - if (not open_dev(device_idx, args.device_name, device_args_list[device_idx])) { - logger.error("Error opening RF device %d", device_idx); + if (args.device_name != "file" || device_args_list[0] != "auto") { + // regular RF device + for (uint32_t device_idx = 0; device_idx < (uint32_t)device_args_list.size(); device_idx++) { + if (not open_dev(device_idx, args.device_name, device_args_list[device_idx])) { + logger.error("Error opening RF device %d", device_idx); + return SRSRAN_ERROR; + } + } + } else { + // file-based RF device abstraction using pre-opened FILE* objects + if (args.rx_files == nullptr && args.tx_files == nullptr) { + logger.error("File-based RF device abstraction requested, but no files provided"); return SRSRAN_ERROR; } + for (uint32_t device_idx = 0; device_idx < (uint32_t)device_args_list.size(); device_idx++) { + if (not open_dev(device_idx, + &args.rx_files[device_idx * nof_channels_x_dev], + &args.tx_files[device_idx * nof_channels_x_dev], + nof_channels_x_dev, + args.srate_hz)) { + logger.error("Error opening RF device %d", device_idx); + return SRSRAN_ERROR; + } + } } is_start_of_burst = true; @@ -482,6 +501,29 @@ bool radio::open_dev(const uint32_t& device_idx, const std::string& device_name, return true; } +bool radio::open_dev(const uint32_t &device_idx, FILE** rx_files, FILE** tx_files, uint32_t nof_channels, uint32_t base_srate) +{ + srsran_rf_t* rf_device = &rf_devices[device_idx]; + + srsran::console("Opening channels idx %d in RF device abstraction\n", device_idx); + + if (srsran_rf_open_file(rf_device, rx_files, tx_files, nof_channels, base_srate)) { + logger.error("Error opening RF device abstraction"); + return false; + } + + // Suppress radio stdout + srsran_rf_suppress_stdout(rf_device); + + // Register handler for processing O/U/L + srsran_rf_register_error_handler(rf_device, rf_msg_callback, this); + + // Get device info + rf_info[device_idx] = *srsran_rf_get_info(rf_device); + + return true; +} + bool radio::tx_dev(const uint32_t& device_idx, rf_buffer_interface& buffer, const srsran_timestamp_t& tx_time_) { uint32_t nof_samples = buffer.get_nof_samples(); @@ -623,11 +665,11 @@ void radio::set_rx_freq(const uint32_t& carrier_idx, const double& freq) // Map carrier index to physical channel if (rx_channel_mapping.allocate_freq(carrier_idx, freq)) { channel_mapping::device_mapping_t device_mapping = rx_channel_mapping.get_device_mapping(carrier_idx); - if (device_mapping.carrier_idx >= nof_channels_x_dev) { - logger.error("Invalid mapping RF channel %d to logical carrier %d on f_rx=%.1f MHz", - device_mapping.carrier_idx, + if (device_mapping.channel_idx >= nof_channels_x_dev) { + logger.error("Invalid mapping physical channel %d to logical carrier %d on f_rx=%.1f MHz (nof_channels_x_dev=%d, device_idx=%d)", + device_mapping.channel_idx, carrier_idx, - freq / 1e6); + freq / 1e6, nof_channels_x_dev, device_mapping.device_idx); return; } @@ -642,9 +684,12 @@ void radio::set_rx_freq(const uint32_t& carrier_idx, const double& freq) cur_rx_freqs[device_mapping.carrier_idx] = freq; for (uint32_t i = 0; i < nof_antennas; i++) { channel_mapping::device_mapping_t dm = rx_channel_mapping.get_device_mapping(carrier_idx, i); - if (dm.device_idx >= rf_devices.size() or dm.carrier_idx >= nof_channels_x_dev) { - logger.error( - "Invalid port mapping %d:%d to logical carrier %d on f_rx=%.1f MHz", carrier_idx, i, freq / 1e6); + if (dm.device_idx >= rf_devices.size() or dm.channel_idx >= nof_channels_x_dev) { + logger.error("Invalid port mapping %d:%d to logical carrier %d on f_rx=%.1f MHz", + dm.device_idx, + dm.channel_idx, + carrier_idx, + freq / 1e6); return; } @@ -759,9 +804,9 @@ void radio::set_tx_freq(const uint32_t& carrier_idx, const double& freq) // Map carrier index to physical channel if (tx_channel_mapping.allocate_freq(carrier_idx, freq)) { channel_mapping::device_mapping_t device_mapping = tx_channel_mapping.get_device_mapping(carrier_idx); - if (device_mapping.carrier_idx >= nof_channels_x_dev) { - logger.error("Invalid mapping RF channel %d to logical carrier %d on f_tx=%.1f MHz", - device_mapping.carrier_idx, + if (device_mapping.channel_idx >= nof_channels_x_dev) { + logger.error("Invalid mapping physical channel %d to logical carrier %d on f_tx=%.1f MHz", + device_mapping.channel_idx, carrier_idx, freq / 1e6); return; @@ -778,9 +823,12 @@ void radio::set_tx_freq(const uint32_t& carrier_idx, const double& freq) cur_tx_freqs[device_mapping.carrier_idx] = freq; for (uint32_t i = 0; i < nof_antennas; i++) { device_mapping = tx_channel_mapping.get_device_mapping(carrier_idx, i); - if (device_mapping.device_idx >= rf_devices.size() or device_mapping.carrier_idx >= nof_channels_x_dev) { - logger.error( - "Invalid port mapping %d:%d to logical carrier %d on f_rx=%.1f MHz", carrier_idx, i, freq / 1e6); + if (device_mapping.device_idx >= rf_devices.size() or device_mapping.channel_idx >= nof_channels_x_dev) { + logger.error("Invalid port mapping %d:%d to logical carrier %d on f_rx=%.1f MHz", + device_mapping.device_idx, + device_mapping.channel_idx, + carrier_idx, + freq / 1e6); return; } diff --git a/lib/src/radio/test/CMakeLists.txt b/lib/src/radio/test/CMakeLists.txt index 5c88a7994c..5a5f0193dc 100644 --- a/lib/src/radio/test/CMakeLists.txt +++ b/lib/src/radio/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/radio/test/benchmark_radio.cc b/lib/src/radio/test/benchmark_radio.cc index b80a2293b2..20ef5ba758 100644 --- a/lib/src/radio/test/benchmark_radio.cc +++ b/lib/src/radio/test/benchmark_radio.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -65,6 +65,7 @@ static pthread_t radio_thread; #include "srsgui/srsgui.h" #include static pthread_t plot_thread; +static bool plot_thread_launched = false; static sem_t plot_sem; static uint32_t plot_sf_idx = 0; static plot_real_t fft_plot[SRSRAN_MAX_RADIOS] = {}; @@ -256,6 +257,7 @@ static int init_plots(uint32_t frame_size) perror("pthread_create"); exit(-1); } + plot_thread_launched = true; return SRSRAN_SUCCESS; } @@ -324,7 +326,10 @@ static void* radio_thread_run(void* arg) #ifdef ENABLE_GUI if (fft_plot_enable) { - init_plots(frame_size); + if (init_plots(frame_size) != SRSRAN_SUCCESS) { + ERROR("Error: Could not init plots"); + goto clean_exit; + } sleep(1); } #endif /* ENABLE_GUI */ @@ -583,18 +588,22 @@ static void* radio_thread_run(void* arg) srsran_dft_plan_free(&idft_plan); #ifdef ENABLE_GUI - pthread_join(plot_thread, NULL); - srsran_dft_plan_free(&dft_spectrum); - for (uint32_t r = 0; r < nof_radios; r++) { - for (uint32_t p = 0; p < nof_ports; p++) { - uint32_t plot_idx = r * nof_ports + p; - if (fft_plot_buffer[plot_idx]) { - free(fft_plot_buffer[plot_idx]); + if (fft_plot_enable) { + if (plot_thread_launched == true) { + pthread_join(plot_thread, NULL); + } + srsran_dft_plan_free(&dft_spectrum); + for (uint32_t r = 0; r < nof_radios; r++) { + for (uint32_t p = 0; p < nof_ports; p++) { + uint32_t plot_idx = r * nof_ports + p; + if (fft_plot_buffer[plot_idx]) { + free(fft_plot_buffer[plot_idx]); + } } } - } - if (fft_plot_temp) { - free(fft_plot_temp); + if (fft_plot_temp) { + free(fft_plot_temp); + } } #endif /* ENABLE_GUI */ diff --git a/lib/src/radio/test/test_radio_rt_gain.cc b/lib/src/radio/test/test_radio_rt_gain.cc index 640c3de499..6bee5c57f3 100644 --- a/lib/src/radio/test/test_radio_rt_gain.cc +++ b/lib/src/radio/test/test_radio_rt_gain.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/rlc/CMakeLists.txt b/lib/src/rlc/CMakeLists.txt index e954ab76d4..aed087c2f0 100644 --- a/lib/src/rlc/CMakeLists.txt +++ b/lib/src/rlc/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -22,12 +22,14 @@ set(SOURCES rlc.cc rlc_tm.cc rlc_um_base.cc rlc_um_lte.cc + rlc_um_nr.cc rlc_am_base.cc rlc_am_lte.cc - rlc_um_nr.cc rlc_am_nr.cc + rlc_am_lte_packing.cc + rlc_am_nr_packing.cc bearer_mem_pool.cc) add_library(srsran_rlc STATIC ${SOURCES}) target_link_libraries(srsran_rlc srsran_common ${ATOMIC_LIBS}) -INSTALL(TARGETS srsran_rlc DESTINATION ${LIBRARY_DIR}) +install(TARGETS srsran_rlc DESTINATION ${LIBRARY_DIR} OPTIONAL) diff --git a/lib/src/rlc/bearer_mem_pool.cc b/lib/src/rlc/bearer_mem_pool.cc index d3a17d3e97..9989612cae 100644 --- a/lib/src/rlc/bearer_mem_pool.cc +++ b/lib/src/rlc/bearer_mem_pool.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,6 +22,8 @@ #include "srsran/rlc/bearer_mem_pool.h" #include "srsran/adt/pool/batch_mem_pool.h" #include "srsran/rlc/rlc_am_lte.h" +#include "srsran/rlc/rlc_am_nr.h" +#include "srsran/rlc/rlc_tm.h" #include "srsran/rlc/rlc_um_lte.h" #include "srsran/rlc/rlc_um_nr.h" @@ -30,7 +32,11 @@ namespace srsran { srsran::background_mem_pool* get_bearer_pool() { static background_mem_pool pool( - 4, std::max(std::max(sizeof(rlc_am_lte), sizeof(rlc_um_lte)), sizeof(rlc_um_nr)), 8, 8); + 4, + std::max(std::max(std::max(std::max(sizeof(rlc_am), sizeof(rlc_am)), sizeof(rlc_um_lte)), sizeof(rlc_um_nr)), + sizeof(rlc_tm)), + 8, + 8); return &pool; } diff --git a/lib/src/rlc/rlc.cc b/lib/src/rlc/rlc.cc index 88f20c908e..5a69fb09e5 100644 --- a/lib/src/rlc/rlc.cc +++ b/lib/src/rlc/rlc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ #include "srsran/rlc/rlc.h" #include "srsran/common/rwlock_guard.h" -#include "srsran/rlc/rlc_am_lte.h" +#include "srsran/rlc/rlc_am_base.h" #include "srsran/rlc/rlc_tm.h" #include "srsran/rlc/rlc_um_lte.h" #include "srsran/rlc/rlc_um_nr.h" @@ -112,12 +112,12 @@ void rlc::get_metrics(rlc_metrics_t& m, const uint32_t nof_tti) double rx_rate_mbps = (nof_tti > 0) ? ((metrics.num_rx_pdu_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; double tx_rate_mbps = (nof_tti > 0) ? ((metrics.num_tx_pdu_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; - logger.info("lcid=%d, rx_rate_mbps=%4.2f (real=%4.2f), tx_rate_mbps=%4.2f (real=%4.2f)", - it->first, - rx_rate_mbps, - rx_rate_mbps_real_time, - tx_rate_mbps, - tx_rate_mbps_real_time); + logger.debug("lcid=%d, rx_rate_mbps=%4.2f (real=%4.2f), tx_rate_mbps=%4.2f (real=%4.2f)", + it->first, + rx_rate_mbps, + rx_rate_mbps_real_time, + tx_rate_mbps, + tx_rate_mbps_real_time); m.bearer[it->first] = metrics; } @@ -230,9 +230,12 @@ void rlc::write_sdu_mch(uint32_t lcid, unique_byte_buffer_t sdu) bool rlc::rb_is_um(uint32_t lcid) { bool ret = false; + uint32_t mch_idx = 0; // [TODO] if (valid_lcid(lcid)) { ret = rlc_array.at(lcid)->get_mode() == rlc_mode_t::um; + } else if (valid_lcid_mrb(mch_idx, lcid)) { + ret = rlc_array_mrb.at(mch_idx).at(lcid)->get_mode() == rlc_mode_t::um; } else { logger.warning("LCID %d doesn't exist.", lcid); } @@ -252,8 +255,11 @@ void rlc::discard_sdu(uint32_t lcid, uint32_t discard_sn) bool rlc::sdu_queue_is_full(uint32_t lcid) { + uint32_t mch_idx = 0; // [TODO] if (valid_lcid(lcid)) { return rlc_array.at(lcid)->sdu_queue_is_full(); + } else if (valid_lcid_mrb(mch_idx, lcid)) { + return rlc_array_mrb.at(mch_idx).at(lcid)->sdu_queue_is_full(); } logger.warning("RLC LCID %d doesn't exist. Ignoring queue check", lcid); return false; @@ -413,7 +419,7 @@ int rlc::add_bearer(uint32_t lcid, const rlc_config_t& cnfg) rwlock_write_guard lock(rwlock); if (valid_lcid(lcid)) { - logger.error("LCID %d already exists", lcid); + logger.warning("LCID %d already exists", lcid); return SRSRAN_ERROR; } @@ -426,7 +432,10 @@ int rlc::add_bearer(uint32_t lcid, const rlc_config_t& cnfg) case rlc_mode_t::am: switch (cnfg.rat) { case srsran_rat_t::lte: - rlc_entity = std::unique_ptr(new rlc_am_lte(logger, lcid, pdcp, rrc, timers)); + rlc_entity = std::unique_ptr(new rlc_am(cnfg.rat, logger, lcid, pdcp, rrc, timers)); + break; + case srsran_rat_t::nr: + rlc_entity = std::unique_ptr(new rlc_am(cnfg.rat, logger, lcid, pdcp, rrc, timers)); break; default: logger.error("AM not supported for this RAT"); @@ -467,7 +476,7 @@ int rlc::add_bearer(uint32_t lcid, const rlc_config_t& cnfg) rlc_entity->set_bsr_callback(bsr_callback); - if (not rlc_array.insert(rlc_map_pair_t(lcid, std::move(rlc_entity))).second) { + if (not rlc_array.emplace(lcid, std::move(rlc_entity)).second) { logger.error("Error inserting RLC entity in to array."); return SRSRAN_ERROR; } @@ -500,7 +509,7 @@ int rlc::add_bearer_mrb(uint32_t mch_idx, uint32_t lcid) } logger.info("Added bearer MRB%d with mode RLC_UM", lcid); } else { - logger.warning("Bearer MRB%d already created.", lcid); + logger.info("Bearer MRB%d already created.", lcid); } return SRSRAN_SUCCESS; @@ -549,7 +558,7 @@ void rlc::change_lcid(uint32_t old_lcid, uint32_t new_lcid) // insert old rlc entity into new LCID rlc_map_t::iterator it = rlc_array.find(old_lcid); std::unique_ptr rlc_entity = std::move(it->second); - if (not rlc_array.insert(rlc_map_pair_t(new_lcid, std::move(rlc_entity))).second) { + if (not rlc_array.emplace(new_lcid, std::move(rlc_entity)).second) { logger.error("Error inserting RLC entity into array."); return; } diff --git a/lib/src/rlc/rlc_am_base.cc b/lib/src/rlc/rlc_am_base.cc index c63b4776e1..3bcecedcc6 100644 --- a/lib/src/rlc/rlc_am_base.cc +++ b/lib/src/rlc/rlc_am_base.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,6 +20,8 @@ */ #include "srsran/rlc/rlc_am_base.h" +#include "srsran/rlc/rlc_am_lte.h" +#include "srsran/rlc/rlc_am_nr.h" #include namespace srsran { @@ -34,4 +36,284 @@ bool rlc_am_is_control_pdu(byte_buffer_t* pdu) return rlc_am_is_control_pdu(pdu->msg); } +/******************************************************* + * RLC AM entity + * This entity is common between LTE and NR + * and only the TX/RX entities change between them + *******************************************************/ +rlc_am::rlc_am(srsran_rat_t rat, + srslog::basic_logger& logger, + uint32_t lcid_, + srsue::pdcp_interface_rlc* pdcp_, + srsue::rrc_interface_rlc* rrc_, + srsran::timer_handler* timers_) : + rlc_common(logger), rrc(rrc_), pdcp(pdcp_), timers(timers_), lcid(lcid_) +{ + if (rat == srsran_rat_t::lte) { + rlc_am_lte_tx* tx = new rlc_am_lte_tx(this); + rlc_am_lte_rx* rx = new rlc_am_lte_rx(this); + tx_base = std::unique_ptr(tx); + rx_base = std::unique_ptr(rx); + tx->set_rx(rx); + rx->set_tx(tx); + } else if (rat == srsran_rat_t::nr) { + rlc_am_nr_tx* tx = new rlc_am_nr_tx(this); + rlc_am_nr_rx* rx = new rlc_am_nr_rx(this); + tx_base = std::unique_ptr(tx); + rx_base = std::unique_ptr(rx); + tx->set_rx(rx); + rx->set_tx(tx); + } else { + RlcError("Invalid RAT at entity initialization"); + } +} + +bool rlc_am::configure(const rlc_config_t& cfg_) +{ + // determine bearer name and configure rx/tx objects + rb_name = rrc->get_rb_name(lcid); + + // store configuration + cfg = cfg_; + + if (not rx_base->configure(cfg)) { + RlcError("Error configuring bearer (RX)"); + return false; + } + + if (not tx_base->configure(cfg)) { + RlcError("Error configuring bearer (TX)"); + return false; + } + + if (cfg.rat == srsran_rat_t::lte) { + RlcInfo("AM LTE configured - t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, " + "t_reordering=%d, t_status_prohibit=%d, tx_queue_length=%d", + cfg.am.t_poll_retx, + cfg.am.poll_pdu, + cfg.am.poll_byte, + cfg.am.max_retx_thresh, + cfg.am.t_reordering, + cfg.am.t_status_prohibit, + cfg.tx_queue_length); + } else if (cfg.rat == srsran_rat_t::nr) { + RlcInfo("AM NR configured - tx_sn_field_length=%d, rx_sn_field_length=%d, " + "t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, " + "max_retx_thresh=%d, t_reassembly=%d, t_status_prohibit=%d, tx_queue_length=%d", + to_number(cfg.am_nr.tx_sn_field_length), + to_number(cfg.am_nr.rx_sn_field_length), + cfg.am_nr.t_poll_retx, + cfg.am_nr.poll_pdu, + cfg.am_nr.poll_byte, + cfg.am_nr.max_retx_thresh, + cfg.am_nr.t_reassembly, + cfg.am_nr.t_status_prohibit, + cfg.tx_queue_length); + } else { + RlcError("Invalid RAT at entity configuration"); + } + return true; +} + +void rlc_am::stop() +{ + RlcDebug("Stopped bearer"); + tx_base->stop(); + rx_base->stop(); +} + +void rlc_am::reestablish() +{ + RlcDebug("Reestablished bearer"); + tx_base->reestablish(); // calls stop and enables tx again + rx_base->reestablish(); // calls only stop +} + +/**************************************************************************** + * PDCP interface + ***************************************************************************/ +void rlc_am::write_sdu(unique_byte_buffer_t sdu) +{ + uint32_t nof_bytes = sdu->N_bytes; + if (tx_base->write_sdu(std::move(sdu)) == SRSRAN_SUCCESS) { + std::lock_guard lock(metrics_mutex); + metrics.num_tx_sdus++; + metrics.num_tx_sdu_bytes += nof_bytes; + } +} + +void rlc_am::discard_sdu(uint32_t discard_sn) +{ + tx_base->discard_sdu(discard_sn); + + std::lock_guard lock(metrics_mutex); + metrics.num_lost_sdus++; +} + +bool rlc_am::sdu_queue_is_full() +{ + return tx_base->sdu_queue_is_full(); +} + +/**************************************************************************** + * MAC interface + ***************************************************************************/ +bool rlc_am::has_data() +{ + return tx_base->has_data(); +} + +uint32_t rlc_am::get_buffer_state() +{ + return tx_base->get_buffer_state(); +} + +void rlc_am::get_buffer_state(uint32_t& n_bytes_newtx, uint32_t& n_bytes_prio) +{ + tx_base->get_buffer_state(n_bytes_newtx, n_bytes_prio); + return; +} + +uint32_t rlc_am::read_pdu(uint8_t* payload, uint32_t nof_bytes) +{ + uint32_t read_bytes = tx_base->read_pdu(payload, nof_bytes); + + std::lock_guard lock(metrics_mutex); + metrics.num_tx_pdus += read_bytes > 0 ? 1 : 0; + metrics.num_tx_pdu_bytes += read_bytes; + return read_bytes; +} + +void rlc_am::write_pdu(uint8_t* payload, uint32_t nof_bytes) +{ + rx_base->write_pdu(payload, nof_bytes); + + std::lock_guard lock(metrics_mutex); + metrics.num_rx_pdus++; + metrics.num_rx_pdu_bytes += nof_bytes; +} + +/**************************************************************************** + * Metrics + ***************************************************************************/ +rlc_bearer_metrics_t rlc_am::get_metrics() +{ + // update values that aren't calculated on the fly + uint32_t latency = rx_base->get_sdu_rx_latency_ms(); + uint32_t buffered_bytes = rx_base->get_rx_buffered_bytes(); + + std::lock_guard lock(metrics_mutex); + metrics.rx_latency_ms = latency; + metrics.rx_buffered_bytes = buffered_bytes; + return metrics; +} + +void rlc_am::reset_metrics() +{ + std::lock_guard lock(metrics_mutex); + metrics = {}; +} + +/**************************************************************************** + * BSR callback + ***************************************************************************/ +void rlc_am::set_bsr_callback(bsr_callback_t callback) +{ + tx_base->set_bsr_callback(callback); +} + +/******************************************************* + * RLC AM TX entity + * This class is used for common code between the + * LTE and NR TX entities + *******************************************************/ +int rlc_am::rlc_am_base_tx::write_sdu(unique_byte_buffer_t sdu) +{ + std::lock_guard lock(mutex); + + if (!tx_enabled) { + return SRSRAN_ERROR; + } + + if (sdu.get() == nullptr) { + RlcWarning("NULL SDU pointer in write_sdu()"); + return SRSRAN_ERROR; + } + + // Get SDU info + uint32_t sdu_pdcp_sn = sdu->md.pdcp_sn; + + // Store SDU + uint8_t* msg_ptr = sdu->msg; + uint32_t nof_bytes = sdu->N_bytes; + srsran::error_type ret = tx_sdu_queue.try_write(std::move(sdu)); + if (ret) { + RlcHexInfo(msg_ptr, + nof_bytes, + "Tx SDU (%d B, PDCP_SN=%ld tx_sdu_queue_len=%d)", + nof_bytes, + sdu_pdcp_sn, + tx_sdu_queue.size()); + } else { + // in case of fail, the try_write returns back the sdu + RlcHexWarning(ret.error()->msg, + ret.error()->N_bytes, + "[Dropped SDU] Tx SDU (%d B, PDCP_SN=%ld, tx_sdu_queue_len=%d)", + ret.error()->N_bytes, + sdu_pdcp_sn, + tx_sdu_queue.size()); + return SRSRAN_ERROR; + } + + return SRSRAN_SUCCESS; +} + +void rlc_am::rlc_am_base_tx::discard_sdu(uint32_t discard_sn) +{ + std::lock_guard lock(mutex); + + if (!tx_enabled) { + return; + } + bool discarded = tx_sdu_queue.apply_first([&discard_sn, this](unique_byte_buffer_t& sdu) { + if (sdu != nullptr && sdu->md.pdcp_sn == discard_sn) { + tx_sdu_queue.queue.pop_func(sdu); + sdu = nullptr; + return true; + } + return false; + }); + + // Discard fails when the PDCP PDU is already in Tx window. + RlcInfo("%s PDU with PDCP_SN=%d", discarded ? "Discarding" : "Couldn't discard", discard_sn); +} + +bool rlc_am::rlc_am_base_tx::sdu_queue_is_full() +{ + return tx_sdu_queue.is_full(); +} + +void rlc_am::rlc_am_base_tx::set_bsr_callback(bsr_callback_t callback) +{ + bsr_callback = callback; +} + +/******************************************************* + * RLC AM RX entity + * This class is used for common code between the + * LTE and NR TX entities + *******************************************************/ +void rlc_am::rlc_am_base_rx::write_pdu(uint8_t* payload, const uint32_t nof_bytes) +{ + RlcInfo("Rx PDU - N bytes %d", nof_bytes); + if (nof_bytes < 1) { + return; + } + + if (rlc_am_is_control_pdu(payload)) { + parent->tx_base->handle_control_pdu(payload, nof_bytes); + } else { + handle_data_pdu(payload, nof_bytes); + } +} } // namespace srsran diff --git a/lib/src/rlc/rlc_am_lte.cc b/lib/src/rlc/rlc_am_lte.cc index d94034e5a3..f9b979d22b 100644 --- a/lib/src/rlc/rlc_am_lte.cc +++ b/lib/src/rlc/rlc_am_lte.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,304 +20,46 @@ */ #include "srsran/rlc/rlc_am_lte.h" -#include "srsran/common/string_helpers.h" #include "srsran/interfaces/ue_pdcp_interfaces.h" #include "srsran/interfaces/ue_rrc_interfaces.h" +#include "srsran/rlc/rlc_am_lte_packing.h" #include "srsran/srslog/event_trace.h" #include -#define MOD 1024 #define RX_MOD_BASE(x) (((x)-vr_r) % 1024) #define TX_MOD_BASE(x) (((x)-vt_a) % 1024) #define LCID (parent->lcid) -#define RB_NAME (parent->rb_name.c_str()) #define MAX_SDUS_PER_PDU (128) namespace srsran { -/******************************* - * Helper methods - ******************************/ - -/** - * Logs Status PDU into provided log channel, using fmt_str as format string - */ -template -void log_rlc_am_status_pdu_to_string(srslog::log_channel& log_ch, - const char* fmt_str, - rlc_status_pdu_t* status, - Args&&... args) -{ - if (not log_ch.enabled()) { - return; - } - fmt::memory_buffer buffer; - fmt::format_to(buffer, "ACK_SN = {}, N_nack = {}", status->ack_sn, status->N_nack); - if (status->N_nack > 0) { - fmt::format_to(buffer, ", NACK_SN = "); - for (uint32_t i = 0; i < status->N_nack; ++i) { - if (status->nacks[i].has_so) { - fmt::format_to( - buffer, "[{} {}:{}]", status->nacks[i].nack_sn, status->nacks[i].so_start, status->nacks[i].so_end); - } else { - fmt::format_to(buffer, "[{}]", status->nacks[i].nack_sn); - } - } - } - log_ch(fmt_str, std::forward(args)..., to_c_str(buffer)); -} - -/******************************* - * RLC AM Segments - ******************************/ - -int rlc_am_pdu_segment_pool::segment_resource::id() const -{ - return std::distance(parent_pool->segments.cbegin(), this); -} - -void rlc_am_pdu_segment_pool::segment_resource::release_pdcp_sn() -{ - pdcp_sn_ = invalid_pdcp_sn; - if (empty()) { - parent_pool->free_list.push_front(this); - } -} - -void rlc_am_pdu_segment_pool::segment_resource::release_rlc_sn() -{ - rlc_sn_ = invalid_rlc_sn; - if (empty()) { - parent_pool->free_list.push_front(this); - } -} - -rlc_am_pdu_segment_pool::rlc_am_pdu_segment_pool() -{ - for (segment_resource& s : segments) { - s.parent_pool = this; - free_list.push_front(&s); - } -} - -bool rlc_am_pdu_segment_pool::make_segment(rlc_amd_tx_pdu& rlc_list, pdcp_pdu_info& pdcp_list) -{ - if (not has_segments()) { - return false; - } - segment_resource* segment = free_list.pop_front(); - segment->rlc_sn_ = rlc_list.rlc_sn; - segment->pdcp_sn_ = pdcp_list.sn; - rlc_list.add_segment(*segment); - pdcp_list.add_segment(*segment); - return true; -} - -void pdcp_pdu_info::ack_segment(rlc_am_pdu_segment& segment) -{ - // remove from list - list.pop(&segment); - // signal pool that the pdcp handle is released - segment.release_pdcp_sn(); -} - -rlc_amd_tx_pdu::~rlc_amd_tx_pdu() -{ - while (not list.empty()) { - // remove from list - rlc_am_pdu_segment* segment = list.pop_front(); - // deallocate if also removed from PDCP - segment->release_rlc_sn(); - } -} - -/******************************* - * rlc_am_lte class - ******************************/ - -rlc_am_lte::rlc_am_lte(srslog::basic_logger& logger, - uint32_t lcid_, - srsue::pdcp_interface_rlc* pdcp_, - srsue::rrc_interface_rlc* rrc_, - srsran::timer_handler* timers_) : - logger(logger), rrc(rrc_), pdcp(pdcp_), timers(timers_), lcid(lcid_), tx(this), rx(this) -{} - -// Applies new configuration. Must be just reestablished or initiated -bool rlc_am_lte::configure(const rlc_config_t& cfg_) -{ - // determine bearer name and configure Rx/Tx objects - rb_name = rrc->get_rb_name(lcid); - - // store config - cfg = cfg_; - - if (not rx.configure(cfg.am)) { - logger.error("Error configuring bearer (RX)"); - return false; - } - - if (not tx.configure(cfg)) { - logger.error("Error configuring bearer (TX)"); - return false; - } - - logger.info("%s configured: t_poll_retx=%d, poll_pdu=%d, poll_byte=%d, max_retx_thresh=%d, " - "t_reordering=%d, t_status_prohibit=%d", - rb_name.c_str(), - cfg.am.t_poll_retx, - cfg.am.poll_pdu, - cfg.am.poll_byte, - cfg.am.max_retx_thresh, - cfg.am.t_reordering, - cfg.am.t_status_prohibit); - return true; -} - -void rlc_am_lte::set_bsr_callback(bsr_callback_t callback) -{ - tx.set_bsr_callback(callback); -} - -void rlc_am_lte::empty_queue() -{ - // Drop all messages in TX SDU queue - tx.empty_queue(); -} - -void rlc_am_lte::reestablish() -{ - logger.debug("Reestablished bearer %s", rb_name.c_str()); - tx.reestablish(); // calls stop and enables tx again - rx.reestablish(); // calls only stop -} - -void rlc_am_lte::stop() -{ - logger.debug("Stopped bearer %s", rb_name.c_str()); - tx.stop(); - rx.stop(); -} - -rlc_mode_t rlc_am_lte::get_mode() -{ - return rlc_mode_t::am; -} - -uint32_t rlc_am_lte::get_bearer() -{ - return lcid; -} - -rlc_bearer_metrics_t rlc_am_lte::get_metrics() -{ - // update values that aren't calculated on the fly - uint32_t latency = rx.get_sdu_rx_latency_ms(); - uint32_t buffered_bytes = rx.get_rx_buffered_bytes(); - - std::lock_guard lock(metrics_mutex); - metrics.rx_latency_ms = latency; - metrics.rx_buffered_bytes = buffered_bytes; - - return metrics; -} - -void rlc_am_lte::reset_metrics() -{ - std::lock_guard lock(metrics_mutex); - metrics = {}; -} - -/**************************************************************************** - * PDCP interface - ***************************************************************************/ - -void rlc_am_lte::write_sdu(unique_byte_buffer_t sdu) -{ - if (tx.write_sdu(std::move(sdu)) == SRSRAN_SUCCESS) { - std::lock_guard lock(metrics_mutex); - metrics.num_tx_sdus++; - } -} - -void rlc_am_lte::discard_sdu(uint32_t discard_sn) -{ - tx.discard_sdu(discard_sn); - - std::lock_guard lock(metrics_mutex); - metrics.num_lost_sdus++; -} - -bool rlc_am_lte::sdu_queue_is_full() -{ - return tx.sdu_queue_is_full(); -} - -/**************************************************************************** - * MAC interface - ***************************************************************************/ - -bool rlc_am_lte::has_data() -{ - return tx.has_data(); -} - -uint32_t rlc_am_lte::get_buffer_state() -{ - return tx.get_buffer_state(); -} - -void rlc_am_lte::get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue) -{ - tx.get_buffer_state(tx_queue, prio_tx_queue); -} - -uint32_t rlc_am_lte::read_pdu(uint8_t* payload, uint32_t nof_bytes) -{ - uint32_t read_bytes = tx.read_pdu(payload, nof_bytes); - - std::lock_guard lock(metrics_mutex); - metrics.num_tx_pdus++; - metrics.num_tx_pdu_bytes += read_bytes; - - return read_bytes; -} - -void rlc_am_lte::write_pdu(uint8_t* payload, uint32_t nof_bytes) -{ - rx.write_pdu(payload, nof_bytes); - - std::lock_guard lock(metrics_mutex); - metrics.num_rx_pdus++; - metrics.num_rx_pdu_bytes += nof_bytes; -} +using pdcp_pdu_info_lte = pdcp_pdu_info; +using rlc_amd_tx_pdu_lte = rlc_amd_tx_pdu; +using rlc_am_pdu_segment = rlc_am_pdu_segment_pool::segment_resource; /**************************************************************************** * Tx subclass implementation ***************************************************************************/ - -rlc_am_lte::rlc_am_lte_tx::rlc_am_lte_tx(rlc_am_lte* parent_) : +rlc_am_lte_tx::rlc_am_lte_tx(rlc_am* parent_) : parent(parent_), - logger(parent_->logger), pool(byte_buffer_pool::get_instance()), poll_retx_timer(parent_->timers->get_unique_timer()), - status_prohibit_timer(parent_->timers->get_unique_timer()) -{} - -rlc_am_lte::rlc_am_lte_tx::~rlc_am_lte_tx() {} - -void rlc_am_lte::rlc_am_lte_tx::set_bsr_callback(bsr_callback_t callback) + status_prohibit_timer(parent_->timers->get_unique_timer()), + rlc_am_base_tx(parent_->logger) { - bsr_callback = callback; + rx = dynamic_cast(parent->rx_base.get()); } -bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) +bool rlc_am_lte_tx::configure(const rlc_config_t& cfg_) { std::lock_guard lock(mutex); + + rb_name = parent->rb_name; + if (cfg_.tx_queue_length > MAX_SDUS_PER_RLC_PDU) { - logger.error("Configuring Tx queue length of %d PDUs too big. Maximum value is %d.", - cfg_.tx_queue_length, - MAX_SDUS_PER_RLC_PDU); + RlcError("Configuring Tx queue length of %d PDUs too big. Maximum value is %d.", + cfg_.tx_queue_length, + MAX_SDUS_PER_RLC_PDU); return false; } @@ -326,7 +68,7 @@ bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) // check timers if (not poll_retx_timer.is_valid() or not status_prohibit_timer.is_valid()) { - logger.error("Configuring RLC AM TX: timers not configured"); + RlcError("Configuring RLC AM TX: timers not configured"); return false; } @@ -349,13 +91,13 @@ bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) return true; } -void rlc_am_lte::rlc_am_lte_tx::stop() +void rlc_am_lte_tx::stop() { std::lock_guard lock(mutex); stop_nolock(); } -void rlc_am_lte::rlc_am_lte_tx::stop_nolock() +void rlc_am_lte_tx::stop_nolock() { empty_queue_nolock(); @@ -387,13 +129,13 @@ void rlc_am_lte::rlc_am_lte_tx::stop_nolock() undelivered_sdu_info_queue.clear(); } -void rlc_am_lte::rlc_am_lte_tx::empty_queue() +void rlc_am_lte_tx::empty_queue() { std::lock_guard lock(mutex); empty_queue_nolock(); } -void rlc_am_lte::rlc_am_lte_tx::empty_queue_nolock() +void rlc_am_lte_tx::empty_queue_nolock() { // deallocate all SDUs in transmit queue while (tx_sdu_queue.size() > 0) { @@ -407,20 +149,20 @@ void rlc_am_lte::rlc_am_lte_tx::empty_queue_nolock() tx_sdu.reset(); } -void rlc_am_lte::rlc_am_lte_tx::reestablish() +void rlc_am_lte_tx::reestablish() { std::lock_guard lock(mutex); stop_nolock(); tx_enabled = true; } -bool rlc_am_lte::rlc_am_lte_tx::do_status() +bool rlc_am_lte_tx::do_status() { - return parent->rx.get_do_status(); + return rx->get_do_status(); } // Function is supposed to return as fast as possible -bool rlc_am_lte::rlc_am_lte_tx::has_data() +bool rlc_am_lte_tx::has_data() { return (((do_status() && not status_prohibit_timer.is_running())) || // if we have a status PDU to transmit (not retx_queue.empty()) || // if we have a retransmission @@ -437,10 +179,10 @@ bool rlc_am_lte::rlc_am_lte_tx::has_data() * * @param sn The SN of the PDU to check */ -void rlc_am_lte::rlc_am_lte_tx::check_sn_reached_max_retx(uint32_t sn) +void rlc_am_lte_tx::check_sn_reached_max_retx(uint32_t sn) { if (tx_window[sn].retx_count == cfg.max_retx_thresh) { - logger.warning("%s Signaling max number of reTx=%d for SN=%d", RB_NAME, tx_window[sn].retx_count, sn); + RlcWarning("Signaling max number of reTx=%d for SN=%d", tx_window[sn].retx_count, sn); parent->rrc->max_retx_attempted(); srsran::pdcp_sn_vector_t pdcp_sns; for (const rlc_am_pdu_segment& segment : tx_window[sn]) { @@ -453,61 +195,63 @@ void rlc_am_lte::rlc_am_lte_tx::check_sn_reached_max_retx(uint32_t sn) } } -uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() +uint32_t rlc_am_lte_tx::get_buffer_state() { uint32_t new_tx_queue = 0, prio_tx_queue = 0; get_buffer_state(new_tx_queue, prio_tx_queue); return new_tx_queue + prio_tx_queue; } -void rlc_am_lte::rlc_am_lte_tx::get_buffer_state(uint32_t& n_bytes_newtx, uint32_t& n_bytes_prio) +void rlc_am_lte_tx::get_buffer_state(uint32_t& n_bytes_newtx, uint32_t& n_bytes_prio) { std::lock_guard lock(mutex); get_buffer_state_nolock(n_bytes_newtx, n_bytes_prio); } -void rlc_am_lte::rlc_am_lte_tx::get_buffer_state_nolock(uint32_t& n_bytes_newtx, uint32_t& n_bytes_prio) +void rlc_am_lte_tx::get_buffer_state_nolock(uint32_t& n_bytes_newtx, uint32_t& n_bytes_prio) { n_bytes_newtx = 0; n_bytes_prio = 0; uint32_t n_sdus = 0; - logger.debug("%s Buffer state - do_status=%s, status_prohibit_running=%s (%d/%d)", - RB_NAME, - do_status() ? "yes" : "no", - status_prohibit_timer.is_running() ? "yes" : "no", - status_prohibit_timer.time_elapsed(), - status_prohibit_timer.duration()); + if (not tx_enabled) { + return; + } + + RlcDebug("Buffer state - do_status=%s, status_prohibit_running=%s (%d/%d)", + do_status() ? "yes" : "no", + status_prohibit_timer.is_running() ? "yes" : "no", + status_prohibit_timer.time_elapsed(), + status_prohibit_timer.duration()); // Bytes needed for status report if (do_status() && not status_prohibit_timer.is_running()) { - n_bytes_prio += parent->rx.get_status_pdu_length(); - logger.debug("%s Buffer state - total status report: %d bytes", RB_NAME, n_bytes_prio); + n_bytes_prio += rx->get_status_pdu_length(); + RlcDebug("Buffer state - total status report: %d bytes", n_bytes_prio); } // Bytes needed for retx if (not retx_queue.empty()) { - rlc_amd_retx_t& retx = retx_queue.front(); - logger.debug("%s Buffer state - retx - SN=%d, Segment: %s, %d:%d", - RB_NAME, - retx.sn, - retx.is_segment ? "true" : "false", - retx.so_start, - retx.so_end); + rlc_amd_retx_lte_t& retx = retx_queue.front(); + RlcDebug("Buffer state - retx - SN=%d, Segment: %s, %d:%d", + retx.sn, + retx.is_segment ? "true" : "false", + retx.so_start, + retx.so_end); if (tx_window.has_sn(retx.sn)) { int req_bytes = required_buffer_size(retx); if (req_bytes < 0) { - logger.error("In get_buffer_state(): Removing retx.sn=%d from queue", retx.sn); + RlcError("In get_buffer_state(): Removing retx.sn=%d from queue", retx.sn); retx_queue.pop(); } else { n_bytes_prio += req_bytes; - logger.debug("Buffer state - retx: %d bytes", n_bytes_prio); + RlcDebug("Buffer state - retx: %d bytes", n_bytes_prio); } } } // Bytes needed for tx SDUs - if (tx_window.size() < 1024) { + if (not window_full()) { n_sdus = tx_sdu_queue.get_n_sdus(); n_bytes_newtx += tx_sdu_queue.size_bytes(); if (tx_sdu != NULL) { @@ -524,74 +268,16 @@ void rlc_am_lte::rlc_am_lte_tx::get_buffer_state_nolock(uint32_t& n_bytes_newtx, // Room needed for fixed header of data PDUs if (n_bytes_newtx > 0 && n_sdus > 0) { n_bytes_newtx += 2; // Two bytes for fixed header with SN length = 10 - logger.debug("%s Total buffer state - %d SDUs (%d B)", RB_NAME, n_sdus, n_bytes_newtx); + RlcDebug("Total buffer state - %d SDUs (%d B)", n_sdus, n_bytes_newtx); } if (bsr_callback) { + RlcDebug("Calling BSR callback - %d new_tx, %d prio bytes", n_bytes_newtx, n_bytes_prio); bsr_callback(parent->lcid, n_bytes_newtx, n_bytes_prio); } } -int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu) -{ - std::lock_guard lock(mutex); - - if (!tx_enabled) { - return SRSRAN_ERROR; - } - - if (sdu.get() == nullptr) { - logger.warning("NULL SDU pointer in write_sdu()"); - return SRSRAN_ERROR; - } - - // Get SDU info - uint32_t sdu_pdcp_sn = sdu->md.pdcp_sn; - - // Store SDU - uint8_t* msg_ptr = sdu->msg; - uint32_t nof_bytes = sdu->N_bytes; - srsran::error_type ret = tx_sdu_queue.try_write(std::move(sdu)); - if (ret) { - logger.info(msg_ptr, nof_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", RB_NAME, nof_bytes, tx_sdu_queue.size()); - } else { - // in case of fail, the try_write returns back the sdu - logger.warning(ret.error()->msg, - ret.error()->N_bytes, - "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", - RB_NAME, - ret.error()->N_bytes, - tx_sdu_queue.size()); - return SRSRAN_ERROR; - } - - return SRSRAN_SUCCESS; -} - -void rlc_am_lte::rlc_am_lte_tx::discard_sdu(uint32_t discard_sn) -{ - if (!tx_enabled) { - return; - } - - bool discarded = tx_sdu_queue.apply_first([&discard_sn, this](unique_byte_buffer_t& sdu) { - if (sdu != nullptr && sdu->md.pdcp_sn == discard_sn) { - tx_sdu_queue.queue.pop_func(sdu); - sdu = nullptr; - } - return false; - }); - - // Discard fails when the PDCP PDU is already in Tx window. - logger.info("%s PDU with PDCP_SN=%d", discarded ? "Discarding" : "Couldn't discard", discard_sn); -} - -bool rlc_am_lte::rlc_am_lte_tx::sdu_queue_is_full() -{ - return tx_sdu_queue.is_full(); -} - -uint32_t rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes) +uint32_t rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes) { std::lock_guard lock(mutex); @@ -599,11 +285,11 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_byte return 0; } - logger.debug("MAC opportunity - %d bytes", nof_bytes); - logger.debug("tx_window size - %zu PDUs", tx_window.size()); + RlcDebug("MAC opportunity - %d bytes", nof_bytes); + RlcDebug("tx_window size - %zu PDUs", tx_window.size()); if (not tx_enabled) { - logger.debug("RLC entity not active. Not generating PDU."); + RlcDebug("RLC entity not active. Not generating PDU."); return 0; } @@ -613,7 +299,7 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_byte } // Section 5.2.2.3 in TS 36.311, if tx_window is full and retx_queue empty, retransmit PDU - if (tx_window.size() >= RLC_AM_WINDOW_SIZE && retx_queue.empty()) { + if (window_full() && retx_queue.empty()) { retransmit_pdu(vt_a); } @@ -629,19 +315,19 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_byte return build_data_pdu(payload, nof_bytes); } -void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id) +void rlc_am_lte_tx::timer_expired(uint32_t timeout_id) { std::unique_lock lock(mutex); if (poll_retx_timer.is_valid() && poll_retx_timer.id() == timeout_id) { - logger.debug("%s Poll reTx timer expired after %dms", RB_NAME, poll_retx_timer.duration()); + RlcDebug("Poll retx timer expired after %dms", poll_retx_timer.duration()); // Section 5.2.2.3 in TS 36.322, schedule PDU for retransmission if // (a) both tx and retx buffer are empty (excluding tx'ed PDU waiting for ack), or // (b) no new data PDU can be transmitted (tx window is full) - if ((retx_queue.empty() && tx_sdu_queue.size() == 0) || tx_window.size() >= RLC_AM_WINDOW_SIZE) { + if ((retx_queue.empty() && tx_sdu_queue.size() == 0) || window_full()) { retransmit_pdu(vt_a); // TODO: TS says to send vt_s - 1 here } } else if (status_prohibit_timer.is_valid() && status_prohibit_timer.id() == timeout_id) { - logger.debug("%s Status prohibit timer expired after %dms", RB_NAME, status_prohibit_timer.duration()); + RlcDebug("Status prohibit timer expired after %dms", status_prohibit_timer.duration()); } if (bsr_callback) { @@ -650,37 +336,43 @@ void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id) } } -void rlc_am_lte::rlc_am_lte_tx::retransmit_pdu(uint32_t sn) +void rlc_am_lte_tx::retransmit_pdu(uint32_t sn) { if (tx_window.empty()) { - logger.warning("%s No PDU to retransmit", RB_NAME); + RlcWarning("No PDU to retransmit"); return; } if (not tx_window.has_sn(sn)) { - logger.warning("%s Can't retransmit unexisting SN=%d", RB_NAME, sn); + RlcWarning("Can't retransmit unexisting SN=%d", sn); return; } // select first PDU in tx window for retransmission - rlc_amd_tx_pdu& pdu = tx_window[sn]; + rlc_amd_tx_pdu_lte& pdu = tx_window[sn]; // increment retx counter and inform upper layers pdu.retx_count++; check_sn_reached_max_retx(sn); - logger.info("%s Schedule SN=%d for reTx", RB_NAME, pdu.rlc_sn); - rlc_amd_retx_t& retx = retx_queue.push(); - retx.is_segment = false; - retx.so_start = 0; - retx.so_end = pdu.buf->N_bytes; - retx.sn = pdu.rlc_sn; + RlcInfo("Schedule SN=%d for retx", pdu.rlc_sn); + + rlc_amd_retx_lte_t& retx = retx_queue.push(); + retx.is_segment = false; + retx.so_start = 0; + retx.so_end = pdu.buf->N_bytes; + retx.sn = pdu.rlc_sn; } /**************************************************************************** * Helper functions ***************************************************************************/ +bool rlc_am_lte_tx::window_full() +{ + return TX_MOD_BASE(vt_s) >= RLC_AM_WINDOW_SIZE; +}; + /** * Called when building a RLC PDU for checking whether the poll bit needs * to be set. @@ -689,49 +381,55 @@ void rlc_am_lte::rlc_am_lte_tx::retransmit_pdu(uint32_t sn) * * @return True if a status PDU needs to be requested, false otherwise. */ -bool rlc_am_lte::rlc_am_lte_tx::poll_required() +bool rlc_am_lte_tx::poll_required() { if (cfg.poll_pdu > 0 && pdu_without_poll > static_cast(cfg.poll_pdu)) { + RlcDebug("Poll required. Cause: PDU_WITHOUT_POLL > pollPdu."); return true; } if (cfg.poll_byte > 0 && byte_without_poll > static_cast(cfg.poll_byte)) { + RlcDebug("Poll required. Cause: BYTE_WITHOUT_POLL > pollByte."); return true; } if (poll_retx_timer.is_valid() && poll_retx_timer.is_expired()) { // re-arming of timer is handled by caller + RlcDebug("Poll required. Cause: t-PollRetransmission expired."); return true; } - if (tx_window.size() >= RLC_AM_WINDOW_SIZE) { + if (window_full()) { + RlcDebug("Poll required. Cause: TX window full."); return true; } if (tx_sdu_queue.size() == 0 && retx_queue.empty()) { + RlcDebug("Poll required. Cause: Empty TX and ReTX queues."); return true; } /* According to 5.2.2.1 in 36.322 v13.3.0 a poll should be requested if * the entire AM window is unacknowledged, i.e. no new PDU can be transmitted. - * However, it seems more appropiate to request more often if polling + * However, it seems more appropriate to request more often if polling * is disabled otherwise, e.g. every N PDUs. */ - if (cfg.poll_pdu == 0 && cfg.poll_byte == 0 && vt_s % poll_periodicity == 0) { + if (cfg.poll_pdu == 0 && cfg.poll_byte == 0 && vt_s % rlc_am::poll_periodicity == 0) { return true; } return false; } -int rlc_am_lte::rlc_am_lte_tx::build_status_pdu(uint8_t* payload, uint32_t nof_bytes) +int rlc_am_lte_tx::build_status_pdu(uint8_t* payload, uint32_t nof_bytes) { - int pdu_len = parent->rx.get_status_pdu(&tx_status, nof_bytes); + RlcDebug("Generating status PDU. Nof bytes %d", nof_bytes); + int pdu_len = rx->get_status_pdu(&tx_status, nof_bytes); if (pdu_len == SRSRAN_ERROR) { - logger.debug("%s Deferred Status PDU. Cause: Failed to acquire Rx lock", RB_NAME); + RlcDebug("Deferred Status PDU. Cause: Failed to acquire Rx lock"); pdu_len = 0; } else if (pdu_len > 0 && nof_bytes >= static_cast(pdu_len)) { - log_rlc_am_status_pdu_to_string(logger.info, "%s Tx status PDU - %s", &tx_status, RB_NAME); + log_rlc_am_status_pdu_to_string(logger.info, rb_name, "Tx status PDU - %s", &tx_status); if (cfg.t_status_prohibit > 0 && status_prohibit_timer.is_valid()) { // re-arm timer status_prohibit_timer.run(); @@ -739,22 +437,22 @@ int rlc_am_lte::rlc_am_lte_tx::build_status_pdu(uint8_t* payload, uint32_t nof_b debug_state(); pdu_len = rlc_am_write_status_pdu(&tx_status, payload); } else { - logger.info("%s Cannot tx status PDU - %d bytes available, %d bytes required", RB_NAME, nof_bytes, pdu_len); + RlcInfo("Cannot tx status PDU - %d bytes available, %d bytes required", nof_bytes, pdu_len); pdu_len = 0; } return pdu_len; } -int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_bytes) +int rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_bytes) { // Check there is at least 1 element before calling front() if (retx_queue.empty()) { - logger.error("In build_retx_pdu(): retx_queue is empty"); + RlcError("In build_retx_pdu(): retx_queue is empty"); return -1; } - rlc_amd_retx_t retx = retx_queue.front(); + rlc_amd_retx_lte_t retx = retx_queue.front(); // Sanity check - drop any retx SNs not present in tx_window while (not tx_window.has_sn(retx.sn)) { @@ -762,7 +460,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt if (!retx_queue.empty()) { retx = retx_queue.front(); } else { - logger.info("%s SN=%d not in Tx window. Ignoring retx.", RB_NAME, retx.sn); + RlcInfo("SN=%d not in Tx window. Ignoring retx.", retx.sn); if (tx_window.has_sn(vt_a)) { // schedule next SN for retx retransmit_pdu(vt_a); @@ -777,13 +475,13 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt // Is resegmentation needed? int req_size = required_buffer_size(retx); if (req_size < 0) { - logger.error("In build_retx_pdu(): Removing retx.sn=%d from queue", retx.sn); + RlcError("In build_retx_pdu(): Removing retx.sn=%d from queue", retx.sn); retx_queue.pop(); return -1; } if (retx.is_segment || req_size > static_cast(nof_bytes)) { - logger.debug("%s build_retx_pdu - resegmentation required", RB_NAME); + RlcDebug("build_retx_pdu - resegmentation required"); return build_segment(payload, nof_bytes, retx); } @@ -794,8 +492,8 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt // Set poll bit pdu_without_poll++; byte_without_poll += (tx_window[retx.sn].buf->N_bytes + rlc_am_packed_length(&new_header)); - logger.info("%s pdu_without_poll: %d", RB_NAME, pdu_without_poll); - logger.info("%s byte_without_poll: %d", RB_NAME, byte_without_poll); + RlcInfo("pdu_without_poll: %d", pdu_without_poll); + RlcInfo("byte_without_poll: %d", byte_without_poll); if (poll_required()) { new_header.p = 1; // vt_s won't change for reTx, so don't update poll_sn @@ -803,6 +501,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt byte_without_poll = 0; if (poll_retx_timer.is_valid()) { // re-arm timer (will be stopped when status PDU is received) + RlcDebug("re-arming retx timer"); poll_retx_timer.run(); } } @@ -813,24 +512,23 @@ int rlc_am_lte::rlc_am_lte_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_byt retx_queue.pop(); - logger.info(payload, - tx_window[retx.sn].buf->N_bytes, - "%s Tx PDU SN=%d (%d B) (attempt %d/%d)", - RB_NAME, - retx.sn, - tx_window[retx.sn].buf->N_bytes, - tx_window[retx.sn].retx_count + 1, - cfg.max_retx_thresh); - log_rlc_amd_pdu_header_to_string(logger.debug, new_header); + RlcHexInfo(payload, + tx_window[retx.sn].buf->N_bytes, + "Tx PDU SN=%d (%d B) (attempt %d/%d)", + retx.sn, + tx_window[retx.sn].buf->N_bytes, + tx_window[retx.sn].retx_count + 1, + cfg.max_retx_thresh); + log_rlc_amd_pdu_header_to_string(logger.debug, rb_name, "Tx PDU - %s", new_header); debug_state(); return (ptr - payload) + tx_window[retx.sn].buf->N_bytes; } -int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_retx_t retx) +int rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_retx_lte_t retx) { if (tx_window[retx.sn].buf == NULL) { - logger.error("In build_segment: retx.sn=%d has null buffer", retx.sn); + RlcError("In build_segment: retx.sn=%d has null buffer", retx.sn); return 0; } if (!retx.is_segment) { @@ -844,8 +542,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte pdu_without_poll++; byte_without_poll += (tx_window[retx.sn].buf->N_bytes + rlc_am_packed_length(&new_header)); - logger.info("%s pdu_without_poll: %d", RB_NAME, pdu_without_poll); - logger.info("%s byte_without_poll: %d", RB_NAME, byte_without_poll); + RlcInfo("pdu_without_poll: %d, byte_without_poll: %d", pdu_without_poll, byte_without_poll); new_header.dc = RLC_DC_FIELD_DATA_PDU; new_header.rf = 1; @@ -854,17 +551,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte new_header.lsf = 0; new_header.so = retx.so_start; new_header.N_li = 0; - new_header.p = 0; - if (poll_required()) { - logger.debug("%s setting poll bit to request status", RB_NAME); - new_header.p = 1; - // vt_s won't change for reTx, so don't update poll_sn - pdu_without_poll = 0; - byte_without_poll = 0; - if (poll_retx_timer.is_valid()) { - poll_retx_timer.run(); - } - } + new_header.p = 0; // Poll Requirements are done later after updating RETX queue uint32_t head_len = 0; uint32_t pdu_space = 0; @@ -876,10 +563,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte } if (nof_bytes <= head_len) { - logger.info("%s Cannot build a PDU segment - %d bytes available, %d bytes required for header", - RB_NAME, - nof_bytes, - head_len); + RlcInfo("Cannot build a PDU segment - %d bytes available, %d bytes required for header", nof_bytes, head_len); return 0; } @@ -970,6 +654,18 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte retx_queue.front().so_start = retx.so_end; } + // Check POLL requeriments for segment + if (poll_required()) { + RlcDebug("setting poll bit to request status"); + new_header.p = 1; + // vt_s won't change for reTx, so don't update poll_sn + pdu_without_poll = 0; + byte_without_poll = 0; + if (poll_retx_timer.is_valid()) { + poll_retx_timer.run(); + } + } + // Write header and pdu uint8_t* ptr = payload; rlc_am_write_data_pdu_header(&new_header, &ptr); @@ -980,46 +676,43 @@ int rlc_am_lte::rlc_am_lte_tx::build_segment(uint8_t* payload, uint32_t nof_byte debug_state(); int pdu_len = (ptr - payload) + len; if (pdu_len > static_cast(nof_bytes)) { - logger.error("%s Retx PDU segment length error. Available: %d, Used: %d", RB_NAME, nof_bytes, pdu_len); + RlcError("Retx PDU segment length error. Available: %d, Used: %d", nof_bytes, pdu_len); int header_len = (ptr - payload); - logger.debug("%s Retx PDU segment length error. Actual header len: %d, Payload len: %d, N_li: %d", - RB_NAME, - header_len, - len, - new_header.N_li); - } - - logger.info(payload, - pdu_len, - "%s Retx PDU segment SN=%d [so=%d] (%d B) (attempt %d/%d)", - RB_NAME, - retx.sn, - retx.so_start, - pdu_len, - tx_window[retx.sn].retx_count + 1, - cfg.max_retx_thresh); + RlcDebug("Retx PDU segment length error. Actual header len: %d, Payload len: %d, N_li: %d", + header_len, + len, + new_header.N_li); + } + + RlcHexInfo(payload, + pdu_len, + "retx PDU segment SN=%d [so=%d] (%d B) (attempt %d/%d)", + retx.sn, + retx.so_start, + pdu_len, + tx_window[retx.sn].retx_count + 1, + cfg.max_retx_thresh); return pdu_len; } -int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_bytes) +int rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_bytes) { if (tx_sdu == NULL && tx_sdu_queue.is_empty()) { - logger.info("No data available to be sent"); + RlcInfo("No data available to be sent"); return 0; } // do not build any more PDU if window is already full - if (tx_sdu == NULL && tx_window.size() >= RLC_AM_WINDOW_SIZE) { - logger.info("Tx window full."); + if (window_full()) { + RlcInfo("Cannot build data PDU - Tx window full."); return 0; } if (nof_bytes < RLC_AM_MIN_DATA_PDU_SIZE) { - logger.info("%s Cannot build data PDU - %d bytes available but at least %d bytes are required ", - RB_NAME, - nof_bytes, - RLC_AM_MIN_DATA_PDU_SIZE); + RlcInfo("Cannot build data PDU - %d bytes available but at least %d bytes are required ", + nof_bytes, + RLC_AM_MIN_DATA_PDU_SIZE); return 0; } @@ -1036,7 +729,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt } exit(-1); #else - logger.error("Fatal Error: Couldn't allocate PDU in build_data_pdu()."); + RlcError("Fatal Error: Couldn't allocate PDU in build_data_pdu()."); return 0; #endif } @@ -1046,13 +739,13 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt header.sn = vt_s; if (not segment_pool.has_segments()) { - logger.info("Can't build a PDU - No segments available"); + RlcInfo("Can't build a PDU - No segments available"); return 0; } // insert newly assigned SN into window and use reference for in-place operations // NOTE: from now on, we can't return from this function anymore before increasing vt_s - rlc_amd_tx_pdu& tx_pdu = tx_window.add_pdu(header.sn); + rlc_amd_tx_pdu_lte& tx_pdu = tx_window.add_pdu(header.sn); uint32_t head_len = rlc_am_packed_length(&header); uint32_t to_move = 0; @@ -1060,7 +753,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt uint32_t pdu_space = SRSRAN_MIN(nof_bytes, pdu->get_tailroom()); uint8_t* pdu_ptr = pdu->msg; - logger.debug("%s Building PDU - pdu_space: %d, head_len: %d ", RB_NAME, pdu_space, head_len); + RlcDebug("Building PDU - pdu_space: %d, head_len: %d ", pdu_space, head_len); // Check for SDU segment if (tx_sdu != nullptr) { @@ -1072,18 +765,18 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt tx_sdu->N_bytes -= to_move; tx_sdu->msg += to_move; if (undelivered_sdu_info_queue.has_pdcp_sn(tx_sdu->md.pdcp_sn)) { - pdcp_pdu_info& pdcp_pdu = undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn]; + pdcp_pdu_info_lte& pdcp_pdu = undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn]; segment_pool.make_segment(tx_pdu, pdcp_pdu); if (tx_sdu->N_bytes == 0) { pdcp_pdu.fully_txed = true; } } else { // PDCP SNs for the RLC SDU has been removed from the queue - logger.warning("Couldn't find PDCP_SN=%d in SDU info queue (segment)", tx_sdu->md.pdcp_sn); + RlcWarning("Couldn't find PDCP_SN=%d in SDU info queue (segment)", tx_sdu->md.pdcp_sn); } if (tx_sdu->N_bytes == 0) { - logger.debug("%s Complete SDU scheduled for tx.", RB_NAME); + RlcDebug("Complete SDU scheduled for tx."); tx_sdu.reset(); } if (pdu_space > to_move) { @@ -1093,19 +786,17 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt } header.fi |= RLC_FI_FIELD_NOT_START_ALIGNED; // First byte does not correspond to first byte of SDU - logger.debug( - "%s Building PDU - added SDU segment from previous PDU (len:%d) - pdu_space: %d, head_len: %d header_sn=%d", - RB_NAME, - to_move, - pdu_space, - head_len, - header.sn); + RlcDebug("Building PDU - added SDU segment from previous PDU (len:%d) - pdu_space: %d, head_len: %d header_sn=%d", + to_move, + pdu_space, + head_len, + header.sn); } // Pull SDUs from queue while (pdu_space > head_len && tx_sdu_queue.get_n_sdus() > 0 && header.N_li < MAX_SDUS_PER_PDU) { if (not segment_pool.has_segments()) { - logger.info("Can't build a PDU segment - No segment resources available"); + RlcInfo("Can't build a PDU segment - No segment resources available"); if (pdu_ptr != pdu->msg) { break; // continue with the segments created up to this point } @@ -1136,14 +827,14 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt // store sdu info if (undelivered_sdu_info_queue.has_pdcp_sn(tx_sdu->md.pdcp_sn)) { - logger.warning("PDCP_SN=%d already marked as undelivered", tx_sdu->md.pdcp_sn); + RlcWarning("PDCP_SN=%d already marked as undelivered", tx_sdu->md.pdcp_sn); } else { - logger.debug("marking pdcp_sn=%d as undelivered (queue_len=%ld)", - tx_sdu->md.pdcp_sn, - undelivered_sdu_info_queue.nof_sdus()); + RlcDebug("marking pdcp_sn=%d as undelivered (queue_len=%ld)", + tx_sdu->md.pdcp_sn, + undelivered_sdu_info_queue.nof_sdus()); undelivered_sdu_info_queue.add_pdcp_sdu(tx_sdu->md.pdcp_sn); } - pdcp_pdu_info& pdcp_pdu = undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn]; + pdcp_pdu_info_lte& pdcp_pdu = undelivered_sdu_info_queue[tx_sdu->md.pdcp_sn]; to_move = ((pdu_space - head_len) >= tx_sdu->N_bytes) ? tx_sdu->N_bytes : pdu_space - head_len; memcpy(pdu_ptr, tx_sdu->msg, to_move); @@ -1158,7 +849,7 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt } if (tx_sdu->N_bytes == 0) { - logger.debug("%s Complete SDU scheduled for tx. PDCP SN=%d", RB_NAME, tx_sdu->md.pdcp_sn); + RlcDebug("Complete SDU scheduled for tx. PDCP SN=%d", tx_sdu->md.pdcp_sn); tx_sdu.reset(); } if (pdu_space > to_move) { @@ -1167,16 +858,12 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt pdu_space = 0; } - logger.debug("%s Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d ", - RB_NAME, - to_move, - pdu_space, - head_len); + RlcDebug("Building PDU - added SDU segment (len:%d) - pdu_space: %d, head_len: %d ", to_move, pdu_space, head_len); } // Make sure, at least one SDU (segment) has been added until this point if (pdu->N_bytes == 0) { - logger.error("Generated empty RLC PDU."); + RlcError("Generated empty RLC PDU."); } if (tx_sdu != NULL) { @@ -1186,10 +873,10 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt // Set Poll bit pdu_without_poll++; byte_without_poll += (pdu->N_bytes + head_len); - logger.debug("%s pdu_without_poll: %d", RB_NAME, pdu_without_poll); - logger.debug("%s byte_without_poll: %d", RB_NAME, byte_without_poll); + RlcDebug("pdu_without_poll: %d", pdu_without_poll); + RlcDebug("byte_without_poll: %d", byte_without_poll); if (poll_required()) { - logger.debug("%s setting poll bit to request status", RB_NAME); + RlcDebug("setting poll bit to request status"); header.p = 1; poll_sn = vt_s; pdu_without_poll = 0; @@ -1211,14 +898,14 @@ int rlc_am_lte::rlc_am_lte_tx::build_data_pdu(uint8_t* payload, uint32_t nof_byt rlc_am_write_data_pdu_header(&header, &ptr); memcpy(ptr, buffer_ptr->msg, buffer_ptr->N_bytes); int total_len = (ptr - payload) + buffer_ptr->N_bytes; - logger.info(payload, total_len, "%s Tx PDU SN=%d (%d B)", RB_NAME, header.sn, total_len); - log_rlc_amd_pdu_header_to_string(logger.debug, header); + RlcHexInfo(payload, total_len, "Tx PDU SN=%d (%d B)", header.sn, total_len); + log_rlc_amd_pdu_header_to_string(logger.debug, rb_name, "%s", header); debug_state(); return total_len; } -void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) +void rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) { if (not tx_enabled) { return; @@ -1232,27 +919,23 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no { std::lock_guard lock(mutex); - logger.debug(payload, nof_bytes, "%s Rx control PDU", RB_NAME); + RlcHexDebug(payload, nof_bytes, "Rx control PDU"); rlc_am_read_status_pdu(payload, nof_bytes, &status); - log_rlc_am_status_pdu_to_string(logger.info, "%s Rx Status PDU: %s", &status, RB_NAME); + log_rlc_am_status_pdu_to_string(logger.info, rb_name, "Rx Status PDU %s", &status); // make sure ACK_SN is within our Tx window if (((MOD + status.ack_sn - vt_a) % MOD > RLC_AM_WINDOW_SIZE) || ((MOD + vt_s - status.ack_sn) % MOD > RLC_AM_WINDOW_SIZE)) { - logger.warning("%s Received invalid status PDU (ack_sn=%d, vt_a=%d, vt_s=%d). Dropping PDU.", - RB_NAME, - status.ack_sn, - vt_a, - vt_s); + RlcWarning("Received invalid status PDU (ack_sn=%d, vt_a=%d, vt_s=%d). Dropping PDU.", status.ack_sn, vt_a, vt_s); return; } // Sec 5.2.2.2, stop poll reTx timer if status PDU comprises a positive _or_ negative acknowledgement // for the RLC data PDU with sequence number poll_sn if (poll_retx_timer.is_valid() && (TX_MOD_BASE(poll_sn) < TX_MOD_BASE(status.ack_sn))) { - logger.debug("%s Stopping pollRetx timer", RB_NAME); + RlcDebug("Stopping pollRetx timer"); poll_retx_timer.stop(); } @@ -1282,7 +965,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no pdu.retx_count++; check_sn_reached_max_retx(i); - rlc_amd_retx_t& retx = retx_queue.push(); + rlc_amd_retx_lte_t& retx = retx_queue.push(); srsran_expect(tx_window[i].rlc_sn == i, "Incorrect RLC SN=%d!=%d being accessed", tx_window[i].rlc_sn, i); retx.sn = i; retx.is_segment = false; @@ -1293,8 +976,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no // sanity check if (status.nacks[j].so_start >= pdu.buf->N_bytes) { // print error but try to send original PDU again - logger.info( - "SO_start is larger than original PDU (%d >= %d)", status.nacks[j].so_start, pdu.buf->N_bytes); + RlcInfo("SO_start is larger than original PDU (%d >= %d)", status.nacks[j].so_start, pdu.buf->N_bytes); status.nacks[j].so_start = 0; } @@ -1309,19 +991,18 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no retx.is_segment = true; retx.so_start = status.nacks[j].so_start; } else { - logger.warning("%s invalid segment NACK received for SN %d. so_start: %d, so_end: %d, N_bytes: %d", - RB_NAME, - i, - status.nacks[j].so_start, - status.nacks[j].so_end, - pdu.buf->N_bytes); + RlcWarning("invalid segment NACK received for SN %d. so_start: %d, so_end: %d, N_bytes: %d", + i, + status.nacks[j].so_start, + status.nacks[j].so_end, + pdu.buf->N_bytes); } } } else { - logger.info("%s NACKed SN=%d already considered for retransmission", RB_NAME, i); + RlcInfo("NACKed SN=%d already considered for retransmission", i); } } else { - logger.error("%s NACKed SN=%d already removed from Tx window", RB_NAME, i); + RlcError("NACKed SN=%d already removed from Tx window", i); } } } @@ -1331,7 +1012,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no std::lock_guard lock(mutex); if (tx_window.has_sn(i)) { update_notification_ack_info(i); - logger.debug("Tx PDU SN=%zd being removed from tx window", i); + RlcDebug("Tx PDU SN=%zd being removed from tx window", i); tx_window.remove_pdu(i); } // Advance window if possible @@ -1347,7 +1028,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no // Make sure vt_a points to valid SN std::lock_guard lock(mutex); if (not tx_window.empty() && not tx_window.has_sn(vt_a)) { - logger.error("%s vt_a=%d points to invalid position in Tx window.", RB_NAME, vt_a); + RlcError("vt_a=%d points to invalid position in Tx window.", vt_a); parent->rrc->protocol_failure(); } } @@ -1366,12 +1047,12 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no * @tx_pdu: RLC PDU that was ack'ed. * @notify_info_vec: Vector which will keep track of the PDCP PDU SNs that have been fully ack'ed. */ -void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(uint32_t rlc_sn) +void rlc_am_lte_tx::update_notification_ack_info(uint32_t rlc_sn) { - logger.debug("Updating ACK info: RLC SN=%d, number of notified SDU=%ld, number of undelivered SDUs=%ld", - rlc_sn, - notify_info_vec.size(), - undelivered_sdu_info_queue.nof_sdus()); + RlcDebug("Updating ACK info: RLC SN=%d, number of notified SDU=%ld, number of undelivered SDUs=%ld", + rlc_sn, + notify_info_vec.size(), + undelivered_sdu_info_queue.nof_sdus()); // Iterate over all undelivered SDUs if (not tx_window.has_sn(rlc_sn)) { return; @@ -1381,10 +1062,10 @@ void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(uint32_t rlc_sn) for (rlc_am_pdu_segment& acked_segment : acked_pdu) { uint32_t pdcp_sn = acked_segment.pdcp_sn(); if (pdcp_sn == rlc_am_pdu_segment::invalid_pdcp_sn) { - logger.debug("ACKed segment in RLC_SN=%d already discarded in PDCP. No need to notify the PDCP.", rlc_sn); + RlcDebug("ACKed segment in RLC_SN=%d already discarded in PDCP. No need to notify the PDCP.", rlc_sn); continue; } - pdcp_pdu_info& info = undelivered_sdu_info_queue[pdcp_sn]; + pdcp_pdu_info_lte& info = undelivered_sdu_info_queue[pdcp_sn]; // Remove RLC SN from PDCP PDU undelivered list info.ack_segment(acked_segment); @@ -1395,31 +1076,31 @@ void rlc_am_lte::rlc_am_lte_tx::update_notification_ack_info(uint32_t rlc_sn) if (not notify_info_vec.full()) { notify_info_vec.push_back(pdcp_sn); } else { - logger.warning("Can't notify delivery of PDCP_SN=%d.", pdcp_sn); + RlcWarning("Can't notify delivery of PDCP_SN=%d.", pdcp_sn); } - logger.debug("Erasing SDU info: PDCP_SN=%d", pdcp_sn); + RlcDebug("Erasing SDU info: PDCP_SN=%d", pdcp_sn); undelivered_sdu_info_queue.clear_pdcp_sdu(pdcp_sn); } } } -void rlc_am_lte::rlc_am_lte_tx::debug_state() +void rlc_am_lte_tx::debug_state() { - logger.debug("%s vt_a = %d, vt_ms = %d, vt_s = %d, poll_sn = %d", RB_NAME, vt_a, vt_ms, vt_s, poll_sn); + RlcDebug("vt_a = %d, vt_ms = %d, vt_s = %d, poll_sn = %d", vt_a, vt_ms, vt_s, poll_sn); } -int rlc_am_lte::rlc_am_lte_tx::required_buffer_size(const rlc_amd_retx_t& retx) +int rlc_am_lte_tx::required_buffer_size(const rlc_amd_retx_lte_t& retx) { if (!retx.is_segment) { if (tx_window.has_sn(retx.sn)) { if (tx_window[retx.sn].buf) { return rlc_am_packed_length(&tx_window[retx.sn].header) + tx_window[retx.sn].buf->N_bytes; } else { - logger.warning("retx.sn=%d has null ptr in required_buffer_size()", retx.sn); + RlcWarning("retx.sn=%d has null ptr in required_buffer_size()", retx.sn); return -1; } } else { - logger.warning("retx.sn=%d does not exist in required_buffer_size()", retx.sn); + RlcWarning("retx.sn=%d does not exist in required_buffer_size()", retx.sn); return -1; } } @@ -1484,24 +1165,24 @@ int rlc_am_lte::rlc_am_lte_tx::required_buffer_size(const rlc_amd_retx_t& retx) /**************************************************************************** * Rx subclass implementation ***************************************************************************/ - -rlc_am_lte::rlc_am_lte_rx::rlc_am_lte_rx(rlc_am_lte* parent_) : +rlc_am_lte_rx::rlc_am_lte_rx(rlc_am* parent_) : parent(parent_), pool(byte_buffer_pool::get_instance()), - logger(parent_->logger), - reordering_timer(parent_->timers->get_unique_timer()) -{} - -rlc_am_lte::rlc_am_lte_rx::~rlc_am_lte_rx() {} + reordering_timer(parent_->timers->get_unique_timer()), + rlc_am_base_rx(parent_, parent_->logger) +{ +} -bool rlc_am_lte::rlc_am_lte_rx::configure(rlc_am_config_t cfg_) +bool rlc_am_lte_rx::configure(const rlc_config_t& cfg_) { // TODO: add config checks - cfg = cfg_; + cfg = cfg_.am; + + rb_name = parent->rb_name; // check timers if (not reordering_timer.is_valid()) { - logger.error("Configuring RLC AM TX: timers not configured"); + RlcError("Configuring RLC AM TX: timers not configured"); return false; } @@ -1513,12 +1194,12 @@ bool rlc_am_lte::rlc_am_lte_rx::configure(rlc_am_config_t cfg_) return true; } -void rlc_am_lte::rlc_am_lte_rx::reestablish() +void rlc_am_lte_rx::reestablish() { stop(); } -void rlc_am_lte::rlc_am_lte_rx::stop() +void rlc_am_lte_rx::stop() { std::lock_guard lock(mutex); @@ -1544,18 +1225,41 @@ void rlc_am_lte::rlc_am_lte_rx::stop() rx_window.clear(); } +/** Called from stack thread when MAC has received a new RLC PDU + * + * @param payload Pointer to payload + * @param nof_bytes Payload length + */ +void rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_bytes) +{ + std::lock_guard lock(mutex); + + rlc_amd_pdu_header_t header = {}; + uint32_t payload_len = nof_bytes; + rlc_am_read_data_pdu_header(&payload, &payload_len, &header); + if (payload_len > nof_bytes) { + RlcInfo("Dropping corrupted PDU (%d B). Remaining length after header %d B.", nof_bytes, payload_len); + return; + } + if (header.rf != 0) { + handle_data_pdu_segment(payload, payload_len, header); + } else { + handle_data_pdu_full(payload, payload_len, header); + } +} + /** Called from stack thread when MAC has received a new RLC PDU * * @param payload Pointer to payload * @param nof_bytes Payload length * @param header Reference to PDU header (unpacked by caller) */ -void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_bytes, rlc_amd_pdu_header_t& header) +void rlc_am_lte_rx::handle_data_pdu_full(uint8_t* payload, uint32_t nof_bytes, rlc_amd_pdu_header_t& header) { std::map::iterator it; - logger.info(payload, nof_bytes, "%s Rx data PDU SN=%d (%d B)", RB_NAME, header.sn, nof_bytes); - log_rlc_amd_pdu_header_to_string(logger.debug, header); + RlcHexInfo(payload, nof_bytes, "Rx data PDU SN=%d (%d B)", header.sn, nof_bytes); + log_rlc_amd_pdu_header_to_string(logger.debug, rb_name, "%s", header); // sanity check for segments not exceeding PDU length if (header.N_li > 0) { @@ -1563,7 +1267,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b for (uint32_t i = 0; i < header.N_li; i++) { segments_len += header.li[i]; if (segments_len > nof_bytes) { - logger.info("Dropping corrupted PDU (segments_len=%d > pdu_len=%d)", segments_len, nof_bytes); + RlcInfo("Dropping corrupted PDU (segments_len=%d > pdu_len=%d)", segments_len, nof_bytes); return; } } @@ -1571,19 +1275,19 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b if (!inside_rx_window(header.sn)) { if (header.p) { - logger.info("%s Status packet requested through polling bit", RB_NAME); + RlcInfo("Status packet requested through polling bit"); do_status = true; } - logger.info("%s SN=%d outside rx window [%d:%d] - discarding", RB_NAME, header.sn, vr_r, vr_mr); + RlcInfo("SN=%d outside rx window [%d:%d] - discarding", header.sn, vr_r, vr_mr); return; } if (rx_window.has_sn(header.sn)) { if (header.p) { - logger.info("%s Status packet requested through polling bit", RB_NAME); + RlcInfo("Status packet requested through polling bit"); do_status = true; } - logger.info("%s Discarding duplicate SN=%d", RB_NAME, header.sn); + RlcInfo("Discarding duplicate SN=%d", header.sn); return; } @@ -1595,7 +1299,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b srsran::console("Fatal Error: Couldn't allocate PDU in handle_data_pdu().\n"); exit(-1); #else - logger.error("Fatal Error: Couldn't allocate PDU in handle_data_pdu()."); + RlcError("Fatal Error: Couldn't allocate PDU in handle_data_pdu()."); rx_window.remove_pdu(header.sn); return; #endif @@ -1604,11 +1308,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b // check available space for payload if (nof_bytes > pdu.buf->get_tailroom()) { - logger.error("%s Discarding SN=%d of size %d B (available space %d B)", - RB_NAME, - header.sn, - nof_bytes, - pdu.buf->get_tailroom()); + RlcError("Discarding SN=%d of size %d B (available space %d B)", header.sn, nof_bytes, pdu.buf->get_tailroom()); return; } memcpy(pdu.buf->msg, payload, nof_bytes); @@ -1627,7 +1327,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b // Check poll bit if (header.p) { - logger.info("%s Status packet requested through polling bit", RB_NAME); + RlcInfo("Status packet requested through polling bit"); poll_received = true; // 36.322 v10 Section 5.2.3 @@ -1644,21 +1344,21 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b if (reordering_timer.is_valid()) { if (reordering_timer.is_running()) { if (vr_x == vr_r || (!inside_rx_window(vr_x) && vr_x != vr_mr)) { - logger.debug("Stopping reordering timer."); + RlcDebug("Stopping reordering timer."); reordering_timer.stop(); } else { - logger.debug("Leave reordering timer running."); + RlcDebug("Leave reordering timer running."); } debug_state(); } if (not reordering_timer.is_running()) { if (RX_MOD_BASE(vr_h) > RX_MOD_BASE(vr_r)) { - logger.debug("Starting reordering timer."); + RlcDebug("Starting reordering timer."); reordering_timer.run(); vr_x = vr_h; } else { - logger.debug("Leave reordering timer stopped."); + RlcDebug("Leave reordering timer stopped."); } debug_state(); } @@ -1667,29 +1367,26 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b debug_state(); } -void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu_segment(uint8_t* payload, - uint32_t nof_bytes, - rlc_amd_pdu_header_t& header) +void rlc_am_lte_rx::handle_data_pdu_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_pdu_header_t& header) { std::map::iterator it; - logger.info(payload, - nof_bytes, - "%s Rx data PDU segment of SN=%d (%d B), SO=%d, N_li=%d", - RB_NAME, - header.sn, - nof_bytes, - header.so, - header.N_li); - log_rlc_amd_pdu_header_to_string(logger.debug, header); + RlcHexInfo(payload, + nof_bytes, + "Rx data PDU segment of SN=%d (%d B), SO=%d, N_li=%d", + header.sn, + nof_bytes, + header.so, + header.N_li); + log_rlc_amd_pdu_header_to_string(logger.debug, rb_name, "Rx data PDU segment %s", header); // Check inside rx window if (!inside_rx_window(header.sn)) { if (header.p) { - logger.info("%s Status packet requested through polling bit", RB_NAME); + logger.info("Status packet requested through polling bit"); do_status = true; } - logger.info("%s SN=%d outside rx window [%d:%d] - discarding", RB_NAME, header.sn, vr_r, vr_mr); + logger.info("SN=%d outside rx window [%d:%d] - discarding", header.sn, vr_r, vr_mr); return; } @@ -1706,7 +1403,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu_segment(uint8_t* pa } if (segment.buf->get_tailroom() < nof_bytes) { - logger.info("Dropping corrupted segment SN=%d, not enough space to fit %d B", header.sn, nof_bytes); + RlcInfo("Dropping corrupted segment SN=%d, not enough space to fit %d B", header.sn, nof_bytes); return; } @@ -1718,7 +1415,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu_segment(uint8_t* pa it = rx_segments.find(header.sn); if (rx_segments.end() != it) { if (header.p) { - logger.info("%s Status packet requested through polling bit", RB_NAME); + RlcInfo("Status packet requested through polling bit"); do_status = true; } @@ -1741,7 +1438,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu_segment(uint8_t* pa // Check poll bit if (header.p) { - logger.info("%s Status packet requested through polling bit", RB_NAME); + RlcInfo("Status packet requested through polling bit"); poll_received = true; // 36.322 v10 Section 5.2.3 @@ -1757,7 +1454,7 @@ void rlc_am_lte::rlc_am_lte_rx::handle_data_pdu_segment(uint8_t* pa debug_state(); } -void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() +void rlc_am_lte_rx::reassemble_rx_sdus() { uint32_t len = 0; if (rx_sdu == NULL) { @@ -1767,7 +1464,7 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() srsran::console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (1)\n"); exit(-1); #else - logger.error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (1)"); + RlcError("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (1)"); return; #endif } @@ -1779,13 +1476,13 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() for (uint32_t i = 0; i < rx_window[vr_r].header.N_li; i++) { len = rx_window[vr_r].header.li[i]; - logger.debug(rx_window[vr_r].buf->msg, - len, - "Handling segment %d/%d of length %d B of SN=%d", - i + 1, - rx_window[vr_r].header.N_li, - len, - vr_r); + RlcHexDebug(rx_window[vr_r].buf->msg, + len, + "Handling segment %d/%d of length %d B of SN=%d", + i + 1, + rx_window[vr_r].header.N_li, + len, + vr_r); // sanity check to avoid zero-size SDUs if (len == 0) { @@ -1795,7 +1492,7 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() if (rx_sdu->get_tailroom() >= len) { if ((rx_window[vr_r].buf->msg - rx_window[vr_r].buf->buffer) + len < SRSRAN_MAX_BUFFER_SIZE_BYTES) { if (rx_window[vr_r].buf->N_bytes < len) { - logger.error("Dropping corrupted SN=%d", vr_r); + RlcError("Dropping corrupted SN=%d", vr_r); rx_sdu.reset(); goto exit; } @@ -1809,7 +1506,7 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() rx_window[vr_r].buf->msg += len; rx_window[vr_r].buf->N_bytes -= len; - logger.info(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes); + RlcHexInfo(rx_sdu->msg, rx_sdu->N_bytes, "Rx SDU (%d B)", rx_sdu->N_bytes); sdu_rx_latency_ms.push(std::chrono::duration_cast( std::chrono::high_resolution_clock::now() - rx_sdu->get_timestamp()) .count()); @@ -1825,18 +1522,18 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() srsran::console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)\n"); exit(-1); #else - logger.error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)"); + RlcError("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (2)"); return; #endif } } else { int buf_len = rx_window[vr_r].buf->msg - rx_window[vr_r].buf->buffer; - logger.error("Cannot read %d bytes from rx_window. vr_r=%d, msg-buffer=%d B", len, vr_r, buf_len); + RlcError("Cannot read %d bytes from rx_window. vr_r=%d, msg-buffer=%d B", len, vr_r, buf_len); rx_sdu.reset(); goto exit; } } else { - logger.error("Cannot fit RLC PDU in SDU buffer, dropping both."); + RlcError("Cannot fit RLC PDU in SDU buffer, dropping both."); rx_sdu.reset(); goto exit; } @@ -1844,7 +1541,7 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() // Handle last segment len = rx_window[vr_r].buf->N_bytes; - logger.debug(rx_window[vr_r].buf->msg, len, "Handling last segment of length %d B of SN=%d", len, vr_r); + RlcHexDebug(rx_window[vr_r].buf->msg, len, "Handling last segment of length %d B of SN=%d", len, vr_r); if (rx_sdu->get_tailroom() >= len) { // store timestamp of the first segment when starting to assemble SDUs if (rx_sdu->N_bytes == 0) { @@ -1862,7 +1559,7 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() } if (rlc_am_end_aligned(rx_window[vr_r].header.fi)) { - logger.info(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes); + RlcHexInfo(rx_sdu->msg, rx_sdu->N_bytes, "Rx SDU (%d B)", rx_sdu->N_bytes); sdu_rx_latency_ms.push(std::chrono::duration_cast( std::chrono::high_resolution_clock::now() - rx_sdu->get_timestamp()) .count()); @@ -1878,7 +1575,7 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() srsran::console("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (3)\n"); exit(-1); #else - logger.error("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (3)"); + RlcError("Fatal Error: Could not allocate PDU in reassemble_rx_sdus() (3)"); return; #endif } @@ -1886,19 +1583,19 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() exit: // Move the rx_window - logger.debug("Erasing SN=%d.", vr_r); + RlcDebug("Erasing SN=%d.", vr_r); // also erase any segments of this SN std::map::iterator it; it = rx_segments.find(vr_r); if (rx_segments.end() != it) { - logger.debug("Erasing segments of SN=%d", vr_r); + RlcDebug("Erasing segments of SN=%d", vr_r); std::list::iterator segit; for (segit = it->second.segments.begin(); segit != it->second.segments.end(); ++segit) { - logger.debug(" Erasing segment of SN=%d SO=%d Len=%d N_li=%d", - segit->header.sn, - segit->header.so, - segit->buf->N_bytes, - segit->header.N_li); + RlcDebug(" Erasing segment of SN=%d SO=%d Len=%d N_li=%d", + segit->header.sn, + segit->header.so, + segit->buf->N_bytes, + segit->header.N_li); } it->second.segments.clear(); } @@ -1908,49 +1605,24 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus() } } -void rlc_am_lte::rlc_am_lte_rx::reset_status() +void rlc_am_lte_rx::reset_status() { do_status = false; poll_received = false; } -bool rlc_am_lte::rlc_am_lte_rx::get_do_status() +bool rlc_am_lte_rx::get_do_status() { return do_status.load(std::memory_order_relaxed); } -void rlc_am_lte::rlc_am_lte_rx::write_pdu(uint8_t* payload, const uint32_t nof_bytes) -{ - if (nof_bytes < 1) { - return; - } - - if (rlc_am_is_control_pdu(payload)) { - parent->tx.handle_control_pdu(payload, nof_bytes); - } else { - std::lock_guard lock(mutex); - rlc_amd_pdu_header_t header = {}; - uint32_t payload_len = nof_bytes; - rlc_am_read_data_pdu_header(&payload, &payload_len, &header); - if (payload_len > nof_bytes) { - logger.info("Dropping corrupted PDU (%d B). Remaining length after header %d B.", nof_bytes, payload_len); - return; - } - if (header.rf) { - handle_data_pdu_segment(payload, payload_len, header); - } else { - handle_data_pdu(payload, payload_len, header); - } - } -} - -uint32_t rlc_am_lte::rlc_am_lte_rx::get_rx_buffered_bytes() +uint32_t rlc_am_lte_rx::get_rx_buffered_bytes() { std::lock_guard lock(mutex); return rx_window.get_buffered_bytes(); } -uint32_t rlc_am_lte::rlc_am_lte_rx::get_sdu_rx_latency_ms() +uint32_t rlc_am_lte_rx::get_sdu_rx_latency_ms() { std::lock_guard lock(mutex); return sdu_rx_latency_ms.value(); @@ -1961,11 +1633,11 @@ uint32_t rlc_am_lte::rlc_am_lte_rx::get_sdu_rx_latency_ms() * * @param timeout_id */ -void rlc_am_lte::rlc_am_lte_rx::timer_expired(uint32_t timeout_id) +void rlc_am_lte_rx::timer_expired(uint32_t timeout_id) { std::lock_guard lock(mutex); if (reordering_timer.is_valid() and reordering_timer.id() == timeout_id) { - logger.debug("%s reordering timeout expiry - updating vr_ms (was %d)", RB_NAME, vr_ms); + RlcDebug("reordering timeout expiry - updating vr_ms (was %d)", vr_ms); // 36.322 v10 Section 5.1.3.2.4 vr_ms = vr_x; @@ -1988,7 +1660,7 @@ void rlc_am_lte::rlc_am_lte_rx::timer_expired(uint32_t timeout_id) // Called from Tx object to pack status PDU that doesn't exceed a given size // If lock-acquisition fails, return -1. Otherwise it returns the length of the generated PDU. -int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const uint32_t max_pdu_size) +int rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const uint32_t max_pdu_size) { std::unique_lock lock(mutex, std::try_to_lock); if (not lock.owns_lock()) { @@ -2011,22 +1683,22 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui // make sure we don't exceed grant size if (rlc_am_packed_length(status) > max_pdu_size) { - logger.debug("Status PDU too big (%d > %d)", rlc_am_packed_length(status), max_pdu_size); + RlcDebug("Status PDU too big (%d > %d)", rlc_am_packed_length(status), max_pdu_size); if (status->N_nack >= 1 && status->N_nack < RLC_AM_WINDOW_SIZE) { - logger.debug("Removing last NACK SN=%d", status->nacks[status->N_nack].nack_sn); + RlcDebug("Removing last NACK SN=%d", status->nacks[status->N_nack].nack_sn); status->N_nack--; // make sure we don't have the current ACK_SN in the NACK list if (rlc_am_is_valid_status_pdu(*status, vr_r) == false) { // No space to send any NACKs, play safe and just ack lower edge - logger.warning("Resetting ACK_SN and N_nack to initial state"); + RlcWarning("Resetting ACK_SN and N_nack to initial state"); status->ack_sn = vr_r; status->N_nack = 0; } } else { - logger.warning("Failed to generate small enough status PDU (packed_len=%d, max_pdu_size=%d, status->N_nack=%d)", - rlc_am_packed_length(status), - max_pdu_size, - status->N_nack); + RlcWarning("Failed to generate small enough status PDU (packed_len=%d, max_pdu_size=%d, status->N_nack=%d)", + rlc_am_packed_length(status), + max_pdu_size, + status->N_nack); return 0; } break; @@ -2041,7 +1713,7 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui } // Called from Tx object to obtain length of the full status PDU -int rlc_am_lte::rlc_am_lte_rx::get_status_pdu_length() +int rlc_am_lte_rx::get_status_pdu_length() { std::unique_lock lock(mutex, std::try_to_lock); if (not lock.owns_lock()) { @@ -2059,7 +1731,7 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu_length() return rlc_am_packed_length(&status); } -void rlc_am_lte::rlc_am_lte_rx::print_rx_segments() +void rlc_am_lte_rx::print_rx_segments() { std::map::iterator it; std::stringstream ss; @@ -2071,11 +1743,11 @@ void rlc_am_lte::rlc_am_lte_rx::print_rx_segments() << " N_li: " << segit->header.N_li << std::endl; } } - logger.debug("%s", ss.str().c_str()); + RlcDebug("%s", ss.str().c_str()); } // NOTE: Preference would be to capture by value, and then move; but header is stack allocated -bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* pdu, rlc_amd_rx_pdu* segment) +bool rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* pdu, rlc_amd_rx_pdu* segment) { // Find segment insertion point in the list of segments auto it1 = pdu->segments.begin(); @@ -2145,7 +1817,7 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* header.fi |= (pdu->segments.front().header.fi & RLC_FI_FIELD_NOT_START_ALIGNED); header.fi |= (pdu->segments.back().header.fi & RLC_FI_FIELD_NOT_END_ALIGNED); - logger.debug("Starting header reconstruction of %zd segments", pdu->segments.size()); + RlcDebug("Starting header reconstruction of %zd segments", pdu->segments.size()); // Reconstruct li fields uint16_t count = 0; @@ -2153,7 +1825,7 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* uint16_t consumed_bytes = 0; // rolling sum of all allocated LIs during segment reconstruction for (it = pdu->segments.begin(); it != pdu->segments.end(); ++it) { - logger.debug(" Handling %d PDU segments", it->header.N_li); + RlcDebug(" Handling %d PDU segments", it->header.N_li); for (uint32_t i = 0; i < it->header.N_li; i++) { // variable marks total offset of each _processed_ LI of this segment uint32_t total_pdu_offset = it->header.so; @@ -2161,28 +1833,28 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* total_pdu_offset += it->header.li[k]; } - logger.debug(" - (total_pdu_offset=%d, consumed_bytes=%d, header.li[i]=%d)", - total_pdu_offset, - consumed_bytes, - header.li[i]); + RlcDebug(" - (total_pdu_offset=%d, consumed_bytes=%d, header.li[i]=%d)", + total_pdu_offset, + consumed_bytes, + header.li[i]); if (total_pdu_offset > header.li[i] && total_pdu_offset > consumed_bytes) { header.li[header.N_li] = total_pdu_offset - consumed_bytes; consumed_bytes = total_pdu_offset; - logger.debug(" - adding segment %d/%d (%d B, SO=%d, carryover=%d, count=%d)", - i + 1, - it->header.N_li, - header.li[header.N_li], - header.so, - carryover, - count); + RlcDebug(" - adding segment %d/%d (%d B, SO=%d, carryover=%d, count=%d)", + i + 1, + it->header.N_li, + header.li[header.N_li], + header.so, + carryover, + count); header.N_li++; count += it->header.li[i]; carryover = 0; } else { - logger.debug(" - Skipping segment in reTx PDU segment which is already included (%d B, SO=%d)", - it->header.li[i], - header.so); + RlcDebug(" - Skipping segment in reTx PDU segment which is already included (%d B, SO=%d)", + it->header.li[i], + header.so); } } @@ -2192,24 +1864,24 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* for (uint32_t k = 0; k < header.N_li; ++k) { carryover -= header.li[k]; } - logger.debug("Incremented carryover (it->buf->N_bytes=%d, count=%d). New carryover=%d", - it->buf->N_bytes, - count, - carryover); + RlcDebug("Incremented carryover (it->buf->N_bytes=%d, count=%d). New carryover=%d", + it->buf->N_bytes, + count, + carryover); } else { // Next segment would be too long, recalculate carryover header.N_li--; carryover = it->buf->N_bytes - (count - header.li[header.N_li]); - logger.debug("Recalculated carryover=%d (it->buf->N_bytes=%d, count=%d, header.li[header.N_li]=%d)", - carryover, - it->buf->N_bytes, - count, - header.li[header.N_li]); + RlcDebug("Recalculated carryover=%d (it->buf->N_bytes=%d, count=%d, header.li[header.N_li]=%d)", + carryover, + it->buf->N_bytes, + count, + header.li[header.N_li]); } tmpit = it; if (rlc_am_end_aligned(it->header.fi) && ++tmpit != pdu->segments.end()) { - logger.debug("Header is end-aligned, overwrite header.li[%d]=%d", header.N_li, carryover); + RlcDebug("Header is end-aligned, overwrite header.li[%d]=%d", header.N_li, carryover); header.li[header.N_li] = carryover; header.N_li++; consumed_bytes += carryover; @@ -2221,7 +1893,7 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* header.p |= it->header.p; } - logger.debug("Finished header reconstruction of %zd segments", pdu->segments.size()); + RlcDebug("Finished header reconstruction of %zd segments", pdu->segments.size()); // Copy data unique_byte_buffer_t full_pdu = srsran::make_byte_buffer(); @@ -2230,7 +1902,7 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* srsran::console("Fatal Error: Could not allocate PDU in add_segment_and_check()\n"); exit(-1); #else - logger.error("Fatal Error: Could not allocate PDU in add_segment_and_check()"); + RlcError("Fatal Error: Could not allocate PDU in add_segment_and_check()"); return false; #endif } @@ -2251,11 +1923,11 @@ bool rlc_am_lte::rlc_am_lte_rx::add_segment_and_check(rlc_amd_rx_pdu_segments_t* full_pdu->N_bytes += n; } - handle_data_pdu(full_pdu->msg, full_pdu->N_bytes, header); + handle_data_pdu_full(full_pdu->msg, full_pdu->N_bytes, header); return true; } -bool rlc_am_lte::rlc_am_lte_rx::inside_rx_window(const int16_t sn) +bool rlc_am_lte_rx::inside_rx_window(const int16_t sn) { if (RX_MOD_BASE(sn) >= RX_MOD_BASE(static_cast(vr_r)) && RX_MOD_BASE(sn) < RX_MOD_BASE(vr_mr)) { return true; @@ -2264,343 +1936,9 @@ bool rlc_am_lte::rlc_am_lte_rx::inside_rx_window(const int16_t sn) } } -void rlc_am_lte::rlc_am_lte_rx::debug_state() -{ - logger.debug("%s vr_r = %d, vr_mr = %d, vr_x = %d, vr_ms = %d, vr_h = %d", RB_NAME, vr_r, vr_mr, vr_x, vr_ms, vr_h); -} - -buffered_pdcp_pdu_list::buffered_pdcp_pdu_list() : buffered_pdus(buffered_pdcp_pdu_list::buffer_size) -{ - clear(); -} - -void buffered_pdcp_pdu_list::clear() -{ - count = 0; - for (pdcp_pdu_info& b : buffered_pdus) { - b.clear(); - } -} - -/**************************************************************************** - * Header pack/unpack helper functions - * Ref: 3GPP TS 36.322 v10.0.0 Section 6.2.1 - ***************************************************************************/ - -// Read header from pdu struct, don't strip header -void rlc_am_read_data_pdu_header(byte_buffer_t* pdu, rlc_amd_pdu_header_t* header) -{ - uint8_t* ptr = pdu->msg; - uint32_t n = 0; - rlc_am_read_data_pdu_header(&ptr, &n, header); -} - -// Read header from raw pointer, strip header -void rlc_am_read_data_pdu_header(uint8_t** payload, uint32_t* nof_bytes, rlc_amd_pdu_header_t* header) -{ - uint8_t ext; - uint8_t* ptr = *payload; - - header->dc = static_cast((*ptr >> 7) & 0x01); - - if (RLC_DC_FIELD_DATA_PDU == header->dc) { - // Fixed part - header->rf = ((*ptr >> 6) & 0x01); - header->p = ((*ptr >> 5) & 0x01); - header->fi = static_cast((*ptr >> 3) & 0x03); - ext = ((*ptr >> 2) & 0x01); - header->sn = (*ptr & 0x03) << 8; // 2 bits SN - ptr++; - header->sn |= (*ptr & 0xFF); // 8 bits SN - ptr++; - - if (header->rf) { - header->lsf = ((*ptr >> 7) & 0x01); - header->so = (*ptr & 0x7F) << 8; // 7 bits of SO - ptr++; - header->so |= (*ptr & 0xFF); // 8 bits of SO - ptr++; - } - - // Extension part - header->N_li = 0; - while (ext) { - if (header->N_li % 2 == 0) { - ext = ((*ptr >> 7) & 0x01); - header->li[header->N_li] = (*ptr & 0x7F) << 4; // 7 bits of LI - ptr++; - header->li[header->N_li] |= (*ptr & 0xF0) >> 4; // 4 bits of LI - header->N_li++; - } else { - ext = (*ptr >> 3) & 0x01; - header->li[header->N_li] = (*ptr & 0x07) << 8; // 3 bits of LI - ptr++; - header->li[header->N_li] |= (*ptr & 0xFF); // 8 bits of LI - header->N_li++; - ptr++; - } - } - - // Account for padding if N_li is odd - if (header->N_li % 2 == 1) { - ptr++; - } - - *nof_bytes -= ptr - *payload; - *payload = ptr; - } -} - -// Write header to pdu struct -void rlc_am_write_data_pdu_header(rlc_amd_pdu_header_t* header, byte_buffer_t* pdu) -{ - uint8_t* ptr = pdu->msg; - rlc_am_write_data_pdu_header(header, &ptr); - pdu->N_bytes += ptr - pdu->msg; -} - -// Write header to pointer & move pointer -void rlc_am_write_data_pdu_header(rlc_amd_pdu_header_t* header, uint8_t** payload) -{ - uint32_t i; - uint8_t ext = (header->N_li > 0) ? 1 : 0; - - uint8_t* ptr = *payload; - - // Fixed part - *ptr = (header->dc & 0x01) << 7; - *ptr |= (header->rf & 0x01) << 6; - *ptr |= (header->p & 0x01) << 5; - *ptr |= (header->fi & 0x03) << 3; - *ptr |= (ext & 0x01) << 2; - - *ptr |= (header->sn & 0x300) >> 8; // 2 bits SN - ptr++; - *ptr = (header->sn & 0xFF); // 8 bits SN - ptr++; - - // Segment part - if (header->rf) { - *ptr = (header->lsf & 0x01) << 7; - *ptr |= (header->so & 0x7F00) >> 8; // 7 bits of SO - ptr++; - *ptr = (header->so & 0x00FF); // 8 bits of SO - ptr++; - } - - // Extension part - i = 0; - while (i < header->N_li) { - ext = ((i + 1) == header->N_li) ? 0 : 1; - *ptr = (ext & 0x01) << 7; // 1 bit header - *ptr |= (header->li[i] & 0x7F0) >> 4; // 7 bits of LI - ptr++; - *ptr = (header->li[i] & 0x00F) << 4; // 4 bits of LI - i++; - if (i < header->N_li) { - ext = ((i + 1) == header->N_li) ? 0 : 1; - *ptr |= (ext & 0x01) << 3; // 1 bit header - *ptr |= (header->li[i] & 0x700) >> 8; // 3 bits of LI - ptr++; - *ptr = (header->li[i] & 0x0FF); // 8 bits of LI - ptr++; - i++; - } - } - // Pad if N_li is odd - if (header->N_li % 2 == 1) { - ptr++; - } - - *payload = ptr; -} - -void rlc_am_read_status_pdu(byte_buffer_t* pdu, rlc_status_pdu_t* status) -{ - rlc_am_read_status_pdu(pdu->msg, pdu->N_bytes, status); -} - -void rlc_am_read_status_pdu(uint8_t* payload, uint32_t nof_bytes, rlc_status_pdu_t* status) -{ - uint32_t i; - uint8_t ext1, ext2; - bit_buffer_t tmp; - uint8_t* ptr = tmp.msg; - - srsran_bit_unpack_vector(payload, tmp.msg, nof_bytes * 8); - tmp.N_bits = nof_bytes * 8; - - rlc_dc_field_t dc = static_cast(srsran_bit_pack(&ptr, 1)); - - if (RLC_DC_FIELD_CONTROL_PDU == dc) { - uint8_t cpt = srsran_bit_pack(&ptr, 3); // 3-bit Control PDU Type (0 == status) - if (0 == cpt) { - status->ack_sn = srsran_bit_pack(&ptr, 10); // 10 bits ACK_SN - ext1 = srsran_bit_pack(&ptr, 1); // 1 bits E1 - status->N_nack = 0; - while (ext1) { - status->nacks[status->N_nack].nack_sn = srsran_bit_pack(&ptr, 10); - ext1 = srsran_bit_pack(&ptr, 1); // 1 bits E1 - ext2 = srsran_bit_pack(&ptr, 1); // 1 bits E2 - if (ext2) { - status->nacks[status->N_nack].has_so = true; - status->nacks[status->N_nack].so_start = srsran_bit_pack(&ptr, 15); - status->nacks[status->N_nack].so_end = srsran_bit_pack(&ptr, 15); - } - status->N_nack++; - } - } - } -} - -void rlc_am_write_status_pdu(rlc_status_pdu_t* status, byte_buffer_t* pdu) -{ - pdu->N_bytes = rlc_am_write_status_pdu(status, pdu->msg); -} - -int rlc_am_write_status_pdu(rlc_status_pdu_t* status, uint8_t* payload) -{ - uint32_t i; - uint8_t ext1; - bit_buffer_t tmp; - uint8_t* ptr = tmp.msg; - - srsran_bit_unpack(RLC_DC_FIELD_CONTROL_PDU, &ptr, 1); // D/C - srsran_bit_unpack(0, &ptr, 3); // CPT (0 == STATUS) - srsran_bit_unpack(status->ack_sn, &ptr, 10); // 10 bit ACK_SN - ext1 = (status->N_nack == 0) ? 0 : 1; - srsran_bit_unpack(ext1, &ptr, 1); // E1 - for (i = 0; i < status->N_nack; i++) { - srsran_bit_unpack(status->nacks[i].nack_sn, &ptr, 10); // 10 bit NACK_SN - ext1 = ((status->N_nack - 1) == i) ? 0 : 1; - srsran_bit_unpack(ext1, &ptr, 1); // E1 - if (status->nacks[i].has_so) { - srsran_bit_unpack(1, &ptr, 1); // E2 - srsran_bit_unpack(status->nacks[i].so_start, &ptr, 15); - srsran_bit_unpack(status->nacks[i].so_end, &ptr, 15); - } else { - srsran_bit_unpack(0, &ptr, 1); // E2 - } - } - - // Pad - tmp.N_bits = ptr - tmp.msg; - uint8_t n_pad = 8 - (tmp.N_bits % 8); - srsran_bit_unpack(0, &ptr, n_pad); - tmp.N_bits = ptr - tmp.msg; - - // Pack bits - srsran_bit_pack_vector(tmp.msg, payload, tmp.N_bits); - return tmp.N_bits / 8; -} - -bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status, uint32_t rx_win_min) -{ - // check if ACK_SN is inside Rx window - if ((MOD + status.ack_sn - rx_win_min) % MOD > RLC_AM_WINDOW_SIZE) { - return false; - } - - for (uint32_t i = 0; i < status.N_nack; ++i) { - // NACK can't be larger than ACK - if ((MOD + status.ack_sn - status.nacks[i].nack_sn) % MOD > RLC_AM_WINDOW_SIZE) { - return false; - } - // Don't NACK the ACK SN - if (status.nacks[i].nack_sn == status.ack_sn) { - return false; - } - } - return true; -} - -uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t* header) -{ - uint32_t len = 2; // Fixed part is 2 bytes - if (header->rf) { - len += 2; // Segment header is 2 bytes - } - len += header->N_li * 1.5 + 0.5; // Extension part - integer rounding up - return len; -} - -uint32_t rlc_am_packed_length(rlc_status_pdu_t* status) -{ - uint32_t len_bits = 15; // Fixed part is 15 bits - for (uint32_t i = 0; i < status->N_nack; i++) { - if (status->nacks[i].has_so) { - len_bits += 42; // 10 bits SN, 2 bits ext, 15 bits so_start, 15 bits so_end - } else { - len_bits += 12; // 10 bits SN, 2 bits ext - } - } - - return (len_bits + 7) / 8; // Convert to bytes - integer rounding up -} - -bool rlc_am_is_pdu_segment(uint8_t* payload) -{ - return ((*(payload) >> 6) & 0x01) == 1; -} - -void rlc_am_undelivered_sdu_info_to_string(fmt::memory_buffer& buffer, const std::vector& info_queue) -{ - fmt::format_to(buffer, "\n"); - for (const auto& pdcp_pdu : info_queue) { - fmt::format_to(buffer, "\tPDCP_SN = {}, undelivered RLC SNs = [", pdcp_pdu.sn); - for (const auto& nacked_segment : pdcp_pdu) { - fmt::format_to(buffer, "{} ", nacked_segment.rlc_sn()); - } - fmt::format_to(buffer, "]\n"); - } -} - -void log_rlc_amd_pdu_header_to_string(srslog::log_channel& log_ch, const rlc_amd_pdu_header_t& header) -{ - if (not log_ch.enabled()) { - return; - } - fmt::memory_buffer buffer; - fmt::format_to(buffer, - "[{}, RF={}, P={}, FI={}, SN={}, LSF={}, SO={}, N_li={}", - rlc_dc_field_text[header.dc], - (header.rf ? "1" : "0"), - (header.p ? "1" : "0"), - (header.fi ? "1" : "0"), - header.sn, - (header.lsf ? "1" : "0"), - header.so, - header.N_li); - if (header.N_li > 0) { - fmt::format_to(buffer, " ({}", header.li[0]); - for (uint32_t i = 1; i < header.N_li; ++i) { - fmt::format_to(buffer, ", {}", header.li[i]); - } - fmt::format_to(buffer, ")"); - } - fmt::format_to(buffer, "]"); - - log_ch("%s", to_c_str(buffer)); -} - -bool rlc_am_start_aligned(const uint8_t fi) -{ - return (fi == RLC_FI_FIELD_START_AND_END_ALIGNED || fi == RLC_FI_FIELD_NOT_END_ALIGNED); -} - -bool rlc_am_end_aligned(const uint8_t fi) -{ - return (fi == RLC_FI_FIELD_START_AND_END_ALIGNED || fi == RLC_FI_FIELD_NOT_START_ALIGNED); -} - -bool rlc_am_is_unaligned(const uint8_t fi) -{ - return (fi == RLC_FI_FIELD_NOT_START_OR_END_ALIGNED); -} - -bool rlc_am_not_start_aligned(const uint8_t fi) +void rlc_am_lte_rx::debug_state() { - return (fi == RLC_FI_FIELD_NOT_START_ALIGNED || fi == RLC_FI_FIELD_NOT_START_OR_END_ALIGNED); + RlcDebug("vr_r = %d, vr_mr = %d, vr_x = %d, vr_ms = %d, vr_h = %d", vr_r, vr_mr, vr_x, vr_ms, vr_h); } } // namespace srsran diff --git a/lib/src/rlc/rlc_am_lte_packing.cc b/lib/src/rlc/rlc_am_lte_packing.cc new file mode 100644 index 0000000000..4d67b8b36b --- /dev/null +++ b/lib/src/rlc/rlc_am_lte_packing.cc @@ -0,0 +1,321 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/rlc/rlc_am_lte_packing.h" +#include + +namespace srsran { + +/**************************************************************************** + * Header pack/unpack helper functions + * Ref: 3GPP TS 36.322 v10.0.0 Section 6.2.1 + ***************************************************************************/ + +// Read header from pdu struct, don't strip header +void rlc_am_read_data_pdu_header(byte_buffer_t* pdu, rlc_amd_pdu_header_t* header) +{ + uint8_t* ptr = pdu->msg; + uint32_t n = 0; + rlc_am_read_data_pdu_header(&ptr, &n, header); +} + +// Read header from raw pointer, strip header +void rlc_am_read_data_pdu_header(uint8_t** payload, uint32_t* nof_bytes, rlc_amd_pdu_header_t* header) +{ + uint8_t ext; + uint8_t* ptr = *payload; + + header->dc = static_cast((*ptr >> 7) & 0x01); + + if (RLC_DC_FIELD_DATA_PDU == header->dc) { + // Fixed part + header->rf = ((*ptr >> 6) & 0x01); + header->p = ((*ptr >> 5) & 0x01); + header->fi = static_cast((*ptr >> 3) & 0x03); + ext = ((*ptr >> 2) & 0x01); + header->sn = (*ptr & 0x03) << 8; // 2 bits SN + ptr++; + header->sn |= (*ptr & 0xFF); // 8 bits SN + ptr++; + + if (header->rf) { + header->lsf = ((*ptr >> 7) & 0x01); + header->so = (*ptr & 0x7F) << 8; // 7 bits of SO + ptr++; + header->so |= (*ptr & 0xFF); // 8 bits of SO + ptr++; + } + + // Extension part + header->N_li = 0; + while (ext) { + if (header->N_li % 2 == 0) { + ext = ((*ptr >> 7) & 0x01); + header->li[header->N_li] = (*ptr & 0x7F) << 4; // 7 bits of LI + ptr++; + header->li[header->N_li] |= (*ptr & 0xF0) >> 4; // 4 bits of LI + header->N_li++; + } else { + ext = (*ptr >> 3) & 0x01; + header->li[header->N_li] = (*ptr & 0x07) << 8; // 3 bits of LI + ptr++; + header->li[header->N_li] |= (*ptr & 0xFF); // 8 bits of LI + header->N_li++; + ptr++; + } + } + + // Account for padding if N_li is odd + if (header->N_li % 2 == 1) { + ptr++; + } + + *nof_bytes -= ptr - *payload; + *payload = ptr; + } +} + +// Write header to pdu struct +void rlc_am_write_data_pdu_header(rlc_amd_pdu_header_t* header, byte_buffer_t* pdu) +{ + uint8_t* ptr = pdu->msg; + rlc_am_write_data_pdu_header(header, &ptr); + pdu->N_bytes += ptr - pdu->msg; +} + +// Write header to pointer & move pointer +void rlc_am_write_data_pdu_header(rlc_amd_pdu_header_t* header, uint8_t** payload) +{ + uint32_t i; + uint8_t ext = (header->N_li > 0) ? 1 : 0; + + uint8_t* ptr = *payload; + + // Fixed part + *ptr = (header->dc & 0x01) << 7; + *ptr |= (header->rf & 0x01) << 6; + *ptr |= (header->p & 0x01) << 5; + *ptr |= (header->fi & 0x03) << 3; + *ptr |= (ext & 0x01) << 2; + + *ptr |= (header->sn & 0x300) >> 8; // 2 bits SN + ptr++; + *ptr = (header->sn & 0xFF); // 8 bits SN + ptr++; + + // Segment part + if (header->rf) { + *ptr = (header->lsf & 0x01) << 7; + *ptr |= (header->so & 0x7F00) >> 8; // 7 bits of SO + ptr++; + *ptr = (header->so & 0x00FF); // 8 bits of SO + ptr++; + } + + // Extension part + i = 0; + while (i < header->N_li) { + ext = ((i + 1) == header->N_li) ? 0 : 1; + *ptr = (ext & 0x01) << 7; // 1 bit header + *ptr |= (header->li[i] & 0x7F0) >> 4; // 7 bits of LI + ptr++; + *ptr = (header->li[i] & 0x00F) << 4; // 4 bits of LI + i++; + if (i < header->N_li) { + ext = ((i + 1) == header->N_li) ? 0 : 1; + *ptr |= (ext & 0x01) << 3; // 1 bit header + *ptr |= (header->li[i] & 0x700) >> 8; // 3 bits of LI + ptr++; + *ptr = (header->li[i] & 0x0FF); // 8 bits of LI + ptr++; + i++; + } + } + // Pad if N_li is odd + if (header->N_li % 2 == 1) { + ptr++; + } + + *payload = ptr; +} + +void rlc_am_read_status_pdu(byte_buffer_t* pdu, rlc_status_pdu_t* status) +{ + rlc_am_read_status_pdu(pdu->msg, pdu->N_bytes, status); +} + +void rlc_am_read_status_pdu(uint8_t* payload, uint32_t nof_bytes, rlc_status_pdu_t* status) +{ + uint32_t i; + uint8_t ext1, ext2; + bit_buffer_t tmp; + uint8_t* ptr = tmp.msg; + + srsran_bit_unpack_vector(payload, tmp.msg, nof_bytes * 8); + tmp.N_bits = nof_bytes * 8; + + rlc_dc_field_t dc = static_cast(srsran_bit_pack(&ptr, 1)); + + if (RLC_DC_FIELD_CONTROL_PDU == dc) { + uint8_t cpt = srsran_bit_pack(&ptr, 3); // 3-bit Control PDU Type (0 == status) + if (0 == cpt) { + status->ack_sn = srsran_bit_pack(&ptr, 10); // 10 bits ACK_SN + ext1 = srsran_bit_pack(&ptr, 1); // 1 bits E1 + status->N_nack = 0; + while (ext1) { + status->nacks[status->N_nack].nack_sn = srsran_bit_pack(&ptr, 10); + ext1 = srsran_bit_pack(&ptr, 1); // 1 bits E1 + ext2 = srsran_bit_pack(&ptr, 1); // 1 bits E2 + if (ext2) { + status->nacks[status->N_nack].has_so = true; + status->nacks[status->N_nack].so_start = srsran_bit_pack(&ptr, 15); + status->nacks[status->N_nack].so_end = srsran_bit_pack(&ptr, 15); + } + status->N_nack++; + } + } + } +} + +void rlc_am_write_status_pdu(rlc_status_pdu_t* status, byte_buffer_t* pdu) +{ + pdu->N_bytes = rlc_am_write_status_pdu(status, pdu->msg); +} + +int rlc_am_write_status_pdu(rlc_status_pdu_t* status, uint8_t* payload) +{ + uint32_t i; + uint8_t ext1; + bit_buffer_t tmp; + uint8_t* ptr = tmp.msg; + + srsran_bit_unpack(RLC_DC_FIELD_CONTROL_PDU, &ptr, 1); // D/C + srsran_bit_unpack(0, &ptr, 3); // CPT (0 == STATUS) + srsran_bit_unpack(status->ack_sn, &ptr, 10); // 10 bit ACK_SN + ext1 = (status->N_nack == 0) ? 0 : 1; + srsran_bit_unpack(ext1, &ptr, 1); // E1 + for (i = 0; i < status->N_nack; i++) { + srsran_bit_unpack(status->nacks[i].nack_sn, &ptr, 10); // 10 bit NACK_SN + ext1 = ((status->N_nack - 1) == i) ? 0 : 1; + srsran_bit_unpack(ext1, &ptr, 1); // E1 + if (status->nacks[i].has_so) { + srsran_bit_unpack(1, &ptr, 1); // E2 + srsran_bit_unpack(status->nacks[i].so_start, &ptr, 15); + srsran_bit_unpack(status->nacks[i].so_end, &ptr, 15); + } else { + srsran_bit_unpack(0, &ptr, 1); // E2 + } + } + + // Pad + tmp.N_bits = ptr - tmp.msg; + uint8_t n_pad = 8 - (tmp.N_bits % 8); + srsran_bit_unpack(0, &ptr, n_pad); + tmp.N_bits = ptr - tmp.msg; + + // Pack bits + srsran_bit_pack_vector(tmp.msg, payload, tmp.N_bits); + return tmp.N_bits / 8; +} + +uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t* header) +{ + uint32_t len = 2; // Fixed part is 2 bytes + if (header->rf) { + len += 2; // Segment header is 2 bytes + } + len += header->N_li * 1.5 + 0.5; // Extension part - integer rounding up + return len; +} + +uint32_t rlc_am_packed_length(rlc_status_pdu_t* status) +{ + uint32_t len_bits = 15; // Fixed part is 15 bits + for (uint32_t i = 0; i < status->N_nack; i++) { + if (status->nacks[i].has_so) { + len_bits += 42; // 10 bits SN, 2 bits ext, 15 bits so_start, 15 bits so_end + } else { + len_bits += 12; // 10 bits SN, 2 bits ext + } + } + + return (len_bits + 7) / 8; // Convert to bytes - integer rounding up +} + +bool rlc_am_is_pdu_segment(uint8_t* payload) +{ + return ((*(payload) >> 6) & 0x01) == 1; +} + +bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status, uint32_t rx_win_min) +{ + // check if ACK_SN is inside Rx window + if ((MOD + status.ack_sn - rx_win_min) % MOD > RLC_AM_WINDOW_SIZE) { + return false; + } + + for (uint32_t i = 0; i < status.N_nack; ++i) { + // NACK can't be larger than ACK + if ((MOD + status.ack_sn - status.nacks[i].nack_sn) % MOD > RLC_AM_WINDOW_SIZE) { + return false; + } + // Don't NACK the ACK SN + if (status.nacks[i].nack_sn == status.ack_sn) { + return false; + } + } + return true; +} + +void rlc_am_undelivered_sdu_info_to_string(fmt::memory_buffer& buffer, + const std::vector >& info_queue) +{ + fmt::format_to(buffer, "\n"); + for (const auto& pdcp_pdu : info_queue) { + fmt::format_to(buffer, "\tPDCP_SN = {}, undelivered RLC SNs = [", pdcp_pdu.sn); + for (const auto& nacked_segment : pdcp_pdu) { + fmt::format_to(buffer, "{} ", nacked_segment.rlc_sn()); + } + fmt::format_to(buffer, "]\n"); + } +} + +bool rlc_am_start_aligned(const uint8_t fi) +{ + return (fi == RLC_FI_FIELD_START_AND_END_ALIGNED || fi == RLC_FI_FIELD_NOT_END_ALIGNED); +} + +bool rlc_am_end_aligned(const uint8_t fi) +{ + return (fi == RLC_FI_FIELD_START_AND_END_ALIGNED || fi == RLC_FI_FIELD_NOT_START_ALIGNED); +} + +bool rlc_am_is_unaligned(const uint8_t fi) +{ + return (fi == RLC_FI_FIELD_NOT_START_OR_END_ALIGNED); +} + +bool rlc_am_not_start_aligned(const uint8_t fi) +{ + return (fi == RLC_FI_FIELD_NOT_START_ALIGNED || fi == RLC_FI_FIELD_NOT_START_OR_END_ALIGNED); +} + +} // namespace srsran diff --git a/lib/src/rlc/rlc_am_nr.cc b/lib/src/rlc/rlc_am_nr.cc index 17440d18b8..c47f8b832c 100644 --- a/lib/src/rlc/rlc_am_nr.cc +++ b/lib/src/rlc/rlc_am_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,240 +20,2009 @@ */ #include "srsran/rlc/rlc_am_nr.h" -#include +#include "srsran/common/standard_streams.h" +#include "srsran/common/string_helpers.h" +#include "srsran/interfaces/ue_pdcp_interfaces.h" +#include "srsran/interfaces/ue_rrc_interfaces.h" +#include "srsran/rlc/rlc_am_nr_packing.h" +#include "srsran/srslog/event_trace.h" +#include +#include namespace srsran { +const static uint32_t max_tx_queue_size = 256; + /**************************************************************************** - * Header pack/unpack helper functions - * Ref: 3GPP TS 38.322 v15.3.0 Section 6.2.2.4 + * RLC AM NR entity ***************************************************************************/ -uint32_t rlc_am_nr_read_data_pdu_header(const byte_buffer_t* pdu, - const rlc_am_nr_sn_size_t sn_size, - rlc_am_nr_pdu_header_t* header) +/*************************************************************************** + * Tx subclass implementation + ***************************************************************************/ +rlc_am_nr_tx::rlc_am_nr_tx(rlc_am* parent_) : + parent(parent_), rlc_am_base_tx(parent_->logger), poll_retransmit_timer(parent->timers->get_unique_timer()) { - return rlc_am_nr_read_data_pdu_header(pdu->msg, pdu->N_bytes, sn_size, header); } -uint32_t rlc_am_nr_read_data_pdu_header(const uint8_t* payload, - const uint32_t nof_bytes, - const rlc_am_nr_sn_size_t sn_size, - rlc_am_nr_pdu_header_t* header) +bool rlc_am_nr_tx::configure(const rlc_config_t& cfg_) { - uint8_t* ptr = const_cast(payload); + cfg = cfg_.am_nr; + rb_name = parent->rb_name; + + if (cfg_.tx_queue_length > max_tx_queue_size) { + RlcError("configuring tx queue length of %d PDUs too big. Maximum value is %d.", + cfg_.tx_queue_length, + max_tx_queue_size); + return false; + } - header->sn_size = sn_size; + mod_nr = cardinality(cfg.tx_sn_field_length); + switch (cfg.tx_sn_field_length) { + case rlc_am_nr_sn_size_t::size12bits: + min_hdr_size = 2; + tx_window = std::unique_ptr >( + new rlc_ringbuffer_t); + break; + case rlc_am_nr_sn_size_t::size18bits: + min_hdr_size = 3; + tx_window = std::unique_ptr >( + new rlc_ringbuffer_t); + break; + default: + RlcError("attempt to configure unsupported tx_sn_field_length %s", to_string(cfg.tx_sn_field_length)); + return false; + } + + max_hdr_size = min_hdr_size + so_size; - // Fixed part - header->dc = (rlc_dc_field_t)((*ptr >> 7) & 0x01); // 1 bit D/C field - header->p = (*ptr >> 6) & 0x01; // 1 bit P flag - header->si = (rlc_nr_si_field_t)((*ptr >> 4) & 0x03); // 2 bits SI + // make sure Tx queue is empty before attempting to resize + empty_queue_no_lock(); + tx_sdu_queue.resize(cfg_.tx_queue_length); + + // Check timers are valid + if (not poll_retransmit_timer.is_valid()) { + RlcError("Configuring TX: timers not configured"); + return false; + } + + // Configure t_poll_retransmission timer + if (cfg.t_poll_retx > 0) { + poll_retransmit_timer.set(static_cast(cfg.t_poll_retx), + [this](uint32_t timerid) { timer_expired(timerid); }); + } + + tx_enabled = true; + + RlcDebug("RLC AM NR configured tx entity."); + return true; +} + +bool rlc_am_nr_tx::has_data() +{ + return do_status() || // if we have a status PDU to transmit + tx_sdu_queue.get_n_sdus() != 0 || !retx_queue.empty(); // or if there is a SDU queued up for transmission +} + +/** + * Builds the RLC PDU. + * + * Called by the MAC, trough one of the PHY worker threads. + * + * \param [payload] is a pointer to the buffer that will hold the PDU. + * \param [nof_bytes] is the number of bytes the RLC is allowed to fill. + * + * \returns the number of bytes written to the payload buffer. + * \remark: This will be called multiple times from the MAC, + * while there is something to TX and enough space in the TB. + */ +uint32_t rlc_am_nr_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes) +{ + std::lock_guard lock(mutex); + + if (not tx_enabled) { + RlcDebug("RLC entity not active. Not generating PDU."); + return 0; + } + RlcDebug("MAC opportunity - bytes=%d, tx_window size=%zu PDUs", nof_bytes, tx_window->size()); + + // Tx STATUS if requested + if (do_status()) { + unique_byte_buffer_t tx_pdu = srsran::make_byte_buffer(); + if (tx_pdu == nullptr) { + RlcError("Couldn't allocate PDU in %s().", __FUNCTION__); + return 0; + } + build_status_pdu(tx_pdu.get(), nof_bytes); + memcpy(payload, tx_pdu->msg, tx_pdu->N_bytes); + RlcDebug("Status PDU built - %d bytes", tx_pdu->N_bytes); + return tx_pdu->N_bytes; + } - if (sn_size == rlc_am_nr_sn_size_t::size12bits) { - header->sn = (*ptr & 0x0F) << 8; // first 4 bits SN - ptr++; + // Retransmit if required + if (not retx_queue.empty()) { + RlcInfo("Re-transmission required. Retransmission queue size: %d", retx_queue.size()); + return build_retx_pdu(payload, nof_bytes); + } - header->sn |= (*ptr & 0xFF); // last 8 bits SN - ptr++; - } else if (sn_size == rlc_am_nr_sn_size_t::size18bits) { - // sanity check - if ((*ptr & 0x0c) != 0) { - fprintf(stderr, "Malformed PDU, reserved bits are set.\n"); + // Send remaining segment, if it exists + if (sdu_under_segmentation_sn != INVALID_RLC_SN) { + if (not tx_window->has_sn(sdu_under_segmentation_sn)) { + sdu_under_segmentation_sn = INVALID_RLC_SN; + RlcError("SDU currently being segmented does not exist in tx_window. Aborting segmentation SN=%d", + sdu_under_segmentation_sn); return 0; } - header->sn = (*ptr & 0x03) << 16; // first 4 bits SN - ptr++; - header->sn |= (*ptr & 0xFF) << 8; // bit 2-10 of SN - ptr++; - header->sn |= (*ptr & 0xFF); // last 8 bits SN - ptr++; + return build_continuation_sdu_segment((*tx_window)[sdu_under_segmentation_sn], payload, nof_bytes); + } + + // Check whether there is something to TX + if (tx_sdu_queue.is_empty()) { + RlcInfo("No data available to be sent"); + return 0; + } + + return build_new_pdu(payload, nof_bytes); +} + +/** + * Builds a new RLC PDU. + * + * This will be called after checking whether control, retransmission, + * or segment PDUs needed to be transmitted first. + * + * This will read an SDU from the SDU queue, build a new PDU, and add it to the tx_window. + * SDU segmentation will be done if necessary. + * + * \param [payload] is a pointer to the buffer that will hold the PDU. + * \param [nof_bytes] is the number of bytes the RLC is allowed to fill. + * + * \returns the number of bytes written to the payload buffer. + */ +uint32_t rlc_am_nr_tx::build_new_pdu(uint8_t* payload, uint32_t nof_bytes) +{ + if (nof_bytes <= min_hdr_size) { + RlcInfo("Not enough bytes for payload plus header. nof_bytes=%d", nof_bytes); + return 0; + } + + // do not build any more PDU if window is already full + if (tx_window->full()) { + RlcInfo("Cannot build data PDU - Tx window full."); + return 0; + } + + // Read new SDU from TX queue + unique_byte_buffer_t tx_sdu; + RlcDebug("Reading from RLC SDU queue. Queue size %d", tx_sdu_queue.size()); + do { + tx_sdu = tx_sdu_queue.read(); + } while (tx_sdu == nullptr && tx_sdu_queue.size() != 0); + + if (tx_sdu != nullptr) { + RlcDebug("Read RLC SDU - RLC_SN=%d, PDCP_SN=%d, %d bytes", st.tx_next, tx_sdu->md.pdcp_sn, tx_sdu->N_bytes); } else { - fprintf(stderr, "Unsupported SN length\n"); + RlcDebug("No SDUs left in the tx queue."); return 0; } - // Read optional part - if (header->si == rlc_nr_si_field_t::last_segment || - header->si == rlc_nr_si_field_t::neither_first_nor_last_segment) { - // read SO - header->so = (*ptr & 0xFF) << 8; - ptr++; - header->so |= (*ptr & 0xFF); - ptr++; + // insert newly assigned SN into window and use reference for in-place operations + // NOTE: from now on, we can't return from this function anymore before increasing tx_next + rlc_amd_tx_pdu_nr& tx_pdu = tx_window->add_pdu(st.tx_next); + tx_pdu.pdcp_sn = tx_sdu->md.pdcp_sn; + tx_pdu.sdu_buf = srsran::make_byte_buffer(); + if (tx_pdu.sdu_buf == nullptr) { + RlcError("Couldn't allocate PDU in %s().", __FUNCTION__); + return 0; } - // return consumed bytes - return (ptr - payload); + // Copy SDU into TX window SDU info + memcpy(tx_pdu.sdu_buf->msg, tx_sdu->msg, tx_sdu->N_bytes); + tx_pdu.sdu_buf->N_bytes = tx_sdu->N_bytes; + + // Segment new SDU if necessary + if (tx_sdu->N_bytes + min_hdr_size > nof_bytes) { + RlcInfo("trying to build PDU segment from SDU."); + return build_new_sdu_segment(tx_pdu, payload, nof_bytes); + } + + // Prepare header + rlc_am_nr_pdu_header_t hdr = {}; + hdr.dc = RLC_DC_FIELD_DATA_PDU; + hdr.p = get_pdu_poll(st.tx_next, false, tx_sdu->N_bytes); + hdr.si = rlc_nr_si_field_t::full_sdu; + hdr.sn_size = cfg.tx_sn_field_length; + hdr.sn = st.tx_next; + tx_pdu.header = hdr; + log_rlc_am_nr_pdu_header_to_string(logger.info, hdr, rb_name); + + // Write header + uint32_t len = rlc_am_nr_write_data_pdu_header(hdr, tx_sdu.get()); + if (len > nof_bytes) { + RlcError("error writing AMD PDU header"); + } + + // Update TX Next + st.tx_next = (st.tx_next + 1) % mod_nr; + + memcpy(payload, tx_sdu->msg, tx_sdu->N_bytes); + RlcDebug("wrote RLC PDU - %d bytes", tx_sdu->N_bytes); + + return tx_sdu->N_bytes; } -uint32_t rlc_am_nr_packed_length(const rlc_am_nr_pdu_header_t& header) +/** + * Builds a new RLC PDU segment, from a RLC SDU. + * + * \param [tx_pdu] is the tx_pdu info contained in the tx_window. + * \param [payload] is a pointer to the MAC buffer that will hold the PDU segment. + * \param [nof_bytes] is the number of bytes the RLC is allowed to fill. + * + * \returns the number of bytes written to the payload buffer. + * \remark: This functions assumes that the SDU has already been copied to tx_pdu.sdu_buf. + */ +uint32_t rlc_am_nr_tx::build_new_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint8_t* payload, uint32_t nof_bytes) { - uint32_t len = 0; - if (header.si == rlc_nr_si_field_t::full_sdu || header.si == rlc_nr_si_field_t::first_segment) { - len = 2; - if (header.sn_size == rlc_am_nr_sn_size_t::size18bits) { - len++; - } - } else { - // PDU contains SO - len = 4; - if (header.sn_size == rlc_am_nr_sn_size_t::size18bits) { - len++; - } + RlcInfo("creating new SDU segment. Tx SDU (%d B), nof_bytes=%d B ", tx_pdu.sdu_buf->N_bytes, nof_bytes); + + // Sanity check: can this SDU be sent this in a single PDU? + if ((tx_pdu.sdu_buf->N_bytes + min_hdr_size) < nof_bytes) { + RlcError("calling build_new_sdu_segment(), but there are enough bytes to tx in a single PDU. Tx SDU (%d B), " + "nof_bytes=%d B ", + tx_pdu.sdu_buf->N_bytes, + nof_bytes); + return 0; + } + + // Sanity check: can this SDU be sent considering header overhead? + if (nof_bytes <= min_hdr_size) { // Small header as SO is not present + RlcInfo("cannot build new sdu_segment, there are not enough bytes allocated to tx header plus data. nof_bytes=%d, " + "min_hdr_size=%d", + nof_bytes, + min_hdr_size); + return 0; } - return len; + + uint32_t segment_payload_len = nof_bytes - min_hdr_size; + + // Save SDU currently being segmented + // This needs to be done before calculating the polling bit + // To make sure we check correctly that the buffers are empty. + sdu_under_segmentation_sn = st.tx_next; + + // Prepare header + rlc_am_nr_pdu_header_t hdr = {}; + hdr.dc = RLC_DC_FIELD_DATA_PDU; + hdr.p = get_pdu_poll(st.tx_next, false, segment_payload_len); + hdr.si = rlc_nr_si_field_t::first_segment; + hdr.sn_size = cfg.tx_sn_field_length; + hdr.sn = st.tx_next; + hdr.so = 0; + tx_pdu.header = hdr; + log_rlc_am_nr_pdu_header_to_string(logger.info, hdr, rb_name); + + // Write header + uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(hdr, payload); + if (hdr_len >= nof_bytes || hdr_len != min_hdr_size) { + RlcError("error writing AMD PDU header"); + return 0; + } + + // Copy PDU to payload + srsran_assert((hdr_len + segment_payload_len) <= nof_bytes, "Error calculating hdr_len and segment_payload_len"); + memcpy(&payload[hdr_len], tx_pdu.sdu_buf->msg, segment_payload_len); + + // Store Segment Info + rlc_amd_tx_pdu_nr::pdu_segment segment_info; + segment_info.payload_len = segment_payload_len; + tx_pdu.segment_list.push_back(segment_info); + return hdr_len + segment_payload_len; } -uint32_t rlc_am_nr_write_data_pdu_header(const rlc_am_nr_pdu_header_t& header, byte_buffer_t* pdu) +/** + * Build PDU segment for an RLC SDU that is already on-going segmentation. + * + * \param [tx_pdu] is the tx_pdu info contained in the tx_window. + * \param [payload] is a pointer to the MAC buffer that will hold the PDU segment. + * \param [nof_bytes] is the number of bytes the RLC is allowed to fill. + * + * \returns the number of bytes written to the payload buffer. + * \remark: This functions assumes that the SDU has already been copied to tx_pdu.sdu_buf. + */ +uint32_t rlc_am_nr_tx::build_continuation_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint8_t* payload, uint32_t nof_bytes) { - // Make room for the header - uint32_t len = rlc_am_nr_packed_length(header); - pdu->msg -= len; - uint8_t* ptr = pdu->msg; + RlcInfo("continuing SDU segment. SN=%d, Tx SDU (%d B), nof_bytes=%d B ", + sdu_under_segmentation_sn, + tx_pdu.sdu_buf->N_bytes, + nof_bytes); - // fixed header part - *ptr = (header.dc & 0x01) << 7; ///< 1 bit D/C field - *ptr |= (header.p & 0x01) << 6; ///< 1 bit P flag - *ptr |= (header.si & 0x03) << 4; ///< 2 bits SI + // Sanity check: is there an initial SDU segment? + if (tx_pdu.segment_list.empty()) { + RlcError("build_continuation_sdu_segment was called, but there was no initial segment. SN=%d, Tx SDU (%d B), " + "nof_bytes=%d B ", + sdu_under_segmentation_sn, + tx_pdu.sdu_buf->N_bytes, + nof_bytes); + sdu_under_segmentation_sn = INVALID_RLC_SN; + return 0; + } - if (header.sn_size == rlc_am_nr_sn_size_t::size12bits) { - // write first 4 bit of SN - *ptr |= (header.sn >> 8) & 0x0f; // 4 bit SN - ptr++; - *ptr = header.sn & 0xff; // remaining 8 bit of SN - ptr++; + // Sanity check: can this SDU be sent considering header overhead? + if (nof_bytes <= max_hdr_size) { // Larger header size, as SO is present + RlcInfo("cannot build new sdu_segment, there are not enough bytes allocated to tx header plus data. nof_bytes=%d, " + "max_header_size=%d", + nof_bytes, + max_hdr_size); + return 0; + } + + // Can the rest of the SDU be sent on a single segment PDU? + const rlc_amd_tx_pdu_nr::pdu_segment& seg = tx_pdu.segment_list.back(); + uint32_t last_byte = seg.so + seg.payload_len; + RlcDebug("continuing SDU segment. SN=%d, last byte transmitted %d", tx_pdu.rlc_sn, last_byte); + + // Sanity check: last byte must be smaller than SDU size + if (last_byte > tx_pdu.sdu_buf->N_bytes) { + RlcError( + "last byte transmitted larger than SDU len. SDU len=%d B, last_byte=%d B", tx_pdu.sdu_buf->N_bytes, last_byte); + return 0; + } + + uint32_t segment_payload_full_len = tx_pdu.sdu_buf->N_bytes - last_byte + max_hdr_size; // SO is included + uint32_t segment_payload_len = tx_pdu.sdu_buf->N_bytes - last_byte; + rlc_nr_si_field_t si = {}; + + if (segment_payload_full_len > nof_bytes) { + RlcInfo("grant is not large enough for full SDU. " + "SDU bytes left %d, nof_bytes %d, ", + segment_payload_full_len, + nof_bytes); + si = rlc_nr_si_field_t::neither_first_nor_last_segment; + segment_payload_len = nof_bytes - max_hdr_size; + segment_payload_full_len = nof_bytes; + } else { + RlcInfo("grant is large enough for full SDU." + "SDU bytes left %d, nof_bytes %d, ", + segment_payload_full_len, + nof_bytes); + si = rlc_nr_si_field_t::last_segment; + sdu_under_segmentation_sn = INVALID_RLC_SN; + } + + // Prepare header + rlc_am_nr_pdu_header_t hdr = {}; + hdr.dc = RLC_DC_FIELD_DATA_PDU; + hdr.p = get_pdu_poll(st.tx_next, false, segment_payload_len); + hdr.si = si; + hdr.sn_size = cfg.tx_sn_field_length; + hdr.sn = st.tx_next; + hdr.so = last_byte; + tx_pdu.header = hdr; + log_rlc_am_nr_pdu_header_to_string(logger.info, hdr, rb_name); + + // Write header + uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(hdr, payload); + if (hdr_len >= nof_bytes || hdr_len != max_hdr_size) { + RlcError("error writing AMD PDU header"); + return 0; + } + + // Copy PDU to payload + srsran_assert((hdr_len + segment_payload_len) <= nof_bytes, "Error calculating hdr_len and segment_payload_len"); + memcpy(&payload[hdr_len], &tx_pdu.sdu_buf->msg[last_byte], segment_payload_len); + + // Store PDU segment info into tx_window + rlc_amd_tx_pdu_nr::pdu_segment segment_info = {}; + segment_info.so = last_byte; + segment_info.payload_len = segment_payload_len; + tx_pdu.segment_list.push_back(segment_info); + + if (si == rlc_nr_si_field_t::neither_first_nor_last_segment) { + RlcInfo("grant is not large enough for full SDU." + "Storing SDU segment info"); } else { - // 18bit SN - *ptr |= (header.sn >> 16) & 0x3; // 2 bit SN - ptr++; - *ptr = header.sn >> 8; // bit 3 - 10 of SN - ptr++; - *ptr = (header.sn & 0xff); // remaining 8 bit of SN - ptr++; + RlcInfo("grant is large enough for full SDU." + "Removing current SDU info"); + // SDU is fully TX'ed. Increment TX_NEXT + st.tx_next = (st.tx_next + 1) % mod_nr; + } + + return hdr_len + segment_payload_len; +} + +/** + * Builds a retx RLC PDU. + * + * This will use the retx_queue to get information about the RLC PDU + * being retx'ed. The retx may have been previously transmitted as + * a full SDU or an SDU segment. + * + * \param [tx_pdu] is the tx_pdu info contained in the tx_window. + * \param [payload] is a pointer to the MAC buffer that will hold the PDU segment. + * \param [nof_bytes] is the number of bytes the RLC is allowed to fill. + * + * \returns the number of bytes written to the payload buffer. + * \remark: This functions assumes that the SDU has already been copied to tx_pdu.sdu_buf. + */ +uint32_t rlc_am_nr_tx::build_retx_pdu(uint8_t* payload, uint32_t nof_bytes) +{ + // Check there is at least 1 element before calling front() + if (retx_queue.empty()) { + RlcError("in build_retx_pdu(): retx_queue is empty"); + return 0; } - if (header.so) { - // write SO - *ptr = header.so >> 8; // first part of SO - ptr++; - *ptr = (header.so & 0xff); // second part of SO - ptr++; + rlc_amd_retx_nr_t& retx = retx_queue.front(); + + // Sanity check - drop any retx SNs not present in tx_window + while (not tx_window->has_sn(retx.sn)) { + RlcInfo("SN=%d not in tx window, probably already ACKed. Skip and remove from retx queue", retx.sn); + retx_queue.pop(); + if (!retx_queue.empty()) { + retx = retx_queue.front(); + } else { + RlcInfo("empty retx queue, cannot provide any retx PDU"); + return 0; + } } - pdu->N_bytes += ptr - pdu->msg; + RlcDebug("RETX - SN=%d, is_segment=%s, current_so=%d, so_start=%d, segment_length=%d", + retx.sn, + retx.is_segment ? "true" : "false", + retx.current_so, + retx.so_start, + retx.segment_length); + + // Is segmentation/re-segmentation required? + bool segmentation_required = is_retx_segmentation_required(retx, nof_bytes); - return len; + if (segmentation_required) { + return build_retx_pdu_with_segmentation(retx, payload, nof_bytes); + } + return build_retx_pdu_without_segmentation(retx, payload, nof_bytes); } +/** + * Builds a retx RLC PDU, without requiring (re-)segmentation. + * + * The RETX PDU may be transporting a full SDU or an SDU segment. + * + * \param [retx] is the retx info contained in the retx_queue. This is passed by copy, to avoid + * issues when using retx after pop'ing it from the queue. + * \param [payload] is a pointer to the MAC buffer that will hold the PDU segment. + * \param [nof_bytes] is the number of bytes the RLC is allowed to fill. + * + * \returns the number of bytes written to the payload buffer. + * \remark this function will not update the SI. This means that if the retx is of the last + * SDU segment, the SI should already be of the `last_segment` type. + */ uint32_t -rlc_am_nr_read_status_pdu(const byte_buffer_t* pdu, const rlc_am_nr_sn_size_t sn_size, rlc_am_nr_status_pdu_t* status) +rlc_am_nr_tx::build_retx_pdu_without_segmentation(const rlc_amd_retx_nr_t retx, uint8_t* payload, uint32_t nof_bytes) { - return rlc_am_nr_read_status_pdu(pdu->msg, pdu->N_bytes, sn_size, status); + srsran_assert(tx_window->has_sn(retx.sn), "Called %s without checking retx SN", __FUNCTION__); + srsran_assert(not is_retx_segmentation_required(retx, nof_bytes), + "Called %s without checking if segmentation was required", + __FUNCTION__); + + // Get tx_pdu info from tx_window + rlc_amd_tx_pdu_nr& tx_pdu = (*tx_window)[retx.sn]; + + // Get expected header and payload len + uint32_t expected_hdr_len = get_retx_expected_hdr_len(retx); + uint32_t retx_payload_len = retx.is_segment ? (retx.so_start + retx.segment_length - retx.current_so) + : (*tx_window)[retx.sn].sdu_buf->N_bytes; + srsran_assert(nof_bytes >= (expected_hdr_len + retx_payload_len), + "Called %s but segmentation is required. nof_bytes=%d, expeced_hdr_len=%d, retx_payload_len=%d", + __FUNCTION__, + nof_bytes, + expected_hdr_len, + retx_payload_len); + + // Log RETX info + RlcDebug("SDU%scan be fully re-transmitted. SN=%d, nof_bytes=%d, expected_hdr_len=%d, " + "current_so=%d, so_start=%d, segment_length=%d", + retx.is_segment ? " segment " : " ", + retx.sn, + nof_bytes, + expected_hdr_len, + retx.current_so, + retx.so_start, + retx.segment_length); + + // Get RETX SN, current SO and SI + rlc_nr_si_field_t si = rlc_nr_si_field_t::full_sdu; + if (retx.is_segment) { + if (retx.current_so == 0) { + si = rlc_nr_si_field_t::first_segment; + } else if ((retx.current_so + retx_payload_len) < tx_pdu.sdu_buf->N_bytes) { + si = rlc_nr_si_field_t::neither_first_nor_last_segment; + } else { + si = rlc_nr_si_field_t::last_segment; + } + } + + // Get RETX PDU payload size + uint32_t retx_pdu_payload_size = 0; + if (not retx.is_segment) { + // RETX full SDU + retx_pdu_payload_size = (*tx_window)[retx.sn].sdu_buf->N_bytes; + } else { + // RETX SDU segment + retx_pdu_payload_size = (retx.so_start + retx.segment_length - retx.current_so); + } + + // Update RETX queue. This must be done before calculating + // the polling bit, to make sure the poll bit is calculated correctly + retx_queue.pop(); + + // Write header to payload + rlc_am_nr_pdu_header_t new_header = tx_pdu.header; + new_header.si = si; + new_header.so = retx.current_so; + new_header.p = get_pdu_poll(retx.sn, true, 0); + uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(new_header, payload); + + // Write SDU/SDU segment to payload + uint32_t pdu_bytes = hdr_len + retx_pdu_payload_size; + srsran_assert(pdu_bytes <= nof_bytes, "Error calculating hdr_len and pdu_payload_len"); + memcpy(&payload[hdr_len], &tx_pdu.sdu_buf->msg[retx.current_so], retx_pdu_payload_size); + + // Log RETX + RlcHexInfo((*tx_window)[retx.sn].sdu_buf->msg, + (*tx_window)[retx.sn].sdu_buf->N_bytes, + "Original SDU SN=%d (%d B) (attempt %d/%d)", + retx.sn, + (*tx_window)[retx.sn].sdu_buf->N_bytes, + (*tx_window)[retx.sn].retx_count + 1, + cfg.max_retx_thresh); + RlcHexInfo(payload, pdu_bytes, "RETX PDU SN=%d (%d B)", retx.sn, pdu_bytes); + log_rlc_am_nr_pdu_header_to_string(logger.debug, new_header, rb_name); + + debug_state(); + return pdu_bytes; } -uint32_t rlc_am_nr_read_status_pdu(const uint8_t* payload, - const uint32_t nof_bytes, - const rlc_am_nr_sn_size_t sn_size, - rlc_am_nr_status_pdu_t* status) +/** + * Builds a retx RLC PDU that requires (re-)segmentation. + * + * \param [tx_pdu] is the tx_pdu info contained in the tx_window. + * \param [payload] is a pointer to the MAC buffer that will hold the PDU segment. + * \param [nof_bytes] is the number of bytes the RLC is allowed to fill. + * + * \returns the number of bytes written to the payload buffer. + * \remark: This functions assumes that the SDU has already been copied to tx_pdu.sdu_buf. + */ +uint32_t rlc_am_nr_tx::build_retx_pdu_with_segmentation(rlc_amd_retx_nr_t& retx, uint8_t* payload, uint32_t nof_bytes) { - uint8_t* ptr = const_cast(payload); + // Get tx_pdu info from tx_window + srsran_assert(tx_window->has_sn(retx.sn), "Called %s without checking retx SN", __FUNCTION__); + srsran_assert(is_retx_segmentation_required(retx, nof_bytes), + "Called %s without checking if segmentation was not required", + __FUNCTION__); + + rlc_amd_tx_pdu_nr& tx_pdu = (*tx_window)[retx.sn]; - // fixed part - status->cpt = (rlc_am_nr_control_pdu_type_t)((*ptr >> 4) & 0x07); // 3 bits CPT + // Is this an SDU segment or a full SDU? + if (not retx.is_segment) { + RlcDebug("Creating SDU segment from full SDU. SN=%d Tx SDU (%d B), nof_bytes=%d B ", + retx.sn, + tx_pdu.sdu_buf->N_bytes, + nof_bytes); - // sanity check - if (status->cpt != rlc_am_nr_control_pdu_type_t::status_pdu) { - fprintf(stderr, "Malformed PDU, reserved bits are set.\n"); + } else { + RlcDebug("Creating SDU segment from SDU segment. SN=%d, current_so=%d, so_start=%d, segment_length=%d", + retx.sn, + retx.current_so, + retx.so_start, + retx.segment_length); + } + + uint32_t expected_hdr_len = min_hdr_size; + rlc_nr_si_field_t si = rlc_nr_si_field_t::first_segment; + if (retx.current_so != 0) { + si = rlc_nr_si_field_t::neither_first_nor_last_segment; + expected_hdr_len = max_hdr_size; + } + + // Sanity check: are there enough bytes for header plus data? + if (nof_bytes <= expected_hdr_len) { + RlcInfo("Not enough bytes for RETX payload plus header. SN=%d, nof_bytes=%d, hdr_len=%d", + retx.sn, + nof_bytes, + expected_hdr_len); return 0; } - if (sn_size == rlc_am_nr_sn_size_t::size12bits) { - status->ack_sn = (*ptr & 0x0F) << 8; // first 4 bits SN - ptr++; + // Sanity check: could this have been transmitted without segmentation? + if (nof_bytes > (tx_pdu.sdu_buf->N_bytes + expected_hdr_len)) { + RlcError("called %s, but there are enough bytes to avoid segmentation. SN=%d", __FUNCTION__, retx.sn); + return 0; + } - status->ack_sn |= (*ptr & 0xFF); // last 8 bits SN - ptr++; + // Can the RETX PDU be transmitted in a single PDU? + uint32_t retx_pdu_payload_size = nof_bytes - expected_hdr_len; - // read E1 flag - uint8_t e1 = *ptr & 0x80; + // Write header + rlc_am_nr_pdu_header_t hdr = tx_pdu.header; + hdr.p = get_pdu_poll(retx.sn, true, 0); + hdr.so = retx.current_so; + hdr.si = si; + uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(hdr, payload); + if (hdr_len >= nof_bytes || hdr_len != expected_hdr_len) { + log_rlc_am_nr_pdu_header_to_string(logger.error, hdr, rb_name); + RlcError("Error writing AMD PDU header. nof_bytes=%d, hdr_len=%d", nof_bytes, hdr_len); + return 0; + } + log_rlc_am_nr_pdu_header_to_string(logger.info, hdr, rb_name); - // sanity check for reserved bits - if ((*ptr & 0x7f) != 0) { - fprintf(stderr, "Malformed PDU, reserved bits are set.\n"); - return 0; + // Copy SDU segment into payload + srsran_assert((hdr_len + retx_pdu_payload_size) <= nof_bytes, "Error calculating hdr_len and segment_payload_len"); + memcpy(&payload[hdr_len], &tx_pdu.sdu_buf->msg[retx.current_so], retx_pdu_payload_size); + + // Store PDU segment info into tx_window + RlcDebug("Updating RETX segment info. SN=%d, is_segment=%s", retx.sn, retx.is_segment ? "true" : "false"); + if (!retx.is_segment) { + // Retx is not a segment yet + rlc_amd_tx_pdu_nr::pdu_segment seg1 = {}; + seg1.so = retx.current_so; + seg1.payload_len = retx_pdu_payload_size; + rlc_amd_tx_pdu_nr::pdu_segment seg2 = {}; + seg2.so = retx.current_so + retx_pdu_payload_size; + seg2.payload_len = retx.segment_length - retx_pdu_payload_size; + tx_pdu.segment_list.push_back(seg1); + tx_pdu.segment_list.push_back(seg2); + RlcDebug("New segment: SN=%d, SO=%d len=%d", retx.sn, seg1.so, seg1.payload_len); + RlcDebug("New segment: SN=%d, SO=%d len=%d", retx.sn, seg2.so, seg2.payload_len); + } else { + // Retx is already a segment + // Find current segment in segment list. + std::list::iterator it; + for (it = tx_pdu.segment_list.begin(); it != tx_pdu.segment_list.end(); ++it) { + if (it->so == retx.current_so) { + break; + } } + if (it != tx_pdu.segment_list.end()) { + rlc_amd_tx_pdu_nr::pdu_segment seg1 = {}; + seg1.so = it->so; + seg1.payload_len = retx_pdu_payload_size; + rlc_amd_tx_pdu_nr::pdu_segment seg2 = {}; + seg2.so = it->so + retx_pdu_payload_size; + seg2.payload_len = it->payload_len - retx_pdu_payload_size; - // all good, continue with next byte depending on E1 - ptr++; + std::list::iterator begin_it = tx_pdu.segment_list.erase(it); + std::list::iterator insert_it = tx_pdu.segment_list.insert(begin_it, seg2); + std::list::iterator insert_it2 = tx_pdu.segment_list.insert(insert_it, seg1); + RlcDebug("Old segment SN=%d, SO=%d len=%d", retx.sn, retx.current_so, retx.segment_length); + RlcDebug("New segment SN=%d, SO=%d len=%d", retx.sn, seg1.so, seg1.payload_len); + RlcDebug("New segment SN=%d, SO=%d len=%d", retx.sn, seg2.so, seg2.payload_len); + } else { + RlcDebug("Could not find segment. SN=%d, SO=%d length=%d", retx.sn, retx.current_so, retx.segment_length); + } + } - // reset number of acks - status->N_nack = 0; + // Update retx queue + retx.is_segment = true; + retx.current_so = retx.current_so + retx_pdu_payload_size; - if (e1) { - // E1 flag set, read a NACK_SN - rlc_status_nack_t nack = {}; - nack.nack_sn = (*ptr & 0xff) << 4; - ptr++; - // uint8_t len2 = (*ptr & 0xF0) >> 4; - nack.nack_sn |= (*ptr & 0xF0) >> 4; - status->nacks[status->N_nack] = nack; + RlcDebug("Updated RETX info. is_segment=%s, current_so=%d, so_start=%d, segment_length=%d", + retx.is_segment ? "true" : "false", + retx.current_so, + retx.so_start, + retx.segment_length); - status->N_nack++; + if (retx.current_so >= tx_pdu.sdu_buf->N_bytes) { + RlcError("Current SO larger or equal to SDU size when creating SDU segment. SN=%d, current SO=%d, SO_start=%d, " + "segment_length=%d", + retx.sn, + retx.current_so, + retx.so_start, + retx.segment_length); + return 0; + } + + if (retx.current_so >= retx.so_start + retx.segment_length) { + RlcError("Current SO larger than SO_start + segment_length. SN=%d, current SO=%d, SO_start=%d, segment_length=%s", + retx.sn, + retx.current_so, + retx.so_start, + retx.segment_length); + return 0; + } + + return hdr_len + retx_pdu_payload_size; +} + +bool rlc_am_nr_tx::is_retx_segmentation_required(const rlc_amd_retx_nr_t& retx, uint32_t nof_bytes) +{ + bool segmentation_required = false; + if (retx.is_segment) { + uint32_t expected_hdr_size = retx.current_so == 0 ? min_hdr_size : max_hdr_size; + if (nof_bytes < ((retx.so_start + retx.segment_length - retx.current_so) + expected_hdr_size)) { + RlcInfo("Re-segmentation required for RETX. SN=%d", retx.sn); + segmentation_required = true; + } + } else { + if (nof_bytes < ((*tx_window)[retx.sn].sdu_buf->N_bytes + min_hdr_size)) { + RlcInfo("Segmentation required for RETX. SN=%d", retx.sn); + segmentation_required = true; } } + return segmentation_required; +} - return SRSRAN_SUCCESS; +uint32_t rlc_am_nr_tx::get_retx_expected_hdr_len(const rlc_amd_retx_nr_t& retx) +{ + uint32_t expected_hdr_len = min_hdr_size; + if (retx.is_segment && retx.current_so != 0) { + expected_hdr_len = max_hdr_size; + } + return expected_hdr_len; } +uint32_t rlc_am_nr_tx::build_status_pdu(byte_buffer_t* payload, uint32_t nof_bytes) +{ + RlcInfo("generating status PDU. Bytes available:%d", nof_bytes); + rlc_am_nr_status_pdu_t status(cfg.rx_sn_field_length); // carries status of RX entity, hence use SN length of RX + int pdu_len = rx->get_status_pdu(&status, nof_bytes); + if (pdu_len == SRSRAN_ERROR) { + RlcDebug("deferred status PDU. Cause: Failed to acquire rx lock"); + pdu_len = 0; + } else if (pdu_len > 0 && nof_bytes >= static_cast(pdu_len)) { + RlcDebug("generated status PDU. Bytes:%d", pdu_len); + log_rlc_am_nr_status_pdu_to_string(logger.info, "TX status PDU - %s", &status, rb_name); + pdu_len = rlc_am_nr_write_status_pdu(status, cfg.tx_sn_field_length, payload); + } else { + RlcInfo("cannot tx status PDU - %d bytes available, %d bytes required", nof_bytes, pdu_len); + pdu_len = 0; + } + + return payload->N_bytes; +} + +void rlc_am_nr_tx::handle_control_pdu(uint8_t* payload, uint32_t nof_bytes) +{ + if (not tx_enabled) { + return; + } + + std::lock_guard lock(mutex); + rlc_am_nr_status_pdu_t status(cfg.tx_sn_field_length); + RlcHexDebug(payload, nof_bytes, "%s Rx control PDU", parent->rb_name); + rlc_am_nr_read_status_pdu(payload, nof_bytes, cfg.tx_sn_field_length, &status); + log_rlc_am_nr_status_pdu_to_string(logger.info, "RX status PDU: %s", &status, parent->rb_name); + + /* + * Sanity check the received status report. + * Checking if the ACK_SN is inside the valid ACK_SN window (the TX window "off-by-one") + * makes sure we discard out of order status reports. + * Checking if ACK_SN > Tx_Next + 1 makes sure we do not receive a ACK/NACK for something we did not TX + * ACK_SN may be equal to TX_NEXT + 1, if not all SDU segments with SN=TX_NEXT have been transmitted. + */ + if (not valid_ack_sn(status.ack_sn)) { + RlcInfo("Received ACK with SN outside of TX_WINDOW, ignoring status report. ACK_SN=%d, TX_NEXT_ACK=%d.", + status.ack_sn, + st.tx_next_ack); + info_state(); + return; + } + + if (tx_mod_base_nr(status.ack_sn) > tx_mod_base_nr(st.tx_next + 1)) { + RlcWarning("Received ACK with SN larger than TX_NEXT, ignoring status report. SN=%d, TX_NEXT_ACK=%d, TX_NEXT=%d", + status.ack_sn, + st.tx_next_ack, + st.tx_next); + info_state(); + return; + } + + /** + * Section 5.3.3.3: Reception of a STATUS report + * - if the STATUS report comprises a positive or negative acknowledgement for the RLC SDU with sequence + * number equal to POLL_SN: + * - if t-PollRetransmit is running: + * - stop and reset t-PollRetransmit. + */ + if (tx_mod_base_nr(st.poll_sn) < tx_mod_base_nr(status.ack_sn)) { + if (poll_retransmit_timer.is_running()) { + RlcDebug("Received ACK or NACK for POLL_SN=%d. Stopping t-PollRetransmit", st.poll_sn); + poll_retransmit_timer.stop(); + } else { + RlcDebug("Received ACK or NACK for POLL_SN=%d. t-PollRetransmit already stopped", st.poll_sn); + } + } else { + RlcDebug("POLL_SN=%d > ACK_SN=%d. Not stopping t-PollRetransmit ", st.poll_sn, status.ack_sn); + } + + /* + * - if the SN of the corresponding RLC SDU falls within the range + * TX_Next_Ack <= SN < = the highest SN of the AMD PDU among the AMD PDUs submitted to lower layer: + * - consider the RLC SDU or the RLC SDU segment for which a negative acknowledgement was received for + * retransmission. + */ + // Process ACKs + uint32_t stop_sn = status.nacks.size() == 0 + ? status.ack_sn + : status.nacks[0].nack_sn; // Stop processing ACKs at the first NACK, if it exists. + for (uint32_t sn = st.tx_next_ack; tx_mod_base_nr(sn) < tx_mod_base_nr(stop_sn); sn = (sn + 1) % mod_nr) { + if (tx_window->has_sn(sn)) { + notify_info_vec.push_back((*tx_window)[sn].pdcp_sn); + retx_queue.remove_sn(sn); // remove any pending retx for that SN + tx_window->remove_pdu(sn); + st.tx_next_ack = (sn + 1) % mod_nr; + } else { + RlcError("Missing ACKed SN from TX window"); + break; + } + } + RlcDebug("Processed status report ACKs. ACK_SN=%d. Tx_Next_Ack=%d", status.ack_sn, st.tx_next_ack); + + // Process N_nacks + std::set retx_sn_set; // Set of PDU SNs added for retransmission (no duplicates) + for (uint32_t nack_idx = 0; nack_idx < status.nacks.size(); nack_idx++) { + if (status.nacks[nack_idx].has_nack_range) { + for (uint32_t range_sn = status.nacks[nack_idx].nack_sn; + range_sn < status.nacks[nack_idx].nack_sn + status.nacks[nack_idx].nack_range; + range_sn++) { + rlc_status_nack_t nack = {}; + nack.nack_sn = range_sn; + if (status.nacks[nack_idx].has_so) { + // Apply so_start to first range item + if (range_sn == status.nacks[nack_idx].nack_sn) { + nack.so_start = status.nacks[nack_idx].so_start; + } + // Apply so_end to last range item + if (range_sn == (status.nacks[nack_idx].nack_sn + status.nacks[nack_idx].nack_range - 1)) { + nack.so_end = status.nacks[nack_idx].so_end; + } + // Enable has_so only if the offsets do not span the whole SDU + nack.has_so = (nack.so_start != 0) || (nack.so_end != rlc_status_nack_t::so_end_of_sdu); + } + handle_nack(nack, retx_sn_set); + } + } else { + handle_nack(status.nacks[nack_idx], retx_sn_set); + } + } + + // Process retx_count and inform upper layers if needed + for (uint32_t retx_sn : retx_sn_set) { + auto& pdu = (*tx_window)[retx_sn]; + // Increment retx_count + if (pdu.retx_count == RETX_COUNT_NOT_STARTED) { + // Set retx_count = 0 on first RE-transmission of associated SDU (38.322 Sec. 5.3.2) + pdu.retx_count = 0; + } else { + // Increment otherwise + pdu.retx_count++; + } + + // Inform upper layers if needed + check_sn_reached_max_retx(retx_sn); + } + + // Notify PDCP + if (not notify_info_vec.empty()) { + parent->pdcp->notify_delivery(parent->lcid, notify_info_vec); + } + notify_info_vec.clear(); +} + +void rlc_am_nr_tx::handle_nack(const rlc_status_nack_t& nack, std::set& retx_sn_set) +{ + if (tx_mod_base_nr(st.tx_next_ack) <= tx_mod_base_nr(nack.nack_sn) && + tx_mod_base_nr(nack.nack_sn) <= tx_mod_base_nr(st.tx_next)) { + RlcDebug("Handling NACK for SN=%d", nack.nack_sn); + if (tx_window->has_sn(nack.nack_sn)) { + auto& pdu = (*tx_window)[nack.nack_sn]; + + if (nack.has_so) { + // NACK'ing missing bytes in SDU segment. + // Retransmit all SDU segments within those missing bytes. + if (pdu.segment_list.empty()) { + RlcError("Received NACK with SO, but there is no segment information. SN=%d", nack.nack_sn); + } + bool segment_found = false; + for (const rlc_amd_tx_pdu_nr::pdu_segment& segm : pdu.segment_list) { + if (segm.so >= nack.so_start && segm.so <= nack.so_end) { + if (not retx_queue.has_sn(nack.nack_sn, segm.so)) { + rlc_amd_retx_nr_t& retx = retx_queue.push(); + retx.sn = nack.nack_sn; + retx.is_segment = true; + retx.so_start = segm.so; + retx.current_so = segm.so; + retx.segment_length = segm.payload_len; + retx_sn_set.insert(nack.nack_sn); + RlcInfo("Scheduled RETX of SDU segment SN=%d, so_start=%d, segment_length=%d", + retx.sn, + retx.so_start, + retx.segment_length); + } else { + RlcInfo("Skip already scheduled RETX of SDU segment SN=%d, so_start=%d, segment_length=%d", + nack.nack_sn, + segm.so, + segm.payload_len); + } + segment_found = true; + } + } + if (!segment_found) { + RlcWarning("Could not find segment for NACK_SN=%d. SO_start=%d, SO_end=%d", + nack.nack_sn, + nack.so_start, + nack.so_end); + for (const rlc_amd_tx_pdu_nr::pdu_segment& segm : pdu.segment_list) { + RlcDebug("Segments for SN=%d. SO=%d, SO_end=%d", nack.nack_sn, segm.so, segm.payload_len); + } + } + } else { + // NACK'ing full SDU. + // add to retx queue if it's not already there + if (not retx_queue.has_sn(nack.nack_sn)) { + // Have we segmented the SDU already? + if ((*tx_window)[nack.nack_sn].segment_list.empty()) { + rlc_amd_retx_nr_t& retx = retx_queue.push(); + retx.sn = nack.nack_sn; + retx.is_segment = false; + retx.so_start = 0; + retx.current_so = 0; + retx.segment_length = pdu.sdu_buf->N_bytes; + retx_sn_set.insert(nack.nack_sn); + RlcInfo("Scheduled RETX of SDU SN=%d", retx.sn); + } else { + RlcInfo("Scheduled RETX of SDU SN=%d", nack.nack_sn); + retx_sn_set.insert(nack.nack_sn); + for (auto segm : (*tx_window)[nack.nack_sn].segment_list) { + rlc_amd_retx_nr_t& retx = retx_queue.push(); + retx.sn = nack.nack_sn; + retx.is_segment = true; + retx.so_start = segm.so; + retx.current_so = segm.so; + retx.segment_length = segm.payload_len; + RlcInfo("Scheduled RETX of SDU Segment. SN=%d, SO=%d, len=%d", retx.sn, segm.so, segm.payload_len); + } + } + } else { + RlcInfo("RETX queue already has NACK_SN. SDU SN=%d, Tx_Next_Ack=%d, Tx_Next=%d", + nack.nack_sn, + st.tx_next_ack, + st.tx_next); + } + } + } else { + RlcInfo("TX window does not contain NACK_SN. SDU SN=%d, Tx_Next_Ack=%d, Tx_Next=%d", + nack.nack_sn, + st.tx_next_ack, + st.tx_next); + } // TX window containts NACK SN + } else { + RlcInfo( + "RETX not in expected range. SDU SN=%d, Tx_Next_Ack=%d, Tx_Next=%d", nack.nack_sn, st.tx_next_ack, st.tx_next); + } // NACK SN within expected range +} /** - * Write a RLC AM NR status PDU to a PDU buffer and eets the length of the generate PDU accordingly - * @param status_pdu The status PDU - * @param pdu A pointer to a unique bytebuffer - * @return SRSRAN_SUCCESS if PDU was written, SRSRAN_ERROR otherwise + * Helper to check if a SN has reached the max reTx threshold + * + * Caller _must_ hold the mutex when calling the function. + * If the retx has been reached for a SN the upper layers (i.e. RRC/PDCP) will be informed. + * The SN is _not_ removed from the Tx window, so retransmissions of that SN can still occur. + * + * + * @param sn The SN of the PDU to check */ -int32_t rlc_am_nr_write_status_pdu(const rlc_am_nr_status_pdu_t& status_pdu, - const rlc_am_nr_sn_size_t sn_size, - byte_buffer_t* pdu) +void rlc_am_nr_tx::check_sn_reached_max_retx(uint32_t sn) +{ + if ((*tx_window)[sn].retx_count == cfg.max_retx_thresh) { + RlcWarning("Signaling max number of reTx=%d for SN=%d", (*tx_window)[sn].retx_count, sn); + parent->rrc->max_retx_attempted(); + srsran::pdcp_sn_vector_t pdcp_sns; + pdcp_sns.push_back((*tx_window)[sn].pdcp_sn); + parent->pdcp->notify_failure(parent->lcid, pdcp_sns); + + std::lock_guard lock(parent->metrics_mutex); + parent->metrics.num_lost_pdus++; + } +} + +uint32_t rlc_am_nr_tx::get_buffer_state() { - uint8_t* ptr = pdu->msg; + uint32_t tx_queue = 0; + uint32_t prio_tx_queue = 0; + get_buffer_state(tx_queue, prio_tx_queue); + return tx_queue + prio_tx_queue; +} - // fixed header part - *ptr = 0; ///< 1 bit D/C field and 3bit CPT are all zero +void rlc_am_nr_tx::get_buffer_state(uint32_t& n_bytes_new, uint32_t& n_bytes_prio) +{ + std::lock_guard lock(mutex); + RlcDebug("buffer state - do_status=%s", do_status() ? "yes" : "no"); - if (sn_size == rlc_am_nr_sn_size_t::size12bits) { - // write first 4 bit of ACK_SN - *ptr |= (status_pdu.ack_sn >> 8) & 0x0f; // 4 bit ACK_SN - ptr++; - *ptr = status_pdu.ack_sn & 0xff; // remaining 8 bit of SN - ptr++; + if (!tx_enabled) { + RlcError("get_buffer_state() failed: TX is not enabled."); + return; + } - // write E1 flag in octet 3 - *ptr = (status_pdu.N_nack > 0) ? 0x80 : 0x00; - ptr++; + // Bytes needed for status report + if (do_status()) { + n_bytes_prio += rx->get_status_pdu_length(); + RlcDebug("buffer state - total status report: %d bytes", n_bytes_prio); + } - if (status_pdu.N_nack > 0) { - // write first 8 bit of NACK_SN - *ptr = (status_pdu.nacks[0].nack_sn >> 4) & 0xff; - ptr++; + // Bytes needed for retx + for (const rlc_amd_retx_nr_t& retx : retx_queue.get_inner_queue()) { + RlcDebug("buffer state - retx - SN=%d, Segment: %s, %d:%d", + retx.sn, + retx.is_segment ? "true" : "false", + retx.so_start, + retx.so_start + retx.segment_length - 1); + if (tx_window->has_sn(retx.sn)) { + int req_bytes = retx.segment_length; + int hdr_req_bytes = (retx.is_segment && retx.current_so != 0) ? max_hdr_size : min_hdr_size; + if (req_bytes <= 0) { + RlcError("buffer state - retx - invalid length=%d for SN=%d", req_bytes, retx.sn); + } else { + n_bytes_prio += (req_bytes + hdr_req_bytes); + RlcDebug("buffer state - retx: %d bytes", n_bytes_prio); + } + } else { + RlcWarning("buffer state - retx for SN=%d is outside the tx_window", retx.sn); + } + } - // write remaining 4 bits of NACK_SN - *ptr = status_pdu.nacks[0].nack_sn & 0xf0; - ptr++; + // Bytes needed for tx of the rest of the SDU that is currently under segmentation (if any) + if (sdu_under_segmentation_sn != INVALID_RLC_SN) { + if (tx_window->has_sn(sdu_under_segmentation_sn)) { + rlc_amd_tx_pdu_nr& seg_pdu = (*tx_window)[sdu_under_segmentation_sn]; + if (not seg_pdu.segment_list.empty()) { + // obtain amount of already transmitted Bytes + const rlc_amd_tx_pdu_nr::pdu_segment& seg = seg_pdu.segment_list.back(); + uint32_t last_byte = seg.so + seg.payload_len; + if (last_byte <= seg_pdu.sdu_buf->N_bytes) { + // compute remaining bytes pending for transmission + uint32_t remaining_bytes = seg_pdu.sdu_buf->N_bytes - last_byte; + n_bytes_new += remaining_bytes + max_hdr_size; + } else { + RlcError( + "buffer state - last segment of SDU under segmentation exceeds SDU len. SDU len=%d B, last_byte=%d B", + seg_pdu.sdu_buf->N_bytes, + last_byte); + } + } else { + RlcError("buffer state - SDU under segmentation has empty segment list. Ignoring SN=%d", + sdu_under_segmentation_sn); + } + } else { + sdu_under_segmentation_sn = INVALID_RLC_SN; + RlcError("buffer state - SDU under segmentation does not exist in tx_window. Aborting segmentation SN=%d", + sdu_under_segmentation_sn); + } + } + + // Bytes needed for tx SDUs in queue + uint32_t n_sdus = tx_sdu_queue.get_n_sdus(); + n_bytes_new += tx_sdu_queue.size_bytes(); + + // Room needed for fixed header of data PDUs + n_bytes_new += min_hdr_size * n_sdus; + RlcDebug("total buffer state - %d SDUs (%d B)", n_sdus, n_bytes_new + n_bytes_prio); + + if (bsr_callback) { + RlcDebug("calling BSR callback - %d new_tx, %d priority bytes", n_bytes_new, n_bytes_prio); + bsr_callback(parent->lcid, n_bytes_new, n_bytes_prio); + } +} + +/* + * Check whether the polling bit needs to be set, as specified in + * TS 38.322, section 5.3.3.2 + */ +uint8_t rlc_am_nr_tx::get_pdu_poll(uint32_t sn, bool is_retx, uint32_t sdu_bytes) +{ + RlcDebug("Checking poll bit requirements for PDU. SN=%d, retx=%s, sdu_bytes=%d, POLL_SN=%d", + sn, + is_retx ? "true" : "false", + sdu_bytes, + st.poll_sn); + /* For each AMD PDU or AMD PDU segment that has not been previoulsy tranmitted: + * - increment PDU_WITHOUT_POLL by one; + * - increment BYTE_WITHOUT_POLL by every new byte of Data field element that it maps to the Data field of the AMD + * PDU; + * - if PDU_WITHOUT_POLL >= pollPDU; or + * - if BYTE_WITHOUT_POLL >= pollByte: + * - include a poll in the AMD PDU as described below. + */ + uint8_t poll = 0; + if (!is_retx) { + st.pdu_without_poll++; + st.byte_without_poll += sdu_bytes; + if (cfg.poll_pdu > 0 && st.pdu_without_poll >= (uint32_t)cfg.poll_pdu) { + poll = 1; + RlcDebug("Setting poll bit due to PollPDU. SN=%d, POLL_SN=%d", sn, st.poll_sn); + } + if (cfg.poll_byte > 0 && st.byte_without_poll >= (uint32_t)cfg.poll_byte) { + poll = 1; + RlcDebug("Setting poll bit due to PollBYTE. SN=%d, POLL_SN=%d", sn, st.poll_sn); + } + } + + /* + * - if both the transmission buffer and the retransmission buffer becomes empty + * (excluding transmitted RLC SDUs or RLC SDU segments awaiting acknowledgements) + * after the transmission of the AMD PDU; or + * - if no new RLC SDU can be transmitted after the transmission of the AMD PDU (e.g. due to window stalling); + * - include a poll in the AMD PDU as described below. + */ + if ((tx_sdu_queue.is_empty() && retx_queue.empty() && sdu_under_segmentation_sn == INVALID_RLC_SN) || + tx_window->full()) { + RlcDebug("Setting poll bit due to empty buffers/inablity to TX. SN=%d, POLL_SN=%d", sn, st.poll_sn); + poll = 1; + } + + /* + * - If poll bit is included: + * - set PDU_WITHOUT_POLL to 0; + * - set BYTE_WITHOUT_POLL to 0. + */ + if (poll == 1) { + st.pdu_without_poll = 0; + st.byte_without_poll = 0; + /* + * - set POLL_SN to the highest SN of the AMD PDU among the AMD PDUs submitted to lower layer; + * - if t-PollRetransmit is not running: + * - start t-PollRetransmit. + * - else: + * - restart t-PollRetransmit. + */ + if (!is_retx) { + // This is not an RETX, but a new transmission + // As such it should be the highest SN submitted to the lower layers + st.poll_sn = sn; + RlcDebug("Setting new POLL_SN. POLL_SN=%d", sn); + } + if (cfg.t_poll_retx > 0) { + if (not poll_retransmit_timer.is_running()) { + poll_retransmit_timer.run(); + } else { + poll_retransmit_timer.stop(); + poll_retransmit_timer.run(); + } + RlcInfo("Started t-PollRetransmit. POLL_SN=%d", st.poll_sn); + } + } + return poll; +} + +bool rlc_am_nr_tx::do_status() +{ + return rx->get_do_status(); +} + +void rlc_am_nr_tx::reestablish() +{ + stop(); +} + +void rlc_am_nr_tx::empty_queue() +{ + std::lock_guard lock(mutex); + empty_queue_no_lock(); +} + +void rlc_am_nr_tx::empty_queue_no_lock() +{ + // deallocate all SDUs in transmit queue + while (tx_sdu_queue.size() > 0) { + unique_byte_buffer_t buf = tx_sdu_queue.read(); + } +} + +void rlc_am_nr_tx::stop() +{ + std::lock_guard lock(mutex); + empty_queue_no_lock(); + + if (parent->timers != nullptr && poll_retransmit_timer.is_valid()) { + poll_retransmit_timer.stop(); + } + + st = {}; + + sdu_under_segmentation_sn = INVALID_RLC_SN; + + // Drop all messages in TX window + tx_window->clear(); + + // Drop all messages in RETX queue + retx_queue.clear(); + + tx_enabled = false; +} + +void rlc_am_nr_tx::timer_expired(uint32_t timeout_id) +{ + std::unique_lock lock(mutex); + + // t-PollRetransmit + if (poll_retransmit_timer.is_valid() && poll_retransmit_timer.id() == timeout_id) { + RlcDebug("Poll retransmission timer expired after %dms", poll_retransmit_timer.duration()); + debug_state(); + /* + * - if both the transmission buffer and the retransmission buffer are empty + * (excluding transmitted RLC SDU or RLC SDU segment awaiting acknowledgements); or + * - if no new RLC SDU or RLC SDU segment can be transmitted (e.g. due to window stalling): + * - consider the RLC SDU with the highest SN among the RLC SDUs submitted to lower layer for + * retransmission; or + * - consider any RLC SDU which has not been positively acknowledged for retransmission. + * - include a poll in an AMD PDU as described in section 5.3.3.2. + */ + if ((tx_sdu_queue.is_empty() && retx_queue.empty()) || tx_window->full()) { + if (tx_window->empty()) { + RlcError("t-PollRetransmit expired, but the tx_window is empty. POLL_SN=%d, Tx_Next_Ack=%d, tx_window_size=%d", + st.poll_sn, + st.tx_next_ack, + tx_window->size()); + return; + } + if (not tx_window->has_sn(st.tx_next_ack)) { + RlcError("t-PollRetransmit expired, but Tx_Next_Ack is not in the tx_widow. POLL_SN=%d, Tx_Next_Ack=%d, " + "tx_window_size=%d", + st.poll_sn, + st.tx_next_ack, + tx_window->size()); + return; + } + // RETX first RLC SDU that has not been ACKed + // or first SDU segment of the first RLC SDU + // that has not been acked + rlc_amd_retx_nr_t& retx = retx_queue.push(); + retx.sn = st.tx_next_ack; + if ((*tx_window)[st.tx_next_ack].segment_list.empty()) { + // Full SDU + retx.is_segment = false; + retx.so_start = 0; + retx.segment_length = (*tx_window)[st.tx_next_ack].sdu_buf->N_bytes; + retx.current_so = 0; + } else { + // To make sure we do not mess up the segment list + // We RETX an SDU segment instead of the full SDU + // if the SDU has been segmented before. + // As we cannot know which segments have been ACKed before + // we simply RETX the first one. + retx.is_segment = true; + retx.so_start = 0; + retx.current_so = 0; + retx.segment_length = (*tx_window)[st.tx_next_ack].segment_list.begin()->payload_len; + } + RlcDebug("Retransmission because of t-PollRetransmit. RETX SN=%d, is_segment=%s, so_start=%d, segment_length=%d", + retx.sn, + retx.is_segment ? "true" : "false", + retx.so_start, + retx.segment_length); + } + return; + } +} + +/* + * Window helpers + */ +uint32_t rlc_am_nr_tx::tx_mod_base_nr(uint32_t sn) const +{ + return (sn - st.tx_next_ack) % mod_nr; +} + +uint32_t rlc_am_nr_tx::tx_window_size() const +{ + return am_window_size(cfg.tx_sn_field_length); +} + +bool rlc_am_nr_tx::inside_tx_window(uint32_t sn) const +{ + // TX_Next_Ack <= SN < TX_Next_Ack + AM_Window_Size + return tx_mod_base_nr(sn) < tx_window_size(); +} + +/* + * This function is used to check if a received status report + * as a valid ACK_SN. + * + * ACK_SN may be equal to TX_NEXT + AM_Window_Size if the PDU + * with SN=TX_NEXT+AM_Window_Size has been received by the RX + * An ACK_SN == Tx_Next_Ack doesn't ACK or NACKs any PDUs, as + * such, such a status report can be discarded. + */ +bool rlc_am_nr_tx::valid_ack_sn(uint32_t sn) const +{ + // Tx_Next_Ack < SN <= TX_Next + AM_Window_Size + return (0 < tx_mod_base_nr(sn)) && (tx_mod_base_nr(sn) <= tx_window_size()); +} + +/* + * Debug Helpers + */ +void rlc_am_nr_tx::debug_state() const +{ + RlcDebug("TX entity state: Tx_Next_Ack=%d, Tx_Next=%d, POLL_SN=%d, PDU_WITHOUT_POLL=%d, BYTE_WITHOUT_POLL=%d", + st.tx_next_ack, + st.tx_next, + st.poll_sn, + st.pdu_without_poll, + st.byte_without_poll); +} + +void rlc_am_nr_tx::info_state() const +{ + RlcInfo("TX window state: SDUs %d", tx_window->size()); + RlcInfo("TX entity state: Tx_Next_Ack=%d, Tx_Next=%d, POLL_SN=%d, PDU_WITHOUT_POLL=%d, BYTE_WITHOUT_POLL=%d", + st.tx_next_ack, + st.tx_next, + st.poll_sn, + st.pdu_without_poll, + st.byte_without_poll); +} + +void rlc_am_nr_tx::debug_window() const +{ + RlcDebug("TX window state: Tx_Next_Ack=%d, Tx_Next=%d, SDUs=%d", st.tx_next_ack, st.tx_next, tx_window->size()); +} +/**************************************************************************** + * Rx subclass implementation + ***************************************************************************/ +rlc_am_nr_rx::rlc_am_nr_rx(rlc_am* parent_) : + parent(parent_), + pool(byte_buffer_pool::get_instance()), + status_prohibit_timer(parent->timers->get_unique_timer()), + reassembly_timer(parent->timers->get_unique_timer()), + rlc_am_base_rx(parent_, parent_->logger) +{ +} + +bool rlc_am_nr_rx::configure(const rlc_config_t& cfg_) +{ + cfg = cfg_.am_nr; + rb_name = parent->rb_name; + // Configure status prohibit timer + if (cfg.t_status_prohibit > 0) { + status_prohibit_timer.set(static_cast(cfg.t_status_prohibit), + [this](uint32_t timerid) { timer_expired(timerid); }); + } + + // Configure t_reassembly timer + if (cfg.t_reassembly > 0) { + reassembly_timer.set(static_cast(cfg.t_reassembly), [this](uint32_t timerid) { timer_expired(timerid); }); + } + + mod_nr = cardinality(cfg.rx_sn_field_length); + switch (cfg.rx_sn_field_length) { + case rlc_am_nr_sn_size_t::size12bits: + rx_window = std::unique_ptr >( + new rlc_ringbuffer_t); + break; + case rlc_am_nr_sn_size_t::size18bits: + rx_window = std::unique_ptr >( + new rlc_ringbuffer_t); + break; + default: + RlcError("attempt to configure unsupported rx_sn_field_length %s", to_string(cfg.rx_sn_field_length)); + return false; + } + + RlcDebug("RLC AM NR configured rx entity."); + + return true; +} + +void rlc_am_nr_rx::stop() +{ + std::lock_guard lock(mutex); + + if (parent->timers != nullptr && reassembly_timer.is_valid()) { + reassembly_timer.stop(); + } + + if (parent->timers != nullptr && status_prohibit_timer.is_valid()) { + status_prohibit_timer.stop(); + } + + st = {}; + + do_status = false; + + // Drop all messages in RX window + rx_window->clear(); +} + +void rlc_am_nr_rx::reestablish() +{ + stop(); +} + +void rlc_am_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_bytes) +{ + std::lock_guard lock(mutex); + + // Get AMD PDU Header + rlc_am_nr_pdu_header_t header = {}; + uint32_t hdr_len = rlc_am_nr_read_data_pdu_header(payload, nof_bytes, cfg.rx_sn_field_length, &header); + + RlcHexInfo(payload, nof_bytes, "Rx data PDU SN=%d (%d B)", header.sn, nof_bytes); + log_rlc_am_nr_pdu_header_to_string(logger.debug, header, rb_name); + + // Trigger polling if poll bit is set. + // We do this before checking if the PDU is inside the RX window, + // as the RX window may have advanced without the TX having received the ACKs + // This can cause a data stall, whereby the TX keeps retransmiting + // a PDU outside of the Rx window. + // Also, we do this before discarding duplicate SDUs/SDU segments + // Because t-PollRetransmit may transmit a PDU that was already + // received. + if (header.p != 0U) { + RlcInfo("status packet requested through polling bit"); + do_status = true; + } + + // Check whether SDU is within Rx Window + if (!inside_rx_window(header.sn)) { + RlcInfo("SN=%d outside rx window [%d:%d] - discarding", header.sn, st.rx_next, st.rx_next + rx_window_size()); + return; + } + + // Section 5.2.3.2.2, discard duplicate PDUs + if (rx_window->has_sn(header.sn) && (*rx_window)[header.sn].fully_received) { + RlcInfo("discarding duplicate SN=%d", header.sn); + return; + } + + // Section 5.2.3.2.2, discard segments with overlapping bytes + if (rx_window->has_sn(header.sn) && header.si != rlc_nr_si_field_t::full_sdu) { + for (const auto& segm : (*rx_window)[header.sn].segments) { + uint32_t segm_last_byte = segm.header.so + segm.buf->N_bytes - 1; + uint32_t pdu_last_byte = header.so + nof_bytes - hdr_len - 1; + if ((header.so >= segm.header.so && header.so <= segm_last_byte) || + (pdu_last_byte >= segm.header.so && pdu_last_byte <= segm_last_byte)) { + RlcInfo("Got SDU segment with duplicate bytes. Discarding."); + RlcInfo("Discarded SDU segment. SN=%d, SO=%d, last_byte=%d, payload=%d", + header.sn, + header.so, + header.so + (nof_bytes - hdr_len), + (nof_bytes - hdr_len)); + RlcInfo("Overlaping with SDU segment with SN=%d, SO=%d, last_byte=%d, payload=%d", + header.sn, + segm.header.so, + segm_last_byte, + segm.buf->N_bytes); + return; + } + } + } + + // Write to rx window either full SDU or SDU segment + if (header.si == rlc_nr_si_field_t::full_sdu) { + int err = handle_full_data_sdu(header, payload, nof_bytes); + if (err != SRSRAN_SUCCESS) { + return; } } else { - // 18bit SN - *ptr |= (status_pdu.ack_sn >> 14) & 0x0f; // 4 bit ACK_SN - ptr++; - *ptr = status_pdu.ack_sn >> 8; // bit 3 - 10 of SN - ptr++; - *ptr = (status_pdu.ack_sn & 0xff); // remaining 6 bit of SN - ptr++; + int err = handle_segment_data_sdu(header, payload, nof_bytes); + if (err != SRSRAN_SUCCESS) { + return; + } } - pdu->N_bytes = ptr - pdu->msg; + debug_state(); + + // 5.2.3.2.3 Actions when an AMD PDU is placed in the reception buffer + /* + * - if x >= RX_Next_Highest + * - update RX_Next_Highest to x+ 1. + */ + if (rx_mod_base_nr(header.sn) >= rx_mod_base_nr(st.rx_next_highest)) { + st.rx_next_highest = (header.sn + 1) % mod_nr; + } + + /* + * - if all bytes of the RLC SDU with SN = x are received: + */ + if (rx_window->has_sn(header.sn) && (*rx_window)[header.sn].fully_received) { + /* + * - reassemble the RLC SDU from AMD PDU(s) with SN = x, remove RLC headers when doing so and deliver + * the reassembled RLC SDU to upper layer; + */ + write_to_upper_layers(parent->lcid, std::move((*rx_window)[header.sn].buf)); + + /* + * - if x = RX_Highest_Status, + * - update RX_Highest_Status to the SN of the first RLC SDU with SN > current RX_Highest_Status for which not + * all bytes have been received. + */ + if (rx_mod_base_nr(header.sn) == rx_mod_base_nr(st.rx_highest_status)) { + uint32_t sn_upd = 0; + for (sn_upd = (st.rx_highest_status + 1) % mod_nr; rx_mod_base_nr(sn_upd) < rx_mod_base_nr(st.rx_next_highest); + sn_upd = (sn_upd + 1) % mod_nr) { + if (rx_window->has_sn(sn_upd)) { + if (not(*rx_window)[sn_upd].fully_received) { + break; // first SDU not fully received + } + } else { + break; // first SDU not fully received + } + } + // Update to the SN of the first SDU with missing bytes. + // If it not exists, update to the end of the rx_window. + st.rx_highest_status = sn_upd; + } + /* + * - if x = RX_Next: + * - update RX_Next to the SN of the first RLC SDU with SN > current RX_Next for which not all bytes + * have been received. + */ + if (rx_mod_base_nr(header.sn) == rx_mod_base_nr(st.rx_next)) { + uint32_t sn_upd = 0; + // move rx_next forward and remove all fully received SDUs from rx_window + for (sn_upd = (st.rx_next) % mod_nr; rx_mod_base_nr(sn_upd) < rx_mod_base_nr(st.rx_next_highest); + sn_upd = (sn_upd + 1) % mod_nr) { + if (rx_window->has_sn(sn_upd)) { + if (not(*rx_window)[sn_upd].fully_received) { + break; // first SDU not fully received + } + // RX_Next serves as the lower edge of the receiving window + // As such, we remove any SDU from the window if we update this value + rx_window->remove_pdu(sn_upd); + } else { + break; // first SDU not fully received + } + } + // Update to the SN of the first SDU with missing bytes. + // If it not exists, update to the end of the rx_window. + st.rx_next = sn_upd; + } + } + if (reassembly_timer.is_running()) { + // if t-Reassembly is running: + /* + * - if RX_Next_Status_Trigger = RX_Next; or + * - if RX_Next_Status_Trigger = RX_Next + 1 and there is no missing byte segment of the SDU associated with + * SN = RX_Next before the last byte of all received segments of this SDU; or + * - if RX_Next_Status_Trigger falls outside of the receiving window and RX_Next_Status_Trigger is not equal + * to RX_Next + AM_Window_Size: + * - stop and reset t-Reassembly. + */ + bool stop_reassembly_timer = false; + if (st.rx_next_status_trigger == st.rx_next) { + stop_reassembly_timer = true; + } + if (rx_mod_base_nr(st.rx_next_status_trigger) == rx_mod_base_nr(st.rx_next + 1)) { + if (not(*rx_window)[st.rx_next].has_gap) { + stop_reassembly_timer = true; + } + } + if (not inside_rx_window(st.rx_next_status_trigger)) { + stop_reassembly_timer = true; + } + if (stop_reassembly_timer) { + reassembly_timer.stop(); + } + } + + if (not reassembly_timer.is_running()) { + // if t-Reassembly is not running (includes the case t-Reassembly is stopped due to actions above): + /* + * - if RX_Next_Highest> RX_Next +1; or + * - if RX_Next_Highest = RX_Next + 1 and there is at least one missing byte segment of the SDU associated + * with SN = RX_Next before the last byte of all received segments of this SDU: + * - start t-Reassembly; + * - set RX_Next_Status_Trigger to RX_Next_Highest. + */ + bool restart_reassembly_timer = false; + if (rx_mod_base_nr(st.rx_next_highest) > rx_mod_base_nr(st.rx_next + 1)) { + restart_reassembly_timer = true; + } + if (rx_mod_base_nr(st.rx_next_highest) == rx_mod_base_nr(st.rx_next + 1)) { + if (rx_window->has_sn(st.rx_next) && (*rx_window)[st.rx_next].has_gap) { + restart_reassembly_timer = true; + } + } + if (restart_reassembly_timer) { + reassembly_timer.run(); + st.rx_next_status_trigger = st.rx_next_highest; + } + } +} + +/* + * SDU handling helpers + */ +int rlc_am_nr_rx::handle_full_data_sdu(const rlc_am_nr_pdu_header_t& header, const uint8_t* payload, uint32_t nof_bytes) +{ + uint32_t hdr_len = rlc_am_nr_packed_length(header); + // Full SDU received. Add SDU to Rx Window and copy full PDU into SDU buffer. + rlc_amd_rx_sdu_nr_t& rx_sdu = rx_window->add_pdu(header.sn); + rx_sdu.buf = srsran::make_byte_buffer(); + if (rx_sdu.buf == nullptr) { + RlcError("fatal error. Couldn't allocate PDU in %s.", __FUNCTION__); + rx_window->remove_pdu(header.sn); + return SRSRAN_ERROR; + } + rx_sdu.buf->set_timestamp(); + + // check available space for payload + if (nof_bytes > rx_sdu.buf->get_tailroom()) { + RlcError("discarding SN=%d of size %d B (available space %d B)", header.sn, nof_bytes, rx_sdu.buf->get_tailroom()); + rx_window->remove_pdu(header.sn); + return SRSRAN_ERROR; + } + memcpy(rx_sdu.buf->msg, payload + hdr_len, nof_bytes - hdr_len); // Don't copy header + rx_sdu.buf->N_bytes = nof_bytes - hdr_len; + rx_sdu.fully_received = true; + rx_sdu.has_gap = false; return SRSRAN_SUCCESS; } +int rlc_am_nr_rx::handle_segment_data_sdu(const rlc_am_nr_pdu_header_t& header, + const uint8_t* payload, + uint32_t nof_bytes) +{ + if (header.si == rlc_nr_si_field_t::full_sdu) { + RlcError("called %s but the SI implies a full SDU. SN=%d", __FUNCTION__, header.sn); + return SRSRAN_ERROR; + } + + uint32_t hdr_len = rlc_am_nr_packed_length(header); + + // Log SDU segment reception + if (header.si == rlc_nr_si_field_t::first_segment) { // Check whether it's a full SDU + RlcDebug("Initial segment PDU. SN=%d.", header.sn); + } else if (header.si == rlc_nr_si_field_t::neither_first_nor_last_segment) { + RlcDebug("Middle segment PDU. SN=%d.", header.sn); + } else if (header.si == rlc_nr_si_field_t::last_segment) { + RlcDebug("Final segment PDU. SN=%d.", header.sn); + } + + // Add a new SDU to the RX window if necessary + rlc_amd_rx_sdu_nr_t& rx_sdu = rx_window->has_sn(header.sn) ? (*rx_window)[header.sn] : rx_window->add_pdu(header.sn); + + // Create PDU segment info, to be stored later + rlc_amd_rx_pdu_nr pdu_segment = {}; + pdu_segment.header = header; + pdu_segment.buf = srsran::make_byte_buffer(); + if (pdu_segment.buf == nullptr) { + RlcError("fatal error. Couldn't allocate PDU in %s.", __FUNCTION__); + return SRSRAN_ERROR; + } + memcpy(pdu_segment.buf->msg, payload + hdr_len, nof_bytes - hdr_len); // Don't copy header + pdu_segment.buf->N_bytes = nof_bytes - hdr_len; + + // Store SDU segment. Sort by SO and check for duplicate bytes. + insert_received_segment(std::move(pdu_segment), rx_sdu.segments); + + // Check weather all segments have been received + update_segment_inventory(rx_sdu); + if (rx_sdu.fully_received) { + RlcInfo("Fully received segmented SDU. SN=%d.", header.sn); + rx_sdu.buf = srsran::make_byte_buffer(); + if (rx_sdu.buf == nullptr) { + RlcError("fatal error. Couldn't allocate PDU in %s.", __FUNCTION__); + rx_window->remove_pdu(header.sn); + return SRSRAN_ERROR; + } + // Assemble SDU from segments + for (const auto& it : rx_sdu.segments) { + memcpy(&rx_sdu.buf->msg[rx_sdu.buf->N_bytes], it.buf->msg, it.buf->N_bytes); + rx_sdu.buf->N_bytes += it.buf->N_bytes; + } + } + return SRSRAN_SUCCESS; +} + +/* + * Status PDU + */ +uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t max_len) +{ + std::unique_lock lock(mutex, std::try_to_lock); + if (not lock.owns_lock()) { + return SRSRAN_ERROR; + } + + status->reset(); + + /* + * - for the RLC SDUs with SN such that RX_Next <= SN < RX_Highest_Status that has not been completely + * received yet, in increasing SN order of RLC SDUs and increasing byte segment order within RLC SDUs, + * starting with SN = RX_Next up to the point where the resulting STATUS PDU still fits to the total size of RLC + * PDU(s) indicated by lower layer: + */ + RlcDebug("Generating status PDU"); + for (uint32_t i = st.rx_next; rx_mod_base_nr(i) < rx_mod_base_nr(st.rx_highest_status); i = (i + 1) % mod_nr) { + if ((rx_window->has_sn(i) && (*rx_window)[i].fully_received)) { + RlcDebug("SDU SN=%d is fully received", i); + } else { + if (not rx_window->has_sn(i)) { + // No segment received, NACK the whole SDU + RlcDebug("Adding NACK for full SDU. NACK SN=%d", i); + rlc_status_nack_t nack; + nack.nack_sn = i; + nack.has_so = false; + status->push_nack(nack); + } else if (not(*rx_window)[i].fully_received) { + // Some segments were received, but not all. + // NACK non consecutive missing bytes + RlcDebug("Adding NACKs for segmented SDU. NACK SN=%d", i); + uint32_t last_so = 0; + bool last_segment_rx = false; + for (auto segm = (*rx_window)[i].segments.begin(); segm != (*rx_window)[i].segments.end(); segm++) { + if (segm->header.so != last_so) { + // Some bytes were not received + rlc_status_nack_t nack; + nack.nack_sn = i; + nack.has_so = true; + nack.so_start = last_so; + nack.so_end = segm->header.so - 1; // set to last missing byte + status->push_nack(nack); + if (nack.so_start > nack.so_end) { + // Print segment list + for (auto segm_it = (*rx_window)[i].segments.begin(); segm_it != (*rx_window)[i].segments.end(); + segm_it++) { + RlcError("Segment: segm.header.so=%d, segm.buf.N_bytes=%d", segm_it->header.so, segm_it->buf->N_bytes); + } + RlcError("Error: SO_start=%d > SO_end=%d. NACK_SN=%d. SO_start=%d, SO_end=%d, seg.so=%d", + nack.so_start, + nack.so_end, + nack.nack_sn, + nack.so_start, + nack.so_end, + segm->header.so); + srsran_assert(nack.so_start <= nack.so_end, + "Error: SO_start=%d > SO_end=%d. NACK_SN=%d", + nack.so_start, + nack.so_end, + nack.nack_sn); + } else { + RlcDebug("First/middle segment missing. NACK_SN=%d. SO_start=%d, SO_end=%d", + nack.nack_sn, + nack.so_start, + nack.so_end); + } + } + if (segm->header.si == rlc_nr_si_field_t::last_segment) { + last_segment_rx = true; + } + last_so = segm->header.so + segm->buf->N_bytes; + } // Segment loop + if (not last_segment_rx) { + rlc_status_nack_t nack; + nack.nack_sn = i; + nack.has_so = true; + nack.so_start = last_so; + nack.so_end = rlc_status_nack_t::so_end_of_sdu; + status->push_nack(nack); + RlcDebug( + "Final segment missing. NACK_SN=%d. SO_start=%d, SO_end=%d", nack.nack_sn, nack.so_start, nack.so_end); + srsran_assert(nack.so_start <= nack.so_end, "Error: SO_start > SO_end. NACK_SN=%d", nack.nack_sn); + } + } + } + } // NACK loop + + /* + * - set the ACK_SN to the SN of the next not received RLC SDU which is not + * indicated as missing in the resulting STATUS PDU. + */ + status->ack_sn = st.rx_highest_status; + + // trim PDU if necessary + if (status->packed_size > max_len) { + RlcInfo("Trimming status PDU with %d NACKs and packed_size=%d into max_len=%d", + status->nacks.size(), + status->packed_size, + max_len); + log_rlc_am_nr_status_pdu_to_string(logger.debug, "Untrimmed status PDU - %s", status, rb_name); + if (not status->trim(max_len)) { + RlcError("Failed to trim status PDU into provided space: max_len=%d", max_len); + } + } + + if (max_len != UINT32_MAX) { + // UINT32_MAX is used just to query the status PDU length + if (status_prohibit_timer.is_valid() && cfg.t_status_prohibit != 0) { + status_prohibit_timer.run(); + } + do_status = false; + } + + return status->packed_size; +} + +uint32_t rlc_am_nr_rx::get_status_pdu_length() +{ + rlc_am_nr_status_pdu_t tmp_status(cfg.rx_sn_field_length); + get_status_pdu(&tmp_status, UINT32_MAX); + return tmp_status.get_packed_size(); +} + +bool rlc_am_nr_rx::get_do_status() +{ + if (cfg.t_status_prohibit != 0) { + return do_status.load(std::memory_order_relaxed) && not status_prohibit_timer.is_running(); + } else { + return do_status.load(std::memory_order_relaxed); + } +} + +void rlc_am_nr_rx::timer_expired(uint32_t timeout_id) +{ + std::unique_lock lock(mutex); + + // Status Prohibit + if (status_prohibit_timer.is_valid() && status_prohibit_timer.id() == timeout_id) { + RlcDebug("Status prohibit timer expired after %dms", status_prohibit_timer.duration()); + return; + } + + // Reassembly + if (reassembly_timer.is_valid() && reassembly_timer.id() == timeout_id) { + RlcDebug("Reassembly timer expired after %dms", reassembly_timer.duration()); + /* + * 5.2.3.2.4 Actions when t-Reassembly expires: + * - update RX_Highest_Status to the SN of the first RLC SDU with SN >= RX_Next_Status_Trigger for which not + * all bytes have been received; + * - if RX_Next_Highest> RX_Highest_Status +1: or + * - if RX_Next_Highest = RX_Highest_Status + 1 and there is at least one missing byte segment of the SDU + * associated with SN = RX_Highest_Status before the last byte of all received segments of this SDU: + * - start t-Reassembly; + * - set RX_Next_Status_Trigger to RX_Next_Highest. + */ + uint32_t sn_upd = {}; + for (sn_upd = st.rx_next_status_trigger; rx_mod_base_nr(sn_upd) < rx_mod_base_nr(st.rx_next_highest); + sn_upd = (sn_upd + 1) % mod_nr) { + if (not rx_window->has_sn(sn_upd) || (rx_window->has_sn(sn_upd) && not(*rx_window)[sn_upd].fully_received)) { + break; + } + } + st.rx_highest_status = sn_upd; + if (not valid_ack_sn(st.rx_highest_status)) { + RlcError("Rx_Highest_Status not inside RX window"); + debug_state(); + } + srsran_assert(valid_ack_sn(st.rx_highest_status), "Error: rx_highest_status assigned outside rx window"); + + bool restart_reassembly_timer = false; + if (rx_mod_base_nr(st.rx_next_highest) > rx_mod_base_nr(st.rx_highest_status + 1)) { + restart_reassembly_timer = true; + } + if (rx_mod_base_nr(st.rx_next_highest) == rx_mod_base_nr(st.rx_highest_status + 1)) { + if (rx_window->has_sn(st.rx_highest_status) && (*rx_window)[st.rx_highest_status].has_gap) { + restart_reassembly_timer = true; + } + } + if (restart_reassembly_timer) { + reassembly_timer.run(); + st.rx_next_status_trigger = st.rx_next_highest; + } + + /* 5.3.4 Status reporting: + * - The receiving side of an AM RLC entity shall trigger a STATUS report when t-Reassembly expires. + * NOTE 2: The expiry of t-Reassembly triggers both RX_Highest_Status to be updated and a STATUS report to be + * triggered, but the STATUS report shall be triggered after RX_Highest_Status is updated. + */ + do_status = true; + debug_state(); + debug_window(); + return; + } +} + +void rlc_am_nr_rx::write_to_upper_layers(uint32_t lcid, unique_byte_buffer_t sdu) +{ + uint32_t nof_bytes = sdu->N_bytes; + parent->pdcp->write_pdu(lcid, std::move(sdu)); + std::lock_guard lock(parent->metrics_mutex); + parent->metrics.num_rx_sdus++; + parent->metrics.num_rx_sdu_bytes += nof_bytes; +} + +/* + * Segment Helpers + */ +void rlc_am_nr_rx::insert_received_segment(rlc_amd_rx_pdu_nr segment, + std::set& segment_list) const +{ + segment_list.insert(std::move(segment)); +} + +void rlc_am_nr_rx::update_segment_inventory(rlc_amd_rx_sdu_nr_t& rx_sdu) const +{ + if (rx_sdu.segments.empty()) { + rx_sdu.fully_received = false; + rx_sdu.has_gap = false; + return; + } + + // Check for gaps and if all segments have been received + uint32_t next_byte = 0; + for (const auto& it : rx_sdu.segments) { + if (it.header.so != next_byte) { + // Found gap: set flags and return + rx_sdu.has_gap = true; + rx_sdu.fully_received = false; + return; + } + if (it.header.si == rlc_nr_si_field_t::last_segment) { + // Reached last segment without any gaps: set flags and return + rx_sdu.has_gap = false; + rx_sdu.fully_received = true; + return; + } + next_byte += it.buf->N_bytes; + } + // No gaps, but last segment not yet received + rx_sdu.has_gap = false; + rx_sdu.fully_received = false; +} + +/* + * Window Helpers + */ +uint32_t rlc_am_nr_rx::rx_mod_base_nr(uint32_t sn) const +{ + return (sn - st.rx_next) % mod_nr; +} + +uint32_t rlc_am_nr_rx::rx_window_size() const +{ + return am_window_size(cfg.rx_sn_field_length); +} + +bool rlc_am_nr_rx::inside_rx_window(uint32_t sn) const +{ + // RX_Next <= SN < RX_Next + AM_Window_Size + return rx_mod_base_nr(sn) < rx_window_size(); +} + +/* + * This function is used to check if the Rx_Highest_Status is + * valid when t-Reasseambly expires. + * + * ACK_SN may be equal to RX_NEXT + AM_Window_Size if the PDU + * with SN=RX_NEXT+AM_Window_Size has been received by the RX. + * An ACK_SN == Rx_Next should not update Rx_Highest_Status, + * it should be updated when Rx_Next is updated. + */ +bool rlc_am_nr_rx::valid_ack_sn(uint32_t sn) const +{ + // RX_Next < SN <= RX_Next + AM_Window_Size + return (0 < rx_mod_base_nr(sn)) && (rx_mod_base_nr(sn) <= rx_window_size()); +} + +/* + * Debug Helpers + */ +void rlc_am_nr_rx::debug_state() const +{ + RlcDebug("RX entity state: Rx_Next=%d, Rx_Next_Status_Trigger=%d, Rx_Highest_Status=%d, Rx_Next_Highest=%d", + st.rx_next, + st.rx_next_status_trigger, + st.rx_highest_status, + st.rx_next_highest); +} + +void rlc_am_nr_rx::debug_window() const +{ + RlcDebug( + "RX window state: Rx_Next=%d, Rx_Next_Highest=%d, SDUs %d", st.rx_next, st.rx_next_highest, rx_window->size()); +} + +/* + * Metrics + */ +uint32_t rlc_am_nr_rx::get_sdu_rx_latency_ms() +{ + return 0; +} + +uint32_t rlc_am_nr_rx::get_rx_buffered_bytes() +{ + return 0; +} } // namespace srsran diff --git a/lib/src/rlc/rlc_am_nr_packing.cc b/lib/src/rlc/rlc_am_nr_packing.cc new file mode 100644 index 0000000000..6a9950f74a --- /dev/null +++ b/lib/src/rlc/rlc_am_nr_packing.cc @@ -0,0 +1,627 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/rlc/rlc_am_nr_packing.h" +#include + +namespace srsran { + +/**************************************************************************** + * Container implementation for pack/unpack functions + ***************************************************************************/ + +rlc_am_nr_status_pdu_t::rlc_am_nr_status_pdu_t(rlc_am_nr_sn_size_t sn_size) : + sn_size(sn_size), mod_nr(cardinality(sn_size)) +{ + nacks_.reserve(RLC_AM_NR_TYP_NACKS); +} + +void rlc_am_nr_status_pdu_t::reset() +{ + cpt = rlc_am_nr_control_pdu_type_t::status_pdu; + ack_sn = INVALID_RLC_SN; + nacks_.clear(); + packed_size_ = rlc_am_nr_status_pdu_sizeof_header_ack_sn; +} + +bool rlc_am_nr_status_pdu_t::is_continuous_sequence(const rlc_status_nack_t& left, const rlc_status_nack_t& right) const +{ + // SN must be continuous + if (right.nack_sn != ((left.has_nack_range ? left.nack_sn + left.nack_range : (left.nack_sn + 1)) % mod_nr)) { + return false; + } + + // Segments on left side (if present) must reach the end of sdu + if (left.has_so && left.so_end != rlc_status_nack_t::so_end_of_sdu) { + return false; + } + + // Segments on right side (if present) must start from the beginning + if (right.has_so && right.so_start != 0) { + return false; + } + + return true; +} + +void rlc_am_nr_status_pdu_t::push_nack(const rlc_status_nack_t& nack) +{ + if (nacks_.size() == 0) { + nacks_.push_back(nack); + packed_size_ += nack_size(nack); + return; + } + + rlc_status_nack_t& prev = nacks_.back(); + if (is_continuous_sequence(prev, nack) == false) { + nacks_.push_back(nack); + packed_size_ += nack_size(nack); + return; + } + + // expand previous NACK + // subtract size of previous NACK (add updated size later) + packed_size_ -= nack_size(prev); + + // enable and update NACK range + if (nack.has_nack_range == true) { + if (prev.has_nack_range == true) { + // [NACK range][NACK range] + prev.nack_range += nack.nack_range; + } else { + // [NACK SDU][NACK range] + prev.nack_range = nack.nack_range + 1; + prev.has_nack_range = true; + } + } else { + if (prev.has_nack_range == true) { + // [NACK range][NACK SDU] + prev.nack_range++; + } else { + // [NACK SDU][NACK SDU] + prev.nack_range = 2; + prev.has_nack_range = true; + } + } + + // enable and update segment offsets (if required) + if (nack.has_so == true) { + if (prev.has_so == false) { + // [NACK SDU][NACK segm] + prev.has_so = true; + prev.so_start = 0; + } + // [NACK SDU][NACK segm] or [NACK segm][NACK segm] + prev.so_end = nack.so_end; + } else { + if (prev.has_so == true) { + // [NACK segm][NACK SDU] + prev.so_end = rlc_status_nack_t::so_end_of_sdu; + } + // [NACK segm][NACK SDU] or [NACK SDU][NACK SDU] + } + + // add updated size + packed_size_ += nack_size(prev); +} + +bool rlc_am_nr_status_pdu_t::trim(uint32_t max_packed_size) +{ + if (max_packed_size >= packed_size_) { + // no trimming required + return true; + } + if (max_packed_size < rlc_am_nr_status_pdu_sizeof_header_ack_sn) { + // too little space for smallest possible status PDU (only header + ACK). + return false; + } + + // remove NACKs (starting from the back) until it fits into given space + // note: when removing a NACK for a segment, we have to remove all other NACKs with the same SN as well, + // see TS 38.322 Sec. 5.3.4: + // "set the ACK_SN to the SN of the next not received RLC SDU + // which is not indicated as missing in the resulting STATUS PDU." + while (nacks_.size() > 0 && (max_packed_size < packed_size_ || nacks_.back().nack_sn == ack_sn)) { + packed_size_ -= nack_size(nacks_.back()); + ack_sn = nacks_.back().nack_sn; + nacks_.pop_back(); + } + return true; +} + +void rlc_am_nr_status_pdu_t::refresh_packed_size() +{ + packed_size_ = rlc_am_nr_status_pdu_sizeof_header_ack_sn; + for (auto nack : nacks_) { + packed_size_ += nack_size(nack); + } +} + +uint32_t rlc_am_nr_status_pdu_t::nack_size(const rlc_status_nack_t& nack) const +{ + uint32_t result = sn_size == rlc_am_nr_sn_size_t::size12bits ? rlc_am_nr_status_pdu_sizeof_nack_sn_ext_12bit_sn + : rlc_am_nr_status_pdu_sizeof_nack_sn_ext_18bit_sn; + if (nack.has_so) { + result += rlc_am_nr_status_pdu_sizeof_nack_so; + } + if (nack.has_nack_range) { + result += rlc_am_nr_status_pdu_sizeof_nack_range; + } + return result; +} + +/**************************************************************************** + * Header pack/unpack helper functions + * Ref: 3GPP TS 38.322 v15.3.0 Section 6.2.2.4 + ***************************************************************************/ + +uint32_t rlc_am_nr_read_data_pdu_header(const byte_buffer_t* pdu, + const rlc_am_nr_sn_size_t sn_size, + rlc_am_nr_pdu_header_t* header) +{ + return rlc_am_nr_read_data_pdu_header(pdu->msg, pdu->N_bytes, sn_size, header); +} + +uint32_t rlc_am_nr_read_data_pdu_header(const uint8_t* payload, + const uint32_t nof_bytes, + const rlc_am_nr_sn_size_t sn_size, + rlc_am_nr_pdu_header_t* header) +{ + uint8_t* ptr = const_cast(payload); + + header->sn_size = sn_size; + + // Fixed part + header->dc = (rlc_dc_field_t)((*ptr >> 7) & 0x01); // 1 bit D/C field + header->p = (*ptr >> 6) & 0x01; // 1 bit P flag + header->si = (rlc_nr_si_field_t)((*ptr >> 4) & 0x03); // 2 bits SI + + if (sn_size == rlc_am_nr_sn_size_t::size12bits) { + header->sn = (*ptr & 0x0F) << 8; // first 4 bits SN + ptr++; + + header->sn |= (*ptr & 0xFF); // last 8 bits SN + ptr++; + } else if (sn_size == rlc_am_nr_sn_size_t::size18bits) { + // sanity check + if ((*ptr & 0x0c) != 0) { + fprintf(stderr, "Malformed PDU, reserved bits are set.\n"); + return 0; + } + header->sn = (*ptr & 0x03) << 16; // first 4 bits SN + ptr++; + header->sn |= (*ptr & 0xFF) << 8; // bit 2-10 of SN + ptr++; + header->sn |= (*ptr & 0xFF); // last 8 bits SN + ptr++; + } else { + fprintf(stderr, "Unsupported SN length\n"); + return 0; + } + + // Read optional part + if (header->si == rlc_nr_si_field_t::last_segment || + header->si == rlc_nr_si_field_t::neither_first_nor_last_segment) { + // read SO + header->so = (*ptr & 0xFF) << 8; + ptr++; + header->so |= (*ptr & 0xFF); + ptr++; + } + + // return consumed bytes + return (ptr - payload); +} + +uint32_t rlc_am_nr_packed_length(const rlc_am_nr_pdu_header_t& header) +{ + uint32_t len = 0; + if (header.si == rlc_nr_si_field_t::full_sdu || header.si == rlc_nr_si_field_t::first_segment) { + len = 2; + if (header.sn_size == rlc_am_nr_sn_size_t::size18bits) { + len++; + } + } else { + // PDU contains SO + len = 4; + if (header.sn_size == rlc_am_nr_sn_size_t::size18bits) { + len++; + } + } + return len; +} + +uint32_t rlc_am_nr_write_data_pdu_header(const rlc_am_nr_pdu_header_t& header, uint8_t* payload) +{ + uint8_t* ptr = payload; + + // fixed header part + *ptr = (header.dc & 0x01) << 7; ///< 1 bit D/C field + *ptr |= (header.p & 0x01) << 6; ///< 1 bit P flag + *ptr |= (header.si & 0x03) << 4; ///< 2 bits SI + + if (header.sn_size == rlc_am_nr_sn_size_t::size12bits) { + // write first 4 bit of SN + *ptr |= (header.sn >> 8) & 0x0f; // 4 bit SN + ptr++; + *ptr = header.sn & 0xff; // remaining 8 bit of SN + ptr++; + } else { + // 18bit SN + *ptr |= (header.sn >> 16) & 0x3; // 2 bit SN + ptr++; + *ptr = header.sn >> 8; // bit 3 - 10 of SN + ptr++; + *ptr = (header.sn & 0xff); // remaining 8 bit of SN + ptr++; + } + + if (header.so) { + // write SO + *ptr = header.so >> 8; // first part of SO + ptr++; + *ptr = (header.so & 0xff); // second part of SO + ptr++; + } + return rlc_am_nr_packed_length(header); +} + +uint32_t rlc_am_nr_write_data_pdu_header(const rlc_am_nr_pdu_header_t& header, byte_buffer_t* pdu) +{ + // Make room for the header + uint32_t len = rlc_am_nr_packed_length(header); + pdu->msg -= len; + pdu->N_bytes += len; + rlc_am_nr_write_data_pdu_header(header, pdu->msg); + return len; +} + +/**************************************************************************** + * Status PDU pack/unpack helper functions + * Ref: 3GPP TS 38.322 v16.2.0 Section 6.2.2.5 + ***************************************************************************/ + +uint32_t +rlc_am_nr_read_status_pdu(const byte_buffer_t* pdu, const rlc_am_nr_sn_size_t sn_size, rlc_am_nr_status_pdu_t* status) +{ + return rlc_am_nr_read_status_pdu(pdu->msg, pdu->N_bytes, sn_size, status); +} + +uint32_t rlc_am_nr_read_status_pdu(const uint8_t* payload, + const uint32_t nof_bytes, + const rlc_am_nr_sn_size_t sn_size, + rlc_am_nr_status_pdu_t* status) +{ + if (sn_size == rlc_am_nr_sn_size_t::size12bits) { + return rlc_am_nr_read_status_pdu_12bit_sn(payload, nof_bytes, status); + } else { // 18bit SN + return rlc_am_nr_read_status_pdu_18bit_sn(payload, nof_bytes, status); + } +} + +uint32_t +rlc_am_nr_read_status_pdu_12bit_sn(const uint8_t* payload, const uint32_t nof_bytes, rlc_am_nr_status_pdu_t* status) +{ + uint8_t* ptr = const_cast(payload); + status->reset(); + + // fixed part + status->cpt = (rlc_am_nr_control_pdu_type_t)((*ptr >> 4) & 0x07); // 3 bits CPT + + // sanity check + if (status->cpt != rlc_am_nr_control_pdu_type_t::status_pdu) { + fprintf(stderr, "Malformed PDU, reserved bits are set.\n"); + return 0; + } + + status->ack_sn = (*ptr & 0x0F) << 8; // first 4 bits SN + ptr++; + + status->ack_sn |= (*ptr & 0xFF); // last 8 bits SN + ptr++; + + // read E1 flag + uint8_t e1 = *ptr & 0x80; + + // sanity check for reserved bits + if ((*ptr & 0x7f) != 0) { + fprintf(stderr, "Malformed PDU, reserved bits are set.\n"); + return 0; + } + + // all good, continue with next byte depending on E1 + ptr++; + + while (e1 != 0) { + // check buffer headroom + if (uint32_t(ptr - payload) >= nof_bytes) { + fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n"); + return 0; + } + + // E1 flag set, read a NACK_SN + rlc_status_nack_t nack = {}; + nack.nack_sn = (*ptr & 0xff) << 4; + ptr++; + + e1 = *ptr & 0x08; // 1 = further NACKs follow + uint8_t e2 = *ptr & 0x04; // 1 = set of {so_start, so_end} follows + uint8_t e3 = *ptr & 0x02; // 1 = NACK range follows (i.e. NACK across multiple SNs) + + // sanity check for reserved bits + if ((*ptr & 0x01) != 0) { + fprintf(stderr, "Malformed PDU, reserved bits are set.\n"); + return 0; + } + nack.nack_sn |= (*ptr & 0xF0) >> 4; + + ptr++; + if (e2 != 0) { + nack.has_so = true; + nack.so_start = (*ptr) << 8; + ptr++; + nack.so_start |= (*ptr); + ptr++; + nack.so_end = (*ptr) << 8; + ptr++; + nack.so_end |= (*ptr); + ptr++; + } + if (e3 != 0) { + nack.has_nack_range = true; + nack.nack_range = (*ptr); + ptr++; + } + status->push_nack(nack); + } + + return SRSRAN_SUCCESS; +} + +uint32_t +rlc_am_nr_read_status_pdu_18bit_sn(const uint8_t* payload, const uint32_t nof_bytes, rlc_am_nr_status_pdu_t* status) +{ + uint8_t* ptr = const_cast(payload); + status->reset(); + + // fixed part + status->cpt = (rlc_am_nr_control_pdu_type_t)((*ptr >> 4) & 0x07); // 3 bits CPT + + // sanity check + if (status->cpt != rlc_am_nr_control_pdu_type_t::status_pdu) { + fprintf(stderr, "Malformed PDU, reserved bits are set.\n"); + return 0; + } + + status->ack_sn = (*ptr & 0x0F) << 14; // upper 4 bits of SN + ptr++; + + status->ack_sn |= (*ptr & 0xFF) << 6; // center 8 bits of SN + ptr++; + + status->ack_sn |= (*ptr & 0xFC) >> 2; // lower 6 bits of SN + + // read E1 flag + uint8_t e1 = *ptr & 0x02; + + // sanity check for reserved bits + if ((*ptr & 0x01) != 0) { + fprintf(stderr, "Malformed PDU, reserved bit is set.\n"); + return 0; + } + + // all good, continue with next byte depending on E1 + ptr++; + + while (e1 != 0) { + // check buffer headroom + if (uint32_t(ptr - payload) >= nof_bytes) { + fprintf(stderr, "Malformed PDU, trying to read more bytes than it is available\n"); + return 0; + } + + // E1 flag set, read a NACK_SN + rlc_status_nack_t nack = {}; + + nack.nack_sn = (*ptr & 0xFF) << 10; // upper 8 bits of SN + ptr++; + nack.nack_sn |= (*ptr & 0xFF) << 2; // center 8 bits of SN + ptr++; + nack.nack_sn |= (*ptr & 0xC0) >> 6; // lower 2 bits of SN + + e1 = *ptr & 0x20; // 1 = further NACKs follow + uint8_t e2 = *ptr & 0x10; // 1 = set of {so_start, so_end} follows + uint8_t e3 = *ptr & 0x08; // 1 = NACK range follows (i.e. NACK across multiple SNs) + + // sanity check for reserved bits + if ((*ptr & 0x07) != 0) { + fprintf(stderr, "Malformed PDU, reserved bits are set.\n"); + return 0; + } + + ptr++; + if (e2 != 0) { + nack.has_so = true; + nack.so_start = (*ptr) << 8; + ptr++; + nack.so_start |= (*ptr); + ptr++; + nack.so_end = (*ptr) << 8; + ptr++; + nack.so_end |= (*ptr); + ptr++; + } + if (e3 != 0) { + nack.has_nack_range = true; + nack.nack_range = (*ptr); + ptr++; + } + status->push_nack(nack); + } + + return SRSRAN_SUCCESS; +} + +/** + * Write a RLC AM NR status PDU to a PDU buffer and eets the length of the generate PDU accordingly + * @param status_pdu The status PDU + * @param pdu A pointer to a unique bytebuffer + * @return SRSRAN_SUCCESS if PDU was written, SRSRAN_ERROR otherwise + */ +int32_t rlc_am_nr_write_status_pdu(const rlc_am_nr_status_pdu_t& status_pdu, + const rlc_am_nr_sn_size_t sn_size, + byte_buffer_t* pdu) +{ + if (sn_size == rlc_am_nr_sn_size_t::size12bits) { + return rlc_am_nr_write_status_pdu_12bit_sn(status_pdu, pdu); + } else { // 18bit SN + return rlc_am_nr_write_status_pdu_18bit_sn(status_pdu, pdu); + } +} + +int32_t rlc_am_nr_write_status_pdu_12bit_sn(const rlc_am_nr_status_pdu_t& status_pdu, byte_buffer_t* pdu) +{ + uint8_t* ptr = pdu->msg; + + // fixed header part + *ptr = 0; ///< 1 bit D/C field and 3bit CPT are all zero + + // write first 4 bit of ACK_SN + *ptr |= (status_pdu.ack_sn >> 8) & 0x0f; // 4 bit ACK_SN + ptr++; + *ptr = status_pdu.ack_sn & 0xff; // remaining 8 bit of SN + ptr++; + + // write E1 flag in octet 3 + if (status_pdu.nacks.size() > 0) { + *ptr = 0x80; + } else { + *ptr = 0x00; + } + ptr++; + + if (status_pdu.nacks.size() > 0) { + for (uint32_t i = 0; i < status_pdu.nacks.size(); i++) { + // write first 8 bit of NACK_SN + *ptr = (status_pdu.nacks[i].nack_sn >> 4) & 0xff; + ptr++; + + // write remaining 4 bits of NACK_SN + *ptr = (status_pdu.nacks[i].nack_sn & 0x0f) << 4; + // Set E1 if necessary + if (i < (uint32_t)(status_pdu.nacks.size() - 1)) { + *ptr |= 0x08; + } + + if (status_pdu.nacks[i].has_so) { + // Set E2 + *ptr |= 0x04; + } + + if (status_pdu.nacks[i].has_nack_range) { + // Set E3 + *ptr |= 0x02; + } + + ptr++; + if (status_pdu.nacks[i].has_so) { + (*ptr) = status_pdu.nacks[i].so_start >> 8; + ptr++; + (*ptr) = status_pdu.nacks[i].so_start; + ptr++; + (*ptr) = status_pdu.nacks[i].so_end >> 8; + ptr++; + (*ptr) = status_pdu.nacks[i].so_end; + ptr++; + } + if (status_pdu.nacks[i].has_nack_range) { + (*ptr) = status_pdu.nacks[i].nack_range; + ptr++; + } + } + } + + pdu->N_bytes = ptr - pdu->msg; + + return SRSRAN_SUCCESS; +} + +int32_t rlc_am_nr_write_status_pdu_18bit_sn(const rlc_am_nr_status_pdu_t& status_pdu, byte_buffer_t* pdu) +{ + uint8_t* ptr = pdu->msg; + + // fixed header part + *ptr = 0; ///< 1 bit D/C field and 3bit CPT are all zero + + *ptr |= (status_pdu.ack_sn >> 14) & 0x0F; // upper 4 bits of SN + ptr++; + *ptr = (status_pdu.ack_sn >> 6) & 0xFF; // center 8 bits of SN + ptr++; + *ptr = (status_pdu.ack_sn << 2) & 0xFC; // lower 6 bits of SN + + // set E1 flag if necessary + if (status_pdu.nacks.size() > 0) { + *ptr |= 0x02; + } + ptr++; + + if (status_pdu.nacks.size() > 0) { + for (uint32_t i = 0; i < status_pdu.nacks.size(); i++) { + *ptr = (status_pdu.nacks[i].nack_sn >> 10) & 0xFF; // upper 8 bits of SN + ptr++; + *ptr = (status_pdu.nacks[i].nack_sn >> 2) & 0xFF; // center 8 bits of SN + ptr++; + *ptr = (status_pdu.nacks[i].nack_sn << 6) & 0xC0; // lower 2 bits of SN + + if (i < (uint32_t)(status_pdu.nacks.size() - 1)) { + *ptr |= 0x20; // Set E1 + } + if (status_pdu.nacks[i].has_so) { + *ptr |= 0x10; // Set E2 + } + if (status_pdu.nacks[i].has_nack_range) { + *ptr |= 0x08; // Set E3 + } + + ptr++; + if (status_pdu.nacks[i].has_so) { + (*ptr) = status_pdu.nacks[i].so_start >> 8; + ptr++; + (*ptr) = status_pdu.nacks[i].so_start; + ptr++; + (*ptr) = status_pdu.nacks[i].so_end >> 8; + ptr++; + (*ptr) = status_pdu.nacks[i].so_end; + ptr++; + } + if (status_pdu.nacks[i].has_nack_range) { + (*ptr) = status_pdu.nacks[i].nack_range; + ptr++; + } + } + } + + pdu->N_bytes = ptr - pdu->msg; + + return SRSRAN_SUCCESS; +} + +} // namespace srsran diff --git a/lib/src/rlc/rlc_tm.cc b/lib/src/rlc/rlc_tm.cc index 219ca36b1f..9b820a81f9 100644 --- a/lib/src/rlc/rlc_tm.cc +++ b/lib/src/rlc/rlc_tm.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -30,9 +30,10 @@ rlc_tm::rlc_tm(srslog::basic_logger& logger, uint32_t lcid_, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_) : - logger(logger), pdcp(pdcp_), rrc(rrc_), lcid(lcid_) + rlc_common(logger), pdcp(pdcp_), rrc(rrc_), lcid(lcid_) { - pool = byte_buffer_pool::get_instance(); + pool = byte_buffer_pool::get_instance(); + rb_name = "SRB0"; } // Warning: must call stop() to properly deallocate all buffers @@ -43,7 +44,7 @@ rlc_tm::~rlc_tm() bool rlc_tm::configure(const rlc_config_t& cnfg) { - logger.error("Attempted to configure TM RLC entity"); + RlcError("Attempted to configure TM RLC entity"); return true; } @@ -73,7 +74,7 @@ rlc_mode_t rlc_tm::get_mode() return rlc_mode_t::tm; } -uint32_t rlc_tm::get_bearer() +uint32_t rlc_tm::get_lcid() { return lcid; } @@ -89,23 +90,17 @@ void rlc_tm::write_sdu(unique_byte_buffer_t sdu) uint32_t nof_bytes = sdu->N_bytes; srsran::error_type ret = ul_queue.try_write(std::move(sdu)); if (ret) { - logger.info(msg_ptr, - nof_bytes, - "%s Tx SDU, queue size=%d, bytes=%d", - rrc->get_rb_name(lcid), - ul_queue.size(), - ul_queue.size_bytes()); + RlcHexInfo(msg_ptr, nof_bytes, "Tx SDU, queue size=%d, bytes=%d", ul_queue.size(), ul_queue.size_bytes()); } else { - logger.warning(ret.error()->msg, - ret.error()->N_bytes, - "[Dropped SDU] %s Tx SDU, queue size=%d, bytes=%d", - rrc->get_rb_name(lcid), - ul_queue.size(), - ul_queue.size_bytes()); + RlcHexWarning(ret.error()->msg, + ret.error()->N_bytes, + "[Dropped SDU] Tx SDU, queue size=%d, bytes=%d", + ul_queue.size(), + ul_queue.size_bytes()); } } else { - logger.warning("NULL SDU pointer in write_sdu()"); + RlcWarning("NULL SDU pointer in write_sdu()"); } } @@ -114,7 +109,7 @@ void rlc_tm::discard_sdu(uint32_t discard_sn) if (!tx_enabled) { return; } - logger.warning("SDU discard not implemented on RLC TM"); + RlcWarning("SDU discard not implemented on RLC TM"); } bool rlc_tm::sdu_queue_is_full() @@ -162,35 +157,31 @@ uint32_t rlc_tm::read_pdu(uint8_t* payload, uint32_t nof_bytes) { uint32_t pdu_size = ul_queue.size_tail_bytes(); if (pdu_size > nof_bytes) { - logger.info("%s Tx PDU size larger than MAC opportunity (%d > %d)", rrc->get_rb_name(lcid), pdu_size, nof_bytes); + RlcInfo("Tx PDU size larger than MAC opportunity (%d > %d)", pdu_size, nof_bytes); return 0; } unique_byte_buffer_t buf; if (ul_queue.try_read(&buf)) { pdu_size = buf->N_bytes; memcpy(payload, buf->msg, buf->N_bytes); - logger.debug("%s Complete SDU scheduled for tx. Stack latency: %" PRIu64 " us", - rrc->get_rb_name(lcid), - (uint64_t)buf->get_latency_us().count()); - logger.info(payload, - pdu_size, - "%s Tx %s PDU, queue size=%d, bytes=%d", - rrc->get_rb_name(lcid), - srsran::to_string(rlc_mode_t::tm), - ul_queue.size(), - ul_queue.size_bytes()); + RlcDebug("Complete SDU scheduled for tx. Stack latency: %" PRIu64 " us", (uint64_t)buf->get_latency_us().count()); + RlcHexInfo(payload, + pdu_size, + "Tx %s PDU, queue size=%d, bytes=%d", + srsran::to_string(rlc_mode_t::tm), + ul_queue.size(), + ul_queue.size_bytes()); std::lock_guard lock(metrics_mutex); metrics.num_tx_pdu_bytes += pdu_size; return pdu_size; - } else { - logger.warning("Queue empty while trying to read"); - if (ul_queue.size_bytes() > 0) { - logger.warning("Corrupted queue: empty but size_bytes > 0. Resetting queue"); - ul_queue.reset(); - } - return 0; } + + if (ul_queue.size_bytes() > 0) { + RlcWarning("Corrupted queue: empty but size_bytes > 0. Resetting queue"); + ul_queue.reset(); + } + return 0; } void rlc_tm::write_pdu(uint8_t* payload, uint32_t nof_bytes) @@ -211,7 +202,7 @@ void rlc_tm::write_pdu(uint8_t* payload, uint32_t nof_bytes) pdcp->write_pdu(lcid, std::move(buf)); } } else { - logger.error("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu()."); + RlcError("Fatal Error: Couldn't allocate buffer in rlc_tm::write_pdu()."); } } diff --git a/lib/src/rlc/rlc_um_base.cc b/lib/src/rlc/rlc_um_base.cc index faaf08ab34..1706f730d2 100644 --- a/lib/src/rlc/rlc_um_base.cc +++ b/lib/src/rlc/rlc_um_base.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -30,7 +30,7 @@ rlc_um_base::rlc_um_base(srslog::basic_logger& logger, srsue::pdcp_interface_rlc* pdcp_, srsue::rrc_interface_rlc* rrc_, srsran::timer_handler* timers_) : - logger(logger), lcid(lcid_), pdcp(pdcp_), rrc(rrc_), timers(timers_), pool(byte_buffer_pool::get_instance()) + rlc_common(logger), lcid(lcid_), pdcp(pdcp_), rrc(rrc_), timers(timers_), pool(byte_buffer_pool::get_instance()) {} rlc_um_base::~rlc_um_base() {} @@ -51,7 +51,7 @@ rlc_mode_t rlc_um_base::get_mode() return rlc_mode_t::um; } -uint32_t rlc_um_base::get_bearer() +uint32_t rlc_um_base::get_lcid() { return lcid; } @@ -90,7 +90,7 @@ void rlc_um_base::empty_queue() void rlc_um_base::write_sdu(unique_byte_buffer_t sdu) { if (not tx_enabled || not tx) { - logger.debug("%s is currently deactivated. Dropping SDU (%d B)", rb_name.c_str(), sdu->N_bytes); + RlcDebug("RB is currently deactivated. Dropping SDU (%d B)", sdu->N_bytes); std::lock_guard lock(metrics_mutex); metrics.num_lost_sdus++; return; @@ -110,7 +110,7 @@ void rlc_um_base::write_sdu(unique_byte_buffer_t sdu) void rlc_um_base::discard_sdu(uint32_t discard_sn) { if (not tx_enabled || not tx) { - logger.debug("%s is currently deactivated. Ignoring SDU discard (SN=%u)", rb_name.c_str(), discard_sn); + RlcDebug("RB is currently deactivated. Ignoring SDU discard (SN=%u)", discard_sn); return; } tx->discard_sdu(discard_sn); @@ -275,15 +275,10 @@ void rlc_um_base::rlc_um_base_tx::set_bsr_callback(bsr_callback_t callback) void rlc_um_base::rlc_um_base_tx::write_sdu(unique_byte_buffer_t sdu) { if (sdu) { - logger.info(sdu->msg, - sdu->N_bytes, - "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", - rb_name.c_str(), - sdu->N_bytes, - tx_sdu_queue.size()); + RlcHexInfo(sdu->msg, sdu->N_bytes, "Tx SDU (%d B, tx_sdu_queue_len=%d)", sdu->N_bytes, tx_sdu_queue.size()); tx_sdu_queue.write(std::move(sdu)); } else { - logger.warning("NULL SDU pointer in write_sdu()"); + RlcWarning("NULL SDU pointer in write_sdu()"); } } @@ -294,26 +289,36 @@ int rlc_um_base::rlc_um_base_tx::try_write_sdu(unique_byte_buffer_t sdu) uint32_t nof_bytes = sdu->N_bytes; srsran::error_type ret = tx_sdu_queue.try_write(std::move(sdu)); if (ret) { - logger.info( - msg_ptr, nof_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rb_name.c_str(), nof_bytes, tx_sdu_queue.size()); + RlcHexInfo(msg_ptr, nof_bytes, "Tx SDU (%d B, tx_sdu_queue_len=%d)", nof_bytes, tx_sdu_queue.size()); return SRSRAN_SUCCESS; } else { - logger.warning(ret.error()->msg, - ret.error()->N_bytes, - "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", - rb_name.c_str(), - ret.error()->N_bytes, - tx_sdu_queue.size()); + RlcHexWarning(ret.error()->msg, + ret.error()->N_bytes, + "[Dropped SDU] %s Tx SDU (%d B, tx_sdu_queue_len=%d)", + rb_name.c_str(), + ret.error()->N_bytes, + tx_sdu_queue.size()); } } else { - logger.warning("NULL SDU pointer in write_sdu()"); + RlcWarning("NULL SDU pointer in write_sdu()"); } return SRSRAN_ERROR; } void rlc_um_base::rlc_um_base_tx::discard_sdu(uint32_t discard_sn) { - logger.warning("RLC UM: Discard SDU not implemented yet."); + std::lock_guard lock(mutex); + + bool discarded = tx_sdu_queue.apply_first([&discard_sn, this](unique_byte_buffer_t& sdu) { + if (sdu != nullptr && sdu->md.pdcp_sn == discard_sn) { + tx_sdu_queue.queue.pop_func(sdu); + sdu = nullptr; + } + return false; + }); + + // Discard fails when the PDCP PDU is already in Tx window. + RlcInfo("%s PDU with PDCP_SN=%d", discarded ? "Discarding" : "Couldn't discard", discard_sn); } bool rlc_um_base::rlc_um_base_tx::sdu_queue_is_full() @@ -326,16 +331,16 @@ uint32_t rlc_um_base::rlc_um_base_tx::build_data_pdu(uint8_t* payload, uint32_t unique_byte_buffer_t pdu; { std::lock_guard lock(mutex); - logger.debug("MAC opportunity - %d bytes", nof_bytes); + RlcDebug("MAC opportunity - %d bytes", nof_bytes); if (tx_sdu == nullptr && tx_sdu_queue.is_empty()) { - logger.info("No data available to be sent"); + RlcInfo("No data available to be sent"); return 0; } pdu = make_byte_buffer(); if (!pdu || pdu->N_bytes != 0) { - logger.error("Failed to allocate PDU buffer"); + RlcError("Failed to allocate PDU buffer"); return 0; } } diff --git a/lib/src/rlc/rlc_um_lte.cc b/lib/src/rlc/rlc_um_lte.cc index cb0edf250f..958b4f50e6 100644 --- a/lib/src/rlc/rlc_um_lte.cc +++ b/lib/src/rlc/rlc_um_lte.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -59,12 +59,11 @@ bool rlc_um_lte::configure(const rlc_config_t& cnfg_) return false; } - logger.info("%s configured in %s: t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits", - rb_name.c_str(), - srsran::to_string(cnfg_.rlc_mode), - cfg.um.t_reordering, - srsran::to_number(cfg.um.rx_sn_field_length), - srsran::to_number(cfg.um.tx_sn_field_length)); + RlcInfo("configured in %s - t_reordering=%d ms, rx_sn_field_length=%u bits, tx_sn_field_length=%u bits", + srsran::to_string(cnfg_.rlc_mode), + cfg.um.t_reordering, + srsran::to_number(cfg.um.rx_sn_field_length), + srsran::to_number(cfg.um.tx_sn_field_length)); rx_enabled = true; tx_enabled = true; @@ -111,7 +110,7 @@ bool rlc_um_lte::rlc_um_lte_tx::configure(const rlc_config_t& cnfg_, std::string cfg = cnfg_; if (cfg.um.tx_mod == 0) { - logger.error("Error configuring %s RLC UM: tx_mod==0", rb_name.c_str()); + RlcError("Error configuring RLC UM - tx_mod==0"); return false; } @@ -125,7 +124,7 @@ bool rlc_um_lte::rlc_um_lte_tx::configure(const rlc_config_t& cnfg_, std::string uint32_t rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8_t* payload, uint32_t nof_bytes) { std::lock_guard lock(mutex); - rlc_umd_pdu_header_t header; + rlc_umd_pdu_header_t header = {}; header.fi = RLC_FI_FIELD_START_AND_END_ALIGNED; header.sn = vt_us; header.N_li = 0; @@ -139,10 +138,7 @@ uint32_t rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uin int pdu_space = SRSRAN_MIN(nof_bytes, pdu->get_tailroom()); if (pdu_space <= head_len + 1) { - logger.info("%s Cannot build a PDU - %d bytes available, %d bytes required for header", - rb_name.c_str(), - nof_bytes, - head_len); + RlcInfo("Cannot build a PDU - %d bytes available, %d bytes required for header", nof_bytes, head_len); return 0; } @@ -150,8 +146,7 @@ uint32_t rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uin if (tx_sdu) { uint32_t space = pdu_space - head_len; to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space; - logger.debug( - "%s adding remainder of SDU segment - %d bytes of %d remaining", rb_name.c_str(), to_move, tx_sdu->N_bytes); + RlcDebug("adding remainder of SDU segment - %d bytes of %d remaining", to_move, tx_sdu->N_bytes); memcpy(pdu_ptr, tx_sdu->msg, to_move); last_li = to_move; pdu_ptr += to_move; @@ -162,12 +157,11 @@ uint32_t rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uin #ifdef ENABLE_TIMESTAMP auto latency_us = tx_sdu->get_latency_us().count(); mean_pdu_latency_us.push(latency_us); - logger.debug("%s Complete SDU scheduled for tx. Stack latency (last/average): %" PRIu64 "/%ld us", - rb_name.c_str(), - (uint64_t)latency_us, - (long)mean_pdu_latency_us.value()); + RlcDebug("Complete SDU scheduled for tx. Stack latency (last/average): %" PRIu64 "/%ld us", + (uint64_t)latency_us, + (long)mean_pdu_latency_us.value()); #else - logger.debug("%s Complete SDU scheduled for tx.", rb_name.c_str()); + RlcDebug("%s Complete SDU scheduled for tx.", rb_name.c_str()); #endif tx_sdu.reset(); } @@ -177,7 +171,7 @@ uint32_t rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uin // Pull SDUs from queue while (pdu_space > head_len + 1 && tx_sdu_queue.size() > 0) { - logger.debug("pdu_space=%d, head_len=%d", pdu_space, head_len); + RlcDebug("pdu_space=%d, head_len=%d", pdu_space, head_len); if (last_li > 0) { header.li[header.N_li++] = last_li; } @@ -190,7 +184,7 @@ uint32_t rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uin } tx_sdu = tx_sdu_queue.read(); to_move = (space >= tx_sdu->N_bytes) ? tx_sdu->N_bytes : space; - logger.debug("%s adding new SDU segment - %d bytes of %d remaining", rb_name.c_str(), to_move, tx_sdu->N_bytes); + RlcDebug("adding new SDU segment - %d bytes of %d remaining", to_move, tx_sdu->N_bytes); memcpy(pdu_ptr, tx_sdu->msg, to_move); last_li = to_move; pdu_ptr += to_move; @@ -201,12 +195,11 @@ uint32_t rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uin #ifdef ENABLE_TIMESTAMP auto latency_us = tx_sdu->get_latency_us().count(); mean_pdu_latency_us.push(latency_us); - logger.debug("%s Complete SDU scheduled for tx. Stack latency (last/average): %" PRIu64 "/%ld us", - rb_name.c_str(), - (uint64_t)latency_us, - (long)mean_pdu_latency_us.value()); + RlcDebug("Complete SDU scheduled for tx. Stack latency (last/average): %" PRIu64 "/%ld us", + (uint64_t)latency_us, + (long)mean_pdu_latency_us.value()); #else - logger.debug("%s Complete SDU scheduled for tx.", rb_name.c_str()); + RlcDebug("Complete SDU scheduled for tx."); #endif tx_sdu.reset(); } @@ -225,7 +218,7 @@ uint32_t rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uin rlc_um_write_data_pdu_header(&header, pdu.get()); memcpy(payload, pdu->msg, pdu->N_bytes); - logger.info(payload, pdu->N_bytes, "%s Tx PDU SN=%d (%d B)", rb_name.c_str(), header.sn, pdu->N_bytes); + RlcHexInfo(payload, pdu->N_bytes, "Tx PDU SN=%d (%d B)", header.sn, pdu->N_bytes); debug_state(); @@ -234,7 +227,7 @@ uint32_t rlc_um_lte::rlc_um_lte_tx::build_data_pdu(unique_byte_buffer_t pdu, uin void rlc_um_lte::rlc_um_lte_tx::debug_state() { - logger.debug("%s vt_us = %d", rb_name.c_str(), vt_us); + RlcDebug("vt_us = %d", vt_us); } void rlc_um_lte::rlc_um_lte_tx::reset() @@ -256,14 +249,16 @@ bool rlc_um_lte::rlc_um_lte_rx::configure(const rlc_config_t& cnfg_, std::string { cfg = cnfg_; + rb_name = rb_name_; + if (cfg.um.rx_mod == 0) { - logger.error("Error configuring %s RLC UM: rx_mod==0", rb_name.c_str()); + RlcError("Error configuring RLC UM: rx_mod==0"); return false; } // check timer if (not reordering_timer.is_valid()) { - logger.error("Configuring RLC UM RX: timers not configured"); + RlcError("Configuring RLC UM RX: timers not configured"); return false; } @@ -272,8 +267,6 @@ bool rlc_um_lte::rlc_um_lte_rx::configure(const rlc_config_t& cnfg_, std::string reordering_timer.set(static_cast(cfg.um.t_reordering), [this](uint32_t tid) { timer_expired(tid); }); } - rb_name = rb_name_; - return true; } @@ -319,17 +312,17 @@ void rlc_um_lte::rlc_um_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b rlc_umd_pdu_header_t header; rlc_um_read_data_pdu_header(payload, nof_bytes, cfg.um.rx_sn_field_length, &header); - logger.info(payload, nof_bytes, "%s Rx data PDU SN=%d (%d B)", rb_name.c_str(), header.sn, nof_bytes); + RlcHexInfo(payload, nof_bytes, "Rx data PDU SN=%d (%d B)", header.sn, nof_bytes); if (RX_MOD_BASE(header.sn) >= RX_MOD_BASE(vr_uh - cfg.um.rx_window_size) && RX_MOD_BASE(header.sn) < RX_MOD_BASE(vr_ur)) { - logger.info("%s SN=%d outside rx window [%d:%d] - discarding", rb_name.c_str(), header.sn, vr_ur, vr_uh); + RlcInfo("SN=%d outside rx window [%d:%d] - discarding", header.sn, vr_ur, vr_uh); return; } std::map::iterator it = rx_window.find(header.sn); if (rx_window.end() != it) { - logger.info("%s Discarding duplicate SN=%d", rb_name.c_str(), header.sn); + RlcInfo("Discarding duplicate SN=%d", header.sn); return; } @@ -337,7 +330,7 @@ void rlc_um_lte::rlc_um_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b rlc_umd_pdu_t pdu = {}; pdu.buf = make_byte_buffer(); if (!pdu.buf) { - logger.error("Discarting packet: no space in buffer pool"); + RlcError("Discarding packet: no space in buffer pool"); return; } memcpy(pdu.buf->msg, payload, nof_bytes); @@ -355,9 +348,9 @@ void rlc_um_lte::rlc_um_lte_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_b } // Reassemble and deliver SDUs, while updating vr_ur - logger.debug("Entering Reassemble from received PDU"); + RlcDebug("Entering Reassemble from received PDU"); reassemble_rx_sdus(); - logger.debug("Finished reassemble from received PDU"); + RlcDebug("Finished reassemble from received PDU"); // Update reordering variables and timers if (reordering_timer.is_running()) { @@ -381,32 +374,32 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() if (!rx_sdu) { rx_sdu = make_byte_buffer(); if (!rx_sdu) { - logger.error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); + RlcError("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); return; } } // First catch up with lower edge of reordering window while (!inside_reordering_window(vr_ur)) { - logger.debug("SN=%d is not inside reordering windows", vr_ur); + RlcDebug("SN=%d is not inside reordering windows", vr_ur); if (rx_window.end() == rx_window.find(vr_ur)) { - logger.debug("SN=%d not in rx_window. Reset received SDU", vr_ur); + RlcDebug("SN=%d not in rx_window. Reset received SDU", vr_ur); rx_sdu->clear(); } else { // Handle any SDU segments for (uint32_t i = 0; i < rx_window[vr_ur].header.N_li; i++) { int len = rx_window[vr_ur].header.li[i]; - logger.debug(rx_window[vr_ur].buf->msg, - len, - "Handling segment %d/%d of length %d B of SN=%d", - i + 1, - rx_window[vr_ur].header.N_li, - len, - vr_ur); + RlcHexDebug(rx_window[vr_ur].buf->msg, + len, + "Handling segment %d/%d of length %d B of SN=%d", + i + 1, + rx_window[vr_ur].header.N_li, + len, + vr_ur); // Check if we received a middle or end segment if (rx_sdu->N_bytes == 0 && i == 0 && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - logger.warning("Dropping PDU %d in reassembly due to lost start segment", vr_ur); + RlcWarning("Dropping PDU %d in reassembly due to lost start segment", vr_ur); // Advance data pointers and continue with next segment rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->N_bytes -= len; @@ -421,18 +414,13 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() rx_window[vr_ur].buf->N_bytes -= len; if ((pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) || (vr_ur != ((vr_ur_in_rx_sdu + 1) % cfg.um.rx_mod))) { - logger.warning("Dropping remainder of lost PDU (lower edge middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)", - vr_ur, - vr_ur_in_rx_sdu); + RlcWarning("Dropping remainder of lost PDU (lower edge middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)", + vr_ur, + vr_ur_in_rx_sdu); rx_sdu->clear(); metrics.num_lost_pdus++; } else { - logger.info(rx_sdu->msg, - rx_sdu->N_bytes, - "%s Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", - rb_name.c_str(), - vr_ur, - i); + RlcHexInfo(rx_sdu->msg, rx_sdu->N_bytes, "Rx SDU vr_ur=%d, i=%d (lower edge middle segments)", vr_ur, i); rx_sdu->set_timestamp(); metrics.num_rx_sdus++; metrics.num_rx_sdu_bytes += rx_sdu->N_bytes; @@ -443,7 +431,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() } rx_sdu = make_byte_buffer(); if (!rx_sdu) { - logger.error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); + RlcError("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); return; } } @@ -452,22 +440,21 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() // Handle last segment if (rx_sdu->N_bytes > 0 || rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - logger.info("Writing last segment in SDU buffer. Lower edge vr_ur=%d, Buffer size=%d, segment size=%d", - vr_ur, - rx_sdu->N_bytes, - rx_window[vr_ur].buf->N_bytes); + RlcInfo("Writing last segment in SDU buffer. Lower edge vr_ur=%d, Buffer size=%d, segment size=%d", + vr_ur, + rx_sdu->N_bytes, + rx_window[vr_ur].buf->N_bytes); memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, rx_window[vr_ur].buf->N_bytes); rx_sdu->N_bytes += rx_window[vr_ur].buf->N_bytes; vr_ur_in_rx_sdu = vr_ur; if (rlc_um_end_aligned(rx_window[vr_ur].header.fi)) { if (pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - logger.warning("Dropping remainder of lost PDU (lower edge last segments)"); + RlcWarning("Dropping remainder of lost PDU (lower edge last segments)"); rx_sdu->clear(); metrics.num_lost_pdus++; } else { - logger.info( - rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", rb_name.c_str(), vr_ur); + RlcHexInfo(rx_sdu->msg, rx_sdu->N_bytes, "Rx SDU vr_ur=%d (lower edge last segments)", vr_ur); rx_sdu->set_timestamp(); metrics.num_rx_sdus++; metrics.num_rx_sdu_bytes += rx_sdu->N_bytes; @@ -478,7 +465,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() } rx_sdu = make_byte_buffer(); if (!rx_sdu) { - logger.error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); + RlcError("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); return; } } @@ -495,10 +482,10 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() // Now update vr_ur until we reach an SN we haven't yet received while (rx_window.end() != rx_window.find(vr_ur)) { - logger.debug("Reassemble loop for vr_ur=%d", vr_ur); + RlcDebug("Reassemble loop for vr_ur=%d", vr_ur); if (not pdu_belongs_to_rx_sdu()) { - logger.info("PDU SN=%d lost, stop reassambling SDU (vr_ur_in_rx_sdu=%d)", vr_ur_in_rx_sdu + 1, vr_ur_in_rx_sdu); + RlcInfo("PDU SN=%d lost, stop reassambling SDU (vr_ur_in_rx_sdu=%d)", vr_ur_in_rx_sdu + 1, vr_ur_in_rx_sdu); pdu_lost = false; // Reset flag to not prevent reassembling of further segments rx_sdu->clear(); } @@ -506,22 +493,22 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() // Handle any SDU segments for (uint32_t i = 0; i < rx_window[vr_ur].header.N_li; i++) { uint16_t len = rx_window[vr_ur].header.li[i]; - logger.debug("Handling SDU segment i=%d with len=%d of vr_ur=%d N_li=%d [%s]", - i, - len, - vr_ur, - rx_window[vr_ur].header.N_li, - rlc_fi_field_text[rx_window[vr_ur].header.fi]); + RlcDebug("Handling SDU segment i=%d with len=%d of vr_ur=%d N_li=%d [%s]", + i, + len, + vr_ur, + rx_window[vr_ur].header.N_li, + rlc_fi_field_text[rx_window[vr_ur].header.fi]); // Check if the first part of the PDU is a middle or end segment if (rx_sdu->N_bytes == 0 && i == 0 && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - logger.info( + RlcHexInfo( rx_window[vr_ur].buf->msg, len, "Dropping first %d B of SN=%d due to lost start segment", len, vr_ur); if (rx_window[vr_ur].buf->N_bytes < len) { - logger.error("Dropping remaining remainder of SN=%d too (N_bytes=%u < len=%d)", - vr_ur, - rx_window[vr_ur].buf->N_bytes, - len); + RlcError("Dropping remaining remainder of SN=%d too (N_bytes=%u < len=%d)", + vr_ur, + rx_window[vr_ur].buf->N_bytes, + len); goto clean_up_rx_window; } @@ -538,31 +525,31 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() // Check available space in SDU if ((uint32_t)len > rx_sdu->get_tailroom()) { - logger.error("Dropping PDU %d due to buffer mis-alignment (current segment len %d B, received %d B)", - vr_ur, - rx_sdu->N_bytes, - len); + RlcError("Dropping PDU %d due to buffer mis-alignment (current segment len %d B, received %d B)", + vr_ur, + rx_sdu->N_bytes, + len); rx_sdu->clear(); metrics.num_lost_pdus++; goto clean_up_rx_window; } if (not pdu_belongs_to_rx_sdu()) { - logger.info(rx_window[vr_ur].buf->msg, len, "Copying first %d bytes of new SDU", len); - logger.info("Updating vr_ur_in_rx_sdu. old=%d, new=%d", vr_ur_in_rx_sdu, vr_ur); + RlcHexInfo(rx_window[vr_ur].buf->msg, len, "Copying first %d bytes of new SDU", len); + RlcInfo("Updating vr_ur_in_rx_sdu. old=%d, new=%d", vr_ur_in_rx_sdu, vr_ur); vr_ur_in_rx_sdu = vr_ur; } else { - logger.info(rx_window[vr_ur].buf->msg, - len, - "Concatenating %d bytes in to current length %d. rx_window remaining bytes=%d, " - "vr_ur_in_rx_sdu=%d, vr_ur=%d, rx_mod=%d, last_mod=%d", - len, - rx_sdu->N_bytes, - rx_window[vr_ur].buf->N_bytes, - vr_ur_in_rx_sdu, - vr_ur, - cfg.um.rx_mod, - (vr_ur_in_rx_sdu + 1) % cfg.um.rx_mod); + RlcHexInfo(rx_window[vr_ur].buf->msg, + len, + "Concatenating %d bytes in to current length %d. rx_window remaining bytes=%d, " + "vr_ur_in_rx_sdu=%d, vr_ur=%d, rx_mod=%d, last_mod=%d", + len, + rx_sdu->N_bytes, + rx_window[vr_ur].buf->N_bytes, + vr_ur_in_rx_sdu, + vr_ur, + cfg.um.rx_mod, + (vr_ur_in_rx_sdu + 1) % cfg.um.rx_mod); } memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, len); @@ -572,12 +559,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() vr_ur_in_rx_sdu = vr_ur; if (pdu_belongs_to_rx_sdu()) { - logger.info(rx_sdu->msg, - rx_sdu->N_bytes, - "%s Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", - rb_name.c_str(), - vr_ur, - i); + RlcHexInfo(rx_sdu->msg, rx_sdu->N_bytes, "Rx SDU vr_ur=%d, i=%d, (update vr_ur middle segments)", vr_ur, i); rx_sdu->set_timestamp(); metrics.num_rx_sdus++; metrics.num_rx_sdu_bytes += rx_sdu->N_bytes; @@ -588,13 +570,13 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() } rx_sdu = make_byte_buffer(); if (!rx_sdu) { - logger.error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); + RlcError("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); return; } } else { - logger.warning("Dropping remainder of lost PDU (update vr_ur middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)", - vr_ur, - vr_ur_in_rx_sdu); + RlcWarning("Dropping remainder of lost PDU (update vr_ur middle segments, vr_ur=%d, vr_ur_in_rx_sdu=%d)", + vr_ur, + vr_ur_in_rx_sdu); // Advance data pointers and continue with next segment rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->N_bytes -= len; @@ -606,7 +588,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() // Handle last segment if (rx_sdu->N_bytes == 0 && rx_window[vr_ur].header.N_li == 0 && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - logger.warning("Dropping PDU %d during last segment handling due to lost start segment", vr_ur); + RlcWarning("Dropping PDU %d during last segment handling due to lost start segment", vr_ur); rx_sdu->clear(); metrics.num_lost_pdus++; goto clean_up_rx_window; @@ -615,31 +597,30 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() if (rx_sdu->N_bytes < SRSRAN_MAX_BUFFER_SIZE_BYTES && rx_window[vr_ur].buf->N_bytes < SRSRAN_MAX_BUFFER_SIZE_BYTES && rx_window[vr_ur].buf->N_bytes + rx_sdu->N_bytes < SRSRAN_MAX_BUFFER_SIZE_BYTES) { - logger.info(rx_window[vr_ur].buf->msg, - rx_window[vr_ur].buf->N_bytes, - "Writing last segment in SDU buffer. Updating vr_ur=%d, vr_ur_in_rx_sdu=%d, Buffer size=%d, " - "segment size=%d", - vr_ur, - vr_ur_in_rx_sdu, - rx_sdu->N_bytes, - rx_window[vr_ur].buf->N_bytes); + RlcHexInfo(rx_window[vr_ur].buf->msg, + rx_window[vr_ur].buf->N_bytes, + "Writing last segment in SDU buffer. Updating vr_ur=%d, vr_ur_in_rx_sdu=%d, Buffer size=%d, " + "segment size=%d", + vr_ur, + vr_ur_in_rx_sdu, + rx_sdu->N_bytes, + rx_window[vr_ur].buf->N_bytes); memcpy(&rx_sdu->msg[rx_sdu->N_bytes], rx_window[vr_ur].buf->msg, rx_window[vr_ur].buf->N_bytes); rx_sdu->N_bytes += rx_window[vr_ur].buf->N_bytes; } else { - logger.error("Out of bounds while reassembling SDU buffer in UM: sdu_len=%d, window_buffer_len=%d, vr_ur=%d", - rx_sdu->N_bytes, - rx_window[vr_ur].buf->N_bytes, - vr_ur); + RlcError("Out of bounds while reassembling SDU buffer in UM: sdu_len=%d, window_buffer_len=%d, vr_ur=%d", + rx_sdu->N_bytes, + rx_window[vr_ur].buf->N_bytes, + vr_ur); } vr_ur_in_rx_sdu = vr_ur; if (rlc_um_end_aligned(rx_window[vr_ur].header.fi)) { if (pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { - logger.warning("Dropping remainder of lost PDU (update vr_ur last segments)"); + RlcWarning("Dropping remainder of lost PDU (update vr_ur last segments)"); rx_sdu->clear(); metrics.num_lost_pdus++; } else { - logger.info( - rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", rb_name.c_str(), vr_ur); + RlcHexInfo(rx_sdu->msg, rx_sdu->N_bytes, "Rx SDU vr_ur=%d (update vr_ur last segments)", vr_ur); rx_sdu->set_timestamp(); metrics.num_rx_sdus++; metrics.num_rx_sdu_bytes += rx_sdu->N_bytes; @@ -650,7 +631,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus() } rx_sdu = make_byte_buffer(); if (!rx_sdu) { - logger.error("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); + RlcError("Fatal Error: Couldn't allocate buffer in rlc_um::reassemble_rx_sdus()."); return; } } @@ -697,9 +678,9 @@ void rlc_um_lte::rlc_um_lte_rx::timer_expired(uint32_t timeout_id) { if (reordering_timer.id() == timeout_id) { // 36.322 v10 Section 5.1.2.2.4 - logger.info("%s reordering timeout expiry - updating vr_ur and reassembling", rb_name.c_str()); + RlcInfo("%s reordering timeout expiry - updating vr_ur and reassembling", rb_name.c_str()); - logger.warning("Lost PDU SN=%d", vr_ur); + RlcWarning("Lost PDU SN=%d", vr_ur); pdu_lost = true; if (rx_sdu != NULL) { @@ -708,9 +689,9 @@ void rlc_um_lte::rlc_um_lte_rx::timer_expired(uint32_t timeout_id) while (RX_MOD_BASE(vr_ur) < RX_MOD_BASE(vr_ux)) { vr_ur = (vr_ur + 1) % cfg.um.rx_mod; - logger.debug("Entering Reassemble from timeout id=%d", timeout_id); + RlcDebug("Entering Reassemble from timeout id=%d", timeout_id); reassemble_rx_sdus(); - logger.debug("Finished reassemble from timeout id=%d", timeout_id); + RlcDebug("Finished reassemble from timeout id=%d", timeout_id); } if (RX_MOD_BASE(vr_uh) > RX_MOD_BASE(vr_ur)) { @@ -728,7 +709,7 @@ void rlc_um_lte::rlc_um_lte_rx::timer_expired(uint32_t timeout_id) void rlc_um_lte::rlc_um_lte_rx::debug_state() { - logger.debug("%s vr_ur = %d, vr_ux = %d, vr_uh = %d", rb_name.c_str(), vr_ur, vr_ux, vr_uh); + RlcDebug("vr_ur = %d, vr_ux = %d, vr_uh = %d", vr_ur, vr_ux, vr_uh); } /**************************************************************************** diff --git a/lib/src/rlc/rlc_um_nr.cc b/lib/src/rlc/rlc_um_nr.cc index e4d3536022..197466b01c 100644 --- a/lib/src/rlc/rlc_um_nr.cc +++ b/lib/src/rlc/rlc_um_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -42,12 +42,12 @@ rlc_um_nr::~rlc_um_nr() bool rlc_um_nr::configure(const rlc_config_t& cnfg_) { - // determine bearer name and configure Rx/Tx objects - rb_name = get_rb_name(rrc, lcid, cnfg_.um.is_mrb); - // store config cfg = cnfg_; + // determine bearer name and configure Rx/Tx objects + rb_name = get_rb_name(); + rx.reset(new rlc_um_nr_rx(this)); if (not rx->configure(cfg, rb_name)) { return false; @@ -58,11 +58,10 @@ bool rlc_um_nr::configure(const rlc_config_t& cnfg_) return false; } - logger.info("%s configured in %s: sn_field_length=%u bits, t_reassembly=%d ms", - rb_name.c_str(), - srsran::to_string(cnfg_.rlc_mode), - srsran::to_number(cfg.um_nr.sn_field_length), - cfg.um_nr.t_reassembly_ms); + RlcInfo("configured in %s: sn_field_length=%u bits, t_reassembly=%d ms", + srsran::to_string(cnfg_.rlc_mode), + srsran::to_number(cfg.um_nr.sn_field_length), + cfg.um_nr.t_reassembly_ms); rx_enabled = true; tx_enabled = true; @@ -70,6 +69,16 @@ bool rlc_um_nr::configure(const rlc_config_t& cnfg_) return true; } +/**************************************************************************** + * Logging helpers + ***************************************************************************/ +std::string rlc_um_nr::get_rb_name() const +{ + fmt::memory_buffer fmtbuf; + fmt::format_to(fmtbuf, "DRB{}", cfg.um_nr.bearer_id); + return fmt::to_string(fmtbuf); +} + /**************************************************************************** * Tx Subclass implementation ***************************************************************************/ @@ -81,7 +90,7 @@ uint32_t rlc_um_nr::rlc_um_nr_tx::get_buffer_state() std::lock_guard lock(mutex); // Bytes needed for tx SDUs - uint32_t n_sdus = tx_sdu_queue.size(); + uint32_t n_sdus = tx_sdu_queue.get_n_sdus(); uint32_t n_bytes = tx_sdu_queue.size_bytes(); if (tx_sdu) { n_sdus++; @@ -101,7 +110,6 @@ uint32_t rlc_um_nr::rlc_um_nr_tx::get_buffer_state() if (bsr_callback) { bsr_callback(parent->get_lcid(), n_bytes, 0); } - return n_bytes; } @@ -132,7 +140,7 @@ uint32_t rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8 { // Sanity check (we need at least 2B for a SDU) if (nof_bytes < 2) { - logger.warning("%s Cannot build a PDU with %d byte.", rb_name.c_str(), nof_bytes); + RlcWarning("Cannot build a PDU with %d byte.", nof_bytes); return 0; } @@ -147,7 +155,13 @@ uint32_t rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8 // Select segmentation information and header size if (tx_sdu == nullptr) { // Read a new SDU - tx_sdu = tx_sdu_queue.read(); + do { + tx_sdu = tx_sdu_queue.read(); + } while (tx_sdu == nullptr && tx_sdu_queue.size() != 0); + if (tx_sdu == nullptr) { + RlcDebug("Cannot build any PDU, tx_sdu_queue has no non-null SDU."); + return 0; + } next_so = 0; // Check for full SDU case @@ -169,10 +183,7 @@ uint32_t rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8 // Calculate actual header length uint32_t head_len = rlc_um_nr_packed_length(header); if (pdu_space <= head_len + 1) { - logger.info("%s Cannot build a PDU - %d bytes available, %d bytes required for header", - rb_name.c_str(), - nof_bytes, - head_len); + RlcInfo("Cannot build a PDU - %d bytes available, %d bytes required for header", nof_bytes, head_len); return 0; } @@ -181,7 +192,7 @@ uint32_t rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8 uint32_t to_move = space >= tx_sdu->N_bytes ? tx_sdu->N_bytes : space; // Log - logger.debug("%s adding %s - (%d/%d)", rb_name.c_str(), to_string(header.si).c_str(), to_move, tx_sdu->N_bytes); + RlcDebug("adding %s - (%d/%d)", to_string(header.si).c_str(), to_move, tx_sdu->N_bytes); // Move data from SDU to PDU uint8_t* pdu_ptr = pdu->msg; @@ -216,9 +227,9 @@ uint32_t rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8 if (header.si == rlc_nr_si_field_t::full_sdu) { // log without SN - logger.info(payload, ret, "%s Tx PDU (%d B)", rb_name.c_str(), pdu->N_bytes); + RlcHexInfo(payload, ret, "Tx PDU (%d B)", pdu->N_bytes); } else { - logger.info(payload, ret, "%s Tx PDU SN=%d (%d B)", rb_name.c_str(), header.sn, pdu->N_bytes); + RlcHexInfo(payload, ret, "Tx PDU SN=%d (%d B)", header.sn, pdu->N_bytes); } debug_state(); @@ -228,7 +239,7 @@ uint32_t rlc_um_nr::rlc_um_nr_tx::build_data_pdu(unique_byte_buffer_t pdu, uint8 void rlc_um_nr::rlc_um_nr_tx::debug_state() { - logger.debug("%s TX_Next=%d, next_so=%d", rb_name.c_str(), TX_Next, next_so); + RlcDebug("TX_Next=%d, next_so=%d", TX_Next, next_so); } void rlc_um_nr::rlc_um_nr_tx::reset() @@ -250,9 +261,11 @@ bool rlc_um_nr::rlc_um_nr_rx::configure(const rlc_config_t& cnfg_, std::string r mod = (cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 64 : 4096; UM_Window_Size = (cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size6bits) ? 32 : 2048; + rb_name = rb_name_; + // check timer if (not reassembly_timer.is_valid()) { - logger.error("Configuring RLC UM NR RX: timers not configured"); + RlcError("Configuring RLC UM NR RX: timers not configured"); return false; } @@ -301,9 +314,8 @@ void rlc_um_nr::rlc_um_nr_rx::timer_expired(uint32_t timeout_id) { std::lock_guard lock(mutex); if (reassembly_timer.id() == timeout_id) { - logger.info("%s reassembly timeout expiry - updating RX_Next_Reassembly and reassembling", rb_name.c_str()); + RlcDebug("reassembly timeout expiry for SN=%d - updating RX_Next_Reassembly and reassembling", RX_Next_Reassembly); - logger.info("Lost PDU SN=%d", RX_Next_Reassembly); metrics.num_lost_pdus++; if (rx_sdu != nullptr) { @@ -319,7 +331,7 @@ void rlc_um_nr::rlc_um_nr_rx::timer_expired(uint32_t timeout_id) // discard all segments with SN < updated RX_Next_Reassembly for (auto it = rx_window.begin(); it != rx_window.end();) { - if (it->first < RX_Next_Reassembly) { + if (RX_MOD_NR_BASE(it->first) < RX_MOD_NR_BASE(RX_Next_Reassembly)) { it = rx_window.erase(it); } else { ++it; @@ -330,6 +342,7 @@ void rlc_um_nr::rlc_um_nr_rx::timer_expired(uint32_t timeout_id) if (RX_MOD_NR_BASE(RX_Next_Highest) > RX_MOD_NR_BASE(RX_Next_Reassembly + 1) || ((RX_MOD_NR_BASE(RX_Next_Highest) == RX_MOD_NR_BASE(RX_Next_Reassembly + 1) && has_missing_byte_segment(RX_Next_Reassembly)))) { + RlcDebug("starting reassembly timer for SN=%d", rb_name.c_str(), RX_Next_Reassembly); reassembly_timer.run(); RX_Timer_Trigger = RX_Next_Highest; } @@ -358,7 +371,7 @@ unique_byte_buffer_t rlc_um_nr::rlc_um_nr_rx::rlc_um_nr_strip_pdu_header(const r { unique_byte_buffer_t sdu = make_byte_buffer(); if (sdu == nullptr) { - logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + RlcError("Couldn't allocate PDU in %s().", __FUNCTION__); return nullptr; } memcpy(sdu->msg, payload, nof_bytes); @@ -382,35 +395,37 @@ bool rlc_um_nr::rlc_um_nr_rx::has_missing_byte_segment(const uint32_t sn) void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn) { if (rx_window.find(sn) != rx_window.end()) { + bool sdu_complete = false; + // iterate over received segments and try to assemble full SDU auto& pdu = rx_window.at(sn); for (auto it = pdu.segments.begin(); it != pdu.segments.end();) { - logger.debug("Have %s segment with SO=%d for SN=%d", - to_string_short(it->second.header.si).c_str(), - it->second.header.so, - it->second.header.sn); + RlcDebug("Have %s segment with SO=%d for SN=%d", + to_string_short(it->second.header.si).c_str(), + it->second.header.so, + it->second.header.sn); if (it->second.header.so == pdu.next_expected_so) { if (pdu.next_expected_so == 0) { if (pdu.sdu == nullptr) { // reuse buffer of first segment for final SDU pdu.sdu = std::move(it->second.buf); pdu.next_expected_so = pdu.sdu->N_bytes; - logger.debug("Reusing first segment of SN=%d for final SDU", it->second.header.sn); + RlcDebug("Reusing first segment of SN=%d for final SDU", it->second.header.sn); it = pdu.segments.erase(it); } else { - logger.debug("SDU buffer already allocated. Possible retransmission of first segment."); + RlcDebug("SDU buffer already allocated. Possible retransmission of first segment."); if (it->second.header.so != pdu.next_expected_so) { - logger.error("Invalid PDU. SO doesn't match. Discarting all segments of SN=%d.", sn); + RlcError("Invalid PDU. SO doesn't match. Discarding all segments of SN=%d.", sn); rx_window.erase(sn); return; } } } else { if (it->second.buf->N_bytes > pdu.sdu->get_tailroom()) { - logger.error("Cannot fit RLC PDU in SDU buffer (tailroom=%d, len=%d), dropping both. Erasing SN=%d.", - rx_sdu->get_tailroom(), - it->second.buf->N_bytes, - it->second.header.sn); + RlcError("Cannot fit RLC PDU in SDU buffer (tailroom=%d, len=%d), dropping both. Erasing SN=%d.", + rx_sdu->get_tailroom(), + it->second.buf->N_bytes, + it->second.header.sn); rx_window.erase(sn); metrics.num_lost_pdus++; return; @@ -420,26 +435,13 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn) memcpy(pdu.sdu->msg + pdu.sdu->N_bytes, it->second.buf->msg, it->second.buf->N_bytes); pdu.sdu->N_bytes += it->second.buf->N_bytes; pdu.next_expected_so += it->second.buf->N_bytes; - logger.debug("Appended SO=%d of SN=%d", it->second.header.so, it->second.header.sn); + RlcDebug("Appended SO=%d of SN=%d", it->second.header.so, it->second.header.sn); it = pdu.segments.erase(it); if (pdu.next_expected_so == pdu.total_sdu_length) { - // deliver full SDU to upper layers - logger.info("Delivering %s SDU SN=%d (%d B)", rb_name.c_str(), sn, pdu.sdu->N_bytes); - pdcp->write_pdu(lcid, std::move(pdu.sdu)); - - // find next SN in rx buffer - if (sn == RX_Next_Reassembly) { - RX_Next_Reassembly = ((RX_Next_Reassembly + 1) % mod); - while (RX_MOD_NR_BASE(RX_Next_Reassembly) < RX_MOD_NR_BASE(RX_Next_Highest)) { - RX_Next_Reassembly = (RX_Next_Reassembly + 1) % mod; - } - logger.debug("Updating RX_Next_Reassembly=%d", RX_Next_Reassembly); - } - - // delete PDU from rx_window - rx_window.erase(sn); - return; + // entire SDU has been received, it will be passed up the stack outside the loop + sdu_complete = true; + break; } } } else { @@ -448,20 +450,43 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn) } } - // check for SN outside of rx window - if (not sn_in_reassembly_window(sn)) { - // update RX_Next_highest - RX_Next_Highest = sn + 1; - logger.debug("Updating RX_Next_Highest=%d", RX_Next_Highest); + if (sdu_complete) { + // deliver full SDU to upper layers + RlcInfo("Rx SDU (%d B)", pdu.sdu->N_bytes); + pdcp->write_pdu(lcid, std::move(pdu.sdu)); + + // delete PDU from rx_window + rx_window.erase(sn); + + // find next SN in rx buffer + if (sn == RX_Next_Reassembly) { + if (rx_window.empty()) { + // no further segments received + RX_Next_Reassembly = RX_Next_Highest; + } else { + for (auto it = rx_window.begin(); it != rx_window.end(); ++it) { + RlcDebug("SN=%d has %zd segments", it->first, it->second.segments.size()); + if (RX_MOD_NR_BASE(it->first) > RX_MOD_NR_BASE(RX_Next_Reassembly)) { + RX_Next_Reassembly = it->first; + break; + } + } + } + RlcDebug("Updating RX_Next_Reassembly=%d", RX_Next_Reassembly); + } + } else if (not sn_in_reassembly_window(sn)) { + // SN outside of rx window + + RX_Next_Highest = (sn + 1) % mod; // update RX_Next_highest + RlcDebug("Updating RX_Next_Highest=%d", RX_Next_Highest); // drop all SNs outside of new rx window for (auto it = rx_window.begin(); it != rx_window.end();) { if (not sn_in_reassembly_window(it->first)) { - logger.info("%s SN: %d outside rx window [%d:%d] - discarding", - rb_name.c_str(), - it->first, - RX_Next_Highest - UM_Window_Size, - RX_Next_Highest); + RlcInfo("SN=%d outside rx window [%d:%d] - discarding", + it->first, + RX_Next_Highest - UM_Window_Size, + RX_Next_Highest); it = rx_window.erase(it); metrics.num_lost_pdus++; } else { @@ -474,29 +499,33 @@ void rlc_um_nr::rlc_um_nr_rx::handle_rx_buffer_update(const uint32_t sn) for (const auto& rx_pdu : rx_window) { if (rx_pdu.first >= RX_MOD_NR_BASE(RX_Next_Highest - UM_Window_Size)) { RX_Next_Reassembly = rx_pdu.first; - logger.debug("Updating RX_Next_Reassembly=%d", RX_Next_Reassembly); + RlcDebug("Updating RX_Next_Reassembly=%d", RX_Next_Reassembly); break; } } } + } - if (reassembly_timer.is_running()) { - if (RX_Timer_Trigger <= RX_Next_Reassembly || - (not sn_in_reassembly_window(RX_Timer_Trigger) and RX_Timer_Trigger != RX_Next_Highest) || - ((RX_Next_Highest == RX_Next_Reassembly + 1) && not has_missing_byte_segment(sn))) { - reassembly_timer.stop(); - } + if (reassembly_timer.is_running()) { + if (RX_Timer_Trigger <= RX_Next_Reassembly || + (not sn_in_reassembly_window(RX_Timer_Trigger) and RX_Timer_Trigger != RX_Next_Highest) || + ((RX_Next_Highest == RX_Next_Reassembly + 1) && not has_missing_byte_segment(RX_Next_Reassembly))) { + RlcDebug("stopping reassembly timer"); + reassembly_timer.stop(); } + } - if (not reassembly_timer.is_running() && has_missing_byte_segment(sn)) { - if (RX_Next_Highest > RX_Next_Reassembly + 1) { - reassembly_timer.run(); - RX_Timer_Trigger = RX_Next_Highest; - } + if (not reassembly_timer.is_running()) { + if ((RX_MOD_NR_BASE(RX_Next_Highest) > RX_MOD_NR_BASE(RX_Next_Reassembly + 1)) || + ((RX_MOD_NR_BASE(RX_Next_Highest) == RX_MOD_NR_BASE(RX_Next_Reassembly + 1)) && + has_missing_byte_segment(RX_Next_Reassembly))) { + RlcDebug("Starting reassembly timer for SN=%d", sn); + reassembly_timer.run(); + RX_Timer_Trigger = RX_Next_Highest; } } } else { - logger.error("SN=%d does not exist in Rx buffer", sn); + RlcError("SN=%d does not exist in Rx buffer", sn); } } @@ -505,10 +534,7 @@ inline void rlc_um_nr::rlc_um_nr_rx::update_total_sdu_length(rlc_umd_pdu_segment { if (rx_pdu.header.si == rlc_nr_si_field_t::last_segment) { pdu_segments.total_sdu_length = rx_pdu.header.so + rx_pdu.buf->N_bytes; - logger.info("%s updating total SDU length for SN=%d to %d B", - rb_name.c_str(), - rx_pdu.header.sn, - pdu_segments.total_sdu_length); + RlcDebug("updating total SDU length for SN=%d to %d B", rx_pdu.header.sn, pdu_segments.total_sdu_length); } }; @@ -519,7 +545,7 @@ void rlc_um_nr::rlc_um_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_byt rlc_um_nr_pdu_header_t header = {}; rlc_um_nr_read_data_pdu_header(payload, nof_bytes, cfg.um_nr.sn_field_length, &header); - logger.debug(payload, nof_bytes, "RX %s Rx data PDU (%d B)", rb_name.c_str(), nof_bytes); + RlcHexDebug(payload, nof_bytes, "Rx data PDU (%d B)", nof_bytes); // check if PDU contains a SN if (header.si == rlc_nr_si_field_t::full_sdu) { @@ -527,10 +553,10 @@ void rlc_um_nr::rlc_um_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_byt unique_byte_buffer_t sdu = rlc_um_nr_strip_pdu_header(header, payload, nof_bytes); // deliver to PDCP - logger.info("Delivering %s SDU (%d B)", rb_name.c_str(), sdu->N_bytes); + RlcInfo("Rx SDU (%d B)", sdu->N_bytes); pdcp->write_pdu(lcid, std::move(sdu)); } else if (sn_invalid_for_rx_buffer(header.sn)) { - logger.info("%s Discarding SN=%d", rb_name.c_str(), header.sn); + RlcInfo("Discarding SN=%d", header.sn); // Nothing else to do here .. } else { // place PDU in receive buffer @@ -541,10 +567,9 @@ void rlc_um_nr::rlc_um_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_byt // check if this SN is already present in rx buffer if (rx_window.find(header.sn) == rx_window.end()) { // first received segment of this SN, add to rx buffer - logger.info(rx_pdu.buf->msg, + RlcHexDebug(rx_pdu.buf->msg, rx_pdu.buf->N_bytes, - "%s placing %s segment of SN=%d (%d B) in Rx buffer", - rb_name.c_str(), + "placing %s segment of SN=%d (%d B) in Rx buffer", to_string_short(header.si).c_str(), header.sn, rx_pdu.buf->N_bytes); @@ -554,8 +579,9 @@ void rlc_um_nr::rlc_um_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_byt rx_window[header.sn] = std::move(pdu_segments); } else { // other segment for this SN already present, update received data - logger.info("%s updating SN=%d at SO=%d with %d B", - rb_name.c_str(), + RlcHexDebug(rx_pdu.buf->msg, + rx_pdu.buf->N_bytes, + "updating SN=%d at SO=%d with %d B", rx_pdu.header.sn, rx_pdu.header.so, rx_pdu.buf->N_bytes); @@ -578,12 +604,11 @@ void rlc_um_nr::rlc_um_nr_rx::handle_data_pdu(uint8_t* payload, uint32_t nof_byt void rlc_um_nr::rlc_um_nr_rx::debug_state() { - logger.debug("%s RX_Next_Reassembly=%d, RX_Timer_Trigger=%d, RX_Next_Highest=%d, t_Reassembly=%s", - rb_name.c_str(), - RX_Next_Reassembly, - RX_Timer_Trigger, - RX_Next_Highest, - reassembly_timer.is_running() ? "running" : "stopped"); + RlcDebug("RX_Next_Reassembly=%d, RX_Timer_Trigger=%d, RX_Next_Highest=%d, t_Reassembly=%s", + RX_Next_Reassembly, + RX_Timer_Trigger, + RX_Next_Highest, + reassembly_timer.is_running() ? "running" : "stopped"); } /**************************************************************************** * Header pack/unpack helper functions diff --git a/lib/src/srslog/CMakeLists.txt b/lib/src/srslog/CMakeLists.txt index 635d064be7..2fda19f5c0 100644 --- a/lib/src/srslog/CMakeLists.txt +++ b/lib/src/srslog/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -42,4 +42,4 @@ find_package(Threads REQUIRED) add_library(srslog STATIC ${SOURCES}) target_link_libraries(srslog ${CMAKE_THREAD_LIBS_INIT}) -INSTALL(TARGETS srslog DESTINATION ${LIBRARY_DIR}) +install(TARGETS srslog DESTINATION ${LIBRARY_DIR} OPTIONAL) diff --git a/lib/src/srslog/backend_worker.cpp b/lib/src/srslog/backend_worker.cpp index 5767d1e658..93a2843ed8 100644 --- a/lib/src/srslog/backend_worker.cpp +++ b/lib/src/srslog/backend_worker.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/backend_worker.h b/lib/src/srslog/backend_worker.h index 28dc0b0a6b..56343f9755 100644 --- a/lib/src/srslog/backend_worker.h +++ b/lib/src/srslog/backend_worker.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/event_trace.cpp b/lib/src/srslog/event_trace.cpp index 4064996faf..fcdece28d3 100644 --- a/lib/src/srslog/event_trace.cpp +++ b/lib/src/srslog/event_trace.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/formatters/json_formatter.cpp b/lib/src/srslog/formatters/json_formatter.cpp index f2daf6cf52..fe742a8f2a 100644 --- a/lib/src/srslog/formatters/json_formatter.cpp +++ b/lib/src/srslog/formatters/json_formatter.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/formatters/json_formatter.h b/lib/src/srslog/formatters/json_formatter.h index 76d7502fe0..38d0a621a3 100644 --- a/lib/src/srslog/formatters/json_formatter.h +++ b/lib/src/srslog/formatters/json_formatter.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/formatters/text_formatter.cpp b/lib/src/srslog/formatters/text_formatter.cpp index 50e126fb5a..ac9b9f3ad7 100644 --- a/lib/src/srslog/formatters/text_formatter.cpp +++ b/lib/src/srslog/formatters/text_formatter.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/formatters/text_formatter.h b/lib/src/srslog/formatters/text_formatter.h index b630d26738..addb1f6d77 100644 --- a/lib/src/srslog/formatters/text_formatter.h +++ b/lib/src/srslog/formatters/text_formatter.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/log_backend_impl.h b/lib/src/srslog/log_backend_impl.h index 2f44971dc3..61be8aee80 100644 --- a/lib/src/srslog/log_backend_impl.h +++ b/lib/src/srslog/log_backend_impl.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/object_repository.h b/lib/src/srslog/object_repository.h index 26a07059d7..48dfd0bc6c 100644 --- a/lib/src/srslog/object_repository.h +++ b/lib/src/srslog/object_repository.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/sinks/buffered_file_sink.h b/lib/src/srslog/sinks/buffered_file_sink.h index 7640b043a0..8f503564da 100644 --- a/lib/src/srslog/sinks/buffered_file_sink.h +++ b/lib/src/srslog/sinks/buffered_file_sink.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/sinks/file_sink.h b/lib/src/srslog/sinks/file_sink.h index ee261cb0d6..a5377bec47 100644 --- a/lib/src/srslog/sinks/file_sink.h +++ b/lib/src/srslog/sinks/file_sink.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/sinks/file_utils.h b/lib/src/srslog/sinks/file_utils.h index 17da585953..d32c8f76eb 100644 --- a/lib/src/srslog/sinks/file_utils.h +++ b/lib/src/srslog/sinks/file_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/sinks/stream_sink.h b/lib/src/srslog/sinks/stream_sink.h index f9116f361c..c4edaef25b 100644 --- a/lib/src/srslog/sinks/stream_sink.h +++ b/lib/src/srslog/sinks/stream_sink.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/sinks/syslog_sink.h b/lib/src/srslog/sinks/syslog_sink.h index edf001fdb6..18795dc48a 100644 --- a/lib/src/srslog/sinks/syslog_sink.h +++ b/lib/src/srslog/sinks/syslog_sink.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/srslog.cpp b/lib/src/srslog/srslog.cpp index ba87d9570d..a7a10965ef 100644 --- a/lib/src/srslog/srslog.cpp +++ b/lib/src/srslog/srslog.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/srslog_c.cpp b/lib/src/srslog/srslog_c.cpp index ca0a776edc..7edc10d341 100644 --- a/lib/src/srslog/srslog_c.cpp +++ b/lib/src/srslog/srslog_c.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/srslog/srslog_instance.h b/lib/src/srslog/srslog_instance.h index 96959aa380..a928a88c1f 100644 --- a/lib/src/srslog/srslog_instance.h +++ b/lib/src/srslog/srslog_instance.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/support/CMakeLists.txt b/lib/src/support/CMakeLists.txt index 8dc73cc5fa..1d420e3c0a 100644 --- a/lib/src/support/CMakeLists.txt +++ b/lib/src/support/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/support/emergency_handlers.cc b/lib/src/support/emergency_handlers.cc index 55616ef1e7..ccf01e66c6 100644 --- a/lib/src/support/emergency_handlers.cc +++ b/lib/src/support/emergency_handlers.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,6 +20,7 @@ */ #include "srsran/support/emergency_handlers.h" +#include "srsran/config.h" #include "srsran/support/srsran_assert.h" namespace { @@ -34,11 +35,11 @@ struct handler_instance { // Handlers are added in a thread safe manner without using locks to avoid possible issues if a signal is emitted while // modifying the callback array. -static constexpr unsigned max_handlers = 12; +static constexpr unsigned max_handlers = 256; static handler_instance registered_handlers[max_handlers]; static std::atomic num_handlers; -void add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* data) +int add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* data) { // Reserve a slot in the array. auto pos = num_handlers.fetch_add(1); @@ -46,13 +47,25 @@ void add_emergency_cleanup_handler(emergency_cleanup_callback callback, void* da // Check if we have space in the array. if (pos >= max_handlers) { srsran_assert(0, "Exceeded the emergency cleanup handler registered limit"); - return; + return SRSRAN_ERROR; } // Order is important here: write last the callback member as it is used to signal that the handler is valid when // reading the array. registered_handlers[pos].data.store(data); registered_handlers[pos].callback.store(callback); + + return pos; +} + +void remove_emergency_cleanup_handler(int id) +{ + if (id < 0 || static_cast(id) >= num_handlers) { + srsran_assert(0, "Invalid emergency handler id"); + return; + } + + registered_handlers[id].callback.store(nullptr); } void execute_emergency_cleanup_handlers() diff --git a/lib/src/support/signal_handler.cc b/lib/src/support/signal_handler.cc index d67e47f55f..9f2082e2ff 100644 --- a/lib/src/support/signal_handler.cc +++ b/lib/src/support/signal_handler.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/src/system/CMakeLists.txt b/lib/src/system/CMakeLists.txt index 6a24a0c83c..ae09a43719 100644 --- a/lib/src/system/CMakeLists.txt +++ b/lib/src/system/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/src/system/sys_metrics_processor.cc b/lib/src/system/sys_metrics_processor.cc index 80de195786..ef2a866d82 100644 --- a/lib/src/system/sys_metrics_processor.cc +++ b/lib/src/system/sys_metrics_processor.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/CMakeLists.txt b/lib/test/CMakeLists.txt index 00372acb4a..a3454f590b 100644 --- a/lib/test/CMakeLists.txt +++ b/lib/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -20,7 +20,6 @@ add_subdirectory(asn1) add_subdirectory(common) -add_subdirectory(mac) add_subdirectory(phy) add_subdirectory(srslog) add_subdirectory(rlc) diff --git a/lib/test/adt/CMakeLists.txt b/lib/test/adt/CMakeLists.txt index 8dc1a0d1f1..ebd878ae00 100644 --- a/lib/test/adt/CMakeLists.txt +++ b/lib/test/adt/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/test/adt/bounded_bitset_test.cc b/lib/test/adt/bounded_bitset_test.cc index 1e10067035..f17cae8fe0 100644 --- a/lib/test/adt/bounded_bitset_test.cc +++ b/lib/test/adt/bounded_bitset_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/adt/bounded_vector_test.cc b/lib/test/adt/bounded_vector_test.cc index 68d547b5d8..9e7f69262c 100644 --- a/lib/test/adt/bounded_vector_test.cc +++ b/lib/test/adt/bounded_vector_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/adt/cached_alloc_test.cc b/lib/test/adt/cached_alloc_test.cc index 8f063982bb..7fded5b3b9 100644 --- a/lib/test/adt/cached_alloc_test.cc +++ b/lib/test/adt/cached_alloc_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/adt/circular_buffer_test.cc b/lib/test/adt/circular_buffer_test.cc index fc4a0104fa..089e946304 100644 --- a/lib/test/adt/circular_buffer_test.cc +++ b/lib/test/adt/circular_buffer_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -27,7 +27,7 @@ namespace srsran { struct C { C() : val_ptr(new int(5)) { count++; } ~C() { count--; } - C(C&& other) : val_ptr(move(other.val_ptr)) { count++; } + C(C&& other) : val_ptr(std::move(other.val_ptr)) { count++; } C& operator=(C&&) = default; std::unique_ptr val_ptr; @@ -275,4 +275,4 @@ int main(int argc, char** argv) srsran::test_queue_block_api_2(); srsran::console("Success\n"); return SRSRAN_SUCCESS; -} \ No newline at end of file +} diff --git a/lib/test/adt/circular_map_test.cc b/lib/test/adt/circular_map_test.cc index a852f8af5c..fb0dc26f07 100644 --- a/lib/test/adt/circular_map_test.cc +++ b/lib/test/adt/circular_map_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/adt/expected_test.cc b/lib/test/adt/expected_test.cc index fcc3934473..ef144f40d2 100644 --- a/lib/test/adt/expected_test.cc +++ b/lib/test/adt/expected_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/adt/fsm_test.cc b/lib/test/adt/fsm_test.cc index 6c33251989..cd6d1ec964 100644 --- a/lib/test/adt/fsm_test.cc +++ b/lib/test/adt/fsm_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/adt/interval_test.cc b/lib/test/adt/interval_test.cc index c85c208065..b21d5c2ee1 100644 --- a/lib/test/adt/interval_test.cc +++ b/lib/test/adt/interval_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/adt/mem_pool_test.cc b/lib/test/adt/mem_pool_test.cc index 764d09e111..b4efd3f7b1 100644 --- a/lib/test/adt/mem_pool_test.cc +++ b/lib/test/adt/mem_pool_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/adt/observer_test.cc b/lib/test/adt/observer_test.cc index 6a7b3b716f..b646b78db2 100644 --- a/lib/test/adt/observer_test.cc +++ b/lib/test/adt/observer_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/adt/optional_array_test.cc b/lib/test/adt/optional_array_test.cc index 4c79a3d02b..3a14ba10f1 100644 --- a/lib/test/adt/optional_array_test.cc +++ b/lib/test/adt/optional_array_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/adt/optional_test.cc b/lib/test/adt/optional_test.cc index 116d7c878d..a9d77cb2ff 100644 --- a/lib/test/adt/optional_test.cc +++ b/lib/test/adt/optional_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -38,7 +38,26 @@ void test_optional_int() TESTASSERT(opt == opt2); } +struct C { + std::unique_ptr val; + + C(int val = 0) : val(std::make_unique(val)) {} +}; + +void test_optional_move_only() +{ + optional a, b; + a.emplace(C{}); + TESTASSERT(a.has_value()); + TESTASSERT_EQ(0, *a.value().val); + TESTASSERT(not b.has_value()); + b.emplace(C{5}); + a = std::move(b); + TESTASSERT_EQ(5, *a.value().val); +} + int main() { test_optional_int(); + test_optional_move_only(); } \ No newline at end of file diff --git a/lib/test/adt/scope_exit_test.cc b/lib/test/adt/scope_exit_test.cc index 28c9116cc9..ead9b1e7be 100644 --- a/lib/test/adt/scope_exit_test.cc +++ b/lib/test/adt/scope_exit_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/adt/span_test.cc b/lib/test/adt/span_test.cc index c30eab9a0b..36ca5c2f4e 100644 --- a/lib/test/adt/span_test.cc +++ b/lib/test/adt/span_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/asn1/CMakeLists.txt b/lib/test/asn1/CMakeLists.txt index 4253218c6e..8882e5a787 100644 --- a/lib/test/asn1/CMakeLists.txt +++ b/lib/test/asn1/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/test/asn1/asn1_utils_test.cc b/lib/test/asn1/asn1_utils_test.cc index 6a680193b0..a7accd6ac7 100644 --- a/lib/test/asn1/asn1_utils_test.cc +++ b/lib/test/asn1/asn1_utils_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -404,7 +404,7 @@ int test_seq_of() cbit_ref borig2(&buf[0], sizeof(buf)); uint32_t fixed_list_size = 33; - std::array fixed_list; + std::array fixed_list = {}; for (uint32_t i = 0; i < fixed_list_size; ++i) { fixed_list[i] = i; } @@ -653,6 +653,21 @@ int test_big_integers() return 0; } +void test_varlength_field_pack() +{ + uint8_t buffer[128]; + bit_ref bref(&buffer[0], sizeof(buffer)); + TESTASSERT_EQ(SRSRAN_SUCCESS, bref.pack(0, 1)); + TESTASSERT_EQ(1, bref.distance()); + { + varlength_field_pack_guard guard(bref); + TESTASSERT_EQ(0, bref.distance()); + bref.pack(0, 8); + TESTASSERT_EQ(1, bref.distance_bytes()); + } + TESTASSERT_EQ(17, bref.distance()); // accounts for length determinant and 1 byte of data +} + int main() { // Setup the log spy to intercept error and warning log entries. @@ -681,6 +696,7 @@ int main() TESTASSERT(test_copy_ptr() == 0); TESTASSERT(test_enum() == 0); TESTASSERT(test_big_integers() == 0); + test_varlength_field_pack(); // TESTASSERT(test_json_writer()==0); srslog::flush(); diff --git a/lib/test/asn1/nas_5g_msg_test.cc b/lib/test/asn1/nas_5g_msg_test.cc index 51d4de0b25..7d8780b0c4 100644 --- a/lib/test/asn1/nas_5g_msg_test.cc +++ b/lib/test/asn1/nas_5g_msg_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/asn1/nas_decoder.cc b/lib/test/asn1/nas_decoder.cc index 12682764f6..e156c66f57 100644 --- a/lib/test/asn1/nas_decoder.cc +++ b/lib/test/asn1/nas_decoder.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/asn1/ngap_test.cc b/lib/test/asn1/ngap_test.cc index 8da16e7086..77c0265f60 100644 --- a/lib/test/asn1/ngap_test.cc +++ b/lib/test/asn1/ngap_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,39 +23,39 @@ #include "srsran/common/test_common.h" using namespace asn1; -using namespace asn1::ngap_nr; +using namespace asn1::ngap; /* TESTS */ int test_amf_upd() { - uint8_t ngap_msg[] = {0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x11}; + uint8_t ngap_msg[] = { + 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x02, 0x80, 0x73, 0x72, 0x73, 0x72, 0x61, 0x6e}; cbit_ref bref(&ngap_msg[0], sizeof(ngap_msg)); - // 0000000A00000100010003000011 + // 0000000F00000100010008028073727372616E ngap_pdu_c pdu; - TESTASSERT(pdu.unpack(bref) == SRSASN_SUCCESS); + TESTASSERT_EQ(SRSASN_SUCCESS, pdu.unpack(bref)); - TESTASSERT(pdu.type().value == ngap_pdu_c::types_opts::init_msg); - TESTASSERT(pdu.init_msg().proc_code == 0); - TESTASSERT(pdu.init_msg().crit.value == crit_opts::reject); + TESTASSERT_EQ(ngap_pdu_c::types_opts::init_msg, pdu.type().value); + TESTASSERT_EQ(0, pdu.init_msg().proc_code); + TESTASSERT_EQ(crit_opts::reject, pdu.init_msg().crit.value); ngap_elem_procs_o::init_msg_c& init_choice = pdu.init_msg().value; - TESTASSERT(init_choice.type().value == ngap_elem_procs_o::init_msg_c::types_opts::amf_cfg_upd); + TESTASSERT_EQ(ngap_elem_procs_o::init_msg_c::types_opts::amf_cfg_upd, init_choice.type().value); amf_cfg_upd_s& amf_upd = init_choice.amf_cfg_upd(); TESTASSERT(not amf_upd.ext); - auto& amf_name = amf_upd.protocol_ies.amf_name; - TESTASSERT(amf_upd.protocol_ies.amf_name_present); - TESTASSERT(amf_name.id == 1); - TESTASSERT(amf_name.crit == crit_opts::reject); - TESTASSERT(amf_name.value.size() == 1); - TESTASSERT(amf_name.value[0] == 17); - - TESTASSERT(ceil(bref.distance_bytes()) == sizeof(ngap_msg)); - TESTASSERT(test_pack_unpack_consistency(pdu) == SRSASN_SUCCESS); + auto& amf_name = amf_upd->amf_name; + TESTASSERT(amf_upd->amf_name_present); + TESTASSERT_EQ(1, amf_name.id); + TESTASSERT_EQ(crit_opts::reject, amf_name.crit); + TESTASSERT_EQ("srsran", amf_name.value.to_string()); + + TESTASSERT_EQ(sizeof(ngap_msg), ceil(bref.distance_bytes())); + TESTASSERT_EQ(SRSASN_SUCCESS, test_pack_unpack_consistency(pdu)); - // json_writer js; - // pdu.to_json(js); - // printf("PDU json: %s\n", js.to_string().c_str()); + json_writer js; + pdu.to_json(js); + printf("PDU json: %s\n", js.to_string().c_str()); return 0; } @@ -79,30 +79,29 @@ int test_ngsetup_request() ng_setup_request_s& ngsetup = pdu.init_msg().value.ng_setup_request(); TESTASSERT(not ngsetup.ext); // Field 0 - TESTASSERT(ngsetup.protocol_ies.global_ran_node_id.id == 27); - TESTASSERT(ngsetup.protocol_ies.global_ran_node_id.crit.value == crit_opts::reject); - TESTASSERT(ngsetup.protocol_ies.global_ran_node_id.value.type().value == - global_ran_node_id_c::types_opts::global_gnb_id); - global_gnb_id_s& global_gnb = ngsetup.protocol_ies.global_ran_node_id.value.global_gnb_id(); + TESTASSERT(ngsetup->global_ran_node_id.id == 27); + TESTASSERT(ngsetup->global_ran_node_id.crit.value == crit_opts::reject); + TESTASSERT(ngsetup->global_ran_node_id.value.type().value == global_ran_node_id_c::types_opts::global_gnb_id); + global_gnb_id_s& global_gnb = ngsetup->global_ran_node_id.value.global_gnb_id(); TESTASSERT(global_gnb.plmn_id.to_number() == 0xF110); TESTASSERT(global_gnb.gnb_id.type().value == gnb_id_c::types_opts::gnb_id); TESTASSERT(global_gnb.gnb_id.gnb_id().to_number() == 1); // Field 1 - TESTASSERT(ngsetup.protocol_ies.ran_node_name_present); + TESTASSERT(ngsetup->ran_node_name_present); // Field 2 - TESTASSERT(ngsetup.protocol_ies.supported_ta_list.id == 102); - TESTASSERT(ngsetup.protocol_ies.supported_ta_list.crit.value == crit_opts::reject); - TESTASSERT(ngsetup.protocol_ies.supported_ta_list.value.size() == 1); - TESTASSERT(ngsetup.protocol_ies.supported_ta_list.value[0].tac.to_number() == 0x75); - TESTASSERT(ngsetup.protocol_ies.supported_ta_list.value[0].broadcast_plmn_list.size() == 1); - auto& bcast_item = ngsetup.protocol_ies.supported_ta_list.value[0].broadcast_plmn_list[0]; + TESTASSERT(ngsetup->supported_ta_list.id == 102); + TESTASSERT(ngsetup->supported_ta_list.crit.value == crit_opts::reject); + TESTASSERT(ngsetup->supported_ta_list.value.size() == 1); + TESTASSERT(ngsetup->supported_ta_list.value[0].tac.to_number() == 0x75); + TESTASSERT(ngsetup->supported_ta_list.value[0].broadcast_plmn_list.size() == 1); + auto& bcast_item = ngsetup->supported_ta_list.value[0].broadcast_plmn_list[0]; TESTASSERT(bcast_item.plmn_id.to_number() == 0xF110); TESTASSERT(bcast_item.tai_slice_support_list.size()); TESTASSERT(bcast_item.tai_slice_support_list[0].s_nssai.sst.to_number() == 1); // Field 3 - TESTASSERT(ngsetup.protocol_ies.default_paging_drx.id == 21); - TESTASSERT(ngsetup.protocol_ies.default_paging_drx.crit.value == crit_opts::ignore); - TESTASSERT(ngsetup.protocol_ies.default_paging_drx.value.value == paging_drx_opts::v256); + TESTASSERT(ngsetup->default_paging_drx.id == 21); + TESTASSERT(ngsetup->default_paging_drx.crit.value == crit_opts::ignore); + TESTASSERT(ngsetup->default_paging_drx.value.value == paging_drx_opts::v256); TESTASSERT(ceil(bref.distance(ngap_msg) / 8.0) == sizeof(ngap_msg)); TESTASSERT(test_pack_unpack_consistency(pdu) == SRSASN_SUCCESS); @@ -137,19 +136,18 @@ int test_ngsetup_response() ngap_elem_procs_o::successful_outcome_c::types_opts::ng_setup_resp); ng_setup_resp_s& resp = pdu.successful_outcome().value.ng_setup_resp(); // field 0 - TESTASSERT(resp.protocol_ies.amf_name.id == 1); - TESTASSERT(resp.protocol_ies.amf_name.crit.value == crit_opts::reject); - TESTASSERT(resp.protocol_ies.amf_name.value.size() == 56); - TESTASSERT(resp.protocol_ies.amf_name.value.to_string() == - "amf1.cluster1.net2.amf.5gc.mnc001.mcc001.3gppnetwork.org"); + TESTASSERT(resp->amf_name.id == 1); + TESTASSERT(resp->amf_name.crit.value == crit_opts::reject); + TESTASSERT(resp->amf_name.value.size() == 56); + TESTASSERT(resp->amf_name.value.to_string() == "amf1.cluster1.net2.amf.5gc.mnc001.mcc001.3gppnetwork.org"); // field 1 - TESTASSERT(resp.protocol_ies.served_guami_list.id == 96); - TESTASSERT(resp.protocol_ies.served_guami_list.crit.value == crit_opts::reject); - TESTASSERT(resp.protocol_ies.served_guami_list.value.size() == 1); - TESTASSERT(resp.protocol_ies.served_guami_list.value[0].guami.plmn_id.to_number() == 0xF110); - TESTASSERT(resp.protocol_ies.served_guami_list.value[0].guami.amf_region_id.to_number() == 0b111000); - TESTASSERT(resp.protocol_ies.served_guami_list.value[0].guami.amf_set_id.to_number() == 0b100010); - TESTASSERT(resp.protocol_ies.served_guami_list.value[0].guami.amf_pointer.to_number() == 0b10111); + TESTASSERT(resp->served_guami_list.id == 96); + TESTASSERT(resp->served_guami_list.crit.value == crit_opts::reject); + TESTASSERT(resp->served_guami_list.value.size() == 1); + TESTASSERT(resp->served_guami_list.value[0].guami.plmn_id.to_number() == 0xF110); + TESTASSERT(resp->served_guami_list.value[0].guami.amf_region_id.to_number() == 0b111000); + TESTASSERT(resp->served_guami_list.value[0].guami.amf_set_id.to_number() == 0b100010); + TESTASSERT(resp->served_guami_list.value[0].guami.amf_pointer.to_number() == 0b10111); // field 2 // ... @@ -181,7 +179,7 @@ int test_init_ue_msg() TESTASSERT(pdu.init_msg().proc_code == 15); TESTASSERT(pdu.init_msg().crit.value == crit_opts::ignore); TESTASSERT(pdu.init_msg().value.type().value == ngap_elem_procs_o::init_msg_c::types_opts::init_ue_msg); - auto& container = pdu.init_msg().value.init_ue_msg().protocol_ies; + auto& container = *pdu.init_msg().value.init_ue_msg(); // Field 0 TESTASSERT(container.ran_ue_ngap_id.id == 85); TESTASSERT(container.ran_ue_ngap_id.crit.value == crit_opts::reject); @@ -220,7 +218,40 @@ int test_dl_nas_transport() // Field 0 // ... // Field 1 - TESTASSERT(dl_nas.protocol_ies.nas_pdu.value.size() == 42); + TESTASSERT(dl_nas->nas_pdu.value.size() == 42); + + TESTASSERT(ceil(bref.distance(ngap_msg) / 8.0) == sizeof(ngap_msg)); + TESTASSERT(test_pack_unpack_consistency(pdu) == SRSASN_SUCCESS); + return 0; +} + +// DL NAS transport with AMF-UE-NGAP-ID larger than 32bit +int test_dl_nas_transport2() +{ + uint8_t ngap_msg[] = {0x00, 0x04, 0x40, 0x42, 0x00, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x06, 0x80, 0x03, 0x03, + 0xcf, 0x37, 0xd0, 0x00, 0x55, 0x00, 0x02, 0x00, 0x01, 0x00, 0x26, 0x00, 0x2b, 0x2a, + 0x7e, 0x00, 0x56, 0x00, 0x02, 0x00, 0x00, 0x21, 0xbc, 0x8d, 0xe5, 0x61, 0xf5, 0xb4, + 0xa7, 0x05, 0x8f, 0xdb, 0xe2, 0x3b, 0x4e, 0x21, 0xda, 0x45, 0x20, 0x10, 0x5a, 0xb8, + 0xd1, 0xdb, 0x13, 0x76, 0x80, 0x00, 0x1b, 0x1a, 0x8d, 0x3c, 0x98, 0x4c, 0x01, 0x06}; + // 00044042000003000a0006800303cf37d00055000200010026002b2a7e00560002000021bc8de561f5b4a7058fdbe23b4e21da4520105ab8d1db137680001b1a8d3c984c0106 + + cbit_ref bref(ngap_msg, sizeof(ngap_msg)); + ngap_pdu_c pdu; + TESTASSERT(pdu.unpack(bref) == SRSASN_SUCCESS); + + // Check Fields + TESTASSERT(pdu.type().value == ngap_pdu_c::types_opts::init_msg); + TESTASSERT(pdu.init_msg().proc_code == ASN1_NGAP_ID_DL_NAS_TRANSPORT); + TESTASSERT(pdu.init_msg().crit.value == crit_opts::ignore); + TESTASSERT(pdu.init_msg().value.type().value == ngap_elem_procs_o::init_msg_c::types_opts::dl_nas_transport); + + auto& dl_nas = pdu.init_msg().value.dl_nas_transport(); + // Field 0 + TESTASSERT_EQ(12948813776, dl_nas->amf_ue_ngap_id.value); + + // ... + // Field 2 + TESTASSERT(dl_nas->nas_pdu.value.size() == 42); TESTASSERT(ceil(bref.distance(ngap_msg) / 8.0) == sizeof(ngap_msg)); TESTASSERT(test_pack_unpack_consistency(pdu) == SRSASN_SUCCESS); @@ -246,7 +277,7 @@ int test_ul_ran_status_transfer() TESTASSERT(pdu.init_msg().value.type().value == ngap_elem_procs_o::init_msg_c::types_opts::ul_nas_transport); auto& ul_nas = pdu.init_msg().value.ul_nas_transport(); // Field 1 - TESTASSERT(ul_nas.protocol_ies.nas_pdu.value.size() == 21); + TESTASSERT(ul_nas->nas_pdu.value.size() == 21); TESTASSERT(ceil(bref.distance(ngap_msg) / 8.0) == sizeof(ngap_msg)); TESTASSERT(test_pack_unpack_consistency(pdu) == SRSASN_SUCCESS); @@ -317,10 +348,10 @@ int test_session_res_setup_request() TESTASSERT(pdu.init_msg().crit.value == crit_opts::reject); TESTASSERT(pdu.init_msg().value.type().value == ngap_elem_procs_o::init_msg_c::types_opts::pdu_session_res_setup_request); - auto& container = pdu.init_msg().value.pdu_session_res_setup_request().protocol_ies; - TESTASSERT(container.pdu_session_res_setup_list_su_req.id == ASN1_NGAP_NR_ID_PDU_SESSION_RES_SETUP_LIST_SU_REQ); - TESTASSERT(container.pdu_session_res_setup_list_su_req.value.size() == 1); - auto& item = container.pdu_session_res_setup_list_su_req.value[0]; + auto& container = pdu.init_msg().value.pdu_session_res_setup_request(); + TESTASSERT(container->pdu_session_res_setup_list_su_req.id == ASN1_NGAP_ID_PDU_SESSION_RES_SETUP_LIST_SU_REQ); + TESTASSERT(container->pdu_session_res_setup_list_su_req.value.size() == 1); + auto& item = container->pdu_session_res_setup_list_su_req.value[0]; TESTASSERT(item.pdu_session_id == 1); TESTASSERT(item.s_nssai.sst.to_number() == 0); TESTASSERT(item.pdu_session_res_setup_request_transfer.to_string() == @@ -330,10 +361,9 @@ int test_session_res_setup_request() item.pdu_session_res_setup_request_transfer.size()); pdu_session_res_setup_request_transfer_s req; TESTASSERT(req.unpack(bref2) == SRSASN_SUCCESS); - TESTASSERT(req.protocol_ies.ul_ngu_up_tnl_info.id == 139); - TESTASSERT(req.protocol_ies.ul_ngu_up_tnl_info.value.type().value == - up_transport_layer_info_c::types_opts::gtp_tunnel); - TESTASSERT(req.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().transport_layer_address.to_string() == + TESTASSERT(req->ul_ngu_up_tnl_info.id == 139); + TESTASSERT(req->ul_ngu_up_tnl_info.value.type().value == up_transport_layer_info_c::types_opts::gtp_tunnel); + TESTASSERT(req->ul_ngu_up_tnl_info.value.gtp_tunnel().transport_layer_address.to_string() == "11000000101010000001000111010010"); TESTASSERT(bref2.distance_bytes() == (int)item.pdu_session_res_setup_request_transfer.size()); @@ -353,15 +383,16 @@ int main() // Start the log backend. srslog::init(); - TESTASSERT(test_amf_upd() == 0); - TESTASSERT(test_ngsetup_request() == 0); - TESTASSERT(test_ngsetup_response() == 0); - TESTASSERT(test_init_ue_msg() == 0); - TESTASSERT(test_dl_nas_transport() == 0); - TESTASSERT(test_ul_ran_status_transfer() == 0); - TESTASSERT(test_ue_context_release() == 0); - TESTASSERT(test_ue_context_release_complete() == 0); - TESTASSERT(test_session_res_setup_request() == 0); + test_amf_upd(); + test_ngsetup_request(); + test_ngsetup_response(); + test_init_ue_msg(); + test_dl_nas_transport(); + test_dl_nas_transport2(); + test_ul_ran_status_transfer(); + test_ue_context_release(); + test_ue_context_release_complete(); + test_session_res_setup_request(); srslog::flush(); diff --git a/lib/test/asn1/rrc_asn1_decoder.cc b/lib/test/asn1/rrc_asn1_decoder.cc index 46cd15db46..1bed698366 100644 --- a/lib/test/asn1/rrc_asn1_decoder.cc +++ b/lib/test/asn1/rrc_asn1_decoder.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/asn1/rrc_nr_utils_test.cc b/lib/test/asn1/rrc_nr_utils_test.cc index 2b0ef0bb91..9f551bce1a 100644 --- a/lib/test/asn1/rrc_nr_utils_test.cc +++ b/lib/test/asn1/rrc_nr_utils_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -44,7 +44,8 @@ int test_rlc_config() srslog::fetch_basic_logger("RRC").info("RLC NR Config: \n %s", jw.to_string().c_str()); rlc_config_t rlc_cfg; - TESTASSERT(make_rlc_config_t(rlc_cfg_asn1, &rlc_cfg) == SRSRAN_SUCCESS); + // We hard-code the bearer_id=1 and rb_type=DRB + TESTASSERT(make_rlc_config_t(rlc_cfg_asn1, /* bearer_id */ 1, &rlc_cfg) == SRSRAN_SUCCESS); TESTASSERT(rlc_cfg.rat == srsran_rat_t::nr); TESTASSERT(rlc_cfg.um_nr.sn_field_length == rlc_um_nr_sn_size_t::size12bits); return SRSRAN_SUCCESS; @@ -66,13 +67,14 @@ int test_mac_rach_common_config() rach_common_config_asn1.to_json(jw); srslog::fetch_basic_logger("RRC").info("MAC NR RACH Common config: \n %s", jw.to_string().c_str()); - rach_nr_cfg_t rach_nr_cfg = make_mac_rach_cfg(rach_common_config_asn1); - TESTASSERT(rach_nr_cfg.ra_responseWindow == 10); - TESTASSERT(rach_nr_cfg.ra_ContentionResolutionTimer == 64); - TESTASSERT(rach_nr_cfg.prach_ConfigurationIndex == 160); - TESTASSERT(rach_nr_cfg.PreambleReceivedTargetPower == -110); - TESTASSERT(rach_nr_cfg.preambleTransMax == 7); - TESTASSERT(rach_nr_cfg.powerRampingStep == 4); + rach_cfg_nr_t rach_cfg_nr = {}; + make_mac_rach_cfg(rach_common_config_asn1, &rach_cfg_nr); + TESTASSERT(rach_cfg_nr.ra_responseWindow == 10); + TESTASSERT(rach_cfg_nr.ra_ContentionResolutionTimer == 64); + TESTASSERT(rach_cfg_nr.prach_ConfigurationIndex == 160); + TESTASSERT(rach_cfg_nr.PreambleReceivedTargetPower == -110); + TESTASSERT(rach_cfg_nr.preambleTransMax == 7); + TESTASSERT(rach_cfg_nr.powerRampingStep == 4); return SRSRAN_SUCCESS; } @@ -676,6 +678,179 @@ int make_phy_nzp_csi_rs_resource_test() return SRSRAN_SUCCESS; } +int fill_phy_pdsch_cfg_common_test() +{ + // "pdsch-ConfigCommon": + // "setup": + // "pdsch-TimeDomainAllocationList": [ + // "mappingType": "typeA", + // "startSymbolAndLength": 40 + // ] + + asn1::rrc_nr::pdsch_cfg_common_s pdsch_cfg = {}; + pdsch_cfg.pdsch_time_domain_alloc_list.resize(1); + pdsch_cfg.pdsch_time_domain_alloc_list[0].map_type = + asn1::rrc_nr::pdsch_time_domain_res_alloc_s::map_type_opts::options::type_a; + pdsch_cfg.pdsch_time_domain_alloc_list[0].k0_present = false; + pdsch_cfg.pdsch_time_domain_alloc_list[0].start_symbol_and_len = 40; + + srsran_sch_hl_cfg_nr_t pdsch; + fill_phy_pdsch_cfg_common(pdsch_cfg, &pdsch); + + TESTASSERT(pdsch.nof_common_time_ra == 1); + TESTASSERT(pdsch.common_time_ra[0].k == 0); + TESTASSERT(pdsch.common_time_ra[0].mapping_type == srsran_sch_mapping_type_A); + TESTASSERT(pdsch.common_time_ra[0].sliv == 40); + + return SRSRAN_SUCCESS; +} + +int fill_phy_pucch_cfg_common_test() +{ + // "pucch-ConfigCommon": + // "setup": + // "pucch-ResourceCommon": 11, + // "pucch-GroupHopping": "neither", + // "p0-nominal": -90 + + asn1::rrc_nr::pucch_cfg_common_s pucch_cfg = {}; + pucch_cfg.pucch_res_common_present = true; + pucch_cfg.pucch_res_common = 11; + pucch_cfg.hop_id_present = false; + pucch_cfg.p0_nominal_present = true; + pucch_cfg.p0_nominal = -90; + pucch_cfg.pucch_group_hop = pucch_cfg_common_s::pucch_group_hop_opts::neither; + + srsran_pucch_nr_common_cfg_t pucch = {}; + fill_phy_pucch_cfg_common(pucch_cfg, &pucch); + + TESTASSERT(pucch.resource_common == 11); + TESTASSERT(pucch.p0_nominal == -90); + TESTASSERT(pucch.group_hopping == SRSRAN_PUCCH_NR_GROUP_HOPPING_NEITHER); + + return SRSRAN_SUCCESS; +} + +int fill_phy_pusch_cfg_common_test() +{ + // "pusch-ConfigCommon": + // "setup": { + // "pusch-TimeDomainAllocationList": [ + // "k2": 4, + // "mappingType": "typeA", + // "startSymbolAndLength": 27 + // ], + // "p0-NominalWithGrant": -76 + + asn1::rrc_nr::pusch_cfg_common_s pusch_cfg = {}; + pusch_cfg.pusch_time_domain_alloc_list.resize(1); + pusch_cfg.pusch_time_domain_alloc_list[0].map_type = + asn1::rrc_nr::pusch_time_domain_res_alloc_s::map_type_opts::options::type_a; + pusch_cfg.pusch_time_domain_alloc_list[0].k2_present = true; + pusch_cfg.pusch_time_domain_alloc_list[0].k2 = 4; + pusch_cfg.pusch_time_domain_alloc_list[0].start_symbol_and_len = 27; + pusch_cfg.p0_nominal_with_grant_present = true; + pusch_cfg.p0_nominal_with_grant = -76; + + srsran_sch_hl_cfg_nr_t pusch; + fill_phy_pusch_cfg_common(pusch_cfg, &pusch); + + TESTASSERT(pusch.nof_common_time_ra == 1); + TESTASSERT(pusch.common_time_ra[0].k == 4); + TESTASSERT(pusch.common_time_ra[0].mapping_type == srsran_sch_mapping_type_A); + TESTASSERT(pusch.common_time_ra[0].sliv == 27); + + return SRSRAN_SUCCESS; +} + +int fill_phy_carrier_cfg_test() +{ + // "frequencyInfoDL": + // "frequencyBandList": [ + // "freqBandIndicatorNR": 3 + // ], + // "offsetToPointA": 13, + // "scs-SpecificCarrierList": [ + // "offsetToCarrier": 0, + // "subcarrierSpacing": "kHz15", + // "carrierBandwidth": 52 + // ] + // + // ... + // + // "frequencyInfoUL": + // "frequencyBandList": [ + // "freqBandIndicatorNR": 3 + // ], + // "absoluteFrequencyPointA": 348564, + // "scs-SpecificCarrierList": [ + // "offsetToCarrier": 0, + // "subcarrierSpacing": "kHz15", + // "carrierBandwidth": 52 + // ], + // "p-Max": 10 + + asn1::rrc_nr::serving_cell_cfg_common_sib_s serv_cell_cfg = {}; + serv_cell_cfg.dl_cfg_common.freq_info_dl.freq_band_list.resize(1); + serv_cell_cfg.dl_cfg_common.freq_info_dl.freq_band_list[0].freq_band_ind_nr_present = true; + serv_cell_cfg.dl_cfg_common.freq_info_dl.freq_band_list[0].freq_band_ind_nr = 3; + serv_cell_cfg.dl_cfg_common.freq_info_dl.offset_to_point_a = 13; + serv_cell_cfg.dl_cfg_common.freq_info_dl.scs_specific_carrier_list.resize(1); + serv_cell_cfg.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].offset_to_carrier = 0; + serv_cell_cfg.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].subcarrier_spacing = + asn1::rrc_nr::subcarrier_spacing_opts::options::khz15; + serv_cell_cfg.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].carrier_bw = 52; + + serv_cell_cfg.ul_cfg_common.freq_info_ul.freq_band_list.resize(1); + serv_cell_cfg.ul_cfg_common.freq_info_ul.freq_band_list[0].freq_band_ind_nr_present = true; + serv_cell_cfg.ul_cfg_common.freq_info_ul.freq_band_list[0].freq_band_ind_nr = 3; + serv_cell_cfg.ul_cfg_common.freq_info_ul.absolute_freq_point_a_present = true; + serv_cell_cfg.ul_cfg_common.freq_info_ul.absolute_freq_point_a = 348564; + serv_cell_cfg.ul_cfg_common.freq_info_ul.scs_specific_carrier_list.resize(1); + serv_cell_cfg.ul_cfg_common.freq_info_ul.scs_specific_carrier_list[0].offset_to_carrier = 0; + serv_cell_cfg.ul_cfg_common.freq_info_ul.scs_specific_carrier_list[0].subcarrier_spacing = + asn1::rrc_nr::subcarrier_spacing_opts::options::khz15; + serv_cell_cfg.ul_cfg_common.freq_info_ul.scs_specific_carrier_list[0].carrier_bw = 52; + serv_cell_cfg.ul_cfg_common.freq_info_ul.p_max_present = true; + serv_cell_cfg.ul_cfg_common.freq_info_ul.p_max = 10; + + srsran_carrier_nr_t carrier_nr = {}; + fill_phy_carrier_cfg(serv_cell_cfg, &carrier_nr); + + TESTASSERT(carrier_nr.offset_to_carrier == 0); + TESTASSERT(carrier_nr.scs == srsran_subcarrier_spacing_15kHz); + TESTASSERT(carrier_nr.nof_prb == 52); + TESTASSERT(carrier_nr.ul_center_frequency_hz == 1747.5e6); + + return SRSRAN_SUCCESS; +} + +int fill_phy_ssb_cfg_test() +{ + // "ssb-PositionsInBurst": + // "inOneGroup": "10000000" + // "ssb-PeriodicityServingCell": "ms20", + + asn1::rrc_nr::serving_cell_cfg_common_sib_s serv_cell_cfg = {}; + serv_cell_cfg.ssb_periodicity_serving_cell = + asn1::rrc_nr::serving_cell_cfg_common_sib_s::ssb_periodicity_serving_cell_opts::options::ms20; + serv_cell_cfg.ssb_positions_in_burst.group_presence_present = false; + serv_cell_cfg.ssb_positions_in_burst.in_one_group.from_number(128); + + phy_cfg_nr_t::ssb_cfg_t ssb = {}; + fill_phy_ssb_cfg(serv_cell_cfg, &ssb); + + TESTASSERT(ssb.periodicity_ms == 20); + + uint64_t position_in_burst = 0; + for (uint64_t i = 0; i < 8; i++) { + position_in_burst = position_in_burst << 1 | ssb.position_in_burst[i]; + } + TESTASSERT(position_in_burst == 128); + + return SRSRAN_SUCCESS; +} + int main() { auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); @@ -704,6 +879,11 @@ int main() TESTASSERT(make_phy_pusch_scaling_test() == SRSRAN_SUCCESS); TESTASSERT(make_phy_zp_csi_rs_resource_test() == SRSRAN_SUCCESS); TESTASSERT(make_phy_nzp_csi_rs_resource_test() == SRSRAN_SUCCESS); + TESTASSERT(fill_phy_pdsch_cfg_common_test() == SRSRAN_SUCCESS); + TESTASSERT(fill_phy_pucch_cfg_common_test() == SRSRAN_SUCCESS); + TESTASSERT(fill_phy_pusch_cfg_common_test() == SRSRAN_SUCCESS); + TESTASSERT(fill_phy_carrier_cfg_test() == SRSRAN_SUCCESS); + TESTASSERT(fill_phy_ssb_cfg_test() == SRSRAN_SUCCESS); srslog::flush(); printf("Success\n"); diff --git a/lib/test/asn1/rrc_test.cc b/lib/test/asn1/rrc_test.cc index d24fffe7c6..f68e92822b 100644 --- a/lib/test/asn1/rrc_test.cc +++ b/lib/test/asn1/rrc_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -143,7 +143,8 @@ int test_mib_msg() TESTASSERT(bcch_msg.sys_frame_num == "00011001"); TESTASSERT(bcch_msg.sched_info_sib1_br_r13 == 6); TESTASSERT(not bcch_msg.sys_info_unchanged_br_r15); - TESTASSERT(bcch_msg.spare == "0000"); + TESTASSERT(bcch_msg.part_earfcn_minus17.type().value == asn1::rrc::mib_s::part_earfcn_minus17_c_::types_opts::spare); + TESTASSERT(bcch_msg.spare == "0"); TESTASSERT((uint32_t)bref.distance(bref0) / 8 == rrc_msg_len); @@ -167,7 +168,7 @@ int test_bcch_dl_sch_msg() { // 000149001250400800094000A03F01000A7FC9800104286C000C uint8_t rrc_msg[] = {0x00, 0x01, 0x49, 0x00, 0x12, 0x50, 0x40, 0x08, 0x00, 0x09, 0x40, 0x00, 0xA0, - 0x3F, 0x01, 0x00, 0x0A, 0x7F, 0xC9, 0x80, 0x01, 0x04, 0x28, 0x6C, 0x00, 0x0C}; + 0x3F, 0x01, 0x00, 0x0A, 0x7F, 0xC9, 0x80, 0x01, 0x04, 0x28, 0x6C, 0x00, 0x0C}; uint32_t rrc_msg_len = sizeof(rrc_msg); cbit_ref bref(&rrc_msg[0], sizeof(rrc_msg)); cbit_ref bref0(&rrc_msg[0], sizeof(rrc_msg)); @@ -279,8 +280,8 @@ int test_bcch_dl_sch_msg3() { // 00830992B7EC9300A3424B000C000500205D6AAAF04200C01DDC801C4880030010A713228500 uint8_t rrc_msg[] = {0x00, 0x83, 0x09, 0x92, 0xB7, 0xEC, 0x93, 0x00, 0xA3, 0x42, 0x4B, 0x00, 0x0C, - 0x00, 0x05, 0x00, 0x20, 0x5D, 0x6A, 0xAA, 0xF0, 0x42, 0x00, 0xC0, 0x1D, 0xDC, - 0x80, 0x1C, 0x48, 0x80, 0x03, 0x00, 0x10, 0xA7, 0x13, 0x22, 0x85, 0x00}; + 0x00, 0x05, 0x00, 0x20, 0x5D, 0x6A, 0xAA, 0xF0, 0x42, 0x00, 0xC0, 0x1D, 0xDC, + 0x80, 0x1C, 0x48, 0x80, 0x03, 0x00, 0x10, 0xA7, 0x13, 0x22, 0x85, 0x00}; uint32_t rrc_msg_len = sizeof(rrc_msg); cbit_ref bref(&rrc_msg[0], sizeof(rrc_msg)); diff --git a/lib/test/asn1/s1ap_test.cc b/lib/test/asn1/s1ap_test.cc index 29d19037cb..360705b2de 100644 --- a/lib/test/asn1/s1ap_test.cc +++ b/lib/test/asn1/s1ap_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -48,10 +48,10 @@ int test_s1setup_request() TESTASSERT(init_choice.type().value == s1ap_elem_procs_o::init_msg_c::types_opts::s1_setup_request); s1_setup_request_s& s1req = init_choice.s1_setup_request(); TESTASSERT(not s1req.ext); - TESTASSERT(s1req.protocol_ies.global_enb_id.id == ASN1_S1AP_ID_GLOBAL_ENB_ID); - TESTASSERT(s1req.protocol_ies.global_enb_id.crit.value == crit_opts::reject); - TESTASSERT(s1req.protocol_ies.global_enb_id.value.enb_id.type().value == enb_id_c::types_opts::macro_enb_id); - TESTASSERT(s1req.protocol_ies.global_enb_id.value.enb_id.macro_enb_id().to_number() == 0x0019B); + TESTASSERT(s1req->global_enb_id.id == ASN1_S1AP_ID_GLOBAL_ENB_ID); + TESTASSERT(s1req->global_enb_id.crit.value == crit_opts::reject); + TESTASSERT(s1req->global_enb_id.value.enb_id.type().value == enb_id_c::types_opts::macro_enb_id); + TESTASSERT(s1req->global_enb_id.value.enb_id.macro_enb_id().to_number() == 0x0019B); // // // json_writer js; // // pdu.to_json(js); @@ -86,10 +86,10 @@ int test_init_ctxt_setup_req() TESTASSERT(pdu.init_msg().proc_code == 9); TESTASSERT(pdu.init_msg().crit.value == crit_opts::reject); s1ap_elem_procs_o::init_msg_c& init_choice = pdu.init_msg().value; - auto& ctxt_setup = init_choice.init_context_setup_request().protocol_ies; - TESTASSERT(ctxt_setup.ue_security_cap.id == 107); - TESTASSERT(ctxt_setup.ue_security_cap.value.encryption_algorithms.to_string() == "1100000000000000"); - TESTASSERT(ctxt_setup.ue_security_cap.value.integrity_protection_algorithms.to_string() == "1100000000000000"); + auto& ctxt_setup = init_choice.init_context_setup_request(); + TESTASSERT(ctxt_setup->ue_security_cap.id == 107); + TESTASSERT(ctxt_setup->ue_security_cap.value.encryption_algorithms.to_string() == "1100000000000000"); + TESTASSERT(ctxt_setup->ue_security_cap.value.integrity_protection_algorithms.to_string() == "1100000000000000"); TESTASSERT(test_pack_unpack_consistency(pdu) == SRSASN_SUCCESS); @@ -108,11 +108,11 @@ int test_ue_ctxt_release_req() TESTASSERT(pdu.type().value == s1ap_pdu_c::types_opts::init_msg); TESTASSERT(pdu.init_msg().proc_code == ASN1_S1AP_ID_UE_CONTEXT_RELEASE_REQUEST); - auto& req = pdu.init_msg().value.ue_context_release_request().protocol_ies; - TESTASSERT(req.mme_ue_s1ap_id.value.value == 1); - TESTASSERT(req.enb_ue_s1ap_id.value.value == 1); - TESTASSERT(req.cause.value.type().value == cause_c::types_opts::radio_network); - TESTASSERT(req.cause.value.radio_network().value == cause_radio_network_opts::user_inactivity); + auto& req = pdu.init_msg().value.ue_context_release_request(); + TESTASSERT(req->mme_ue_s1ap_id.value.value == 1); + TESTASSERT(req->enb_ue_s1ap_id.value.value == 1); + TESTASSERT(req->cause.value.type().value == cause_c::types_opts::radio_network); + TESTASSERT(req->cause.value.radio_network().value == cause_radio_network_opts::user_inactivity); TESTASSERT(test_pack_unpack_consistency(pdu) == SRSASN_SUCCESS); @@ -187,9 +187,9 @@ int test_ho_request() TESTASSERT(pdu.type().value == s1ap_pdu_c::types_opts::init_msg); TESTASSERT(pdu.init_msg().proc_code == ASN1_S1AP_ID_HO_RES_ALLOC); TESTASSERT(pdu.init_msg().crit.value == crit_opts::reject); - auto& horeq = pdu.init_msg().value.ho_request().protocol_ies; + auto& horeq = pdu.init_msg().value.ho_request(); - auto& erab_item = horeq.erab_to_be_setup_list_ho_req.value[0].value.erab_to_be_setup_item_ho_req(); + auto& erab_item = horeq->erab_to_be_setup_list_ho_req.value[0]->erab_to_be_setup_item_ho_req(); TESTASSERT(erab_item.erab_id == 5); TESTASSERT(erab_item.gtp_teid.to_string() == "b7361c56"); @@ -203,15 +203,16 @@ int test_enb_status_transfer() s1ap_pdu_c pdu; TESTASSERT(pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_ENB_STATUS_TRANSFER)); - auto& enb_status_transfer = pdu.init_msg().value.enb_status_transfer().protocol_ies; - enb_status_transfer.mme_ue_s1ap_id.value.value = 1; - enb_status_transfer.enb_ue_s1ap_id.value.value = 1; - enb_status_transfer.enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list.resize(1); + auto& enb_status_transfer = pdu.init_msg().value.enb_status_transfer(); + enb_status_transfer->mme_ue_s1ap_id.value.value = 1; + enb_status_transfer->enb_ue_s1ap_id.value.value = 1; + enb_status_transfer->enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list.resize( + 1); auto& bearer = - enb_status_transfer.enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list[0]; + enb_status_transfer->enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list[0]; TESTASSERT(bearer.load_info_obj(ASN1_S1AP_ID_BEARERS_SUBJECT_TO_STATUS_TRANSFER_ITEM)); - auto& bearer_item = bearer.value.bearers_subject_to_status_transfer_item(); + auto& bearer_item = bearer->bearers_subject_to_status_transfer_item(); bearer_item.erab_id = 5; bearer_item.dl_coun_tvalue.pdcp_sn = 5; @@ -230,11 +231,10 @@ int test_enb_status_transfer() s1ap_pdu_c pdu2; TESTASSERT(pdu2.unpack(bref2) == SRSASN_SUCCESS); - auto& bearer2 = - pdu2.init_msg() - .value.enb_status_transfer() - .protocol_ies.enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list[0]; - auto& bearer_item2 = bearer2.value.bearers_subject_to_status_transfer_item(); + auto& bearer2 = pdu2.init_msg() + .value.enb_status_transfer() + ->enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list[0]; + auto& bearer_item2 = bearer2->bearers_subject_to_status_transfer_item(); TESTASSERT(bearer_item2.dl_coun_tvalue.hfn == bearer_item.dl_coun_tvalue.hfn); TESTASSERT(bearer_item2.dl_coun_tvalue.hfn == 0); @@ -264,7 +264,7 @@ int test_load_info_obj() container.erab_failed_to_setup_list_ctxt_su_res.value.resize(1); container.erab_failed_to_setup_list_ctxt_su_res.value[0].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); - TESTASSERT(container.erab_failed_to_setup_list_ctxt_su_res.value[0].id == ASN1_S1AP_ID_ERAB_ITEM); + TESTASSERT_EQ(ASN1_S1AP_ID_ERAB_ITEM, container.erab_failed_to_setup_list_ctxt_su_res.value[0].id()); return SRSRAN_SUCCESS; } @@ -276,15 +276,15 @@ int test_initial_ctxt_setup_response() tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_INIT_CONTEXT_SETUP); // Fill in the MME and eNB IDs - auto& container = tx_pdu.successful_outcome().value.init_context_setup_resp().protocol_ies; - container.mme_ue_s1ap_id.value = 1; - container.enb_ue_s1ap_id.value = 1; + auto& container = tx_pdu.successful_outcome().value.init_context_setup_resp(); + container->mme_ue_s1ap_id.value = 1; + container->enb_ue_s1ap_id.value = 1; - container.erab_setup_list_ctxt_su_res.value.resize(1); + container->erab_setup_list_ctxt_su_res.value.resize(1); // Fill in the GTP bind address for all bearers - for (uint32_t i = 0; i < container.erab_setup_list_ctxt_su_res.value.size(); ++i) { - container.erab_setup_list_ctxt_su_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_CTXT_SU_RES); - auto& item = container.erab_setup_list_ctxt_su_res.value[i].value.erab_setup_item_ctxt_su_res(); + for (uint32_t i = 0; i < container->erab_setup_list_ctxt_su_res.value.size(); ++i) { + container->erab_setup_list_ctxt_su_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_CTXT_SU_RES); + auto& item = container->erab_setup_list_ctxt_su_res.value[i]->erab_setup_item_ctxt_su_res(); item.erab_id = 1; // uint32_to_uint8(teid_in, item.gtp_teid.data()); item.transport_layer_address.resize(32); diff --git a/lib/test/asn1/srsran_asn1_nas_test.cc b/lib/test/asn1/srsran_asn1_nas_test.cc index ec2df32a80..3c0ec4d4cd 100644 --- a/lib/test/asn1/srsran_asn1_nas_test.cc +++ b/lib/test/asn1/srsran_asn1_nas_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,19 +20,12 @@ */ #include "srsran/asn1/liblte_mme.h" +#include "srsran/common/test_common.h" #include "srsran/srslog/srslog.h" #include #include #include -#define TESTASSERT(cond) \ - { \ - if (!(cond)) { \ - std::cout << "[" << __FUNCTION__ << "][Line " << __LINE__ << "]: FAIL at " << (#cond) << std::endl; \ - return -1; \ - } \ - } - int nas_dedicated_eps_bearer_context_setup_request_test() { auto& nas_logger = srslog::fetch_basic_logger("NAS", false); @@ -112,7 +105,95 @@ int nas_dedicated_eps_bearer_context_setup_request_test() srslog::flush(); printf("Test NAS Activate Dedicated EPS Bearer Context Request successfull\n"); - return 0; + return SRSRAN_SUCCESS; +} + +int downlink_generic_nas_transport_unpacking_test() +{ + uint8_t nas_message[] = { + 0x27, 0xae, 0x80, 0xc8, 0xf9, 0x06, 0x07, 0x68, 0x01, 0x00, 0x06, 0xf0, 0x00, 0x00, 0x00, 0x08, 0x70}; + srsran::unique_byte_buffer_t buf; + LIBLTE_MME_DOWNLINK_GENERIC_NAS_TRANSPORT_MSG_STRUCT dl_generic_nas_transport; + LIBLTE_ERROR_ENUM err; + + copy_msg_to_buffer(buf, nas_message); + err = liblte_mme_unpack_downlink_generic_nas_transport_msg((LIBLTE_BYTE_MSG_STRUCT*)buf.get(), + &dl_generic_nas_transport); + TESTASSERT(err == LIBLTE_SUCCESS); + TESTASSERT(dl_generic_nas_transport.generic_msg_cont_type == 1); + TESTASSERT(dl_generic_nas_transport.generic_msg_cont.N_bytes == 6); + TESTASSERT(dl_generic_nas_transport.add_info_present == false); + + return SRSRAN_SUCCESS; +} + +int downlink_generic_nas_transport_packing_test() +{ + uint8_t nas_message[] = { + 0x27, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x68, 0x01, 0x00, 0x06, 0xf0, 0x00, 0x00, 0x00, 0x08, 0x70}; + uint8_t generic_msg_cont[] = {0xf0, 0x00, 0x00, 0x00, 0x08, 0x70}; + LIBLTE_BYTE_MSG_STRUCT buf = {}; + LIBLTE_MME_DOWNLINK_GENERIC_NAS_TRANSPORT_MSG_STRUCT dl_generic_nas_transport; + LIBLTE_ERROR_ENUM err; + + dl_generic_nas_transport.generic_msg_cont_type = 1; + dl_generic_nas_transport.generic_msg_cont.N_bytes = sizeof(generic_msg_cont); + memcpy(dl_generic_nas_transport.generic_msg_cont.msg, generic_msg_cont, sizeof(generic_msg_cont)); + dl_generic_nas_transport.add_info_present = false; + + err = liblte_mme_pack_downlink_generic_nas_transport_msg( + &dl_generic_nas_transport, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, 0xffffffff, &buf); + + TESTASSERT(err == LIBLTE_SUCCESS); + TESTASSERT(buf.N_bytes == sizeof(nas_message)); + TESTASSERT(memcmp(buf.msg, nas_message, buf.N_bytes) == 0); + return SRSRAN_SUCCESS; +} + +int downlink_generic_nas_transport_with_add_info_unpacking_test() +{ + uint8_t nas_message[] = {0x27, 0xae, 0x80, 0xc8, 0xf9, 0x06, 0x07, 0x68, 0x01, 0x00, 0x06, + 0xf0, 0x00, 0x00, 0x00, 0x08, 0x70, 0x65, 0x02, 0x11, 0x11}; + srsran::unique_byte_buffer_t buf; + LIBLTE_MME_DOWNLINK_GENERIC_NAS_TRANSPORT_MSG_STRUCT dl_generic_nas_transport; + LIBLTE_ERROR_ENUM err; + + copy_msg_to_buffer(buf, nas_message); + err = liblte_mme_unpack_downlink_generic_nas_transport_msg((LIBLTE_BYTE_MSG_STRUCT*)buf.get(), + &dl_generic_nas_transport); + TESTASSERT(err == LIBLTE_SUCCESS); + TESTASSERT(dl_generic_nas_transport.generic_msg_cont_type == 1); + TESTASSERT(dl_generic_nas_transport.generic_msg_cont.N_bytes == 6); + TESTASSERT(dl_generic_nas_transport.add_info_present == true); + TESTASSERT(dl_generic_nas_transport.add_info.N_octets == 2); + + return SRSRAN_SUCCESS; +} + +int downlink_generic_nas_transport_with_add_info_packing_test() +{ + uint8_t nas_message[] = {0x27, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x68, 0x01, 0x00, 0x06, + 0xf0, 0x00, 0x00, 0x00, 0x08, 0x70, 0x65, 0x02, 0x11, 0x11}; + uint8_t generic_msg_cont[] = {0xf0, 0x00, 0x00, 0x00, 0x08, 0x70}; + uint8_t add_info[] = {0x11, 0x11}; + LIBLTE_BYTE_MSG_STRUCT buf = {}; + LIBLTE_MME_DOWNLINK_GENERIC_NAS_TRANSPORT_MSG_STRUCT dl_generic_nas_transport; + LIBLTE_ERROR_ENUM err; + + dl_generic_nas_transport.generic_msg_cont_type = 1; + dl_generic_nas_transport.generic_msg_cont.N_bytes = sizeof(generic_msg_cont); + memcpy(dl_generic_nas_transport.generic_msg_cont.msg, generic_msg_cont, sizeof(generic_msg_cont)); + dl_generic_nas_transport.add_info_present = true; + dl_generic_nas_transport.add_info.N_octets = sizeof(add_info); + memcpy(dl_generic_nas_transport.add_info.info, add_info, sizeof(add_info)); + + err = liblte_mme_pack_downlink_generic_nas_transport_msg( + &dl_generic_nas_transport, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, 0xffffffff, &buf); + + TESTASSERT(err == LIBLTE_SUCCESS); + TESTASSERT(buf.N_bytes == sizeof(nas_message)); + TESTASSERT(memcmp(buf.msg, nas_message, buf.N_bytes) == 0); + return SRSRAN_SUCCESS; } int main(int argc, char** argv) @@ -121,9 +202,13 @@ int main(int argc, char** argv) asn1_logger.set_level(srslog::basic_levels::debug); asn1_logger.set_hex_dump_max_size(-1); - srslog::init(); + srsran::test_init(argc, argv); - int result = nas_dedicated_eps_bearer_context_setup_request_test(); + TESTASSERT(nas_dedicated_eps_bearer_context_setup_request_test() == SRSRAN_SUCCESS); + TESTASSERT(downlink_generic_nas_transport_unpacking_test() == SRSRAN_SUCCESS); + TESTASSERT(downlink_generic_nas_transport_packing_test() == SRSRAN_SUCCESS); + TESTASSERT(downlink_generic_nas_transport_with_add_info_unpacking_test() == SRSRAN_SUCCESS); + TESTASSERT(downlink_generic_nas_transport_with_add_info_packing_test() == SRSRAN_SUCCESS); - return result; + return SRSRAN_SUCCESS; } diff --git a/lib/test/asn1/srsran_asn1_rrc_dl_ccch_test.cc b/lib/test/asn1/srsran_asn1_rrc_dl_ccch_test.cc index 1c120dc17a..2364fe8752 100644 --- a/lib/test/asn1/srsran_asn1_rrc_dl_ccch_test.cc +++ b/lib/test/asn1/srsran_asn1_rrc_dl_ccch_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/asn1/srsran_asn1_rrc_dl_dcch_test.cc b/lib/test/asn1/srsran_asn1_rrc_dl_dcch_test.cc index 487f98a261..d5f1b95a62 100644 --- a/lib/test/asn1/srsran_asn1_rrc_dl_dcch_test.cc +++ b/lib/test/asn1/srsran_asn1_rrc_dl_dcch_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -66,6 +66,31 @@ int rrc_conn_reconfig_ho_test1() return 0; } +int rrc_ue_cap_enquiry_test() +{ + uint8_t rrc_msg[] = {0x38, 0x00, 0x00}; + // 38 00 00 + + cbit_ref bref(rrc_msg, sizeof(rrc_msg)); + + dl_dcch_msg_s dl_dcch_msg; + dl_dcch_msg.unpack(bref); + + TESTASSERT(dl_dcch_msg.msg.type() == dl_dcch_msg_type_c::types::c1); + TESTASSERT(dl_dcch_msg.msg.c1().type() == dl_dcch_msg_type_c::c1_c_::types::ue_cap_enquiry); + + // assign to stack-allocated variable + asn1::rrc::ue_cap_enquiry_s ue_cap; + ue_cap = dl_dcch_msg.msg.c1().ue_cap_enquiry(); + + TESTASSERT(ue_cap.crit_exts.c1().type() == + asn1::rrc::ue_cap_enquiry_s::crit_exts_c_::c1_c_::types::ue_cap_enquiry_r8); + TESTASSERT(ue_cap.crit_exts.c1().ue_cap_enquiry_r8().ue_cap_request.size() == 1); + TESTASSERT(ue_cap.crit_exts.c1().ue_cap_enquiry_r8().ue_cap_request[0] == asn1::rrc::rat_type_e::eutra); + + return 0; +} + int main(int argc, char** argv) { auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); @@ -75,6 +100,7 @@ int main(int argc, char** argv) srslog::init(); TESTASSERT(rrc_conn_reconfig_ho_test1() == 0); + TESTASSERT(rrc_ue_cap_enquiry_test() == 0); return 0; } diff --git a/lib/test/asn1/srsran_asn1_rrc_mcch_test.cc b/lib/test/asn1/srsran_asn1_rrc_mcch_test.cc index 6506055d3f..0a26b2c0ad 100644 --- a/lib/test/asn1/srsran_asn1_rrc_mcch_test.cc +++ b/lib/test/asn1/srsran_asn1_rrc_mcch_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/asn1/srsran_asn1_rrc_meas_test.cc b/lib/test/asn1/srsran_asn1_rrc_meas_test.cc index 35492fb22d..e48c778834 100644 --- a/lib/test/asn1/srsran_asn1_rrc_meas_test.cc +++ b/lib/test/asn1/srsran_asn1_rrc_meas_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -42,7 +42,7 @@ int meas_obj_test() cbit_ref bref(&rrc_msg[0], sizeof(rrc_msg)); ul_dcch_msg_s ul_dcch_msg; - ul_dcch_msg.unpack(bref); + TESTASSERT(ul_dcch_msg.unpack(bref) == SRSASN_SUCCESS); TESTASSERT(ul_dcch_msg.msg.type() == ul_dcch_msg_type_c::types::c1); TESTASSERT(ul_dcch_msg.msg.c1().type() == ul_dcch_msg_type_c::c1_c_::types::meas_report); diff --git a/lib/test/asn1/srsran_asn1_rrc_nr_test.cc b/lib/test/asn1/srsran_asn1_rrc_nr_test.cc index 012464f67a..dbf8f0aa25 100644 --- a/lib/test/asn1/srsran_asn1_rrc_nr_test.cc +++ b/lib/test/asn1/srsran_asn1_rrc_nr_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -33,6 +33,26 @@ using namespace asn1; using namespace asn1::rrc_nr; +void test_rrc_setup_complete() +{ + uint8_t msg[] = {0x10, 0xc0, 0x10, 0x00, 0x20, 0x25, 0x97, 0xe0, 0x1e, 0x1e, 0x34, 0xb5, 0x30, 0xb7, 0xe0, 0x04, + 0x10, 0x90, 0x00, 0xbf, 0x20, 0x0f, 0x11, 0x08, 0x00, 0x10, 0x15, 0x66, 0x75, 0xf7, 0x12, 0xe0, + 0x4f, 0x07, 0x0f, 0x07, 0x07, 0x10, 0x03, 0x87, 0xe0, 0x04, 0x10, 0x90, 0x00, 0xbf, 0x20, 0x0f, + 0x11, 0x08, 0x00, 0x10, 0x15, 0x66, 0x75, 0xf7, 0x11, 0x00, 0x10, 0x32, 0xe0, 0x4f, 0x07, 0x0f, + 0x07, 0x02, 0xf0, 0x20, 0x10, 0x15, 0x20, 0x0f, 0x11, 0x00, 0x00, 0x06, 0x41, 0x70, 0x7f, 0x07, + 0x00, 0x00, 0x01, 0x88, 0x0b, 0x01, 0x80, 0x10, 0x17, 0x40, 0x00, 0x09, 0x05, 0x30, 0x10, 0x10}; + // 10c01000202597e01e1e34b530b7e004109000bf200f11080010156675f712e04f070f0707100387e004109000bf200f11080010156675f711001032e04f070f0702f0201015200f1100000641707f07000001880b0180101740000905301010 + + asn1::cbit_ref bref{msg, sizeof(msg)}; + asn1::rrc_nr::ul_dcch_msg_s ul_dcch_msg; + TESTASSERT_SUCCESS(ul_dcch_msg.unpack(bref)); + + TESTASSERT_EQ(ul_dcch_msg_type_c::types_opts::c1, ul_dcch_msg.msg.type().value); + TESTASSERT_EQ(ul_dcch_msg_type_c::c1_c_::types_opts::rrc_setup_complete, ul_dcch_msg.msg.c1().type().value); + + TESTASSERT_SUCCESS(test_pack_unpack_consistency(ul_dcch_msg)); +} + int test_eutra_nr_capabilities() { struct ue_mrdc_cap_s mrdc_cap; @@ -55,7 +75,6 @@ int test_eutra_nr_capabilities() band_combination.band_list.push_back(band_param_nr); mrdc_cap.rf_params_mrdc.supported_band_combination_list.push_back(band_combination); - mrdc_cap.rf_params_mrdc.supported_band_combination_list_present = true; mrdc_cap.rf_params_mrdc.ext = true; @@ -72,8 +91,6 @@ int test_eutra_nr_capabilities() band_info_nr.band_info_nr().band_nr = 78; mrdc_cap.rf_params_mrdc.applied_freq_band_list_filt.push_back(band_info_nr); - mrdc_cap.rf_params_mrdc.applied_freq_band_list_filt_present = true; - // rf_params_mrdc supported band combination list v1540 band_combination_list_v1540_l* band_combination_list_v1450 = new band_combination_list_v1540_l(); @@ -126,8 +143,6 @@ int test_eutra_nr_capabilities() mrdc_cap.feature_set_combinations.push_back(feature_set_combination); - mrdc_cap.feature_set_combinations_present = true; - // Pack mrdc_cap uint8_t buffer[1024]; asn1::bit_ref bref(buffer, sizeof(buffer)); @@ -198,7 +213,7 @@ int test_ue_rrc_reconfiguration() #endif TESTASSERT(rrc_recfg.crit_exts.type() == asn1::rrc_nr::rrc_recfg_s::crit_exts_c_::types::rrc_recfg); - TESTASSERT(rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group_present == true); + TESTASSERT(rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group.size() > 0); cell_group_cfg_s cell_group_cfg; cbit_ref bref0(rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group.data(), @@ -210,7 +225,6 @@ int test_ue_rrc_reconfiguration() srslog::fetch_basic_logger("RRC").info("RRC Secondary Cell Group: \n %s", jw1.to_string().c_str()); #endif TESTASSERT(cell_group_cfg.cell_group_id == 1); - TESTASSERT(cell_group_cfg.rlc_bearer_to_add_mod_list_present == true); TESTASSERT(cell_group_cfg.rlc_bearer_to_add_mod_list.size() == 1); TESTASSERT(cell_group_cfg.mac_cell_group_cfg_present == true); TESTASSERT(cell_group_cfg.phys_cell_group_cfg_present == true); @@ -220,7 +234,7 @@ int test_ue_rrc_reconfiguration() int test_radio_bearer_config() { - uint8_t rrc_msg[] = "\x14\x09\x28\x17\x87\xc0\x0c\x28"; + uint8_t rrc_msg[] = "\x14\x09\x28\x17\x87\xc0\x0c\x28"; cbit_ref bref(&rrc_msg[0], sizeof(rrc_msg)); radio_bearer_cfg_s radio_bearer_cfg; TESTASSERT(radio_bearer_cfg.unpack(bref) == SRSASN_SUCCESS); @@ -229,7 +243,6 @@ int test_radio_bearer_config() radio_bearer_cfg.to_json(jw); srslog::fetch_basic_logger("RRC").info("RRC Bearer CFG Message: \n %s", jw.to_string().c_str()); #endif - TESTASSERT(radio_bearer_cfg.drb_to_add_mod_list_present == true); TESTASSERT(radio_bearer_cfg.drb_to_add_mod_list.size() == 1); TESTASSERT(radio_bearer_cfg.security_cfg_present == true); TESTASSERT(radio_bearer_cfg.security_cfg.security_algorithm_cfg_present == true); @@ -240,8 +253,7 @@ int test_radio_bearer_config() reconfig.rrc_transaction_id = 0; rrc_recfg_ies_s& recfg_ies = reconfig.crit_exts.set_rrc_recfg(); - recfg_ies.radio_bearer_cfg_present = true; - recfg_ies.radio_bearer_cfg.drb_to_add_mod_list_present = true; + recfg_ies.radio_bearer_cfg_present = true; recfg_ies.radio_bearer_cfg.drb_to_add_mod_list.resize(1); auto& drb_item = recfg_ies.radio_bearer_cfg.drb_to_add_mod_list[0]; @@ -351,9 +363,8 @@ int test_cell_group_config_tdd() cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common_present == true); - TESTASSERT( - cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common.type() == - asn1::rrc_nr::setup_release_c::types_opts::setup); + TESTASSERT(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common + .is_setup()); asn1::rrc_nr::rach_cfg_common_s& rach_cfg_common = cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common.setup(); @@ -379,7 +390,6 @@ int test_cell_group_config_tdd() cell_group_cfg_s cell_group_cfg_pack; // RLC for DRB1 - cell_group_cfg_pack.rlc_bearer_to_add_mod_list_present = true; cell_group_cfg_pack.rlc_bearer_to_add_mod_list.resize(1); auto& rlc = cell_group_cfg_pack.rlc_bearer_to_add_mod_list[0]; rlc.lc_ch_id = 1; @@ -408,10 +418,9 @@ int test_cell_group_config_tdd() rlc.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0; // mac-CellGroup-Config - cell_group_cfg_pack.mac_cell_group_cfg_present = true; - auto& mac_cell_group = cell_group_cfg_pack.mac_cell_group_cfg; - mac_cell_group.sched_request_cfg_present = true; - mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list_present = true; + cell_group_cfg_pack.mac_cell_group_cfg_present = true; + auto& mac_cell_group = cell_group_cfg_pack.mac_cell_group_cfg; + mac_cell_group.sched_request_cfg_present = true; mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list.resize(1); mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list[0].sched_request_id = 0; mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list[0].sr_trans_max = @@ -432,7 +441,6 @@ int test_cell_group_config_tdd() cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg_present = true; auto& pdcch_cfg_dedicated = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg; pdcch_cfg_dedicated.set_setup(); - pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list_present = true; pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list.resize(1); pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list[0].ctrl_res_set_id = 2; pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list[0].freq_domain_res.from_number( @@ -443,7 +451,6 @@ int test_cell_group_config_tdd() asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; // search spaces - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list_present = true; pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list.resize(1); pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].search_space_id = 2; pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].ctrl_res_set_id_present = true; @@ -478,7 +485,6 @@ int test_cell_group_config_tdd() pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position_present = true; pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position = asn1::rrc_nr::dmrs_dl_cfg_s::dmrs_add_position_opts::pos1; - pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list_present = true; pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list.resize(1); pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].tci_state_id = 0; pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].qcl_type1.ref_sig.set_ssb(); @@ -493,7 +499,6 @@ int test_cell_group_config_tdd() asn1::rrc_nr::pdsch_cfg_s::prb_bundling_type_c_::static_bundling_s_::bundle_size_opts::wideband; // ZP-CSI - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list_present = true; pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list.resize(1); pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].zp_csi_rs_res_id = 0; pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.set_row4(); @@ -532,7 +537,6 @@ int test_cell_group_config_tdd() ul_config.init_ul_bwp.pucch_cfg.setup().format2.setup().max_code_rate = pucch_max_code_rate_opts::zero_dot25; // SR resources - ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list_present = true; ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list.resize(1); auto& sr_res1 = ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list[0]; sr_res1.sched_request_res_id = 1; @@ -544,7 +548,6 @@ int test_cell_group_config_tdd() sr_res1.res = 0; // only PUCCH resource we have defined so far // DL data - ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack_present = true; ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack.resize(5); ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack[0] = 8; ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack[1] = 7; @@ -553,7 +556,6 @@ int test_cell_group_config_tdd() ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack[4] = 4; // PUCCH resources (only one format1 for the moment) - ul_config.init_ul_bwp.pucch_cfg.setup().res_to_add_mod_list_present = true; ul_config.init_ul_bwp.pucch_cfg.setup().res_to_add_mod_list.resize(1); auto& pucch_res1 = ul_config.init_ul_bwp.pucch_cfg.setup().res_to_add_mod_list[0]; pucch_res1.pucch_res_id = 0; @@ -615,7 +617,6 @@ int test_cell_group_config_tdd() cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.set_setup(); // nzp-CSI-RS Resource - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list_present = true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list.resize(1); auto& nzp_csi_res = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list[0]; @@ -639,8 +640,6 @@ int test_cell_group_config_tdd() nzp_csi_res.qcl_info_periodic_csi_rs = 0; // nzp-CSI-RS ResourceSet - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list_present = - true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list.resize(1); auto& nzp_csi_res_set = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list[0]; @@ -650,7 +649,6 @@ int test_cell_group_config_tdd() // Skip TRS info // CSI report config - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list_present = true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list.resize(1); auto& csi_report = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list[0]; @@ -733,7 +731,6 @@ int test_cell_group_config_tdd() asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; // common search space list - pdcch_cfg_common.setup().common_search_space_list_present = true; pdcch_cfg_common.setup().common_search_space_list.resize(1); pdcch_cfg_common.setup().common_search_space_list[0].search_space_id = 1; pdcch_cfg_common.setup().common_search_space_list[0].ctrl_res_set_id_present = true; @@ -769,7 +766,6 @@ int test_cell_group_config_tdd() .set_setup(); auto& pdsch_cfg_common = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp .pdsch_cfg_common.setup(); - pdsch_cfg_common.pdsch_time_domain_alloc_list_present = true; pdsch_cfg_common.pdsch_time_domain_alloc_list.resize(1); pdsch_cfg_common.pdsch_time_domain_alloc_list[0].map_type = pdsch_time_domain_res_alloc_s::map_type_opts::type_a; pdsch_cfg_common.pdsch_time_domain_alloc_list[0].start_symbol_and_len = 40; @@ -823,7 +819,6 @@ int test_cell_group_config_tdd() auto& pusch_cfg_common_pack = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common; pusch_cfg_common_pack.set_setup(); - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list_present = true; pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list.resize(2); pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].k2_present = true; pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].k2 = 4; @@ -969,9 +964,8 @@ int test_cell_group_config_fdd() cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common_present == true); - TESTASSERT( - cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common.type() == - asn1::rrc_nr::setup_release_c::types_opts::setup); + TESTASSERT(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common + .is_setup()); asn1::rrc_nr::rach_cfg_common_s& rach_cfg_common = cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common.setup(); @@ -997,7 +991,6 @@ int test_cell_group_config_fdd() cell_group_cfg_s cell_group_cfg_pack; // RLC for DRB1 - cell_group_cfg_pack.rlc_bearer_to_add_mod_list_present = true; cell_group_cfg_pack.rlc_bearer_to_add_mod_list.resize(1); auto& rlc = cell_group_cfg_pack.rlc_bearer_to_add_mod_list[0]; rlc.lc_ch_id = 4; @@ -1026,10 +1019,9 @@ int test_cell_group_config_fdd() rlc.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0; // mac-CellGroup-Config - cell_group_cfg_pack.mac_cell_group_cfg_present = true; - auto& mac_cell_group = cell_group_cfg_pack.mac_cell_group_cfg; - mac_cell_group.sched_request_cfg_present = true; - mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list_present = true; + cell_group_cfg_pack.mac_cell_group_cfg_present = true; + auto& mac_cell_group = cell_group_cfg_pack.mac_cell_group_cfg; + mac_cell_group.sched_request_cfg_present = true; mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list.resize(1); mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list[0].sched_request_id = 0; mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list[0].sr_trans_max = @@ -1050,7 +1042,6 @@ int test_cell_group_config_fdd() cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg_present = true; auto& pdcch_cfg_dedicated = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg; pdcch_cfg_dedicated.set_setup(); - pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list_present = true; pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list.resize(1); pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list[0].ctrl_res_set_id = 2; pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list[0].freq_domain_res.from_number( @@ -1061,7 +1052,6 @@ int test_cell_group_config_fdd() asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; // search spaces - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list_present = true; pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list.resize(1); pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].search_space_id = 2; pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].ctrl_res_set_id_present = true; @@ -1096,7 +1086,6 @@ int test_cell_group_config_fdd() pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position_present = true; pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position = asn1::rrc_nr::dmrs_dl_cfg_s::dmrs_add_position_opts::pos1; - pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list_present = true; pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list.resize(1); pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].tci_state_id = 0; pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].qcl_type1.ref_sig.set_ssb(); @@ -1111,7 +1100,6 @@ int test_cell_group_config_fdd() asn1::rrc_nr::pdsch_cfg_s::prb_bundling_type_c_::static_bundling_s_::bundle_size_opts::wideband; // ZP-CSI - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list_present = true; pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list.resize(1); pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].zp_csi_rs_res_id = 0; pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.set_row4(); @@ -1150,7 +1138,6 @@ int test_cell_group_config_fdd() ul_config.init_ul_bwp.pucch_cfg.setup().format2.setup().max_code_rate = pucch_max_code_rate_opts::zero_dot25; // SR resources - ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list_present = true; ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list.resize(1); auto& sr_res1 = ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list[0]; sr_res1.sched_request_res_id = 1; @@ -1162,14 +1149,11 @@ int test_cell_group_config_fdd() sr_res1.res = 16; // DL data - ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack_present = true; ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack.resize(1); ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack[0] = 4; - - //TODO? - // PUCCH resources (only one format1 for the moment) - ul_config.init_ul_bwp.pucch_cfg.setup().res_to_add_mod_list_present = true; + // TODO? + // PUCCH resources (only one format1 for the moment) ul_config.init_ul_bwp.pucch_cfg.setup().res_to_add_mod_list.resize(1); auto& pucch_res1 = ul_config.init_ul_bwp.pucch_cfg.setup().res_to_add_mod_list[0]; pucch_res1.pucch_res_id = 0; @@ -1231,10 +1215,8 @@ int test_cell_group_config_fdd() cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.set_setup(); // nzp-CSI-RS Resource - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list_present = true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list.resize(5); - auto& nzp_csi_res = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup(); + auto& nzp_csi_res = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup(); // item 0 nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].nzp_csi_rs_res_id = 0; nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.set_row2(); @@ -1342,11 +1324,8 @@ int test_cell_group_config_fdd() nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].qcl_info_periodic_csi_rs = 0; // nzp-CSI-RS ResourceSet - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list_present = - true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list.resize(2); - auto& nzp_csi_res_set = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup(); + auto& nzp_csi_res_set = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup(); // item 0 nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[0].nzp_csi_res_set_id = 0; nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[0].nzp_csi_rs_res.resize(1); @@ -1367,7 +1346,6 @@ int test_cell_group_config_fdd() // TODO: add csi resource config // CSI report config - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list_present = true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list.resize(1); auto& csi_report = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list[0]; @@ -1396,7 +1374,7 @@ int test_cell_group_config_fdd() // Reconfig with Sync cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.new_ue_id = 17933; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.t304 = recfg_with_sync_s::t304_opts::ms1000; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.t304 = recfg_with_sync_s::t304_opts::ms1000; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ss_pbch_block_pwr = -36; @@ -1450,7 +1428,6 @@ int test_cell_group_config_fdd() asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; // common search space list - pdcch_cfg_common.setup().common_search_space_list_present = true; pdcch_cfg_common.setup().common_search_space_list.resize(1); pdcch_cfg_common.setup().common_search_space_list[0].search_space_id = 1; pdcch_cfg_common.setup().common_search_space_list[0].ctrl_res_set_id_present = true; @@ -1486,7 +1463,6 @@ int test_cell_group_config_fdd() .set_setup(); auto& pdsch_cfg_common = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp .pdsch_cfg_common.setup(); - pdsch_cfg_common.pdsch_time_domain_alloc_list_present = true; pdsch_cfg_common.pdsch_time_domain_alloc_list.resize(1); pdsch_cfg_common.pdsch_time_domain_alloc_list[0].map_type = pdsch_time_domain_res_alloc_s::map_type_opts::type_a; pdsch_cfg_common.pdsch_time_domain_alloc_list[0].start_symbol_and_len = 40; @@ -1544,7 +1520,6 @@ int test_cell_group_config_fdd() auto& pusch_cfg_common_pack = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common; pusch_cfg_common_pack.set_setup(); - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list_present = true; pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list.resize(2); pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].k2_present = true; pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].k2 = 4; @@ -1625,7 +1600,6 @@ int test_cell_group_config_fdd() return SRSRAN_SUCCESS; } - int main() { auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); @@ -1643,6 +1617,7 @@ int main() pcap_handle->open("srsran_asn1_rrc_nr_test.pcap"); #endif + test_rrc_setup_complete(); TESTASSERT(test_eutra_nr_capabilities() == SRSRAN_SUCCESS); TESTASSERT(test_ue_mrdc_capabilities() == SRSRAN_SUCCESS); TESTASSERT(test_ue_rrc_reconfiguration() == SRSRAN_SUCCESS); diff --git a/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc b/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc index 31b80aa2a2..1f06e45a57 100644 --- a/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc +++ b/lib/test/asn1/srsran_asn1_rrc_ul_dcch_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,9 +24,11 @@ #include "srsran/common/mac_pcap.h" #include +using namespace asn1; using namespace asn1::rrc; #define PCAP 0 +#define JSON_OUTPUT 1 #define TESTASSERT(cond) \ { \ @@ -126,6 +128,352 @@ int rrc_ue_cap_info_test(srsran::mac_pcap* pcap) return 0; } +int rrc_ue_cap_info_pack_buff_size_test(srsran::mac_pcap* pcap, const uint32_t buf_size) +{ + auto& rrc_logger = srslog::fetch_basic_logger("RRC", false); + rrc_logger.set_level(srslog::basic_levels::debug); + rrc_logger.set_hex_dump_max_size(128); + + srsue::rrc_args_t args = {}; + args.ue_category = 8; + args.ue_category_ul = 5; + args.ue_category_dl = 14; + args.release = 15; + args.feature_group = 0xe6041c00; + args.nof_supported_bands = 1; + args.supported_bands[0] = 8; + args.nof_lte_carriers = 4; + args.nof_nr_carriers = 0; + args.support_ca = true; + args.supported_bands_nr.push_back(3); + + asn1::rrc::ul_dcch_msg_s ul_dcch_msg; + ul_dcch_msg.msg.set(ul_dcch_msg_type_c::types::c1); + ul_dcch_msg.msg.c1().set(ul_dcch_msg_type_c::c1_c_::types::ue_cap_info); + ul_dcch_msg.msg.c1().ue_cap_info().rrc_transaction_id = 0; + + ul_dcch_msg.msg.c1().ue_cap_info().crit_exts.set(ue_cap_info_s::crit_exts_c_::types::c1); + ul_dcch_msg.msg.c1().ue_cap_info().crit_exts.c1().set(ue_cap_info_s::crit_exts_c_::c1_c_::types::ue_cap_info_r8); + ue_cap_info_r8_ies_s* info = &ul_dcch_msg.msg.c1().ue_cap_info().crit_exts.c1().ue_cap_info_r8(); + info->ue_cap_rat_container_list.resize(1); + info->ue_cap_rat_container_list[0].rat_type = rat_type_e::eutra; + + ue_eutra_cap_s cap; + cap.access_stratum_release = (access_stratum_release_e::options)(args.release - SRSRAN_RELEASE_MIN); + cap.ue_category = (uint8_t)((args.ue_category < 1 || args.ue_category > 5) ? 4 : args.ue_category); + cap.pdcp_params.max_num_rohc_context_sessions_present = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0001_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0002_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0003_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0004_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0006_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0101_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0102_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0103_r15 = false; + cap.pdcp_params.supported_rohc_profiles.profile0x0104_r15 = false; + + cap.phy_layer_params.ue_specific_ref_sigs_supported = false; + cap.phy_layer_params.ue_tx_ant_sel_supported = false; + + cap.rf_params.supported_band_list_eutra.resize(args.nof_supported_bands); + cap.meas_params.band_list_eutra.resize(args.nof_supported_bands); + for (uint32_t k = 0; k < args.nof_supported_bands; k++) { + cap.rf_params.supported_band_list_eutra[k].band_eutra = args.supported_bands[k]; + cap.rf_params.supported_band_list_eutra[k].half_duplex = false; + cap.meas_params.band_list_eutra[k].inter_freq_band_list.resize(1); + cap.meas_params.band_list_eutra[k].inter_freq_band_list[0].inter_freq_need_for_gaps = true; + } + + cap.feature_group_inds_present = true; + cap.feature_group_inds.from_number(args.feature_group); + + ue_eutra_cap_v1280_ies_s* ue_eutra_cap_v1280_ies; + ue_eutra_cap_v1360_ies_s* ue_eutra_cap_v1360_ies; + ue_eutra_cap_v1450_ies_s* ue_eutra_cap_v1450_ies; + if (args.release > 8) { + ue_eutra_cap_v920_ies_s cap_v920; + + cap_v920.phy_layer_params_v920.enhanced_dual_layer_fdd_r9_present = false; + cap_v920.phy_layer_params_v920.enhanced_dual_layer_tdd_r9_present = false; + cap_v920.inter_rat_params_geran_v920.dtm_r9_present = false; + cap_v920.inter_rat_params_geran_v920.e_redirection_geran_r9_present = false; + cap_v920.csg_proximity_ind_params_r9.inter_freq_proximity_ind_r9_present = false; + cap_v920.csg_proximity_ind_params_r9.intra_freq_proximity_ind_r9_present = false; + cap_v920.csg_proximity_ind_params_r9.utran_proximity_ind_r9_present = false; + cap_v920.neigh_cell_si_acquisition_params_r9.inter_freq_si_acquisition_for_ho_r9_present = false; + cap_v920.neigh_cell_si_acquisition_params_r9.intra_freq_si_acquisition_for_ho_r9_present = false; + cap_v920.neigh_cell_si_acquisition_params_r9.utran_si_acquisition_for_ho_r9_present = false; + cap_v920.son_params_r9.rach_report_r9_present = false; + + cap.non_crit_ext_present = true; + cap.non_crit_ext = cap_v920; + } + + if (args.release > 9) { + phy_layer_params_v1020_s phy_layer_params_v1020; + phy_layer_params_v1020.two_ant_ports_for_pucch_r10_present = false; + phy_layer_params_v1020.tm9_with_minus8_tx_fdd_r10_present = false; + phy_layer_params_v1020.pmi_disabling_r10_present = false; + phy_layer_params_v1020.cross_carrier_sched_r10_present = args.support_ca; + phy_layer_params_v1020.simul_pucch_pusch_r10_present = false; + phy_layer_params_v1020.multi_cluster_pusch_within_cc_r10_present = false; + phy_layer_params_v1020.non_contiguous_ul_ra_within_cc_list_r10_present = false; + + rf_params_v1020_s rf_params; + band_combination_params_r10_l combination_params; + if (args.support_ca) { + // add Intra‑band Contiguous or Inter‑band Non-contiguous CA band combination + // note that nof_supported_bands=1 when all cells are in the same but non-contiguous band + for (uint32_t k = 0; k < args.nof_supported_bands; k++) { + ca_mimo_params_dl_r10_s ca_mimo_params_dl; + ca_mimo_params_dl.ca_bw_class_dl_r10 = ca_bw_class_r10_e::f; + ca_mimo_params_dl.supported_mimo_cap_dl_r10_present = false; + + ca_mimo_params_ul_r10_s ca_mimo_params_ul; + ca_mimo_params_ul.ca_bw_class_ul_r10 = ca_bw_class_r10_e::f; + ca_mimo_params_ul.supported_mimo_cap_ul_r10_present = false; + + band_params_r10_s band_params; + band_params.band_eutra_r10 = args.supported_bands[k]; + band_params.band_params_dl_r10_present = true; + band_params.band_params_dl_r10.push_back(ca_mimo_params_dl); + band_params.band_params_ul_r10_present = true; + band_params.band_params_ul_r10.push_back(ca_mimo_params_ul); + + combination_params.push_back(band_params); + } + } + rf_params.supported_band_combination_r10.push_back(combination_params); + + // add all 2CC, 3CC and 4CC Intra‑band Non-contiguous CA band combinations + for (uint32_t k = 0; k < args.nof_supported_bands; k++) { + for (uint32_t j = 2; j <= args.nof_lte_carriers; j++) { + combination_params.clear(); + + ca_mimo_params_dl_r10_s ca_mimo_params_dl; + ca_mimo_params_dl.ca_bw_class_dl_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_dl.supported_mimo_cap_dl_r10_present = false; + + ca_mimo_params_ul_r10_s ca_mimo_params_ul; + ca_mimo_params_ul.ca_bw_class_ul_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_ul.supported_mimo_cap_ul_r10_present = false; + + band_params_r10_s band_params; + band_params.band_eutra_r10 = args.supported_bands[k]; + band_params.band_params_dl_r10_present = true; + band_params.band_params_dl_r10.push_back(ca_mimo_params_dl); + band_params.band_params_ul_r10_present = true; + band_params.band_params_ul_r10.push_back(ca_mimo_params_ul); + + for (uint32_t l = 0; l < j; l++) { + combination_params.push_back(band_params); + } + rf_params.supported_band_combination_r10.push_back(combination_params); + } + } + + ue_eutra_cap_v1020_ies_s cap_v1020; + if (args.ue_category >= 6 && args.ue_category <= 8) { + cap_v1020.ue_category_v1020_present = true; + cap_v1020.ue_category_v1020 = (uint8_t)args.ue_category; + } else { + // Do not populate UE category for this release if the category is out of range + } + cap_v1020.phy_layer_params_v1020_present = true; + cap_v1020.phy_layer_params_v1020 = phy_layer_params_v1020; + cap_v1020.rf_params_v1020_present = args.support_ca; + cap_v1020.rf_params_v1020 = rf_params; + + ue_eutra_cap_v940_ies_s cap_v940; + cap_v940.non_crit_ext_present = true; + cap_v940.non_crit_ext = cap_v1020; + + cap.non_crit_ext.non_crit_ext_present = true; + cap.non_crit_ext.non_crit_ext = cap_v940; + } + + if (args.release > 10) { + ue_eutra_cap_v11a0_ies_s cap_v11a0; + if (args.ue_category >= 11 && args.ue_category <= 12) { + cap_v11a0.ue_category_v11a0 = (uint8_t)args.ue_category; + cap_v11a0.ue_category_v11a0_present = true; + } else { + // Do not populate UE category for this release if the category is out of range + } + + ue_eutra_cap_v1180_ies_s cap_v1180; + cap_v1180.non_crit_ext_present = true; + cap_v1180.non_crit_ext = cap_v11a0; + + ue_eutra_cap_v1170_ies_s cap_v1170; + cap_v1170.non_crit_ext_present = true; + cap_v1170.non_crit_ext = cap_v1180; + if (args.ue_category >= 9 && args.ue_category <= 10) { + cap_v1170.ue_category_v1170 = (uint8_t)args.ue_category; + cap_v1170.ue_category_v1170_present = true; + } else { + // Do not populate UE category for this release if the category is out of range + } + + ue_eutra_cap_v1130_ies_s cap_v1130; + cap_v1130.non_crit_ext_present = true; + cap_v1130.non_crit_ext = cap_v1170; + + ue_eutra_cap_v1090_ies_s cap_v1090; + cap_v1090.non_crit_ext_present = true; + cap_v1090.non_crit_ext = cap_v1130; + + ue_eutra_cap_v1060_ies_s cap_v1060; + cap_v1060.non_crit_ext_present = true; + cap_v1060.non_crit_ext = cap_v1090; + + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext = cap_v1060; + } + + if (args.release > 11) { + supported_band_list_eutra_v1250_l supported_band_list_eutra_v1250; + for (uint32_t k = 0; k < args.nof_supported_bands; k++) { + supported_band_eutra_v1250_s supported_band_eutra_v1250; + // According to 3GPP 36.306 v12 Table 4.1A-1, 256QAM is supported for ue_category_dl 11-16 + supported_band_eutra_v1250.dl_minus256_qam_r12_present = (args.ue_category_dl >= 11); + + // According to 3GPP 36.331 v12 UE-EUTRA-Capability field descriptions + // This field is only present when the field ue-CategoryUL is considered to 5 or 13. + supported_band_eutra_v1250.ul_minus64_qam_r12_present = true; + + supported_band_list_eutra_v1250.push_back(supported_band_eutra_v1250); + } + + rf_params_v1250_s rf_params_v1250; + rf_params_v1250.supported_band_list_eutra_v1250_present = true; + rf_params_v1250.supported_band_list_eutra_v1250 = supported_band_list_eutra_v1250; + + ue_eutra_cap_v1250_ies_s cap_v1250; + + // Optional UE Category UL/DL + // Warning: Make sure the UE Category UL/DL matches with 3GPP 36.306 Table 4.1A-6 + if (args.ue_category_dl >= 0) { + cap_v1250.ue_category_dl_r12_present = true; + cap_v1250.ue_category_dl_r12 = (uint8_t)args.ue_category_dl; + } else { + // Do not populate UE category for this release if the category is not available + } + if (args.ue_category_ul >= 0) { + cap_v1250.ue_category_ul_r12_present = true; + cap_v1250.ue_category_ul_r12 = (uint8_t)args.ue_category_ul; + } else { + // Do not populate UE category for this release if the category is not available + } + cap_v1250.rf_params_v1250_present = true; + cap_v1250.rf_params_v1250 = rf_params_v1250; + + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext_present = true; + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext = cap_v1250; + // 12.50 + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 12.60 + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 12.70 + cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + } + // Release 13 + if (args.release > 12) { + // 12.80 + ue_eutra_cap_v1280_ies = + &cap.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext + .non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext; + ue_eutra_cap_v1280_ies->non_crit_ext_present = true; + // 13.10 + ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext_present = true; + // 13.20 + ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 13.30 + ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 13.40 + ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 13.50 + ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = + true; + } + // Release 14 + if (args.release > 13) { + // 13.60 + ue_eutra_cap_v1360_ies = + &ue_eutra_cap_v1280_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext; + ue_eutra_cap_v1360_ies->non_crit_ext_present = true; + // 14.30 + ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext_present = true; + // 14.40 + ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext.non_crit_ext_present = true; + // 14.50 + ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext_present = true; + } + // Release 15 + if (args.release > 14) { + ue_eutra_cap_v1450_ies = &ue_eutra_cap_v1360_ies->non_crit_ext.non_crit_ext.non_crit_ext; + // 14.60 + ue_eutra_cap_v1450_ies->non_crit_ext_present = true; + ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext_present = true; + + irat_params_nr_r15_s irat_params_nr_r15; + irat_params_nr_r15.en_dc_r15_present = true; + irat_params_nr_r15.supported_band_list_en_dc_r15_present = true; + + uint32_t nof_supported_nr_bands = args.supported_bands_nr.size(); + irat_params_nr_r15.supported_band_list_en_dc_r15.resize(nof_supported_nr_bands); + for (uint32_t k = 0; k < nof_supported_nr_bands; k++) { + irat_params_nr_r15.supported_band_list_en_dc_r15[k].band_nr_r15 = args.supported_bands_nr[k]; + } + + ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext.irat_params_nr_r15_present = true; + ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext.irat_params_nr_r15 = irat_params_nr_r15; + ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext.non_crit_ext_present = true; + + // 15.10 + ue_eutra_cap_v1510_ies_s* ue_cap_enquiry_v1510_ies = &ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext; + ue_cap_enquiry_v1510_ies->pdcp_params_nr_r15_present = true; + ue_cap_enquiry_v1510_ies->pdcp_params_nr_r15.sn_size_lo_r15_present = true; + } + + // Pack caps and copy to cap info + uint8_t buf[128]; + bzero(buf, sizeof(buf)); + asn1::bit_ref bref(buf, buf_size); + if (cap.pack(bref) != asn1::SRSASN_SUCCESS) { + rrc_logger.debug("Error packing EUTRA capabilities"); + return -1; + } + + bref.align_bytes_zero(); + uint32_t cap_len = (uint32_t)bref.distance_bytes(buf); + + info->ue_cap_rat_container_list[0].ue_cap_rat_container.resize(cap_len); + memcpy(info->ue_cap_rat_container_list[0].ue_cap_rat_container.data(), buf, cap_len); + rrc_logger.debug(buf, cap_len, "UE-Cap (%d/%zd B)", cap_len, sizeof(buf)); + + // pack the message + uint8_t byte_buf[512]; + bzero(byte_buf, sizeof(byte_buf)); + asn1::bit_ref bref3(byte_buf, sizeof(byte_buf)); + ul_dcch_msg.pack(bref3); + bref3.align_bytes_zero(); + + uint32_t len = (uint32_t)bref3.distance_bytes(byte_buf); + rrc_logger.debug(byte_buf, len, "UL-DCCH (%d/%zd B)", len, sizeof(byte_buf)); + + if (pcap != NULL) { + pcap->write_ul_rrc_pdu(byte_buf, len); + } + + return 0; +} + int pack_fail_test() { srsue::rrc_args_t args = {}; @@ -175,6 +523,160 @@ int pack_fail_test() return 0; } +int rrc_ue_cap_information_test() +{ + uint8_t rrc_msg[] = { + 0x38, 0x01, 0x08, 0x89, 0x9e, 0x01, 0xb8, 0x05, 0x18, 0x18, 0x01, 0x33, 0xe6, 0xc0, 0x82, 0x06, 0x10, 0x38, 0xb1, + 0x84, 0x08, 0x92, 0x30, 0x65, 0x2a, 0x64, 0xea, 0x14, 0xaa, 0x5e, 0xfc, 0xc1, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, + 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, + 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, + 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, + 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, + 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xf9, 0x8f, 0xff, 0xff, 0xfb, 0xf0, + 0x6e, 0xc4, 0xf0, 0x01, 0x41, 0xbc, 0x05, 0xdc, 0x80, 0x00, 0x00, 0x00, 0x2f, 0x60, 0x00, 0x00, 0x02, 0x02, 0x77, + 0xc0, 0x00, 0x00, 0x00, 0xbf, 0xf0, 0x03, 0x00, 0x21, 0x00, 0x30, 0x02, 0x00, 0x80, 0x14, 0x00, 0xc0, 0x0c, 0x00, + 0x90, 0x03, 0x04, 0x21, 0x80, 0x18, 0x01, 0x82, 0x10, 0xc1, 0x08, 0x60, 0x80, 0x30, 0x40, 0x18, 0x20, 0x0c, 0x10, + 0x86, 0x08, 0x43, 0x04, 0x21, 0x82, 0x10, 0xc1, 0x00, 0x60, 0x80, 0x24, 0x10, 0x06, 0x08, 0x03, 0x04, 0x20, 0x82, + 0x10, 0x41, 0x08, 0x60, 0x84, 0x30, 0x42, 0x18, 0x21, 0x0c, 0x10, 0x82, 0x08, 0x41, 0x04, 0x21, 0x41, 0x00, 0x60, + 0x80, 0x30, 0x40, 0x12, 0x08, 0x43, 0x04, 0x21, 0x82, 0x10, 0xc1, 0x08, 0x60, 0x84, 0x30, 0x42, 0x18, 0x20, 0x0c, + 0x10, 0x04, 0x20, 0x80, 0x30, 0x40, 0x18, 0x20, 0x0c, 0x10, 0x06, 0x08, 0x43, 0x04, 0x21, 0x41, 0x08, 0x20, 0x84, + 0x10, 0x42, 0x08, 0x21, 0x04, 0x10, 0x06, 0x08, 0x02, 0x41, 0x00, 0x40, 0x82, 0x00, 0xc1, 0x00, 0x60, 0x80, 0x30, + 0x40, 0x12, 0x08, 0x41, 0x04, 0x20, 0x02, 0x08, 0x41, 0x04, 0x20, 0x20, 0x84, 0x30, 0x42, 0x18, 0x21, 0x0c, 0x10, + 0x86, 0x08, 0x43, 0x04, 0x21, 0x08, 0x20, 0x0c, 0x10, 0x06, 0x08, 0x03, 0x04, 0x01, 0x82, 0x10, 0xc0, 0x0c, 0x30, + 0x84, 0x21, 0x80, 0x12, 0xd7, 0xd5, 0x46, 0xc0, 0x3c, 0x00, 0x03, 0xf8, 0x18, 0xc0, 0x00, 0x82, 0x06, 0x00, 0x00, + 0x20, 0x81, 0xa6, 0x00, 0x08, 0x00, 0x2f, 0x84, 0x00, 0x36, 0xc0, 0x01, 0x00, 0x0c, 0x10, 0x00, 0x40, 0x03, 0x08, + 0x00, 0x10, 0x40, 0xc3, 0x00, 0x04, 0x10, 0x31, 0x00, 0x01, 0x00, 0x0c, 0x70, 0x00, 0x40, 0x03, 0x2c, 0x00, 0x10, + 0x00, 0xcc, 0x00, 0x04, 0x00, 0x34, 0x00, 0x01, 0x00, 0x0d, 0x10, 0x00, 0x40, 0x03, 0x48, 0x00, 0x10, 0x00, 0xd8, + 0x00, 0x04, 0x00, 0x36, 0x40, 0x01, 0x00, 0x0e, 0x50, 0x00, 0x41, 0x03, 0x98, 0x00, 0x10, 0x00, 0xe7, 0x00, 0x04, + 0x10, 0x3a, 0x00, 0x01, 0x04, 0x0e, 0x90, 0x00, 0x41, 0x03, 0xa8, 0x00, 0x10, 0x00, 0xef, 0x00, 0x04, 0x00, 0x3f, + 0xc0, 0x01, 0x04, 0x1c, 0x60, 0x00, 0x41, 0x46, 0x08, 0x20, 0x63, 0x00, 0x02, 0x48, 0x18, 0xc0, 0x00, 0x8a, 0x0e, + 0x30, 0x00, 0x20, 0xa0, 0x04, 0x10, 0x51, 0x82, 0x0e, 0x00, 0x00, 0x20, 0x83, 0xa6, 0x00, 0x08, 0x08, 0xc1, 0x04, + 0x15, 0x30, 0x81, 0x8c, 0x00, 0x08, 0x20, 0xaf, 0x84, 0x0c, 0x60, 0x00, 0x41, 0x07, 0xfc, 0x00, 0x10, 0x51, 0x82, + 0x08, 0x2f, 0xe1, 0x07, 0x18, 0x00, 0x10, 0x41, 0xe9, 0x00, 0x04, 0x14, 0x60, 0x82, 0x0b, 0x48, 0x41, 0xc6, 0x00, + 0x04, 0x10, 0x76, 0xc0, 0x01, 0x01, 0x18, 0x20, 0x82, 0xb6, 0x10, 0x31, 0x80, 0x01, 0x04, 0x1d, 0x90, 0x00, 0x40, + 0x46, 0x08, 0x00, 0xac, 0x84, 0x0c, 0x60, 0x00, 0x40, 0x07, 0x1c, 0x00, 0x10, 0x11, 0x82, 0x08, 0x28, 0xe1, 0x03, + 0x18, 0x00, 0x10, 0x41, 0xc6, 0x00, 0x04, 0x14, 0x40, 0x80, 0x0a, 0x30, 0x41, 0xc4, 0x00, 0x04, 0x00, 0x71, 0x80, + 0x01, 0x05, 0x0c, 0x20, 0x82, 0x8c, 0x10, 0x70, 0xc0, 0x01, 0x04, 0x1c, 0x60, 0x00, 0x41, 0x42, 0x08, 0x20, 0xa3, + 0x04, 0x1c, 0x20, 0x00, 0x41, 0x07, 0x18, 0x00, 0x10, 0x50, 0x42, 0x00, 0x28, 0xc1, 0x07, 0x04, 0x00, 0x10, 0x01, + 0xc0, 0x00, 0x04, 0x14, 0x00, 0x82, 0x06, 0x00, 0x00, 0x24, 0x03, 0xa6, 0x00, 0x08, 0x08, 0x01, 0x04, 0x15, 0x30, + 0x81, 0x80, 0x00, 0x08, 0x20, 0xaf, 0x84, 0x0c, 0x00, 0x00, 0x41, 0x07, 0xa4, 0x00, 0x10, 0x10, 0x02, 0x00, 0x2d, + 0x21, 0x03, 0x00, 0x00, 0x10, 0x01, 0xe8, 0x00, 0x04, 0x14, 0x00, 0x82, 0x0b, 0x40, 0x41, 0xc0, 0x00, 0x04, 0x10, + 0x79, 0xc0, 0x01, 0x05, 0x00, 0x20, 0x82, 0xce, 0x10, 0x70, 0x00, 0x01, 0x04, 0x1e, 0x50, 0x00, 0x41, 0x40, 0x08, + 0x20, 0xb2, 0x84, 0x1c, 0x00, 0x00, 0x41, 0x07, 0x6c, 0x00, 0x10, 0x10, 0x02, 0x08, 0x2b, 0x61, 0x03, 0x00, 0x00, + 0x10, 0x41, 0xd2, 0x00, 0x04, 0x04, 0x00, 0x80, 0x0a, 0x90, 0x40, 0xc0, 0x00, 0x04, 0x00, 0x74, 0x40, 0x01, 0x01, + 0x00, 0x20, 0x02, 0xa2, 0x10, 0x30, 0x00, 0x01, 0x00, 0x1c, 0x70, 0x00, 0x40, 0x40, 0x08, 0x20, 0xa3, 0x84, 0x0c, + 0x00, 0x00, 0x41, 0x07, 0x10, 0x00, 0x10, 0x10, 0x02, 0x08, 0x28, 0x81, 0x03, 0x00, 0x00, 0x10, 0x41, 0xc2, 0x00, + 0x04, 0x14, 0x00, 0x82, 0x0a, 0x10, 0x41, 0xc0, 0x00, 0x04, 0x10, 0x57, 0xc2, 0x06, 0x98, 0x00, 0x20, 0x03, 0xce, + 0x00, 0x08, 0x2a, 0x61, 0x00, 0x16, 0x70, 0x83, 0xa6, 0x00, 0x08, 0x00, 0xf2, 0x80, 0x02, 0x0a, 0x98, 0x40, 0x05, + 0x94, 0x20, 0xe9, 0x80, 0x02, 0x00, 0x3a, 0x60, 0x00, 0x80, 0x84, 0x10, 0x41, 0x53, 0x08, 0x18, 0x40, 0x00, 0x82, + 0x0a, 0xf8, 0x40, 0xdb, 0x00, 0x04, 0x00, 0x57, 0xc2, 0x06, 0x38, 0x00, 0x20, 0x02, 0xbe, 0x10, 0x30, 0x80, 0x01, + 0x04, 0x1e, 0x90, 0x00, 0x40, 0x5b, 0x08, 0x00, 0xb4, 0x84, 0x0d, 0xb0, 0x00, 0x40, 0x07, 0xa0, 0x00, 0x10, 0x16, + 0xc2, 0x00, 0x2d, 0x01, 0x03, 0x6c, 0x00, 0x10, 0x01, 0xe5, 0x00, 0x04, 0x05, 0xb0, 0x80, 0x0b, 0x28, 0x40, 0xdb, + 0x00, 0x04, 0x00, 0x76, 0xc0, 0x01, 0x01, 0x0c, 0x20, 0x82, 0xb6, 0x10, 0x30, 0xc0, 0x01, 0x04, 0x1d, 0xb0, 0x00, + 0x40, 0x42, 0x08, 0x20, 0xad, 0x84, 0x0c, 0x20, 0x00, 0x41, 0x07, 0x6c, 0x00, 0x10, 0x10, 0x42, 0x00, 0x2b, 0x61, + 0x03, 0x04, 0x00, 0x10, 0x01, 0xff, 0x00, 0x04, 0x14, 0x10, 0x80, 0x0b, 0xf8, 0x41, 0xc1, 0x00, 0x04, 0x00, 0x74, + 0x00, 0x01, 0x01, 0x04, 0x20, 0x02, 0xa0, 0x10, 0x30, 0x40, 0x01, 0x00, 0x1c, 0xb0, 0x00, 0x40, 0x41, 0x08, 0x00, + 0xa5, 0x84, 0x0c, 0x10, 0x00, 0x40, 0x07, 0x10, 0x00, 0x10, 0x10, 0x42, 0x00, 0x28, 0x81, 0x03, 0x04, 0x00, 0x10, + 0x01, 0xc3, 0x00, 0x04, 0x14, 0x10, 0x80, 0x0a, 0x18, 0x41, 0xc1, 0x00, 0x04, 0x00, 0x7a, 0x40, 0x01, 0x01, 0x08, + 0x20, 0x02, 0xd2, 0x10, 0x30, 0x80, 0x01, 0x00, 0x1e, 0x80, 0x00, 0x41, 0x42, 0x08, 0x20, 0xb4, 0x04, 0x1c, 0x20, + 0x00, 0x41, 0x07, 0x9c, 0x00, 0x10, 0x50, 0x82, 0x08, 0x2c, 0xe1, 0x07, 0x08, 0x00, 0x10, 0x41, 0xe5, 0x00, 0x04, + 0x14, 0x20, 0x82, 0x0b, 0x28, 0x41, 0xc2, 0x00, 0x04, 0x10, 0x74, 0x80, 0x01, 0x01, 0x08, 0x20, 0x02, 0xa4, 0x10, + 0x30, 0x80, 0x01, 0x00, 0x1d, 0x10, 0x00, 0x40, 0x42, 0x08, 0x00, 0xa8, 0x84, 0x0c, 0x20, 0x00, 0x40, 0x07, 0x1c, + 0x00, 0x10, 0x10, 0x82, 0x08, 0x28, 0xe1, 0x03, 0x08, 0x00, 0x10, 0x41, 0xc4, 0x00, 0x04, 0x04, 0x20, 0x82, 0x0a, + 0x20, 0x40, 0xc2, 0x00, 0x04, 0x10, 0x70, 0x80, 0x01, 0x05, 0x08, 0x20, 0x81, 0x84, 0x00, 0x09, 0x21, 0xb2, 0x84, + 0x14, 0x60, 0x83, 0x84, 0x00, 0x09, 0x28, 0x01, 0x04, 0x0c, 0x60, 0x10, 0x49, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, + 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, + 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, + 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, + 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0x63, 0xff, 0xff, 0xfe, 0xf9, 0xc0, 0x00, 0x01, 0xfb, 0x10, + 0x3e, 0x74, 0x00, 0x00, 0x11, 0xf3, 0x80, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x02, 0x3f, 0x8b, 0xa1, 0xe1, 0xe2, 0xf1, + 0x70, 0x43, 0xc3, 0x91, 0x78, 0xbc, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x38, 0x87, 0x04, 0x3c, 0x38, 0x43, 0xc3, 0x90, + 0xf0, 0xf1, 0x78, 0xbc, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x39, 0x0f, 0x0e, 0x08, 0x78, 0x70, 0x87, 0x87, 0x22, + 0xf1, 0x72, 0x2f, 0x17, 0x87, 0x87, 0x8b, 0xc5, 0xc8, 0x78, 0x78, 0x78, 0x70, 0x23, 0xf8, 0xfe, 0x4f, 0xc9, 0xf8, + 0xb9, 0x17, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0x00, 0x00, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, + 0x40, 0x14, 0x04, 0x05, 0x01, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, + 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, + 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, + 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, + 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x14, 0x04, 0x05, 0x01, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, + 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, + 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x3c, 0x08, 0x02, 0x48, 0x07, 0x8c, 0xbc, 0xd0, 0x30, 0x1a, + 0x58, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x4a, 0x5d, 0xe3, 0x80, 0x74, 0x00, 0x2c, 0x10, 0x00, 0xcd, 0x25, + 0x08, 0x00, 0x80, 0x01, 0x2c, 0x3f, 0xc0, 0x12, 0x00, 0x90, 0x04, 0x10, 0x04, 0x80, 0x24, 0x01, 0x20, 0x09, 0x00, + 0x48, 0x02, 0x40, 0x12, 0x00, 0x90, 0x04, 0x80, 0x24, 0x01, 0x20, 0x09, 0x00, 0x48, 0x02, 0x40, 0x12, 0x00, 0x90, + 0x04, 0x80, 0x24, 0x01, 0x20, 0x09, 0x00, 0x48, 0x0a, 0x04, 0x01, 0x20, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, + 0x20, 0x20, 0x90, 0x10, 0x48, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x81, 0x01, 0x04, 0x80, 0xa0, 0x40, 0x41, 0x20, 0x28, + 0x10, 0x10, 0x48, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x81, 0x01, 0x04, 0x80, 0xa0, 0x40, 0x41, 0x20, 0x28, 0x10, 0x10, + 0x48, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x81, 0x00, 0x48, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, + 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, 0x24, 0x05, 0x02, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, + 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, 0x24, 0x05, 0x02, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, + 0x90, 0x10, 0x48, 0x0a, 0x04, 0x04, 0x12, 0x02, 0x81, 0x01, 0x04, 0x80, 0xa0, 0x40, 0x41, 0x20, 0x20, 0x90, 0x10, + 0x48, 0x08, 0x24, 0x05, 0x02, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, + 0x24, 0x05, 0x02, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, 0x24, 0x05, + 0x02, 0x02, 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, 0x24, 0x05, 0x02, 0x02, + 0x09, 0x01, 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x08, 0x24, 0x05, 0x02, 0x02, 0x09, 0x01, + 0x40, 0x80, 0x82, 0x40, 0x50, 0x20, 0x20, 0x90, 0x14, 0x08, 0x02, 0x40, 0xc0, 0x10, 0x20, 0x04, 0x0c, 0x43, 0x2a, + 0x78, 0x18, 0x00, 0x00, 0x40, 0x20, 0x0c, 0x03, 0x82, 0x60, 0xd8, 0x4a, 0x13, 0x85, 0x02, 0x08, 0x98, 0x26, 0x88, + 0x00, 0x44, 0x02, 0x0a, 0x18, 0x32, 0xc0, 0x80, 0x00, 0x02, 0x01, 0x80, 0x70, 0x4c, 0x1b, 0x09, 0x42, 0x71, 0x36, + 0x90, 0x00}; + + cbit_ref bref(rrc_msg, sizeof(rrc_msg)); + + ul_dcch_msg_s ul_dcch_msg; + TESTASSERT(ul_dcch_msg.unpack(bref) == SRSASN_SUCCESS); + + TESTASSERT(ul_dcch_msg.msg.type() == ul_dcch_msg_type_c::types::c1); + TESTASSERT(ul_dcch_msg.msg.c1().type() == ul_dcch_msg_type_c::c1_c_::types::ue_cap_info); + + // assign to stack-allocated variable + asn1::rrc::ue_cap_info_s ue_cap; + ue_cap = ul_dcch_msg.msg.c1().ue_cap_info(); + + TESTASSERT(ue_cap.crit_exts.c1().type() == asn1::rrc::ue_cap_info_s::crit_exts_c_::c1_c_::types::ue_cap_info_r8); + TESTASSERT(ue_cap.crit_exts.c1().ue_cap_info_r8().ue_cap_rat_container_list.size() == 1); + TESTASSERT(ue_cap.crit_exts.c1().ue_cap_info_r8().ue_cap_rat_container_list[0].rat_type == + asn1::rrc::rat_type_e::eutra); + + asn1::rrc::ue_eutra_cap_s eutra_capabilities; + asn1::cbit_ref bref2(ue_cap.crit_exts.c1().ue_cap_info_r8().ue_cap_rat_container_list[0].ue_cap_rat_container.data(), + ue_cap.crit_exts.c1().ue_cap_info_r8().ue_cap_rat_container_list[0].ue_cap_rat_container.size()); + TESTASSERT(eutra_capabilities.unpack(bref2) == asn1::SRSASN_SUCCESS); + +#if JSON_OUTPUT + int unpacked_len = bref2.distance_bytes(); + asn1::json_writer json_writer1; + eutra_capabilities.to_json(json_writer1); + srslog::fetch_basic_logger("ASN1").info( + rrc_msg, sizeof(rrc_msg), "UE cap info unpacked (%d B): \n %s", unpacked_len, json_writer1.to_string().c_str()); +#endif + + return 0; +} + int main(int argc, char** argv) { auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false); @@ -187,11 +689,16 @@ int main(int argc, char** argv) srsran::mac_pcap pcap; pcap.open("ul_dcch.pcap"); TESTASSERT(rrc_ue_cap_info_test(&pcap) == 0); + TESTASSERT(rrc_ue_cap_info_pack_buff_size_test(&pcap, 64) == -1); + TESTASSERT(rrc_ue_cap_info_pack_buff_size_test(&pcap, 128) == 0); #else // TESTASSERT(rrc_ue_cap_info_test(NULL) == 0); + TESTASSERT(rrc_ue_cap_info_pack_buff_size_test(NULL, 64) == -1); + TESTASSERT(rrc_ue_cap_info_pack_buff_size_test(NULL, 128) == 0); #endif TESTASSERT(pack_fail_test() == -1); TESTASSERT(rrc_nr_test_scg_fail_packing() == SRSRAN_SUCCESS) + TESTASSERT(rrc_ue_cap_information_test() == 0); #if PCAP pcap.close(); diff --git a/lib/test/common/CMakeLists.txt b/lib/test/common/CMakeLists.txt index 1a9b480c94..72854d9693 100644 --- a/lib/test/common/CMakeLists.txt +++ b/lib/test/common/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/test/common/bcd_helpers_test.cc b/lib/test/common/bcd_helpers_test.cc index a8f5062777..4ff6eeebf9 100644 --- a/lib/test/common/bcd_helpers_test.cc +++ b/lib/test/common/bcd_helpers_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/byte_buffer_queue_test.cc b/lib/test/common/byte_buffer_queue_test.cc index 7c80c5e41d..21246df205 100644 --- a/lib/test/common/byte_buffer_queue_test.cc +++ b/lib/test/common/byte_buffer_queue_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/choice_type_test.cc b/lib/test/common/choice_type_test.cc index e9970f17cf..14ff33ce96 100644 --- a/lib/test/common/choice_type_test.cc +++ b/lib/test/common/choice_type_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/mac_pcap_net_test.cc b/lib/test/common/mac_pcap_net_test.cc index cd33d55aef..16c0592c72 100644 --- a/lib/test/common/mac_pcap_net_test.cc +++ b/lib/test/common/mac_pcap_net_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/multiqueue_test.cc b/lib/test/common/multiqueue_test.cc index f45e0d1317..d24852af87 100644 --- a/lib/test/common/multiqueue_test.cc +++ b/lib/test/common/multiqueue_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/network_utils_test.cc b/lib/test/common/network_utils_test.cc index b06a0561fb..719bbe2654 100644 --- a/lib/test/common/network_utils_test.cc +++ b/lib/test/common/network_utils_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -61,13 +61,19 @@ int test_socket_handler() const char* server_addr = "127.0.100.1"; using namespace srsran::net_utils; - TESTASSERT(sctp_init_socket(&server_socket, socket_type::seqpacket, server_addr, server_port)); + TESTASSERT(server_socket.open_socket( + srsran::net_utils::addr_family::ipv4, socket_type::seqpacket, srsran::net_utils::protocol_type::SCTP)); + TESTASSERT(server_socket.bind_addr(server_addr, server_port)); TESTASSERT(server_socket.start_listen()); logger.info("Listening from fd=%d", server_socket.fd()); - TESTASSERT(sctp_init_socket(&client_socket, socket_type::seqpacket, "127.0.0.1", 0)); - TESTASSERT(sctp_init_socket(&client_socket2, socket_type::seqpacket, "127.0.0.2", 0)); + TESTASSERT(client_socket.open_socket( + srsran::net_utils::addr_family::ipv4, socket_type::seqpacket, srsran::net_utils::protocol_type::SCTP)); + TESTASSERT(client_socket.bind_addr("127.0.0.1", 0)); TESTASSERT(client_socket.connect_to(server_addr, server_port)); + TESTASSERT(client_socket2.open_socket( + srsran::net_utils::addr_family::ipv4, socket_type::seqpacket, srsran::net_utils::protocol_type::SCTP)); + TESTASSERT(client_socket2.bind_addr("127.0.0.2", 0)); TESTASSERT(client_socket2.connect_to(server_addr, server_port)); // register server Rx handler @@ -127,12 +133,18 @@ int test_socket_handler() int test_sctp_bind_error() { srsran::unique_socket sock; - TESTASSERT(not srsran::net_utils::sctp_init_socket( - &sock, srsran::net_utils::socket_type::seqpacket, "1.1.1.1", 8000)); // Bogus IP address - // should not be able to bind - TESTASSERT(srsran::net_utils::sctp_init_socket( - &sock, srsran::net_utils::socket_type::seqpacket, "127.0.0.1", 8000)); // Good IP address - // should be able to bind + TESTASSERT(sock.open_socket(srsran::net_utils::addr_family::ipv4, + srsran::net_utils::socket_type::seqpacket, + srsran::net_utils::protocol_type::SCTP)); + TESTASSERT(not sock.bind_addr("1.1.1.1", 8000)); // Bogus IP address + // should not be able to bind + + srsran::unique_socket sock2; + TESTASSERT(sock2.open_socket(srsran::net_utils::addr_family::ipv4, + srsran::net_utils::socket_type::seqpacket, + srsran::net_utils::protocol_type::SCTP)); + TESTASSERT(sock.bind_addr("127.0.0.1", 8000)); // Good IP address + // should be able to bind return SRSRAN_SUCCESS; } diff --git a/lib/test/common/stack_procedure_test.cc b/lib/test/common/stack_procedure_test.cc index 57474bd428..7307712d82 100644 --- a/lib/test/common/stack_procedure_test.cc +++ b/lib/test/common/stack_procedure_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/task_scheduler_test.cc b/lib/test/common/task_scheduler_test.cc index bcb4f903d3..62cef82c2f 100644 --- a/lib/test/common/task_scheduler_test.cc +++ b/lib/test/common/task_scheduler_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/test_eea1.cc b/lib/test/common/test_eea1.cc index b92178c7a6..ad82d05e0a 100644 --- a/lib/test/common/test_eea1.cc +++ b/lib/test/common/test_eea1.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/test_eea2.cc b/lib/test/common/test_eea2.cc index cb70de3210..d539387c00 100644 --- a/lib/test/common/test_eea2.cc +++ b/lib/test/common/test_eea2.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/test_eea3.cc b/lib/test/common/test_eea3.cc index 270c699fd4..84d628d35f 100644 --- a/lib/test/common/test_eea3.cc +++ b/lib/test/common/test_eea3.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/test_eia1.cc b/lib/test/common/test_eia1.cc index dd7a16d7ba..30adb15197 100644 --- a/lib/test/common/test_eia1.cc +++ b/lib/test/common/test_eia1.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/test_eia3.cc b/lib/test/common/test_eia3.cc index 83fd3a6e2d..2bf3cf069a 100644 --- a/lib/test/common/test_eia3.cc +++ b/lib/test/common/test_eia3.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/test_f12345.cc b/lib/test/common/test_f12345.cc index fbd72b493b..bd0e7c549e 100644 --- a/lib/test/common/test_f12345.cc +++ b/lib/test/common/test_f12345.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/test_security_kdf.cc b/lib/test/common/test_security_kdf.cc index d18cd8c8b3..77c8a3640d 100644 --- a/lib/test/common/test_security_kdf.cc +++ b/lib/test/common/test_security_kdf.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -167,6 +167,26 @@ int test_generate_k_nas() return SRSRAN_SUCCESS; } +int test_generate_k_gnb() +{ + auto& logger = srslog::fetch_basic_logger("LOG", false); + + as_key_t k_gnb_o; + + as_key_t k_gnb = {0x49, 0x3a, 0x16, 0xc5, 0x8b, 0x77, 0xb6, 0x27, 0xfa, 0x3f, 0x1a, 0xc6, 0x34, 0x4c, 0x18, 0x30, + 0x39, 0xf0, 0x1b, 0xa0, 0xcb, 0x76, 0x36, 0xbb, 0xcc, 0xc4, 0x36, 0x5b, 0x02, 0x3b, 0xd5, 0x62}; + + as_key_t k_amf = {0xd6, 0x55, 0xf1, 0x61, 0x42, 0x03, 0x5d, 0x4d, 0x72, 0xca, 0x39, 0x58, 0x3d, 0x22, 0x8d, 0x2d, + 0xd2, 0xec, 0x0c, 0xa7, 0x92, 0x9a, 0xd0, 0x07, 0xf5, 0x3b, 0x38, 0x2d, 0x05, 0x54, 0x44, 0x05}; + + uint32_t nas_ul_count = 0; + + TESTASSERT(srsran::security_generate_k_gnb(k_amf, nas_ul_count, k_gnb_o) == SRSRAN_SUCCESS); + TESTASSERT(k_gnb_o == k_gnb); + + return SRSRAN_SUCCESS; +} + int test_generate_k_enb() { auto& logger = srslog::fetch_basic_logger("LOG", false); @@ -442,7 +462,7 @@ int main(int argc, char** argv) TESTASSERT(test_generate_up_keys() == SRSRAN_SUCCESS); TESTASSERT(test_generate_k_enb_star() == SRSRAN_SUCCESS); TESTASSERT(test_generate_k_nh() == SRSRAN_SUCCESS); - + TESTASSERT(test_generate_k_gnb() == SRSRAN_SUCCESS); TESTASSERT(test_generate_res_star() == SRSRAN_SUCCESS); TESTASSERT(test_generate_k_ausf() == SRSRAN_SUCCESS); TESTASSERT(test_generate_k_seaf() == SRSRAN_SUCCESS); diff --git a/lib/test/common/timeout_test.cc b/lib/test/common/timeout_test.cc index 69bc198e81..57e788be60 100644 --- a/lib/test/common/timeout_test.cc +++ b/lib/test/common/timeout_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/timer_test.cc b/lib/test/common/timer_test.cc index 2854acfb88..d0020a08aa 100644 --- a/lib/test/common/timer_test.cc +++ b/lib/test/common/timer_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/common/tti_point_test.cc b/lib/test/common/tti_point_test.cc index cd376f7aab..4b3ecee376 100644 --- a/lib/test/common/tti_point_test.cc +++ b/lib/test/common/tti_point_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/pdcp/CMakeLists.txt b/lib/test/pdcp/CMakeLists.txt index 39b00ac807..07f0c325b1 100644 --- a/lib/test/pdcp/CMakeLists.txt +++ b/lib/test/pdcp/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/test/pdcp/pdcp_base_test.h b/lib/test/pdcp/pdcp_base_test.h index d7c7ab88d6..a81ceac598 100644 --- a/lib/test/pdcp/pdcp_base_test.h +++ b/lib/test/pdcp/pdcp_base_test.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/pdcp/pdcp_lte_test.h b/lib/test/pdcp/pdcp_lte_test.h index 01848d9b1c..d2ccbb7b43 100644 --- a/lib/test/pdcp/pdcp_lte_test.h +++ b/lib/test/pdcp/pdcp_lte_test.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/pdcp/pdcp_lte_test_discard_sdu.cc b/lib/test/pdcp/pdcp_lte_test_discard_sdu.cc index 6451cbf556..0e48079144 100644 --- a/lib/test/pdcp/pdcp_lte_test_discard_sdu.cc +++ b/lib/test/pdcp/pdcp_lte_test_discard_sdu.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/pdcp/pdcp_lte_test_rx.cc b/lib/test/pdcp/pdcp_lte_test_rx.cc index c0bb3ecadd..57e5013670 100644 --- a/lib/test/pdcp/pdcp_lte_test_rx.cc +++ b/lib/test/pdcp/pdcp_lte_test_rx.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/pdcp/pdcp_lte_test_status_report.cc b/lib/test/pdcp/pdcp_lte_test_status_report.cc index 25b066ebf0..1fcaef37ad 100644 --- a/lib/test/pdcp/pdcp_lte_test_status_report.cc +++ b/lib/test/pdcp/pdcp_lte_test_status_report.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/pdcp/pdcp_nr_test.h b/lib/test/pdcp/pdcp_nr_test.h index 7417a67693..5163f6841d 100644 --- a/lib/test/pdcp/pdcp_nr_test.h +++ b/lib/test/pdcp/pdcp_nr_test.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -66,18 +66,18 @@ uint8_t sdu1[] = {0x18, 0xe2}; uint8_t sdu2[] = {0xde, 0xad}; // Test PDUs for rx (generated from SDU1) -uint8_t pdu1_count0_snlen12[] = {0x80, 0x00, 0x8f, 0xe3, 0xe0, 0xdf, 0x82, 0x92}; -uint8_t pdu1_count2048_snlen12[] = {0x88, 0x00, 0x8d, 0x2c, 0x47, 0x5e, 0xb1, 0x5b}; -uint8_t pdu1_count4096_snlen12[] = {0x80, 0x00, 0x97, 0xbe, 0xa3, 0x32, 0xfa, 0x61}; -uint8_t pdu1_count4294967295_snlen12[] = {0x8f, 0xff, 0x1e, 0x47, 0xe6, 0x86, 0x28, 0x6c}; -uint8_t pdu1_count0_snlen18[] = {0x80, 0x00, 0x00, 0x8f, 0xe3, 0xe0, 0xdf, 0x82, 0x92}; -uint8_t pdu1_count131072_snlen18[] = {0x82, 0x00, 0x00, 0x15, 0x01, 0xf4, 0xb0, 0xfc, 0xc5}; -uint8_t pdu1_count262144_snlen18[] = {0x80, 0x00, 0x00, 0xc2, 0x47, 0xa8, 0xdd, 0xc0, 0x73}; -uint8_t pdu1_count4294967295_snlen18[] = {0x83, 0xff, 0xff, 0x1e, 0x47, 0xe6, 0x86, 0x28, 0x6c}; +uint8_t pdu1_count0_snlen12[] = {0x80, 0x00, 0x8f, 0xe3, 0xc7, 0x1b, 0xad, 0x14}; +uint8_t pdu1_count2048_snlen12[] = {0x88, 0x00, 0x8d, 0x2c, 0xe5, 0x38, 0xc0, 0x42}; +uint8_t pdu1_count4096_snlen12[] = {0x80, 0x00, 0x97, 0xbe, 0xee, 0x62, 0xf5, 0xe0}; +uint8_t pdu1_count4294967295_snlen12[] = {0x8f, 0xff, 0x1e, 0x47, 0xa9, 0x55, 0xa9, 0xd8}; +uint8_t pdu1_count0_snlen18[] = {0x80, 0x00, 0x00, 0x8f, 0xe3, 0x37, 0x33, 0xd5, 0x64}; +uint8_t pdu1_count131072_snlen18[] = {0x82, 0x00, 0x00, 0x15, 0x01, 0x99, 0x97, 0xe0, 0x4e}; +uint8_t pdu1_count262144_snlen18[] = {0x80, 0x00, 0x00, 0xc2, 0x47, 0xc2, 0xee, 0x46, 0xd9}; +uint8_t pdu1_count4294967295_snlen18[] = {0x83, 0xff, 0xff, 0x1e, 0x47, 0x78, 0xb8, 0x7a, 0x9f}; // Test PDUs for rx (generated from SDU2) -uint8_t pdu2_count1_snlen12[] = {0x80, 0x01, 0x5e, 0x3d, 0x64, 0xaf, 0xac, 0x7c}; -uint8_t pdu2_count1_snlen18[] = {0x80, 0x00, 0x01, 0x5e, 0x3d, 0x64, 0xaf, 0xac, 0x7c}; +uint8_t pdu2_count1_snlen12[] = {0x80, 0x01, 0x5e, 0x3d, 0x70, 0x6a, 0xa4, 0x90}; +uint8_t pdu2_count1_snlen18[] = {0x80, 0x00, 0x01, 0x5e, 0x3d, 0x93, 0xfe, 0xcc, 0x2e}; // This is the normal initial state. All state variables are set to zero pdcp_initial_state normal_init_state = {}; diff --git a/lib/test/pdcp/pdcp_nr_test_discard_sdu.cc b/lib/test/pdcp/pdcp_nr_test_discard_sdu.cc index 3147f74979..fea11a80ec 100644 --- a/lib/test/pdcp/pdcp_nr_test_discard_sdu.cc +++ b/lib/test/pdcp/pdcp_nr_test_discard_sdu.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/pdcp/pdcp_nr_test_rx.cc b/lib/test/pdcp/pdcp_nr_test_rx.cc index 832790375a..ce2559d975 100644 --- a/lib/test/pdcp/pdcp_nr_test_rx.cc +++ b/lib/test/pdcp/pdcp_nr_test_rx.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,48 +22,60 @@ #include /* - * Genric function to test reception of in-sequence packets + * Generic class to test reception of in-sequence packets */ -int test_rx(std::vector events, - const pdcp_initial_state& init_state, - uint8_t pdcp_sn_len, - uint32_t n_sdus_exp, - const srsran::unique_byte_buffer_t& sdu_exp, - srslog::basic_logger& logger) - +class test_rx_helper { - srsran::pdcp_config_t cfg_rx = {1, - srsran::PDCP_RB_IS_DRB, - srsran::SECURITY_DIRECTION_DOWNLINK, - srsran::SECURITY_DIRECTION_UPLINK, - pdcp_sn_len, - srsran::pdcp_t_reordering_t::ms500, - srsran::pdcp_discard_timer_t::infinity, - false, - srsran::srsran_rat_t::nr}; - - pdcp_nr_test_helper pdcp_hlp_rx(cfg_rx, sec_cfg, logger); - srsran::pdcp_entity_nr* pdcp_rx = &pdcp_hlp_rx.pdcp; - gw_dummy* gw_rx = &pdcp_hlp_rx.gw; - srsue::stack_test_dummy* stack = &pdcp_hlp_rx.stack; - pdcp_hlp_rx.set_pdcp_initial_state(init_state); - - // Generate test message and encript/decript SDU. - for (pdcp_test_event_t& event : events) { - // Decript and integrity check the PDU - pdcp_rx->write_pdu(std::move(event.pkt)); - for (uint32_t i = 0; i < event.ticks; ++i) { - stack->run_tti(); +public: + pdcp_nr_test_helper pdcp_hlp_rx; + srsran::pdcp_entity_nr& pdcp_rx; + gw_dummy& gw_rx; + srsue::stack_test_dummy& stack; + srslog::basic_logger& logger; + + test_rx_helper(uint8_t pdcp_sn_len, srslog::basic_logger& logger) : + pdcp_hlp_rx({1, + srsran::PDCP_RB_IS_DRB, + srsran::SECURITY_DIRECTION_DOWNLINK, + srsran::SECURITY_DIRECTION_UPLINK, + pdcp_sn_len, + srsran::pdcp_t_reordering_t::ms500, + srsran::pdcp_discard_timer_t::infinity, + false, + srsran::srsran_rat_t::nr}, + sec_cfg, + logger), + pdcp_rx(pdcp_hlp_rx.pdcp), + gw_rx(pdcp_hlp_rx.gw), + stack(pdcp_hlp_rx.stack), + logger(logger) + {} + + int test_rx(std::vector events, + const pdcp_initial_state& init_state, + uint32_t n_sdus_exp, + const srsran::unique_byte_buffer_t& sdu_exp) + + { + pdcp_hlp_rx.set_pdcp_initial_state(init_state); + + // Generate test message and encrypt/decrypt SDU. + for (pdcp_test_event_t& event : events) { + // Decrypt and integrity check the PDU + pdcp_rx.write_pdu(std::move(event.pkt)); + for (uint32_t i = 0; i < event.ticks; ++i) { + stack.run_tti(); + } } - } - // Test if the number of RX packets - TESTASSERT(gw_rx->rx_count == n_sdus_exp); - srsran::unique_byte_buffer_t sdu_act = srsran::make_byte_buffer(); - gw_rx->get_last_pdu(sdu_act); - TESTASSERT(compare_two_packets(sdu_exp, sdu_act) == 0); - return 0; -} + // Test if the number of RX packets + TESTASSERT_EQ(gw_rx.rx_count, n_sdus_exp); + srsran::unique_byte_buffer_t sdu_act = srsran::make_byte_buffer(); + gw_rx.get_last_pdu(sdu_act); + TESTASSERT(compare_two_packets(sdu_exp, sdu_act) == 0); + return 0; + } +}; /* * RX Test: PDCP Entity with SN LEN = 12 and 18. @@ -83,12 +95,15 @@ int test_rx_all(srslog::basic_logger& logger) * This tests correct handling of HFN in the case of SN wraparound (SN LEN 12) */ { - std::vector test1_counts(2); // Test two packets + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("RX COUNT [4095,4096], 12 bit SN"); + test_rx_helper rx_helper(srsran::PDCP_SN_LEN_12, logger); + std::vector test1_counts(2); // Test two packets std::iota(test1_counts.begin(), test1_counts.end(), 4095); // Starting at COUNT 4095 std::vector test1_pdus = gen_expected_pdus_vector(tst_sdu1, test1_counts, srsran::PDCP_SN_LEN_12, sec_cfg, logger); pdcp_initial_state test1_init_state = {.tx_next = 4095, .rx_next = 4095, .rx_deliv = 4095, .rx_reord = 0}; - TESTASSERT(test_rx(std::move(test1_pdus), test1_init_state, srsran::PDCP_SN_LEN_12, 2, tst_sdu1, logger) == 0); + TESTASSERT(rx_helper.test_rx(std::move(test1_pdus), test1_init_state, 2, tst_sdu1) == 0); } /* * RX Test 2: PDCP Entity with SN LEN = 12 @@ -97,13 +112,16 @@ int test_rx_all(srslog::basic_logger& logger) * Packet that wraparound should be dropped, so only one packet should be received at the GW. */ { - std::vector test2_counts(2); // Test two packets + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("RX COUNT [4294967295,0], 12 bit SN"); + test_rx_helper rx_helper(srsran::PDCP_SN_LEN_12, logger); + std::vector test2_counts(2); // Test two packets std::iota(test2_counts.begin(), test2_counts.end(), 4294967295); // Starting at COUNT 4294967295 std::vector test2_pdus = gen_expected_pdus_vector(tst_sdu1, test2_counts, srsran::PDCP_SN_LEN_12, sec_cfg, logger); pdcp_initial_state test2_init_state = { .tx_next = 4294967295, .rx_next = 4294967295, .rx_deliv = 4294967295, .rx_reord = 0}; - TESTASSERT(test_rx(std::move(test2_pdus), test2_init_state, srsran::PDCP_SN_LEN_12, 1, tst_sdu1, logger) == 0); + TESTASSERT(rx_helper.test_rx(std::move(test2_pdus), test2_init_state, 1, tst_sdu1) == 0); } /* * RX Test 3: PDCP Entity with SN LEN = 18 @@ -111,12 +129,15 @@ int test_rx_all(srslog::basic_logger& logger) * This tests correct handling of HFN in the case of SN wraparound (SN LEN 18) */ { - std::vector test3_counts(2); // Test two packets + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("RX COUNT [262144,262145], 12 bit SN"); + test_rx_helper rx_helper(srsran::PDCP_SN_LEN_18, logger); + std::vector test3_counts(2); // Test two packets std::iota(test3_counts.begin(), test3_counts.end(), 262144); // Starting at COUNT 262144 std::vector test3_pdus = gen_expected_pdus_vector(tst_sdu1, test3_counts, srsran::PDCP_SN_LEN_18, sec_cfg, logger); pdcp_initial_state test3_init_state = {.tx_next = 262144, .rx_next = 262144, .rx_deliv = 262144, .rx_reord = 0}; - TESTASSERT(test_rx(std::move(test3_pdus), test3_init_state, srsran::PDCP_SN_LEN_18, 2, tst_sdu1, logger) == 0); + TESTASSERT(rx_helper.test_rx(std::move(test3_pdus), test3_init_state, 2, tst_sdu1) == 0); } /* @@ -125,20 +146,27 @@ int test_rx_all(srslog::basic_logger& logger) * This tests correct handling of COUNT in the case of [HFN|SN] wraparound */ { - std::vector test4_counts(2); // Test two packets + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("RX COUNT [4294967295,4294967296], 18 bit SN"); + test_rx_helper rx_helper(srsran::PDCP_SN_LEN_18, logger); + std::vector test4_counts(2); // Test two packets std::iota(test4_counts.begin(), test4_counts.end(), 4294967295); // Starting at COUNT 4294967295 std::vector test4_pdus = gen_expected_pdus_vector(tst_sdu1, test4_counts, srsran::PDCP_SN_LEN_18, sec_cfg, logger); pdcp_initial_state test4_init_state = { .tx_next = 4294967295, .rx_next = 4294967295, .rx_deliv = 4294967295, .rx_reord = 0}; - TESTASSERT(test_rx(std::move(test4_pdus), test4_init_state, srsran::PDCP_SN_LEN_18, 1, tst_sdu1, logger) == 0); + TESTASSERT(rx_helper.test_rx(std::move(test4_pdus), test4_init_state, 1, tst_sdu1) == 0); } /* * RX Test 5: PDCP Entity with SN LEN = 12 * Test reception of two out-of-order packets, starting at COUNT 0. + * Both packets are received and delivered before t-Reordering expires. */ { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("RX out-of-order COUNT [1,0], 12 bit SN"); + test_rx_helper rx_helper(srsran::PDCP_SN_LEN_12, logger); std::vector test5_pdus; pdcp_initial_state test5_init_state = {}; @@ -155,14 +183,21 @@ int test_rx_all(srslog::basic_logger& logger) // Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after) test5_pdus.push_back(std::move(event_pdu2)); test5_pdus.push_back(std::move(event_pdu1)); - TESTASSERT(test_rx(std::move(test5_pdus), test5_init_state, srsran::PDCP_SN_LEN_12, 2, tst_sdu2, logger) == 0); + TESTASSERT(rx_helper.test_rx(std::move(test5_pdus), test5_init_state, 2, tst_sdu2) == 0); + TESTASSERT(rx_helper.pdcp_rx.is_reordering_timer_running() == false); + TESTASSERT(rx_helper.pdcp_rx.get_rx_deliv() == 2); + TESTASSERT(rx_helper.pdcp_rx.get_rx_reord() == 2); } /* * RX Test 6: PDCP Entity with SN LEN = 18 * Test reception of two out-of-order packets, starting at COUNT 0. + * Both packets are received and delivered before t-Reordering expires. */ { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("RX out-of-order COUNT [1,0], 18 bit SN"); + test_rx_helper rx_helper(srsran::PDCP_SN_LEN_18, logger); std::vector test6_pdus; pdcp_initial_state test6_init_state = {}; @@ -179,7 +214,10 @@ int test_rx_all(srslog::basic_logger& logger) // Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after) test6_pdus.push_back(std::move(event_pdu2)); test6_pdus.push_back(std::move(event_pdu1)); - TESTASSERT(test_rx(std::move(test6_pdus), test6_init_state, srsran::PDCP_SN_LEN_18, 2, tst_sdu2, logger) == 0); + TESTASSERT(rx_helper.test_rx(std::move(test6_pdus), test6_init_state, 2, tst_sdu2) == 0); + TESTASSERT(rx_helper.pdcp_rx.is_reordering_timer_running() == false); + TESTASSERT(rx_helper.pdcp_rx.get_rx_deliv() == 2); + TESTASSERT(rx_helper.pdcp_rx.get_rx_reord() == 2); } /* @@ -187,6 +225,9 @@ int test_rx_all(srslog::basic_logger& logger) * Test Reception of one out-of-order packet. */ { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("RX out-of-order COUNT [1,0] t_reordering expired, 12 bit SN"); + test_rx_helper rx_helper(srsran::PDCP_SN_LEN_12, logger); std::vector test7_pdus; pdcp_initial_state test7_init_state = {}; @@ -198,7 +239,10 @@ int test_rx_all(srslog::basic_logger& logger) // Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after) test7_pdus.push_back(std::move(event_pdu1)); - TESTASSERT(test_rx(std::move(test7_pdus), test7_init_state, srsran::PDCP_SN_LEN_12, 1, tst_sdu2, logger) == 0); + TESTASSERT(rx_helper.test_rx(std::move(test7_pdus), test7_init_state, 1, tst_sdu2) == 0); + TESTASSERT(rx_helper.pdcp_rx.is_reordering_timer_running() == false); + TESTASSERT(rx_helper.pdcp_rx.get_rx_deliv() == 2); + TESTASSERT(rx_helper.pdcp_rx.get_rx_reord() == 2); } /* @@ -206,6 +250,8 @@ int test_rx_all(srslog::basic_logger& logger) * Test reception of two duplicate PDUs, with COUNT 0. */ { + srsran::test_delimit_logger delimiter("RX duplicate COUNTs [0,0], 12 bit SN"); + test_rx_helper rx_helper(srsran::PDCP_SN_LEN_12, logger); std::vector test8_pdus; pdcp_initial_state test8_init_state = {}; @@ -222,7 +268,7 @@ int test_rx_all(srslog::basic_logger& logger) // Write PDUs out of order (first the pdu with COUNT 1 and COUNT 0 after) test8_pdus.push_back(std::move(event_pdu1)); test8_pdus.push_back(std::move(event_pdu2)); - TESTASSERT(test_rx(std::move(test8_pdus), test8_init_state, srsran::PDCP_SN_LEN_12, 1, tst_sdu1, logger) == 0); + TESTASSERT(rx_helper.test_rx(std::move(test8_pdus), test8_init_state, 1, tst_sdu1) == 0); } return 0; } diff --git a/lib/test/pdcp/pdcp_nr_test_tx.cc b/lib/test/pdcp/pdcp_nr_test_tx.cc index 322414543c..637960dba1 100644 --- a/lib/test/pdcp/pdcp_nr_test_tx.cc +++ b/lib/test/pdcp/pdcp_nr_test_tx.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,46 +22,57 @@ #include /* - * Genric function to test transmission of in-sequence packets + * Generic class to test transmission of in-sequence packets */ -int test_tx(uint32_t n_packets, - const pdcp_initial_state& init_state, - uint8_t pdcp_sn_len, - uint64_t n_pdus_exp, - srsran::unique_byte_buffer_t pdu_exp, - srslog::basic_logger& logger) +class test_tx_helper { - srsran::pdcp_config_t cfg = {1, - srsran::PDCP_RB_IS_DRB, - srsran::SECURITY_DIRECTION_UPLINK, - srsran::SECURITY_DIRECTION_DOWNLINK, - pdcp_sn_len, - srsran::pdcp_t_reordering_t::ms500, - srsran::pdcp_discard_timer_t::infinity, - false, - srsran::srsran_rat_t::nr}; - - pdcp_nr_test_helper pdcp_hlp(cfg, sec_cfg, logger); - srsran::pdcp_entity_nr* pdcp = &pdcp_hlp.pdcp; - rlc_dummy* rlc = &pdcp_hlp.rlc; - - pdcp_hlp.set_pdcp_initial_state(init_state); - - // Run test - for (uint32_t i = 0; i < n_packets; ++i) { - // Test SDU - srsran::unique_byte_buffer_t sdu = srsran::make_byte_buffer(); - sdu->append_bytes(sdu1, sizeof(sdu1)); - pdcp->write_sdu(std::move(sdu)); +public: + pdcp_nr_test_helper pdcp_hlp_tx; + srsran::pdcp_entity_nr& pdcp_tx; + rlc_dummy& rlc_tx; + srsue::stack_test_dummy& stack; + srslog::basic_logger& logger; + + test_tx_helper(uint8_t pdcp_sn_len, srslog::basic_logger& logger) : + pdcp_hlp_tx({1, + srsran::PDCP_RB_IS_DRB, + srsran::SECURITY_DIRECTION_UPLINK, + srsran::SECURITY_DIRECTION_DOWNLINK, + pdcp_sn_len, + srsran::pdcp_t_reordering_t::ms500, + srsran::pdcp_discard_timer_t::ms500, + false, + srsran::srsran_rat_t::nr}, + sec_cfg, + logger), + pdcp_tx(pdcp_hlp_tx.pdcp), + rlc_tx(pdcp_hlp_tx.rlc), + stack(pdcp_hlp_tx.stack), + logger(logger) + {} + int test_tx(uint32_t n_packets, + const pdcp_initial_state& init_state, + uint64_t n_pdus_exp, + srsran::unique_byte_buffer_t pdu_exp) + { + pdcp_hlp_tx.set_pdcp_initial_state(init_state); + + // Run test + for (uint32_t i = 0; i < n_packets; ++i) { + // Test SDU + srsran::unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + sdu->append_bytes(sdu1, sizeof(sdu1)); + pdcp_hlp_tx.pdcp.write_sdu(std::move(sdu)); + } + + srsran::unique_byte_buffer_t pdu_act = srsran::make_byte_buffer(); + pdcp_hlp_tx.rlc.get_last_sdu(pdu_act); + + TESTASSERT(pdcp_hlp_tx.rlc.rx_count == n_pdus_exp); + TESTASSERT(compare_two_packets(pdu_act, pdu_exp) == 0); + return 0; } - - srsran::unique_byte_buffer_t pdu_act = srsran::make_byte_buffer(); - rlc->get_last_sdu(pdu_act); - - TESTASSERT(rlc->rx_count == n_pdus_exp); - TESTASSERT(compare_two_packets(pdu_act, pdu_exp) == 0); - return 0; -} +}; /* * TX Test: PDCP Entity with SN LEN = 12 and 18. @@ -74,122 +85,143 @@ int test_tx_all(srslog::basic_logger& logger) * TX Test 1: PDCP Entity with SN LEN = 12 * TX_NEXT = 0. * Input: {0x18, 0xE2} - * Output: PDCP Header {0x80, 0x00}, Ciphered Text {0x8f, 0xe3}, MAC-I {0xe0, 0xdf, 0x82, 0x92} + * Output: {0x80, 0x00, 0x8f, 0xe3, 0xc7, 0x1b, 0xad, 0x14} */ - n_packets = 1; - srsran::unique_byte_buffer_t pdu_exp_count0_len12 = srsran::make_byte_buffer(); - pdu_exp_count0_len12->append_bytes(pdu1_count0_snlen12, sizeof(pdu1_count0_snlen12)); - TESTASSERT( - test_tx( - n_packets, normal_init_state, srsran::PDCP_SN_LEN_12, n_packets, std::move(pdu_exp_count0_len12), logger) == - 0); - + { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("TX COUNT 0, 12 bit SN"); + test_tx_helper tx_helper(srsran::PDCP_SN_LEN_12, logger); + n_packets = 1; + srsran::unique_byte_buffer_t pdu_exp_count0_len12 = srsran::make_byte_buffer(); + pdu_exp_count0_len12->append_bytes(pdu1_count0_snlen12, sizeof(pdu1_count0_snlen12)); + TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count0_len12)) == 0); + } /* * TX Test 2: PDCP Entity with SN LEN = 12 * TX_NEXT = 2048. * Input: {0x18, 0xE2} - * Output: PDCP Header {0x88, 0x00}, Ciphered Text {0x8d, 0x2c}, MAC-I {0x47, 0x5e, 0xb1, 0x5b} + * Output: {0x88, 0x00, 0x8d, 0x2c, 0xe5, 0x38, 0xc0, 0x42} */ - n_packets = 2049; - srsran::unique_byte_buffer_t pdu_exp_count2048_len12 = srsran::make_byte_buffer(); - pdu_exp_count2048_len12->append_bytes(pdu1_count2048_snlen12, sizeof(pdu1_count2048_snlen12)); - TESTASSERT(test_tx(n_packets, - normal_init_state, - srsran::PDCP_SN_LEN_12, - n_packets, - std::move(pdu_exp_count2048_len12), - logger) == 0); - + { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("TX COUNT 2048, 12 bit SN"); + test_tx_helper tx_helper(srsran::PDCP_SN_LEN_12, logger); + n_packets = 2049; + srsran::unique_byte_buffer_t pdu_exp_count2048_len12 = srsran::make_byte_buffer(); + pdu_exp_count2048_len12->append_bytes(pdu1_count2048_snlen12, sizeof(pdu1_count2048_snlen12)); + TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count2048_len12)) == 0); + } /* * TX Test 3: PDCP Entity with SN LEN = 12 * TX_NEXT = 4096. * Input: {0x18, 0xE2} - * Output: PDCP Header {0x80,0x00}, Ciphered Text {0x97, 0xbe}, MAC-I {0xa3, 0x32, 0xfa, 0x61} + * Output: {0x80, 0x00, 0x97, 0xbe, 0xee, 0x62, 0xf5, 0xe0} */ - n_packets = 4097; - srsran::unique_byte_buffer_t pdu_exp_count4096_len12 = srsran::make_byte_buffer(); - pdu_exp_count4096_len12->append_bytes(pdu1_count4096_snlen12, sizeof(pdu1_count4096_snlen12)); - TESTASSERT(test_tx(n_packets, - normal_init_state, - srsran::PDCP_SN_LEN_12, - n_packets, - std::move(pdu_exp_count4096_len12), - logger) == 0); - + { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("TX COUNT 4096, 12 bit SN"); + test_tx_helper tx_helper(srsran::PDCP_SN_LEN_12, logger); + n_packets = 4097; + srsran::unique_byte_buffer_t pdu_exp_count4096_len12 = srsran::make_byte_buffer(); + pdu_exp_count4096_len12->append_bytes(pdu1_count4096_snlen12, sizeof(pdu1_count4096_snlen12)); + TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count4096_len12)) == 0); + } /* * TX Test 4: PDCP Entity with SN LEN = 18 * TX_NEXT = 0. * Input: {0x18, 0xE2} - * Output: PDCP Header {0x80, 0x80, 0x00}, Ciphered Text {0x8f, 0xe3}, MAC-I {0xe0, 0xdf, 0x82, 0x92} + * Output: {0x80, 0x00, 0x00, 0x8f, 0xe3, 0x37, 0x33, 0xd5, 0x64} */ - n_packets = 1; - srsran::unique_byte_buffer_t pdu_exp_count0_len18 = srsran::make_byte_buffer(); - pdu_exp_count0_len18->append_bytes(pdu1_count0_snlen18, sizeof(pdu1_count0_snlen18)); - TESTASSERT( - test_tx( - n_packets, normal_init_state, srsran::PDCP_SN_LEN_18, n_packets, std::move(pdu_exp_count0_len18), logger) == - 0); + { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("TX COUNT 0, 18 bit SN"); + test_tx_helper tx_helper(srsran::PDCP_SN_LEN_18, logger); + n_packets = 1; + srsran::unique_byte_buffer_t pdu_exp_count0_len18 = srsran::make_byte_buffer(); + pdu_exp_count0_len18->append_bytes(pdu1_count0_snlen18, sizeof(pdu1_count0_snlen18)); + TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count0_len18)) == 0); + } /* * TX Test 5: PDCP Entity with SN LEN = 18 * TX_NEXT = 131072. * Input: {0x18, 0xE2} - * Output: PDCP Header {0x82, 0x00, 0x00}, Ciphered Text {0x15, 0x01}, MAC-I {0xf4, 0xb0, 0xfc, 0xc5} + * Output: {0x82, 0x00, 0x00, 0x15, 0x01, 0x99, 0x97, 0xe0, 0x4e} */ - n_packets = 131073; - srsran::unique_byte_buffer_t pdu_exp_sn131072_len18 = srsran::make_byte_buffer(); - pdu_exp_sn131072_len18->append_bytes(pdu1_count131072_snlen18, sizeof(pdu1_count131072_snlen18)); - TESTASSERT( - test_tx( - n_packets, normal_init_state, srsran::PDCP_SN_LEN_18, n_packets, std::move(pdu_exp_sn131072_len18), logger) == - 0); + { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("TX COUNT 131072, 18 bit SN"); + test_tx_helper tx_helper(srsran::PDCP_SN_LEN_18, logger); + n_packets = 131073; + srsran::unique_byte_buffer_t pdu_exp_sn131072_len18 = srsran::make_byte_buffer(); + pdu_exp_sn131072_len18->append_bytes(pdu1_count131072_snlen18, sizeof(pdu1_count131072_snlen18)); + TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_sn131072_len18)) == 0); + } /* * TX Test 6: PDCP Entity with SN LEN = 18 * TX_NEXT = 262144. * Input: {0x18, 0xE2} - * Output: PDCP Header {0x80, 0x00, 0x00}, Ciphered Text {0xc2, 0x47}, MAC-I {0xa8, 0xdd, 0xc0, 0x73} + * Output: {0x80, 0x00, 0x00, 0xc2, 0x47, 0xc2, 0xee, 0x46, 0xd9} */ - n_packets = 262145; - srsran::unique_byte_buffer_t pdu_exp_count262144_len18 = srsran::make_byte_buffer(); - pdu_exp_count262144_len18->append_bytes(pdu1_count262144_snlen18, sizeof(pdu1_count262144_snlen18)); - TESTASSERT(test_tx(n_packets, - normal_init_state, - srsran::PDCP_SN_LEN_18, - n_packets, - std::move(pdu_exp_count262144_len18), - logger) == 0); - + { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("TX COUNT 262144, 18 bit SN"); + test_tx_helper tx_helper(srsran::PDCP_SN_LEN_18, logger); + n_packets = 262145; + srsran::unique_byte_buffer_t pdu_exp_count262144_len18 = srsran::make_byte_buffer(); + pdu_exp_count262144_len18->append_bytes(pdu1_count262144_snlen18, sizeof(pdu1_count262144_snlen18)); + TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count262144_len18)) == 0); + } /* * TX Test 7: PDCP Entity with SN LEN = 12 * Test TX at COUNT wraparound. - * Should print a warning and drop all packets after wraparound. + * Should print a warning and drop all packets after wrap around. */ - n_packets = 5; - srsran::unique_byte_buffer_t pdu_exp_count4294967295_len12 = srsran::make_byte_buffer(); - pdu_exp_count4294967295_len12->append_bytes(pdu1_count4294967295_snlen12, sizeof(pdu1_count4294967295_snlen12)); - TESTASSERT(test_tx(n_packets, - near_wraparound_init_state, - srsran::PDCP_SN_LEN_12, - 1, - std::move(pdu_exp_count4294967295_len12), - logger) == 0); + { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("TX COUNT wrap around, 12 bit SN"); + test_tx_helper tx_helper(srsran::PDCP_SN_LEN_12, logger); + n_packets = 5; + srsran::unique_byte_buffer_t pdu_exp_count4294967295_len12 = srsran::make_byte_buffer(); + pdu_exp_count4294967295_len12->append_bytes(pdu1_count4294967295_snlen12, sizeof(pdu1_count4294967295_snlen12)); + TESTASSERT(tx_helper.test_tx(n_packets, near_wraparound_init_state, 1, std::move(pdu_exp_count4294967295_len12)) == + 0); + } /* * TX Test 8: PDCP Entity with SN LEN = 18 * Test TX at COUNT wraparound. * Should print a warning and drop all packets after wraparound. */ - n_packets = 5; - srsran::unique_byte_buffer_t pdu_exp_count4294967295_len18 = srsran::make_byte_buffer(); - pdu_exp_count4294967295_len18->append_bytes(pdu1_count4294967295_snlen18, sizeof(pdu1_count4294967295_snlen18)); - TESTASSERT(test_tx(n_packets, - near_wraparound_init_state, - srsran::PDCP_SN_LEN_18, - 1, - std::move(pdu_exp_count4294967295_len18), - logger) == 0); - return 0; + { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("TX COUNT wrap around, 12 bit SN"); + test_tx_helper tx_helper(srsran::PDCP_SN_LEN_18, logger); + n_packets = 5; + srsran::unique_byte_buffer_t pdu_exp_count4294967295_len18 = srsran::make_byte_buffer(); + pdu_exp_count4294967295_len18->append_bytes(pdu1_count4294967295_snlen18, sizeof(pdu1_count4294967295_snlen18)); + TESTASSERT(tx_helper.test_tx(n_packets, near_wraparound_init_state, 1, std::move(pdu_exp_count4294967295_len18)) == + 0); + } + + /* + * TX Test 9: PDCP Entity with SN LEN = 12 + * Test whether discard timers are correctly stopped after receiving a notification from the RLC + */ + { + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + srsran::test_delimit_logger delimiter("Stop discard timers upon RLC notification, 12 bit SN"); + test_tx_helper tx_helper(srsran::PDCP_SN_LEN_12, logger); + n_packets = 1; + srsran::unique_byte_buffer_t pdu_exp_count0_len12 = srsran::make_byte_buffer(); + pdu_exp_count0_len12->append_bytes(pdu1_count0_snlen12, sizeof(pdu1_count0_snlen12)); + TESTASSERT(tx_helper.test_tx(n_packets, normal_init_state, n_packets, std::move(pdu_exp_count0_len12)) == 0); + TESTASSERT(tx_helper.pdcp_tx.nof_discard_timers() == 1); + tx_helper.pdcp_tx.notify_delivery({0}); + TESTASSERT(tx_helper.pdcp_tx.nof_discard_timers() == 0); + } + return SRSRAN_SUCCESS; } // Setup all tests diff --git a/lib/test/phy/CMakeLists.txt b/lib/test/phy/CMakeLists.txt index a07f561ec7..77aa8d0434 100644 --- a/lib/test/phy/CMakeLists.txt +++ b/lib/test/phy/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/test/phy/phy_dl_nr_test.c b/lib/test/phy/phy_dl_nr_test.c index 2bc0c177a6..d8178670b9 100644 --- a/lib/test/phy/phy_dl_nr_test.c +++ b/lib/test/phy/phy_dl_nr_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/phy/phy_dl_test.c b/lib/test/phy/phy_dl_test.c index a9e6a30e88..e52bedec83 100644 --- a/lib/test/phy/phy_dl_test.c +++ b/lib/test/phy/phy_dl_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -466,13 +466,13 @@ int main(int argc, char** argv) dci.rnti = rnti; dci.is_tdd = false; dci.is_dwpts = false; - dci.is_ra_order = false; + dci.is_pdcch_order = false; dci.tb_cw_swap = false; dci.pconf = false; dci.power_offset = false; dci.tpc_pucch = false; - dci.ra_preamble = false; - dci.ra_mask_idx = false; + dci.preamble_idx = 0; + dci.prach_mask_idx = 0; dci.srs_request = false; dci.srs_request_present = false; diff --git a/lib/test/phy/pucch_ca_test.c b/lib/test/phy/pucch_ca_test.c index 3e69bb2c3a..03b8e836d3 100644 --- a/lib/test/phy/pucch_ca_test.c +++ b/lib/test/phy/pucch_ca_test.c @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/rlc/CMakeLists.txt b/lib/test/rlc/CMakeLists.txt index d81e0c3831..6cea201573 100644 --- a/lib/test/rlc/CMakeLists.txt +++ b/lib/test/rlc/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -28,13 +28,17 @@ add_executable(rlc_am_control_test rlc_am_control_test.cc) target_link_libraries(rlc_am_control_test srsran_rlc srsran_phy) add_lte_test(rlc_am_control_test rlc_am_control_test) -add_executable(rlc_am_test rlc_am_test.cc) -target_link_libraries(rlc_am_test srsran_rlc srsran_phy srsran_common) -add_lte_test(rlc_am_test rlc_am_test) +add_executable(rlc_am_lte_test rlc_am_lte_test.cc) +target_link_libraries(rlc_am_lte_test srsran_rlc srsran_phy srsran_common) +add_lte_test(rlc_am_lte_test rlc_am_lte_test) + +add_executable(rlc_am_nr_test rlc_am_nr_test.cc) +target_link_libraries(rlc_am_nr_test srsran_rlc srsran_phy srsran_common) +add_nr_test(rlc_am_nr_test rlc_am_nr_test) add_executable(rlc_am_nr_pdu_test rlc_am_nr_pdu_test.cc) -target_link_libraries(rlc_am_nr_pdu_test srsran_rlc srsran_phy) -add_nr_test(rlc_am_nr_pdu_test rlc_am_nr_pdu_test) +target_link_libraries(rlc_am_nr_pdu_test srsran_rlc srsran_phy srsran_mac srsran_common ) +add_nr_test(rlc_am_nr_pdu_test rlc_am_nr_pdu_test ) add_executable(rlc_stress_test rlc_stress_test.cc) target_link_libraries(rlc_stress_test srsran_rlc srsran_mac srsran_phy srsran_common ${Boost_LIBRARIES} ${ATOMIC_LIBS}) @@ -44,6 +48,8 @@ add_lte_test(rlc_tm_stress_test rlc_stress_test --mode=TM --loglevel 1 --random_ add_nr_test(rlc_um6_nr_stress_test rlc_stress_test --rat NR --mode=UM6 --loglevel 1) add_nr_test(rlc_um12_nr_stress_test rlc_stress_test --rat NR --mode=UM12 --loglevel 1) +add_nr_test(rlc_am12_nr_stress_test rlc_stress_test --rat NR --mode=AM12 --loglevel 1) +add_nr_test(rlc_am12_nr_stress_test rlc_stress_test --rat NR --mode=AM18 --loglevel 1) add_executable(rlc_um_data_test rlc_um_data_test.cc) target_link_libraries(rlc_um_data_test srsran_rlc srsran_phy srsran_common) diff --git a/lib/test/rlc/rlc_am_control_test.cc b/lib/test/rlc/rlc_am_control_test.cc index 23e2b8ac26..ccfb03e321 100644 --- a/lib/test/rlc/rlc_am_control_test.cc +++ b/lib/test/rlc/rlc_am_control_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/rlc/rlc_am_data_test.cc b/lib/test/rlc/rlc_am_data_test.cc index b8f3ebd079..e5f28af857 100644 --- a/lib/test/rlc/rlc_am_data_test.cc +++ b/lib/test/rlc/rlc_am_data_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/rlc/rlc_am_test.cc b/lib/test/rlc/rlc_am_lte_test.cc similarity index 83% rename from lib/test/rlc/rlc_am_test.cc rename to lib/test/rlc/rlc_am_lte_test.cc index d9c7d334a0..16072ff2c3 100644 --- a/lib/test/rlc/rlc_am_test.cc +++ b/lib/test/rlc/rlc_am_lte_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,6 +19,7 @@ * */ +#include "rlc_test_common.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/rlc_pcap.h" #include "srsran/common/test_common.h" @@ -34,67 +35,10 @@ using namespace srsue; using namespace srsran; -bool rx_is_tx(const rlc_bearer_metrics_t& rlc1_metrics, const rlc_bearer_metrics_t& rlc2_metrics) -{ - if (rlc1_metrics.num_tx_pdu_bytes != rlc2_metrics.num_rx_pdu_bytes) { - return false; - } - - if (rlc2_metrics.num_tx_pdu_bytes != rlc1_metrics.num_rx_pdu_bytes) { - return false; - } - return true; -} - -class rlc_am_tester : public pdcp_interface_rlc, public rrc_interface_rlc -{ -public: - rlc_am_tester(rlc_pcap* pcap_ = NULL) : pcap(pcap_) {} - - // PDCP interface - void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu) - { - assert(lcid == 1); - sdus.push_back(std::move(sdu)); - } - void write_pdu_bcch_bch(unique_byte_buffer_t sdu) {} - void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} - void write_pdu_pcch(unique_byte_buffer_t sdu) {} - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) {} - void notify_delivery(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn_vec) - { - assert(lcid == 1); - for (uint32_t pdcp_sn : pdcp_sn_vec) { - if (notified_counts.find(pdcp_sn) == notified_counts.end()) { - notified_counts[pdcp_sn] = 0; - } - notified_counts[pdcp_sn] += 1; - } - } - void notify_failure(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn_vec) - { - assert(lcid == 1); - // TODO - } - - // RRC interface - void max_retx_attempted() { max_retx_triggered = true; } - void protocol_failure() { protocol_failure_triggered = true; } - - const char* get_rb_name(uint32_t lcid) { return ""; } - - std::vector sdus; - rlc_pcap* pcap = nullptr; - bool max_retx_triggered = false; - bool protocol_failure_triggered = false; - - std::map notified_counts; // Map of PDCP SNs to number of notifications -}; - class ul_writer : public thread { public: - ul_writer(rlc_am_lte* rlc_) : rlc(rlc_), thread("UL_WRITER") {} + ul_writer(rlc_am* rlc_) : rlc(rlc_), thread("UL_WRITER") {} ~ul_writer() { stop(); } void stop() { @@ -130,11 +74,11 @@ class ul_writer : public thread running = false; } - rlc_am_lte* rlc = nullptr; + rlc_am* rlc = nullptr; std::atomic running = {false}; }; -int basic_test_tx(rlc_am_lte* rlc, byte_buffer_t pdu_bufs[NBUFS]) +int basic_test_tx(rlc_am* rlc, byte_buffer_t pdu_bufs[NBUFS]) { // Push 5 SDUs into RLC1 unique_byte_buffer_t sdu_bufs[NBUFS]; @@ -161,12 +105,12 @@ int basic_test_tx(rlc_am_lte* rlc, byte_buffer_t pdu_bufs[NBUFS]) int basic_test() { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); timer_handler timers(8); byte_buffer_t pdu_bufs[NBUFS]; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); // before configuring entity TESTASSERT(0 == rlc1.get_buffer_state()); @@ -220,11 +164,11 @@ int basic_test() int concat_test() { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -294,12 +238,12 @@ int concat_test() int segment_test(bool in_seq_rx) { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -389,12 +333,12 @@ int segment_test(bool in_seq_rx) int retx_test() { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -525,11 +469,11 @@ int retx_test() // Test correct upper layer signaling when maxRetx (default 4) have been reached int max_retx_test() { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); const rlc_config_t rlc_cfg = rlc_config_t::default_rlc_am_config(); if (not rlc1.configure(rlc_cfg)) { @@ -588,12 +532,12 @@ int max_retx_test() // Purpose: test correct retx of lost segment and pollRetx timer expiration int segment_retx_test() { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -713,12 +657,12 @@ int resegment_test_1() // PDUs: | 10 | 10 | 10 | 10 | 10 | // Retx PDU segments: | 5 | 5| - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -871,11 +815,11 @@ int resegment_test_2() // PDUs: | 5 | 10 | 20 | 10 | 5 | // Retx PDU segments: | 10 | 10 | - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1003,11 +947,11 @@ int resegment_test_3() // PDUs: | 5 | 5| 20 | 10 | 10 | // Retx PDU segments: | 10 | 10 | - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1133,11 +1077,11 @@ int resegment_test_4() // PDUs: | 5 | 5| 30 | 5 | 5| // Retx PDU segments: | 15 | 15 | - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1265,11 +1209,11 @@ int resegment_test_5() // PDUs: |2|3| 40 |3|2| // Retx PDU segments: | 20 | 20 | - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1391,12 +1335,12 @@ int resegment_test_6() // PDUs: |10|10|10| 270 | 54 | // Retx PDU segments: | 120 | 150 | - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1558,14 +1502,14 @@ int resegment_test_7() #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_test7.pcap", rlc_config_t::default_rlc_am_config()); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, nullptr); #endif srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1743,14 +1687,14 @@ int resegment_test_8() #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_test8.pcap", rlc_config_t::default_rlc_am_config()); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, nullptr); #endif srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -1895,14 +1839,14 @@ int resegment_test_9() #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_resegment_test_9.pcap", config); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, nullptr); #endif srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(config)) { return SRSRAN_ERROR; @@ -2037,14 +1981,14 @@ int resegment_test_10() #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_resegment_test_10.pcap", config); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(config)) { return SRSRAN_ERROR; @@ -2186,14 +2130,14 @@ int resegment_test_11() #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_resegment_test_11.pcap", config); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(config)) { return SRSRAN_ERROR; @@ -2344,14 +2288,14 @@ int resegment_test_12() #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_resegment_test_12.pcap", config); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(config)) { return SRSRAN_ERROR; @@ -2488,13 +2432,13 @@ int header_reconstruction_test(srsran::log_sink_message_spy& spy) #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_header_reconstruction_test.pcap", rlc_config_t::default_rlc_am_config()); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -2551,13 +2495,13 @@ int header_reconstruction_test2(srsran::log_sink_message_spy& spy) #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_header_reconstruction_test2.pcap", rlc_config_t::default_rlc_am_config()); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; } @@ -2614,14 +2558,14 @@ int header_reconstruction_test3(srsran::log_sink_message_spy& spy) #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_header_reconstruction_test3.pcap", rlc_config_t::default_rlc_am_config()); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); // configure RLC - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; } @@ -2700,14 +2644,14 @@ int header_reconstruction_test4(srsran::log_sink_message_spy& spy) #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_header_reconstruction_test4.pcap", rlc_config_t::default_rlc_am_config()); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); // configure RLC - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; } @@ -2777,14 +2721,14 @@ int header_reconstruction_test5(srsran::log_sink_message_spy& spy) #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_header_reconstruction_test5.pcap", rlc_config_t::default_rlc_am_config()); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); // configure RLC - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; } @@ -2856,14 +2800,14 @@ int header_reconstruction_test6(srsran::log_sink_message_spy& spy) #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_header_reconstruction_test6.pcap", rlc_config_t::default_rlc_am_config()); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); // configure RLC - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; } @@ -2955,14 +2899,14 @@ int header_reconstruction_test7(srsran::log_sink_message_spy& spy) #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_header_reconstruction_test7.pcap", rlc_config_t::default_rlc_am_config()); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); // configure RLC - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; } @@ -3057,14 +3001,14 @@ int header_reconstruction_test8(srsran::log_sink_message_spy& spy) #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_header_reconstruction_test8.pcap", rlc_config_t::default_rlc_am_config()); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); // configure RLC - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; } @@ -3091,11 +3035,11 @@ int header_reconstruction_test8(srsran::log_sink_message_spy& spy) bool reset_test() { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -3133,11 +3077,11 @@ bool reset_test() bool resume_test() { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -3175,10 +3119,10 @@ bool resume_test() bool stop_test() { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -3201,12 +3145,12 @@ bool stop_test() // be enough to fit all SNs that would need to be NACKed bool status_pdu_test() { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -3310,12 +3254,12 @@ bool status_pdu_test() // The incidence is reported to the upper layers. bool incorrect_status_pdu_test() { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -3375,12 +3319,12 @@ bool incorrect_status_pdu_test() /// In contrast to the without explicitly NACK-ing specific SNs bool incorrect_status_pdu_test2() { - rlc_am_tester tester; + rlc_am_tester tester(true, nullptr); srsran::timer_handler timers(8); int len = 0; - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); if (not rlc1.configure(rlc_config_t::default_rlc_am_config())) { return -1; @@ -3486,15 +3430,15 @@ bool reestablish_test() #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_reestablish_test.pcap", config); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, nullptr); #endif srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); srslog::fetch_basic_logger("RLC_AM_2").set_hex_dump_max_size(100); @@ -3606,15 +3550,15 @@ bool discard_test() #if HAVE_PCAP rlc_pcap pcap; pcap.open("rlc_am_reestablish_test.pcap", config); - rlc_am_tester tester(&pcap); + rlc_am_tester tester(true, &pcap); #else - rlc_am_tester tester(NULL); + rlc_am_tester tester(true, NULL); #endif srsran::timer_handler timers(8); - rlc_am_lte rlc1(srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); - rlc_am_lte rlc2(srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); srslog::fetch_basic_logger("RLC_AM_2").set_hex_dump_max_size(100); @@ -3672,6 +3616,466 @@ bool discard_test() srslog::fetch_basic_logger("TEST").info("Received %zd SDUs", tester.sdus.size()); +#if HAVE_PCAP + pcap.close(); +#endif + + return SRSRAN_SUCCESS; +} + +// This test checks wether re-transmissions are triggered correctly in case the t-PollRetranmission expires. +// It checks if the poll retx timer is re-armed upon receiving an ACK for POLL_SN +bool poll_retx_expiry_test() +{ + rlc_config_t config = rlc_config_t::default_rlc_am_config(); + // [I] SRB1 configured: t_poll_retx=65, poll_pdu=-1, poll_byte=-1, max_retx_thresh=6, t_reordering=55, + // t_status_prohibit=0 + config.am.t_poll_retx = 65; + config.am.poll_pdu = -1; + config.am.poll_byte = -1; + config.am.max_retx_thresh = 6; + config.am.t_reordering = 55; + config.am.t_status_prohibit = 55; + +#if HAVE_PCAP + rlc_pcap pcap; + pcap.open("rlc_am_poll_rext_expiry_test.pcap", config); + rlc_am_tester tester(true, &pcap); +#else + rlc_am_tester tester(true, NULL); +#endif + + srsran::timer_handler timers(8); + + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + + srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); + srslog::fetch_basic_logger("RLC_AM_2").set_hex_dump_max_size(100); + srslog::fetch_basic_logger("RLC").set_hex_dump_max_size(100); + + if (not rlc1.configure(config)) { + return -1; + } + + if (not rlc2.configure(config)) { + return -1; + } + + // [I] SRB1 Tx SDU (135 B, tx_sdu_queue_len=1) + // [I] SRB1 Tx PDU SN=3 (91 B) + // [I] SRB1 Tx PDU SN=4 (48 B) + { + // Initial Tx + uint32_t num_tx_pdus = 1; + for (uint32_t i = 0; i < num_tx_pdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = 135; + for (uint32_t k = 0; k < sdu->N_bytes; ++k) { + sdu->msg[k] = i; // Write the index into the buffer + } + sdu->md.pdcp_sn = i; + rlc1.write_sdu(std::move(sdu)); + } + unique_byte_buffer_t pdu1 = srsran::make_byte_buffer(); + TESTASSERT(pdu1 != nullptr); + pdu1->N_bytes = rlc1.read_pdu(pdu1->msg, 91); + + unique_byte_buffer_t pdu2 = srsran::make_byte_buffer(); + TESTASSERT(pdu2 != nullptr); + pdu2->N_bytes = rlc1.read_pdu(pdu2->msg, 48); + + // Deliver PDU2 to RLC2. PDU1 is lost + rlc2.write_pdu(pdu2->msg, pdu2->N_bytes); + } + + // Step timers until t-PollRetransmission timer expires on RLC1 + // t-Reordering timer also will expire on RLC2, so we can get an status report. + // [I] SRB1 Schedule SN=3 for reTx + for (int cnt = 0; cnt < 65; cnt++) { + timers.step_all(); + } + + uint32_t status_size = rlc2.get_buffer_state(); + srslog::flush(); + TESTASSERT(4 == status_size); + + // Read status PDU from RLC2 + unique_byte_buffer_t status_buf = srsran::make_byte_buffer(); + TESTASSERT(status_buf != nullptr); + int len = rlc2.read_pdu(status_buf->msg, status_size); + status_buf->N_bytes = len; + + TESTASSERT(0 == rlc2.get_buffer_state()); + + // Assert status is correct + rlc_status_pdu_t status_check = {}; + rlc_am_read_status_pdu(status_buf->msg, status_buf->N_bytes, &status_check); + TESTASSERT(status_check.ack_sn == 2); // 2 is the SN after the largest SN received. + TESTASSERT(status_check.N_nack == 1); // 1 PDU lost + TESTASSERT(rlc_am_is_valid_status_pdu(status_check)); + + // [I] SRB1 Retx PDU segment SN=3 [so=0] (83 B) (attempt 2/6) + { + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 83); + } + + // [I] SRB1 Retx PDU segment SN=3 [so=79] (14 B) (attempt 2/6) + { + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 79); + } + + // Deliver status PDU after ReTX to RLC1. This should restart t-PollRetransmission + TESTASSERT_EQ(false, rlc1.has_data()); + rlc1.write_pdu(status_buf->msg, status_buf->N_bytes); + TESTASSERT_EQ(true, rlc1.has_data()); + + // [I] SRB1 Retx PDU segment SN=3 [so=0] (83 B) (attempt 3/6) (received a NACK and retx...) + // [I] SRB1 Retx PDU segment SN=3 [so=79] (14 B) (attempt 3/6) + { + unique_byte_buffer_t pdu1 = srsran::make_byte_buffer(); + TESTASSERT(pdu1 != nullptr); + pdu1->N_bytes = rlc1.read_pdu(pdu1->msg, 83); + + unique_byte_buffer_t pdu2 = srsran::make_byte_buffer(); + TESTASSERT(pdu2 != nullptr); + pdu2->N_bytes = rlc1.read_pdu(pdu2->msg, 14); + } + + TESTASSERT_EQ(false, rlc1.has_data()); + + // Step timers until t-PollRetransmission timer expires on RLC1 + // [I] SRB1 Schedule SN=3 for reTx + + for (int cnt = 0; cnt < 66; cnt++) { + timers.step_all(); + } + TESTASSERT_EQ(true, rlc1.has_data()); + srslog::fetch_basic_logger("TEST").info("t-Poll Retransmssion successfully restarted."); + +#if HAVE_PCAP + pcap.close(); +#endif + + return SRSRAN_SUCCESS; +} + +bool full_window_check_test() +{ + rlc_config_t config = rlc_config_t::default_rlc_am_config(); + // [I] SRB1 configured: t_poll_retx=65, poll_pdu=-1, poll_byte=-1, max_retx_thresh=6, t_reordering=55, + // t_status_prohibit=0 + config.am.t_poll_retx = 65; + config.am.poll_pdu = -1; + config.am.poll_byte = -1; + config.am.max_retx_thresh = 6; + config.am.t_reordering = 55; + config.am.t_status_prohibit = 55; + +#if HAVE_PCAP + rlc_pcap pcap; + pcap.open("rlc_am_poll_rext_expiry_test.pcap", config); + rlc_am_tester tester(true, &pcap); +#else + rlc_am_tester tester(true, NULL); +#endif + + srsran::timer_handler timers(8); + + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + + srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); + srslog::fetch_basic_logger("RLC_AM_2").set_hex_dump_max_size(100); + srslog::fetch_basic_logger("RLC").set_hex_dump_max_size(100); + + if (not rlc1.configure(config)) { + return -1; + } + + if (not rlc2.configure(config)) { + return -1; + } + + { + // Initial Tx + uint32_t num_tx_pdus = 512; + for (uint32_t i = 0; i < num_tx_pdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = 1; + sdu->msg[0] = i; + sdu->md.pdcp_sn = i; + rlc1.write_sdu(std::move(sdu)); + + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = 1; + pdu->msg[0] = i; + pdu->md.pdcp_sn = i; + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3); + TESTASSERT(pdu->N_bytes == 3); + } + } + { + // Tx one more to check the window is full + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = 1; + sdu->msg[0] = 0; + sdu->md.pdcp_sn = 512; + rlc1.write_sdu(std::move(sdu)); + + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3); + TESTASSERT(pdu->N_bytes == 3); + + // If the TX window is full, we should RETX SN=0 + rlc_amd_pdu_header_t header = {}; + rlc_am_read_data_pdu_header(&pdu->msg, &pdu->N_bytes, &header); + TESTASSERT_EQ(header.sn, 0); + TESTASSERT_EQ(header.N_li, 0); + TESTASSERT_EQ(header.fi, 0); + } + + // Ack one SN in the middle of the TX window. + // This is done to make sure the full window check is correct + // even if PDUs in the middle of the window are ACKed. + // ACK_SN=3, NACK_SN=0 + { + rlc_status_pdu_t status = {}; + status.ack_sn = 3; + status.N_nack = 1; + status.nacks[0].nack_sn = 0; + + unique_byte_buffer_t status_buf = srsran::make_byte_buffer(); + TESTASSERT(status_buf != nullptr); + rlc_am_write_status_pdu(&status, status_buf.get()); + rlc1.write_pdu(status_buf->msg, status_buf->N_bytes); + + // Read RETX for SN=0 from NACK + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3); + TESTASSERT(pdu->N_bytes == 3); + + // Check RETX SN=0 + rlc_amd_pdu_header_t header = {}; + rlc_am_read_data_pdu_header(&pdu->msg, &pdu->N_bytes, &header); + TESTASSERT_EQ(header.sn, 0); + TESTASSERT_EQ(header.N_li, 0); + TESTASSERT_EQ(header.fi, 0); + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + } + { + // Tx more PDUs to check the window is still full + uint32_t num_tx_pdus = 2; + for (uint32_t i = 0; i < num_tx_pdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = 1; + sdu->msg[0] = i; + sdu->md.pdcp_sn = i; + rlc1.write_sdu(std::move(sdu)); + + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = 1; + pdu->msg[0] = i; + pdu->md.pdcp_sn = i; + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3); + TESTASSERT(pdu->N_bytes == 3); + + // If the TX window is full, we should RETX SN=0 + rlc_amd_pdu_header_t header = {}; + rlc_am_read_data_pdu_header(&pdu->msg, &pdu->N_bytes, &header); + TESTASSERT_EQ(header.sn, 0); + TESTASSERT_EQ(header.N_li, 0); + TESTASSERT_EQ(header.fi, 0); + } + } + // ACK more PDUs and advance VT(A). + // New PDUs should be available to read now. + { + rlc_status_pdu_t status = {}; + status.ack_sn = 5; + status.N_nack = 0; + + unique_byte_buffer_t status_buf = srsran::make_byte_buffer(); + TESTASSERT(status_buf != nullptr); + rlc_am_write_status_pdu(&status, status_buf.get()); + rlc1.write_pdu(status_buf->msg, status_buf->N_bytes); + + // Read new PDU + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3); + TESTASSERT(pdu->N_bytes == 3); + + // If the TX window is no longer full, we should TX a new SN (SN=512) + rlc_amd_pdu_header_t header = {}; + rlc_am_read_data_pdu_header(&pdu->msg, &pdu->N_bytes, &header); + TESTASSERT_EQ(header.sn, 512); + TESTASSERT_EQ(header.N_li, 0); + TESTASSERT_EQ(header.fi, 0); + } + +#if HAVE_PCAP + pcap.close(); +#endif + + return SRSRAN_SUCCESS; +} + +bool full_window_check_wraparound_test() +{ + rlc_config_t config = rlc_config_t::default_rlc_am_config(); + // [I] SRB1 configured: t_poll_retx=65, poll_pdu=-1, poll_byte=-1, max_retx_thresh=6, t_reordering=55, + // t_status_prohibit=0 + config.am.t_poll_retx = 65; + config.am.poll_pdu = -1; + config.am.poll_byte = -1; + config.am.max_retx_thresh = 6; + config.am.t_reordering = 55; + config.am.t_status_prohibit = 55; + +#if HAVE_PCAP + rlc_pcap pcap; + pcap.open("rlc_am_poll_rext_expiry_test.pcap", config); + rlc_am_tester tester(true, &pcap); +#else + rlc_am_tester tester(true, NULL); +#endif + + uint32_t pdcp_count = 0; + + srsran::timer_handler timers(8); + + rlc_am rlc1(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::lte, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + + srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); + srslog::fetch_basic_logger("RLC_AM_2").set_hex_dump_max_size(100); + srslog::fetch_basic_logger("RLC").set_hex_dump_max_size(100); + + if (not rlc1.configure(config)) { + return -1; + } + + if (not rlc2.configure(config)) { + return -1; + } + + // Advance vt_a to 512 and vt_s to 512 as well. + { + // Initial Tx + uint32_t num_tx_pdus = 512; + for (uint32_t i = 0; i < num_tx_pdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = 1; + sdu->msg[0] = i; + sdu->md.pdcp_sn = pdcp_count++; + rlc1.write_sdu(std::move(sdu)); + + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3); + TESTASSERT(pdu->N_bytes == 3); + } + + // ACK all SNs to advance the TX window. + rlc_status_pdu_t status = {}; + status.ack_sn = num_tx_pdus; + status.N_nack = 0; + + unique_byte_buffer_t status_buf = srsran::make_byte_buffer(); + TESTASSERT(status_buf != nullptr); + rlc_am_write_status_pdu(&status, status_buf.get()); + rlc1.write_pdu(status_buf->msg, status_buf->N_bytes); + } + + // Advance vt_a and vt_s to 1023 + { + // Initial Tx + uint32_t num_tx_pdus = 511; + for (uint32_t i = 0; i < num_tx_pdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = 1; + sdu->msg[0] = i; + sdu->md.pdcp_sn = pdcp_count++; + rlc1.write_sdu(std::move(sdu)); + + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3); + TESTASSERT(pdu->N_bytes == 3); + } + + // ACK all SNs to advance the TX window. + rlc_status_pdu_t status = {}; + status.ack_sn = 512 + num_tx_pdus; + status.N_nack = 0; + + unique_byte_buffer_t status_buf = srsran::make_byte_buffer(); + TESTASSERT(status_buf != nullptr); + rlc_am_write_status_pdu(&status, status_buf.get()); + rlc1.write_pdu(status_buf->msg, status_buf->N_bytes); + } + + // Now, fill up the window + { + // Initial Tx + uint32_t num_tx_pdus = 512; + for (uint32_t i = 0; i < num_tx_pdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = 1; + sdu->msg[0] = i; + sdu->md.pdcp_sn = pdcp_count++; + rlc1.write_sdu(std::move(sdu)); + + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3); + TESTASSERT(pdu->N_bytes == 3); + } + } + { + // Tx one more to check the window is full + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = 1; + sdu->msg[0] = 0; + sdu->md.pdcp_sn = pdcp_count++; + rlc1.write_sdu(std::move(sdu)); + + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 3); + TESTASSERT(pdu->N_bytes == 3); + + // If the TX window is full, we should RETX SN=1023 + rlc_amd_pdu_header_t header = {}; + rlc_am_read_data_pdu_header(&pdu->msg, &pdu->N_bytes, &header); + TESTASSERT_EQ(header.sn, 1023); + TESTASSERT_EQ(header.N_li, 0); + TESTASSERT_EQ(header.fi, 0); + } + #if HAVE_PCAP pcap.close(); #endif @@ -3883,5 +4287,19 @@ int main(int argc, char** argv) exit(-1); }; + if (poll_retx_expiry_test()) { + printf("poll_retx_expiry_test failed\n"); + exit(-1); + }; + + if (full_window_check_test()) { + printf("full_window_check_test failed\n"); + exit(-1); + }; + + if (full_window_check_wraparound_test()) { + printf("full_window_check_wraparound_test failed\n"); + exit(-1); + }; return SRSRAN_SUCCESS; } diff --git a/lib/test/rlc/rlc_am_nr_pdu_test.cc b/lib/test/rlc/rlc_am_nr_pdu_test.cc index 9f017efeb5..ab377451d2 100644 --- a/lib/test/rlc/rlc_am_nr_pdu_test.cc +++ b/lib/test/rlc/rlc_am_nr_pdu_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,48 +19,38 @@ * */ +#include "srsran/common/test_common.h" #include "srsran/config.h" #include "srsran/rlc/rlc.h" -#include "srsran/rlc/rlc_am_nr.h" +#include "srsran/rlc/rlc_am_nr_packing.h" #include +#include #include #include #include -#define TESTASSERT(cond) \ - { \ - if (!(cond)) { \ - std::cout << "[" << __FUNCTION__ << "][Line " << __LINE__ << "]: FAIL at " << (#cond) << std::endl; \ - return -1; \ - } \ - } - -#define PCAP 0 #define PCAP_CRNTI (0x1001) #define PCAP_TTI (666) using namespace srsran; -#if PCAP -#include "srsran/common/mac_nr_pcap.h" -#include "srsran/mac/mac_nr_pdu.h" -static std::unique_ptr pcap_handle = nullptr; -#endif +#include "srsran/common/mac_pcap.h" +#include "srsran/mac/mac_rar_pdu_nr.h" +#include "srsran/mac/mac_sch_pdu_nr.h" +static std::unique_ptr pcap_handle = nullptr; int write_pdu_to_pcap(const uint32_t lcid, const uint8_t* payload, const uint32_t len) { -#if PCAP if (pcap_handle) { byte_buffer_t tx_buffer; - srsran::mac_nr_sch_pdu tx_pdu; + srsran::mac_sch_pdu_nr tx_pdu; tx_pdu.init_tx(&tx_buffer, len + 10); tx_pdu.add_sdu(lcid, payload, len); tx_pdu.pack(); - pcap_handle->write_dl_crnti(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + pcap_handle->write_dl_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); return SRSRAN_SUCCESS; } -#endif return SRSRAN_ERROR; } @@ -87,6 +77,7 @@ void corrupt_pdu_header(srsran::byte_buffer_t& pdu, const uint32_t header_len, c // RLC AM PDU 12bit with complete SDU int rlc_am_nr_pdu_test1() { + test_delimit_logger delimiter("PDU test 1"); const int header_len = 2, payload_len = 4; std::array tv = {0x80, 0x00, 0x11, 0x22, 0x33, 0x44}; srsran::byte_buffer_t pdu = make_pdu_and_log(tv); @@ -110,6 +101,7 @@ int rlc_am_nr_pdu_test1() // RLC AM PDU 12bit first segment of SDU with P flag and SN 511 int rlc_am_nr_pdu_test2() { + test_delimit_logger delimiter("PDU test 2"); const int header_len = 2, payload_len = 4; std::array tv = {0xd1, 0xff, 0x11, 0x22, 0x33, 0x44}; srsran::byte_buffer_t pdu = make_pdu_and_log(tv); @@ -138,6 +130,7 @@ int rlc_am_nr_pdu_test2() // RLC AM PDU 12bit last segment of SDU without P flag and SN 0x0404 and SO 0x0404 (1028) int rlc_am_nr_pdu_test3() { + test_delimit_logger delimiter("PDU test 3"); const int header_len = 4, payload_len = 4; std::array tv = {0xa4, 0x04, 0x04, 0x04, 0x11, 0x22, 0x33, 0x44}; srsran::byte_buffer_t pdu = make_pdu_and_log(tv); @@ -166,6 +159,7 @@ int rlc_am_nr_pdu_test3() // RLC AM PDU 18bit full SDU with P flag and SN 0x100000001000000010 (131586) int rlc_am_nr_pdu_test4() { + test_delimit_logger delimiter("PDU test 4"); const int header_len = 3, payload_len = 4; std::array tv = {0xc2, 0x02, 0x02, 0x11, 0x22, 0x33, 0x44}; srsran::byte_buffer_t pdu = make_pdu_and_log(tv); @@ -194,6 +188,7 @@ int rlc_am_nr_pdu_test4() // RLC AM PDU 18bit middle part of SDU (SO 514) without P flag and SN 131327 int rlc_am_nr_pdu_test5() { + test_delimit_logger delimiter("PDU test 5"); const int header_len = 5, payload_len = 4; std::array tv = {0xb2, 0x00, 0xff, 0x02, 0x02, 0x11, 0x22, 0x33, 0x44}; srsran::byte_buffer_t pdu = make_pdu_and_log(tv); @@ -222,6 +217,7 @@ int rlc_am_nr_pdu_test5() // Malformed RLC AM PDU 18bit with reserved bits set int rlc_am_nr_pdu_test6() { + test_delimit_logger delimiter("PDU test 6"); const int header_len = 5, payload_len = 4; std::array tv = {0xb7, 0x00, 0xff, 0x02, 0x02, 0x11, 0x22, 0x33, 0x44}; srsran::byte_buffer_t pdu = make_pdu_and_log(tv); @@ -234,10 +230,11 @@ int rlc_am_nr_pdu_test6() return SRSRAN_SUCCESS; } -///< Control PDU tests +///< Control PDU tests (12bit SN) // Status PDU for 12bit SN with ACK_SN=2065 and no further NACK_SN (E1 bit not set) -int rlc_am_nr_control_pdu_test1() +int rlc_am_nr_control_pdu_12bit_sn_test1() { + test_delimit_logger delimiter("Control PDU (12bit SN) test 1"); const int len = 3; std::array tv = {0x08, 0x11, 0x00}; srsran::byte_buffer_t pdu = make_pdu_and_log(tv); @@ -245,10 +242,10 @@ int rlc_am_nr_control_pdu_test1() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 2065); - TESTASSERT(status_pdu.N_nack == 0); + TESTASSERT(status_pdu.nacks.size() == 0); // reset status PDU pdu.clear(); @@ -265,8 +262,9 @@ int rlc_am_nr_control_pdu_test1() } // Status PDU for 12bit SN with ACK_SN=2065 and NACK_SN=273 (E1 bit set) -int rlc_am_nr_control_pdu_test2() +int rlc_am_nr_control_pdu_12bit_sn_test2() { + test_delimit_logger delimiter("Control PDU (12bit SN) test 2"); const int len = 5; std::array tv = {0x08, 0x11, 0x80, 0x11, 0x10}; srsran::byte_buffer_t pdu = make_pdu_and_log(tv); @@ -274,18 +272,2409 @@ int rlc_am_nr_control_pdu_test2() TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); // unpack PDU - rlc_am_nr_status_pdu_t status_pdu = {}; + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); + TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == SRSRAN_SUCCESS); + TESTASSERT(status_pdu.ack_sn == 2065); + TESTASSERT(status_pdu.nacks.size() == 1); + TESTASSERT(status_pdu.nacks[0].nack_sn == 273); + + // reset status PDU + pdu.clear(); + + // pack again + TESTASSERT(rlc_am_nr_write_status_pdu(status_pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &pdu) == SRSRAN_SUCCESS); + TESTASSERT(pdu.N_bytes == tv.size()); + + write_pdu_to_pcap(4, pdu.msg, pdu.N_bytes); + + TESTASSERT(memcmp(pdu.msg, tv.data(), pdu.N_bytes) == 0); + + return SRSRAN_SUCCESS; +} + +// Status PDU for 12bit SN with ACK_SN=2065, NACK_SN=273, SO_START=2, SO_END=5, NACK_SN=275, SO_START=5, SO_END=0xFFFF +// E1 and E2 bit set on first NACK, only E2 on second. +int rlc_am_nr_control_pdu_12bit_sn_test3() +{ + test_delimit_logger delimiter("Control PDU (12bit SN) test 3"); + const int len = 15; + std::array tv = { + 0x08, 0x11, 0x80, 0x11, 0x1c, 0x00, 0x02, 0x00, 0x05, 0x11, 0x34, 0x00, 0x05, 0xFF, 0xFF}; + srsran::byte_buffer_t pdu = make_pdu_and_log(tv); + + TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); + + // unpack PDU + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == SRSRAN_SUCCESS); TESTASSERT(status_pdu.ack_sn == 2065); - TESTASSERT(status_pdu.N_nack == 1); + TESTASSERT(status_pdu.nacks.size() == 2); TESTASSERT(status_pdu.nacks[0].nack_sn == 273); + TESTASSERT(status_pdu.nacks[0].so_start == 2); + TESTASSERT(status_pdu.nacks[0].so_end == 5); + TESTASSERT(status_pdu.nacks[1].nack_sn == 275); + TESTASSERT(status_pdu.nacks[1].so_start == 5); + TESTASSERT(status_pdu.nacks[1].so_end == 0xFFFF); // reset status PDU pdu.clear(); // pack again TESTASSERT(rlc_am_nr_write_status_pdu(status_pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &pdu) == SRSRAN_SUCCESS); - // TESTASSERT(pdu.N_bytes == tv.size()); + TESTASSERT(pdu.N_bytes == tv.size()); + + write_pdu_to_pcap(4, pdu.msg, pdu.N_bytes); + TESTASSERT(memcmp(pdu.msg, tv.data(), pdu.N_bytes) == 0); + + return SRSRAN_SUCCESS; +} + +// Status PDU for 12bit SN with ACK_SN=2065, NACK_SN=273, SO_START=2, SO_END=5, NACK_SN=275 +// E1 and E2 bit set on first NACK, neither E1 or E2 on the second. +int rlc_am_nr_control_pdu_12bit_sn_test4() +{ + test_delimit_logger delimiter("Control PDU (12bit SN) test 4"); + const int len = 11; + std::array tv = {0x08, 0x11, 0x80, 0x11, 0x1c, 0x00, 0x02, 0x00, 0x05, 0x11, 0x30}; + srsran::byte_buffer_t pdu = make_pdu_and_log(tv); + + TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); + + // unpack PDU + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); + TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == SRSRAN_SUCCESS); + TESTASSERT(status_pdu.ack_sn == 2065); + TESTASSERT(status_pdu.nacks.size() == 2); + TESTASSERT(status_pdu.nacks[0].nack_sn == 273); + TESTASSERT(status_pdu.nacks[0].has_so == true); + TESTASSERT(status_pdu.nacks[0].so_start == 2); + TESTASSERT(status_pdu.nacks[0].so_end == 5); + TESTASSERT(status_pdu.nacks[1].nack_sn == 275); + TESTASSERT(status_pdu.nacks[1].has_so == false); + + // reset status PDU + pdu.clear(); + + // pack again + TESTASSERT(rlc_am_nr_write_status_pdu(status_pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &pdu) == SRSRAN_SUCCESS); + TESTASSERT(pdu.N_bytes == tv.size()); + + write_pdu_to_pcap(4, pdu.msg, pdu.N_bytes); + TESTASSERT(memcmp(pdu.msg, tv.data(), pdu.N_bytes) == 0); + + return SRSRAN_SUCCESS; +} + +// Malformed Status PDU, with E1 still set at the end of the PDU +// 12bit SN with ACK_SN=2065, NACK_SN=273, SO_START=2, SO_END=5, NACK_SN=275, SO_START=5, SO_END=0xFFFF +// E1 and E2 bit set on first NACK, only E2 on second. +int rlc_am_nr_control_pdu_12bit_sn_test5() +{ + test_delimit_logger delimiter("Control PDU (12bit SN) test 5"); + const int len = 15; + std::array tv = { + 0x08, 0x11, 0x80, 0x11, 0x1c, 0x00, 0x02, 0x00, 0x05, 0x11, 0x3c, 0x00, 0x05, 0xFF, 0xFF}; + srsran::byte_buffer_t pdu = make_pdu_and_log(tv); + + TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); + + // unpack PDU + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); + TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == 0); + + return SRSRAN_SUCCESS; +} + +// Status PDU for 12bit SN with ACK_SN=2065, +// NACK range0: 3 full SDUs, NACK_SN=273..275 +// NACK range1: missing segment sequence across 4 SDUs +// starting at NACK_SN=276, SO_START=2, +// ending at NACK_SN=279, SO_END=5 +// E1 and E3 bit set on first NACK, E2 and E3 bit set on the second. +int rlc_am_nr_control_pdu_12bit_sn_test_nack_range() +{ + test_delimit_logger delimiter("Control PDU (12bit SN) test NACK range"); + const int len = 13; + std::array tv = {0x08, // D/C | 3CPT | 4ACK_SN_upper + 0x11, // 8ACK_SN_lower + 0x80, // E1 | 7R + 0x11, // 8NACK_SN_upper + 0x1a, // 4NACK_SN_lower | E1 | E2 | E3 | R + 0x03, // 8NACK_range + 0x11, // 8NACK_SN_upper + 0x46, // 4NACK_SN_lower | E1 | E2 | E3 | R + 0x00, // 8SO_START_upper + 0x02, // 8SO_START_lower + 0x00, // 8SO_END_upper + 0x05, // 8SO_END_lower + 0x04}; // 8NACK_range + srsran::byte_buffer_t pdu = make_pdu_and_log(tv); + + TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); + + // unpack PDU + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size12bits); + TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &status_pdu) == SRSRAN_SUCCESS); + TESTASSERT(status_pdu.ack_sn == 2065); + TESTASSERT(status_pdu.nacks.size() == 2); + TESTASSERT(status_pdu.nacks[0].nack_sn == 273); + TESTASSERT(status_pdu.nacks[0].has_so == false); + TESTASSERT(status_pdu.nacks[0].has_nack_range == true); + TESTASSERT(status_pdu.nacks[0].nack_range == 3); + + TESTASSERT(status_pdu.nacks[1].nack_sn == 276); + TESTASSERT(status_pdu.nacks[1].has_so == true); + TESTASSERT(status_pdu.nacks[1].so_start == 2); + TESTASSERT(status_pdu.nacks[1].so_end == 5); + TESTASSERT(status_pdu.nacks[1].has_nack_range == true); + TESTASSERT(status_pdu.nacks[1].nack_range == 4); + + // reset status PDU + pdu.clear(); + + // pack again + TESTASSERT(rlc_am_nr_write_status_pdu(status_pdu, srsran::rlc_am_nr_sn_size_t::size12bits, &pdu) == SRSRAN_SUCCESS); + TESTASSERT(pdu.N_bytes == tv.size()); + + write_pdu_to_pcap(4, pdu.msg, pdu.N_bytes); + TESTASSERT(memcmp(pdu.msg, tv.data(), pdu.N_bytes) == 0); + + return SRSRAN_SUCCESS; +} + +// Test merge of NACKs upon status PDU creation -- previous NACK: non-range; next NACK: non-range +int rlc_am_nr_control_pdu_test_nack_merge_sdu_sdu(rlc_am_nr_sn_size_t sn_size) +{ + test_delimit_logger delimiter("Control PDU ({} bit SN) test NACK merge: SDU + SDU", to_number(sn_size)); + + const uint16_t so_end_of_sdu = rlc_status_nack_t::so_end_of_sdu; + const uint32_t mod_nr = cardinality(sn_size); + const uint32_t min_size = 3; + const uint32_t nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + const uint32_t so_size = 4; + const uint32_t range_size = 1; + + // Case: [...][NACK SDU] + [NACK SDU] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(false, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(2, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK SDU] + [NACK SDU] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1002; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size, status_pdu.packed_size); + TESTASSERT(prev_nack == status_pdu.nacks.front()); + TESTASSERT(next_nack == status_pdu.nacks.back()); + } + + // Case: [...][NACK SDU] + [NACK SDU] (continuous: merge with previous element) -- with SN overflow + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = mod_nr - 1; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 0; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(false, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(2, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK SDU] + [NACK SDU] (non-continuous, SN gap: append as is) -- with SN overflow + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = mod_nr - 1; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size, status_pdu.packed_size); + TESTASSERT(prev_nack == status_pdu.nacks.front()); + TESTASSERT(next_nack == status_pdu.nacks.back()); + } + + // Case: [...][NACK SDU] + [NACK segm] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 50; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(next_nack.so_end, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(2, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK SDU] + [NACK segm] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1002; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 50; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK SDU] + [NACK segm] (non-continuous, SO gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = true; + next_nack.so_start = 1; + next_nack.so_end = 50; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK segm] + [NACK SDU] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(prev_nack.so_start, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(so_end_of_sdu, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(2, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK segm] + [NACK SDU] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1002; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK segm] + [NACK SDU] (non-continuous, SO gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = 99; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK segm] + [NACK segm] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(prev_nack.so_start, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(next_nack.so_end, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(2, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK segm] + [NACK segm] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1002; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK segm] + [NACK segm] (non-continuous, SO gap (left): append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = 99; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK segm] + [NACK segm] (non-continuous, SO gap (right): append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = true; + next_nack.so_start = 5; + next_nack.so_end = 22; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + return SRSRAN_SUCCESS; +} + +// Test merge of NACKs upon status PDU creation -- previous NACK: range; next NACK: non-range +int rlc_am_nr_control_pdu_test_nack_merge_range_sdu(rlc_am_nr_sn_size_t sn_size) +{ + test_delimit_logger delimiter("Control PDU ({} bit SN) test NACK merge: range + SDU", to_number(sn_size)); + + const uint16_t so_end_of_sdu = rlc_status_nack_t::so_end_of_sdu; + const uint32_t mod_nr = cardinality(sn_size); + const uint32_t min_size = 3; + const uint32_t nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + const uint32_t so_size = 4; + const uint32_t range_size = 1; + + // Case: [...][NACK range] + [NACK SDU] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(false, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(prev_nack.nack_range + 1, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK range] + [NACK SDU] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1006; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + range_size, status_pdu.packed_size); + TESTASSERT(prev_nack == status_pdu.nacks.front()); + TESTASSERT(next_nack == status_pdu.nacks.back()); + } + + // Case: [...][NACK range] + [NACK SDU] (continuous: merge with previous element) -- with SN overflow + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = mod_nr - 1; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 4; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(false, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(prev_nack.nack_range + 1, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK range] + [NACK SDU] (non-continuous, SN gap: append as is) -- with SN overflow + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = mod_nr - 1; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 5; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + range_size, status_pdu.packed_size); + TESTASSERT(prev_nack == status_pdu.nacks.front()); + TESTASSERT(next_nack == status_pdu.nacks.back()); + } + + // Case: [...][NACK range] + [NACK segm] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 50; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(next_nack.so_end, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(prev_nack.nack_range + 1, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK range] + [NACK segm] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1006; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 50; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + range_size + so_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range] + [NACK segm] (non-continuous, SO gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = true; + next_nack.so_start = 1; + next_nack.so_end = 50; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + range_size + so_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range+segm] + [NACK SDU] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(prev_nack.so_start, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(so_end_of_sdu, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(prev_nack.nack_range + 1, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK range+segm] + [NACK SDU] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1006; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range+segm] + [NACK SDU] (non-continuous, SO gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = 99; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK SDU] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range+segm] + [NACK segm] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(prev_nack.so_start, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(next_nack.so_end, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(prev_nack.nack_range + 1, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK range+segm] + [NACK segm] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1006; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size + range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range+segm] + [NACK segm] (non-continuous, SO gap (left): append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = 99; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size + range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range+segm] + [NACK segm] (non-continuous, SO gap (right): append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = true; + next_nack.so_start = 5; + next_nack.so_end = 22; + next_nack.has_nack_range = false; + next_nack.nack_range = 0; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size + range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + return SRSRAN_SUCCESS; +} + +// Test merge of NACKs upon status PDU creation -- previous NACK: non-range; next NACK: range +int rlc_am_nr_control_pdu_test_nack_merge_sdu_range(rlc_am_nr_sn_size_t sn_size) +{ + test_delimit_logger delimiter("Control PDU ({} bit SN) test NACK merge: SDU + range", to_number(sn_size)); + + const uint16_t so_end_of_sdu = rlc_status_nack_t::so_end_of_sdu; + const uint32_t mod_nr = cardinality(sn_size); + const uint32_t min_size = 3; + const uint32_t nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + const uint32_t so_size = 4; + const uint32_t range_size = 1; + + // Case: [...][NACK SDU] + [NACK range] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(false, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(3, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK SDU] + [NACK range] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1002; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + range_size, status_pdu.packed_size); + TESTASSERT(prev_nack == status_pdu.nacks.front()); + TESTASSERT(next_nack == status_pdu.nacks.back()); + } + + // Case: [...][NACK SDU] + [NACK range] (continuous: merge with previous element) -- with SN overflow + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = mod_nr - 1; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 0; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(false, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(3, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK SDU] + [NACK range] (non-continuous, SN gap: append as is) -- with SN overflow + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = mod_nr - 1; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + range_size, status_pdu.packed_size); + TESTASSERT(prev_nack == status_pdu.nacks.front()); + TESTASSERT(next_nack == status_pdu.nacks.back()); + } + + // Case: [...][NACK SDU] + [NACK range+segm] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 50; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(next_nack.so_end, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(3, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK SDU] + [NACK range+segm] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1002; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 50; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK SDU] + [NACK range+segm] (non-continuous, SO gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK SDU] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = true; + next_nack.so_start = 1; + next_nack.so_end = 50; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK segm] + [NACK range] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(prev_nack.so_start, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(so_end_of_sdu, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(3, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK segm] + [NACK range] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1002; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK segm] + [NACK range] (non-continuous, SO gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = 99; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK segm] + [NACK range+segm] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(prev_nack.so_start, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(next_nack.so_end, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(3, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK segm] + [NACK range+segm] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1002; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size + range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK segm] + [NACK range+segm] (non-continuous, SO gap (left): append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = 99; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size + range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK segm] + [NACK range+segm] (non-continuous, SO gap (right): append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = false; + prev_nack.nack_range = 0; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1001; + next_nack.has_so = true; + next_nack.so_start = 5; + next_nack.so_end = 22; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size + range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + return SRSRAN_SUCCESS; +} + +// Test merge of NACKs upon status PDU creation -- previous NACK: range; next NACK: range +int rlc_am_nr_control_pdu_test_nack_merge_range_range(rlc_am_nr_sn_size_t sn_size) +{ + test_delimit_logger delimiter("Control PDU ({} bit SN) test NACK merge: range + SDU", to_number(sn_size)); + + const uint16_t so_end_of_sdu = rlc_status_nack_t::so_end_of_sdu; + const uint32_t mod_nr = cardinality(sn_size); + const uint32_t min_size = 3; + const uint32_t nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + const uint32_t so_size = 4; + const uint32_t range_size = 1; + + // Case: [...][NACK range] + [NACK range] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(false, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(prev_nack.nack_range + next_nack.nack_range, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK range] + [NACK range] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1006; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * range_size, status_pdu.packed_size); + TESTASSERT(prev_nack == status_pdu.nacks.front()); + TESTASSERT(next_nack == status_pdu.nacks.back()); + } + + // Case: [...][NACK range] + [NACK range] (continuous: merge with previous element) -- with SN overflow + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = mod_nr - 1; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 4; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(false, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(prev_nack.nack_range + next_nack.nack_range, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK range] + [NACK range] (non-continuous, SN gap: append as is) -- with SN overflow + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = mod_nr - 1; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 5; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * range_size, status_pdu.packed_size); + TESTASSERT(prev_nack == status_pdu.nacks.front()); + TESTASSERT(next_nack == status_pdu.nacks.back()); + } + + // Case: [...][NACK range] + [NACK range+segm] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 50; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(0, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(next_nack.so_end, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(prev_nack.nack_range + next_nack.nack_range, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK range] + [NACK range+segm] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1006; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 50; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * range_size + so_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range] + [NACK range+segm] (non-continuous, SO gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = false; + prev_nack.so_start = 0; + prev_nack.so_end = 0; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = true; + next_nack.so_start = 1; + next_nack.so_end = 50; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * range_size + so_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range+segm] + [NACK range] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(prev_nack.so_start, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(so_end_of_sdu, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(prev_nack.nack_range + next_nack.nack_range, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK range+segm] + [NACK range] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1006; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size + 2 * range_size, status_pdu.packed_size); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range+segm] + [NACK range] (non-continuous, SO gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = 99; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = false; + next_nack.so_start = 0; + next_nack.so_end = 0; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + so_size + 2 * range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range+segm] + [NACK range+segm] (continuous: merge with previous element) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + TESTASSERT_EQ(prev_nack.nack_sn, status_pdu.nacks.back().nack_sn); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_so); + TESTASSERT_EQ(prev_nack.so_start, status_pdu.nacks.back().so_start); + TESTASSERT_EQ(next_nack.so_end, status_pdu.nacks.back().so_end); + TESTASSERT_EQ(true, status_pdu.nacks.back().has_nack_range); + TESTASSERT_EQ(prev_nack.nack_range + next_nack.nack_range, status_pdu.nacks.back().nack_range); + } + + // Case: [...][NACK range+segm] + [NACK range+segm] (non-continuous, SN gap: append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1006; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size + 2 * range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range+segm] + [NACK range+segm] (non-continuous, SO gap (left): append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = 99; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = true; + next_nack.so_start = 0; + next_nack.so_end = 22; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size + 2 * range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + // Case: [...][NACK range+segm] + [NACK range+segm] (non-continuous, SO gap (right): append as is) + { + rlc_am_nr_status_pdu_t status_pdu(sn_size); + status_pdu.ack_sn = 2000; + TESTASSERT_EQ(0, status_pdu.nacks.size()); + + // Prepare status_pdu.nacks: [...][NACK range+segm] + rlc_status_nack_t prev_nack; + prev_nack.nack_sn = 1000; + prev_nack.has_so = true; + prev_nack.so_start = 7; + prev_nack.so_end = so_end_of_sdu; + prev_nack.has_nack_range = true; + prev_nack.nack_range = 5; + status_pdu.push_nack(prev_nack); + TESTASSERT_EQ(1, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + nack_size + so_size + range_size, status_pdu.packed_size); + + // Add next NACK: [NACK range+segm] + rlc_status_nack_t next_nack; + next_nack.nack_sn = 1005; + next_nack.has_so = true; + next_nack.so_start = 5; + next_nack.so_end = 22; + next_nack.has_nack_range = true; + next_nack.nack_range = 2; + status_pdu.push_nack(next_nack); + TESTASSERT_EQ(2, status_pdu.nacks.size()); + TESTASSERT_EQ(min_size + 2 * nack_size + 2 * so_size + 2 * range_size, status_pdu.packed_size); + TESTASSERT(status_pdu.nacks.front() == prev_nack); + TESTASSERT(status_pdu.nacks.back() == next_nack); + } + + return SRSRAN_SUCCESS; +} + +// Test status PDU for correct trimming and estimation of packed size +// 1) Test init, copy and reset +// 2) Test step-wise growth and trimming of status PDU while covering several corner cases +int rlc_am_nr_control_pdu_test_trimming(rlc_am_nr_sn_size_t sn_size) +{ + test_delimit_logger delimiter("Control PDU ({} bit SN) test trimming", to_number(sn_size)); + + // status PDU with no NACKs + { + constexpr uint32_t min_size = 3; + srsran::byte_buffer_t pdu; + rlc_am_nr_status_pdu_t status_pdu(sn_size); + + status_pdu.ack_sn = 99; + TESTASSERT_EQ(status_pdu.packed_size, min_size); // minimum size + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, min_size); + + rlc_am_nr_status_pdu_t status_pdu_copy = status_pdu; + TESTASSERT_EQ(status_pdu_copy.ack_sn, 99); + TESTASSERT_EQ(status_pdu_copy.packed_size, min_size); // minimum size + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu_copy, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, min_size); + + status_pdu.reset(); + + status_pdu.ack_sn = 77; + TESTASSERT_EQ(status_pdu.packed_size, min_size); // should still have minimum size + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, min_size); + + TESTASSERT_EQ(status_pdu_copy.ack_sn, 99); // shouldn't have changed + TESTASSERT_EQ(status_pdu_copy.packed_size, min_size); // minimum size + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu_copy, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, min_size); + } + + // status PDU with multiple NACKs + // expect: ACK=77, NACKs=[12][14][17 50:99][17 150:199][17 250:299][19][21 333:111 r5][27 444:666 r3] + { + constexpr uint32_t min_size = 3; + const uint32_t nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + constexpr uint32_t so_size = 4; + constexpr uint32_t range_size = 1; + uint32_t expected_size = min_size; + srsran::byte_buffer_t pdu; + rlc_am_nr_status_pdu_t status_pdu(sn_size); + + status_pdu.ack_sn = 77; + { + rlc_status_nack_t nack; + nack.nack_sn = 12; + status_pdu.push_nack(nack); + } + expected_size += nack_size; + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + { + rlc_status_nack_t nack; + nack.nack_sn = 14; + status_pdu.push_nack(nack); + } + expected_size += nack_size; + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + { + rlc_status_nack_t nack; + nack.nack_sn = 17; + nack.has_so = true; + nack.so_start = 50; + nack.so_end = 99; + status_pdu.push_nack(nack); + } + expected_size += nack_size + so_size; + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + { + rlc_status_nack_t nack; + nack.nack_sn = 17; + nack.has_so = true; + nack.so_start = 150; + nack.so_end = 199; + status_pdu.push_nack(nack); + } + expected_size += nack_size + so_size; + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + { + rlc_status_nack_t nack; + nack.nack_sn = 17; + nack.has_so = true; + nack.so_start = 250; + nack.so_end = 299; + status_pdu.push_nack(nack); + } + expected_size += nack_size + so_size; + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + { + rlc_status_nack_t nack; + nack.nack_sn = 19; + status_pdu.push_nack(nack); + } + expected_size += nack_size; + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + { + rlc_status_nack_t nack; + nack.nack_sn = 21; + nack.has_so = true; + nack.so_start = 333; + nack.so_end = 111; + nack.has_nack_range = true; + nack.nack_range = 5; + status_pdu.push_nack(nack); + } + expected_size += nack_size + so_size + range_size; + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + { + rlc_status_nack_t nack; + nack.nack_sn = 27; + nack.has_so = true; + nack.so_start = 444; + nack.so_end = 666; + nack.has_nack_range = true; + nack.nack_range = 3; + status_pdu.push_nack(nack); + } + expected_size += nack_size + so_size + range_size; + TESTASSERT_EQ(status_pdu.ack_sn, 77); + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + + // current state: ACK=77, NACKs=[12][14][17 50:99][17 150:199][17 250:299][19][21 333:111 r5][27 444:666 r3] + + // create a copy, check content + rlc_am_nr_status_pdu_t status_pdu_copy = status_pdu; + TESTASSERT_EQ(status_pdu_copy.ack_sn, 77); + TESTASSERT_EQ(status_pdu_copy.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu_copy, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + + // current state: ACK=77, NACKs=[12][14][17 50:99][17 150:199][17 250:299][19][21 333:111 r5][27 444:666 r3] + + // trim to much larger size: nothing should change + TESTASSERT_EQ(status_pdu.trim(expected_size * 2), true); + TESTASSERT_EQ(status_pdu.ack_sn, 77); + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + + // trim to exact size: nothing should change + TESTASSERT_EQ(status_pdu.trim(expected_size), true); + TESTASSERT_EQ(status_pdu.ack_sn, 77); + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + + // trim to (expected_size - 1): this should remove the last NACK and update ACK accordingly + TESTASSERT_EQ(status_pdu.trim(expected_size - 1), true); + expected_size -= nack_size + so_size + range_size; + TESTASSERT_EQ(status_pdu.ack_sn, 27); + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + + // current state: ACK=27, NACKs=[12][14][17 50:99][17 150:199][17 250:299][19][21 333:111 r5] + + // trim to (expected_size - last two NACKs): this should remove the last NACK and update ACK accordingly + TESTASSERT_EQ(status_pdu.trim(expected_size - (2 * nack_size + so_size + range_size)), true); + expected_size -= 2 * nack_size + so_size + range_size; + TESTASSERT_EQ(status_pdu.ack_sn, 19); + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + + // current state: ACK=19, NACKs=[12][14][17 50:99][17 150:199][17 250:299] + + // trim to (expected_size - 1): this should remove the last NACK and all other NACKs with the same SN + TESTASSERT_EQ(status_pdu.trim(expected_size - 1), true); + expected_size -= 3 * (nack_size + so_size); + TESTASSERT_EQ(status_pdu.ack_sn, 17); + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + + // current state: ACK=17, NACKs=[12][14] + + // trim to impossible size = 1: this should report a failure without changes of the PDU + TESTASSERT_EQ(status_pdu.trim(1), false); + TESTASSERT_EQ(status_pdu.ack_sn, 17); + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + + // current state: ACK=17, NACKs=[12][14] + + // trim to minimum size: this should remove all NACKs and update ACK to the SN of the first NACK + expected_size = min_size; + TESTASSERT_EQ(status_pdu.trim(expected_size), true); + TESTASSERT_EQ(status_pdu.ack_sn, 12); + TESTASSERT_EQ(status_pdu.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + + // current state: ACK=12, NACKs empty + + // check the copy again - should be unchanged if not a shallow copy + TESTASSERT_EQ(status_pdu_copy.ack_sn, 77); + TESTASSERT_EQ(status_pdu_copy.packed_size, expected_size); + TESTASSERT_EQ(rlc_am_nr_write_status_pdu(status_pdu_copy, sn_size, &pdu), SRSRAN_SUCCESS); + TESTASSERT_EQ(pdu.N_bytes, expected_size); + } + + return SRSRAN_SUCCESS; +} + +///< Control PDU tests (18bit SN) +// Status PDU for 18bit SN with ACK_SN=235929=0x39999=0b11 1001 1001 1001 1001 and no further NACK_SN (E1 bit not set) +int rlc_am_nr_control_pdu_18bit_sn_test1() +{ + test_delimit_logger delimiter("Control PDU (18bit SN) test 1"); + const int len = 3; + std::array tv = {0x0E, 0x66, 0x64}; + srsran::byte_buffer_t pdu = make_pdu_and_log(tv); + + TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); + + // unpack PDU + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); + TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == SRSRAN_SUCCESS); + TESTASSERT(status_pdu.ack_sn == 235929); + TESTASSERT(status_pdu.nacks.size() == 0); + + // reset status PDU + pdu.clear(); + + // pack again + TESTASSERT(rlc_am_nr_write_status_pdu(status_pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &pdu) == SRSRAN_SUCCESS); + TESTASSERT(pdu.N_bytes == tv.size()); write_pdu_to_pcap(4, pdu.msg, pdu.N_bytes); @@ -294,12 +2683,265 @@ int rlc_am_nr_control_pdu_test2() return SRSRAN_SUCCESS; } +// Status PDU for 18bit SN with ACK_SN=235929=0x39999=0b11 1001 1001 1001 1001 (E1 bit set) +// and NACK_SN=222822=0x36666=0b11 0110 0110 0110 0110 +int rlc_am_nr_control_pdu_18bit_sn_test2() +{ + test_delimit_logger delimiter("Control PDU (18bit SN) test 2"); + const int len = 6; + std::array tv = {0x0E, 0x66, 0x66, 0xD9, 0x99, 0x80}; + srsran::byte_buffer_t pdu = make_pdu_and_log(tv); + + TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); + + // unpack PDU + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); + TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == SRSRAN_SUCCESS); + TESTASSERT(status_pdu.ack_sn == 235929); + TESTASSERT(status_pdu.nacks.size() == 1); + TESTASSERT(status_pdu.nacks[0].nack_sn == 222822); + + // reset status PDU + pdu.clear(); + + // pack again + TESTASSERT(rlc_am_nr_write_status_pdu(status_pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &pdu) == SRSRAN_SUCCESS); + TESTASSERT(pdu.N_bytes == tv.size()); + + write_pdu_to_pcap(4, pdu.msg, pdu.N_bytes); + + TESTASSERT(memcmp(pdu.msg, tv.data(), pdu.N_bytes) == 0); + + return SRSRAN_SUCCESS; +} + +// Status PDU for 18bit SN with ACK_SN=235929=0x39999=0b11 1001 1001 1001 1001 (E1 bit set), +// NACK_SN=222822=0x36666=0b11 0110 0110 0110 0110 (E1 and E2 bit set), +// SO_START=2, SO_END=5, +// NACK_SN=222975=0x366ff=0b11 0110 0110 1111 1111 (E2 bit set), +// SO_START=5, SO_END=0xFFFF +int rlc_am_nr_control_pdu_18bit_sn_test3() +{ + test_delimit_logger delimiter("Control PDU (18bit SN) test 3"); + const int len = 17; + std::array tv = {0b00001110, // D/C | 3CPT | 4ACK_SN_upper + 0b01100110, // 8ACK_SN_center + 0b01100110, // 6ACK_SN_lower | E1 | R + 0b11011001, // 8NACK_SN_upper + 0b10011001, // 8NACK_SN_center + 0b10110000, // 2NACK_SN_lower | E1 | E2 | E3 | 3R + 0x00, // 8SO_START_upper + 0x02, // 8SO_START_lower + 0x00, // 8SO_END_upper + 0x05, // 8SO_END_lower + 0b11011001, // 8NACK_SN_upper + 0b10111111, // 8NACK_SN_center + 0b11010000, // 2NACK_SN_lower | E1 | E2 | E3 | 3R + 0x00, // 8SO_START_upper + 0x05, // 8SO_START_lower + 0xFF, // 8SO_END_upper + 0xFF}; // 8SO_END_lower + srsran::byte_buffer_t pdu = make_pdu_and_log(tv); + + TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); + + // unpack PDU + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); + TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == SRSRAN_SUCCESS); + TESTASSERT(status_pdu.ack_sn == 235929); + TESTASSERT(status_pdu.nacks.size() == 2); + TESTASSERT(status_pdu.nacks[0].nack_sn == 222822); + TESTASSERT(status_pdu.nacks[0].has_so == true); + TESTASSERT(status_pdu.nacks[0].so_start == 2); + TESTASSERT(status_pdu.nacks[0].so_end == 5); + TESTASSERT(status_pdu.nacks[1].nack_sn == 222975); + TESTASSERT(status_pdu.nacks[1].has_so == true); + TESTASSERT(status_pdu.nacks[1].so_start == 5); + TESTASSERT(status_pdu.nacks[1].so_end == 0xFFFF); + + // reset status PDU + pdu.clear(); + + // pack again + TESTASSERT(rlc_am_nr_write_status_pdu(status_pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &pdu) == SRSRAN_SUCCESS); + TESTASSERT(pdu.N_bytes == tv.size()); + + write_pdu_to_pcap(4, pdu.msg, pdu.N_bytes); + TESTASSERT(memcmp(pdu.msg, tv.data(), pdu.N_bytes) == 0); + + return SRSRAN_SUCCESS; +} + +// Status PDU for 18bit SN with ACK_SN=235929=0x39999=0b11 1001 1001 1001 1001 (E1 bit set), +// NACK_SN=222822=0x36666=0b11 0110 0110 0110 0110 (E1 and E2 bit set), +// SO_START=2, SO_END=5, +// NACK_SN=222975=0x366ff=0b11 0110 0110 1111 1111 (E1 and E2 bit not set), +int rlc_am_nr_control_pdu_18bit_sn_test4() +{ + test_delimit_logger delimiter("Control PDU (18bit SN) test 4"); + const int len = 13; + std::array tv = {0b00001110, // D/C | 3CPT | 4ACK_SN_upper + 0b01100110, // 8ACK_SN_center + 0b01100110, // 6ACK_SN_lower | E1 | R + 0b11011001, // 8NACK_SN_upper + 0b10011001, // 8NACK_SN_center + 0b10110000, // 2NACK_SN_lower | E1 | E2 | E3 | 3R + 0x00, // 8SO_START_upper + 0x02, // 8SO_START_lower + 0x00, // 8SO_END_upper + 0x05, // 8SO_END_lower + 0b11011001, // 8NACK_SN_upper + 0b10111111, // 8NACK_SN_center + 0b11000000}; // 2NACK_SN_lower | E1 | E2 | E3 | 3R + srsran::byte_buffer_t pdu = make_pdu_and_log(tv); + + TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); + + // unpack PDU + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); + TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == SRSRAN_SUCCESS); + TESTASSERT(status_pdu.ack_sn == 235929); + TESTASSERT(status_pdu.nacks.size() == 2); + TESTASSERT(status_pdu.nacks[0].nack_sn == 222822); + TESTASSERT(status_pdu.nacks[0].has_so == true); + TESTASSERT(status_pdu.nacks[0].so_start == 2); + TESTASSERT(status_pdu.nacks[0].so_end == 5); + TESTASSERT(status_pdu.nacks[1].nack_sn == 222975); + TESTASSERT(status_pdu.nacks[1].has_so == false); + + // reset status PDU + pdu.clear(); + + // pack again + TESTASSERT(rlc_am_nr_write_status_pdu(status_pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &pdu) == SRSRAN_SUCCESS); + TESTASSERT(pdu.N_bytes == tv.size()); + + write_pdu_to_pcap(4, pdu.msg, pdu.N_bytes); + TESTASSERT(memcmp(pdu.msg, tv.data(), pdu.N_bytes) == 0); + + return SRSRAN_SUCCESS; +} + +// Malformed Status PDU, similar to test3 but with E1 still set at the end of the PDU +// Status PDU for 18bit SN with ACK_SN=235929=0x39999=0b11 1001 1001 1001 1001 (E1 bit set), +// NACK_SN=222822=0x36666=0b11 0110 0110 0110 0110 (E1 and E2 bit set), +// SO_START=2, SO_END=5, +// NACK_SN=222975=0x366ff=0b11 0110 0110 1111 1111 ([!E1!] and E2 bit set), +// SO_START=5, SO_END=0xFFFF +int rlc_am_nr_control_pdu_18bit_sn_test5() +{ + test_delimit_logger delimiter("Control PDU (18bit SN) test 5"); + const int len = 17; + std::array tv = {0b00001110, // D/C | 3CPT | 4ACK_SN_upper + 0b01100110, // 8ACK_SN_center + 0b01100110, // 6ACK_SN_lower | E1 | R + 0b11011001, // 8NACK_SN_upper + 0b10011001, // 8NACK_SN_center + 0b10110000, // 2NACK_SN_lower | E1 | E2 | E3 | 3R + 0x00, // 8SO_START_upper + 0x02, // 8SO_START_lower + 0x00, // 8SO_END_upper + 0x05, // 8SO_END_lower + 0b11011001, // 8NACK_SN_upper + 0b10111111, // 8NACK_SN_center + 0b11110000, // 2NACK_SN_lower | [!E1!] | E2 | E3 | 3R + 0x00, // 8SO_START_upper + 0x05, // 8SO_START_lower + 0xFF, // 8SO_END_upper + 0xFF}; // 8SO_END_lower + srsran::byte_buffer_t pdu = make_pdu_and_log(tv); + + TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); + + // unpack PDU + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); + TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == 0); + + return SRSRAN_SUCCESS; +} + +// Status PDU for 18bit SN with ACK_SN=200977=0x31111=0b11 0001 0001 0001 0001, +// NACK range0: 3 full SDUs, NACK_SN=69905=0x11111=0b01 0001 0001 0001 0001 +// NACK range1: missing segment sequence across 4 SDUs +// starting at NACK_SN=69913=0x11119=0b01 0001 0001 0001 1001, SO_START=2, +// ending at NACK_SN=69916, SO_END=5 +// E1 and E3 bit set on first NACK, E2 and E3 bit set on the second. +int rlc_am_nr_control_pdu_18bit_sn_test_nack_range() +{ + test_delimit_logger delimiter("Control PDU (18bit SN) test NACK range"); + const int len = 15; + std::array tv = {0b00001100, // D/C | 3CPT | 4ACK_SN_upper + 0b01000100, // 8ACK_SN_center + 0b01000110, // 6ACK_SN_lower | E1 | R + 0b01000100, // 8NACK_SN_upper + 0b01000100, // 8NACK_SN_center + 0b01101000, // 2NACK_SN_lower | E1 | E2 | E3 | 3R + 0x03, // 8NACK_range + 0b01000100, // 8NACK_SN_upper + 0b01000110, // 8NACK_SN_center + 0b01011000, // 2NACK_SN_lower | E1 | E2 | E3 | 3R + 0x00, // 8SO_START_upper + 0x02, // 8SO_START_lower + 0x00, // 8SO_END_upper + 0x05, // 8SO_END_lower + 0x04}; // 8NACK_range + srsran::byte_buffer_t pdu = make_pdu_and_log(tv); + + TESTASSERT(rlc_am_is_control_pdu(pdu.msg) == true); + + // unpack PDU + rlc_am_nr_status_pdu_t status_pdu(srsran::rlc_am_nr_sn_size_t::size18bits); + TESTASSERT(rlc_am_nr_read_status_pdu(&pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &status_pdu) == SRSRAN_SUCCESS); + TESTASSERT(status_pdu.ack_sn == 200977); + TESTASSERT(status_pdu.nacks.size() == 2); + TESTASSERT(status_pdu.nacks[0].nack_sn == 69905); + TESTASSERT(status_pdu.nacks[0].has_so == false); + TESTASSERT(status_pdu.nacks[0].has_nack_range == true); + TESTASSERT(status_pdu.nacks[0].nack_range == 3); + + TESTASSERT(status_pdu.nacks[1].nack_sn == 69913); + TESTASSERT(status_pdu.nacks[1].has_so == true); + TESTASSERT(status_pdu.nacks[1].so_start == 2); + TESTASSERT(status_pdu.nacks[1].so_end == 5); + TESTASSERT(status_pdu.nacks[1].has_nack_range == true); + TESTASSERT(status_pdu.nacks[1].nack_range == 4); + + // reset status PDU + pdu.clear(); + + // pack again + TESTASSERT(rlc_am_nr_write_status_pdu(status_pdu, srsran::rlc_am_nr_sn_size_t::size18bits, &pdu) == SRSRAN_SUCCESS); + TESTASSERT(pdu.N_bytes == tv.size()); + + write_pdu_to_pcap(4, pdu.msg, pdu.N_bytes); + TESTASSERT(memcmp(pdu.msg, tv.data(), pdu.N_bytes) == 0); + + return SRSRAN_SUCCESS; +} + int main(int argc, char** argv) { -#if PCAP - pcap_handle = std::unique_ptr(new srsran::mac_nr_pcap()); - pcap_handle->open("rlc_am_nr_pdu_test.pcap"); -#endif + static const struct option long_options[] = {{"pcap", no_argument, nullptr, 'p'}, {nullptr, 0, nullptr, 0}}; + + // Parse arguments + while (true) { + int option_index = 0; + int c = getopt_long(argc, argv, "p", long_options, &option_index); + if (c == -1) { + break; + } + + switch (c) { + case 'p': + printf("Setting up PCAP\n"); + pcap_handle = std::unique_ptr(new srsran::mac_pcap()); + pcap_handle->open("rlc_am_nr_pdu_test.pcap"); + break; + default: + fprintf(stderr, "error parsing arguments\n"); + return SRSRAN_ERROR; + } + } srslog::init(); @@ -333,13 +2975,113 @@ int main(int argc, char** argv) return SRSRAN_ERROR; } - if (rlc_am_nr_control_pdu_test1()) { - fprintf(stderr, "rlc_am_nr_control_pdu_test1() failed.\n"); + if (rlc_am_nr_control_pdu_12bit_sn_test1()) { + fprintf(stderr, "rlc_am_nr_control_pdu_12bit_sn_test1() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_12bit_sn_test2()) { + fprintf(stderr, "rlc_am_nr_control_pdu_12bit_sn_test2() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_12bit_sn_test3()) { + fprintf(stderr, "rlc_am_nr_control_pdu_12bit_sn_test3() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_12bit_sn_test4()) { + fprintf(stderr, "rlc_am_nr_control_pdu_12bit_sn_test4() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_12bit_sn_test5()) { + fprintf(stderr, "rlc_am_nr_control_pdu_12bit_sn_test5() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_12bit_sn_test_nack_range()) { + fprintf(stderr, "rlc_am_nr_control_pdu_12bit_sn_test_nack_range() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_test_nack_merge_sdu_sdu(rlc_am_nr_sn_size_t::size12bits)) { + fprintf(stderr, "rlc_am_nr_control_pdu_test_nack_merge_sdu_sdu(size12bits) failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_test_nack_merge_range_sdu(rlc_am_nr_sn_size_t::size12bits)) { + fprintf(stderr, "rlc_am_nr_control_pdu_test_nack_merge_range_sdu(size12bits) failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_test_nack_merge_sdu_range(rlc_am_nr_sn_size_t::size12bits)) { + fprintf(stderr, "rlc_am_nr_control_pdu_test_nack_merge_sdu_range(size12bits) failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_test_nack_merge_range_range(rlc_am_nr_sn_size_t::size12bits)) { + fprintf(stderr, "rlc_am_nr_control_pdu_test_nack_merge_range_range(size12bits) failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_test_trimming(rlc_am_nr_sn_size_t::size12bits)) { + fprintf(stderr, "rlc_am_nr_control_pdu_test_trimming(size12bits) failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_18bit_sn_test1()) { + fprintf(stderr, "rlc_am_nr_control_pdu_18bit_sn_test1() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_18bit_sn_test2()) { + fprintf(stderr, "rlc_am_nr_control_pdu_18bit_sn_test2() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_18bit_sn_test3()) { + fprintf(stderr, "rlc_am_nr_control_pdu_18bit_sn_test3() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_18bit_sn_test4()) { + fprintf(stderr, "rlc_am_nr_control_pdu_18bit_sn_test4() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_18bit_sn_test5()) { + fprintf(stderr, "rlc_am_nr_control_pdu_18bit_sn_test5() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_18bit_sn_test_nack_range()) { + fprintf(stderr, "rlc_am_nr_control_pdu_18bit_sn_test_nack_range() failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_test_nack_merge_sdu_sdu(rlc_am_nr_sn_size_t::size18bits)) { + fprintf(stderr, "rlc_am_nr_control_pdu_test_nack_merge_sdu_sdu(size18bits) failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_test_nack_merge_range_sdu(rlc_am_nr_sn_size_t::size18bits)) { + fprintf(stderr, "rlc_am_nr_control_pdu_test_nack_merge_range_sdu(size18bits) failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_test_nack_merge_sdu_range(rlc_am_nr_sn_size_t::size18bits)) { + fprintf(stderr, "rlc_am_nr_control_pdu_test_nack_merge_sdu_range(size18bits) failed.\n"); + return SRSRAN_ERROR; + } + + if (rlc_am_nr_control_pdu_test_nack_merge_range_range(rlc_am_nr_sn_size_t::size18bits)) { + fprintf(stderr, "rlc_am_nr_control_pdu_test_nack_merge_range_range(size18bits) failed.\n"); return SRSRAN_ERROR; } - if (rlc_am_nr_control_pdu_test2()) { - fprintf(stderr, "rlc_am_nr_control_pdu_test2() failed.\n"); + if (rlc_am_nr_control_pdu_test_trimming(rlc_am_nr_sn_size_t::size18bits)) { + fprintf(stderr, "rlc_am_nr_control_pdu_test_trimming(size18bits) failed.\n"); return SRSRAN_ERROR; } diff --git a/lib/test/rlc/rlc_am_nr_test.cc b/lib/test/rlc/rlc_am_nr_test.cc new file mode 100644 index 0000000000..6a08a0bd8b --- /dev/null +++ b/lib/test/rlc/rlc_am_nr_test.cc @@ -0,0 +1,3493 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "rlc_test_common.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/common/rlc_pcap.h" +#include "srsran/common/test_common.h" +#include "srsran/common/threads.h" +#include "srsran/interfaces/ue_pdcp_interfaces.h" +#include "srsran/interfaces/ue_rrc_interfaces.h" +#include "srsran/rlc/rlc_am_nr.h" + +#define NBUFS 5 +#define HAVE_PCAP 0 +#define SDU_SIZE 500 + +using namespace srsue; +using namespace srsran; + +int basic_test_tx(rlc_am* rlc, byte_buffer_t pdu_bufs[NBUFS], rlc_am_nr_sn_size_t sn_size) +{ + // Push 5 SDUs into RLC1 + unique_byte_buffer_t sdu_bufs[NBUFS]; + constexpr uint32_t payload_size = 1; // Give each buffer a size of 1 byte + for (int i = 0; i < NBUFS; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = payload_size; // Give each buffer a size of 1 byte + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc->write_sdu(std::move(sdu_bufs[i])); + } + + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + uint32_t data_pdu_size = header_size + payload_size; + uint32_t expect_buffer_state = NBUFS * data_pdu_size; + TESTASSERT_EQ(expect_buffer_state, rlc->get_buffer_state()); + + // Read 5 PDUs from RLC1 (1 byte each) + for (int i = 0; i < NBUFS; i++) { + uint32_t len = rlc->read_pdu(pdu_bufs[i].msg, data_pdu_size); + pdu_bufs[i].N_bytes = len; + TESTASSERT_EQ(data_pdu_size, len); + } + + TESTASSERT_EQ(0, rlc->get_buffer_state()); + return SRSRAN_SUCCESS; +} + +/* + * Test the limits of the TX/RX window checkers + */ +int window_checker_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("window checkers ({} bit SN)", to_number(sn_size)); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + + rlc_am_nr_tx* tx = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx = dynamic_cast(rlc1.get_rx()); + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return SRSRAN_ERROR; + } + + { + // RLC1 RX_NEXT == 0 and RLC2 TX_NEXT_ACK == 0 + uint32_t sn_inside_below = 0; + uint32_t sn_inside_above = cardinality(sn_size) / 2 - 1; + uint32_t sn_outside_below = cardinality(sn_size) - 1; + uint32_t sn_outside_above = cardinality(sn_size) / 2; + TESTASSERT_EQ(true, rx->inside_rx_window(sn_inside_below)); + TESTASSERT_EQ(true, rx->inside_rx_window(sn_inside_above)); + TESTASSERT_EQ(false, rx->inside_rx_window(sn_outside_below)); + TESTASSERT_EQ(false, rx->inside_rx_window(sn_outside_above)); + TESTASSERT_EQ(true, tx->inside_tx_window(sn_inside_below)); + TESTASSERT_EQ(true, tx->inside_tx_window(sn_inside_above)); + TESTASSERT_EQ(false, tx->inside_tx_window(sn_outside_below)); + TESTASSERT_EQ(false, tx->inside_tx_window(sn_outside_above)); + } + + rlc_am_nr_rx_state_t rx_st = {}; + rx_st.rx_next = cardinality(sn_size) - 1; + ; + rlc_am_nr_tx_state_t tx_st = {}; + tx_st.tx_next_ack = cardinality(sn_size) - 1; + ; + + rx->set_rx_state(rx_st); + tx->set_tx_state(tx_st); + + { + // RX_NEXT == 4095 TX_NEXT_ACK == 4095 + uint32_t sn_inside_below = 0; + uint32_t sn_inside_above = cardinality(sn_size) / 2 - 2; + uint32_t sn_outside_below = cardinality(sn_size) - 2; + uint32_t sn_outside_above = cardinality(sn_size) / 2; + TESTASSERT_EQ(true, rx->inside_rx_window(sn_inside_below)); + TESTASSERT_EQ(true, rx->inside_rx_window(sn_inside_above)); + TESTASSERT_EQ(false, rx->inside_rx_window(sn_outside_below)); + TESTASSERT_EQ(false, rx->inside_rx_window(sn_outside_above)); + TESTASSERT_EQ(true, tx->inside_tx_window(sn_inside_below)); + TESTASSERT_EQ(true, tx->inside_tx_window(sn_inside_above)); + TESTASSERT_EQ(false, tx->inside_tx_window(sn_outside_below)); + TESTASSERT_EQ(false, tx->inside_tx_window(sn_outside_above)); + } + return SRSRAN_SUCCESS; +} + +/* + * Test is retx_segmentation required + * + */ +int retx_segmentation_required_checker_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("retx segmentation required checkers ({} bit SN)", to_number(sn_size)); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + + rlc_am_nr_tx* tx = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx = dynamic_cast(rlc1.get_rx()); + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return SRSRAN_ERROR; + } + + unique_byte_buffer_t sdu_bufs[NBUFS]; + unique_byte_buffer_t pdu_bufs[NBUFS]; + for (int i = 0; i < NBUFS; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + pdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = 5; // Give each buffer a size of 1 byte + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_bufs[i])); + rlc1.read_pdu(pdu_bufs[i]->msg, 8); + } + + // Test full SDU retx + { + uint32_t nof_bytes = 8; + rlc_amd_retx_nr_t retx = {}; + retx.sn = 0; + retx.is_segment = false; + + tx->is_retx_segmentation_required(retx, nof_bytes); + TESTASSERT_EQ(false, tx->is_retx_segmentation_required(retx, nof_bytes)); + } + + // Test SDU retx segmentation required + { + uint32_t nof_bytes = 4; + rlc_amd_retx_nr_t retx; + retx.sn = 0; + retx.is_segment = false; + + tx->is_retx_segmentation_required(retx, nof_bytes); + TESTASSERT_EQ(true, tx->is_retx_segmentation_required(retx, nof_bytes)); + } + + // Test full SDU segment retx + { + uint32_t nof_bytes = 40; + rlc_amd_retx_nr_t retx = {}; + retx.sn = 0; + retx.is_segment = true; + retx.so_start = 4; + retx.segment_length = 2; + + tx->is_retx_segmentation_required(retx, nof_bytes); + TESTASSERT_EQ(false, tx->is_retx_segmentation_required(retx, nof_bytes)); + } + + // Test SDU segment retx segmentation required + { + uint32_t nof_bytes = 4; + rlc_amd_retx_nr_t retx = {}; + retx.sn = 0; + retx.is_segment = true; + retx.so_start = 4; + retx.segment_length = 2; + + tx->is_retx_segmentation_required(retx, nof_bytes); + TESTASSERT_EQ(true, tx->is_retx_segmentation_required(retx, nof_bytes)); + } + return SRSRAN_SUCCESS; +} + +/* + * Test the transmission and acknowledgement of 5 SDUs. + * + * Each SDU is transmitted as a single PDU. + * There are no lost PDUs, and the byte size is small, so the Poll_PDU configuration + * will trigger the status report. + * Poll PDU is configured to 4, so the 5th PDU should set the polling bit. + */ +int basic_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("basic tx/rx ({} bit SN)", to_number(sn_size)); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + if (not rlc2.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + // after configuring entity + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + + basic_test_tx(&rlc1, pdu_bufs, sn_size); + + // Write 5 PDUs into RLC2 + for (int i = 0; i < NBUFS; i++) { + rlc2.write_pdu(pdu_bufs[i].msg, pdu_bufs[i].N_bytes); + } + + TESTASSERT_EQ(3, rlc2.get_buffer_state()); + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, 3); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the last SN that was not received. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check TX_NEXT_ACK + rlc_am_nr_tx_state_t st = tx1->get_tx_state(); + TESTASSERT_EQ(5, st.tx_next_ack); + TESTASSERT_EQ(0, tx1->get_tx_window_utilization()); + + // Check PDCP notifications + TESTASSERT_EQ(5, tester.notified_counts.size()); + for (uint16_t i = 0; i < tester.sdus.size(); i++) { + TESTASSERT_EQ(1, tester.sdus[i]->N_bytes); + TESTASSERT_EQ(i, *(tester.sdus[i]->msg)); + TESTASSERT_EQ(1, tester.notified_counts[i]); + } + + // Check statistics + rlc_bearer_metrics_t metrics1 = rlc1.get_metrics(); + rlc_bearer_metrics_t metrics2 = rlc2.get_metrics(); + + constexpr uint32_t payload_size = 1; + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + uint32_t data_pdu_size = header_size + payload_size; + constexpr uint32_t status_pdu_size = 3; + uint32_t total_tx_pdu_bytes = NBUFS * data_pdu_size; // NBUFS * PDU size + uint32_t total_rx_pdu_bytes = status_pdu_size; // One status PDU + + // RLC1 PDU metrics + TESTASSERT_EQ(5, metrics1.num_tx_sdus); + TESTASSERT_EQ(0, metrics1.num_rx_sdus); + TESTASSERT_EQ(5, metrics1.num_tx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_lost_sdus); + // RLC1 SDU metrics + TESTASSERT_EQ(5, metrics1.num_tx_pdus); + TESTASSERT_EQ(1, metrics1.num_rx_pdus); // One status PDU + TESTASSERT_EQ(total_tx_pdu_bytes, metrics1.num_tx_pdu_bytes); // NBUFS * PDU size + TESTASSERT_EQ(total_rx_pdu_bytes, metrics1.num_rx_pdu_bytes); // One status PDU + TESTASSERT_EQ(0, metrics1.num_lost_sdus); // No lost SDUs + + // RLC2 PDU metrics + TESTASSERT_EQ(0, metrics2.num_tx_sdus); + TESTASSERT_EQ(5, metrics2.num_rx_sdus); + TESTASSERT_EQ(0, metrics2.num_tx_sdu_bytes); + TESTASSERT_EQ(5, metrics2.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics2.num_lost_sdus); + // RLC2 SDU metrics + TESTASSERT_EQ(1, metrics2.num_tx_pdus); // One status PDU + TESTASSERT_EQ(5, metrics2.num_rx_pdus); // 5 SDUs + TESTASSERT_EQ(total_rx_pdu_bytes, metrics2.num_tx_pdu_bytes); // One status PDU + TESTASSERT_EQ(total_tx_pdu_bytes, metrics2.num_rx_pdu_bytes); // NBUFS * PDU size + TESTASSERT_EQ(0, metrics2.num_lost_sdus); // No lost SDUs + return SRSRAN_SUCCESS; +} + +/* + * Test the loss of a single PDU. + * NACK should be visible in the status report. + * Retx after NACK should be present too. + * No further status reports shall be issued. + */ +int lost_pdu_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + test_delimit_logger delimiter("lost PDU ({} bit SN)", to_number(sn_size)); + + constexpr uint32_t payload_size = 1; + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + uint32_t data_pdu_size = header_size + payload_size; + uint32_t expect_buffer_state = NBUFS * data_pdu_size; + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + rlc_config_t rlc2_config = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + if (not rlc2.configure(rlc2_config)) { + return -1; + } + + // after configuring entity + TESTASSERT(0 == rlc1.get_buffer_state()); + + basic_test_tx(&rlc1, pdu_bufs, sn_size); + + // Write 5 PDUs into RLC2 + for (int i = 0; i < NBUFS; i++) { + if (i != 3) { + rlc2.write_pdu(pdu_bufs[i].msg, pdu_bufs[i].N_bytes); // Don't write RLC_SN=3. + } + } + + // Only after t-reassembly has expired, will the status report include NACKs. + TESTASSERT_EQ(3, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, 5); + status_buf.N_bytes = len; + + TESTASSERT(0 == rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(3, status_check.ack_sn); // 3 is the next expected SN (i.e. the lost packet.) + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + } + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // t-reassembly has expired. There should be a NACK in the status report. + constexpr uint32_t status_pdu_ack_size = 3; + uint32_t status_pdu_nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + TESTASSERT_EQ(status_pdu_ack_size + status_pdu_nack_size, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + uint32_t len = rlc2.read_pdu(status_buf.msg, status_pdu_ack_size + status_pdu_nack_size); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. + TESTASSERT_EQ(3, status_check.nacks[0].nack_sn); // Lost PDU SN=3. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check there is an Retx of SN=3 + TESTASSERT_EQ(data_pdu_size, rlc1.get_buffer_state()); + } + + { + // Check correct re-transmission + byte_buffer_t retx_buf; + uint32_t len = rlc1.read_pdu(retx_buf.msg, data_pdu_size); + retx_buf.N_bytes = len; + TESTASSERT_EQ(data_pdu_size, len); + + // Polling bit on the RETX should be required, as the buffers are not empty. + rlc2.write_pdu(retx_buf.msg, retx_buf.N_bytes); + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); // t-StatusProhibit is still running + } + + // Step timers until t-StatusProhibit expires + for (int cnt = 0; cnt < 8; cnt++) { + timers.step_all(); + } + TESTASSERT_EQ(3, rlc2.get_buffer_state()); // t-StatusProhibit no longer running + + { + // Double check status report + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, 3); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(0, status_check.nacks.size()); // All PDUs are acked now + } + + { + // rlc2 should not issue further status PDUs as time passes (even after expiry of t_status_prohibit) + int32_t checktime = 2 * rlc2_config.am_nr.t_status_prohibit; + for (int cnt = 0; cnt < checktime; cnt++) { + timers.step_all(); + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + } + } + + // Check statistics + rlc_bearer_metrics_t metrics1 = rlc1.get_metrics(); + rlc_bearer_metrics_t metrics2 = rlc2.get_metrics(); + + uint32_t total_tx_pdu_bytes1 = (NBUFS + 1) * data_pdu_size; // (NBUFS + 1 RETX) * PDU size + uint32_t total_rx_pdu_bytes1 = 2 * status_pdu_ack_size + status_pdu_nack_size; // Two status PDU (one with a NACK) + uint32_t total_tx_pdu_bytes2 = + 3 * status_pdu_ack_size + status_pdu_nack_size; // Three status PDU (one with a NACK, two without) + uint32_t total_rx_pdu_bytes2 = (NBUFS)*data_pdu_size; // (NBUFS - 1 Lost + 1 RETX) * PDU size + + // SDU metrics + TESTASSERT_EQ(5, metrics1.num_tx_sdus); + TESTASSERT_EQ(0, metrics1.num_rx_sdus); + TESTASSERT_EQ(5, metrics1.num_tx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_lost_sdus); + // PDU metrics + TESTASSERT_EQ(5 + 1, metrics1.num_tx_pdus); // One re-transmission + TESTASSERT_EQ(2, metrics1.num_rx_pdus); // One status PDU + TESTASSERT_EQ(total_tx_pdu_bytes1, metrics1.num_tx_pdu_bytes); // (NBUFS + 1 RETX) * PDU size + TESTASSERT_EQ(total_rx_pdu_bytes1, metrics1.num_rx_pdu_bytes); // Two status PDU (one with a NACK) + TESTASSERT_EQ(0, metrics1.num_lost_sdus); // No lost SDUs + + // PDU metrics + TESTASSERT_EQ(0, metrics2.num_tx_sdus); + TESTASSERT_EQ(5, metrics2.num_rx_sdus); + TESTASSERT_EQ(0, metrics2.num_tx_sdu_bytes); + TESTASSERT_EQ(5, metrics2.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics2.num_lost_sdus); + // SDU metrics + TESTASSERT_EQ(3, metrics2.num_tx_pdus); // Three status PDUs + TESTASSERT_EQ(5, metrics2.num_rx_pdus); // 5 PDUs (6 tx'ed, but one was lost) + TESTASSERT_EQ(total_tx_pdu_bytes2, metrics2.num_tx_pdu_bytes); // Three status PDU (one with a NACK, two without) + TESTASSERT_EQ(total_rx_pdu_bytes2, metrics2.num_rx_pdu_bytes); // (NBUFS - 1 Lost + 1 RETX) * PDU size + TESTASSERT_EQ(0, metrics2.num_lost_sdus); // No lost SDUs + return SRSRAN_SUCCESS; +} + +/* + * Test the loss of a single PDU with NACK duplicate + * NACK should be visible in the status report. + * + * Retx after NACK should be present too. + * No further status reports shall be issued. + */ +int lost_pdu_duplicated_nack_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + test_delimit_logger delimiter("lost PDU with NACK duplicate ({} bit SN)", to_number(sn_size)); + + constexpr uint32_t payload_size = 1; + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + uint32_t data_pdu_size = header_size + payload_size; + uint32_t expect_buffer_state = NBUFS * data_pdu_size; + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + rlc_config_t rlc2_config = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + if (not rlc2.configure(rlc2_config)) { + return -1; + } + + // after configuring entity + TESTASSERT(0 == rlc1.get_buffer_state()); + + basic_test_tx(&rlc1, pdu_bufs, sn_size); + + // Write 5 PDUs into RLC2 + for (int i = 0; i < NBUFS; i++) { + if (i != 3) { + rlc2.write_pdu(pdu_bufs[i].msg, pdu_bufs[i].N_bytes); // Don't write RLC_SN=3. + } + } + + // Only after t-reassembly has expired, will the status report include NACKs. + TESTASSERT_EQ(3, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, 5); + status_buf.N_bytes = len; + + TESTASSERT(0 == rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(3, status_check.ack_sn); // 3 is the next expected SN (i.e. the lost packet.) + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Write duplicated status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check there is nothing pending in RLC1 + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + } + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // t-reassembly has expired. There should be a NACK in the status report. + constexpr uint32_t status_pdu_ack_size = 3; + uint32_t status_pdu_nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + TESTASSERT_EQ(status_pdu_ack_size + status_pdu_nack_size, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + uint32_t len = rlc2.read_pdu(status_buf.msg, status_pdu_ack_size + status_pdu_nack_size); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. + TESTASSERT_EQ(3, status_check.nacks[0].nack_sn); // Lost PDU SN=3. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Write duplicated status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check there is only one Retx of SN=3 + TESTASSERT_EQ(data_pdu_size, rlc1.get_buffer_state()); + } + + { + // Check correct re-transmission + byte_buffer_t retx_buf; + uint32_t len = rlc1.read_pdu(retx_buf.msg, data_pdu_size); + retx_buf.N_bytes = len; + TESTASSERT_EQ(data_pdu_size, len); + + rlc2.write_pdu(retx_buf.msg, retx_buf.N_bytes); + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Status report shoud be required, as the TX buffers are now empty. + } + + // Step timers until t-StatusProhibit expires + for (int cnt = 0; cnt < 8; cnt++) { + timers.step_all(); + } + TESTASSERT_EQ(3, rlc2.get_buffer_state()); // t-StatusProhibit no longer running + + { + // Double check status report + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, 3); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(0, status_check.nacks.size()); // All PDUs are acked now + } + + { + // rlc2 should not issue further status PDUs as time passes (even after expiry of t_status_prohibit) + int32_t checktime = 2 * rlc2_config.am_nr.t_status_prohibit; + for (int cnt = 0; cnt < checktime; cnt++) { + timers.step_all(); + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + } + } + + // Check statistics + rlc_bearer_metrics_t metrics1 = rlc1.get_metrics(); + rlc_bearer_metrics_t metrics2 = rlc2.get_metrics(); + + uint32_t total_tx_pdu_bytes1 = (NBUFS + 1) * data_pdu_size; // (NBUFS + 1 RETX) * PDU size + uint32_t total_rx_pdu_bytes1 = 4 * status_pdu_ack_size + 2 * status_pdu_nack_size; // 4 status PDU (2 with a NACK) + uint32_t total_tx_pdu_bytes2 = + 3 * status_pdu_ack_size + status_pdu_nack_size; // Three status PDU (one with a NACK, two without) + uint32_t total_rx_pdu_bytes2 = (NBUFS)*data_pdu_size; // (NBUFS - 1 Lost + 1 RETX) * PDU size + + // SDU metrics + TESTASSERT_EQ(5, metrics1.num_tx_sdus); + TESTASSERT_EQ(0, metrics1.num_rx_sdus); + TESTASSERT_EQ(5, metrics1.num_tx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_lost_sdus); + // PDU metrics + TESTASSERT_EQ(5 + 1, metrics1.num_tx_pdus); // One re-transmission + TESTASSERT_EQ(4, metrics1.num_rx_pdus); // 4 status PDUs + TESTASSERT_EQ(total_tx_pdu_bytes1, metrics1.num_tx_pdu_bytes); // (NBUFS + 1 RETX) * PDU size + TESTASSERT_EQ(total_rx_pdu_bytes1, metrics1.num_rx_pdu_bytes); // Two status PDU (one with a NACK) + TESTASSERT_EQ(0, metrics1.num_lost_sdus); // No lost SDUs + + // PDU metrics + TESTASSERT_EQ(0, metrics2.num_tx_sdus); + TESTASSERT_EQ(5, metrics2.num_rx_sdus); + TESTASSERT_EQ(0, metrics2.num_tx_sdu_bytes); + TESTASSERT_EQ(5, metrics2.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics2.num_lost_sdus); + // SDU metrics + TESTASSERT_EQ(3, metrics2.num_tx_pdus); // Three status PDUs + TESTASSERT_EQ(5, metrics2.num_rx_pdus); // 5 PDUs (6 tx'ed, but one was lost) + TESTASSERT_EQ(total_tx_pdu_bytes2, metrics2.num_tx_pdu_bytes); // Three status PDU (one with a NACK, two without) + TESTASSERT_EQ(total_rx_pdu_bytes2, metrics2.num_rx_pdu_bytes); // (NBUFS - 1 Lost + 1 RETX) * PDU size + TESTASSERT_EQ(0, metrics2.num_lost_sdus); // No lost SDUs + return SRSRAN_SUCCESS; +} + +/* + * Test the loss of multiple PDUs. + * NACKs for all missing PDUs should be visible in buffer state -- but we enforce + * a trimmed status PDU by providing little space for the whole status PDU. + * Retx after NACK should be present too. + * Further status report shall contain the trimmed NACK. + * Another Retx after NACK should be present. + * No further status reports shall be issued. + */ +int lost_pdus_trimmed_nack_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + test_delimit_logger delimiter("lost PDUs and trimmed NACKs ({} bit SN)", to_number(sn_size)); + + constexpr uint32_t payload_size = 1; + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + uint32_t data_pdu_size = header_size + payload_size; + uint32_t expect_buffer_state = NBUFS * data_pdu_size; + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + rlc_config_t rlc2_config = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + if (not rlc2.configure(rlc2_config)) { + return -1; + } + + // after configuring entity + TESTASSERT(0 == rlc1.get_buffer_state()); + + basic_test_tx(&rlc1, pdu_bufs, sn_size); + + // Write 5 PDUs into RLC2 + for (int i = 0; i < NBUFS; i++) { + if (i != 1 && i != 3) { + rlc2.write_pdu(pdu_bufs[i].msg, pdu_bufs[i].N_bytes); // Don't write RLC_SN=1 and 3. + } + } + + // Only after t-reassembly has expired, will the status report include NACKs. + TESTASSERT_EQ(3, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, 5); + status_buf.N_bytes = len; + + TESTASSERT(0 == rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(1, status_check.ack_sn); // 1 is the next expected SN (i.e. the first lost packet.) + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + } + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // t-reassembly has expired. There should be two NACKs in the status report. + constexpr uint32_t status_pdu_ack_size = 3; + uint32_t status_pdu_nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + uint32_t expected_size = status_pdu_ack_size + 2 * status_pdu_nack_size; + TESTASSERT_EQ(expected_size, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2, enforce to trimming by providing little space (expected_size - 1) + // to drop the second NACK. + byte_buffer_t status_buf; + uint32_t len = rlc2.read_pdu(status_buf.msg, expected_size - 1); + status_buf.N_bytes = len; + expected_size = status_pdu_ack_size + 1 * status_pdu_nack_size; // only one NACK left + TESTASSERT_EQ(len, expected_size); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(3, status_check.ack_sn); // 3 is the next expected SN (after trimming) + TESTASSERT_EQ(1, status_check.nacks.size()); // Expect only one NACK left + TESTASSERT_EQ(1, status_check.nacks[0].nack_sn); // The NACK'ed SN is 1. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check there is an Retx of SN=1 + TESTASSERT_EQ(data_pdu_size, rlc1.get_buffer_state()); + } + + { + // Check correct re-transmission + byte_buffer_t retx_buf; + uint32_t len = rlc1.read_pdu(retx_buf.msg, data_pdu_size); + retx_buf.N_bytes = len; + TESTASSERT_EQ(data_pdu_size, len); + + rlc2.write_pdu(retx_buf.msg, retx_buf.N_bytes); + + expected_size = status_pdu_ack_size + 1 * status_pdu_nack_size; + TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Status report should now include the chopped NACK + } + + // Step timers until t-StatusProhibit expires + for (int cnt = 0; cnt < 8; cnt++) { + timers.step_all(); + } + TESTASSERT_EQ(expected_size, rlc2.get_buffer_state()); // t-StatusProhibit no longer running + + { + // Double check status report + byte_buffer_t status_buf; + uint32_t len = rlc2.read_pdu(status_buf.msg, expected_size); + status_buf.N_bytes = len; + expected_size = status_pdu_ack_size + 1 * status_pdu_nack_size; // the remaining NACK + TESTASSERT_EQ(len, expected_size); + + // Nothing else pending + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(1, status_check.nacks.size()); // Expect only the second NACK + TESTASSERT_EQ(3, status_check.nacks[0].nack_sn); // The NACK'ed SN is 3. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check there is an Retx of SN=3 + TESTASSERT_EQ(data_pdu_size, rlc1.get_buffer_state()); + } + { + // Check correct re-transmission + byte_buffer_t retx_buf; + uint32_t len = rlc1.read_pdu(retx_buf.msg, data_pdu_size); + retx_buf.N_bytes = len; + TESTASSERT_EQ(data_pdu_size, len); + + rlc2.write_pdu(retx_buf.msg, retx_buf.N_bytes); + + expected_size = status_pdu_ack_size; + TESTASSERT_EQ(0, rlc2.get_buffer_state()); // Status report should have no NACKs + } + // Step timers until t-StatusProhibit expires + for (int cnt = 0; cnt < 8; cnt++) { + timers.step_all(); + } + TESTASSERT_EQ(expected_size, rlc2.get_buffer_state()); // t-StatusProhibit no longer running + { + // Double check status report + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, expected_size); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(0, status_check.nacks.size()); // All PDUs are acked now + } + + { + // rlc2 should not issue further status PDUs as time passes (even after expiry of t_status_prohibit) + int32_t checktime = 2 * rlc2_config.am_nr.t_status_prohibit; + for (int cnt = 0; cnt < checktime; cnt++) { + timers.step_all(); + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + } + } + + // Check statistics + rlc_bearer_metrics_t metrics1 = rlc1.get_metrics(); + rlc_bearer_metrics_t metrics2 = rlc2.get_metrics(); + + uint32_t total_tx_pdu_bytes1 = (NBUFS + 2) * data_pdu_size; // (NBUFS + 2 RETX) * PDU size + uint32_t total_rx_pdu_bytes1 = 3 * status_pdu_ack_size + 2 * status_pdu_nack_size; // 3 status PDUs (2 with one NACK) + uint32_t total_tx_pdu_bytes2 = + 4 * status_pdu_ack_size + 2 * status_pdu_nack_size; // 4 status PDUs (2 with one NACK, two without) + uint32_t total_rx_pdu_bytes2 = (NBUFS)*data_pdu_size; // (NBUFS - 2 Lost + 2 RETX) * PDU size + + // SDU metrics + TESTASSERT_EQ(5, metrics1.num_tx_sdus); + TESTASSERT_EQ(0, metrics1.num_rx_sdus); + TESTASSERT_EQ(5, metrics1.num_tx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_lost_sdus); + // PDU metrics + TESTASSERT_EQ(5 + 2, metrics1.num_tx_pdus); // One re-transmission + TESTASSERT_EQ(3, metrics1.num_rx_pdus); // 3 status PDUs + TESTASSERT_EQ(total_tx_pdu_bytes1, metrics1.num_tx_pdu_bytes); // (NBUFS + 2 RETX) * PDU size + TESTASSERT_EQ(total_rx_pdu_bytes1, metrics1.num_rx_pdu_bytes); // Two status PDU (one with a NACK) + TESTASSERT_EQ(0, metrics1.num_lost_sdus); // No lost SDUs + + // PDU metrics + TESTASSERT_EQ(0, metrics2.num_tx_sdus); + TESTASSERT_EQ(5, metrics2.num_rx_sdus); + TESTASSERT_EQ(0, metrics2.num_tx_sdu_bytes); + TESTASSERT_EQ(5, metrics2.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics2.num_lost_sdus); + // SDU metrics + TESTASSERT_EQ(4, metrics2.num_tx_pdus); // 4 status PDUs + TESTASSERT_EQ(5, metrics2.num_rx_pdus); // 5 PDUs (7 tx'ed, but 2 were lost) + TESTASSERT_EQ(total_tx_pdu_bytes2, metrics2.num_tx_pdu_bytes); // Three status PDU (one with a NACK, two without) + TESTASSERT_EQ(total_rx_pdu_bytes2, metrics2.num_rx_pdu_bytes); // (NBUFS - 2 Lost + 2 RETX) * PDU size + TESTASSERT_EQ(0, metrics2.num_lost_sdus); // No lost SDUs + return SRSRAN_SUCCESS; +} + +/* + * Test if retx queue is cleared of SDUs that are ACK'ed by a late/delayed ACK. + */ +int clean_retx_queue_of_acked_sdus_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + test_delimit_logger delimiter("Clean retx_queue of SDUs that are ACK'ed by a late/delayed ACK ({} bit SN)", + to_number(sn_size)); + + constexpr uint32_t payload_size = 1; + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + uint32_t data_pdu_size = header_size + payload_size; + uint32_t expect_buffer_state = NBUFS * data_pdu_size; + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + rlc_config_t rlc2_config = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + if (not rlc2.configure(rlc2_config)) { + return -1; + } + + rlc_am_nr_tx* rlc1_tx = dynamic_cast(rlc1.get_tx()); + + // after configuring entity + TESTASSERT(0 == rlc1.get_buffer_state()); + + basic_test_tx(&rlc1, pdu_bufs, sn_size); + + // Write 5 PDUs into RLC2 + for (int i = 0; i < NBUFS; i++) { + if (i != 3) { + rlc2.write_pdu(pdu_bufs[i].msg, pdu_bufs[i].N_bytes); // Don't write RLC_SN=3. + } + } + + // Only after t-reassembly has expired, will the status report include NACKs. + TESTASSERT_EQ(3, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, 5); + status_buf.N_bytes = len; + + TESTASSERT(0 == rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(3, status_check.ack_sn); // 3 is the next expected SN (i.e. the lost packet.) + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check there is nothing pending in RLC1 + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + } + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // t-reassembly has expired. There should be a NACK in the status report. + constexpr uint32_t status_pdu_ack_size = 3; + uint32_t status_pdu_nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + TESTASSERT_EQ(status_pdu_ack_size + status_pdu_nack_size, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + uint32_t len = rlc2.read_pdu(status_buf.msg, status_pdu_ack_size + status_pdu_nack_size); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. + TESTASSERT_EQ(3, status_check.nacks[0].nack_sn); // Lost PDU SN=3. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check there is only one Retx of SN=3 + TESTASSERT_EQ(data_pdu_size, rlc1.get_buffer_state()); + } + + // now we deliver the late PDU SN=3 to rlc2 + rlc2.write_pdu(pdu_bufs[3].msg, pdu_bufs[3].N_bytes); + + // Check there is only one Retx of SN=3 + TESTASSERT_EQ(data_pdu_size, rlc1.get_buffer_state()); + TESTASSERT_EQ(1, rlc1_tx->get_retx_queue_size()); + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // t-reassembly has expired. There should be an ACK in the status report. + TESTASSERT_EQ(status_pdu_ack_size, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + uint32_t len = rlc2.read_pdu(status_buf.msg, status_pdu_ack_size); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(0, status_check.nacks.size()); // Nothing else lost + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check the Retx of SN=3 has been removed + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + TESTASSERT_EQ(0, rlc1_tx->get_retx_queue_size()); + } + + { + // Attempt to read from rlc1 to verify there nothing to read from it + byte_buffer_t retx_buf; + uint32_t len = rlc1.read_pdu(retx_buf.msg, data_pdu_size); + retx_buf.N_bytes = len; + TESTASSERT_EQ(0, len); + } + + { + // rlc2 should not issue further status PDUs as time passes (even after expiry of t_status_prohibit) + int32_t checktime = 2 * rlc2_config.am_nr.t_status_prohibit; + for (int cnt = 0; cnt < checktime; cnt++) { + timers.step_all(); + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + } + } + + // Check statistics + rlc_bearer_metrics_t metrics1 = rlc1.get_metrics(); + rlc_bearer_metrics_t metrics2 = rlc2.get_metrics(); + + uint32_t total_tx_pdu_bytes1 = (NBUFS)*data_pdu_size; // (NBUFS) * PDU size + uint32_t total_rx_pdu_bytes1 = 3 * status_pdu_ack_size + 1 * status_pdu_nack_size; // 3 status PDU (1 with a NACK) + uint32_t total_tx_pdu_bytes2 = + 3 * status_pdu_ack_size + status_pdu_nack_size; // Three status PDU (one with a NACK, two without) + uint32_t total_rx_pdu_bytes2 = (NBUFS)*data_pdu_size; // (NBUFS - 1 Lost + 1 Late) * PDU size + + // SDU metrics + TESTASSERT_EQ(5, metrics1.num_tx_sdus); + TESTASSERT_EQ(0, metrics1.num_rx_sdus); + TESTASSERT_EQ(5, metrics1.num_tx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_lost_sdus); + // PDU metrics + TESTASSERT_EQ(5, metrics1.num_tx_pdus); // 5 transmissions, no re-transmission + TESTASSERT_EQ(3, metrics1.num_rx_pdus); // 3 status PDUs + TESTASSERT_EQ(total_tx_pdu_bytes1, metrics1.num_tx_pdu_bytes); // (NBUFS) * PDU size + TESTASSERT_EQ(total_rx_pdu_bytes1, metrics1.num_rx_pdu_bytes); // 3 status PDU (1 with a NACK) + TESTASSERT_EQ(0, metrics1.num_lost_sdus); // No lost SDUs + + // SDU metrics + TESTASSERT_EQ(0, metrics2.num_tx_sdus); + TESTASSERT_EQ(5, metrics2.num_rx_sdus); + TESTASSERT_EQ(0, metrics2.num_tx_sdu_bytes); + TESTASSERT_EQ(5, metrics2.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics2.num_lost_sdus); + // PDU metrics + TESTASSERT_EQ(3, metrics2.num_tx_pdus); // 3 status PDUs + TESTASSERT_EQ(5, metrics2.num_rx_pdus); // 5 transmissions, no re-transmission + TESTASSERT_EQ(total_tx_pdu_bytes2, metrics2.num_tx_pdu_bytes); // Three status PDU (one with a NACK, two without) + TESTASSERT_EQ(total_rx_pdu_bytes2, metrics2.num_rx_pdu_bytes); // (NBUFS - 1 Lost + 1 Late) * PDU size + TESTASSERT_EQ(0, metrics2.num_lost_sdus); // No lost SDUs + return SRSRAN_SUCCESS; +} + +/* + * Test the basic segmentation of a single SDU. + * A single SDU of 3 bytes is segmented into 3 PDUs + */ +int basic_segmentation_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("basic segmentation ({} bit SN)", to_number(sn_size)); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + if (not rlc2.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + // after configuring entity + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + + // Push 1 SDU into RLC1 + unique_byte_buffer_t sdu; + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + sdu = srsran::make_byte_buffer(); + TESTASSERT(nullptr != sdu); + sdu->msg[0] = 0; // Write the index into the buffer + sdu->N_bytes = payload_size; // Give the SDU the size of 3 bytes + sdu->md.pdcp_sn = 0; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu)); + + // Read 3 PDUs + constexpr uint16_t n_pdus = 3; + unique_byte_buffer_t pdu_bufs[n_pdus]; + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + constexpr uint32_t so_size = 2; + constexpr uint32_t segment_size = 1; + uint32_t pdu_size_first = header_size + segment_size; + uint32_t pdu_size_continued = header_size + so_size + segment_size; + for (int i = 0; i < n_pdus; i++) { + pdu_bufs[i] = srsran::make_byte_buffer(); + TESTASSERT(nullptr != pdu_bufs[i]); + if (i == 0) { + pdu_bufs[i]->N_bytes = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_first); + TESTASSERT_EQ(pdu_size_first, pdu_bufs[i]->N_bytes); + } else { + pdu_bufs[i]->N_bytes = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_continued); + TESTASSERT_EQ(pdu_size_continued, pdu_bufs[i]->N_bytes); + } + } + + // Write 3 PDUs into RLC2 + for (int i = 0; i < n_pdus; i++) { + rlc2.write_pdu(pdu_bufs[i]->msg, pdu_bufs[i]->N_bytes); + } + + // Check statistics + rlc_bearer_metrics_t metrics1 = rlc1.get_metrics(); + rlc_bearer_metrics_t metrics2 = rlc2.get_metrics(); + + uint32_t total_rx_pdu_bytes = pdu_size_first + (n_pdus - 1) * pdu_size_continued; // 1 PDU (No SO) + 2 PDUs (with SO) + + // SDU metrics + TESTASSERT_EQ(0, metrics2.num_tx_sdus); + TESTASSERT_EQ(1, metrics2.num_rx_sdus); + TESTASSERT_EQ(0, metrics2.num_tx_sdu_bytes); + TESTASSERT_EQ(payload_size, metrics2.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics2.num_lost_sdus); + // PDU metrics + TESTASSERT_EQ(0, metrics2.num_tx_pdus); + TESTASSERT_EQ(n_pdus, metrics2.num_rx_pdus); // 3 PDUs + TESTASSERT_EQ(0, metrics2.num_tx_pdu_bytes); + TESTASSERT_EQ(total_rx_pdu_bytes, metrics2.num_rx_pdu_bytes); // 1 PDU (No SO) + 2 PDUs (with SO) + TESTASSERT_EQ(0, metrics2.num_lost_sdus); // No lost SDUs + + // Check state + rlc_am_nr_tx_state_t state1_tx = tx1->get_tx_state(); + TESTASSERT_EQ(1, state1_tx.tx_next); + + return SRSRAN_SUCCESS; +} + +// This tests correct behaviour of the following flow: +// - Transmit 5 SDUs as whole PDUs +// - Loose 3rd PDU +// - Receive NACK for missing PDU +// - Retransmit lost PDU in 3 segments +// - Check metrics and state +int segment_retx_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + test_delimit_logger delimiter("segment retx PDU ({} bit SN)", to_number(sn_size)); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + auto rlc_cnfg = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + rlc_cnfg.am_nr.t_poll_retx = -1; + if (not rlc1.configure(rlc_cnfg)) { + return -1; + } + + if (not rlc2.configure(rlc_cnfg)) { + return -1; + } + + // after configuring entity + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + + // Push 5 SDUs into RLC1 + unique_byte_buffer_t sdu_bufs[NBUFS]; + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (int i = 0; i < NBUFS; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = payload_size; // Give each buffer a size of 3 bytes + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_bufs[i])); + } + + uint32_t expected_buffer_state = (header_size + payload_size) * NBUFS; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + // Read 5 PDUs from RLC1 (1 byte each) + for (int i = 0; i < NBUFS; i++) { + uint32_t len = rlc1.read_pdu(pdu_bufs[i].msg, header_size + payload_size); + pdu_bufs[i].N_bytes = len; + TESTASSERT_EQ(header_size + payload_size, len); + } + + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + + // Write 5 PDUs into RLC2 + for (int i = 0; i < NBUFS; i++) { + if (i != 3) { + rlc2.write_pdu(pdu_bufs[i].msg, pdu_bufs[i].N_bytes); // Don't write RLC_SN=3. + } + } + + // Only after t-reassembly has expired, will the status report include NACKs. + TESTASSERT_EQ(3, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, 5); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(3, status_check.ack_sn); // 3 is the next expected SN (i.e. the lost packet.) + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + } + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // t-reassembly has expired. There should be a NACK in the status report. + constexpr uint32_t status_pdu_ack_size = 3; + uint32_t status_pdu_nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + TESTASSERT_EQ(status_pdu_ack_size + status_pdu_nack_size, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, status_pdu_ack_size + status_pdu_nack_size); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. + TESTASSERT_EQ(3, status_check.nacks[0].nack_sn); // Lost PDU SN=3. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check there is an Retx of SN=3 + TESTASSERT_EQ(header_size + payload_size, rlc1.get_buffer_state()); + } + + constexpr uint32_t so_size = 2; + constexpr uint32_t segment_size = 1; + uint32_t pdu_size_first = header_size + segment_size; + uint32_t pdu_size_continued = header_size + so_size + segment_size; + { + // Re-transmit PDU in 3 segments + for (int i = 0; i < 3; i++) { + byte_buffer_t retx_buf; + uint32_t len = 0; + if (i == 0) { + len = rlc1.read_pdu(retx_buf.msg, pdu_size_first); + TESTASSERT_EQ(pdu_size_first, len); + } else { + len = rlc1.read_pdu(retx_buf.msg, pdu_size_continued); + TESTASSERT_EQ(pdu_size_continued, len); + } + retx_buf.N_bytes = len; + + rlc_am_nr_pdu_header_t header_check = {}; + uint32_t hdr_len = rlc_am_nr_read_data_pdu_header(&retx_buf, sn_size, &header_check); + // Double check header. + TESTASSERT_EQ(3, header_check.sn); // Double check RETX SN + if (i == 0) { + TESTASSERT_EQ(rlc_nr_si_field_t::first_segment, header_check.si); + } else if (i == 1) { + TESTASSERT_EQ(rlc_nr_si_field_t::neither_first_nor_last_segment, header_check.si); + } else { + TESTASSERT_EQ(rlc_nr_si_field_t::last_segment, header_check.si); + } + + rlc2.write_pdu(retx_buf.msg, retx_buf.N_bytes); + } + TESTASSERT(0 == rlc1.get_buffer_state()); + } + + // Check statistics + rlc_bearer_metrics_t metrics1 = rlc1.get_metrics(); + rlc_bearer_metrics_t metrics2 = rlc2.get_metrics(); + + uint32_t data_pdu_size = header_size + payload_size; + uint32_t total_tx_pdu_bytes1 = NBUFS * data_pdu_size + pdu_size_first + 2 * pdu_size_continued; + uint32_t total_rx_pdu_bytes1 = 2 * status_pdu_ack_size + status_pdu_nack_size; // Two status PDU (one with a NACK) + uint32_t total_tx_pdu_bytes2 = total_rx_pdu_bytes1; + uint32_t total_rx_pdu_bytes2 = (NBUFS - 1) * data_pdu_size + pdu_size_first + 2 * pdu_size_continued; + + // SDU metrics + TESTASSERT_EQ(5, metrics1.num_tx_sdus); + TESTASSERT_EQ(0, metrics1.num_rx_sdus); + TESTASSERT_EQ(15, metrics1.num_tx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_lost_sdus); + // PDU metrics + TESTASSERT_EQ(5 + 3, metrics1.num_tx_pdus); // 3 re-transmissions + TESTASSERT_EQ(2, metrics1.num_rx_pdus); // Two status PDU + TESTASSERT_EQ(total_tx_pdu_bytes1, metrics1.num_tx_pdu_bytes); + TESTASSERT_EQ(total_rx_pdu_bytes1, metrics1.num_rx_pdu_bytes); + TESTASSERT_EQ(0, metrics1.num_lost_sdus); // No lost SDUs + + // PDU metrics + TESTASSERT_EQ(0, metrics2.num_tx_sdus); + TESTASSERT_EQ(5, metrics2.num_rx_sdus); + TESTASSERT_EQ(0, metrics2.num_tx_sdu_bytes); + TESTASSERT_EQ(15, metrics2.num_rx_sdu_bytes); // 5 SDUs, 3 bytes each + TESTASSERT_EQ(0, metrics2.num_lost_sdus); + // SDU metrics + TESTASSERT_EQ(2, metrics2.num_tx_pdus); // Two status PDUs + TESTASSERT_EQ(7, metrics2.num_rx_pdus); // 7 PDUs (8 tx'ed, but one was lost) + TESTASSERT_EQ(total_tx_pdu_bytes2, metrics2.num_tx_pdu_bytes); + TESTASSERT_EQ(total_rx_pdu_bytes2, + metrics2.num_rx_pdu_bytes); // 2 Bytes * (NBUFFS-1) (header size) + (NBUFFS-1) * 3 (data) + // 3 (1 retx no SO) + 2 * 5 (2 retx with SO) = 33 + TESTASSERT_EQ(0, metrics2.num_lost_sdus); // No lost SDUs + + // Check state + rlc_am_nr_rx_state_t state2_rx = rx2->get_rx_state(); + TESTASSERT_EQ(5, state2_rx.rx_next); + return SRSRAN_SUCCESS; +} + +// This tests correct behaviour of the following flow: +// - Transmit 5 SDUs as whole PDUs +// - Loose 3rd PDU +// - Receive NACK for missing PDU +// - Retransmit lost PDU in 3 segments +// - Loose first and last segment +// - Receive NACKs for missing segments +// - Receive duplicate of previous NACKs +// - Retransmit missing segments again, but only once! +// - Check metrics and state +int segment_retx_and_loose_segments_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + test_delimit_logger delimiter("segment retx PDU and loose some segments ({} bit SN)", to_number(sn_size)); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + if (not rlc2.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + // after configuring entity + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + + // Push 5 SDUs into RLC1 + unique_byte_buffer_t sdu_bufs[NBUFS]; + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (int i = 0; i < NBUFS; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = payload_size; // Give each buffer a size of 3 bytes + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_bufs[i])); + } + + uint32_t expected_buffer_state = (header_size + payload_size) * NBUFS; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + // Read 5 PDUs from RLC1 (each with a full SDU) + for (int i = 0; i < NBUFS; i++) { + uint32_t len = rlc1.read_pdu(pdu_bufs[i].msg, header_size + payload_size); + pdu_bufs[i].N_bytes = len; + TESTASSERT_EQ(header_size + payload_size, len); + } + + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + + // Write 5 - 1 PDUs into RLC2 + for (int i = 0; i < NBUFS; i++) { + if (i != 3) { + rlc2.write_pdu(pdu_bufs[i].msg, pdu_bufs[i].N_bytes); // Don't write RLC_SN=3. + } + } + + // Only after t-reassembly has expired, will the status report include NACKs. + TESTASSERT_EQ(3, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, 5); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(3, status_check.ack_sn); // 3 is the next expected SN (i.e. the lost packet.) + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + } + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // t-reassembly has expired. There should be a NACK in the status report. + constexpr uint32_t status_pdu_ack_size = 3; + uint32_t status_pdu_nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + TESTASSERT_EQ(status_pdu_ack_size + status_pdu_nack_size, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, status_pdu_ack_size + status_pdu_nack_size); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. + TESTASSERT_EQ(3, status_check.nacks[0].nack_sn); // Lost PDU SN=3. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check there is an Retx of SN=3 + TESTASSERT_EQ(header_size + payload_size, rlc1.get_buffer_state()); + } + + constexpr uint32_t so_size = 2; + constexpr uint32_t segment_size = 1; + uint32_t pdu_size_first = header_size + segment_size; + uint32_t pdu_size_continued = header_size + so_size + segment_size; + { + // Re-transmit PDU in 3 segments + for (int i = 0; i < 3; i++) { + byte_buffer_t retx_buf; + uint32_t len = 0; + if (i == 0) { + len = rlc1.read_pdu(retx_buf.msg, pdu_size_first); + TESTASSERT_EQ(pdu_size_first, len); + } else { + len = rlc1.read_pdu(retx_buf.msg, pdu_size_continued); + TESTASSERT_EQ(pdu_size_continued, len); + } + retx_buf.N_bytes = len; + + rlc_am_nr_pdu_header_t header_check = {}; + uint32_t hdr_len = rlc_am_nr_read_data_pdu_header(&retx_buf, sn_size, &header_check); + // Double check header. + TESTASSERT_EQ(3, header_check.sn); // Double check RETX SN + if (i == 0) { + TESTASSERT_EQ(rlc_nr_si_field_t::first_segment, header_check.si); + } else if (i == 1) { + TESTASSERT_EQ(rlc_nr_si_field_t::neither_first_nor_last_segment, header_check.si); + } else { + TESTASSERT_EQ(rlc_nr_si_field_t::last_segment, header_check.si); + } + + // We loose the first and the last segment + if (i != 0 && i != 2) { + rlc2.write_pdu(retx_buf.msg, retx_buf.N_bytes); + } + } + TESTASSERT(0 == rlc1.get_buffer_state()); + } + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // t-reassembly has expired. There should be another NACK in the status report. + constexpr uint32_t status_pdu_so_size = 4; + TESTASSERT_EQ(status_pdu_ack_size + 2 * status_pdu_nack_size + 2 * status_pdu_so_size, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, status_pdu_ack_size + 2 * status_pdu_nack_size + 2 * status_pdu_so_size); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(2, status_check.nacks.size()); // We lost two PDU segments. + TESTASSERT_EQ(3, status_check.nacks[0].nack_sn); // Lost PDU SN=3. + TESTASSERT_EQ(true, status_check.nacks[0].has_so); // This is a segment missing. + TESTASSERT_EQ(0, status_check.nacks[0].so_start); // Segment offset should be 0 here + TESTASSERT_EQ(0, status_check.nacks[0].so_end); // Segment end should be 0 here + TESTASSERT_EQ(true, status_check.nacks[1].has_so); // This is a segment missing. + TESTASSERT_EQ(2, status_check.nacks[1].so_start); // Segment offset should be 2 here + TESTASSERT_EQ(0xFFFF, status_check.nacks[1].so_end); // Segment end should be 0xFFFF here + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Write status PDU duplicate to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check there are two Retx segments (a first one and a continued one) + TESTASSERT_EQ(pdu_size_first + pdu_size_continued, rlc1.get_buffer_state()); + } + + { + // Re-transmit the lost 2 segments + for (int i = 0; i < 2; i++) { + byte_buffer_t retx_buf; + uint32_t len = 0; + if (i == 0) { + len = rlc1.read_pdu(retx_buf.msg, pdu_size_first); + TESTASSERT_EQ(pdu_size_first, len); + } else { + len = rlc1.read_pdu(retx_buf.msg, pdu_size_continued); + TESTASSERT_EQ(pdu_size_continued, len); + } + retx_buf.N_bytes = len; + + rlc_am_nr_pdu_header_t header_check = {}; + uint32_t hdr_len = rlc_am_nr_read_data_pdu_header(&retx_buf, sn_size, &header_check); + // Double check header. + TESTASSERT_EQ(3, header_check.sn); // Double check RETX SN + if (i == 0) { + TESTASSERT_EQ(rlc_nr_si_field_t::first_segment, header_check.si); + } else { + TESTASSERT_EQ(rlc_nr_si_field_t::last_segment, header_check.si); + } + + rlc2.write_pdu(retx_buf.msg, retx_buf.N_bytes); + } + TESTASSERT(0 == rlc1.get_buffer_state()); + } + + // Check statistics + rlc_bearer_metrics_t metrics1 = rlc1.get_metrics(); + rlc_bearer_metrics_t metrics2 = rlc2.get_metrics(); + + uint32_t data_pdu_size = header_size + payload_size; + uint32_t total_tx_pdu_bytes1 = NBUFS * data_pdu_size + 2 * pdu_size_first + 3 * pdu_size_continued; + uint32_t total_rx_pdu_bytes1 = status_pdu_ack_size + // ACK, no NACK + (status_pdu_ack_size + status_pdu_nack_size) + // ACK + NACK full SDU + 2 * (status_pdu_ack_size + 2 * status_pdu_nack_size + // 2 * (ACK + NACK two segments) + 2 * status_pdu_so_size); + uint32_t total_tx_pdu_bytes2 = status_pdu_ack_size + // ACK, no NACK + (status_pdu_ack_size + status_pdu_nack_size) + // ACK + NACK full SDU + 1 * (status_pdu_ack_size + 2 * status_pdu_nack_size + // 1 * (ACK + NACK two segments) + 2 * status_pdu_so_size); + uint32_t total_rx_pdu_bytes2 = (NBUFS - 1) * data_pdu_size + pdu_size_first + 2 * pdu_size_continued; + + // SDU metrics + TESTASSERT_EQ(5, metrics1.num_tx_sdus); + TESTASSERT_EQ(0, metrics1.num_rx_sdus); + TESTASSERT_EQ(15, metrics1.num_tx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_lost_sdus); + // PDU metrics + TESTASSERT_EQ(5 + 3 + 2, metrics1.num_tx_pdus); // 5 + (3 + 2) re-transmissions + TESTASSERT_EQ(4, metrics1.num_rx_pdus); // 4 status PDU + TESTASSERT_EQ(total_tx_pdu_bytes1, metrics1.num_tx_pdu_bytes); + TESTASSERT_EQ(total_rx_pdu_bytes1, metrics1.num_rx_pdu_bytes); + TESTASSERT_EQ(0, metrics1.num_lost_sdus); // No lost SDUs + + // PDU metrics + TESTASSERT_EQ(0, metrics2.num_tx_sdus); + TESTASSERT_EQ(5, metrics2.num_rx_sdus); + TESTASSERT_EQ(0, metrics2.num_tx_sdu_bytes); + TESTASSERT_EQ(15, metrics2.num_rx_sdu_bytes); // 5 SDUs, 3 bytes each + TESTASSERT_EQ(0, metrics2.num_lost_sdus); + // SDU metrics + TESTASSERT_EQ(3, metrics2.num_tx_pdus); // 3 status PDUs + TESTASSERT_EQ(7, metrics2.num_rx_pdus); // 7 PDUs (10 tx'ed, but 3 were lost) + TESTASSERT_EQ(total_tx_pdu_bytes2, metrics2.num_tx_pdu_bytes); + TESTASSERT_EQ(total_rx_pdu_bytes2, + metrics2.num_rx_pdu_bytes); // 2 Bytes * (NBUFFS-1) (header size) + (NBUFFS-1) * 3 (data) + // 3 (1 retx no SO) + 2 * 5 (2 retx with SO) = 33 + TESTASSERT_EQ(0, metrics2.num_lost_sdus); // No lost SDUs + + // Check state + rlc_am_nr_rx_state_t state2_rx = rx2->get_rx_state(); + TESTASSERT_EQ(5, state2_rx.rx_next); + return SRSRAN_SUCCESS; +} + +int retx_segment_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + std::string str = "retx segment PDU (" + std::to_string(to_number(sn_size)) + " bit SN)"; + test_delimit_logger delimiter(str.c_str()); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + auto rlc_cnfg = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + rlc_cnfg.am_nr.t_poll_retx = -1; + if (not rlc1.configure(rlc_cnfg)) { + return -1; + } + + if (not rlc2.configure(rlc_cnfg)) { + return -1; + } + + // after configuring entity + TESTASSERT(0 == rlc1.get_buffer_state()); + + int n_sdu_bufs = 5; + int n_pdu_bufs = 15; + + // Push 5 SDUs into RLC1 + std::vector sdu_bufs(n_sdu_bufs); + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (int i = 0; i < n_sdu_bufs; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = payload_size; // Give each buffer a size of 3 bytes + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_bufs[i])); + } + + uint32_t expected_buffer_state = (header_size + payload_size) * n_sdu_bufs; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + constexpr uint32_t so_size = 2; + constexpr uint32_t segment_size = 1; + uint32_t pdu_size_first = header_size + segment_size; + uint32_t pdu_size_continued = header_size + so_size + segment_size; + + // Read 15 PDUs from RLC1 + std::vector pdu_bufs(n_pdu_bufs); + for (int i = 0; i < n_pdu_bufs; i++) { + // First also test buffer state + uint32_t remaining_total_bytes = (payload_size * n_sdu_bufs) - (i * segment_size); + uint32_t remaining_full_sdus = remaining_total_bytes / payload_size; + uint32_t remaining_seg_bytes = remaining_total_bytes % payload_size; + + uint32_t buffer_state_full_sdus = (header_size + payload_size) * remaining_full_sdus; + uint32_t buffer_state_seg_sdu = remaining_seg_bytes == 0 ? 0 : (header_size + so_size + remaining_seg_bytes); + expected_buffer_state = buffer_state_full_sdus + buffer_state_seg_sdu; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + pdu_bufs[i] = srsran::make_byte_buffer(); + if (i == 0 || i == 3 || i == 6 || i == 9 || i == 12) { + // First segment, no SO + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_first); // 2 bytes for header + 1 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_first, len); + } else { + // Middle or last segment, SO present + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_continued); // 4 bytes for header + 1 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_continued, len); + } + } + + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + + // Write 15 - 3 PDUs into RLC2 + for (int i = 0; i < n_pdu_bufs; i++) { + if (i != 3 && i != 7 && i != 11) { + // Lose first segment of RLC_SN=1. + // Lose middle segment of RLC_SN=2. + // Lose last segment of RLC_SN=3. + rlc2.write_pdu(pdu_bufs[i]->msg, pdu_bufs[i]->N_bytes); + } + } + + { + // Double check rx state + rlc_am_nr_rx_state_t st = rx2->get_rx_state(); + TESTASSERT_EQ(1, st.rx_next); + TESTASSERT_EQ(1, st.rx_highest_status); + TESTASSERT_EQ(2, st.rx_next_status_trigger); // Rx_Next_Highest + 1, when the t-Reordering was started + TESTASSERT_EQ(5, st.rx_next_highest); // Highest SN received + 1 + } + + // Only after t-reassembly has expired, will the status report include NACKs. + // RX_Highest_Status will be updated to to the SN + // of the first RLC SDU with SN >= RX_Next_Status_Trigger + TESTASSERT_EQ(3, rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, 5); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(1, status_check.ack_sn); // 1 is the next expected SN (i.e. the first lost packet.) + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + } + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // After the t-Reassembly expires: + // - RX_Highest_Status is updated to the SN of the first RLC SDU with SN >= RX_Next_Status_Trigger, i.e., SN=2 + // - Because RX_Next_Highest> RX_Highest_Status +1: + // - t-Reassembly is restarted, and + // - RX_Next_Status_Trigger is set to RX_Next_Highest. + { + // Double check rx state + rlc_am_nr_rx_state_t st = rx2->get_rx_state(); + TESTASSERT_EQ(1, st.rx_next); + TESTASSERT_EQ(2, st.rx_highest_status); + TESTASSERT_EQ(5, st.rx_next_status_trigger); // Rx_Next_Highest + 1, when the t-Reassembly was started + TESTASSERT_EQ(5, st.rx_next_highest); // Highest SN received + 1 + } + + // t-reassembly has expired. Becuse RX_Highest_Status is 2 + // There should be an ACK of SN=2 and a NACK of SN=1 + constexpr uint32_t status_pdu_ack_size = 3; + uint32_t status_pdu_nack_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + constexpr uint32_t status_pdu_so_size = 4; + TESTASSERT_EQ(status_pdu_ack_size + status_pdu_nack_size + status_pdu_so_size, + rlc2.get_buffer_state()); // 3 bytes for fixed header (ACK+E1) + 6 for NACK with SO = 9. + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, status_pdu_ack_size + status_pdu_nack_size + status_pdu_so_size); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(2, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(1, status_check.nacks.size()); // We lost one PDU. + TESTASSERT_EQ(1, status_check.nacks[0].nack_sn); // Lost SDU on SN=1. + TESTASSERT_EQ(true, status_check.nacks[0].has_so); // It's a segment. + TESTASSERT_EQ(0, status_check.nacks[0].so_start); // First byte missing is 0. + TESTASSERT_EQ(0, status_check.nacks[0].so_end); // Last byte of the segment. + } + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // After the t-Reassembly expires: + // - RX_Highest_Status is updated to the SN of the first RLC SDU with SN >= RX_Next_Status_Trigger, i.e., SN=2 + // - Because RX_Next_Highest> RX_Highest_Status +1: + // - t-Reassembly is restarted, and + // - RX_Next_Status_Trigger is set to RX_Next_Highest. + { + // Double check rx state + rlc_am_nr_rx_state_t st = rx2->get_rx_state(); + TESTASSERT_EQ(1, st.rx_next); + TESTASSERT_EQ(5, st.rx_highest_status); + TESTASSERT_EQ(5, st.rx_next_status_trigger); // Rx_Next_Highest + 1, when the t-Reordering was started + TESTASSERT_EQ(5, st.rx_next_highest); // Highest SN received + 1 + } + + // t-reassembly has expired. There should be a NACK in the status report. + // There should be 3 NACKs with SO_start and SO_end + TESTASSERT_EQ(status_pdu_ack_size + 3 * (status_pdu_nack_size + status_pdu_so_size), rlc2.get_buffer_state()); + { + // Read status PDU from RLC2 + byte_buffer_t status_buf; + int len = rlc2.read_pdu(status_buf.msg, status_pdu_ack_size + 3 * (status_pdu_nack_size + status_pdu_so_size)); + status_buf.N_bytes = len; + + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(&status_buf, sn_size, &status_check); + TESTASSERT_EQ(5, status_check.ack_sn); // 5 is the next expected SN. + TESTASSERT_EQ(3, status_check.nacks.size()); // We lost one PDU. + TESTASSERT_EQ(1, status_check.nacks[0].nack_sn); // Lost SDU on SN=1. + TESTASSERT_EQ(true, status_check.nacks[0].has_so); // Lost SDU on SN=1. + TESTASSERT_EQ(0, status_check.nacks[0].so_start); // Lost SDU on SN=1. + TESTASSERT_EQ(0, status_check.nacks[0].so_end); // Lost SDU on SN=1. + TESTASSERT_EQ(2, status_check.nacks[1].nack_sn); // Lost SDU on SN=1. + TESTASSERT_EQ(true, status_check.nacks[1].has_so); // Lost SDU on SN=1. + TESTASSERT_EQ(1, status_check.nacks[1].so_start); // Lost SDU on SN=1. + TESTASSERT_EQ(1, status_check.nacks[1].so_end); // Lost SDU on SN=1. + TESTASSERT_EQ(3, status_check.nacks[2].nack_sn); // Lost SDU on SN=1. + TESTASSERT_EQ(true, status_check.nacks[2].has_so); // Lost SDU on SN=1. + TESTASSERT_EQ(2, status_check.nacks[2].so_start); // Lost SDU on SN=1. + TESTASSERT_EQ(0xFFFF, status_check.nacks[2].so_end); // Lost SDU on SN=1. + + // Write status PDU to RLC1 + rlc1.write_pdu(status_buf.msg, status_buf.N_bytes); + + // Check there are 3 Retx segments (a first one and two continued ones) + TESTASSERT_EQ(pdu_size_first + 2 * pdu_size_continued, rlc1.get_buffer_state()); + } + + { + // Re-transmit the 3 lost segments + for (int i = 0; i < 3; i++) { + // First also test buffer state + uint32_t remaining_segments = 3 - i; + expected_buffer_state = remaining_segments * (header_size + so_size + segment_size); + if (i == 0) { // subtract so_size, because in this setup the first retx is a "first_segment" without SO. + expected_buffer_state -= so_size; + } + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + byte_buffer_t retx_buf; + uint32_t len = 0; + if (i == 0) { + len = rlc1.read_pdu(retx_buf.msg, pdu_size_first); + TESTASSERT_EQ(pdu_size_first, len); + } else { + len = rlc1.read_pdu(retx_buf.msg, pdu_size_continued); + TESTASSERT_EQ(pdu_size_continued, len); + } + retx_buf.N_bytes = len; + + rlc_am_nr_pdu_header_t header_check = {}; + uint32_t hdr_len = rlc_am_nr_read_data_pdu_header(&retx_buf, sn_size, &header_check); + // Double check header. + if (i == 0) { + TESTASSERT_EQ(1, header_check.sn); // Double check RETX SN + TESTASSERT_EQ(rlc_nr_si_field_t::first_segment, header_check.si); + } else if (i == 1) { + TESTASSERT_EQ(2, header_check.sn); // Double check RETX SN + TESTASSERT_EQ(rlc_nr_si_field_t::neither_first_nor_last_segment, header_check.si); + } else { + TESTASSERT_EQ(3, header_check.sn); // Double check RETX SN + TESTASSERT_EQ(rlc_nr_si_field_t::last_segment, header_check.si); + } + + rlc2.write_pdu(retx_buf.msg, retx_buf.N_bytes); + } + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + } + + // Check statistics + rlc_bearer_metrics_t metrics1 = rlc1.get_metrics(); + rlc_bearer_metrics_t metrics2 = rlc2.get_metrics(); + + uint32_t data_pdu_size = header_size + payload_size; + uint32_t total_tx_pdu_bytes1 = 5 * pdu_size_first + 10 * pdu_size_continued + pdu_size_first + 2 * pdu_size_continued; + uint32_t total_rx_pdu_bytes1 = 2 * status_pdu_ack_size + 3 * (status_pdu_nack_size + status_pdu_so_size); + uint32_t total_tx_pdu_bytes2 = 3 * status_pdu_ack_size + 4 * (status_pdu_nack_size + status_pdu_so_size); + uint32_t total_rx_pdu_bytes2 = 4 * pdu_size_first + 8 * pdu_size_continued + pdu_size_first + 2 * pdu_size_continued; + + // SDU metrics + TESTASSERT_EQ(5, metrics1.num_tx_sdus); + TESTASSERT_EQ(0, metrics1.num_rx_sdus); + TESTASSERT_EQ(15, metrics1.num_tx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_rx_sdu_bytes); + TESTASSERT_EQ(0, metrics1.num_lost_sdus); + + // PDU metrics + TESTASSERT_EQ(15 + 3, metrics1.num_tx_pdus); // 15 PDUs + 3 re-transmissions + TESTASSERT_EQ(2, metrics1.num_rx_pdus); // Two status PDU + TESTASSERT_EQ(total_tx_pdu_bytes1, + metrics1.num_tx_pdu_bytes); // 3 Bytes * 5 (5 PDUs without SO) + 10 * 5 (10 PDUs with SO) + // 3 (1 retx no SO) + 2 * 5 (2 retx with SO) = 78 + TESTASSERT_EQ(total_rx_pdu_bytes1, + metrics1.num_rx_pdu_bytes); // Two status PDU. One with just an ack (3 bytes) + // Another with 3 NACKs all with SO. (3 + 3*6 bytes) = 24 + TESTASSERT_EQ(0, metrics1.num_lost_sdus); // No lost SDUs + + // PDU metrics + TESTASSERT_EQ(0, metrics2.num_tx_sdus); + TESTASSERT_EQ(5, metrics2.num_rx_sdus); + TESTASSERT_EQ(0, metrics2.num_tx_sdu_bytes); + TESTASSERT_EQ(15, metrics2.num_rx_sdu_bytes); // 5 SDUs, 3 bytes each + TESTASSERT_EQ(0, metrics2.num_lost_sdus); + // SDU metrics + TESTASSERT_EQ(3, metrics2.num_tx_pdus); // 3 status PDUs + TESTASSERT_EQ(15, metrics2.num_rx_pdus); // 15 PDUs (18 tx'ed, but three were lost) + TESTASSERT_EQ(total_tx_pdu_bytes2, // Three status PDU. One with just an ack + metrics2.num_tx_pdu_bytes); // Another with 1 NACK with SO. + // Another with 3 NACKs all with SO. + TESTASSERT_EQ(total_rx_pdu_bytes2, // 3 Bytes (header + data size, without SO) * 5 (N PDUs without SO) + metrics2.num_rx_pdu_bytes); // 5 bytes (header + data size, with SO) * 10 (N PDUs with SO) + // = 81 bytes + TESTASSERT_EQ(0, metrics2.num_lost_sdus); // No lost SDUs + + // Check state + rlc_am_nr_rx_state_t state2_rx = rx2->get_rx_state(); + TESTASSERT_EQ(5, state2_rx.rx_next); + + return SRSRAN_SUCCESS; +} + +// We only increment TX_NEXT after transmitting the last segment of a SDU +// This means that we need to handle status reports where ACK_SN may be larger +// than TX_NEXT, as it may contain a NACK for the partially transmitted PDU with +// SN==TX_NEXT. +int handle_status_of_non_tx_last_segment(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("basic segmentation ({} bit SN)", to_number(sn_size)); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + if (not rlc2.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + + // after configuring entity + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + + // Push 1 SDU into RLC1 + unique_byte_buffer_t sdu; + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + sdu = srsran::make_byte_buffer(); + TESTASSERT(nullptr != sdu); + sdu->msg[0] = 0; // Write the index into the buffer + sdu->N_bytes = payload_size; // Give the SDU the size of 3 bytes + sdu->md.pdcp_sn = 0; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu)); + + // Read 2 PDUs. Leave last one in the tx_window. + constexpr uint16_t n_pdus = 2; + unique_byte_buffer_t pdu_bufs[n_pdus]; + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + constexpr uint32_t so_size = 2; + constexpr uint32_t segment_size = 1; + uint32_t pdu_size_first = header_size + segment_size; + uint32_t pdu_size_continued = header_size + so_size + segment_size; + for (int i = 0; i < n_pdus; i++) { + pdu_bufs[i] = srsran::make_byte_buffer(); + TESTASSERT(nullptr != pdu_bufs[i]); + if (i == 0) { + pdu_bufs[i]->N_bytes = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_first); + TESTASSERT_EQ(pdu_size_first, pdu_bufs[i]->N_bytes); + } else { + pdu_bufs[i]->N_bytes = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_continued); + TESTASSERT_EQ(pdu_size_continued, pdu_bufs[i]->N_bytes); + } + } + + // Only middle PDU into RLC2 + // First PDU is lost to trigger status report + for (int i = 0; i < n_pdus; i++) { + if (i == 1) { + rlc2.write_pdu(pdu_bufs[i]->msg, pdu_bufs[i]->N_bytes); + } + } + + // Advance timer to trigger status report + for (uint8_t t = 0; t < 35; t++) { + timers.step_all(); + } + TESTASSERT_NEQ(0, rlc2.get_buffer_state()); + + // Make sure RLC 1 has only the last segment to TX before getting the status report + TESTASSERT_EQ(pdu_size_continued, rlc1.get_buffer_state()); + + // Get status report from RLC 2 + // and write it to RLC 1 + { + unique_byte_buffer_t status_buf = srsran::make_byte_buffer(); + status_buf->N_bytes = rlc2.read_pdu(status_buf->msg, 100); + rlc1.write_pdu(status_buf->msg, status_buf->N_bytes); + } + + // Make sure RLC 1 now has the last segment to TX and the RETX of the first segment + TESTASSERT_EQ(pdu_size_continued + pdu_size_first, rlc1.get_buffer_state()); + return SRSRAN_SUCCESS; +} + +// This test checks whether RLC informs upper layer when max retransmission has been reached +// due to lost SDUs as a whole +int max_retx_lost_sdu_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + int len = 0; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); + srslog::fetch_basic_logger("RLC").set_hex_dump_max_size(100); + test_delimit_logger delimiter("max retx lost SDU ({} bit SN)", to_number(sn_size)); + + const rlc_config_t rlc_cfg = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + if (not rlc1.configure(rlc_cfg)) { + return SRSRAN_ERROR; + } + + // Push 2 SDUs into RLC1 + const uint32_t n_sdus = 2; + unique_byte_buffer_t sdu_bufs[n_sdus]; + constexpr uint32_t payload_size = 1; // Give each buffer a size of 1 byte + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (uint32_t i = 0; i < n_sdus; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = payload_size; // Give each buffer a size of 1 byte + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_bufs[i])); + } + + uint32_t pdu_size = header_size + payload_size; + + // Read 2 PDUs from RLC1 (1 byte each) + const uint32_t n_pdus = 2; + byte_buffer_t pdu_bufs[n_pdus]; + for (uint32_t i = 0; i < n_pdus; i++) { + len = rlc1.read_pdu(pdu_bufs[i].msg, pdu_size); // 2 byte header + 1 byte payload + pdu_bufs[i].N_bytes = len; + } + + TESTASSERT(0 == rlc1.get_buffer_state()); + + // Fake status PDU that ack SN=1 and nack SN=0 + rlc_am_nr_status_pdu_t fake_status(sn_size); + fake_status.ack_sn = 2; // delivered up to SN=1 + rlc_status_nack_t nack; // one SN was lost + nack.nack_sn = 0; // it was SN=0 that was lost + fake_status.push_nack(nack); + + // pack into PDU + byte_buffer_t status_pdu; + rlc_am_nr_write_status_pdu(fake_status, rlc_cfg.am_nr.tx_sn_field_length, &status_pdu); + + // Exceed the number of tolerated retransmissions by one additional retransmission + // to trigger notification of the higher protocol layers. Note that the initial transmission + // (before starting retransmissions) does not count. See TS 38.322 Sec. 5.3.2 + for (uint32_t retx_count = 0; retx_count < rlc_cfg.am_nr.max_retx_thresh + 1; ++retx_count) { + // we've not yet reached max attempts + TESTASSERT(tester.max_retx_triggered == false); + + // Write status PDU to RLC1 + rlc1.write_pdu(status_pdu.msg, status_pdu.N_bytes); + + byte_buffer_t pdu_buf; + len = rlc1.read_pdu(pdu_buf.msg, pdu_size); // 2 byte header + 1 byte payload + } + + // Now maxRetx should have been triggered + TESTASSERT(tester.max_retx_triggered == true); + + return SRSRAN_SUCCESS; +} + +// This test checks whether RLC informs upper layer when max retransmission has been reached +// due to lost SDU segments +int max_retx_lost_segments_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + int len = 0; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); + srslog::fetch_basic_logger("RLC").set_hex_dump_max_size(100); + test_delimit_logger delimiter("max retx lost SDU segment ({} bit SN)", to_number(sn_size)); + + const rlc_config_t rlc_cfg = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + if (not rlc1.configure(rlc_cfg)) { + return SRSRAN_ERROR; + } + + // Push 2 SDUs into RLC1 + const uint32_t n_sdus = 2; + unique_byte_buffer_t sdu_bufs[n_sdus]; + constexpr uint32_t payload_size = 20; // Give each buffer a size of 20 bytes + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (uint32_t i = 0; i < n_sdus; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = payload_size; // Give each buffer a size of 20 bytes + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_bufs[i])); + } + + constexpr uint32_t so_size = 2; + constexpr uint32_t segment_size_first = 13; + constexpr uint32_t segment_size_continued = 7; + uint32_t pdu_size_first = header_size + segment_size_first; + uint32_t pdu_size_continued = header_size + so_size + segment_size_continued; + + // Read 2*2=4 PDUs from RLC1 and limit to 15 byte to force segmentation in two parts: + // Segment 1: 2 byte header + 13 byte payload; space fully used + // Segment 2: 4 byte header + 7 byte payload; space not fully used, 4 bytes left over + const uint32_t n_pdus = 4; + byte_buffer_t pdu_bufs[n_pdus]; + for (uint32_t i = 0; i < n_pdus; i++) { + len = rlc1.read_pdu(pdu_bufs[i].msg, pdu_size_first); + pdu_bufs[i].N_bytes = len; + } + + TESTASSERT(0 == rlc1.get_buffer_state()); + + // Fake status PDU that ack SN=1 and nack {SN=0 segment 0, SN=0 segment 1} + rlc_am_nr_status_pdu_t status_lost_both_segments(sn_size); + status_lost_both_segments.ack_sn = 2; // delivered up to SN=1 + + // two segments lost + { + rlc_status_nack_t nack; + nack.nack_sn = 0; // it was SN=0 that was lost + nack.has_so = true; // this NACKs a segment + nack.so_start = 0; // segment starts at (and includes) byte 0 + nack.so_end = 12; // segment ends at (and includes) byte 12 + status_lost_both_segments.push_nack(nack); + } + + { + rlc_status_nack_t nack; + nack.nack_sn = 0; // it was SN=0 that was lost + nack.has_so = true; // this NACKs a segment + nack.so_start = 13; // segment starts at (and includes) byte 13 + nack.so_end = 19; // segment ends at (and includes) byte 19 + status_lost_both_segments.push_nack(nack); + } + + // pack into PDU + byte_buffer_t status_pdu_lost_both_segments; + rlc_am_nr_write_status_pdu( + status_lost_both_segments, rlc_cfg.am_nr.tx_sn_field_length, &status_pdu_lost_both_segments); + + // Fake status PDU that ack SN=1 and nack {SN=0 segment 1} + rlc_am_nr_status_pdu_t status_lost_second_segment(sn_size); + status_lost_second_segment.ack_sn = 2; // delivered up to SN=1 + + // one SN was lost + { + rlc_status_nack_t nack; + nack.nack_sn = 0; // it was SN=0 that was lost + nack.has_so = true; // this NACKs a segment + nack.so_start = 13; // segment starts at (and includes) byte 13 + nack.so_end = 19; // segment ends at (and includes) byte 19 + status_lost_second_segment.push_nack(nack); + } + + // pack into PDU + byte_buffer_t status_pdu_lost_second_segment; + rlc_am_nr_write_status_pdu( + status_lost_second_segment, rlc_cfg.am_nr.tx_sn_field_length, &status_pdu_lost_second_segment); + + // Exceed the number of tolerated retransmissions by one additional retransmission + // to trigger notification of the higher protocol layers. Note that the initial transmission + // (before starting retransmissions) does not count. See TS 38.322 Sec. 5.3.2 + for (uint32_t retx_count = 0; retx_count < rlc_cfg.am_nr.max_retx_thresh + 1; ++retx_count) { + byte_buffer_t pdu_buf; + + // we've not yet reached max attempts + TESTASSERT(tester.max_retx_triggered == false); + + if (retx_count < rlc_cfg.am_nr.max_retx_thresh / 2) { + // Send NACK for segment 1 and segment 2 + // Although two segments, this must count as one retransmission, + // because both segments NACK the same SDU in the same status message. + rlc1.write_pdu(status_pdu_lost_both_segments.msg, status_pdu_lost_both_segments.N_bytes); + + // read the retransmitted PDUs + len = rlc1.read_pdu(pdu_buf.msg, pdu_size_first); // 2 byte header + 13 byte payload + len = rlc1.read_pdu(pdu_buf.msg, pdu_size_first); // 4 byte header + 7 byte payload + } else { + // Send NACK for segment 2 (assume at least segment 1 was finally received) + rlc1.write_pdu(status_pdu_lost_second_segment.msg, status_pdu_lost_second_segment.N_bytes); + + // read the retransmitted PDUs + len = rlc1.read_pdu(pdu_buf.msg, pdu_size_first); // 4 byte header + 7 byte payload + } + } + + // Now maxRetx should have been triggered + TESTASSERT(tester.max_retx_triggered == true); + + return SRSRAN_SUCCESS; +} + +// This test checks the correct functioning of RLC discard functionality +int discard_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + test_delimit_logger delimiter("discard test ({} bit SN)", to_number(sn_size)); + + srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); + srslog::fetch_basic_logger("RLC_AM_2").set_hex_dump_max_size(100); + srslog::fetch_basic_logger("RLC").set_hex_dump_max_size(100); + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return SRSRAN_ERROR; + } + + if (not rlc2.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return SRSRAN_ERROR; + } + + uint32_t num_tx_sdus = 1; + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + uint32_t payload_size = 5; // Give each buffer a size of 5 bytes + // Test discarding the single SDU from the queue + { + for (uint32_t i = 0; i < num_tx_sdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = payload_size; + for (uint32_t k = 0; k < sdu->N_bytes; ++k) { + sdu->msg[k] = i; // Write the index into the buffer + } + sdu->md.pdcp_sn = i; + rlc1.write_sdu(std::move(sdu)); + } + } + rlc1.discard_sdu(0); // Try to discard PDCP_SN=0 + TESTASSERT(rlc1.has_data() == false); + + num_tx_sdus = 10; + payload_size = 7; // Give each buffer a size of 7 bytes + // Test discarding two SDUs in the middle (SN=3) and end (SN=9) of the queue and read PDUs after + { + for (uint32_t i = 0; i < num_tx_sdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = payload_size; + for (uint32_t k = 0; k < sdu->N_bytes; ++k) { + sdu->msg[k] = i; // Write the index into the buffer + } + sdu->md.pdcp_sn = i; + rlc1.write_sdu(std::move(sdu)); + } + } + TESTASSERT(rlc1.get_buffer_state() == num_tx_sdus * (header_size + payload_size)); // 10 * (2B Header + 7B Payload) + rlc1.discard_sdu(3); // Try to discard PDCP_SN=3 + TESTASSERT(rlc1.has_data() == true); + TESTASSERT(rlc1.get_buffer_state() == (num_tx_sdus - 1) * (header_size + payload_size)); + rlc1.discard_sdu(9); // Try to discard PDCP_SN=9 + TESTASSERT(rlc1.has_data() == true); + TESTASSERT(rlc1.get_buffer_state() == (num_tx_sdus - 2) * (header_size + payload_size)); + + num_tx_sdus = 8; + { + for (uint32_t i = 0; i < num_tx_sdus; ++i) { + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + uint32_t len = rlc1.read_pdu(pdu->msg, 50); // sufficient space to read without segmentation + pdu->N_bytes = len; + TESTASSERT((header_size + payload_size) == len); + // Check that we don't have any SN gaps + rlc_am_nr_pdu_header_t header = {}; + rlc_am_nr_read_data_pdu_header(pdu.get(), sn_size, &header); + TESTASSERT(header.sn == i); + } + } + TESTASSERT(rlc1.has_data() == false); + srslog::fetch_basic_logger("TEST").info("Received %zd SDUs", tester.sdus.size()); + + num_tx_sdus = 3; + payload_size = 7; // Give each buffer a size of 7 bytes + // Test discarding non-existing SDU from the queue + { + for (uint32_t i = 0; i < num_tx_sdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = payload_size; + for (uint32_t k = 0; k < sdu->N_bytes; ++k) { + sdu->msg[k] = i; // Write the index into the buffer + } + sdu->md.pdcp_sn = i; + rlc1.write_sdu(std::move(sdu)); + } + } + TESTASSERT(rlc1.get_buffer_state() == num_tx_sdus * (header_size + payload_size)); // 3 * (2B Header + 7B Payload) + rlc1.discard_sdu(8); // Try to discard PDCP_SN=8, which doesn't exist + TESTASSERT(rlc1.get_buffer_state() == num_tx_sdus * (header_size + payload_size)); // 3 * (2B Header + 7B Payload) + + return SRSRAN_SUCCESS; +} + +// Test p bit set on new TX with PollPDU +int poll_pdu(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("pollPDU test ({} bit SN)", to_number(sn_size)); + + srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); + + rlc_config_t rlc_cnfg = {}; + rlc_cnfg.rat = srsran_rat_t::nr; + rlc_cnfg.rlc_mode = rlc_mode_t::am; + rlc_cnfg.am_nr.tx_sn_field_length = sn_size; // Number of bits used for tx (UL) sequence number + rlc_cnfg.am_nr.rx_sn_field_length = sn_size; // Number of bits used for rx (DL) sequence number + rlc_cnfg.am_nr.poll_pdu = 4; + rlc_cnfg.am_nr.poll_byte = 3000; + rlc_cnfg.am_nr.t_status_prohibit = 8; + rlc_cnfg.am_nr.max_retx_thresh = 8; + rlc_cnfg.am_nr.t_reassembly = 35; + + // Test p bit set on new TX with PollPDU + { + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + if (not rlc1.configure(rlc_cnfg)) { + return SRSRAN_ERROR; + } + // pollPDU == 4 + uint32_t num_tx_sdus = 6; + for (uint32_t i = 0; i < num_tx_sdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = 1; + sdu->md.pdcp_sn = i; + rlc1.write_sdu(std::move(sdu)); + } + uint32_t num_tx_pdus = 6; + uint32_t pdu_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 3 : 4; + for (uint32_t i = 0; i < num_tx_pdus; ++i) { + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, pdu_size); + rlc_am_nr_pdu_header_t hdr; + rlc_am_nr_read_data_pdu_header(pdu.get(), sn_size, &hdr); + if (i != 3 && i != 5) { // P bit set for PollPDU and for empty TX queue + TESTASSERT_EQ(0, hdr.p); + } else { + TESTASSERT_EQ(1, hdr.p); + } + } + } + return SRSRAN_SUCCESS; +} + +// Test p bit set on new TX with PollBYTE +int poll_byte(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("pollBYTE test ({} bit SN)", to_number(sn_size)); + + srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); + + rlc_config_t rlc_cnfg = {}; + rlc_cnfg.rat = srsran_rat_t::nr; + rlc_cnfg.rlc_mode = rlc_mode_t::am; + rlc_cnfg.am_nr.tx_sn_field_length = sn_size; // Number of bits used for tx (UL) sequence number + rlc_cnfg.am_nr.rx_sn_field_length = sn_size; // Number of bits used for rx (DL) sequence number + rlc_cnfg.am_nr.poll_pdu = 4; + rlc_cnfg.am_nr.poll_byte = 3000; + rlc_cnfg.am_nr.t_status_prohibit = 8; + rlc_cnfg.am_nr.max_retx_thresh = 8; + rlc_cnfg.am_nr.t_reassembly = 35; + + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + if (not rlc1.configure(rlc_cnfg)) { + return SRSRAN_ERROR; + } + // pollByte == 3000 + uint32_t num_tx_sdus = 4; + for (uint32_t i = 0; i < num_tx_sdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = i == 0 ? 2999 : 1; + sdu->md.pdcp_sn = i; + rlc1.write_sdu(std::move(sdu)); + } + uint32_t num_tx_pdus = num_tx_sdus; + uint32_t small_pdu_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 3 : 4; + uint32_t large_pdu_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 3001 : 3002; + for (uint32_t i = 0; i < num_tx_pdus; ++i) { + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + uint32_t nof_bytes = i == 0 ? large_pdu_size : small_pdu_size; + pdu->N_bytes = rlc1.read_pdu(pdu->msg, nof_bytes); + TESTASSERT_EQ(nof_bytes, pdu->N_bytes); + rlc_am_nr_pdu_header_t hdr; + rlc_am_nr_read_data_pdu_header(pdu.get(), rlc_am_nr_sn_size_t::size18bits, &hdr); + if (i != 1 && i != 3) { + TESTASSERT_EQ(0, hdr.p); + } else { + TESTASSERT_EQ(1, hdr.p); + } + } + return SRSRAN_SUCCESS; +} + +// Test p bit set on RETXes that cause an empty retx queue. +int poll_retx(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("poll retx test ({} bit SN)", to_number(sn_size)); + + srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); + + rlc_config_t rlc_cnfg = {}; + rlc_cnfg.rat = srsran_rat_t::nr; + rlc_cnfg.rlc_mode = rlc_mode_t::am; + rlc_cnfg.am_nr.tx_sn_field_length = sn_size; // Number of bits used for tx (UL) sequence number + rlc_cnfg.am_nr.rx_sn_field_length = sn_size; // Number of bits used for rx (DL) sequence number + rlc_cnfg.am_nr.poll_pdu = 4; + rlc_cnfg.am_nr.poll_byte = 3000; + rlc_cnfg.am_nr.t_status_prohibit = 8; + rlc_cnfg.am_nr.max_retx_thresh = 8; + rlc_cnfg.am_nr.t_reassembly = 35; + + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + if (not rlc1.configure(rlc_cnfg)) { + return SRSRAN_ERROR; + } + + // pollPDU == 4 + { + uint32_t num_tx_sdus = 5; + for (uint32_t i = 0; i < num_tx_sdus; ++i) { + // Write SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = 1; + sdu->md.pdcp_sn = i; + rlc1.write_sdu(std::move(sdu)); + } + } + { + // Read 3 PDUs and NACK the second one + uint32_t num_tx_pdus = 3; + uint32_t pdu_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 3 : 4; + for (uint32_t i = 0; i < num_tx_pdus; ++i) { + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, pdu_size); + rlc_am_nr_pdu_header_t hdr; + rlc_am_nr_read_data_pdu_header(pdu.get(), sn_size, &hdr); + TESTASSERT_EQ(0, hdr.p); + } + } + { + unique_byte_buffer_t status_pdu = srsran::make_byte_buffer(); + TESTASSERT(status_pdu != nullptr); + rlc_am_nr_status_pdu_t status(rlc_am_nr_sn_size_t::size12bits); + status.ack_sn = 2; + { + rlc_status_nack_t nack; + nack.nack_sn = 1; // SN=1 needs RETX + status.push_nack(nack); + } + rlc_am_nr_write_status_pdu(status, rlc_cnfg.am_nr.tx_sn_field_length, status_pdu.get()); + rlc1.write_pdu(status_pdu->msg, status_pdu->N_bytes); + } + { + // Read 2 PDUs, + uint32_t num_tx_pdus = 3; + uint32_t pdu_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 3 : 4; + for (uint32_t i = 0; i < num_tx_pdus; ++i) { + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, pdu_size); + TESTASSERT_EQ(pdu_size, pdu->N_bytes); + rlc_am_nr_pdu_header_t hdr; + rlc_am_nr_read_data_pdu_header(pdu.get(), sn_size, &hdr); + if (i == 0) { + TESTASSERT_EQ(0, hdr.p); // No poll since pollPDU is not incremented for RETX + TESTASSERT_EQ(1, hdr.sn); + } else { + TESTASSERT_EQ(1, hdr.p); // poll set because of pollPDU for SN=3 and empty buffer on SN=4 + } + } + } + { + unique_byte_buffer_t status_pdu = srsran::make_byte_buffer(); + TESTASSERT(status_pdu != nullptr); + rlc_am_nr_status_pdu_t status(rlc_am_nr_sn_size_t::size12bits); + status.ack_sn = 4; + { + rlc_status_nack_t nack; + nack.nack_sn = 1; // SN=1 needs RETX + status.push_nack(nack); + } + rlc_am_nr_write_status_pdu(status, rlc_cnfg.am_nr.tx_sn_field_length, status_pdu.get()); + rlc1.write_pdu(status_pdu->msg, status_pdu->N_bytes); + } + { + // Read 1 RETX PDU. Empty retx buffer, so poll should be set + uint32_t num_tx_pdus = 1; + uint32_t pdu_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 3 : 4; + for (uint32_t i = 0; i < num_tx_pdus; ++i) { + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, pdu_size); + TESTASSERT_EQ(pdu_size, pdu->N_bytes); + rlc_am_nr_pdu_header_t hdr; + rlc_am_nr_read_data_pdu_header(pdu.get(), sn_size, &hdr); + if (i == 0) { + TESTASSERT_EQ(1, hdr.p); // Poll set because of empty retx buffer + TESTASSERT_EQ(1, hdr.sn); + } + } + } + return SRSRAN_SUCCESS; +} + +// This test checks whether re-transmissions are triggered correctly in case the t-PollRetranmission expires. +// It checks if the poll retx timer is re-armed upon receiving an ACK for POLL_SN +bool poll_retx_expiry(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("poll retx expiry test ({} bit SN)", to_number(sn_size)); + + srslog::fetch_basic_logger("RLC_AM_1").set_hex_dump_max_size(100); + srslog::fetch_basic_logger("RLC_AM_2").set_hex_dump_max_size(100); + + rlc_config_t rlc_cnfg = rlc_config_t::default_rlc_am_nr_config(); + + rlc_cnfg.am_nr.tx_sn_field_length = sn_size; // Number of bits used for tx (UL) sequence number + rlc_cnfg.am_nr.rx_sn_field_length = sn_size; // Number of bits used for rx (DL) sequence number + rlc_cnfg.am_nr.t_poll_retx = 65; + rlc_cnfg.am_nr.poll_pdu = -1; + rlc_cnfg.am_nr.poll_byte = -1; + rlc_cnfg.am_nr.max_retx_thresh = 6; + rlc_cnfg.am_nr.t_status_prohibit = 55; + + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + if (not rlc1.configure(rlc_cnfg)) { + return SRSRAN_ERROR; + } + + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + if (not rlc2.configure(rlc_cnfg)) { + return SRSRAN_ERROR; + } + + unsigned hdr_no_so = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + unsigned hdr_with_so = sn_size == rlc_am_nr_sn_size_t::size12bits ? 4 : 5; + unsigned ack_size = 3; + unsigned nack_size_no_so = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + unsigned nack_size_with_so = sn_size == rlc_am_nr_sn_size_t::size12bits ? (2 + 4) : (3 + 4); + // Tx SDU with 135 B of data + // Read it in two PDU segments, so=0 (89B of data) + // and so=89 (46B of data) + { + // TX a single SDU + unique_byte_buffer_t sdu = srsran::make_byte_buffer(); + TESTASSERT(sdu != nullptr); + sdu->N_bytes = 135; + for (uint32_t k = 0; k < sdu->N_bytes; ++k) { + sdu->msg[k] = 0; // Write the index into the buffer + } + sdu->md.pdcp_sn = 0; + rlc1.write_sdu(std::move(sdu)); + + // Read two PDUs. The last PDU should trigger polling, as it + // is the last SDU segment in the buffer. + uint32_t pdu1_size = 89 + hdr_no_so; + unique_byte_buffer_t pdu1 = srsran::make_byte_buffer(); + TESTASSERT(pdu1 != nullptr); + pdu1->N_bytes = rlc1.read_pdu(pdu1->msg, pdu1_size); // 89 bytes payload + + uint32_t pdu2_size = 46 + hdr_with_so; + unique_byte_buffer_t pdu2 = srsran::make_byte_buffer(); + TESTASSERT(pdu2 != nullptr); + pdu2->N_bytes = rlc1.read_pdu(pdu2->msg, pdu2_size); // 46 bytes payload + + // Deliver PDU2 to RLC2. PDU1 is lost + rlc2.write_pdu(pdu2->msg, pdu2->N_bytes); + + // Double-check polling status in PDUs + rlc_am_nr_pdu_header_t hdr1 = {}; + rlc_am_nr_read_data_pdu_header(pdu1.get(), sn_size, &hdr1); + rlc_am_nr_pdu_header_t hdr2 = {}; + rlc_am_nr_read_data_pdu_header(pdu2.get(), sn_size, &hdr2); + TESTASSERT_EQ(0, hdr1.p); + TESTASSERT_EQ(1, hdr2.p); + } + + // Step timers until t-PollRetransmit timer expires on RLC1 + // t-PollRetransmit will schedule SN=0, so=0, payload_len=89 for RETX + // t-Reordering timer also will expire on RLC2, meaning we will also get a status report. + TESTASSERT_EQ(false, rlc1.has_data()); + for (int cnt = 0; cnt < 65; cnt++) { + timers.step_all(); + } + + // Make sure that the SDU segment was scheduled for RETX + TESTASSERT_EQ(89 + hdr_no_so, rlc1.get_buffer_state()); + + // Further segment RETX segment + // First SDU segment (81B of data) + { + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 81 + hdr_no_so); + } + // Second SDU segment (8B of data) + { + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT(pdu != nullptr); + pdu->N_bytes = rlc1.read_pdu(pdu->msg, 8 + hdr_with_so); + } + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + + // Read status PDU from RLC2 (triggered previously from t-Reordering) + // ACK=1, NACKs=1 + // NACK_SN[0].sn=0, NACK_SN[0].so_start=0, NACK_SN[0].so_end=89 + uint32_t status_size = rlc2.get_buffer_state(); + TESTASSERT_EQ(ack_size + nack_size_with_so, status_size); + + // Read status PDU from RLC2 + unique_byte_buffer_t status_buf = srsran::make_byte_buffer(); + TESTASSERT(status_buf != nullptr); + int len = rlc2.read_pdu(status_buf->msg, status_size); + status_buf->N_bytes = len; + + TESTASSERT(0 == rlc2.get_buffer_state()); + + // Assert status is correct + rlc_am_nr_status_pdu_t status_check(sn_size); + rlc_am_nr_read_status_pdu(status_buf.get(), sn_size, &status_check); + TESTASSERT(status_check.ack_sn == 1); // SN=1 is first SN missing without a NACK + TESTASSERT(status_check.nacks.size() == 1); // 1 PDU lost + TESTASSERT(status_check.nacks[0].nack_sn == 0); // SN=0 + TESTASSERT(status_check.nacks[0].so_start == 0); // SN=0 + TESTASSERT_EQ(88, status_check.nacks[0].so_end); // SN=0 + + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + // Deliver status PDU after ReTX to RLC1. This should restart t-PollRetransmission + // It NACKs SDU segment 0:81 and 81:89 + TESTASSERT_EQ(false, rlc1.has_data()); + rlc1.write_pdu(status_buf->msg, status_buf->N_bytes); + TESTASSERT_EQ(true, rlc1.has_data()); + + // [I] SRB1 Retx SDU segment (81 B of data) + // [I] SRB1 Retx PDU segment (8 B of data) + { + unique_byte_buffer_t pdu1 = srsran::make_byte_buffer(); + TESTASSERT(pdu1 != nullptr); + pdu1->N_bytes = rlc1.read_pdu(pdu1->msg, 81 + hdr_no_so); + + unique_byte_buffer_t pdu2 = srsran::make_byte_buffer(); + TESTASSERT(pdu2 != nullptr); + pdu2->N_bytes = rlc1.read_pdu(pdu2->msg, 8 + hdr_with_so); + } + + TESTASSERT_EQ(false, rlc1.has_data()); // We don't have any more data + + // Step timers until t-PollRetransmission timer expires on RLC1 + // [I] SRB1 Schedule SN=3 for reTx + for (int cnt = 0; cnt < 66; cnt++) { + timers.step_all(); + } + TESTASSERT_EQ(81 + hdr_no_so, rlc1.get_buffer_state()); + srslog::fetch_basic_logger("TEST").info("t-PollRetransmssion successfully restarted."); + + return SRSRAN_SUCCESS; +} + +int rx_nack_range_no_so_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + std::string str = "Rx NACK range test (" + std::to_string(to_number(sn_size)) + " bit SN)"; + test_delimit_logger delimiter(str.c_str()); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + auto rlc_cnfg = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + rlc_cnfg.am_nr.t_poll_retx = -1; + if (not rlc1.configure(rlc_cnfg)) { + return -1; + } + + // after configuring entity + TESTASSERT(0 == rlc1.get_buffer_state()); + + int n_sdu_bufs = 5; + int n_pdu_bufs = 15; + + // Push 5 SDUs into RLC1 + std::vector sdu_bufs(n_sdu_bufs); + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (int i = 0; i < n_sdu_bufs; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = payload_size; // Give each buffer a size of 3 bytes + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_bufs[i])); + } + + uint32_t expected_buffer_state = (header_size + payload_size) * n_sdu_bufs; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + constexpr uint32_t so_size = 2; + constexpr uint32_t segment_size = 1; + uint32_t pdu_size_first = header_size + segment_size; + uint32_t pdu_size_continued = header_size + so_size + segment_size; + + // Read 15 PDUs from RLC1 + std::vector pdu_bufs(n_pdu_bufs); + for (int i = 0; i < n_pdu_bufs; i++) { + // First also test buffer state + uint32_t remaining_total_bytes = (payload_size * n_sdu_bufs) - (i * segment_size); + uint32_t remaining_full_sdus = remaining_total_bytes / payload_size; + uint32_t remaining_seg_bytes = remaining_total_bytes % payload_size; + + uint32_t buffer_state_full_sdus = (header_size + payload_size) * remaining_full_sdus; + uint32_t buffer_state_seg_sdu = remaining_seg_bytes == 0 ? 0 : (header_size + so_size + remaining_seg_bytes); + expected_buffer_state = buffer_state_full_sdus + buffer_state_seg_sdu; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + pdu_bufs[i] = srsran::make_byte_buffer(); + if (i == 0 || i == 3 || i == 6 || i == 9 || i == 12) { + // First segment, no SO + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_first); // 2 bytes for header + 1 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_first, len); + } else { + // Middle or last segment, SO present + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_continued); // 4 bytes for header + 1 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_continued, len); + } + } + + // Deliver dummy status report with nack range betwen PDU 6 and 10. + rlc_am_nr_status_pdu_t status(sn_size); + status.ack_sn = 5; + rlc_status_nack_t nack = {}; + nack.nack_sn = 1; + nack.has_nack_range = true; + nack.nack_range = 3; + status.push_nack(nack); + byte_buffer_t status_pdu; + rlc_am_nr_write_status_pdu(status, sn_size, &status_pdu); + + rlc1.write_pdu(status_pdu.msg, status_pdu.N_bytes); + + TESTASSERT_EQ(3 * pdu_size_first + 6 * pdu_size_continued, rlc1.get_buffer_state()); + return SRSRAN_SUCCESS; +} + +int rx_nack_range_with_so_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + std::string str = "Rx NACK range test (" + std::to_string(to_number(sn_size)) + " bit SN)"; + test_delimit_logger delimiter(str.c_str()); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + auto rlc_cnfg = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + rlc_cnfg.am_nr.t_poll_retx = -1; + if (not rlc1.configure(rlc_cnfg)) { + return -1; + } + + // after configuring entity + TESTASSERT(0 == rlc1.get_buffer_state()); + + int n_sdu_bufs = 5; + int n_pdu_bufs = 15; + + // Push 5 SDUs into RLC1 + std::vector sdu_bufs(n_sdu_bufs); + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (int i = 0; i < n_sdu_bufs; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = payload_size; // Give each buffer a size of 3 bytes + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_bufs[i])); + } + + uint32_t expected_buffer_state = (header_size + payload_size) * n_sdu_bufs; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + constexpr uint32_t so_size = 2; + constexpr uint32_t segment_size = 1; + uint32_t pdu_size_first = header_size + segment_size; + uint32_t pdu_size_continued = header_size + so_size + segment_size; + + // Read 15 PDUs from RLC1 + std::vector pdu_bufs(n_pdu_bufs); + for (int i = 0; i < n_pdu_bufs; i++) { + // First also test buffer state + uint32_t remaining_total_bytes = (payload_size * n_sdu_bufs) - (i * segment_size); + uint32_t remaining_full_sdus = remaining_total_bytes / payload_size; + uint32_t remaining_seg_bytes = remaining_total_bytes % payload_size; + + uint32_t buffer_state_full_sdus = (header_size + payload_size) * remaining_full_sdus; + uint32_t buffer_state_seg_sdu = remaining_seg_bytes == 0 ? 0 : (header_size + so_size + remaining_seg_bytes); + expected_buffer_state = buffer_state_full_sdus + buffer_state_seg_sdu; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + pdu_bufs[i] = srsran::make_byte_buffer(); + if (i == 0 || i == 3 || i == 6 || i == 9 || i == 12) { + // First segment, no SO + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_first); // 2 bytes for header + 1 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_first, len); + } else { + // Middle or last segment, SO present + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_continued); // 4 bytes for header + 1 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_continued, len); + } + } + + // Deliver dummy status report with nack range betwen PDU 6 and 10. + rlc_am_nr_status_pdu_t status(sn_size); + status.ack_sn = 5; + + rlc_status_nack_t nack = {}; + nack.nack_sn = 1; + nack.has_nack_range = true; + nack.nack_range = 3; + nack.has_so = true; + nack.so_start = 2; + nack.so_end = 0; + status.push_nack(nack); + byte_buffer_t status_pdu; + rlc_am_nr_write_status_pdu(status, sn_size, &status_pdu); + + rlc1.write_pdu(status_pdu.msg, status_pdu.N_bytes); + + TESTASSERT_EQ(2 * pdu_size_first + 3 * pdu_size_continued, rlc1.get_buffer_state()); + return SRSRAN_SUCCESS; +} + +int rx_nack_range_with_so_starting_with_full_sdu_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + std::string str = + "Rx NACK range test with SO starting with full SDU (" + std::to_string(to_number(sn_size)) + " bit SN)"; + test_delimit_logger delimiter(str.c_str()); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + auto rlc_cnfg = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + rlc_cnfg.am_nr.t_poll_retx = -1; + if (not rlc1.configure(rlc_cnfg)) { + return -1; + } + + // after configuring entity + TESTASSERT(0 == rlc1.get_buffer_state()); + + int n_sdu_bufs = 5; + int n_pdu_bufs = 15; + + // Push 5 SDUs into RLC1 + std::vector sdu_bufs(n_sdu_bufs); + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (int i = 0; i < n_sdu_bufs; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = payload_size; // Give each buffer a size of 3 bytes + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_bufs[i])); + } + + uint32_t expected_buffer_state = (header_size + payload_size) * n_sdu_bufs; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + constexpr uint32_t so_size = 2; + constexpr uint32_t segment_size = 1; + uint32_t pdu_size_whole = header_size + payload_size; + uint32_t pdu_size_first = header_size + segment_size; + uint32_t pdu_size_continued = header_size + so_size + segment_size; + + // Read 15 PDUs from RLC1 + std::vector pdu_bufs(n_pdu_bufs); + for (int i = 0; i < n_pdu_bufs; i++) { + // First also test buffer state + uint32_t remaining_total_bytes = (payload_size * n_sdu_bufs) - (i * segment_size); + uint32_t remaining_full_sdus = remaining_total_bytes / payload_size; + uint32_t remaining_seg_bytes = remaining_total_bytes % payload_size; + + uint32_t buffer_state_full_sdus = (header_size + payload_size) * remaining_full_sdus; + uint32_t buffer_state_seg_sdu = remaining_seg_bytes == 0 ? 0 : (header_size + so_size + remaining_seg_bytes); + expected_buffer_state = buffer_state_full_sdus + buffer_state_seg_sdu; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + pdu_bufs[i] = srsran::make_byte_buffer(); + if (i == 3) { + // Special handling for SDU SN=1 (i==3): send as a whole, not segmented + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_whole); // 2 bytes for header + 3 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_whole, len); + // update i to skip 2 segments + i += 2; + } else { + if (i == 0 || i == 6 || i == 9 || i == 12) { + // First segment, no SO + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_first); // 2 bytes for header + 1 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_first, len); + } else { + // Middle or last segment, SO present + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_continued); // 4 bytes for header + 1 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_continued, len); + } + } + } + + // Deliver dummy status report with nack range betwen PDU 4 and 10. + rlc_am_nr_status_pdu_t status(sn_size); + status.ack_sn = 5; + + rlc_status_nack_t nack = {}; + nack.nack_sn = 1; + nack.has_nack_range = true; + nack.nack_range = 3; + nack.has_so = true; + nack.so_start = 0; + nack.so_end = 0; + status.push_nack(nack); + byte_buffer_t status_pdu; + rlc_am_nr_write_status_pdu(status, sn_size, &status_pdu); + + rlc1.write_pdu(status_pdu.msg, status_pdu.N_bytes); + + TESTASSERT_EQ(pdu_size_whole + 2 * pdu_size_first + 2 * pdu_size_continued, rlc1.get_buffer_state()); + return SRSRAN_SUCCESS; +} + +int rx_nack_range_with_so_ending_with_full_sdu_test(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + std::string str = + "Rx NACK range test with SO starting with full SDU (" + std::to_string(to_number(sn_size)) + " bit SN)"; + test_delimit_logger delimiter(str.c_str()); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + auto rlc_cnfg = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + rlc_cnfg.am_nr.t_poll_retx = -1; + if (not rlc1.configure(rlc_cnfg)) { + return -1; + } + + // after configuring entity + TESTASSERT(0 == rlc1.get_buffer_state()); + + int n_sdu_bufs = 5; + int n_pdu_bufs = 15; + + // Push 5 SDUs into RLC1 + std::vector sdu_bufs(n_sdu_bufs); + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (int i = 0; i < n_sdu_bufs; i++) { + sdu_bufs[i] = srsran::make_byte_buffer(); + sdu_bufs[i]->msg[0] = i; // Write the index into the buffer + sdu_bufs[i]->N_bytes = payload_size; // Give each buffer a size of 3 bytes + sdu_bufs[i]->md.pdcp_sn = i; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_bufs[i])); + } + + uint32_t expected_buffer_state = (header_size + payload_size) * n_sdu_bufs; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + constexpr uint32_t so_size = 2; + constexpr uint32_t segment_size = 1; + uint32_t pdu_size_whole = header_size + payload_size; + uint32_t pdu_size_first = header_size + segment_size; + uint32_t pdu_size_continued = header_size + so_size + segment_size; + + // Read 15 PDUs from RLC1 + std::vector pdu_bufs(n_pdu_bufs); + for (int i = 0; i < n_pdu_bufs; i++) { + // First also test buffer state + uint32_t remaining_total_bytes = (payload_size * n_sdu_bufs) - (i * segment_size); + uint32_t remaining_full_sdus = remaining_total_bytes / payload_size; + uint32_t remaining_seg_bytes = remaining_total_bytes % payload_size; + + uint32_t buffer_state_full_sdus = (header_size + payload_size) * remaining_full_sdus; + uint32_t buffer_state_seg_sdu = remaining_seg_bytes == 0 ? 0 : (header_size + so_size + remaining_seg_bytes); + expected_buffer_state = buffer_state_full_sdus + buffer_state_seg_sdu; + TESTASSERT_EQ(expected_buffer_state, rlc1.get_buffer_state()); + + pdu_bufs[i] = srsran::make_byte_buffer(); + if (i == 9) { + // Special handling for SDU SN=3 (i==9): send as a whole, not segmented + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_whole); // 2 bytes for header + 3 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_whole, len); + // update i to skip 2 segments + i += 2; + } else { + if (i == 0 || i == 3 || i == 6 || i == 12) { + // First segment, no SO + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_first); // 2 bytes for header + 1 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_first, len); + } else { + // Middle or last segment, SO present + uint32_t len = rlc1.read_pdu(pdu_bufs[i]->msg, pdu_size_continued); // 4 bytes for header + 1 byte payload + pdu_bufs[i]->N_bytes = len; + TESTASSERT_EQ(pdu_size_continued, len); + } + } + } + + // Deliver dummy status report with nack range betwen PDU 6 and 12. + rlc_am_nr_status_pdu_t status(sn_size); + status.ack_sn = 5; + + rlc_status_nack_t nack = {}; + nack.nack_sn = 1; + nack.has_nack_range = true; + nack.nack_range = 3; + nack.has_so = true; + nack.so_start = 2; + nack.so_end = rlc_status_nack_t::so_end_of_sdu; + status.push_nack(nack); + byte_buffer_t status_pdu; + rlc_am_nr_write_status_pdu(status, sn_size, &status_pdu); + + rlc1.write_pdu(status_pdu.msg, status_pdu.N_bytes); + + TESTASSERT_EQ(1 * pdu_size_first + 3 * pdu_size_continued + pdu_size_whole, rlc1.get_buffer_state()); + return SRSRAN_SUCCESS; +} + +int out_of_order_status(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("out of order status report ({} bit SN)", to_number(sn_size)); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + + if (not rlc1.configure(rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)))) { + return -1; + } + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + + basic_test_tx(&rlc1, pdu_bufs, sn_size); + + // Status 1, ACK SN=2, NACK_SN = 1 + rlc_am_nr_status_pdu_t status1(sn_size); + status1.ack_sn = 2; + { + rlc_status_nack_t nack = {}; + nack.nack_sn = 1; + status1.push_nack(nack); + } + + // Status 2, ACK SN=5, NACK SN = 3 + rlc_am_nr_status_pdu_t status2(sn_size); + status2.ack_sn = 5; + { + rlc_status_nack_t nack = {}; + nack.nack_sn = 3; + status2.push_nack(nack); + } + + // pack into PDU + byte_buffer_t status1_pdu; + rlc_am_nr_write_status_pdu(status1, sn_size, &status1_pdu); + + // pack into PDU + byte_buffer_t status2_pdu; + rlc_am_nr_write_status_pdu(status2, sn_size, &status2_pdu); + + // Write status 2 to RLC1 + rlc1.write_pdu(status2_pdu.msg, status2_pdu.N_bytes); + + // Check TX_NEXT_ACK + { + rlc_am_nr_tx_state_t st = tx1->get_tx_state(); + TESTASSERT_EQ(3, st.tx_next_ack); // SN=3 was nacked on status report 2 + TESTASSERT_EQ(2, tx1->get_tx_window_utilization()); // 2 PDUs still in TX_WINDOW + } + // Write status 1 to RLC1 + rlc1.write_pdu(status1_pdu.msg, status1_pdu.N_bytes); + + // Check TX_NEXT_ACK + { + rlc_am_nr_tx_state_t st = tx1->get_tx_state(); + TESTASSERT_EQ(3, st.tx_next_ack); + TESTASSERT_EQ(2, tx1->get_tx_window_utilization()); + } + // Check statistics + rlc_bearer_metrics_t metrics1 = rlc1.get_metrics(); + + return SRSRAN_SUCCESS; +} + +// If we lose the status report +int lost_status_and_advanced_rx_window(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("Lost status report and advance RX window ({} bit SN)", to_number(sn_size)); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + auto cfg = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + if (not rlc1.configure(cfg)) { + return -1; + } + if (not rlc2.configure(cfg)) { + return -1; + } + uint32_t mod_nr = cardinality(cfg.am_nr.tx_sn_field_length); + + // Fill up the RX window + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (uint32_t sn = 0; sn < 10; ++sn) { + // Write SDU + unique_byte_buffer_t sdu_buf = srsran::make_byte_buffer(); + sdu_buf->msg[0] = sn; // Write the index into the buffer + sdu_buf->N_bytes = payload_size; // Give each buffer a size of 3 bytes + sdu_buf->md.pdcp_sn = sn; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_buf)); + + // Read PDU + unique_byte_buffer_t pdu_buf = srsran::make_byte_buffer(); + pdu_buf->N_bytes = rlc1.read_pdu(pdu_buf->msg, 100); + + // Write PDU into RLC 2 + // We receive all PDUs + rlc2.write_pdu(pdu_buf->msg, pdu_buf->N_bytes); + } + + // We got the polling bit, so we generate the status report. + TESTASSERT_EQ(3, rlc2.get_buffer_state()); + + // Read status PDU + { + unique_byte_buffer_t status_buf = srsran::make_byte_buffer(); + status_buf->N_bytes = rlc2.read_pdu(status_buf->msg, 3); + } + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + + // We do not write the status report into RLC 1 + // We step trought the timers to let t-PollRetransmission expire + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + for (int t = 0; t < 45; t++) { + timers.step_all(); + } + TESTASSERT_EQ(header_size + payload_size, rlc1.get_buffer_state()); + + // Read RETX of POLL_SN and check if it triggered the + // Status report + { + unique_byte_buffer_t pdu_buf = srsran::make_byte_buffer(); + pdu_buf->N_bytes = rlc1.read_pdu(pdu_buf->msg, 100); + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + rlc2.write_pdu(pdu_buf->msg, pdu_buf->N_bytes); + TESTASSERT_EQ(3, rlc2.get_buffer_state()); + } + + return SRSRAN_SUCCESS; +} + +// If we lose the status report +int do_status_0ms_status_prohibit(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(true, nullptr); + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("Do status 0ms status prohibit ({} bit SN)", to_number(sn_size)); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + auto cfg = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + cfg.am_nr.t_status_prohibit = 0; + if (not rlc1.configure(cfg)) { + return -1; + } + if (not rlc2.configure(cfg)) { + return -1; + } + uint32_t mod_nr = cardinality(cfg.am_nr.tx_sn_field_length); + + // Tx 5 PDUs + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (uint32_t sn = 0; sn < 5; ++sn) { + // Write SDU + unique_byte_buffer_t sdu_buf = srsran::make_byte_buffer(); + sdu_buf->msg[0] = sn; // Write the index into the buffer + sdu_buf->N_bytes = payload_size; // Give each buffer a size of 3 bytes + sdu_buf->md.pdcp_sn = sn; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_buf)); + + // Read PDU + unique_byte_buffer_t pdu_buf = srsran::make_byte_buffer(); + pdu_buf->N_bytes = rlc1.read_pdu(pdu_buf->msg, 100); + + // Write PDU into RLC 2 + // We receive all PDUs + rlc2.write_pdu(pdu_buf->msg, pdu_buf->N_bytes); + } + + // Read status PDU + { + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + unique_byte_buffer_t status_buf = srsran::make_byte_buffer(); + status_buf->N_bytes = rlc2.read_pdu(status_buf->msg, 1000); + } + + // Let timers run for t-PollRetransmit expire + { + for (int cnt = 0; cnt < 45; cnt++) { + timers.step_all(); + } + TESTASSERT_EQ(header_size + payload_size, rlc1.get_buffer_state()); + TESTASSERT_EQ(0, rlc2.get_buffer_state()); + unique_byte_buffer_t poll_buf = srsran::make_byte_buffer(); + poll_buf->N_bytes = rlc1.read_pdu(poll_buf->msg, 1000); + rlc2.write_pdu(poll_buf->msg, poll_buf->N_bytes); + TESTASSERT_NEQ(0, rlc2.get_buffer_state()); + } + + return SRSRAN_SUCCESS; +} + +int full_rx_window_t_reassembly_expiry(rlc_am_nr_sn_size_t sn_size) +{ + rlc_am_tester tester(false, nullptr); + timer_handler timers(8); + byte_buffer_t pdu_bufs[NBUFS]; + + auto& test_logger = srslog::fetch_basic_logger("TESTER "); + test_delimit_logger delimiter("Full RX window and t-Reassmbly expiry test ({} bit SN)", to_number(sn_size)); + rlc_am rlc1(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_1"), 1, &tester, &tester, &timers); + rlc_am rlc2(srsran_rat_t::nr, srslog::fetch_basic_logger("RLC_AM_2"), 1, &tester, &tester, &timers); + + rlc_am_nr_tx* tx1 = dynamic_cast(rlc1.get_tx()); + rlc_am_nr_rx* rx1 = dynamic_cast(rlc1.get_rx()); + rlc_am_nr_tx* tx2 = dynamic_cast(rlc2.get_tx()); + rlc_am_nr_rx* rx2 = dynamic_cast(rlc2.get_rx()); + + auto cfg = rlc_config_t::default_rlc_am_nr_config(to_number(sn_size)); + if (not rlc1.configure(cfg)) { + return -1; + } + if (not rlc2.configure(cfg)) { + return -1; + } + uint32_t mod_nr = cardinality(cfg.am_nr.tx_sn_field_length); + + // Fill up the RX window + constexpr uint32_t payload_size = 3; // Give the SDU the size of 3 bytes + uint32_t header_size = sn_size == rlc_am_nr_sn_size_t::size12bits ? 2 : 3; + for (uint32_t sn = 0; sn < am_window_size(sn_size); ++sn) { + // Write SDU + unique_byte_buffer_t sdu_buf = srsran::make_byte_buffer(); + sdu_buf->msg[0] = sn; // Write the index into the buffer + sdu_buf->N_bytes = payload_size; // Give each buffer a size of 3 bytes + sdu_buf->md.pdcp_sn = sn; // PDCP SN for notifications + rlc1.write_sdu(std::move(sdu_buf)); + + // Read PDU + unique_byte_buffer_t pdu_buf = srsran::make_byte_buffer(); + pdu_buf->N_bytes = rlc1.read_pdu(pdu_buf->msg, 100); + + // Write PDUs into RLC 2 + // Do not write SN=0 to fill up the RX window + if (sn != 0) { + rlc2.write_pdu(pdu_buf->msg, pdu_buf->N_bytes); + } + } + + // Step timers until reassambly timeout expires + for (int cnt = 0; cnt < 35; cnt++) { + timers.step_all(); + } + + // Read status PDU + { + TESTASSERT_EQ(0, rlc1.get_buffer_state()); + unique_byte_buffer_t status_buf = srsran::make_byte_buffer(); + status_buf->N_bytes = rlc2.read_pdu(status_buf->msg, 1000); + rlc1.write_pdu(status_buf->msg, status_buf->N_bytes); + TESTASSERT_EQ(header_size + payload_size, rlc1.get_buffer_state()); + } + // Check Rx_Status_Highest + { + rlc_am_nr_rx_state_t st = rx2->get_rx_state(); + TESTASSERT_EQ(2048, st.rx_highest_status); + } + + return SRSRAN_SUCCESS; +} + +int main() +{ + // Setup the log message spy to intercept error and warning log entries from RLC + if (!srslog::install_custom_sink(srsran::log_sink_message_spy::name(), + std::unique_ptr( + new srsran::log_sink_message_spy(srslog::get_default_log_formatter())))) { + return SRSRAN_ERROR; + } + + auto* spy = static_cast(srslog::find_sink(srsran::log_sink_message_spy::name())); + if (spy == nullptr) { + return SRSRAN_ERROR; + } + srslog::set_default_sink(*spy); + + auto& logger_rlc1 = srslog::fetch_basic_logger("RLC_AM_1", *spy, false); + auto& logger_rlc2 = srslog::fetch_basic_logger("RLC_AM_2", *spy, false); + logger_rlc1.set_hex_dump_max_size(100); + logger_rlc2.set_hex_dump_max_size(100); + logger_rlc1.set_level(srslog::basic_levels::debug); + logger_rlc2.set_level(srslog::basic_levels::debug); + + // start log back-end + srslog::init(); + std::initializer_list sn_sizes = {rlc_am_nr_sn_size_t::size12bits, + rlc_am_nr_sn_size_t::size18bits}; + for (auto sn_size : sn_sizes) { + TESTASSERT(window_checker_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(retx_segmentation_required_checker_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(basic_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(lost_pdu_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(lost_pdu_duplicated_nack_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(lost_pdus_trimmed_nack_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(clean_retx_queue_of_acked_sdus_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(basic_segmentation_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(segment_retx_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(segment_retx_and_loose_segments_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(retx_segment_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(handle_status_of_non_tx_last_segment(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(max_retx_lost_sdu_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(max_retx_lost_segments_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(discard_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(poll_pdu(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(poll_byte(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(poll_retx(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(poll_retx_expiry(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(rx_nack_range_no_so_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(rx_nack_range_with_so_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(rx_nack_range_with_so_starting_with_full_sdu_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(rx_nack_range_with_so_ending_with_full_sdu_test(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(out_of_order_status(sn_size) == SRSRAN_SUCCESS); + TESTASSERT(lost_status_and_advanced_rx_window(sn_size) == SRSRAN_SUCCESS); + } + TESTASSERT(full_rx_window_t_reassembly_expiry(rlc_am_nr_sn_size_t::size12bits) == SRSRAN_SUCCESS); + return SRSRAN_SUCCESS; +} diff --git a/lib/test/rlc/rlc_common_test.cc b/lib/test/rlc/rlc_common_test.cc index deed7bcd04..e242843d24 100644 --- a/lib/test/rlc/rlc_common_test.cc +++ b/lib/test/rlc/rlc_common_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/rlc/rlc_stress_test.cc b/lib/test/rlc/rlc_stress_test.cc index 5c3bd94020..62b2108204 100644 --- a/lib/test/rlc/rlc_stress_test.cc +++ b/lib/test/rlc/rlc_stress_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,6 +19,7 @@ * */ +#include "rlc_stress_test.h" #include "srsran/common/block_queue.h" #include "srsran/common/crash_handler.h" #include "srsran/common/rlc_pcap.h" @@ -34,458 +35,244 @@ #include #include -#define LOG_HEX_LIMIT (-1) - -#define PCAP_CRNTI (0x1001) -#define PCAP_TTI (666) - #include "srsran/common/mac_pcap.h" #include "srsran/mac/mac_sch_pdu_nr.h" -static std::unique_ptr pcap_handle = nullptr; -int write_pdu_to_pcap(const bool is_dl, const uint32_t lcid, const uint8_t* payload, const uint32_t len) +static std::unique_ptr pcap_handle = nullptr; +/*********************** + * MAC tester class + ***********************/ +void mac_dummy::run_thread() { - if (pcap_handle) { - srsran::byte_buffer_t tx_buffer; - srsran::mac_sch_pdu_nr tx_pdu; - tx_pdu.init_tx(&tx_buffer, len + 10); - tx_pdu.add_sdu(lcid, payload, len); - tx_pdu.pack(); - if (is_dl) { - pcap_handle->write_dl_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); - } else { - pcap_handle->write_ul_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); - } + srsran::move_task_t task; + while (run_enable) { + // Downlink direction first (RLC1->RLC2) + run_tti(rlc1, rlc2, true); - return SRSRAN_SUCCESS; - } - return SRSRAN_ERROR; -} + // UL direction (RLC2->RLC1) + run_tti(rlc2, rlc1, false); -using namespace std; -using namespace srsue; -using namespace srsran; -namespace bpo = boost::program_options; - -#define MIN_SDU_SIZE (5) -#define MAX_SDU_SIZE (1500) - -typedef struct { - std::string rat; - std::string mode; - int32_t sdu_size; - uint32_t test_duration_sec; - float pdu_drop_rate; - float pdu_cut_rate; - float pdu_duplicate_rate; - uint32_t sdu_gen_delay_usec; - uint32_t pdu_tx_delay_usec; - uint32_t log_level; - bool single_tx; - bool write_pcap; - uint32_t avg_opp_size; - bool random_opp; - bool zero_seed; - uint32_t nof_pdu_tti; - uint32_t max_retx; -} stress_test_args_t; - -void parse_args(stress_test_args_t* args, int argc, char* argv[]) -{ - // Command line only options - bpo::options_description general("General options"); - - general.add_options()("help,h", "Produce help message")("version,v", "Print version information and exit"); - - // clang-format off - - // Command line or config file options - bpo::options_description common("Configuration options"); - common.add_options() - ("rat", bpo::value(&args->rat)->default_value("LTE"), "The RLC version to use (LTE/NR)") - ("mode", bpo::value(&args->mode)->default_value("AM"), "Whether to test RLC acknowledged or unacknowledged mode (AM/UM for LTE) (UM6/UM12 for NR)") - ("duration", bpo::value(&args->test_duration_sec)->default_value(5), "Duration (sec)") - ("sdu_size", bpo::value(&args->sdu_size)->default_value(-1), "Size of SDUs (-1 means random)") - ("random_opp", bpo::value(&args->random_opp)->default_value(true), "Whether to generate random MAC opportunities") - ("avg_opp_size", bpo::value(&args->avg_opp_size)->default_value(1505), "Size of the MAC opportunity (if not random)") - ("sdu_gen_delay", bpo::value(&args->sdu_gen_delay_usec)->default_value(0), "SDU generation delay (usec)") - ("pdu_tx_delay", bpo::value(&args->pdu_tx_delay_usec)->default_value(0), "Delay in MAC for transfering PDU from tx'ing RLC to rx'ing RLC (usec)") - ("pdu_drop_rate", bpo::value(&args->pdu_drop_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped") - ("pdu_cut_rate", bpo::value(&args->pdu_cut_rate)->default_value(0.0), "Rate at which RLC PDUs are chopped in length") - ("pdu_duplicate_rate", bpo::value(&args->pdu_duplicate_rate)->default_value(0.0), "Rate at which RLC PDUs are duplicated") - ("loglevel", bpo::value(&args->log_level)->default_value((int)srslog::basic_levels::debug), "Log level (1=Error,2=Warning,3=Info,4=Debug)") - ("singletx", bpo::value(&args->single_tx)->default_value(false), "If set to true, only one node is generating data") - ("pcap", bpo::value(&args->write_pcap)->default_value(false), "Whether to write all RLC PDU to PCAP file") - ("zeroseed", bpo::value(&args->zero_seed)->default_value(false), "Whether to initialize random seed to zero") - ("max_retx", bpo::value(&args->max_retx)->default_value(32), "Maximum number of RLC retransmission attempts") - ("nof_pdu_tti", bpo::value(&args->nof_pdu_tti)->default_value(1), "Number of PDUs processed in a TTI"); - // clang-format on - - // these options are allowed on the command line - bpo::options_description cmdline_options; - cmdline_options.add(common).add(general); - - // parse the command line and store result in vm - bpo::variables_map vm; - bpo::store(bpo::command_line_parser(argc, argv).options(cmdline_options).run(), vm); - bpo::notify(vm); - - // help option was given - print usage and exit - if (vm.count("help") > 0) { - cout << "Usage: " << argv[0] << " [OPTIONS] config_file" << endl << endl; - cout << common << endl << general << endl; - exit(0); - } + // step timer + timers->step_all(); - if (args->log_level > 4) { - args->log_level = 4; - printf("Set log level to %d (%s)\n", - args->log_level, - srslog::basic_level_to_string(static_cast(args->log_level))); + if (pending_tasks.try_pop(&task)) { + task(); + } } - - // convert mode to upper case - for (auto& c : args->mode) { - c = toupper(c); + if (pending_tasks.try_pop(&task)) { + task(); } } -class mac_dummy : public srsran::thread +void mac_dummy::run_tti(srsue::rlc_interface_mac* tx_rlc, srsue::rlc_interface_mac* rx_rlc, bool is_dl) { -public: - mac_dummy(rlc_interface_mac* rlc1_, - rlc_interface_mac* rlc2_, - stress_test_args_t args_, - uint32_t lcid_, - timer_handler* timers_, - rlc_pcap* pcap_, - uint32_t seed_) : - run_enable(true), - rlc1(rlc1_), - rlc2(rlc2_), - args(args_), - pcap(pcap_), - lcid(lcid_), - timers(timers_), - logger(srslog::fetch_basic_logger("MAC", false)), - thread("MAC_DUMMY"), - real_dist(0.0, 1.0), - mt19937(seed_) - { - logger.set_level(static_cast(args.log_level)); - logger.set_hex_dump_max_size(LOG_HEX_LIMIT); - } + std::vector pdu_list; - void stop() - { - run_enable = false; - wait_thread_finish(); - } + // Run Tx + run_tx_tti(tx_rlc, rx_rlc, pdu_list); - void enqueue_task(srsran::move_task_t task) { pending_tasks.push(std::move(task)); } - -private: - void run_tx_tti(rlc_interface_mac* tx_rlc, rlc_interface_mac* rx_rlc, std::vector& pdu_list) - { - // Generate A number of MAC PDUs - for (uint32_t i = 0; i < args.nof_pdu_tti; i++) { - // Create PDU unique buffer - unique_byte_buffer_t pdu = srsran::make_byte_buffer(); - if (!pdu) { - printf("Fatal Error: Could not allocate PDU in mac_reader::run_thread\n"); - exit(-1); - } + // Reverse PDUs + std::reverse(pdu_list.begin(), pdu_list.end()); - // Get MAC PDU size - float factor = 1.0f; - if (args.random_opp) { - factor = 0.5f + real_dist(mt19937); - } - int opp_size = static_cast(args.avg_opp_size * factor); - - // Request data to transmit - uint32_t buf_state = tx_rlc->get_buffer_state(lcid); - if (buf_state > 0) { - pdu->N_bytes = tx_rlc->read_pdu(lcid, pdu->msg, opp_size); + // Run Rx + run_rx_tti(tx_rlc, rx_rlc, is_dl, pdu_list); +} - // Push PDU in the list - pdu_list.push_back(std::move(pdu)); - } +void mac_dummy::run_tx_tti(srsue::rlc_interface_mac* tx_rlc, + srsue::rlc_interface_mac* rx_rlc, + std::vector& pdu_list) +{ + // Generate A number of MAC PDUs + for (uint32_t i = 0; i < args.nof_pdu_tti; i++) { + // Create PDU unique buffer + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + printf("Fatal Error: Could not allocate PDU in %s\n", __FUNCTION__); + exit(-1); } - } - void run_rx_tti(rlc_interface_mac* tx_rlc, - rlc_interface_mac* rx_rlc, - bool is_dl, - std::vector& pdu_list) - { - // Sleep if necessary - if (args.pdu_tx_delay_usec > 0) { - std::this_thread::sleep_for(std::chrono::microseconds(args.pdu_tx_delay_usec)); + // Get MAC PDU size + float factor = 1.0f; + if (args.random_opp) { + factor = 0.5f + real_dist(mt19937); } + int opp_size = static_cast(args.avg_opp_size * factor); - auto it = pdu_list.begin(); // PDU iterator - bool skip_action = false; // Avoid discarding a duplicated or duplicating a discarded - - while (it != pdu_list.end()) { - // Get PDU unique buffer - unique_byte_buffer_t& pdu = *it; - - // Drop - float rnd = real_dist(mt19937); - if (std::isnan(rnd) || (((rnd > args.pdu_drop_rate) || skip_action) && pdu->N_bytes > 0)) { - uint32_t pdu_len = pdu->N_bytes; - - // Cut - if ((real_dist(mt19937) < args.pdu_cut_rate)) { - int cut_pdu_len = static_cast(pdu_len * real_dist(mt19937)); - logger.info("Cutting MAC PDU len (%d B -> %d B)", pdu_len, cut_pdu_len); - pdu_len = cut_pdu_len; - } - - // Write PDU in RX - rx_rlc->write_pdu(lcid, pdu->msg, pdu_len); - - // Write PCAP - write_pdu_to_pcap(is_dl, 4, pdu->msg, pdu_len); // Only handles NR rat - if (is_dl) { - pcap->write_dl_ccch(pdu->msg, pdu_len); - } else { - pcap->write_ul_ccch(pdu->msg, pdu_len); - } - } else { - logger.info(pdu->msg, pdu->N_bytes, "Dropping RLC PDU (%d B)", pdu->N_bytes); - skip_action = true; // Avoid drop duplicating this PDU - } + // Request data to transmit + uint32_t buf_state = tx_rlc->get_buffer_state(lcid); + if (buf_state > 0) { + pdu->N_bytes = tx_rlc->read_pdu(lcid, pdu->msg, opp_size); - // Duplicate - if (real_dist(mt19937) > args.pdu_duplicate_rate || skip_action) { - it++; - skip_action = false; // Allow action on the next PDU - } else { - logger.info(pdu->msg, pdu->N_bytes, "Duplicating RLC PDU (%d B)", pdu->N_bytes); - skip_action = true; // Avoid drop of this PDU - } + // Push PDU in the list + pdu_list.push_back(std::move(pdu)); } } +} - void run_tti(rlc_interface_mac* tx_rlc, rlc_interface_mac* rx_rlc, bool is_dl) - { - std::vector pdu_list; - - // Run Tx - run_tx_tti(tx_rlc, rx_rlc, pdu_list); +void mac_dummy::run_rx_tti(srsue::rlc_interface_mac* tx_rlc, + srsue::rlc_interface_mac* rx_rlc, + bool is_dl, + std::vector& pdu_list) +{ + // Sleep if necessary + if (args.pdu_tx_delay_usec > 0) { + std::this_thread::sleep_for(std::chrono::microseconds(args.pdu_tx_delay_usec)); + } - // Reverse PDUs - std::reverse(pdu_list.begin(), pdu_list.end()); + auto it = pdu_list.begin(); // PDU iterator + bool skip_action = false; // Avoid discarding a duplicated or duplicating a discarded - // Run Rx - run_rx_tti(tx_rlc, rx_rlc, is_dl, pdu_list); - } + while (it != pdu_list.end()) { + // Get PDU unique buffer + srsran::unique_byte_buffer_t& pdu = *it; - void run_thread() override - { - srsran::move_task_t task; - while (run_enable) { - // Downlink direction first (RLC1->RLC2) - run_tti(rlc1, rlc2, true); + // Drop + float rnd = real_dist(mt19937); + if (std::isnan(rnd) || (((rnd > args.pdu_drop_rate) || skip_action) && pdu->N_bytes > 0)) { + uint32_t pdu_len = pdu->N_bytes; - // UL direction (RLC2->RLC1) - run_tti(rlc2, rlc1, false); + // Cut + if ((real_dist(mt19937) < args.pdu_cut_rate)) { + int cut_pdu_len = static_cast(pdu_len * real_dist(mt19937)); + logger.info("Cutting MAC PDU len (%d B -> %d B)", pdu_len, cut_pdu_len); + pdu_len = cut_pdu_len; + } - // step timer - timers->step_all(); + // Write PDU in RX + rx_rlc->write_pdu(lcid, pdu->msg, pdu_len); - if (pending_tasks.try_pop(&task)) { - task(); + // Write PCAP + write_pdu_to_pcap(pcap_handle, is_dl, 4, pdu->msg, pdu_len); // Only handles NR rat + if (is_dl) { + pcap->write_dl_ccch(pdu->msg, pdu_len); + } else { + pcap->write_ul_ccch(pdu->msg, pdu_len); } + } else { + logger.info(pdu->msg, pdu->N_bytes, "Dropping RLC PDU (%d B)", pdu->N_bytes); + skip_action = true; // Avoid drop duplicating this PDU } - if (pending_tasks.try_pop(&task)) { - task(); + + // Duplicate + if (real_dist(mt19937) > args.pdu_duplicate_rate || skip_action) { + it++; + skip_action = false; // Allow action on the next PDU + } else { + logger.info(pdu->msg, pdu->N_bytes, "Duplicating RLC PDU (%d B)", pdu->N_bytes); + skip_action = true; // Avoid drop of this PDU } } +} - rlc_interface_mac* rlc1 = nullptr; - rlc_interface_mac* rlc2 = nullptr; - - std::atomic run_enable = {false}; - stress_test_args_t args = {}; - rlc_pcap* pcap = nullptr; - uint32_t lcid = 0; - srslog::basic_logger& logger; - srsran::timer_handler* timers = nullptr; - - srsran::block_queue pending_tasks; - - std::mt19937 mt19937; - std::uniform_real_distribution real_dist; -}; - -class rlc_tester : public pdcp_interface_rlc, public rrc_interface_rlc, public srsran::thread +/*********************** + * RLC tester class + ***********************/ +// PDCP interface +void rlc_tester::write_pdu(uint32_t rx_lcid, srsran::unique_byte_buffer_t sdu) { -public: - rlc_tester(rlc_interface_pdcp* rlc_pdcp_, - std::string name_, - stress_test_args_t args_, - uint32_t lcid_, - uint32_t seed_) : - logger(srslog::fetch_basic_logger(name_.c_str(), false)), - rlc_pdcp(rlc_pdcp_), - name(name_), - args(args_), - lcid(lcid_), - thread("RLC_TESTER"), - int_dist(MIN_SDU_SIZE, MAX_SDU_SIZE), - mt19937(seed_) - { - logger.set_level(srslog::basic_levels::error); - logger.set_hex_dump_max_size(LOG_HEX_LIMIT); + assert(rx_lcid == lcid); + if (args.mode != "AM") { + // Only AM will guarantee to deliver SDUs, take first byte as reference for other modes + next_expected_sdu = sdu->msg[0]; } - void stop() - { - run_enable = false; - wait_thread_finish(); + // check SDU content (consider faster alternative) + for (uint32_t i = 0; i < sdu->N_bytes; ++i) { + if (sdu->msg[i] != next_expected_sdu) { + logger.error(sdu->msg, + sdu->N_bytes, + "Received malformed SDU with size %d, expected data 0x%X", + sdu->N_bytes, + next_expected_sdu); + fprintf(stderr, "Received malformed SDU with size %d, expected data 0x%X\n", sdu->N_bytes, next_expected_sdu); + fprintf(stdout, "Received malformed SDU with size %d, expected data 0x%X\n", sdu->N_bytes, next_expected_sdu); + + std::this_thread::sleep_for(std::chrono::seconds(1)); // give some time to flush logs + exit(-1); + } } + next_expected_sdu += 1; + rx_pdus++; +} - // PDCP interface - void write_pdu(uint32_t rx_lcid, unique_byte_buffer_t sdu) - { - assert(rx_lcid == lcid); - if (args.mode != "AM") { - // Only AM will guarantee to deliver SDUs, take first byte as reference for other modes - next_expected_sdu = sdu->msg[0]; +void rlc_tester::run_thread() +{ + uint32_t pdcp_sn = 0; + uint32_t sdu_size = 0; + uint8_t payload = 0x0; // increment for each SDU + while (run_enable) { + // SDU queue is full, don't assign PDCP SN + if (rlc_pdcp->sdu_queue_is_full(lcid)) { + continue; } - // check SDU content (consider faster alternative) - for (uint32_t i = 0; i < sdu->N_bytes; ++i) { - if (sdu->msg[i] != next_expected_sdu) { - logger.error(sdu->msg, - sdu->N_bytes, - "Received malformed SDU with size %d, expected data 0x%X", - sdu->N_bytes, - next_expected_sdu); - fprintf(stderr, "Received malformed SDU with size %d\n", sdu->N_bytes); - fprintf(stdout, "Received malformed SDU with size %d\n", sdu->N_bytes); - std::this_thread::sleep_for(std::chrono::seconds(1)); // give some time to flush logs - exit(-1); - } + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (pdu == nullptr) { + printf("Error: Could not allocate PDU in rlc_tester::run_thread\n\n\n"); + // backoff for a bit + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + continue; } - next_expected_sdu += 1; - rx_pdus++; - } - void write_pdu_bcch_bch(unique_byte_buffer_t sdu) {} - void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} - void write_pdu_pcch(unique_byte_buffer_t sdu) {} - void write_pdu_mch(uint32_t lcid_, srsran::unique_byte_buffer_t sdu) {} - void notify_delivery(uint32_t lcid_, const srsran::pdcp_sn_vector_t& pdcp_sns) {} - void notify_failure(uint32_t lcid_, const srsran::pdcp_sn_vector_t& pdcp_sns) {} - - // RRC interface - void max_retx_attempted() - { - logger.error( - "Maximum number of RLC retransmission reached. Consider increasing threshold or lowering channel drop rate."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - exit(1); - } - void protocol_failure() - { - logger.error("RLC protocol error detected."); - std::this_thread::sleep_for(std::chrono::seconds(1)); - exit(1); - } - const char* get_rb_name(uint32_t rx_lcid) { return "DRB1"; } - - int get_nof_rx_pdus() { return rx_pdus; } - -private: - const static size_t max_pdcp_sn = 262143u; // 18bit SN - void run_thread() - { - uint32_t pdcp_sn = 0; - uint32_t sdu_size = 0; - uint8_t payload = 0x0; // increment for each SDU - while (run_enable) { - // SDU queue is full, don't assign PDCP SN - if (rlc_pdcp->sdu_queue_is_full(lcid)) { - continue; - } + pdu->md.pdcp_sn = pdcp_sn; - unique_byte_buffer_t pdu = srsran::make_byte_buffer(); - if (pdu == NULL) { - printf("Error: Could not allocate PDU in rlc_tester::run_thread\n\n\n"); - // backoff for a bit - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - continue; - } - pdu->md.pdcp_sn = pdcp_sn; - - // random or fixed SDU size - if (args.sdu_size < 1) { - sdu_size = int_dist(mt19937); - } else { - sdu_size = args.sdu_size; - } + // random or fixed SDU size + if (args.sdu_size < 1) { + sdu_size = int_dist(mt19937); + } else { + sdu_size = args.sdu_size; + } - for (uint32_t i = 0; i < sdu_size; i++) { - pdu->msg[i] = payload; - } - pdu->N_bytes = sdu_size; - payload++; + for (uint32_t i = 0; i < sdu_size; i++) { + pdu->msg[i] = payload; + } + pdu->N_bytes = sdu_size; + payload++; - rlc_pdcp->write_sdu(lcid, std::move(pdu)); - pdcp_sn = (pdcp_sn + 1) % max_pdcp_sn; - if (args.sdu_gen_delay_usec > 0) { - std::this_thread::sleep_for(std::chrono::microseconds(args.sdu_gen_delay_usec)); - } + rlc_pdcp->write_sdu(lcid, std::move(pdu)); + pdcp_sn = (pdcp_sn + 1) % max_pdcp_sn; + if (args.sdu_gen_delay_usec > 0) { + std::this_thread::sleep_for(std::chrono::microseconds(args.sdu_gen_delay_usec)); } } - - std::atomic run_enable = {true}; - - /// Tx uses thread-local PDCP SN to set SDU content, the Rx uses this variable to check received SDUs - uint8_t next_expected_sdu = 0; - uint64_t rx_pdus = 0; - uint32_t lcid = 0; - srslog::basic_logger& logger; - - std::string name; - - stress_test_args_t args = {}; - - rlc_interface_pdcp* rlc_pdcp = nullptr; // used by run_thread to push PDCP SDUs to RLC - - std::mt19937 mt19937; - std::uniform_int_distribution<> int_dist; -}; +} void stress_test(stress_test_args_t args) { + auto log_sink = + (args.log_filename == "stdout") ? srslog::create_stdout_sink() : srslog::create_file_sink(args.log_filename); + if (!log_sink) { + return; + } + srslog::log_channel* chan = srslog::create_log_channel("main_channel", *log_sink); + if (!chan) { + return; + } + srslog::set_default_sink(*log_sink); + auto& log1 = srslog::fetch_basic_logger("RLC_1", false); log1.set_level(static_cast(args.log_level)); - log1.set_hex_dump_max_size(LOG_HEX_LIMIT); + log1.set_hex_dump_max_size(args.log_hex_limit); auto& log2 = srslog::fetch_basic_logger("RLC_2", false); log2.set_level(static_cast(args.log_level)); - log2.set_hex_dump_max_size(LOG_HEX_LIMIT); + log2.set_hex_dump_max_size(args.log_hex_limit); - rlc_pcap pcap; - uint32_t lcid = 1; + srsran::rlc_pcap pcap; + uint32_t lcid = 1; - rlc_config_t cnfg_ = {}; + srsran::rlc_config_t cnfg_ = {}; if (args.rat == "LTE") { if (args.mode == "AM") { // config RLC AM bearer - cnfg_ = rlc_config_t::default_rlc_am_config(); + cnfg_ = srsran::rlc_config_t::default_rlc_am_config(); cnfg_.am.max_retx_thresh = args.max_retx; } else if (args.mode == "UM") { // config UM bearer - cnfg_ = rlc_config_t::default_rlc_um_config(); + cnfg_ = srsran::rlc_config_t::default_rlc_um_config(); } else if (args.mode == "TM") { // use default LCID in TM lcid = 0; } else { - cout << "Unsupported RLC mode " << args.mode << ", exiting." << endl; + std::cout << "Unsupported RLC mode " << args.mode << ", exiting." << std::endl; exit(-1); } @@ -494,11 +281,17 @@ void stress_test(stress_test_args_t args) } } else if (args.rat == "NR") { if (args.mode == "UM6") { - cnfg_ = rlc_config_t::default_rlc_um_nr_config(6); + cnfg_ = srsran::rlc_config_t::default_rlc_um_nr_config(6); } else if (args.mode == "UM12") { - cnfg_ = rlc_config_t::default_rlc_um_nr_config(12); + cnfg_ = srsran::rlc_config_t::default_rlc_um_nr_config(12); + } else if (args.mode == "AM12") { + cnfg_ = srsran::rlc_config_t::default_rlc_am_nr_config(12); + cnfg_.am_nr.max_retx_thresh = args.max_retx; + } else if (args.mode == "AM18") { + cnfg_ = srsran::rlc_config_t::default_rlc_am_nr_config(18); + cnfg_.am_nr.max_retx_thresh = args.max_retx; } else { - cout << "Unsupported RLC mode " << args.mode << ", exiting." << endl; + std::cout << "Unsupported RLC mode " << args.mode << ", exiting." << std::endl; exit(-1); } @@ -507,7 +300,7 @@ void stress_test(stress_test_args_t args) pcap_handle->open("rlc_stress_test_nr.pcap"); } } else { - cout << "Unsupported RAT mode " << args.rat << ", exiting." << endl; + std::cout << "Unsupported RAT mode " << args.rat << ", exiting." << std::endl; exit(-1); } @@ -518,10 +311,14 @@ void stress_test(stress_test_args_t args) seed = rd(); } + if (args.seed != 0) { + seed = args.seed; + } + srsran::timer_handler timers(8); - rlc rlc1(log1.id().c_str()); - rlc rlc2(log2.id().c_str()); + srsran::rlc rlc1(log1.id().c_str()); + srsran::rlc rlc2(log2.id().c_str()); rlc_tester tester1(&rlc1, "tester1", args, lcid, seed); rlc_tester tester2(&rlc2, "tester2", args, lcid, seed); @@ -536,7 +333,7 @@ void stress_test(stress_test_args_t args) rlc2.add_bearer(lcid, cnfg_); } - printf("Starting test ..\n"); + printf("Starting test ... Seed: %u\n", seed); tester1.start(7); if (!args.single_tx) { @@ -547,6 +344,8 @@ void stress_test(stress_test_args_t args) // wait until test is over std::this_thread::sleep_for(std::chrono::seconds(args.test_duration_sec)); + srslog::flush(); + fflush(stdout); printf("Test finished, tearing down ..\n"); // Stop RLC instances first to release blocking writers @@ -556,7 +355,6 @@ void stress_test(stress_test_args_t args) }); printf("RLC entities stopped.\n"); - // Stop upper layer writers tester1.stop(); tester2.stop(); @@ -568,10 +366,10 @@ void stress_test(stress_test_args_t args) pcap.close(); } - rlc_metrics_t metrics = {}; + srsran::rlc_metrics_t metrics = {}; rlc1.get_metrics(metrics, 1); - printf("RLC1 received %d SDUs in %ds (%.2f/s), Tx=%" PRIu64 " B, Rx=%" PRIu64 " B\n", + printf("RLC1 received %" PRIu64 " SDUs in %ds (%.2f/s), Tx=%" PRIu64 " B, Rx=%" PRIu64 " B\n", tester1.get_nof_rx_pdus(), args.test_duration_sec, static_cast(tester1.get_nof_rx_pdus() / args.test_duration_sec), @@ -580,7 +378,7 @@ void stress_test(stress_test_args_t args) rlc_bearer_metrics_print(metrics.bearer[lcid]); rlc2.get_metrics(metrics, 1); - printf("RLC2 received %d SDUs in %ds (%.2f/s), Tx=%" PRIu64 " B, Rx=%" PRIu64 " B\n", + printf("RLC2 received %" PRIu64 " SDUs in %ds (%.2f/s), Tx=%" PRIu64 " B, Rx=%" PRIu64 " B\n", tester2.get_nof_rx_pdus(), args.test_duration_sec, static_cast(tester2.get_nof_rx_pdus() / args.test_duration_sec), diff --git a/lib/test/rlc/rlc_stress_test.h b/lib/test/rlc/rlc_stress_test.h new file mode 100644 index 0000000000..96e413cf85 --- /dev/null +++ b/lib/test/rlc/rlc_stress_test.h @@ -0,0 +1,297 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/common/block_queue.h" +#include "srsran/common/crash_handler.h" +#include "srsran/common/rlc_pcap.h" +#include "srsran/common/test_common.h" +#include "srsran/common/threads.h" +#include "srsran/common/tsan_options.h" +#include "srsran/rlc/rlc.h" +#include +#include +#include +#include +#include +#include +#include + +#include "srsran/common/mac_pcap.h" +#include "srsran/mac/mac_sch_pdu_nr.h" + +inline int write_pdu_to_pcap(const std::unique_ptr& pcap_handle, + const bool is_dl, + const uint32_t lcid, + const uint8_t* payload, + const uint32_t len) +{ + const uint32_t PCAP_CRNTI = 0x1001; + const uint32_t PCAP_TTI = 666; + if (pcap_handle) { + srsran::byte_buffer_t tx_buffer; + srsran::mac_sch_pdu_nr tx_pdu; + tx_pdu.init_tx(&tx_buffer, len + 10); + tx_pdu.add_sdu(lcid, payload, len); + tx_pdu.pack(); + if (is_dl) { + pcap_handle->write_dl_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + } else { + pcap_handle->write_ul_crnti_nr(tx_buffer.msg, tx_buffer.N_bytes, PCAP_CRNTI, true, PCAP_TTI); + } + + return SRSRAN_SUCCESS; + } + return SRSRAN_ERROR; +} + +typedef struct { + std::string rat; + std::string mode; + int32_t sdu_size; + uint32_t test_duration_sec; + float pdu_drop_rate; + float pdu_cut_rate; + float pdu_duplicate_rate; + uint32_t sdu_gen_delay_usec; + uint32_t pdu_tx_delay_usec; + uint32_t log_level; + bool single_tx; + bool write_pcap; + uint32_t avg_opp_size; + bool random_opp; + bool zero_seed; + uint32_t seed; + uint32_t nof_pdu_tti; + uint32_t max_retx; + int32_t log_hex_limit; + std::string log_filename; + uint32_t min_sdu_size; + uint32_t max_sdu_size; +} stress_test_args_t; + +void parse_args(stress_test_args_t* args, int argc, char* argv[]) +{ + namespace bpo = boost::program_options; + // Command line only options + bpo::options_description general("General options"); + + general.add_options()("help,h", "Produce help message")("version,v", "Print version information and exit"); + + // clang-format off + + // Command line or config file options + bpo::options_description common("Configuration options"); + common.add_options() + ("rat", bpo::value(&args->rat)->default_value("LTE"), "The RLC version to use (LTE/NR)") + ("mode", bpo::value(&args->mode)->default_value("AM"), "Whether to test RLC acknowledged or unacknowledged mode (AM/UM for LTE) (UM6/UM12/AM12/AM18 for NR)") + ("duration", bpo::value(&args->test_duration_sec)->default_value(5), "Duration (sec)") + ("sdu_size", bpo::value(&args->sdu_size)->default_value(-1), "Size of SDUs (-1 means random)") + ("random_opp", bpo::value(&args->random_opp)->default_value(true), "Whether to generate random MAC opportunities") + ("avg_opp_size", bpo::value(&args->avg_opp_size)->default_value(1505), "Size of the MAC opportunity (if not random)") + ("sdu_gen_delay", bpo::value(&args->sdu_gen_delay_usec)->default_value(0), "SDU generation delay (usec)") + ("pdu_tx_delay", bpo::value(&args->pdu_tx_delay_usec)->default_value(0), "Delay in MAC for transfering PDU from tx'ing RLC to rx'ing RLC (usec)") + ("pdu_drop_rate", bpo::value(&args->pdu_drop_rate)->default_value(0.1), "Rate at which RLC PDUs are dropped") + ("pdu_cut_rate", bpo::value(&args->pdu_cut_rate)->default_value(0.0), "Rate at which RLC PDUs are chopped in length") + ("pdu_duplicate_rate", bpo::value(&args->pdu_duplicate_rate)->default_value(0.0), "Rate at which RLC PDUs are duplicated") + ("loglevel", bpo::value(&args->log_level)->default_value((int)srslog::basic_levels::debug), "Log level (1=Error,2=Warning,3=Info,4=Debug)") + ("log_filename", bpo::value(&args->log_filename)->default_value("stdout"), "Filename to save log to") + ("singletx", bpo::value(&args->single_tx)->default_value(false), "If set to true, only one node is generating data") + ("pcap", bpo::value(&args->write_pcap)->default_value(false), "Whether to write all RLC PDU to PCAP file") + ("zeroseed", bpo::value(&args->zero_seed)->default_value(false), "Whether to initialize random seed to zero") + ("seed", bpo::value(&args->seed)->default_value(0), "Seed to use in run. 0 means the seed is randomly generated") + ("max_retx", bpo::value(&args->max_retx)->default_value(32), "Maximum number of RLC retransmission attempts") + ("nof_pdu_tti", bpo::value(&args->nof_pdu_tti)->default_value(1), "Number of PDUs processed in a TTI") + ("log_hex_limit", bpo::value(&args->log_hex_limit)->default_value(-1), "Maximum bytes in hex log") + ("min_sdu_size", bpo::value(&args->min_sdu_size)->default_value(5), "Minimum SDU size") + ("max_sdu_size", bpo::value(&args->max_sdu_size)->default_value(1500), "Maximum SDU size"); + // clang-format on + + // these options are allowed on the command line + bpo::options_description cmdline_options; + cmdline_options.add(common).add(general); + + // parse the command line and store result in vm + bpo::variables_map vm; + bpo::store(bpo::command_line_parser(argc, argv).options(cmdline_options).run(), vm); + bpo::notify(vm); + + // help option was given - print usage and exit + if (vm.count("help") > 0) { + std::cout << "Usage: " << argv[0] << " [OPTIONS] config_file" << std::endl << std::endl; + std::cout << common << std::endl << general << std::endl; + exit(0); + } + + if (args->log_level > 4) { + args->log_level = 4; + printf("Set log level to %d (%s)\n", + args->log_level, + srslog::basic_level_to_string(static_cast(args->log_level))); + } + + // convert mode to upper case + for (auto& c : args->mode) { + c = toupper(c); + } +} + +class mac_dummy : public srsran::thread +{ +public: + mac_dummy(srsue::rlc_interface_mac* rlc1_, + srsue::rlc_interface_mac* rlc2_, + stress_test_args_t args_, + uint32_t lcid_, + srsran::timer_handler* timers_, + srsran::rlc_pcap* pcap_, + uint32_t seed_) : + run_enable(true), + rlc1(rlc1_), + rlc2(rlc2_), + args(args_), + pcap(pcap_), + lcid(lcid_), + timers(timers_), + logger(srslog::fetch_basic_logger("MAC", false)), + thread("MAC_DUMMY"), + real_dist(0.0, 1.0), + mt19937(seed_) + { + logger.set_level(static_cast(args.log_level)); + logger.set_hex_dump_max_size(args.log_hex_limit); + } + + void stop() + { + run_enable = false; + wait_thread_finish(); + } + + void enqueue_task(srsran::move_task_t task) { pending_tasks.push(std::move(task)); } + +private: + void run_thread() final; + + void run_tti(srsue::rlc_interface_mac* tx_rlc, srsue::rlc_interface_mac* rx_rlc, bool is_dl); + + void run_tx_tti(srsue::rlc_interface_mac* tx_rlc, + srsue::rlc_interface_mac* rx_rlc, + std::vector& pdu_list); + + void run_rx_tti(srsue::rlc_interface_mac* tx_rlc, + srsue::rlc_interface_mac* rx_rlc, + bool is_dl, + std::vector& pdu_list); + srsue::rlc_interface_mac* rlc1 = nullptr; + srsue::rlc_interface_mac* rlc2 = nullptr; + + std::atomic run_enable = {false}; + stress_test_args_t args = {}; + srsran::rlc_pcap* pcap = nullptr; + uint32_t lcid = 0; + srslog::basic_logger& logger; + srsran::timer_handler* timers = nullptr; + + srsran::block_queue pending_tasks; + + std::mt19937 mt19937; + std::uniform_real_distribution real_dist; +}; + +class rlc_tester : public srsue::pdcp_interface_rlc, public srsue::rrc_interface_rlc, public srsran::thread +{ +public: + rlc_tester(srsue::rlc_interface_pdcp* rlc_pdcp_, + std::string name_, + stress_test_args_t args_, + uint32_t lcid_, + uint32_t seed_) : + logger(srslog::fetch_basic_logger(name_.c_str(), false)), + rlc_pdcp(rlc_pdcp_), + name(name_), + args(args_), + lcid(lcid_), + thread("RLC_TESTER"), + int_dist(args_.min_sdu_size, args_.max_sdu_size), + mt19937(seed_) + { + logger.set_level(static_cast(args.log_level)); + logger.set_hex_dump_max_size(args_.log_hex_limit); + } + + void stop() + { + run_enable = false; + wait_thread_finish(); + } + + // PDCP interface + void write_pdu(uint32_t rx_lcid, srsran::unique_byte_buffer_t sdu) final; + void write_pdu_bcch_bch(srsran::unique_byte_buffer_t sdu) final {} + void write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t sdu) final {} + void write_pdu_pcch(srsran::unique_byte_buffer_t sdu) final {} + void write_pdu_mch(uint32_t lcid_, srsran::unique_byte_buffer_t sdu) final {} + void notify_delivery(uint32_t lcid_, const srsran::pdcp_sn_vector_t& pdcp_sns) final {} + void notify_failure(uint32_t lcid_, const srsran::pdcp_sn_vector_t& pdcp_sns) final {} + + // RRC interface + void max_retx_attempted() final + { + fprintf( + stderr, + "Maximum number of RLC retransmission reached. Consider increasing threshold or lowering channel drop rate."); + logger.error( + "Maximum number of RLC retransmission reached. Consider increasing threshold or lowering channel drop rate."); + std::this_thread::sleep_for(std::chrono::seconds(1)); + exit(1); + } + void protocol_failure() final + { + logger.error("RLC protocol error detected."); + std::this_thread::sleep_for(std::chrono::seconds(1)); + exit(1); + } + const char* get_rb_name(uint32_t lcid) final { return "DRB1"; } + + uint64_t get_nof_rx_pdus() const { return rx_pdus; } + +private: + const static size_t max_pdcp_sn = 262143U; // 18bit SN + void run_thread() final; + + std::atomic run_enable = {true}; + + /// Tx uses thread-local PDCP SN to set SDU content, the Rx uses this variable to check received SDUs + uint8_t next_expected_sdu = 0; + uint64_t rx_pdus = 0; + uint32_t lcid = 0; + srslog::basic_logger& logger; + + std::string name; + + stress_test_args_t args = {}; + + srsue::rlc_interface_pdcp* rlc_pdcp = nullptr; // used by run_thread to push PDCP SDUs to RLC + + std::mt19937 mt19937; + std::uniform_int_distribution<> int_dist; +}; + diff --git a/lib/test/rlc/rlc_test_common.h b/lib/test/rlc/rlc_test_common.h index 6b2b6ed9d7..c6e336eb57 100644 --- a/lib/test/rlc/rlc_test_common.h +++ b/lib/test/rlc/rlc_test_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,8 +23,10 @@ #define SRSRAN_RLC_TEST_COMMON_H #include "srsran/common/byte_buffer.h" +#include "srsran/common/rlc_pcap.h" #include "srsran/interfaces/ue_pdcp_interfaces.h" #include "srsran/interfaces/ue_rrc_interfaces.h" +#include "srsran/rlc/rlc_metrics.h" #include namespace srsran { @@ -32,10 +34,10 @@ namespace srsran { class rlc_um_tester : public srsue::pdcp_interface_rlc, public srsue::rrc_interface_rlc { public: - rlc_um_tester() {} + rlc_um_tester() = default; // PDCP interface - void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu) + void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu) final { // check length if (lcid != 3 && sdu->N_bytes != expected_sdu_len) { @@ -56,16 +58,16 @@ class rlc_um_tester : public srsue::pdcp_interface_rlc, public srsue::rrc_interf // srsran_vec_fprint_byte(stdout, sdu->msg, sdu->N_bytes); sdus.push_back(std::move(sdu)); } - void write_pdu_bcch_bch(unique_byte_buffer_t sdu) {} - void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} - void write_pdu_pcch(unique_byte_buffer_t sdu) {} - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) { sdus.push_back(std::move(sdu)); } - void notify_delivery(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) {} - void notify_failure(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) {} + void write_pdu_bcch_bch(unique_byte_buffer_t sdu) final {} + void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) final {} + void write_pdu_pcch(unique_byte_buffer_t sdu) final {} + void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) final { sdus.push_back(std::move(sdu)); } + void notify_delivery(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) final {} + void notify_failure(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) final {} // RRC interface - void max_retx_attempted() {} - void protocol_failure() {} + void max_retx_attempted() final {} + void protocol_failure() final {} const char* get_rb_name(uint32_t lcid) { return ""; } void set_expected_sdu_len(uint32_t len) { expected_sdu_len = len; } @@ -76,6 +78,65 @@ class rlc_um_tester : public srsue::pdcp_interface_rlc, public srsue::rrc_interf uint32_t expected_sdu_len = 0; }; +class rlc_am_tester : public srsue::pdcp_interface_rlc, public srsue::rrc_interface_rlc +{ +public: + explicit rlc_am_tester(bool save_sdus_, rlc_pcap* pcap_) : save_sdus(save_sdus_), pcap(pcap_) {} + + // PDCP interface + void write_pdu(uint32_t lcid, unique_byte_buffer_t sdu) + { + assert(lcid == 1); + if (save_sdus) { + sdus.push_back(std::move(sdu)); + } + } + void write_pdu_bcch_bch(unique_byte_buffer_t sdu) {} + void write_pdu_bcch_dlsch(unique_byte_buffer_t sdu) {} + void write_pdu_pcch(unique_byte_buffer_t sdu) {} + void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) {} + void notify_delivery(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn_vec) + { + assert(lcid == 1); + for (uint32_t pdcp_sn : pdcp_sn_vec) { + if (notified_counts.find(pdcp_sn) == notified_counts.end()) { + notified_counts[pdcp_sn] = 0; + } + notified_counts[pdcp_sn] += 1; + } + } + void notify_failure(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn_vec) + { + assert(lcid == 1); + // TODO + } + + // RRC interface + void max_retx_attempted() { max_retx_triggered = true; } + void protocol_failure() { protocol_failure_triggered = true; } + + const char* get_rb_name(uint32_t lcid) { return ""; } + + std::vector sdus; + rlc_pcap* pcap = nullptr; + bool max_retx_triggered = false; + bool protocol_failure_triggered = false; + bool save_sdus = true; + + std::map notified_counts; // Map of PDCP SNs to number of notifications +}; + +bool rx_is_tx(const rlc_bearer_metrics_t& rlc1_metrics, const rlc_bearer_metrics_t& rlc2_metrics) +{ + if (rlc1_metrics.num_tx_pdu_bytes != rlc2_metrics.num_rx_pdu_bytes) { + return false; + } + + if (rlc2_metrics.num_tx_pdu_bytes != rlc1_metrics.num_rx_pdu_bytes) { + return false; + } + return true; +} } // namespace srsran #endif // SRSRAN_RLC_TEST_COMMON_H diff --git a/lib/test/rlc/rlc_um_data_test.cc b/lib/test/rlc/rlc_um_data_test.cc index de8351984a..4614a1c186 100644 --- a/lib/test/rlc/rlc_um_data_test.cc +++ b/lib/test/rlc/rlc_um_data_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/rlc/rlc_um_nr_pdu_test.cc b/lib/test/rlc/rlc_um_nr_pdu_test.cc index 2cb486b810..212b453153 100644 --- a/lib/test/rlc/rlc_um_nr_pdu_test.cc +++ b/lib/test/rlc/rlc_um_nr_pdu_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/rlc/rlc_um_nr_test.cc b/lib/test/rlc/rlc_um_nr_test.cc index 08f9ad7216..ea815caf50 100644 --- a/lib/test/rlc/rlc_um_nr_test.cc +++ b/lib/test/rlc/rlc_um_nr_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -561,7 +561,7 @@ int rlc_um_nr_test8() return SRSRAN_SUCCESS; } -// Similar to rlc_um_nr_test9() but out-of-order PDUs have SNs (from multiple SDUs) +// Similar to rlc_um_nr_test8() but out-of-order PDUs have SNs (from multiple SDUs) int rlc_um_nr_test9() { rlc_um_nr_test_context1 ctxt; @@ -621,6 +621,8 @@ int rlc_um_nr_test9() TESTASSERT(*(ctxt.tester.sdus[i]->msg) == i); } + TESTASSERT(ctxt.timers.nof_running_timers() == 0); + return SRSRAN_SUCCESS; } @@ -676,13 +678,10 @@ int main(int argc, char** argv) return SRSRAN_ERROR; } -// temporarily disabling -#if 0 if (rlc_um_nr_test9()) { fprintf(stderr, "rlc_um_nr_test9() failed.\n"); return SRSRAN_ERROR; } -#endif #if PCAP pcap_handle->close(); diff --git a/lib/test/rlc/rlc_um_test.cc b/lib/test/rlc/rlc_um_test.cc index 12329816c0..9f3858ebc1 100644 --- a/lib/test/rlc/rlc_um_test.cc +++ b/lib/test/rlc/rlc_um_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/CMakeLists.txt b/lib/test/srslog/CMakeLists.txt index 26bb4b4ea5..31077fa057 100644 --- a/lib/test/srslog/CMakeLists.txt +++ b/lib/test/srslog/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/lib/test/srslog/any_test.cpp b/lib/test/srslog/any_test.cpp index ad4a1ac59d..f299c89399 100644 --- a/lib/test/srslog/any_test.cpp +++ b/lib/test/srslog/any_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/benchmarks/frontend_latency.cpp b/lib/test/srslog/benchmarks/frontend_latency.cpp index 5ac3f925de..dc6d50c8b6 100644 --- a/lib/test/srslog/benchmarks/frontend_latency.cpp +++ b/lib/test/srslog/benchmarks/frontend_latency.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/context_test.cpp b/lib/test/srslog/context_test.cpp index 5d31fecc8a..41012ec467 100644 --- a/lib/test/srslog/context_test.cpp +++ b/lib/test/srslog/context_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/event_trace_test.cpp b/lib/test/srslog/event_trace_test.cpp index b44fd9e2aa..d99f1f997d 100644 --- a/lib/test/srslog/event_trace_test.cpp +++ b/lib/test/srslog/event_trace_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/file_sink_test.cpp b/lib/test/srslog/file_sink_test.cpp index 91fbda8dc4..d7ce9e46c4 100644 --- a/lib/test/srslog/file_sink_test.cpp +++ b/lib/test/srslog/file_sink_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/file_test_utils.h b/lib/test/srslog/file_test_utils.h index 57405a56b3..96f9c50d25 100644 --- a/lib/test/srslog/file_test_utils.h +++ b/lib/test/srslog/file_test_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/file_utils_test.cpp b/lib/test/srslog/file_utils_test.cpp index a444e6d3a6..3ccc71268d 100644 --- a/lib/test/srslog/file_utils_test.cpp +++ b/lib/test/srslog/file_utils_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/json_formatter_test.cpp b/lib/test/srslog/json_formatter_test.cpp index bcc9b42104..20514ec625 100644 --- a/lib/test/srslog/json_formatter_test.cpp +++ b/lib/test/srslog/json_formatter_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/log_backend_test.cpp b/lib/test/srslog/log_backend_test.cpp index 0fd6c79aca..858cd58a80 100644 --- a/lib/test/srslog/log_backend_test.cpp +++ b/lib/test/srslog/log_backend_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/log_channel_test.cpp b/lib/test/srslog/log_channel_test.cpp index b6806cbc09..c2a2a5e4b3 100644 --- a/lib/test/srslog/log_channel_test.cpp +++ b/lib/test/srslog/log_channel_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/logger_test.cpp b/lib/test/srslog/logger_test.cpp index ffd62e4001..0632e3808b 100644 --- a/lib/test/srslog/logger_test.cpp +++ b/lib/test/srslog/logger_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/srslog_test.cpp b/lib/test/srslog/srslog_test.cpp index 484d5b51b0..a19871e92b 100644 --- a/lib/test/srslog/srslog_test.cpp +++ b/lib/test/srslog/srslog_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/syslog_sink_test.cpp b/lib/test/srslog/syslog_sink_test.cpp index 367e14106a..197b13236c 100644 --- a/lib/test/srslog/syslog_sink_test.cpp +++ b/lib/test/srslog/syslog_sink_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/test_dummies.h b/lib/test/srslog/test_dummies.h index ce849f20dc..ab20d1d120 100644 --- a/lib/test/srslog/test_dummies.h +++ b/lib/test/srslog/test_dummies.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/testing_helpers.h b/lib/test/srslog/testing_helpers.h index 32deb68010..cb687361a4 100644 --- a/lib/test/srslog/testing_helpers.h +++ b/lib/test/srslog/testing_helpers.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/lib/test/srslog/text_formatter_test.cpp b/lib/test/srslog/text_formatter_test.cpp index f68db4ef1e..532854712a 100644 --- a/lib/test/srslog/text_formatter_test.cpp +++ b/lib/test/srslog/text_formatter_test.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/run-clang-format-diff.sh b/run-clang-format-diff.sh index 4059b88e82..0524856ccc 100755 --- a/run-clang-format-diff.sh +++ b/run-clang-format-diff.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsenb/CMakeLists.txt b/srsenb/CMakeLists.txt index 0592697622..95b8b663d1 100644 --- a/srsenb/CMakeLists.txt +++ b/srsenb/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 8a897bc13c..51f7b58062 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -106,8 +106,9 @@ 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) -# mac_filename: File path to use for packet captures +# 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. # s1ap_filename: File name where to save the PCAP. # @@ -118,16 +119,17 @@ rx_gain = 40 # client_port Client IP address for MAC network trace (default: 5847) ##################################################################### [pcap] -enable = false -filename = /tmp/enb.pcap -s1ap_enable = false -s1ap_filename = /tmp/enb_s1ap.pcap +#enable = false +#filename = /tmp/enb_mac.pcap +#nr_filename = /tmp/enb_mac_nr.pcap +#s1ap_enable = false +#s1ap_filename = /tmp/enb_s1ap.pcap -mac_net_enable = false -bind_ip = 0.0.0.0 -bind_port = 5687 -client_ip = 127.0.0.1 -client_port = 5847 +#mac_net_enable = false +#bind_ip = 0.0.0.0 +#bind_port = 5687 +#client_ip = 127.0.0.1 +#client_port = 5847 ##################################################################### # Log configuration @@ -218,6 +220,23 @@ enable = false #nr_pdsch_mcs=28 #nr_pusch_mcs=28 +##################################################################### +# Slicing configuration +# enable_eMBB Enables enhanced mobile broadband (eMBB) slice in the gNodeB +# enable_URLLC Enables Ultra Reliable Low Latency Communications (URLLC) slice in the gNodeB +# enable_MIoT Enables Massive Internet of Things (MIoT) slice in the gNodeB +# eMBB_sd eMBB slice differentiator +# URLLC_sd URLLC slice differentiator +# MIoT_sd MIoT slice differentiator +##################################################################### +[slicing] +#enable_eMBB = false +#enable_URLLC = false +#enable_MIoT = false +#eMBB_sd = 1 +#URLLC_sd = 1 +#MIoT_sd = 1 + ##################################################################### # eMBMS configuration options # @@ -324,6 +343,50 @@ enable = false #fd_hz = -750.0 #init_time_s = 0.0 +##################################################################### +# CFR configuration options +# +# The CFR module provides crest factor reduction for the transmitted signal. +# +# enable: Enable or disable the CFR. Default: disabled +# +# mode: manual: CFR threshold is set by cfr_manual_thres (default). +# auto_ema: CFR threshold is adaptive based on the signal PAPR. Power avg. with Exponential Moving Average. +# The time constant of the averaging can be tweaked with the ema_alpha parameter. +# auto_cma: CFR threshold is adaptive based on the signal PAPR. Power avg. with Cumulative Moving Average. +# Use with care, as CMA's increasingly slow response may be unsuitable for most use cases. +# +# strength: Ratio between amplitude-limited vs unprocessed signal (0 to 1). Default: 1 +# manual_thres: Fixed manual clipping threshold for CFR manual mode. Default: 0.5 +# auto_target_papr: Signal PAPR target (in dB) in CFR auto modes. output PAPR can be higher due to peak smoothing. Default: 8 +# ema_alpha: Alpha coefficient for the power average in auto_ema mode. Default: 1/7 +# +##################################################################### +[cfr] +#enable = false +#mode = manual +#manual_thres = 0.5 +#strength = 1 +#auto_target_papr = 8 +#ema_alpha = 0.0143 + +# E2 Agent configuration options +# +# ric_ip: IP address of the RIC controller +# ric_port: Port of the RIC controller +# ric_bind_ip: Local IP address to bind for RIC connection +# ric_bind_port: Local port to bind for RIC connection +# max_ric_setup_retries: Maximum amount of retries to setup the RIC connection. If this value is exceeded, an alarm is written to the log. -1 means infinity. +# ric_connect_timer: Connection Retry Timer for RIC connection (seconds) +##################################################################### +[e2_agent] +#enable = false +#ric_ip = 127.0.0.1 +#ric_port = 36421 +#ric_bind_ip = 127.0.0.1 +#ric_bind_port = 36425 +#max_ric_setup_retries = -1 +#ric_connect_timer = 10 ##################################################################### # Expert configuration options @@ -344,7 +407,6 @@ enable = false # tracing_filename: File path to use for tracing information # tracing_buffcapacity: Maximum capacity in bytes the tracing framework can store # stdout_ts_enable: Prints once per second the timestamp into stdout -# pregenerate_signals: Pregenerate uplink signals after attach. Improves CPU performance # tx_amplitude: Transmit amplitude factor (set 0-1 to reduce PAPR) # rrc_inactivity_timer Inactivity timeout used to remove UE context from RRC (in milliseconds) # max_mac_dl_kos: Maximum number of consecutive KOs in DL before triggering the UE's release (default: 100) @@ -359,7 +421,9 @@ enable = false # ts1_reloc_overall_timeout: S1AP TS 36.413 TS1RelocOverall Expiry Timeout value in milliseconds # 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] #pusch_max_its = 8 # These are half iterations @@ -378,7 +442,6 @@ enable = false #tracing_filename = /tmp/enb_tracing.log #tracing_buffcapacity = 1000000 #stdout_ts_enable = false -#pregenerate_signals = false #tx_amplitude = 0.6 #rrc_inactivity_timer = 30000 #max_mac_dl_kos = 100 @@ -395,3 +458,7 @@ enable = false #ts1_reloc_overall_timeout = 10000 #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/cfg_parser.h b/srsenb/hdr/cfg_parser.h index 845ca5a9ee..61cd3d41d1 100644 --- a/srsenb/hdr/cfg_parser.h +++ b/srsenb/hdr/cfg_parser.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/common/common_enb.h b/srsenb/hdr/common/common_enb.h index 431719dda9..ccfa6b28bd 100644 --- a/srsenb/hdr/common/common_enb.h +++ b/srsenb/hdr/common/common_enb.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/common/rnti_pool.h b/srsenb/hdr/common/rnti_pool.h index 6332b226be..64b98bd38a 100644 --- a/srsenb/hdr/common/rnti_pool.h +++ b/srsenb/hdr/common/rnti_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 479e28089b..baec790324 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -40,8 +40,10 @@ #include "srsenb/hdr/stack/enb_stack_base.h" #include "srsenb/hdr/stack/rrc/rrc_config.h" -#include "srsenb/hdr/stack/gnb_stack_nr.h" #include "srsenb/hdr/stack/mac/sched_interface.h" +#include "srsgnb/hdr/stack/gnb_stack_nr.h" +#include "srsgnb/hdr/stack/ric/e2_agent.h" +#include "srsgnb/hdr/stack/ric/e2ap_ric_subscription.h" #include "srsran/common/bcd_helpers.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/interfaces_common.h" @@ -121,6 +123,7 @@ struct all_args_t { general_args_t general; phy_args_t phy; stack_args_t stack; + e2_agent_args_t e2_agent; gnb_stack_args_t nr_stack; }; @@ -145,12 +148,16 @@ class enb : public enb_metrics_interface, enb_command_interface, enb_time_interf void print_pool(); + bool enable_e2_agent(srsenb::e2_interface_metrics* e2_metrics); + // eNodeB metrics interface bool get_metrics(enb_metrics_t* m) override; // eNodeB command interface void cmd_cell_gain(uint32_t cell_id, float gain) override; + void cmd_cell_measure() override; + void toggle_padding() override; void tti_clock() override; @@ -176,6 +183,7 @@ class enb : public enb_metrics_interface, enb_command_interface, enb_time_interf std::unique_ptr nr_stack = nullptr; std::unique_ptr radio = nullptr; std::unique_ptr phy = nullptr; + std::unique_ptr _e2_agent = nullptr; // System metrics processor. srsran::sys_metrics_processor sys_proc; diff --git a/srsenb/hdr/metrics_csv.h b/srsenb/hdr/metrics_csv.h index 3b5fa2ec10..734bc83293 100644 --- a/srsenb/hdr/metrics_csv.h +++ b/srsenb/hdr/metrics_csv.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -41,11 +41,10 @@ namespace srsenb { class metrics_csv : public srsran::metrics_listener { public: - metrics_csv(std::string filename); + metrics_csv(std::string filename, enb_metrics_interface* enb_); ~metrics_csv(); void set_metrics(const enb_metrics_t& m, const uint32_t period_usec); - void set_handle(enb_metrics_interface* enb_); void stop(); private: diff --git a/srsenb/hdr/metrics_e2.h b/srsenb/hdr/metrics_e2.h new file mode 100644 index 0000000000..4bbe8c1bd1 --- /dev/null +++ b/srsenb/hdr/metrics_e2.h @@ -0,0 +1,60 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +/****************************************************************************** + * File: metrics_e2.h + * Description: Metrics class passing to E2 agent. + *****************************************************************************/ + +#ifndef SRSENB_METRICS_E2_H +#define SRSENB_METRICS_E2_H + +#include "srsran/interfaces/e2_metrics_interface.h" +#include "srsran/interfaces/enb_metrics_interface.h" +#include +#include +#include +#include + +#define METRICS_BUFFER_SIZE 20 +namespace srsenb { + +class metrics_e2 : public srsran::metrics_listener, public e2_interface_metrics +{ +public: + metrics_e2(enb_metrics_interface* enb_) : do_print(false) {} + void set_metrics(const enb_metrics_t& m, const uint32_t period_usec) override; + bool pull_metrics(enb_metrics_t* m) override; + void stop() override{}; + + bool register_e2sm(e2sm* sm) override; + bool unregister_e2sm(e2sm* sm) override; + +private: + std::atomic do_print = {false}; + std::queue metrics_queue; + enb_metrics_interface* enb = nullptr; + std::vector e2sm_vec; +}; + +} // namespace srsenb + +#endif // SRSENB_METRICS_STDOUT_H diff --git a/srsenb/hdr/metrics_json.h b/srsenb/hdr/metrics_json.h index a6401a8f83..0924323d55 100644 --- a/srsenb/hdr/metrics_json.h +++ b/srsenb/hdr/metrics_json.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/metrics_stdout.h b/srsenb/hdr/metrics_stdout.h index 9bdc26bc35..4dace236db 100644 --- a/srsenb/hdr/metrics_stdout.h +++ b/srsenb/hdr/metrics_stdout.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/parser.h b/srsenb/hdr/parser.h index bb24a61315..cf15a495f0 100644 --- a/srsenb/hdr/parser.h +++ b/srsenb/hdr/parser.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -452,11 +452,11 @@ int number_to_enum(EnumType& enum_val, Setting& root) ss << val; fprintf(stderr, "Invalid option: %s for enum field \"%s\"\n", ss.str().c_str(), root.getName()); ss.str(""); - ss << EnumType((typename EnumType::options)0).to_number(); + ss << std::to_string(EnumType((typename EnumType::options)0).to_number()); fprintf(stderr, "Valid options: %s", ss.str().c_str()); for (uint32_t i = 1; i < EnumType::nof_types; i++) { ss.str(""); - ss << EnumType((typename EnumType::options)i).to_number(); + ss << std::to_string(EnumType((typename EnumType::options)i).to_number()); fprintf(stderr, ", %s", ss.str().c_str()); } fprintf(stderr, "\n"); diff --git a/srsenb/hdr/phy/enb_phy_base.h b/srsenb/hdr/phy/enb_phy_base.h index 767dfde0bf..aa7ee541d5 100644 --- a/srsenb/hdr/phy/enb_phy_base.h +++ b/srsenb/hdr/phy/enb_phy_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -47,6 +47,8 @@ class enb_phy_base virtual void get_metrics(std::vector& m) = 0; virtual void cmd_cell_gain(uint32_t cell_idx, float gain_db) = 0; + + virtual void cmd_cell_measure() = 0; }; } // namespace srsenb diff --git a/srsenb/hdr/phy/lte/cc_worker.h b/srsenb/hdr/phy/lte/cc_worker.h index 03b47f5fd8..5fa00d0976 100644 --- a/srsenb/hdr/phy/lte/cc_worker.h +++ b/srsenb/hdr/phy/lte/cc_worker.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -109,7 +109,7 @@ class cc_worker void metrics_read(phy_metrics_t* metrics); void metrics_dl(uint32_t mcs); void metrics_ul(uint32_t mcs, float rssi, float sinr, float turbo_iters); - void metrics_ul_pucch(float sinr); + void metrics_ul_pucch(float rssi, float ni, float sinr); uint32_t get_rnti() const { return rnti; } private: diff --git a/srsenb/hdr/phy/lte/sf_worker.h b/srsenb/hdr/phy/lte/sf_worker.h index 2ffa4601ed..6fe6618d95 100644 --- a/srsenb/hdr/phy/lte/sf_worker.h +++ b/srsenb/hdr/phy/lte/sf_worker.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/phy/lte/worker_pool.h b/srsenb/hdr/phy/lte/worker_pool.h index f657dd109c..fffdc16717 100644 --- a/srsenb/hdr/phy/lte/worker_pool.h +++ b/srsenb/hdr/phy/lte/worker_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/phy/nr/slot_worker.h b/srsenb/hdr/phy/nr/slot_worker.h index 4928c87199..fc94c364d8 100644 --- a/srsenb/hdr/phy/nr/slot_worker.h +++ b/srsenb/hdr/phy/nr/slot_worker.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/phy/nr/worker_pool.h b/srsenb/hdr/phy/nr/worker_pool.h index 6f702b0749..bf90d96a46 100644 --- a/srsenb/hdr/phy/nr/worker_pool.h +++ b/srsenb/hdr/phy/nr/worker_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/phy/phy.h b/srsenb/hdr/phy/phy.h index b4a8ca6181..9e56f1d4dc 100644 --- a/srsenb/hdr/phy/phy.h +++ b/srsenb/hdr/phy/phy.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -75,6 +75,7 @@ class phy final : public enb_phy_base, void get_metrics(std::vector& metrics) override; void cmd_cell_gain(uint32_t cell_id, float gain_db) override; + void cmd_cell_measure() override; void radio_overflow() override{}; void radio_failure() override{}; diff --git a/srsenb/hdr/phy/phy_common.h b/srsenb/hdr/phy/phy_common.h index db03829d44..565d483e2d 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -100,8 +100,8 @@ class phy_common : public srsran::phy_common_interface if (cc_idx < cell_list_lte.size()) { ret = cell_list_lte[cc_idx].cell.nof_ports; - } else if (cc_idx == 1 && !cell_list_nr.empty()) { - // one RF port for basic NSA config + } else if ((cc_idx == 0 || cc_idx == 1) && !cell_list_nr.empty()) { + // one RF port for basic NSA/SA config ret = 1; } @@ -131,7 +131,7 @@ class phy_common : public srsran::phy_common_interface cc_idx -= cell_list_lte.size(); if (cc_idx < cell_list_nr.size()) { - ret = cell_list_nr[cc_idx].ul_freq_hz; + ret = cell_list_nr[cc_idx].carrier.ul_center_frequency_hz; } return ret; @@ -146,7 +146,22 @@ class phy_common : public srsran::phy_common_interface cc_idx -= cell_list_lte.size(); if (cc_idx < cell_list_nr.size()) { - ret = cell_list_nr[cc_idx].dl_freq_hz; + ret = cell_list_nr[cc_idx].carrier.dl_center_frequency_hz; + } + + return ret; + } + double get_ssb_freq_hz(uint32_t cc_idx) + { + double ret = 0.0; + + if (cc_idx < cell_list_lte.size()) { + ret = cell_list_lte[cc_idx].dl_freq_hz; + } + + cc_idx -= cell_list_lte.size(); + if (cc_idx < cell_list_nr.size()) { + ret = cell_list_nr[cc_idx].carrier.ssb_center_freq_hz; } return ret; @@ -175,6 +190,45 @@ class phy_common : public srsran::phy_common_interface return c; } + void set_cell_measure_trigger() + { + // Trigger on LTE cell + for (auto it_lte = cell_list_lte.begin(); it_lte != cell_list_lte.end(); ++it_lte) { + it_lte->dl_measure = true; + } + + // Trigger on NR cell + for (auto it_nr = cell_list_nr.begin(); it_nr != cell_list_nr.end(); ++it_nr) { + it_nr->dl_measure = true; + } + } + + bool get_cell_measure_trigger(uint32_t cc_idx) + { + if (cc_idx < cell_list_lte.size()) { + return cell_list_lte.at(cc_idx).dl_measure; + } + + cc_idx -= cell_list_lte.size(); + if (cc_idx < cell_list_nr.size()) { + return cell_list_nr.at(cc_idx).dl_measure; + } + + return false; + } + + void clear_cell_measure_trigger(uint32_t cc_idx) + { + if (cc_idx < cell_list_lte.size()) { + cell_list_lte.at(cc_idx).dl_measure = false; + } + + cc_idx -= cell_list_lte.size(); + if (cc_idx < cell_list_nr.size()) { + cell_list_nr.at(cc_idx).dl_measure = false; + } + } + void set_cell_gain(uint32_t cell_id, float gain_db) { // Find LTE cell @@ -217,6 +271,11 @@ class phy_common : public srsran::phy_common_interface return 0.0f; } + // Common CFR configuration + srsran_cfr_cfg_t cfr_config = {}; + void set_cfr_config(srsran_cfr_cfg_t cfr_cfg) { cfr_config = cfr_cfg; } + srsran_cfr_cfg_t get_cfr_config() { return cfr_config; } + // Common Physical Uplink DMRS configuration srsran_refsignal_dmrs_pusch_cfg_t dmrs_pusch_cfg = {}; @@ -250,8 +309,9 @@ class phy_common : public srsran::phy_common_interface std::mutex cell_gain_mutex; bool have_mtch_stop = false; - pthread_mutex_t mtch_mutex = {}; - pthread_cond_t mtch_cvar = {}; + std::mutex mtch_mutex; + std::mutex mbsfn_mutex; + std::condition_variable mtch_cvar; srsran::phy_cfg_mbsfn_t mbsfn = {}; bool sib13_configured = false; bool mcch_configured = false; diff --git a/srsenb/hdr/phy/phy_interfaces.h b/srsenb/hdr/phy/phy_interfaces.h index 2ee29c74ea..4a03f16632 100644 --- a/srsenb/hdr/phy/phy_interfaces.h +++ b/srsenb/hdr/phy/phy_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,6 +22,7 @@ #ifndef SRSENB_PHY_INTERFACES_H_ #define SRSENB_PHY_INTERFACES_H_ +#include "srsgnb/hdr/phy/phy_nr_interfaces.h" #include "srsran/asn1/rrc/rr_common.h" #include "srsran/common/interfaces_common.h" #include "srsran/phy/channel/channel.h" @@ -40,29 +41,25 @@ struct phy_cell_cfg_t { uint32_t root_seq_idx; uint32_t num_ra_preambles; float gain_db; + bool dl_measure; }; -struct phy_cell_cfg_nr_t { - srsran_carrier_nr_t carrier; - uint32_t rf_port; - uint32_t cell_id; - double dl_freq_hz; - double ul_freq_hz; - uint32_t root_seq_idx; - uint32_t num_ra_preambles; - float gain_db; - srsran_pdcch_cfg_nr_t pdcch = {}; ///< Common CORESET and Search Space configuration - srsran_pdsch_cfg_t pdsch = {}; - srsran_prach_cfg_t prach = {}; -}; +typedef std::vector phy_cell_cfg_list_t; -typedef std::vector phy_cell_cfg_list_t; -typedef std::vector phy_cell_cfg_list_nr_t; +struct cfr_args_t { + bool enable = false; + srsran_cfr_mode_t mode = SRSRAN_CFR_THR_MANUAL; + float manual_thres = 0.5f; + float strength = 1.0f; + float auto_target_papr = 8.0f; + float ema_alpha = 1.0f / (float)SRSRAN_CP_NORM_NSYMB; +}; struct phy_args_t { std::string type; srsran::phy_log_args_t log; + float rx_gain_offset = 62; float max_prach_offset_us = 10; uint32_t pusch_max_its = 10; uint32_t nr_pusch_max_its = 10; @@ -79,8 +76,7 @@ struct phy_args_t { bool extended_cp = false; srsran::channel::args_t dl_channel_args; srsran::channel::args_t ul_channel_args; - - srsran::vnf_args_t vnf_args; + cfr_args_t cfr_args; }; struct phy_cfg_t { @@ -94,6 +90,8 @@ struct phy_cfg_t { asn1::rrc::pusch_cfg_common_s pusch_cnfg; asn1::rrc::pucch_cfg_common_s pucch_cnfg; asn1::rrc::srs_ul_cfg_common_c srs_ul_cnfg; + + srsran_cfr_cfg_t cfr_config; }; } // namespace srsenb diff --git a/srsenb/hdr/phy/phy_metrics.h b/srsenb/hdr/phy/phy_metrics.h index 8307f55bb0..46783f6d9f 100644 --- a/srsenb/hdr/phy/phy_metrics.h +++ b/srsenb/hdr/phy/phy_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,24 +22,30 @@ #ifndef SRSENB_PHY_METRICS_H #define SRSENB_PHY_METRICS_H +#include + namespace srsenb { // PHY metrics per user struct ul_metrics_t { - float n; - float pusch_sinr; - float pucch_sinr; - float rssi; - float turbo_iters; - float mcs; - int n_samples; - int n_samples_pucch; + float n; + float pusch_sinr; + float pusch_rssi; + int64_t pusch_tpc; + float pucch_sinr; + float pucch_rssi; + float pucch_ni; + float turbo_iters; + float mcs; + int n_samples; + int n_samples_pucch; }; struct dl_metrics_t { float mcs; - int n_samples; + int64_t pucch_tpc; + int n_samples; }; struct phy_metrics_t { diff --git a/srsenb/hdr/phy/phy_ue_db.h b/srsenb/hdr/phy/phy_ue_db.h index 9d77d2a116..71f2d3bc61 100644 --- a/srsenb/hdr/phy/phy_ue_db.h +++ b/srsenb/hdr/phy/phy_ue_db.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/phy/prach_worker.h b/srsenb/hdr/phy/prach_worker.h index 6b302686cd..300e1ebb17 100644 --- a/srsenb/hdr/phy/prach_worker.h +++ b/srsenb/hdr/phy/prach_worker.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/phy/txrx.h b/srsenb/hdr/phy/txrx.h index 4d53cb058d..d0304887be 100644 --- a/srsenb/hdr/phy/txrx.h +++ b/srsenb/hdr/phy/txrx.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/enb_stack_base.h b/srsenb/hdr/stack/enb_stack_base.h index 9b9ae95c63..d8939ad149 100644 --- a/srsenb/hdr/stack/enb_stack_base.h +++ b/srsenb/hdr/stack/enb_stack_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index da268b69dc..f3e0ce7464 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -158,8 +158,6 @@ class enb_stack_lte final : public enb_stack_base, stack_args_t args = {}; rrc_cfg_t rrc_cfg = {}; - srsran::socket_manager rx_sockets; - srslog::basic_logger& mac_logger; srslog::basic_logger& rlc_logger; srslog::basic_logger& pdcp_logger; diff --git a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h b/srsenb/hdr/stack/mac/common/base_ue_buffer_manager.h similarity index 89% rename from srsenb/hdr/stack/mac/common/ue_buffer_manager.h rename to srsenb/hdr/stack/mac/common/base_ue_buffer_manager.h index 015befa473..5a9765cfb7 100644 --- a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h +++ b/srsenb/hdr/stack/mac/common/base_ue_buffer_manager.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,8 +19,8 @@ * */ -#ifndef SRSRAN_UE_BUFFER_MANAGER_H -#define SRSRAN_UE_BUFFER_MANAGER_H +#ifndef SRSRAN_BASE_UE_BUFFER_MANAGER_H +#define SRSRAN_BASE_UE_BUFFER_MANAGER_H #include "sched_config.h" #include "srsran/adt/span.h" @@ -35,7 +35,7 @@ namespace srsenb { * Class to handle UE DL+UL RLC and MAC buffers state */ template -class ue_buffer_manager +class base_ue_buffer_manager { protected: const static uint32_t MAX_LC_ID = isNR ? (srsran::MAX_NR_NOF_BEARERS - 1) : srsran::MAX_LTE_LCID; @@ -46,15 +46,15 @@ class ue_buffer_manager constexpr static uint32_t pbr_infinity = -1; public: - explicit ue_buffer_manager(uint16_t rnti, srslog::basic_logger& logger_); + explicit base_ue_buffer_manager(uint16_t rnti, srslog::basic_logger& logger_); // Bearer configuration void config_lcids(srsran::const_span bearer_cfg_list); void config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg); // Buffer Status update - void ul_bsr(uint32_t lcg_id, uint32_t val); - void dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue); + int ul_bsr(uint32_t lcg_id, uint32_t val); + int dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue); // Configuration getters uint16_t get_rnti() const { return rnti; } @@ -89,6 +89,8 @@ class ue_buffer_manager static bool is_lcg_valid(uint32_t lcg) { return lcg <= MAX_LCG_ID; } protected: + ~base_ue_buffer_manager() = default; + bool config_lcid_internal(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg); srslog::basic_logger& logger; @@ -108,4 +110,4 @@ class ue_buffer_manager } // namespace srsenb -#endif // SRSRAN_UE_BUFFER_MANAGER_H +#endif // SRSRAN_BASE_UE_BUFFER_MANAGER_H diff --git a/srsenb/hdr/stack/mac/common/mac_metrics.h b/srsenb/hdr/stack/mac/common/mac_metrics.h index 9c55ccc06a..bc73265da7 100644 --- a/srsenb/hdr/stack/mac/common/mac_metrics.h +++ b/srsenb/hdr/stack/mac/common/mac_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -30,6 +30,7 @@ namespace srsenb { /// MAC metrics per user struct mac_ue_metrics_t { uint16_t rnti; + uint32_t pci; uint32_t nof_tti; uint32_t cc_idx; int tx_pkts; @@ -44,16 +45,18 @@ struct mac_ue_metrics_t { float dl_ri; float dl_pmi; float phr; + float dl_cqi_offset; + float ul_snr_offset; // NR-only UL PHY metrics - float pusch_sinr; - float pucch_sinr; - float ul_rssi; - float fec_iters; - float dl_mcs; - int dl_mcs_samples; - float ul_mcs; - int ul_mcs_samples; + float pusch_sinr; + float pucch_sinr; + float ul_rssi; + float fec_iters; + float dl_mcs; + int dl_mcs_samples; + float ul_mcs; + int ul_mcs_samples; }; /// MAC misc information for each cc. struct mac_cc_info_t { diff --git a/srsenb/hdr/stack/mac/common/sched_config.h b/srsenb/hdr/stack/mac/common/sched_config.h index e01ec00a1a..b90dde0105 100644 --- a/srsenb/hdr/stack/mac/common/sched_config.h +++ b/srsenb/hdr/stack/mac/common/sched_config.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index c97b321831..7e1612fdc7 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -119,6 +119,16 @@ class mac final : public mac_interface_phy_lte, public mac_interface_rlc, public uint16_t allocate_ue(uint32_t enb_cc_idx); bool is_valid_rnti_unprotected(uint16_t rnti); + /* helper function for PDCCH orders */ + /** + * @brief Checks if the current RACH is a RACH triggered by a PDCCH order. + * + * @param[in] preamble_idx RACH preamble idx + * @param rnti is the rnti where the crnti of the RACH is written + * @return true if this is a RACH triggered by a PDCCH order, otherwise it returns false + */ + bool is_pending_pdcch_order_prach(const uint32_t preamble_idx, uint16_t& rnti); + srslog::basic_logger& logger; // We use a rwlock in MAC to allow multiple workers to access MAC simultaneously. No conflicts will happen since @@ -190,6 +200,9 @@ class mac final : public mac_interface_phy_lte, public mac_interface_rlc, public // Number of rach preambles detected for a cc. std::vector detected_rachs; + // PDCCH order + std::vector pending_po_prachs = {}; + // Softbuffer pool std::unique_ptr > softbuffer_pool; }; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h deleted file mode 100644 index 35cc083ce5..0000000000 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#ifndef SRSRAN_SCHED_NR_INTERFACE_H -#define SRSRAN_SCHED_NR_INTERFACE_H - -#include "srsran/adt/bounded_bitset.h" -#include "srsran/adt/bounded_vector.h" -#include "srsran/adt/optional.h" -#include "srsran/adt/span.h" -#include "srsran/common/common_nr.h" -#include "srsran/common/phy_cfg_nr.h" -#include "srsran/common/slot_point.h" -#include "srsran/interfaces/gnb_interfaces.h" -#include "srsran/phy/phch/dci_nr.h" - -namespace srsenb { - -const static size_t SCHED_NR_MAX_CARRIERS = 4; -const static uint16_t SCHED_NR_INVALID_RNTI = 0; -const static size_t SCHED_NR_MAX_NOF_RBGS = 18; -const static size_t SCHED_NR_MAX_TB = 1; -const static size_t SCHED_NR_MAX_HARQ = SRSRAN_DEFAULT_HARQ_PROC_DL_NR; -const static size_t SCHED_NR_MAX_BWP_PER_CELL = 2; -const static size_t SCHED_NR_MAX_LCID = srsran::MAX_NR_NOF_BEARERS; -const static size_t SCHED_NR_MAX_LC_GROUP = 7; - -struct sched_nr_ue_cc_cfg_t { - bool active = false; - uint32_t cc = 0; -}; - -struct sched_nr_ue_cfg_t { - uint32_t maxharq_tx = 4; - srsran::bounded_vector carriers; - std::array ue_bearers = {}; - srsran::phy_cfg_nr_t phy_cfg = {}; -}; - -class sched_nr_interface -{ -public: - static const size_t MAX_GRANTS = mac_interface_phy_nr::MAX_GRANTS; - - ///// Configuration ///// - - struct pdsch_td_res_alloc { - uint8_t k0 = 0; // 0..32 - uint8_t k1 = 4; // 0..32 - }; - using pdsch_td_res_alloc_list = srsran::bounded_vector; - struct pusch_td_res_alloc { - uint8_t k2 = 4; // 0..32 - }; - using pusch_td_res_alloc_list = srsran::bounded_vector; - - struct bwp_cfg_t { - uint32_t start_rb = 0; - uint32_t rb_width = 100; - srsran_pdcch_cfg_nr_t pdcch = {}; - srsran_sch_hl_cfg_nr_t pdsch = {}; - srsran_sch_hl_cfg_nr_t pusch = {}; - uint32_t rar_window_size = 10; // See TS 38.331, ra-ResponseWindow: {1, 2, 4, 8, 10, 20, 40, 80} - uint32_t numerology_idx = 0; - }; - - struct cell_cfg_t { - srsran_carrier_nr_t carrier = {}; - srsran_duplex_config_nr_t duplex = {}; - srsran::phy_cfg_nr_t::ssb_cfg_t ssb = {}; - srsran::bounded_vector bwps{1}; // idx0 for BWP-common - }; - - struct sched_args_t { - bool pdsch_enabled = true; - bool pusch_enabled = true; - bool auto_refill_buffer = false; - int fixed_dl_mcs = 28; - int fixed_ul_mcs = 28; - std::string logger_name = "MAC-NR"; - }; - - using ue_cc_cfg_t = sched_nr_ue_cc_cfg_t; - using ue_cfg_t = sched_nr_ue_cfg_t; - - ////// RA procedure ////// - - struct rar_info_t { - uint32_t preamble_idx; // is this the RAPID? - uint32_t ofdm_symbol_idx; - uint32_t freq_idx; - uint32_t ta_cmd; - uint16_t temp_crnti; - uint32_t msg3_size = 7; - slot_point prach_slot; - }; - struct msg3_grant_t { - rar_info_t data; - srsran_dci_ul_nr_t msg3_dci = {}; - }; - struct rar_t { - srsran::bounded_vector grants; - }; - - ///// Sched Result ///// - - using dl_sched_t = mac_interface_phy_nr::dl_sched_t; - using ul_res_t = mac_interface_phy_nr::ul_sched_t; - - using sched_rar_list_t = srsran::bounded_vector; - struct dl_res_t { - sched_rar_list_t& rar; - dl_sched_t& dl_sched; - dl_res_t(sched_rar_list_t& rar_, dl_sched_t& dl_sched_) : rar(rar_), dl_sched(dl_sched_) {} - }; - - virtual ~sched_nr_interface() = default; - virtual int config(const sched_args_t& sched_cfg, srsran::const_span ue_cfg) = 0; - virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; - virtual void ue_rem(uint16_t rnti) = 0; - virtual bool ue_exists(uint16_t rnti) = 0; - virtual int run_slot(slot_point slot_rx, uint32_t cc, dl_res_t& result) = 0; - virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_res_t& result) = 0; - - virtual void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) = 0; - virtual void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) = 0; - virtual void ul_sr_info(uint16_t rnti) = 0; - virtual void ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) = 0; -}; - -} // namespace srsenb - -#endif // SRSRAN_SCHED_NR_INTERFACE_H diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h b/srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h deleted file mode 100644 index f9074e4c7f..0000000000 --- a/srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#ifndef SRSRAN_SCHED_NR_PDCCH_H -#define SRSRAN_SCHED_NR_PDCCH_H - -#include "srsenb/hdr/stack/mac/nr/sched_nr_cfg.h" -#include "srsran/adt/bounded_bitset.h" -#include "srsran/adt/bounded_vector.h" -#include "srsran/phy/common/phy_common_nr.h" -#include "srsran/phy/phch/dci.h" - -namespace srsenb { - -namespace sched_nr_impl { - -using coreset_bitmap = srsran::bounded_bitset; - -enum class pdcch_grant_type_t { sib, rar, dl_data, ul_data }; - -class slot_ue; - -using bwp_cfg_t = sched_nr_interface::bwp_cfg_t; - -class coreset_region -{ -public: - coreset_region(const bwp_params_t& bwp_cfg_, - uint32_t coreset_id_, - uint32_t slot_idx, - pdcch_dl_list_t& pdcch_dl_list, - pdcch_ul_list_t& pdcch_ul_list); - void reset(); - - /** - * Allocates DCI space in PDCCH, avoiding in the process collisions with other users - * @param pdcch_grant_type_t allocation type (e.g. DL data, UL data, SIB) - * @param aggr_idx Aggregation level index (0..4) - * @param user UE object or null in case of broadcast/RAR/paging allocation - * @return if the allocation was successful - */ - bool alloc_dci(pdcch_grant_type_t alloc_type, uint32_t aggr_idx, uint32_t search_space_id, slot_ue* user = nullptr); - - void rem_last_dci(); - - uint32_t get_td_symbols() const { return coreset_cfg->duration; } - uint32_t get_freq_resources() const { return nof_freq_res; } - uint32_t nof_cces() const { return nof_freq_res * get_td_symbols(); } - size_t nof_allocs() const { return dfs_tree.size(); } - -private: - const srsran_coreset_t* coreset_cfg; - uint32_t coreset_id; - uint32_t slot_idx; - uint32_t nof_freq_res = 0; - const bwp_cce_pos_list& rar_cce_list; - - // List of PDCCH grants - struct alloc_record { - uint32_t aggr_idx; - uint32_t ss_id; - uint32_t idx; - pdcch_grant_type_t alloc_type; - slot_ue* ue; - }; - srsran::bounded_vector dci_list; - pdcch_dl_list_t& pdcch_dl_list; - pdcch_ul_list_t& pdcch_ul_list; - - // DFS decision tree of PDCCH grants - struct tree_node { - uint16_t rnti = SRSRAN_INVALID_RNTI; - uint32_t record_idx = 0; - uint32_t dci_pos_idx = 0; - srsran_dci_location_t dci_pos = {0, 0}; - /// Accumulation of all PDCCH masks for the current solution (DFS path) - coreset_bitmap total_mask, current_mask; - }; - using alloc_tree_dfs_t = std::vector; - alloc_tree_dfs_t dfs_tree, saved_dfs_tree; - - srsran::span get_cce_loc_table(const alloc_record& record) const; - bool alloc_dfs_node(const alloc_record& record, uint32_t dci_idx); - bool get_next_dfs(); -}; - -} // namespace sched_nr_impl - -} // namespace srsenb - -#endif // SRSRAN_SCHED_NR_PDCCH_H diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h deleted file mode 100644 index eb4621bb72..0000000000 --- a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#ifndef SRSRAN_SCHED_NR_UE_H -#define SRSRAN_SCHED_NR_UE_H - -#include "sched_nr_cfg.h" -#include "sched_nr_harq.h" -#include "sched_nr_interface.h" -#include "srsenb/hdr/stack/mac/common/mac_metrics.h" -#include "srsenb/hdr/stack/mac/common/ue_buffer_manager.h" -#include "srsran/adt/circular_map.h" -#include "srsran/adt/move_callback.h" -#include "srsran/adt/pool/cached_alloc.h" - -namespace srsenb { - -namespace sched_nr_impl { - -class ue_carrier; - -class slot_ue -{ -public: - slot_ue() = default; - explicit slot_ue(uint16_t rnti_, slot_point slot_rx_, uint32_t cc); - slot_ue(slot_ue&&) noexcept = default; - slot_ue& operator=(slot_ue&&) noexcept = default; - bool empty() const { return rnti == SCHED_NR_INVALID_RNTI; } - void release() { rnti = SCHED_NR_INVALID_RNTI; } - - uint16_t rnti = SCHED_NR_INVALID_RNTI; - slot_point slot_rx; - uint32_t cc = SCHED_NR_MAX_CARRIERS; - - // UE parameters common to all sectors - int dl_pending_bytes = 0, ul_pending_bytes = 0; - - // UE parameters that are sector specific - const bwp_ue_cfg* cfg = nullptr; - harq_entity* harq_ent = nullptr; - slot_point pdcch_slot; - slot_point pdsch_slot; - slot_point pusch_slot; - slot_point uci_slot; - uint32_t dl_cqi = 0; - uint32_t ul_cqi = 0; - dl_harq_proc* h_dl = nullptr; - ul_harq_proc* h_ul = nullptr; - srsran_uci_cfg_nr_t uci_cfg = {}; -}; - -class ue_carrier -{ -public: - ue_carrier(uint16_t rnti, const ue_cfg_t& cfg, const cell_params_t& cell_params_); - void set_cfg(const ue_cfg_t& ue_cfg); - - /// Called after CC Feedback has been processed - void new_slot(slot_point slot_tx); - - slot_ue try_reserve(slot_point pdcch_slot, uint32_t dl_harq_bytes, uint32_t ul_harq_bytes); - - const uint16_t rnti; - const uint32_t cc; - - // Channel state - uint32_t dl_cqi = 1; - uint32_t ul_cqi = 0; - - harq_entity harq_ent; - - // metrics - mac_ue_metrics_t metrics = {}; - std::mutex metrics_mutex; - -private: - bwp_ue_cfg bwp_cfg; - const cell_params_t& cell_params; -}; - -class ue -{ -public: - ue(uint16_t rnti, const ue_cfg_t& cfg, const sched_params& sched_cfg_); - - void new_slot(slot_point pdcch_slot); - - slot_ue try_reserve(slot_point pdcch_slot, uint32_t cc); - - void set_cfg(const ue_cfg_t& cfg); - const ue_cfg_t& cfg() const { return ue_cfg; } - - void rlc_buffer_state(uint32_t lcid, uint32_t newtx, uint32_t retx) { buffers.dl_buffer_state(lcid, newtx, retx); } - void ul_bsr(uint32_t lcg, uint32_t bsr_val) { buffers.ul_bsr(lcg, bsr_val); } - void ul_sr_info() { last_sr_slot = last_pdcch_slot - TX_ENB_DELAY; } - - bool has_ca() const - { - return ue_cfg.carriers.size() > 1 and std::count_if(ue_cfg.carriers.begin() + 1, - ue_cfg.carriers.end(), - [](const ue_cc_cfg_t& cc) { return cc.active; }) > 0; - } - uint32_t pcell_cc() const { return ue_cfg.carriers[0].cc; } - - ue_buffer_manager buffers; - std::array, SCHED_NR_MAX_CARRIERS> carriers; - -private: - const uint16_t rnti; - const sched_params& sched_cfg; - - slot_point last_pdcch_slot; - slot_point last_sr_slot; - int ul_pending_bytes = 0, dl_pending_bytes = 0; - - ue_cfg_t ue_cfg; -}; - -using ue_map_t = rnti_map_t >; -using slot_ue_map_t = rnti_map_t; - -} // namespace sched_nr_impl - -} // namespace srsenb - -#endif // SRSRAN_SCHED_NR_UE_H diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h b/srsenb/hdr/stack/mac/nr/sched_nr_worker.h deleted file mode 100644 index f9c9364b15..0000000000 --- a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h +++ /dev/null @@ -1,150 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#ifndef SRSRAN_SCHED_NR_WORKER_H -#define SRSRAN_SCHED_NR_WORKER_H - -#include "sched_nr_cell.h" -#include "sched_nr_cfg.h" -#include "sched_nr_grant_allocator.h" -#include "sched_nr_ue.h" -#include "srsran/adt/circular_array.h" -#include "srsran/adt/optional.h" -#include "srsran/adt/pool/cached_alloc.h" -#include "srsran/adt/span.h" -#include -#include - -namespace srsenb { - -struct mac_metrics_t; - -namespace sched_nr_impl { - -class slot_cc_worker -{ -public: - using feedback_callback_t = srsran::move_callback; - - explicit slot_cc_worker(serv_cell_manager& sched); - - void run(slot_point pdcch_slot, ue_map_t& ue_db_); - bool running() const { return slot_rx.valid(); } - - void enqueue_cc_event(srsran::move_callback ev); - - /// Enqueue feedback directed at a given UE in a given cell - void enqueue_cc_feedback(uint16_t rnti, feedback_callback_t fdbk); - -private: - /// Run all pending feedback. This should be called at the beginning of a TTI - void run_feedback(ue_map_t& ue_db); - - void alloc_dl_ues(); - void alloc_ul_ues(); - void postprocess_decisions(); - - const cell_params_t& cfg; - serv_cell_manager& cell; - srslog::basic_logger& logger; - - slot_point slot_rx; - bwp_slot_allocator bwp_alloc; - - // Process of UE cell-specific feedback - struct feedback_t { - uint16_t rnti; - feedback_callback_t fdbk; - }; - std::mutex feedback_mutex; - srsran::deque pending_feedback, tmp_feedback_to_run; - srsran::deque > pending_events, tmp_events_to_run; - - slot_ue_map_t slot_ues; -}; - -class sched_worker_manager -{ - struct slot_worker_ctxt { - std::mutex slot_mutex; // lock of all workers of the same slot. - std::condition_variable cvar; - slot_point slot_rx; - int nof_workers_waiting = 0; - std::atomic worker_count{0}; // variable shared across slot_cc_workers - std::vector workers; - }; - -public: - explicit sched_worker_manager(ue_map_t& ue_db_, - const sched_params& cfg_, - srsran::span > cells_); - sched_worker_manager(const sched_worker_manager&) = delete; - sched_worker_manager(sched_worker_manager&&) = delete; - ~sched_worker_manager(); - - void run_slot(slot_point slot_tx, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res); - - void get_metrics(mac_metrics_t& metrics); - - void enqueue_event(uint16_t rnti, srsran::move_callback ev); - void enqueue_cc_event(uint32_t cc, srsran::move_callback ev); - void enqueue_cc_feedback(uint16_t rnti, uint32_t cc, slot_cc_worker::feedback_callback_t fdbk) - { - cc_worker_list[cc]->worker.enqueue_cc_feedback(rnti, std::move(fdbk)); - } - -private: - void update_ue_db(slot_point slot_tx, bool locked_context); - void get_metrics_nolocking(mac_metrics_t& metrics); - bool save_sched_result(slot_point pdcch_slot, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res); - - const sched_params& cfg; - ue_map_t& ue_db; - srsran::span > cells; - srslog::basic_logger& logger; - - struct ue_event_t { - uint16_t rnti; - srsran::move_callback callback; - }; - std::mutex event_mutex; - srsran::deque next_slot_events, slot_events; - - std::vector > slot_worker_ctxts; - struct cc_context { - std::condition_variable cvar; - int waiting = 0; - slot_cc_worker worker; - - cc_context(serv_cell_manager& sched) : worker(sched) {} - }; - - std::mutex slot_mutex; - std::condition_variable cvar; - slot_point current_slot; - std::atomic worker_count{0}; // variable shared across slot_cc_workers - std::vector > cc_worker_list; -}; - -} // namespace sched_nr_impl -} // namespace srsenb - -#endif // SRSRAN_SCHED_NR_WORKER_H diff --git a/srsenb/hdr/stack/mac/sched.h b/srsenb/hdr/stack/mac/sched.h index d7e84aa3dd..dc106e9be1 100644 --- a/srsenb/hdr/stack/mac/sched.h +++ b/srsenb/hdr/stack/mac/sched.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -80,12 +80,15 @@ class sched : public sched_interface int dl_sched(uint32_t tti, uint32_t enb_cc_idx, dl_sched_res_t& sched_result) final; int ul_sched(uint32_t tti, uint32_t enb_cc_idx, ul_sched_res_t& sched_result) final; + int set_pdcch_order(uint32_t enb_cc_idx, dl_sched_po_info_t pdcch_order_info) final; + /* Custom functions */ void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) final; std::array get_enb_ue_cc_map(uint16_t rnti) final; std::array get_enb_ue_activ_cc_map(uint16_t rnti) final; int ul_buffer_add(uint16_t rnti, uint32_t lcid, uint32_t bytes) final; + int metrics_read(uint16_t rnti, mac_ue_metrics_t& metrics); class carrier_sched; diff --git a/srsenb/hdr/stack/mac/sched_carrier.h b/srsenb/hdr/stack/mac/sched_carrier.h index 42ec21c591..781f77a1e3 100644 --- a/srsenb/hdr/stack/mac/sched_carrier.h +++ b/srsenb/hdr/stack/mac/sched_carrier.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,6 +24,7 @@ #include "sched.h" #include "schedulers/sched_base.h" +#include "srsran/adt/circular_buffer.h" #include "srsran/adt/pool/cached_alloc.h" #include "srsran/srslog/srslog.h" @@ -45,6 +46,7 @@ class sched::carrier_sched void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs); const cc_sched_result& generate_tti_result(srsran::tti_point tti_rx); int dl_rach_info(dl_sched_rar_info_t rar_info); + int pdcch_order_info(dl_sched_po_info_t pdcch_order_info); // getters const ra_sched* get_ra_sched() const { return ra_sched_ptr.get(); } @@ -58,6 +60,8 @@ class sched::carrier_sched int alloc_ul_users(sf_sched* tti_sched); //! Get sf_sched for a given TTI sf_sched* get_sf_sched(srsran::tti_point tti_rx); + //! Schedule PDCCH orders + void pdcch_order_sched(sf_sched* tti_sched); // args const sched_cell_params_t* cc_cfg = nullptr; @@ -77,6 +81,11 @@ class sched::carrier_sched std::unique_ptr bc_sched_ptr; std::unique_ptr ra_sched_ptr; std::unique_ptr sched_algo; + + // pending pdcch orders + std::vector pending_pdcch_orders; + + uint32_t po_aggr_level = 2; }; //! Broadcast (SIB + paging) scheduler @@ -132,9 +141,9 @@ class ra_sched const sched_cell_params_t* cc_cfg = nullptr; sched_ue_list* ue_db = nullptr; - srsran::deque pending_rars; - uint32_t rar_aggr_level = 2; - static const uint32_t PRACH_RAR_OFFSET = 3; // TS 36.321 Sec. 5.1.4 + srsran::dyn_circular_buffer pending_rars; + uint32_t rar_aggr_level = 2; + static const uint32_t PRACH_RAR_OFFSET = 3; // TS 36.321 Sec. 5.1.4 }; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/sched_common.h b/srsenb/hdr/stack/mac/sched_common.h index d683a08dd3..630c6ac10a 100644 --- a/srsenb/hdr/stack/mac/sched_common.h +++ b/srsenb/hdr/stack/mac/sched_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/sched_grid.h b/srsenb/hdr/stack/mac/sched_grid.h index 4ca04555ca..d52d1c9d63 100644 --- a/srsenb/hdr/stack/mac/sched_grid.h +++ b/srsenb/hdr/stack/mac/sched_grid.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -150,6 +150,9 @@ class sf_sched struct bc_alloc_t : public ctrl_alloc_t { sched_interface::dl_sched_bc_t bc_grant; }; + struct po_alloc_t : public ctrl_alloc_t { + sched_interface::dl_sched_po_t po_grant; + }; struct dl_alloc_t { size_t dci_idx; uint16_t rnti; @@ -183,6 +186,8 @@ class sf_sched alloc_result alloc_sib(uint32_t aggr_lvl, uint32_t sib_idx, uint32_t sib_ntx, rbg_interval rbgs); alloc_result alloc_paging(uint32_t aggr_lvl, uint32_t paging_payload, rbg_interval rbgs); alloc_result alloc_rar(uint32_t aggr_lvl, const pending_rar_t& rar_grant, rbg_interval rbgs, uint32_t nof_grants); + alloc_result + alloc_pdcch_order(const sched_interface::dl_sched_po_info_t& po_cfg, uint32_t aggr_lvl, rbg_interval rbgs); bool reserve_dl_rbgs(uint32_t rbg_start, uint32_t rbg_end) { return tti_alloc.reserve_dl_rbgs(rbg_start, rbg_end); } // UL alloc methods @@ -232,6 +237,7 @@ class sf_sched srsran::bounded_vector bc_allocs; srsran::bounded_vector rar_allocs; + srsran::bounded_vector po_allocs; srsran::bounded_vector data_allocs; srsran::bounded_vector ul_data_allocs; uint32_t last_msg3_prb = 0, max_msg3_prb = 0; diff --git a/srsenb/hdr/stack/mac/sched_helpers.h b/srsenb/hdr/stack/mac/sched_helpers.h index d97f66ad5a..8930af25ec 100644 --- a/srsenb/hdr/stack/mac/sched_helpers.h +++ b/srsenb/hdr/stack/mac/sched_helpers.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/sched_interface.h b/srsenb/hdr/stack/mac/sched_interface.h index b56292bcb7..e6531787a5 100644 --- a/srsenb/hdr/stack/mac/sched_interface.h +++ b/srsenb/hdr/stack/mac/sched_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -46,6 +46,7 @@ class sched_interface const static int MAX_DATA_LIST = 32; const static int MAX_RAR_LIST = 8; const static int MAX_BC_LIST = 8; + const static int MAX_PO_LIST = 8; const static int MAX_RLC_PDU_LIST = 8; const static int MAX_PHICH_LIST = 8; @@ -148,6 +149,7 @@ class sched_interface struct ue_cfg_t { struct cc_cfg_t { bool active = false; + bool ul_disabled = false; uint32_t enb_cc_idx = 0; ///< eNB CC index srsran_dl_cfg_t dl_cfg = {}; uint32_t aperiodic_cqi_period = 0; // if 0 is periodic CQI @@ -224,20 +226,31 @@ class sched_interface typedef struct { srsran_dci_dl_t dci; - enum bc_type { BCCH, PCCH } type; - uint32_t index; - uint32_t tbs; - } dl_sched_bc_t; + struct dl_sched_po_info_t { + uint32_t preamble_idx; + uint32_t prach_mask_idx; + uint16_t crnti; + }; + + typedef struct { + srsran_dci_dl_t dci; + uint32_t tbs; + uint16_t crnti; + uint32_t preamble_idx; + uint32_t prach_mask_idx; + } dl_sched_po_t; + struct dl_sched_res_t { uint32_t cfi; srsran::bounded_vector data; srsran::bounded_vector rar; srsran::bounded_vector bc; + srsran::bounded_vector po; }; typedef struct { @@ -310,6 +323,9 @@ class sched_interface virtual int dl_sched(uint32_t tti, uint32_t enb_cc_idx, dl_sched_res_t& sched_result) = 0; virtual int ul_sched(uint32_t tti, uint32_t enb_cc_idx, ul_sched_res_t& sched_result) = 0; + /* PDCCH order */ + virtual int set_pdcch_order(uint32_t enb_cc_idx, dl_sched_po_info_t pdcch_order_info) = 0; + /* Custom */ virtual void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) = 0; virtual std::array get_enb_ue_cc_map(uint16_t rnti) = 0; diff --git a/srsenb/hdr/stack/mac/sched_lte_common.h b/srsenb/hdr/stack/mac/sched_lte_common.h index 02374a2dd5..8c6eb1931c 100644 --- a/srsenb/hdr/stack/mac/sched_lte_common.h +++ b/srsenb/hdr/stack/mac/sched_lte_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -91,10 +91,11 @@ class sched_cell_params_t }; /// Type of Allocation stored in PDSCH/PUSCH -enum class alloc_type_t { DL_BC, DL_PCCH, DL_RAR, DL_DATA, UL_DATA }; +enum class alloc_type_t { DL_BC, DL_PCCH, DL_RAR, DL_PDCCH_ORDER, DL_DATA, UL_DATA }; inline bool is_dl_ctrl_alloc(alloc_type_t a) { - return a == alloc_type_t::DL_BC or a == alloc_type_t::DL_PCCH or a == alloc_type_t::DL_RAR; + return a == alloc_type_t::DL_BC or a == alloc_type_t::DL_PCCH or a == alloc_type_t::DL_RAR or + a == alloc_type_t::DL_PDCCH_ORDER; } } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/sched_phy_ch/sched_dci.h b/srsenb/hdr/stack/mac/sched_phy_ch/sched_dci.h index 29324eb552..b2d5d61b7d 100644 --- a/srsenb/hdr/stack/mac/sched_phy_ch/sched_dci.h +++ b/srsenb/hdr/stack/mac/sched_phy_ch/sched_dci.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -113,6 +113,11 @@ bool generate_rar_dci(sched_interface::dl_sched_rar_t& rar, const sched_cell_params_t& cell_params, uint32_t current_cfi); +void generate_pdcch_order_dci(sched_interface::dl_sched_po_t& pdcch_order, + tti_point tti_tx_dl, + const sched_cell_params_t& cell_params, + uint32_t current_cfi); + void log_broadcast_allocation(const sched_interface::dl_sched_bc_t& bc, rbg_interval rbg_range, const sched_cell_params_t& cell_params); @@ -123,6 +128,10 @@ void log_rar_allocation(const sched_interface::dl_sched_rar_t& rar, void log_rar_allocation(const sched_interface::dl_sched_rar_t& rar, rbg_interval rbg_range); +void log_po_allocation(const sched_interface::dl_sched_po_t& pdcch_order, + rbg_interval rbg_range, + const sched_cell_params_t& cell_params); + } // namespace srsenb #endif // SRSRAN_SCHED_DCI_H diff --git a/srsenb/hdr/stack/mac/sched_phy_ch/sched_phy_resource.h b/srsenb/hdr/stack/mac/sched_phy_ch/sched_phy_resource.h index b0330ac03e..829e5d247c 100644 --- a/srsenb/hdr/stack/mac/sched_phy_ch/sched_phy_resource.h +++ b/srsenb/hdr/stack/mac/sched_phy_ch/sched_phy_resource.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/sched_phy_ch/sched_result.h b/srsenb/hdr/stack/mac/sched_phy_ch/sched_result.h index fc2a82d2d0..0a23dbff51 100644 --- a/srsenb/hdr/stack/mac/sched_phy_ch/sched_result.h +++ b/srsenb/hdr/stack/mac/sched_phy_ch/sched_result.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h b/srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h index 14c0c7b57d..491d1cbfa5 100644 --- a/srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h +++ b/srsenb/hdr/stack/mac/sched_phy_ch/sf_cch_allocator.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/sched_ue.h b/srsenb/hdr/stack/mac/sched_ue.h index 80ba401a1f..422c1bb417 100644 --- a/srsenb/hdr/stack/mac/sched_ue.h +++ b/srsenb/hdr/stack/mac/sched_ue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -27,6 +27,7 @@ #include "sched_ue_ctrl/sched_ue_cell.h" #include "sched_ue_ctrl/tpc.h" #include "srsenb/hdr/common/common_enb.h" +#include "srsenb/hdr/stack/mac/common/mac_metrics.h" #include "srsran/srslog/srslog.h" #include #include @@ -82,6 +83,7 @@ class sched_ue const ue_cfg_t& get_ue_cfg() const { return cfg; } uint32_t get_aggr_level(uint32_t enb_cc_idx, uint32_t nof_bits); void ul_buffer_add(uint8_t lcid, uint32_t bytes); + void metrics_read(mac_ue_metrics_t& metrics); /******************************************************* * Functions used by scheduler metric objects diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_dl_cqi.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_dl_cqi.h index 3752b75093..9de8f256e0 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_dl_cqi.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_dl_cqi.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h index a6fc8759e7..f664a16b61 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_harq.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h index fb3906df67..80cf6c1566 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,7 +22,7 @@ #ifndef SRSRAN_SCHED_LCH_H #define SRSRAN_SCHED_LCH_H -#include "srsenb/hdr/stack/mac/common/ue_buffer_manager.h" +#include "srsenb/hdr/stack/mac/common/base_ue_buffer_manager.h" #include "srsenb/hdr/stack/mac/sched_interface.h" #include "srsran/adt/pool/cached_alloc.h" #include "srsran/mac/pdu.h" @@ -30,18 +30,17 @@ namespace srsenb { -class lch_ue_manager : private ue_buffer_manager +class lch_ue_manager : private base_ue_buffer_manager { - using base_type = ue_buffer_manager; + using base_type = base_ue_buffer_manager; public: - explicit lch_ue_manager(uint16_t rnti) : ue_buffer_manager(rnti, srslog::fetch_basic_logger("MAC")) {} + explicit lch_ue_manager(uint16_t rnti) : base_ue_buffer_manager(rnti, srslog::fetch_basic_logger("MAC")) {} void set_cfg(const sched_interface::ue_cfg_t& cfg_); void new_tti(); // Inherited methods from ue_buffer_manager base class using base_type::config_lcid; - using base_type::dl_buffer_state; using base_type::get_bsr; using base_type::get_bsr_state; using base_type::get_dl_prio_tx; @@ -51,8 +50,9 @@ class lch_ue_manager : private ue_buffer_manager using base_type::is_bearer_dl; using base_type::is_bearer_ul; using base_type::is_lcg_active; - using base_type::ul_bsr; + void dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue); + void ul_bsr(uint32_t lcg_id, uint32_t val); void ul_buffer_add(uint8_t lcid, uint32_t bytes); int alloc_rlc_pdu(sched_interface::dl_sched_pdu_t* lcid, int rem_bytes); diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h index 839bf4880e..ceda23a79b 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -52,6 +52,8 @@ struct sched_ue_cell { const ue_cc_cfg* get_ue_cc_cfg() const { return configured() ? &ue_cfg->supported_cc_list[ue_cc_idx] : nullptr; } const sched_interface::ue_cfg_t* get_ue_cfg() const { return configured() ? ue_cfg : nullptr; } cc_st cc_state() const { return cc_state_; } + float get_ul_snr_offset() const { return ul_snr_coeff; } + float get_dl_cqi_offset() const { return dl_cqi_coeff; } int get_dl_cqi() const; int get_dl_cqi(const rbgmask_t& rbgs) const; diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h index 1ad983f3a6..7a1541c6ea 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/schedulers/sched_base.h b/srsenb/hdr/stack/mac/schedulers/sched_base.h index e43c5e6ca6..34cd33f62e 100644 --- a/srsenb/hdr/stack/mac/schedulers/sched_base.h +++ b/srsenb/hdr/stack/mac/schedulers/sched_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/schedulers/sched_time_pf.h b/srsenb/hdr/stack/mac/schedulers/sched_time_pf.h index 7d0dfcf40b..8839028f26 100644 --- a/srsenb/hdr/stack/mac/schedulers/sched_time_pf.h +++ b/srsenb/hdr/stack/mac/schedulers/sched_time_pf.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/schedulers/sched_time_rr.h b/srsenb/hdr/stack/mac/schedulers/sched_time_rr.h index 9b972d142c..09d29c8aaf 100644 --- a/srsenb/hdr/stack/mac/schedulers/sched_time_rr.h +++ b/srsenb/hdr/stack/mac/schedulers/sched_time_rr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/ta.h b/srsenb/hdr/stack/mac/ta.h index 3de31a2165..3e054bd044 100644 --- a/srsenb/hdr/stack/mac/ta.h +++ b/srsenb/hdr/stack/mac/ta.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/ue.h b/srsenb/hdr/stack/mac/ue.h index 13408b7d35..e8fe3fd35c 100644 --- a/srsenb/hdr/stack/mac/ue.h +++ b/srsenb/hdr/stack/mac/ue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/rrc/mac_controller.h b/srsenb/hdr/stack/rrc/mac_controller.h index 59844c9347..a81ee3911f 100644 --- a/srsenb/hdr/stack/rrc/mac_controller.h +++ b/srsenb/hdr/stack/rrc/mac_controller.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -70,6 +70,7 @@ class mac_controller bool is_crnti_set() const { return crnti_set; } void set_scell_activation(const std::bitset& scell_mask); + void set_srb2_activation(bool active); void set_drb_activation(bool active); void update_mac(); diff --git a/srsenb/hdr/stack/rrc/nr/rrc_config_nr.h b/srsenb/hdr/stack/rrc/nr/rrc_config_nr.h deleted file mode 100644 index 86424a4a16..0000000000 --- a/srsenb/hdr/stack/rrc/nr/rrc_config_nr.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#ifndef SRSRAN_RRC_CONFIG_NR_H -#define SRSRAN_RRC_CONFIG_NR_H - -#include "../rrc_config_common.h" -#include "srsran/asn1/rrc_nr.h" -#include "srsran/interfaces/gnb_rrc_nr_interfaces.h" -#include "srsue/hdr/phy/phy_common.h" - -namespace srsenb { - -// TODO: Make this common to NR and LTE -struct rrc_nr_cfg_sr_t { - uint32_t period; - // asn1::rrc::sched_request_cfg_c::setup_s_::dsr_trans_max_e_ dsr_max; - uint32_t nof_prb; - uint32_t sf_mapping[80]; - uint32_t nof_subframes; -}; - -struct rrc_nr_cfg_t { - asn1::rrc_nr::mib_s mib; - asn1::rrc_nr::sib1_s sib1; - asn1::rrc_nr::sys_info_ies_s::sib_type_and_info_item_c_ sibs[ASN1_RRC_NR_MAX_SIB]; - uint32_t nof_sibs; - rrc_nr_cfg_sr_t sr_cfg; - rrc_cfg_cqi_t cqi_cfg; - rrc_cell_list_nr_t cell_list; - asn1::rrc_nr::rach_cfg_common_s rach_cfg_common; - uint16_t prach_root_seq_idx_type; - - std::string log_name = "RRC-NR"; - std::string log_level; - uint32_t log_hex_limit; -}; - -} // namespace srsenb - -#endif // SRSRAN_RRC_CONFIG_NR_H diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index 520447adb6..beb1a3957c 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -34,7 +34,10 @@ #include "srsran/common/stack_procedure.h" #include "srsran/common/task_scheduler.h" #include "srsran/common/timeout.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" +#include "srsran/interfaces/enb_rrc_interface_mac.h" +#include "srsran/interfaces/enb_rrc_interface_pdcp.h" +#include "srsran/interfaces/enb_rrc_interface_rlc.h" +#include "srsran/interfaces/enb_rrc_interface_s1ap.h" #include "srsran/interfaces/enb_x2_interfaces.h" #include "srsran/srslog/srslog.h" #include @@ -49,14 +52,6 @@ class phy_interface_rrc_lte; class paging_manager; -static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", - "WAIT FOR CON SETUP COMPLETE", - "WAIT FOR SECURITY MODE COMPLETE", - "WAIT FOR UE CAPABILITIY INFORMATION", - "WAIT FOR CON RECONF COMPLETE", - "RRC CONNECTED", - "RELEASE REQUEST"}; - class rrc final : public rrc_interface_pdcp, public rrc_interface_mac, public rrc_interface_rlc, diff --git a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h index e2aa2c8fc8..0034acaa0b 100644 --- a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -102,12 +102,12 @@ class bearer_cfg_handler /// Called after RRCReestablishmentComplete, to add E-RABs of old rnti void reestablish_bearers(bearer_cfg_handler&& old_rnti_bearers); - int add_erab(uint8_t erab_id, - const asn1::s1ap::erab_level_qos_params_s& qos, - const asn1::bounded_bitstring<1, 160, true, true>& addr, - uint32_t teid_out, - srsran::const_span nas_pdu, - asn1::s1ap::cause_c& cause); + int addmod_erab(uint8_t erab_id, + const asn1::s1ap::erab_level_qos_params_s& qos, + const asn1::bounded_bitstring<1, 160, true, true>& addr, + uint32_t teid_out, + srsran::const_span nas_pdu, + asn1::s1ap::cause_c& cause); int release_erab(uint8_t erab_id); void release_erabs(); int modify_erab(uint8_t erab_id, @@ -123,6 +123,7 @@ class bearer_cfg_handler const gtpu_interface_rrc::bearer_props* props = nullptr); void rem_gtpu_bearer(uint32_t erab_id); void fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg); + void clear_pending_nas_info(); const std::map& get_erabs() const { return erabs; } const asn1::rrc::drb_to_add_mod_list_l& get_established_drbs() const { return current_drbs; } @@ -136,6 +137,9 @@ class bearer_cfg_handler const rrc_cfg_t* cfg = nullptr; gtpu_interface_rrc* gtpu = nullptr; + // NAS PDUs being currently sent. + std::vector erab_ids_with_pending_nas_pdus; + // last cfg asn1::rrc::drb_to_add_mod_list_l current_drbs; }; diff --git a/srsenb/hdr/stack/rrc/rrc_cell_cfg.h b/srsenb/hdr/stack/rrc/rrc_cell_cfg.h index c1ce44a5d1..17174fdf69 100644 --- a/srsenb/hdr/stack/rrc/rrc_cell_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_cell_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/rrc/rrc_config.h b/srsenb/hdr/stack/rrc/rrc_config.h index 09f9dd660f..8a00b0a857 100644 --- a/srsenb/hdr/stack/rrc/rrc_config.h +++ b/srsenb/hdr/stack/rrc/rrc_config.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -85,12 +85,12 @@ struct rrc_cfg_t { bool meas_cfg_present = false; srsran_cell_t cell; cell_list_t cell_list; - uint32_t num_nr_cells = 0; /// number of configured NR cells (used to configure RF) - uint32_t max_mac_dl_kos; - uint32_t max_mac_ul_kos; - uint32_t rlf_release_timer_ms; - srb_cfg_t srb1_cfg; - srb_cfg_t srb2_cfg; + uint32_t num_nr_cells = 0; /// number of configured NR cells (used to configure RF) + uint32_t max_mac_dl_kos; + uint32_t max_mac_ul_kos; + uint32_t rlf_release_timer_ms; + srb_cfg_t srb1_cfg; + srb_cfg_t srb2_cfg; rrc_endc_cfg_t endc_cfg; }; diff --git a/srsenb/hdr/stack/rrc/rrc_config_common.h b/srsenb/hdr/stack/rrc/rrc_config_common.h index 04cffc74b2..b64d2286f2 100644 --- a/srsenb/hdr/stack/rrc/rrc_config_common.h +++ b/srsenb/hdr/stack/rrc/rrc_config_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index f79ba48cf7..5e4f8218a1 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -110,7 +110,6 @@ class rrc::ue::rrc_endc : public srsran::fsm_t asn1::rrc::rrc_conn_recfg_complete_s pending_recfg_complete; // fixed ENDC variables - const uint32_t eutra_drb_id = 1; // The DRB ID that converted to NR const uint32_t lcid_drb_nr = 4; // internal events diff --git a/srsenb/hdr/stack/rrc/rrc_metrics.h b/srsenb/hdr/stack/rrc/rrc_metrics.h index a6adbbbae2..550460c50d 100644 --- a/srsenb/hdr/stack/rrc/rrc_metrics.h +++ b/srsenb/hdr/stack/rrc/rrc_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/rrc/rrc_mobility.h b/srsenb/hdr/stack/rrc/rrc_mobility.h index a3b679764f..d7f19f6af7 100644 --- a/srsenb/hdr/stack/rrc/rrc_mobility.h +++ b/srsenb/hdr/stack/rrc/rrc_mobility.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -59,6 +59,8 @@ class rrc::ue::rrc_mobility : public srsran::fsm_t const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container, asn1::s1ap::cause_c& cause); + std::pair get_source_ue_rnti_and_pci(); + private: // helper methods bool update_ue_var_meas_cfg(uint32_t src_earfcn, @@ -66,7 +68,8 @@ class rrc::ue::rrc_mobility : public srsran::fsm_t asn1::rrc::meas_cfg_s* diff_meas_cfg); // Handover from source cell - bool start_ho_preparation(uint32_t target_eci, uint8_t measobj_id, bool fwd_direct_path_available); + bool + start_ho_preparation(uint32_t target_eci, uint16_t target_tac, uint8_t measobj_id, bool fwd_direct_path_available); // Handover to target cell void fill_mobility_reconf_common(asn1::rrc::dl_dcch_msg_s& msg, @@ -90,6 +93,7 @@ class rrc::ue::rrc_mobility : public srsran::fsm_t // events struct ho_meas_report_ev { uint32_t target_eci = 0; + uint16_t target_tac = 0; const asn1::rrc::meas_obj_to_add_mod_s* meas_obj = nullptr; bool direct_fwd_path = false; }; @@ -116,6 +120,8 @@ class rrc::ue::rrc_mobility : public srsran::fsm_t struct s1_target_ho_st { asn1::s1ap::cause_c failure_cause; std::vector pending_tunnels; + uint16_t src_rnti; + uint32_t src_pci; }; struct wait_recfg_comp {}; struct s1_source_ho_st : public subfsm_t { diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h deleted file mode 100644 index 7a2918515a..0000000000 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ /dev/null @@ -1,258 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#ifndef SRSENB_RRC_NR_H -#define SRSENB_RRC_NR_H - -#include "rrc_config_common.h" -#include "rrc_metrics.h" -#include "srsenb/hdr/stack/enb_stack_base.h" -#include "srsenb/hdr/stack/rrc/nr/rrc_config_nr.h" -#include "srsran/asn1/rrc_nr.h" -#include "srsran/common/block_queue.h" -#include "srsran/common/buffer_pool.h" -#include "srsran/common/common.h" -#include "srsran/common/task_scheduler.h" -#include "srsran/common/threads.h" -#include "srsran/common/timeout.h" -#include "srsran/interfaces/enb_pdcp_interfaces.h" -#include "srsran/interfaces/enb_rlc_interfaces.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" -#include "srsran/interfaces/enb_x2_interfaces.h" -#include "srsran/interfaces/gnb_interfaces.h" -#include "srsran/interfaces/gnb_mac_interfaces.h" -#include "srsran/interfaces/gnb_ngap_interfaces.h" -#include "srsran/interfaces/gnb_rrc_nr_interfaces.h" -#include -#include - -namespace srsenb { - -enum class rrc_nr_state_t { RRC_IDLE, RRC_INACTIVE, RRC_CONNECTED }; - -class rrc_nr final : public rrc_interface_pdcp_nr, - public rrc_interface_mac_nr, - public rrc_interface_rlc_nr, - public rrc_interface_ngap_nr, - public rrc_nr_interface_rrc -{ -public: - explicit rrc_nr(srsran::task_sched_handle task_sched_); - - int32_t init(const rrc_nr_cfg_t& cfg, - phy_interface_stack_nr* phy, - mac_interface_rrc_nr* mac, - rlc_interface_rrc* rlc, - pdcp_interface_rrc* pdcp, - ngap_interface_rrc_nr* ngap_, - gtpu_interface_rrc_nr* gtpu, - rrc_eutra_interface_rrc_nr* rrc_eutra_); - - void stop(); - - void get_metrics(srsenb::rrc_metrics_t& m); - - rrc_nr_cfg_t update_default_cfg(const rrc_nr_cfg_t& rrc_cfg); - void config_phy(); - void config_mac(); - int32_t generate_sibs(); - int read_pdu_bcch_bch(const uint32_t tti, srsran::unique_byte_buffer_t& buffer) final; - int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) final; - - /// User manegement - int add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg); - void rem_user(uint16_t rnti); - int update_user(uint16_t new_rnti, uint16_t old_rnti); - void set_activity_user(uint16_t rnti); - - // RLC interface - // TODO - void read_pdu_pcch(uint8_t* payload, uint32_t payload_size) {} - void max_retx_attempted(uint16_t rnti) {} - void protocol_failure(uint16_t rnti) {} - const char* get_rb_name(uint32_t lcid) { return "invalid"; } - - // PDCP interface - void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) final; - void notify_pdcp_integrity_error(uint16_t rnti, uint32_t lcid) final; - - // Interface for EUTRA RRC - void sgnb_addition_request(uint16_t rnti, const sgnb_addition_req_params_t& params); - void sgnb_reconfiguration_complete(uint16_t rnti, const asn1::dyn_octstring& reconfig_response) final; - void sgnb_release_request(uint16_t nr_rnti) final; - - // Interfaces for NGAP - int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key); - int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates); - int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps); - int start_security_mode_procedure(uint16_t rnti); - int establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid); - int release_bearers(uint16_t rnti); - void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu); - int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates); - int allocate_lcid(uint16_t rnti); - - class ue - { - public: - enum activity_timeout_type_t { - MSG3_RX_TIMEOUT = 0, ///< Msg3 has its own timeout to quickly remove fake UEs from random PRACHs - UE_INACTIVITY_TIMEOUT, ///< (currently unused) UE inactivity timeout (usually bigger than reestablishment timeout) - MSG5_RX_TIMEOUT, ///< (currently unused) for receiving RRCConnectionSetupComplete/RRCReestablishmentComplete - nulltype - }; - - /// @param [in] start_msg3_timer: indicates whether the UE is created as part of a RACH process - ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg, bool start_msg3_timer = true); - - void send_connection_setup(); - void send_dl_ccch(asn1::rrc_nr::dl_ccch_msg_s* dl_dcch_msg); - - int handle_sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params); - void crnti_ce_received(); - - // getters - bool is_connected() { return state == rrc_nr_state_t::RRC_CONNECTED; } - bool is_idle() { return state == rrc_nr_state_t::RRC_IDLE; } - bool is_inactive() { return state == rrc_nr_state_t::RRC_INACTIVE; } - bool is_endc() { return endc; } - uint16_t get_eutra_rnti() { return eutra_rnti; } - void get_metrics(rrc_ue_metrics_t& ue_metrics) { ue_metrics = {}; /*TODO fill RRC metrics*/ }; - - // setters - - int pack_rrc_reconfiguration(); - void deactivate_bearers(); - - /// methods to handle activity timer - std::string to_string(const activity_timeout_type_t& type); - void set_activity_timeout(activity_timeout_type_t type); - void set_activity(bool enabled = true); - void activity_timer_expired(const activity_timeout_type_t type); - - private: - rrc_nr* parent = nullptr; - uint16_t rnti = SRSRAN_INVALID_RNTI; - /// for basic DL/UL activity timeout - srsran::unique_timer activity_timer; - - int pack_rrc_reconfiguration(asn1::dyn_octstring& packed_rrc_reconfig); - int pack_secondary_cell_group_cfg(asn1::dyn_octstring& packed_secondary_cell_config); - - int pack_secondary_cell_group_rlc_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_secondary_cell_group_mac_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - - int pack_secondary_cell_group_sp_cell_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - - int pack_sp_cell_cfg_ded(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - - int pack_sp_cell_cfg_ded_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_sp_cell_cfg_ded_init_dl_bwp_pdsch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - - int pack_sp_cell_cfg_ded_ul_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pucch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pusch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - - int pack_sp_cell_cfg_ded_pdcch_serving_cell_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - - int pack_recfg_with_sync(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_recfg_with_sync_sp_cell_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common_phy_cell_group_cfg( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - - int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdsch_cfg_common( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - - int pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - int pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp_pusch_cfg_common( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); - - int pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_bearer_config); - - int add_drb(); - - // state - rrc_nr_state_t state = rrc_nr_state_t::RRC_IDLE; - uint8_t transaction_id = 0; - - // RRC configs for UEs - asn1::rrc_nr::cell_group_cfg_s cell_group_cfg; - asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg; - - // MAC controller - sched_nr_interface::ue_cfg_t uecfg{}; - - const uint32_t drb1_lcid = 4; - - // NSA specific variables - bool endc = false; - uint16_t eutra_rnti = SRSRAN_INVALID_RNTI; - }; - -private: - static constexpr uint32_t UE_PSCELL_CC_IDX = 0; // first NR cell is always Primary Secondary Cell for UE - rrc_nr_cfg_t cfg = {}; - - // interfaces - phy_interface_stack_nr* phy = nullptr; - mac_interface_rrc_nr* mac = nullptr; - rlc_interface_rrc* rlc = nullptr; - pdcp_interface_rrc* pdcp = nullptr; - gtpu_interface_rrc_nr* gtpu = nullptr; - ngap_interface_rrc_nr* ngap = nullptr; - rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr; - - // args - srsran::task_sched_handle task_sched; - - // derived - uint32_t slot_dur_ms = 0; - srslog::basic_logger& logger; - asn1::rrc_nr::sp_cell_cfg_s base_sp_cell_cfg; - - // vars - std::map > users; - bool running = false; - std::vector sib_buffer; - srsran::unique_byte_buffer_t mib_buffer = nullptr; - - uint32_t nof_si_messages = 0; - - /// Private Methods - void handle_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu); - /// This gets called by rrc_nr::sgnb_addition_request and WILL NOT TRIGGER the RX MSG3 activity timer - int add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg, bool start_msg3_timer); - - // logging - typedef enum { Rx = 0, Tx } direction_t; - template - void log_rrc_message(const std::string& source, direction_t dir, const srsran::byte_buffer_t* pdu, const T& msg); -}; - -} // namespace srsenb - -#endif // SRSENB_RRC_NR_H diff --git a/srsenb/hdr/stack/rrc/rrc_paging.h b/srsenb/hdr/stack/rrc/rrc_paging.h index 30a1f56333..3342d82f0b 100644 --- a/srsenb/hdr/stack/rrc/rrc_paging.h +++ b/srsenb/hdr/stack/rrc/rrc_paging.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -41,7 +41,7 @@ class paging_manager T(default_paging_cycle_), Nb(static_cast((float)T * nb_)), N(std::min(T, Nb)), - Ns(std::max(1U, Nb)), + Ns(std::max(1U, static_cast(nb_))), logger(srslog::fetch_basic_logger("RRC")) { for (subframe_info& sf_obj : sf_pending_pcch) { diff --git a/srsenb/hdr/stack/rrc/rrc_ue.h b/srsenb/hdr/stack/rrc/rrc_ue.h index 0d4002053a..a4b402a1da 100644 --- a/srsenb/hdr/stack/rrc/rrc_ue.h +++ b/srsenb/hdr/stack/rrc/rrc_ue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -39,7 +39,8 @@ class rrc::ue enum activity_timeout_type_t { MSG3_RX_TIMEOUT = 0, ///< Msg3 has its own timeout to quickly remove fake UEs from random PRACHs UE_INACTIVITY_TIMEOUT, ///< UE inactivity timeout (usually bigger than reestablishment timeout) - MSG5_RX_TIMEOUT, ///< UE timeout for receiving RRCConnectionSetupComplete / RRCReestablishmentComplete + MSG5_RX_TIMEOUT_T300, ///< UE timeout for receiving RRCConnectionSetupComplete + MSG5_RX_TIMEOUT_T301, ///< UE timeout for receiving RRCReestablishmentComplete nulltype }; @@ -261,6 +262,9 @@ class rrc::ue void apply_pdcp_srb_updates(const asn1::rrc::rr_cfg_ded_s& pending_rr_cfg); void apply_pdcp_drb_updates(const asn1::rrc::rr_cfg_ded_s& pending_rr_cfg); void apply_rlc_rb_updates(const asn1::rrc::rr_cfg_ded_s& pending_rr_cfg); + + /// Find UE whose Handover source identity matches the passed arguments. + ue* find_handover_source_ue(uint16_t old_rnti, uint32_t old_pci); }; // class ue } // namespace srsenb diff --git a/srsenb/hdr/stack/rrc/ue_meas_cfg.h b/srsenb/hdr/stack/rrc/ue_meas_cfg.h index 2a784400a6..95b1cdfba4 100644 --- a/srsenb/hdr/stack/rrc/ue_meas_cfg.h +++ b/srsenb/hdr/stack/rrc/ue_meas_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/rrc/ue_rr_cfg.h b/srsenb/hdr/stack/rrc/ue_rr_cfg.h index 07ab44477f..6e9d9390c6 100644 --- a/srsenb/hdr/stack/rrc/ue_rr_cfg.h +++ b/srsenb/hdr/stack/rrc/ue_rr_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/s1ap/s1ap.h b/srsenb/hdr/stack/s1ap/s1ap.h index 4013742787..9fb46418c7 100644 --- a/srsenb/hdr/stack/s1ap/s1ap.h +++ b/srsenb/hdr/stack/s1ap/s1ap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -90,6 +90,7 @@ class s1ap : public s1ap_interface_rrc bool is_mme_connected() override; bool send_ho_required(uint16_t rnti, uint32_t target_eci, + uint16_t target_tac, srsran::plmn_id_t target_plmn, srsran::span fwd_erabs, srsran::unique_byte_buffer_t rrc_container, @@ -131,6 +132,7 @@ class s1ap : public s1ap_interface_rrc rrc_interface_s1ap* rrc = nullptr; s1ap_args_t args; srslog::basic_logger& logger; + srslog::log_channel& alarms_channel; srsran::task_sched_handle task_sched; srsran::task_queue_handle mme_task_queue; srsran::socket_manager_itf* rx_socket_handler; @@ -220,6 +222,7 @@ class s1ap : public s1ap_interface_rrc struct ts1_reloc_prep_expired {}; ho_prep_proc_t(s1ap::ue* ue_); srsran::proc_outcome_t init(uint32_t target_eci_, + uint16_t target_tac_, srsran::plmn_id_t target_plmn_, srsran::span fwd_erabs, srsran::unique_byte_buffer_t rrc_container, @@ -236,6 +239,7 @@ class s1ap : public s1ap_interface_rrc s1ap* s1ap_ptr = nullptr; uint32_t target_eci = 0; + uint16_t target_tac = 0; srsran::plmn_id_t target_plmn; srsran::unique_byte_buffer_t rrc_container; const asn1::s1ap::ho_cmd_s* ho_cmd_msg = nullptr; @@ -262,16 +266,21 @@ class s1ap : public s1ap_interface_rrc bool send_erab_release_indication(const std::vector& erabs_successfully_released); bool send_ue_cap_info_indication(srsran::unique_byte_buffer_t ue_radio_cap); + /// TS 36.413 8.4.5 - Handover Cancellation + void send_ho_cancel(const asn1::s1ap::cause_c& cause); + 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); + s1ap_proc_id_t get_state() const { return current_state; } ue_ctxt_t ctxt = {}; uint16_t stream_id = 1; private: bool send_ho_required(uint32_t target_eci_, + uint16_t target_tac_, srsran::plmn_id_t target_plmn_, srsran::span fwd_erabs, srsran::unique_byte_buffer_t rrc_container, @@ -330,13 +339,18 @@ 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; + void then(const srsran::proc_state_t& result); const char* name() const { return "MME Connection"; } + uint16_t connect_count = 0; private: srsran::proc_outcome_t start_mme_connection(); diff --git a/srsenb/hdr/stack/s1ap/s1ap_metrics.h b/srsenb/hdr/stack/s1ap/s1ap_metrics.h index 5beeaf683a..1f7f864baa 100644 --- a/srsenb/hdr/stack/s1ap/s1ap_metrics.h +++ b/srsenb/hdr/stack/s1ap/s1ap_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index b25d1ad34f..b68acdf09a 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,8 +20,8 @@ */ #include -#include #include +#include #include "srsenb/hdr/common/common_enb.h" #include "srsran/adt/bounded_vector.h" @@ -58,7 +58,7 @@ class gtpu_tunnel_manager public: // A UE should have <= 3 DRBs active, and each DRB should have two tunnels active at the same time at most - const static size_t MAX_TUNNELS_PER_UE = 6; + const static size_t MAX_TUNNELS_PER_UE = 10; enum class tunnel_state { pdcp_active, buffering, forward_to, forwarded_from, inactive }; @@ -75,8 +75,8 @@ class gtpu_tunnel_manager tunnel* fwd_tunnel = nullptr; ///< forward Rx SDUs to this TEID srsran::move_callback on_removal; - tunnel() = default; - tunnel(tunnel&&) noexcept = default; + tunnel() = default; + tunnel(tunnel&&) noexcept = default; tunnel& operator=(tunnel&&) noexcept = default; ~tunnel() { @@ -101,7 +101,9 @@ class gtpu_tunnel_manager }; using ue_bearer_tunnel_list = srsran::bounded_vector; - explicit gtpu_tunnel_manager(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger); + explicit gtpu_tunnel_manager(srsran::task_sched_handle task_sched_, + srslog::basic_logger& logger, + srsran::srsran_rat_t ran_type_); void init(const gtpu_args_t& gtpu_args, pdcp_interface_gtpu* pdcp_); bool has_teid(uint32_t teid) const { return tunnels.contains(teid); } @@ -127,13 +129,16 @@ class gtpu_tunnel_manager using tunnel_list_t = srsran::static_id_obj_pool; using tunnel_ctxt_it = typename tunnel_list_t::iterator; + // Used to differentiate whether GTPU is used in NR or LTE context. + srsran::srsran_rat_t ran_type; + srsran::task_sched_handle task_sched; const gtpu_args_t* gtpu_args = nullptr; pdcp_interface_gtpu* pdcp = nullptr; srslog::basic_logger& logger; std::unordered_map ue_teidin_db; - tunnel_list_t tunnels; + tunnel_list_t tunnels; }; using gtpu_tunnel_state = gtpu_tunnel_manager::tunnel_state; @@ -144,6 +149,7 @@ class gtpu final : public gtpu_interface_rrc, public gtpu_interface_pdcp public: explicit gtpu(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, + srsran::srsran_rat_t ran_type_, srsran::socket_manager_itf* rx_socket_handler_); ~gtpu(); @@ -177,6 +183,9 @@ class gtpu final : public gtpu_interface_rrc, public gtpu_interface_pdcp srsran::socket_manager_itf* rx_socket_handler = nullptr; srsran::task_queue_handle gtpu_queue; + // Used to differentiate whether GTPU is used in NR or LTE context. + srsran::srsran_rat_t ran_type; + gtpu_args_t args; std::string gtp_bind_addr; std::string mme_addr; @@ -190,10 +199,10 @@ class gtpu final : public gtpu_interface_rrc, public gtpu_interface_pdcp public: explicit m1u_handler(gtpu* gtpu_) : parent(gtpu_), logger(parent->logger) {} ~m1u_handler(); - m1u_handler(const m1u_handler&) = delete; - m1u_handler(m1u_handler&&) = delete; + m1u_handler(const m1u_handler&) = delete; + m1u_handler(m1u_handler&&) = delete; m1u_handler& operator=(const m1u_handler&) = delete; - m1u_handler& operator=(m1u_handler&&) = delete; + m1u_handler& operator=(m1u_handler&&) = delete; bool init(std::string m1u_multiaddr_, std::string m1u_if_addr_); void handle_rx_packet(srsran::unique_byte_buffer_t pdu, const sockaddr_in& addr); diff --git a/srsenb/hdr/stack/upper/gtpu_pdcp_adapter.h b/srsenb/hdr/stack/upper/gtpu_pdcp_adapter.h new file mode 100644 index 0000000000..9373d73999 --- /dev/null +++ b/srsenb/hdr/stack/upper/gtpu_pdcp_adapter.h @@ -0,0 +1,87 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_GTPU_PDCP_ADAPTER_H +#define SRSRAN_GTPU_PDCP_ADAPTER_H + +#include "srsran/common/bearer_manager.h" +#include "srsran/interfaces/enb_gtpu_interfaces.h" +#include "srsran/srslog/logger.h" + +namespace srsenb { + +class gtpu_pdcp_adapter final : public gtpu_interface_pdcp, public pdcp_interface_gtpu +{ +public: + gtpu_pdcp_adapter(srslog::basic_logger& logger_, + pdcp_interface_gtpu* pdcp_lte, + pdcp_interface_gtpu* pdcp_nr, + gtpu* gtpu_, + enb_bearer_manager& bearers_) : + logger(logger_), pdcp_lte_obj(pdcp_lte), pdcp_nr_obj(pdcp_nr), gtpu_obj(gtpu_), bearers(&bearers_) + {} + + /// Converts LCID to EPS-BearerID and sends corresponding PDU to GTPU + void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override + { + auto bearer = bearers->get_lcid_bearer(rnti, lcid); + if (not bearer.is_valid()) { + logger.error("Bearer rnti=0x%x, lcid=%d not found", rnti, lcid); + return; + } + gtpu_obj->write_pdu(rnti, bearer.eps_bearer_id, std::move(pdu)); + } + void write_sdu(uint16_t rnti, uint32_t eps_bearer_id, srsran::unique_byte_buffer_t sdu, int pdcp_sn = -1) override + { + auto bearer = bearers->get_radio_bearer(rnti, eps_bearer_id); + // route SDU to PDCP entity + if (bearer.rat == srsran::srsran_rat_t::lte) { + pdcp_lte_obj->write_sdu(rnti, bearer.lcid, std::move(sdu), pdcp_sn); + } else if (bearer.rat == srsran::srsran_rat_t::nr) { + pdcp_nr_obj->write_sdu(rnti, bearer.lcid, std::move(sdu), pdcp_sn); + } else { + logger.warning("Can't deliver SDU for EPS bearer %d. Dropping it.", eps_bearer_id); + } + } + std::map get_buffered_pdus(uint16_t rnti, uint32_t eps_bearer_id) override + { + auto bearer = bearers->get_radio_bearer(rnti, eps_bearer_id); + // route SDU to PDCP entity + if (bearer.rat == srsran::srsran_rat_t::lte) { + return pdcp_lte_obj->get_buffered_pdus(rnti, bearer.lcid); + } else if (bearer.rat == srsran::srsran_rat_t::nr) { + return pdcp_nr_obj->get_buffered_pdus(rnti, bearer.lcid); + } + logger.error("Bearer rnti=0x%x, eps-BearerID=%d not found", rnti, eps_bearer_id); + return {}; + } + +private: + srslog::basic_logger& logger; + gtpu* gtpu_obj = nullptr; + pdcp_interface_gtpu* pdcp_lte_obj = nullptr; + pdcp_interface_gtpu* pdcp_nr_obj = nullptr; + enb_bearer_manager* bearers = nullptr; +}; + +} // namespace srsenb + +#endif // SRSRAN_GTPU_PDCP_ADAPTER_H diff --git a/srsenb/hdr/stack/upper/pdcp.h b/srsenb/hdr/stack/upper/pdcp.h index 0047f6e482..22ef5f3fb1 100644 --- a/srsenb/hdr/stack/upper/pdcp.h +++ b/srsenb/hdr/stack/upper/pdcp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -50,7 +50,7 @@ class pdcp : public pdcp_interface_rlc, public pdcp_interface_gtpu, public pdcp_ void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) override; void notify_delivery(uint16_t rnti, uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn) override; void notify_failure(uint16_t rnti, uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn) override; - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} + void write_pdu_mch(uint32_t mch_idx, uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} // pdcp_interface_rrc void set_enabled(uint16_t rnti, uint32_t lcid, bool enabled) override; @@ -96,7 +96,7 @@ class pdcp : public pdcp_interface_rlc, public pdcp_interface_gtpu, public pdcp_ srsenb::gtpu_interface_pdcp* gtpu; // gw_interface_pdcp void write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu); - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} + void write_pdu_mch(uint32_t mch_idx, uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} }; class user_interface_rrc : public srsue::rrc_interface_pdcp diff --git a/srsenb/hdr/stack/upper/rlc.h b/srsenb/hdr/stack/upper/rlc.h index 5bda7cfbaf..76af3ed2f4 100644 --- a/srsenb/hdr/stack/upper/rlc.h +++ b/srsenb/hdr/stack/upper/rlc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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); @@ -86,7 +86,7 @@ class rlc : public rlc_interface_mac, public rlc_interface_rrc, public rlc_inter void write_pdu_bcch_bch(srsran::unique_byte_buffer_t sdu); void write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t sdu); void write_pdu_pcch(srsran::unique_byte_buffer_t sdu); - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} + void write_pdu_mch(uint32_t mch_idx, uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} void max_retx_attempted(); void protocol_failure(); const char* get_rb_name(uint32_t lcid); diff --git a/srsenb/hdr/x2_adapter.h b/srsenb/hdr/x2_adapter.h index ad959bb486..ce702cbc2f 100644 --- a/srsenb/hdr/x2_adapter.h +++ b/srsenb/hdr/x2_adapter.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -39,9 +39,9 @@ #ifndef SRSENB_X2_ADAPTER_H #define SRSENB_X2_ADAPTER_H +#include "srsgnb/hdr/stack/gnb_stack_nr.h" #include "srsran/interfaces/enb_x2_interfaces.h" #include "stack/enb_stack_lte.h" -#include "stack/gnb_stack_nr.h" namespace srsenb { diff --git a/srsenb/rb.conf.example b/srsenb/rb.conf.example index de1cb8f332..010599f294 100644 --- a/srsenb/rb.conf.example +++ b/srsenb/rb.conf.example @@ -1,5 +1,7 @@ // All times are in ms. Use -1 for infinity, where available +// 4G Section + // srb1_config = { // rlc_config = { // ul_am = { @@ -8,7 +10,7 @@ // poll_byte = -1; // max_retx_thresh = 4; // }; -// dl_am = { +// dl_am = { // t_reordering = 35; // t_status_prohibit = 0; // }; @@ -37,9 +39,8 @@ // } qci_config = ( - { - qci=7; + qci = 7; pdcp_config = { discard_timer = -1; pdcp_sn_size = 12; @@ -64,7 +65,7 @@ qci_config = ( }; }, { - qci=9; + qci = 9; pdcp_config = { discard_timer = 150; status_report_required = true; @@ -91,5 +92,96 @@ qci_config = ( dl_max_retx_thresh = 32; }; } +); + +// 5G Section +srb1_5g_config = { + rlc_config = { + ul_am = { + sn_field_len = 12; + t_poll_retx = 45; + poll_pdu = -1; + poll_byte = -1; + max_retx_thres = 8; + }; + dl_am = { + sn_field_len = 12; + t_reassembly = 35; + t_status_prohibit = 10; + }; + }; +} +srb2_5g_config = { + rlc_config = { + ul_am = { + sn_field_len = 12; + t_poll_retx = 45; + poll_pdu = -1; + poll_byte = -1; + max_retx_thres = 8; + }; + dl_am = { + sn_field_len = 12; + t_reassembly = 35; + t_status_prohibit = 10; + }; + }; +} + +five_qi_config = ( +{ + five_qi = 7; + pdcp_nr_config = { + drb = { + pdcp_sn_size_ul = 18; + pdcp_sn_size_dl = 18; + discard_timer = 50; + integrity_protection = false; + status_report = false; + }; + t_reordering = 50; + }; + rlc_config = { + um_bi_dir = { + ul_um = { + sn_field_len = 12; + }; + dl_um = { + sn_field_len = 12; + t_reassembly = 50; + }; + }; + }; +}, +{ + five_qi = 9; + pdcp_nr_config = { + drb = { + pdcp_sn_size_ul = 18; + pdcp_sn_size_dl = 18; + discard_timer = 50; + integrity_protection = false; + status_report = false; + }; + t_reordering = 50; + }; + rlc_config = { + am = { + ul_am = { + sn_field_len = 12; + t_poll_retx = 50; + poll_pdu = 4; + poll_byte = 3000; + max_retx_thres = 4; + }; + dl_am = { + sn_field_len = 12; + t_reassembly = 50; + t_status_prohibit = 50; + }; + }; + }; +} ); + diff --git a/srsenb/rr.conf.example b/srsenb/rr.conf.example index 78b2df1541..54c1ba1214 100644 --- a/srsenb/rr.conf.example +++ b/srsenb/rr.conf.example @@ -69,6 +69,7 @@ cell_list = // min_phr_thres = 0; // allowed_meas_bw = 6; // t304 = 2000; // in msec. possible values: 50, 100, 150, 200, 500, 1000, 2000 + // tx_gain = 20.0; // in dB. This gain is set by scaling the source signal. // CA cells scell_list = ( diff --git a/srsenb/sib.conf.example b/srsenb/sib.conf.example index 0d4e60aa4a..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"; @@ -137,12 +146,130 @@ sib3 = } }; +##################################################################### +# sib5 configuration options (See TS 36.331) +# Contains information relevant for inter-frequency cell re-selection. +# Must be added to sib1::sched_info::si_mapping_info array parameter to be transmitted +# +# inter_freq_carrier_freq_list: A list of neighbouring inter-frequencies. +# dl_carrier_freq: The EARFCN for the EUTRA carrier frequency. +# q_rx_lev_min: Minimum received RSRP level in the E-UTRA cell, ([field_val] * 2) = [level in dBm]. +# p_max: Optional maximum allowed transmission power for the neighbouring E-UTRA cells on this carrier frequency. +# t_resel_eutra: Cell reselection timer (seconds). +# t_resel_eutra_sf: Optional speed dependent ScalingFactor for t_resel_eutra. +# sf_medium: Scaling factor if the UE is in Medium Mobility state, one of "0.25", "0.5", "0.75" or "1.0". +# sf_high: Scaling factor if the UE is in High Mobility state, one of "0.25", "0.5", "0.75" or "1.0". +# thresh_x_high: Srclev threshold (dB) to select to a higher-priority RAT/Frequency. +# thresh_x_low: Srclev threshold (dB) to select to a lower-priority RAT/Frequency. +# allowed_meas_bw: Maximum allowed measurement bandwidth on a carrier frequency . +# presence_ant_port_1: whether all the neighbouring cells use Antenna Port 1. +# cell_resel_prio: Optional absolute priority of the carrier frequency group. +# neigh_cell_cfg: Information related to MBSFN and TDD UL/DL configuration of neighbour cells. +# q_offset_freq: Frequency specific offset for equal priority E-UTRAN frequencies. +# inter_freq_neigh_cell_list: A List of inter-frequency neighbouring cells with specific cell re-selection parameters. +# phys_cell_id: Physical layer identity of the cell. +# q_offset_cell: Cell spcific offset. +# inter_freq_black_cell_list: A List of blacklisted inter-frequency neighbouring cells. +# start: The lowest physical cell identity in the range. +# range: The number of physical cell identities in the range. +# +##################################################################### +sib5 = +{ + inter_freq_carrier_freq_list = + ( + { + dl_carrier_freq = 1450; + q_rx_lev_min = -70; + t_resel_eutra = 2; + t_resel_eutra_sf = { + sf_medium = "0.25"; + sf_high = "1.0"; + }; + thresh_x_high = 3; + thresh_x_low = 2; + allowed_meas_bw = 75; + presence_ant_port_1 = True; + cell_resel_prio = 4; + neigh_cell_cfg = 2; + q_offset_freq = -6; + inter_freq_neigh_cell_list = + ( + { + phys_cell_id = 500; + q_offset_cell = 2; + } + ); + inter_freq_black_cell_list = + ( + { + start = 123; + range = 4; + } + ); + } + ); +}; + +##################################################################### +# sib6 configuration options (See TS 36.331) +# Contains UTRA neighbor information for inter-rat handover. +# Must be added to sib1::sched_info::si_mapping_info array parameter to be transmitted +# +# t_resel_utra: Cell reselection timer (seconds) +# t_resel_utra_sf: Optional speed dependent ScalingFactor for t_resel_utra. +# sf_medium: Scaling factor if the UE is in Medium Mobility state, one of "0.25", "0.5", "0.75" or "1.0". +# sf_high: Scaling factor if the UE is in High Mobility state, one of "0.25", "0.5", "0.75" or "1.0". +# carrier_freq_list_utra_fdd / carrier_freq_list_utra_tdd: A list of carrier frequencies of UTRA FDD / TDD. +# carrier_freq: The UARFCN for the UTRA carrier frequency. +# cell_resel_prio: Optional absolute priority of the carrier frequency group. +# thresh_x_high: Srclev threshold (dB) to select to a higher-priority RAT/Frequency. +# thresh_x_low: Srclev threshold (dB) to select to a lower-priority RAT/Frequency. +# q_rx_lev_min: Minimum receive level in UTRA cell, ([field_val] * 2) + 1 = [level in dBm]. +# p_max_utra: The maximum allowed transmission power on the (uplink) carrier frequency. +# q_qual_min: Minimum required quality leve in UTRA cell, applicable only for FDD cells. +# +##################################################################### +sib6 = +{ + t_resel_utra = 1; + t_resel_utra_sf = { + sf_medium = "0.25"; + sf_high = "1.0"; + } + carrier_freq_list_utra_fdd = + ( + { + carrier_freq = 9613; + cell_resel_prio = 6; + thresh_x_high = 3; + thresh_x_low = 2; + q_rx_lev_min = -50; + p_max_utra = 4; + q_qual_min = -10; + } + ); + carrier_freq_list_utra_tdd = + ( + { + carrier_freq = 9505; + thresh_x_high = 1; + thresh_x_low = 2; + q_rx_lev_min = -50; + p_max_utra = -3; + } + ); +}; + ##################################################################### # sib7 configuration options (See TS 36.331) # Contains GERAN neighbor information for CSFB and inter-rat handover. # Must be added to sib1::sched_info::si_mapping_info array parameter to be transmitted # # t_resel_geran: Cell reselection timer (seconds) +# t_resel_geran_sf: Optional speed dependent ScalingFactor for t_resel_geran. +# sf_medium: Scaling factor if the UE is in Medium Mobility state, one of "0.25", "0.5", "0.75" or "1.0". +# sf_high: Scaling factor if the UE is in High Mobility state, one of "0.25", "0.5", "0.75" or "1.0". # carrier_freqs_info_list: A list of carrier frequency groups. # cell_resel_prio: Absolute priority of the carrier frequency group # ncc_permitted: 8-bit bitmap of NCC carriers permitted for monitoring diff --git a/srsenb/src/CMakeLists.txt b/srsenb/src/CMakeLists.txt index 72fa2baf6b..79f962df50 100644 --- a/srsenb/src/CMakeLists.txt +++ b/srsenb/src/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -34,15 +34,15 @@ if (RPATH) endif (RPATH) add_library(enb_cfg_parser STATIC parser.cc enb_cfg_parser.cc) -target_link_libraries(enb_cfg_parser srsran_common ${LIBCONFIGPP_LIBRARIES}) +target_link_libraries(enb_cfg_parser srsran_common srsgnb_rrc_config_utils ${LIBCONFIGPP_LIBRARIES}) -add_executable(srsenb main.cc enb.cc metrics_stdout.cc metrics_csv.cc metrics_json.cc) +add_executable(srsenb main.cc enb.cc metrics_stdout.cc metrics_csv.cc metrics_json.cc metrics_e2.cc) set(SRSENB_SOURCES srsenb_phy srsenb_stack srsenb_common srsenb_s1ap srsenb_upper srsenb_mac srsenb_rrc srslog system) set(SRSRAN_SOURCES srsran_common srsran_mac srsran_phy srsran_gtpu srsran_rlc srsran_pdcp srsran_radio rrc_asn1 s1ap_asn1 enb_cfg_parser srslog support system) -set(SRSENB_SOURCES ${SRSENB_SOURCES} srsgnb_stack srsgnb_ngap srsgnb_upper srsgnb_mac srsgnb_rrc) -set(SRSRAN_SOURCES ${SRSRAN_SOURCES} rrc_nr_asn1 ngap_nr_asn1) +set(SRSENB_SOURCES ${SRSENB_SOURCES} srsgnb_stack srsgnb_ric srsgnb_ngap srsgnb_mac srsgnb_rrc) +set(SRSRAN_SOURCES ${SRSRAN_SOURCES} rrc_nr_asn1 ngap_nr_asn1 ric_e2) target_link_libraries(srsenb ${SRSENB_SOURCES} ${SRSRAN_SOURCES} @@ -66,4 +66,4 @@ else(NOT ${BUILDENB_CMD} STREQUAL "") message(STATUS "No post-build-ENB command defined") endif (NOT ${BUILDENB_CMD} STREQUAL "") -install(TARGETS srsenb DESTINATION ${RUNTIME_DIR}) +install(TARGETS srsenb DESTINATION ${RUNTIME_DIR} OPTIONAL) diff --git a/srsenb/src/common/CMakeLists.txt b/srsenb/src/common/CMakeLists.txt index 2e8c6981db..1e52fdcc58 100644 --- a/srsenb/src/common/CMakeLists.txt +++ b/srsenb/src/common/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsenb/src/common/rnti_pool.cc b/srsenb/src/common/rnti_pool.cc index c1b8741b0d..2dddf5a788 100644 --- a/srsenb/src/common/rnti_pool.cc +++ b/srsenb/src/common/rnti_pool.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index b711c0fbb3..50e05a5a7c 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,9 +21,9 @@ #include "srsenb/hdr/enb.h" #include "srsenb/hdr/stack/enb_stack_lte.h" -#include "srsenb/hdr/stack/gnb_stack_nr.h" #include "srsenb/hdr/x2_adapter.h" #include "srsenb/src/enb_cfg_parser.h" +#include "srsgnb/hdr/stack/gnb_stack_nr.h" #include "srsran/build_info.h" #include "srsran/common/enb_events.h" #include "srsran/radio/radio_null.h" @@ -134,9 +134,8 @@ int enb::init(const all_args_t& args_) if (tmp_nr_stack) { nr_stack = std::move(tmp_nr_stack); } - phy = std::move(tmp_phy); - radio = std::move(tmp_radio); - + phy = std::move(tmp_phy); + radio = std::move(tmp_radio); started = true; // set to true in any case to allow stopping the eNB if an error happened // Now that everything is setup, log sector start events. @@ -161,6 +160,10 @@ void enb::stop() { if (started) { // tear down in reverse order + if (_e2_agent) { + _e2_agent->stop(); + } + if (phy) { phy->stop(); } @@ -200,6 +203,22 @@ void enb::start_plot() phy->start_plot(); } +bool enb::enable_e2_agent(srsenb::e2_interface_metrics* e2_metrics) +{ + std::unique_ptr tmp_e2_agent = std::unique_ptr( + new srsenb::e2_agent(srslog::fetch_basic_logger("E2_AGENT", log_sink, false), e2_metrics)); + if (tmp_e2_agent == nullptr) { + srsran::console("Error creating e2_agent instance.\n"); + return SRSRAN_ERROR; + } + if (tmp_e2_agent->init(args.e2_agent)) { + srsran::console("Error initializing e2_agent client.\n"); + return SRSRAN_ERROR; + } + _e2_agent = std::move(tmp_e2_agent); + return SRSRAN_SUCCESS; +} + void enb::print_pool() { srsran::byte_buffer_pool::get_instance()->print_all_buffers(); @@ -228,6 +247,11 @@ void enb::cmd_cell_gain(uint32_t cell_id, float gain) phy->cmd_cell_gain(cell_id, gain); } +void enb::cmd_cell_measure() +{ + phy->cmd_cell_measure(); +} + std::string enb::get_build_mode() { return std::string(srsran_get_build_mode()); @@ -263,6 +287,11 @@ void enb::tti_clock() if (!started) { return; } + + if (_e2_agent) { + _e2_agent->tic(); + } + if (eutra_stack) { eutra_stack->tti_clock(); } diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 985437f695..82bd3bd407 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,6 +21,7 @@ #include "enb_cfg_parser.h" #include "srsenb/hdr/enb.h" +#include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h" #include "srsran/asn1/rrc_utils.h" #include "srsran/common/band_helper.h" #include "srsran/common/multiqueue.h" @@ -78,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()); @@ -131,21 +165,276 @@ int field_intra_neigh_cell_list::parse(libconfig::Setting& root) int field_intra_black_cell_list::parse(libconfig::Setting& root) { - data->intra_freq_black_cell_list.resize((uint32_t)root.getLength()); - data->intra_freq_black_cell_list_present = data->intra_freq_neigh_cell_list.size() > 0; - for (uint32_t i = 0; i < data->intra_freq_black_cell_list.size() && i < ASN1_RRC_MAX_CELL_BLACK; i++) { - if (not parse_enum_by_number(data->intra_freq_black_cell_list[i].range, "range", root[i])) { - fprintf(stderr, "Missing field range in black_cell=%d\n", i); + data->intra_freq_excluded_cell_list.resize((uint32_t)root.getLength()); + data->intra_freq_excluded_cell_list_present = data->intra_freq_excluded_cell_list.size() > 0; + for (uint32_t i = 0; i < data->intra_freq_excluded_cell_list.size() && i < ASN1_RRC_MAX_EXCLUDED_CELL; i++) { + if (not parse_enum_by_number(data->intra_freq_excluded_cell_list[i].range, "range", root[i])) { + fprintf(stderr, "Missing field range in excluded_cell=%d\n", i); return SRSRAN_ERROR; } - data->intra_freq_black_cell_list[i].range_present = true; + data->intra_freq_excluded_cell_list[i].range_present = true; int start = 0; if (!root[i].lookupValue("start", start)) { - fprintf(stderr, "Missing field start in black_cell=%d\n", i); + fprintf(stderr, "Missing field start in excluded_cell=%d\n", i); + return SRSRAN_ERROR; + } + data->intra_freq_excluded_cell_list[i].start = (uint16)start; + } + return 0; +} + +int field_inter_freq_carrier_freq_list::parse(libconfig::Setting& root) +{ + data->inter_freq_carrier_freq_list.resize((uint32_t)root.getLength()); + for (uint32_t i = 0; i < data->inter_freq_carrier_freq_list.size() && i < ASN1_RRC_MAX_FREQ; i++) { + unsigned int dl_carrier_freq = 0; + if (!root[i].lookupValue("dl_carrier_freq", dl_carrier_freq)) { + ERROR("Missing field `dl_carrier_freq` in inter_freq_carrier_freq_list=%d", i); + return SRSRAN_ERROR; + } + data->inter_freq_carrier_freq_list[i].dl_carrier_freq = dl_carrier_freq; + + int q_rx_lev_min = 0; + if (!root[i].lookupValue("q_rx_lev_min", q_rx_lev_min)) { + ERROR("Missing field `q_rx_lev_min` in inter_freq_carrier_freq_list=%d", i); + return SRSRAN_ERROR; + } + data->inter_freq_carrier_freq_list[i].q_rx_lev_min = q_rx_lev_min; + + int p_max = 0; + if (root[i].lookupValue("p_max", p_max)) { + data->inter_freq_carrier_freq_list[i].p_max_present = true; + data->inter_freq_carrier_freq_list[i].p_max = p_max; + } + + unsigned int t_resel_eutra = 0; + if (!root[i].lookupValue("t_resel_eutra", t_resel_eutra)) { + ERROR("Missing field `t_resel_eutra` in inter_freq_carrier_freq_list=%d", i); + return SRSRAN_ERROR; + } + data->inter_freq_carrier_freq_list[i].t_resel_eutra = t_resel_eutra; + + if (root[i].exists("t_resel_eutra_sf")) { + data->inter_freq_carrier_freq_list[i].t_resel_eutra_sf_present = true; + + field_asn1_enum_number_str sf_medium( + "sf_medium", &data->inter_freq_carrier_freq_list[i].t_resel_eutra_sf.sf_medium); + if (sf_medium.parse(root[i]["t_resel_eutra_sf"])) { + ERROR("Error parsing `sf_medium` in inter_freq_carrier_freq_list=%d t_resel_eutra_sf", i); + return SRSRAN_ERROR; + } + + field_asn1_enum_number_str sf_high( + "sf_high", &data->inter_freq_carrier_freq_list[i].t_resel_eutra_sf.sf_high); + if (sf_high.parse(root[i]["t_resel_eutra_sf"])) { + ERROR("Error parsing `sf_high` in inter_freq_carrier_freq_list=%d t_resel_eutra_sf", i); + return SRSRAN_ERROR; + } + } + + unsigned int thresh_x_high = 0; + if (!root[i].lookupValue("thresh_x_high", thresh_x_high)) { + ERROR("Missing field `thresh_x_high` in inter_freq_carrier_freq_list=%d", i); + return SRSRAN_ERROR; + } + data->inter_freq_carrier_freq_list[i].thresh_x_high = thresh_x_high; + + unsigned int thresh_x_low = 0; + if (!root[i].lookupValue("thresh_x_low", thresh_x_low)) { + ERROR("Missing field `thresh_x_low` in inter_freq_carrier_freq_list=%d", i); + return SRSRAN_ERROR; + } + data->inter_freq_carrier_freq_list[i].thresh_x_low = thresh_x_low; + + field_asn1_enum_number allowed_meas_bw( + "allowed_meas_bw", &data->inter_freq_carrier_freq_list[i].allowed_meas_bw); + if (allowed_meas_bw.parse(root[i])) { + ERROR("Error parsing `allowed_meas_bw` in inter_freq_carrier_freq_list=%d", i); + return SRSRAN_ERROR; + } + + bool presence_ant_port1 = 0; + if (!root[i].lookupValue("presence_ant_port_1", presence_ant_port1)) { + ERROR("Missing field `presence_ant_port_1` in inter_freq_carrier_freq_list=%d", i); + return SRSRAN_ERROR; + } + data->inter_freq_carrier_freq_list[i].presence_ant_port1 = presence_ant_port1; + + unsigned int cell_resel_prio = 0; + if (root[i].lookupValue("cell_resel_prio", cell_resel_prio)) { + data->inter_freq_carrier_freq_list[i].cell_resel_prio_present = true; + data->inter_freq_carrier_freq_list[i].cell_resel_prio = cell_resel_prio; + } + + field_asn1_enum_number q_offset_freq( + "q_offset_freq", &data->inter_freq_carrier_freq_list[i].q_offset_freq); + if (!q_offset_freq.parse(root[i])) { + data->inter_freq_carrier_freq_list[i].q_offset_freq_present = true; + } + + field_asn1_bitstring_number, uint8_t> neigh_cell_cfg( + "neigh_cell_cfg", &data->inter_freq_carrier_freq_list[i].neigh_cell_cfg); + if (neigh_cell_cfg.parse(root[i])) { + ERROR("Error parsing `neigh_cell_cfg` in inter_freq_carrier_freq_list=%d", i); + return SRSRAN_ERROR; + } + + if (root[i].exists("inter_freq_neigh_cell_list")) { + auto inter_neigh_cell_list_parser = new field_inter_freq_neigh_cell_list(&data->inter_freq_carrier_freq_list[i]); + HANDLEPARSERCODE(inter_neigh_cell_list_parser->parse(root[i]["inter_freq_neigh_cell_list"])); + } + + if (root[i].exists("inter_freq_black_cell_list")) { + auto inter_black_cell_list_parser = new field_inter_freq_black_cell_list(&data->inter_freq_carrier_freq_list[i]); + HANDLEPARSERCODE(inter_black_cell_list_parser->parse(root[i]["inter_freq_black_cell_list"])); + } + } + return 0; +} + +int field_inter_freq_neigh_cell_list::parse(libconfig::Setting& root) +{ + data->inter_freq_neigh_cell_list.resize((uint32_t)root.getLength()); + data->inter_freq_neigh_cell_list_present = data->inter_freq_neigh_cell_list.size() > 0; + for (uint32_t i = 0; i < data->inter_freq_neigh_cell_list.size() && i < ASN1_RRC_MAX_EXCLUDED_CELL; i++) { + if (not parse_enum_by_number(data->inter_freq_neigh_cell_list[i].q_offset_cell, "q_offset_cell", root[i])) { + ERROR("Missing field q_offset_cell in neigh_cell=%d\n", i); + return SRSRAN_ERROR; + } + + unsigned int phys_cell_id = 0; + if (!root[i].lookupValue("phys_cell_id", phys_cell_id)) { + ERROR("Missing field phys_cell_id in neigh_cell=%d\n", i); + return SRSRAN_ERROR; + } + data->inter_freq_neigh_cell_list[i].pci = (uint16)phys_cell_id; + } + return 0; +} + +int field_inter_freq_black_cell_list::parse(libconfig::Setting& root) +{ + data->inter_freq_excluded_cell_list.resize((uint32_t)root.getLength()); + data->inter_freq_excluded_cell_list_present = data->inter_freq_excluded_cell_list.size() > 0; + for (uint32_t i = 0; i < data->inter_freq_excluded_cell_list.size() && i < ASN1_RRC_MAX_EXCLUDED_CELL; i++) { + if (not parse_enum_by_number(data->inter_freq_excluded_cell_list[i].range, "range", root[i])) { + ERROR("Missing field range in excluded_cell=%d\n", i); + return SRSRAN_ERROR; + } + data->inter_freq_excluded_cell_list[i].range_present = true; + + unsigned int start = 0; + if (!root[i].lookupValue("start", start)) { + ERROR("Missing field start in excluded_cell=%d\n", i); + return SRSRAN_ERROR; + } + data->inter_freq_excluded_cell_list[i].start = (uint16)start; + } + return 0; +} + +int field_carrier_freq_list_utra_fdd::parse(libconfig::Setting& root) +{ + data->carrier_freq_list_utra_fdd.resize((uint32_t)root.getLength()); + data->carrier_freq_list_utra_fdd_present = data->carrier_freq_list_utra_fdd.size() > 0; + for (uint32_t i = 0; i < data->carrier_freq_list_utra_fdd.size() && i < ASN1_RRC_MAX_UTRA_FDD_CARRIER; i++) { + unsigned int carrier_freq = 0; + if (!root[i].lookupValue("carrier_freq", carrier_freq)) { + fprintf(stderr, "Missing field `carrier_freq` in carrier_freq_list_utra_fdd=%d\n", i); + return SRSRAN_ERROR; + } + data->carrier_freq_list_utra_fdd[i].carrier_freq = carrier_freq; + + unsigned int cell_resel_prio = 0; + if (root[i].lookupValue("cell_resel_prio", cell_resel_prio)) { + data->carrier_freq_list_utra_fdd[i].cell_resel_prio_present = true; + data->carrier_freq_list_utra_fdd[i].cell_resel_prio = cell_resel_prio; + } + + unsigned int thresh_x_high = 0; + if (!root[i].lookupValue("thresh_x_high", thresh_x_high)) { + ERROR("Missing field `thresh_x_high` in carrier_freq_list_utra_fdd=%d", i); + return SRSRAN_ERROR; + } + data->carrier_freq_list_utra_fdd[i].thresh_x_high = thresh_x_high; + + unsigned int thresh_x_low = 0; + if (!root[i].lookupValue("thresh_x_low", thresh_x_low)) { + ERROR("Missing field `thresh_x_low` in carrier_freq_list_utra_fdd=%d", i); + return SRSRAN_ERROR; + } + data->carrier_freq_list_utra_fdd[i].thresh_x_low = thresh_x_low; + + int q_rx_lev_min = 0; + if (!root[i].lookupValue("q_rx_lev_min", q_rx_lev_min)) { + ERROR("Missing field `q_rx_lev_min` in carrier_freq_list_utra_fdd=%d", i); + return SRSRAN_ERROR; + } + data->carrier_freq_list_utra_fdd[i].q_rx_lev_min = q_rx_lev_min; + + int p_max_utra = 0; + if (!root[i].lookupValue("p_max_utra", p_max_utra)) { + ERROR("Missing field `p_max_utra` in carrier_freq_list_utra_fdd=%d", i); + return SRSRAN_ERROR; + } + data->carrier_freq_list_utra_fdd[i].p_max_utra = p_max_utra; + + int q_qual_min = 0; + if (!root[i].lookupValue("q_qual_min", q_qual_min)) { + ERROR("Missing field `q_qual_min` in carrier_freq_list_utra_fdd=%d", i); + return SRSRAN_ERROR; + } + data->carrier_freq_list_utra_fdd[i].q_qual_min = q_qual_min; + } + return 0; +} + +int field_carrier_freq_list_utra_tdd::parse(libconfig::Setting& root) +{ + data->carrier_freq_list_utra_tdd.resize((uint32_t)root.getLength()); + data->carrier_freq_list_utra_tdd_present = data->carrier_freq_list_utra_tdd.size() > 0; + for (uint32_t i = 0; i < data->carrier_freq_list_utra_tdd.size() && i < ASN1_RRC_MAX_UTRA_TDD_CARRIER; i++) { + unsigned int carrier_freq = 0; + if (!root[i].lookupValue("carrier_freq", carrier_freq)) { + fprintf(stderr, "Missing field `carrier_freq` in carrier_freq_list_utra_tdd=%d\n", i); return SRSRAN_ERROR; } - data->intra_freq_black_cell_list[i].start = (uint16)start; + data->carrier_freq_list_utra_tdd[i].carrier_freq = carrier_freq; + + unsigned int cell_resel_prio = 0; + if (root[i].lookupValue("cell_resel_prio", cell_resel_prio)) { + data->carrier_freq_list_utra_tdd[i].cell_resel_prio_present = true; + data->carrier_freq_list_utra_tdd[i].cell_resel_prio = cell_resel_prio; + } + + unsigned int thresh_x_high = 0; + if (!root[i].lookupValue("thresh_x_high", thresh_x_high)) { + ERROR("Missing field `thresh_x_high` in carrier_freq_list_utra_tdd=%d", i); + return SRSRAN_ERROR; + } + data->carrier_freq_list_utra_tdd[i].thresh_x_high = thresh_x_high; + + unsigned int thresh_x_low = 0; + if (!root[i].lookupValue("thresh_x_low", thresh_x_low)) { + ERROR("Missing field `thresh_x_low` in carrier_freq_list_utra_tdd=%d", i); + return SRSRAN_ERROR; + } + data->carrier_freq_list_utra_tdd[i].thresh_x_low = thresh_x_low; + + int q_rx_lev_min = 0; + if (!root[i].lookupValue("q_rx_lev_min", q_rx_lev_min)) { + ERROR("Missing field `q_rx_lev_min` in carrier_freq_list_utra_tdd=%d", i); + return SRSRAN_ERROR; + } + data->carrier_freq_list_utra_tdd[i].q_rx_lev_min = q_rx_lev_min; + + int p_max_utra = 0; + if (!root[i].lookupValue("p_max_utra", p_max_utra)) { + ERROR("Missing field `p_max_utra` in carrier_freq_list_utra_tdd=%d", i); + return SRSRAN_ERROR; + } + data->carrier_freq_list_utra_tdd[i].p_max_utra = p_max_utra; } return 0; } @@ -174,7 +463,7 @@ int field_carrier_freqs_info_list::parse(libconfig::Setting& root) field_asn1_bitstring_number, uint8_t> ncc_permitted( "ncc_permitted", &data->carrier_freqs_info_list[i].common_info.ncc_permitted); if (ncc_permitted.parse(root[i])) { - ERROR("Error parsing `ncc_permitted` in carrier_freqs_info_lsit=%d", i); + ERROR("Error parsing `ncc_permitted` in carrier_freqs_info_list=%d", i); return SRSRAN_ERROR; } @@ -643,6 +932,262 @@ int field_qci::parse(libconfig::Setting& root) return 0; } +int field_5g_srb::parse(libconfig::Setting& root) +{ + // Parse RLC AM section + asn1::rrc_nr::rlc_cfg_c* rlc_cfg = &cfg.rlc_cfg; + if (root.exists("ul_am") && root.exists("dl_am")) { + rlc_cfg->set_am(); + cfg.present = true; + } + + // RLC-UM must not exist in this section + if (root.exists("ul_um") || root.exists("dl_um")) { + ERROR("Error SRBs must be AM."); + return SRSRAN_ERROR; + } + + // Parse RLC-AM section + if (root.exists("ul_am")) { + asn1::rrc_nr::ul_am_rlc_s& ul_am_rlc = rlc_cfg->am().ul_am_rlc; + + // SN length + field_asn1_enum_number rlc_sn_size_ul("sn_field_len", &ul_am_rlc.sn_field_len); + if (rlc_sn_size_ul.parse(root["ul_am"]) == SRSRAN_ERROR) { + ul_am_rlc.sn_field_len_present = false; + } else { + ul_am_rlc.sn_field_len_present = true; + } + + field_asn1_enum_number t_poll_retx("t_poll_retx", &ul_am_rlc.t_poll_retx); + if (t_poll_retx.parse(root["ul_am"])) { + ERROR("Error can't find t_poll_retx in section ul_am"); + return SRSRAN_ERROR; + } + + field_asn1_enum_number poll_pdu("poll_pdu", &ul_am_rlc.poll_pdu); + if (poll_pdu.parse(root["ul_am"])) { + ERROR("Error can't find poll_pdu in section ul_am"); + return SRSRAN_ERROR; + } + + field_asn1_enum_number poll_byte("poll_byte", &ul_am_rlc.poll_byte); + if (poll_byte.parse(root["ul_am"])) { + ERROR("Error can't find poll_byte in section ul_am"); + return SRSRAN_ERROR; + } + + field_asn1_enum_number max_retx_thresh("max_retx_thres", + &ul_am_rlc.max_retx_thres); + if (max_retx_thresh.parse(root["ul_am"])) { + ERROR("Error can't find max_retx_thresh in section ul_am"); + return SRSRAN_ERROR; + } + } + + if (root.exists("dl_am")) { + asn1::rrc_nr::dl_am_rlc_s& dl_am_rlc = rlc_cfg->am().dl_am_rlc; + + // SN length + field_asn1_enum_number rlc_sn_size_ul("sn_field_len", &dl_am_rlc.sn_field_len); + if (rlc_sn_size_ul.parse(root["dl_am"]) == SRSRAN_ERROR) { + dl_am_rlc.sn_field_len_present = false; + } else { + dl_am_rlc.sn_field_len_present = true; + } + + field_asn1_enum_number t_reassembly("t_reassembly", &dl_am_rlc.t_reassembly); + if (t_reassembly.parse(root["dl_am"])) { + ERROR("Error can't find t_reordering in section dl_am"); + return SRSRAN_ERROR; + } + + field_asn1_enum_number t_status_prohibit("t_status_prohibit", + &dl_am_rlc.t_status_prohibit); + if (t_status_prohibit.parse(root["dl_am"])) { + ERROR("Error can't find t_status_prohibit in section dl_am"); + return SRSRAN_ERROR; + } + } + + return 0; +} + +int field_five_qi::parse(libconfig::Setting& root) +{ + uint32_t nof_five_qi = (uint32_t)root.getLength(); + for (uint32_t i = 0; i < nof_five_qi; i++) { + libconfig::Setting& q = root[i]; + + uint32_t five_qi = q["five_qi"]; + + rrc_nr_cfg_five_qi_t five_qi_cfg; + + // Parse PDCP section + if (!q.exists("pdcp_nr_config")) { + fprintf(stderr, "Error section pdcp_nr_config not found for 5qi=%d\n", five_qi); + return SRSRAN_ERROR; + } + libconfig::Setting& pdcp_nr = q["pdcp_nr_config"]; + asn1::rrc_nr::pdcp_cfg_s* pdcp_cfg = &five_qi_cfg.pdcp_cfg; + + // Get PDCP-NR DRB configs + if (!pdcp_nr.exists("drb")) { + fprintf(stderr, "Error section drb not found for 5QI=%d\n", five_qi); + return SRSRAN_ERROR; + } + libconfig::Setting& drb = pdcp_nr["drb"]; + asn1::rrc_nr::pdcp_cfg_s::drb_s_* drb_cfg = &pdcp_cfg->drb; + pdcp_cfg->drb_present = true; + + // PDCP SN size UL + field_asn1_enum_number pdcp_sn_size_ul( + "pdcp_sn_size_ul", &drb_cfg->pdcp_sn_size_ul); + if (pdcp_sn_size_ul.parse(drb) == SRSRAN_ERROR) { + drb_cfg->pdcp_sn_size_ul_present = false; + } else { + drb_cfg->pdcp_sn_size_ul_present = true; + } + + // PDCP SN size DL + field_asn1_enum_number pdcp_sn_size_dl( + "pdcp_sn_size_dl", &drb_cfg->pdcp_sn_size_dl); + if (pdcp_sn_size_dl.parse(drb) == SRSRAN_ERROR) { + drb_cfg->pdcp_sn_size_dl_present = false; + } else { + drb_cfg->pdcp_sn_size_dl_present = true; + } + + // Discard timer + field_asn1_enum_number discard_timer("discard_timer", + &drb_cfg->discard_timer); + if (discard_timer.parse(drb) == -1) { + drb_cfg->discard_timer_present = false; + } else { + drb_cfg->discard_timer_present = true; + } + + parser::field status_report_required("status_report_required", &drb_cfg->status_report_required_present); + status_report_required.parse(drb); + + parser::field out_of_order_delivery("out_of_order_delivery", &drb_cfg->out_of_order_delivery_present); + out_of_order_delivery.parse(drb); + + parser::field integrity_protection("integrity_protection", &drb_cfg->integrity_protection_present); + integrity_protection.parse(drb); + + drb_cfg->hdr_compress.set_not_used(); + // Finish DRB config + + // t_Reordering + field_asn1_enum_number t_reordering("t_reordering", + &pdcp_cfg->t_reordering); + if (t_reordering.parse(pdcp_nr) == SRSRAN_ERROR) { + pdcp_cfg->t_reordering_present = false; + } else { + pdcp_cfg->t_reordering_present = true; + } + + // Parse RLC section + if (!q.exists("rlc_config")) { + fprintf(stderr, "Error section rlc_config not found for 5qi=%d\n", five_qi); + return SRSRAN_ERROR; + } + libconfig::Setting& rlc = q["rlc_config"]; + asn1::rrc_nr::rlc_cfg_c* rlc_cfg = &five_qi_cfg.rlc_cfg; + if (rlc.exists("um_uni_dir_ul") || rlc.exists("um_uni_dir_dl")) { + // Sanity check: RLC UM uni-directional is not supported. + fprintf(stderr, "Error uni-directional UM not supported. 5QI=%d\n", five_qi); + return SRSRAN_ERROR; + } + + if (rlc.exists("am")) { + rlc_cfg->set_am(); + } else if (rlc.exists("um_bi_dir")) { + rlc_cfg->set_um_bi_dir(); + } else { + fprintf(stderr, "Invalid combination of UL/DL UM/AM for 5QI=%d\n", five_qi); + return SRSRAN_ERROR; + } + + // Parse RLC-AM section + if (rlc_cfg->type() == asn1::rrc_nr::rlc_cfg_c::types::am) { + libconfig::Setting& rlc_am = rlc["am"]; + libconfig::Setting& rlc_am_ul = rlc_am["ul_am"]; + libconfig::Setting& rlc_am_dl = rlc_am["dl_am"]; + asn1::rrc_nr::ul_am_rlc_s& ul_am_cfg = rlc_cfg->am().ul_am_rlc; + asn1::rrc_nr::dl_am_rlc_s& dl_am_cfg = rlc_cfg->am().dl_am_rlc; + + // RLC AM UL + // SN length + field_asn1_enum_number rlc_sn_size_ul("sn_field_len", &ul_am_cfg.sn_field_len); + if (rlc_sn_size_ul.parse(rlc_am_ul) == SRSRAN_ERROR) { + ul_am_cfg.sn_field_len_present = false; + } else { + ul_am_cfg.sn_field_len_present = true; + } + // t-PollRetx + field_asn1_enum_number rlc_t_poll_retx("t_poll_retx", &ul_am_cfg.t_poll_retx); + rlc_t_poll_retx.parse(rlc_am_ul); + // pollPDU + field_asn1_enum_number rlc_poll_pdu("poll_pdu", &ul_am_cfg.poll_pdu); + rlc_poll_pdu.parse(rlc_am_ul); + // pollBYTE + field_asn1_enum_number rlc_poll_bytes("poll_byte", &ul_am_cfg.poll_byte); + rlc_poll_bytes.parse(rlc_am_ul); + // maxRetxThreshold + field_asn1_enum_number rlc_max_retx_thres( + "max_retx_thres", &ul_am_cfg.max_retx_thres); + rlc_max_retx_thres.parse(rlc_am_ul); + + // RLC AM DL + // SN length + field_asn1_enum_number rlc_sn_size_dl("sn_field_len", &dl_am_cfg.sn_field_len); + if (rlc_sn_size_dl.parse(rlc_am_dl) == SRSRAN_ERROR) { + dl_am_cfg.sn_field_len_present = false; + } else { + dl_am_cfg.sn_field_len_present = true; + } + // t-reassembly + field_asn1_enum_number rlc_t_reassembly("t_reassembly", &dl_am_cfg.t_reassembly); + rlc_t_reassembly.parse(rlc_am_dl); + // t-statusProhibit + field_asn1_enum_number rlc_status_prohibit("t_status_prohibit", + &dl_am_cfg.t_status_prohibit); + rlc_status_prohibit.parse(rlc_am_dl); + } else if (rlc_cfg->type() == asn1::rrc_nr::rlc_cfg_c::types::um_bi_dir) { + libconfig::Setting& rlc_um = rlc["um_bi_dir"]; + libconfig::Setting& rlc_um_ul = rlc_um["ul_um"]; + libconfig::Setting& rlc_um_dl = rlc_um["dl_um"]; + asn1::rrc_nr::ul_um_rlc_s& ul_um_cfg = rlc_cfg->um_bi_dir().ul_um_rlc; + asn1::rrc_nr::dl_um_rlc_s& dl_um_cfg = rlc_cfg->um_bi_dir().dl_um_rlc; + + // RLC UM UL + // SN field length + field_asn1_enum_number rlc_sn_size_ul("sn_field_len", &ul_um_cfg.sn_field_len); + if (rlc_sn_size_ul.parse(rlc_um_ul) == SRSRAN_ERROR) { + ul_um_cfg.sn_field_len_present = false; + } else { + ul_um_cfg.sn_field_len_present = true; + } + + // RLC UM DL + // SN field length + field_asn1_enum_number rlc_sn_size_dl("sn_field_len", &dl_um_cfg.sn_field_len); + if (rlc_sn_size_dl.parse(rlc_um_dl) == SRSRAN_ERROR) { + dl_um_cfg.sn_field_len_present = false; + } else { + dl_um_cfg.sn_field_len_present = true; + } + // t-reassembly + field_asn1_enum_number rlc_t_reassembly_dl("t_reassembly", &dl_um_cfg.t_reassembly); + rlc_t_reassembly_dl.parse(rlc_um_dl); + } + + cfg.insert(std::make_pair(five_qi, five_qi_cfg)); + } + return 0; +} namespace rr_sections { int parse_rr(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr_cfg_) @@ -784,6 +1329,7 @@ static int parse_meas_cell_list(rrc_meas_cfg_t* meas_cfg, Setting& root) parse_default_field(cell.allowed_meas_bw, root[i], "allowed_meas_bw", 6u); asn1_parsers::default_number_to_enum( cell.cell_individual_offset, root[i], "cell_individual_offset", asn1::rrc::q_offset_range_opts::db0); + parse_default_field(cell.tac, root[i], "tac", -1); srsran_assert(srsran::is_lte_cell_nof_prb(cell.allowed_meas_bw), "Invalid measurement Bandwidth"); } return 0; @@ -853,8 +1399,35 @@ static int parse_meas_report_desc(rrc_meas_cfg_t* meas_cfg, Setting& cellroot) rrc_value_to_range(srsran::quant_rsrq, (int)root[i]["a4_thresh"]); } break; + case 5: + // a5-threshold1 + if (!root[i].exists("a5_thresh1")) { + ERROR("Missing a5_thresh1 field for A5 event\n"); + return SRSRAN_ERROR; + } + if (meas_item.trigger_quant == report_cfg_eutra_s::trigger_quant_opts::rsrp) { + event.event_id.set_event_a5().a5_thres1.set_thres_rsrp() = + rrc_value_to_range(srsran::quant_rsrp, (int)root[i]["a5_thresh1"]); + } else { + event.event_id.set_event_a5().a5_thres1.set_thres_rsrq() = + rrc_value_to_range(srsran::quant_rsrq, (int)root[i]["a5_thresh1"]); + } + + // a5-threshold2 + if (!root[i].exists("a5_thresh2")) { + ERROR("Missing a5_thresh2 field for A5 event\n"); + return SRSRAN_ERROR; + } + if (meas_item.trigger_quant == report_cfg_eutra_s::trigger_quant_opts::rsrp) { + event.event_id.set_event_a5().a5_thres2.set_thres_rsrp() = + rrc_value_to_range(srsran::quant_rsrp, (int)root[i]["a5_thresh2"]); + } else { + event.event_id.set_event_a5().a5_thres2.set_thres_rsrq() = + rrc_value_to_range(srsran::quant_rsrq, (int)root[i]["a5_thresh2"]); + } + break; default: - ERROR("Invalid or unsupported event A%d in meas_report_desc (only A1-A4 are supported)\n", + ERROR("Invalid or unsupported event A%d in meas_report_desc (only A1-A5 are supported)\n", (int)root[i]["eventA"]); return SRSRAN_ERROR; } @@ -906,6 +1479,7 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) HANDLEPARSERCODE(parse_required_field(cell_cfg.cell_id, cellroot, "cell_id")); HANDLEPARSERCODE(parse_required_field(cell_cfg.tac, cellroot, "tac")); HANDLEPARSERCODE(parse_required_field(cell_cfg.pci, cellroot, "pci")); + parse_default_field(cell_cfg.tx_gain, cellroot, "tx_gain", 0.0); cell_cfg.pci = cell_cfg.pci % SRSRAN_NUM_PCI; HANDLEPARSERCODE(parse_required_field(cell_cfg.dl_earfcn, cellroot, "dl_earfcn")); parse_default_field(cell_cfg.dl_freq_hz, cellroot, "dl_freq", 0.0); // will be derived from DL EARFCN If not set @@ -940,6 +1514,10 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) HANDLEPARSERCODE(parse_meas_report_desc(&cell_cfg.meas_cfg, cellroot)); } + if (cellroot.exists("barred") and cellroot["barred"]) { + cell_cfg.barred = true; + } + if (cellroot.exists("scell_list")) { HANDLEPARSERCODE(parse_scell_list(cell_cfg, cellroot)); } @@ -948,7 +1526,16 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) } // Configuration check + // counter for every RF port used by the eNB to avoid misconfiguration/mapping of cells + uint32_t next_rf_port = 0; for (auto it = rrc_cfg->cell_list.begin(); it != rrc_cfg->cell_list.end(); it++) { + // Make sure RF ports are assigned in order + if (it->rf_port != next_rf_port) { + ERROR("RF ports need to be in order starting with 0 (%d != %d)", it->rf_port, next_rf_port); + return SRSRAN_ERROR; + } + next_rf_port++; + for (auto it2 = it + 1; it2 != rrc_cfg->cell_list.end(); it2++) { // Check RF port is not repeated if (it->rf_port == it2->rf_port) { @@ -970,13 +1557,16 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) static int parse_nr_cell_list(all_args_t* args, rrc_nr_cfg_t* rrc_cfg_nr, rrc_cfg_t* rrc_cfg_eutra, Setting& root) { for (uint32_t n = 0; n < (uint32_t)root.getLength(); ++n) { + auto& cellroot = root[n]; + rrc_cell_cfg_nr_t cell_cfg = {}; - auto& cellroot = root[n]; + generate_default_nr_cell(cell_cfg); parse_opt_field(cell_cfg.phy_cell.rf_port, cellroot, "rf_port"); HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.carrier.pci, cellroot, "pci")); HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.cell_id, cellroot, "cell_id")); - HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.root_seq_idx, cellroot, "root_seq_idx")); + HANDLEPARSERCODE(parse_opt_field(cell_cfg.coreset0_idx, cellroot, "coreset0_idx")); + HANDLEPARSERCODE(parse_required_field(cell_cfg.prach_root_seq_idx, cellroot, "root_seq_idx")); HANDLEPARSERCODE(parse_required_field(cell_cfg.tac, cellroot, "tac")); cell_cfg.phy_cell.carrier.pci = cell_cfg.phy_cell.carrier.pci % SRSRAN_NOF_NID_NR; @@ -992,8 +1582,17 @@ static int parse_nr_cell_list(all_args_t* args, rrc_nr_cfg_t* rrc_cfg_nr, rrc_cf srsran::srsran_band_helper band_helper; // Configuration check + // counter for every RF port used by the eNB to avoid misconfiguration/mapping of cells + uint32_t next_rf_port = rrc_cfg_eutra->cell_list.size(); for (auto it = rrc_cfg_nr->cell_list.begin(); it != rrc_cfg_nr->cell_list.end(); ++it) { - // check against NR cells + // Make sure RF ports are assigned in order + if (it->phy_cell.rf_port != next_rf_port) { + ERROR("RF ports need to be in order starting with 0 (%d != %d)", it->phy_cell.rf_port, next_rf_port); + return SRSRAN_ERROR; + } + next_rf_port++; + + // check against other NR cells for (auto it2 = it + 1; it2 != rrc_cfg_nr->cell_list.end(); it2++) { // Check RF port is not repeated if (it->phy_cell.rf_port == it2->phy_cell.rf_port) { @@ -1050,9 +1649,9 @@ static int parse_nr_cell_list(all_args_t* args, rrc_nr_cfg_t* rrc_cfg_nr, rrc_cf if (it->ul_arfcn != 0) { // Check if ul_arfcn is valid for the given band bool ul_arfcn_valid = false; - std::vector bands = band_helper.get_bands_nr(it->ul_arfcn); - for (uint32_t band_idx = 0; band_idx < bands.size(); band_idx++) { - if (bands.at(band_idx) == it->band) { + std::vector ul_bands = band_helper.get_bands_nr(it->ul_arfcn); + for (uint32_t band_idx = 0; band_idx < ul_bands.size(); band_idx++) { + if (ul_bands.at(band_idx) == it->band) { ul_arfcn_valid = true; } } @@ -1113,6 +1712,30 @@ int parse_cell_cfg(all_args_t* args_, srsran_cell_t* cell) return SRSRAN_SUCCESS; } +// Parse the relevant CFR configuration params +int parse_cfr_args(all_args_t* args, srsran_cfr_cfg_t* cfr_config) +{ + cfr_config->cfr_enable = args->phy.cfr_args.enable; + cfr_config->cfr_mode = args->phy.cfr_args.mode; + cfr_config->alpha = args->phy.cfr_args.strength; + cfr_config->manual_thr = args->phy.cfr_args.manual_thres; + cfr_config->max_papr_db = args->phy.cfr_args.auto_target_papr; + cfr_config->ema_alpha = args->phy.cfr_args.ema_alpha; + + if (!srsran_cfr_params_valid(cfr_config)) { + fprintf(stderr, + "Invalid CFR parameters: cfr_mode=%d, alpha=%.2f, manual_thr=%.2f, \n " + "max_papr_db=%.2f, ema_alpha=%.2f\n", + cfr_config->cfr_mode, + cfr_config->alpha, + cfr_config->manual_thr, + cfr_config->max_papr_db, + cfr_config->ema_alpha); + return SRSRAN_ERROR; + } + return SRSRAN_SUCCESS; +} + int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr_cfg_, phy_cfg_t* phy_cfg_) { // Parse config files @@ -1158,18 +1781,33 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr } try { - if (drb_sections::parse_drb(args_, rrc_cfg_) != SRSRAN_SUCCESS) { - fprintf(stderr, "Error parsing DRB configuration\n"); + if (rb_sections::parse_rb(args_, rrc_cfg_, rrc_nr_cfg_) != SRSRAN_SUCCESS) { + fprintf(stderr, "Error parsing RB configuration\n"); return SRSRAN_ERROR; } } catch (const SettingTypeException& stex) { - fprintf(stderr, "Error parsing DRB configuration: %s\n", stex.getPath()); + fprintf(stderr, "Error parsing RB configuration: %s\n", stex.getPath()); return SRSRAN_ERROR; } catch (const ConfigException& cex) { - fprintf(stderr, "Error parsing DRB configuration\n"); + fprintf(stderr, "Error parsing RB configuration\n"); return SRSRAN_ERROR; } + // update number of NR cells + rrc_cfg_->num_nr_cells = rrc_nr_cfg_->cell_list.size(); + args_->rf.nof_carriers = rrc_cfg_->cell_list.size() + rrc_nr_cfg_->cell_list.size(); + ASSERT_VALID_CFG(args_->rf.nof_carriers > 0, "There must be at least one NR or LTE cell"); + if (rrc_nr_cfg_->cell_list.size() > 0) { + // NR cells available. + if (rrc_cfg_->cell_list.size() == 0) { + // SA mode. + rrc_nr_cfg_->is_standalone = true; + } else { + // NSA mode. + rrc_nr_cfg_->is_standalone = false; + } + } + // Set fields derived from others, and check for correctness of the parsed configuration if (enb_conf_sections::set_derived_args(args_, rrc_cfg_, phy_cfg_, cell_common_cfg) != SRSRAN_SUCCESS) { fprintf(stderr, "Error deriving EUTRA cell parameters\n"); @@ -1183,17 +1821,44 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr } // update number of NR cells - rrc_cfg_->num_nr_cells = rrc_nr_cfg_->cell_list.size(); - args_->rf.nof_carriers = rrc_cfg_->cell_list.size() + rrc_nr_cfg_->cell_list.size(); + if (rrc_nr_cfg_->cell_list.size() > 0) { + // NR cells available. + if (rrc_nr_cfg_->is_standalone) { + // SA mode. Update NGAP args + args_->nr_stack.ngap.cell_id = rrc_nr_cfg_->cell_list[0].phy_cell.cell_id; + args_->nr_stack.ngap.tac = rrc_nr_cfg_->cell_list[0].tac; + // take equivalent S1AP params to update NGAP params + args_->nr_stack.ngap.gnb_name = args_->stack.s1ap.enb_name; + args_->nr_stack.ngap.gnb_id = args_->enb.enb_id; + args_->nr_stack.ngap.mcc = args_->stack.s1ap.mcc; + args_->nr_stack.ngap.mnc = args_->stack.s1ap.mnc; + args_->nr_stack.ngap.gtp_bind_addr = args_->stack.s1ap.gtp_bind_addr; + args_->nr_stack.ngap.gtp_advertise_addr = args_->stack.s1ap.gtp_advertise_addr; + args_->nr_stack.ngap.amf_addr = args_->stack.s1ap.mme_addr; + args_->nr_stack.ngap.ngc_bind_addr = args_->stack.s1ap.gtp_bind_addr; + + // Parse NIA/NEA preference list (use same as LTE for now) + for (uint32_t i = 0; i < rrc_cfg_->eea_preference_list.size(); i++) { + rrc_nr_cfg_->nea_preference_list[i] = (srsran::CIPHERING_ALGORITHM_ID_NR_ENUM)rrc_cfg_->eea_preference_list[i]; + rrc_nr_cfg_->nia_preference_list[i] = (srsran::INTEGRITY_ALGORITHM_ID_NR_ENUM)rrc_cfg_->eia_preference_list[i]; + } + + } else { + // NSA mode. + // update EUTRA RRC params for ENDC + rrc_cfg_->endc_cfg.abs_frequency_ssb = rrc_nr_cfg_->cell_list.at(0).ssb_absolute_freq_point; + rrc_cfg_->endc_cfg.nr_band = rrc_nr_cfg_->cell_list.at(0).band; + rrc_cfg_->endc_cfg.ssb_period_offset.set_sf10_r15(); + rrc_cfg_->endc_cfg.ssb_duration = asn1::rrc::mtc_ssb_nr_r15_s::ssb_dur_r15_opts::sf1; + rrc_cfg_->endc_cfg.ssb_ssc = asn1::rrc::rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::khz15; + rrc_cfg_->endc_cfg.act_from_b1_event = true; // ENDC will only be activated from B1 measurment + } + } - // update EUTRA RRC params for ENDC - if (rrc_nr_cfg_->cell_list.size() == 1) { - rrc_cfg_->endc_cfg.abs_frequency_ssb = rrc_nr_cfg_->cell_list.at(0).ssb_absolute_freq_point; - rrc_cfg_->endc_cfg.nr_band = rrc_nr_cfg_->cell_list.at(0).band; - rrc_cfg_->endc_cfg.ssb_period_offset.set_sf10_r15(); - rrc_cfg_->endc_cfg.ssb_duration = asn1::rrc::mtc_ssb_nr_r15_s::ssb_dur_r15_opts::sf1; - rrc_cfg_->endc_cfg.ssb_ssc = asn1::rrc::rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::khz15; - rrc_cfg_->endc_cfg.act_from_b1_event = true; // ENDC will only be activated from B1 measurment + // Parse CFR args + if (parse_cfr_args(args_, &phy_cfg_->cfr_config) < SRSRAN_SUCCESS) { + fprintf(stderr, "Error parsing CFR configuration\n"); + return SRSRAN_ERROR; } return SRSRAN_SUCCESS; @@ -1202,51 +1867,53 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_, const srsran_cell_t& cell_cfg_) { // Sanity checks - ASSERT_VALID_CFG(not rrc_cfg_->cell_list.empty(), "No cell specified in rr.conf."); ASSERT_VALID_CFG(args_->stack.mac.nof_prealloc_ues <= SRSENB_MAX_UES, "mac.nof_prealloc_ues=%d must be within [0, %d]", args_->stack.mac.nof_prealloc_ues, SRSENB_MAX_UES); - // Check for a forced DL EARFCN or frequency (only valid for a single cell config (Xico's favorite feature)) - if (rrc_cfg_->cell_list.size() == 1) { - auto& cfg = rrc_cfg_->cell_list.at(0); - if (args_->enb.dl_earfcn > 0 and args_->enb.dl_earfcn != cfg.dl_earfcn) { - cfg.dl_earfcn = args_->enb.dl_earfcn; - ERROR("Force DL EARFCN for cell PCI=%d to %d", cfg.pci, cfg.dl_earfcn); - } - if (args_->rf.dl_freq > 0) { - cfg.dl_freq_hz = args_->rf.dl_freq; - ERROR("Force DL freq for cell PCI=%d to %f MHz", cfg.pci, cfg.dl_freq_hz / 1e6f); - } - if (args_->rf.ul_freq > 0) { - cfg.ul_freq_hz = args_->rf.ul_freq; - ERROR("Force UL freq for cell PCI=%d to %f MHz", cfg.pci, cfg.ul_freq_hz / 1e6f); - } - } else { - // If more than one cell is defined, single EARFCN or DL freq will be ignored - if (args_->enb.dl_earfcn > 0 || args_->rf.dl_freq > 0) { - INFO("Multiple cells defined in rr.conf. Ignoring single EARFCN and/or frequency config."); + // Check for a forced DL EARFCN or frequency (only valid for a single cell config + if (rrc_cfg_->cell_list.size() > 0) { + if (rrc_cfg_->cell_list.size() == 1) { + auto& cfg = rrc_cfg_->cell_list.at(0); + if (args_->enb.dl_earfcn > 0 and args_->enb.dl_earfcn != cfg.dl_earfcn) { + cfg.dl_earfcn = args_->enb.dl_earfcn; + ERROR("Force DL EARFCN for cell PCI=%d to %d", cfg.pci, cfg.dl_earfcn); + } + if (args_->rf.dl_freq > 0) { + cfg.dl_freq_hz = args_->rf.dl_freq; + ERROR("Force DL freq for cell PCI=%d to %f MHz", cfg.pci, cfg.dl_freq_hz / 1e6f); + } + if (args_->rf.ul_freq > 0) { + cfg.ul_freq_hz = args_->rf.ul_freq; + ERROR("Force UL freq for cell PCI=%d to %f MHz", cfg.pci, cfg.ul_freq_hz / 1e6f); + } + } else { + // If more than one cell is defined, single EARFCN or DL freq will be ignored + if (args_->enb.dl_earfcn > 0 || args_->rf.dl_freq > 0) { + INFO("Multiple cells defined in rr.conf. Ignoring single EARFCN and/or frequency config."); + } } - } - // set config for RRC's base cell - rrc_cfg_->cell = cell_cfg_; + // set config for RRC's base cell + rrc_cfg_->cell = cell_cfg_; - // Set S1AP related params from cell list - args_->stack.s1ap.enb_id = args_->enb.enb_id; - args_->stack.s1ap.cell_id = rrc_cfg_->cell_list.at(0).cell_id; - args_->stack.s1ap.tac = rrc_cfg_->cell_list.at(0).tac; + // Set S1AP related params from cell list + args_->stack.s1ap.enb_id = args_->enb.enb_id; + args_->stack.s1ap.cell_id = rrc_cfg_->cell_list.at(0).cell_id; + args_->stack.s1ap.tac = rrc_cfg_->cell_list.at(0).tac; + } // Create dedicated cell configuration from RRC configuration for (auto it = rrc_cfg_->cell_list.begin(); it != rrc_cfg_->cell_list.end(); ++it) { - auto& cfg = *it; + cell_cfg_t& cfg = *it; phy_cell_cfg_t phy_cell_cfg = {}; phy_cell_cfg.cell = cell_cfg_; phy_cell_cfg.cell.id = cfg.pci; phy_cell_cfg.cell_id = cfg.cell_id; phy_cell_cfg.root_seq_idx = cfg.root_seq_idx; phy_cell_cfg.rf_port = cfg.rf_port; + phy_cell_cfg.gain_db = cfg.tx_gain; phy_cell_cfg.num_ra_preambles = rrc_cfg_->sibs[1].sib2().rr_cfg_common.rach_cfg_common.preamb_info.nof_ra_preambs.to_number(); @@ -1288,6 +1955,13 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ } } + for (meas_cell_cfg_t& meas_cell : cfg.meas_cfg.meas_cells) { + if (meas_cell.tac < 0) { + // if meas cell TAC was not set, use current cell TAC. + meas_cell.tac = cfg.tac; + } + } + // Check if the enb cells PCIs won't lead to PSS detection issues auto is_pss_collision = [&cfg](const cell_cfg_t& c) { return c.pci % 3 == cfg.pci % 3 and c.dl_earfcn == cfg.dl_earfcn; @@ -1452,60 +2126,6 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ */ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_nr_cfg_, phy_cfg_t* phy_cfg_) { - // set rach cfg common - auto& rach_cfg_common = rrc_nr_cfg_->rach_cfg_common; - auto& rach_cfg_generic = rach_cfg_common.rach_cfg_generic; - - uint8_t msg1_fdm = 1; // TODO read from config - if (!asn1::number_to_enum(rach_cfg_generic.msg1_fdm, msg1_fdm)) { - ERROR("Config Error: Invalid msg1_fdm (%d)\n", msg1_fdm); - return SRSRAN_ERROR; - } - - rach_cfg_generic.preamb_rx_target_pwr = -110; // TODO read from config - - uint8_t preamb_trans_max = 7; // TODO read from config - if (!asn1::number_to_enum(rach_cfg_generic.preamb_trans_max, preamb_trans_max)) { - ERROR("Config Error: Invalid preamble_trans_max (%d)\n", preamb_trans_max); - return SRSRAN_ERROR; - } - - uint8_t pwr_ramp_step = 4; // TODO read from config - if (!asn1::number_to_enum(rach_cfg_generic.pwr_ramp_step, pwr_ramp_step)) { - ERROR("Config Error: Invalid pwr_ramp_step (%d)\n", pwr_ramp_step); - return SRSRAN_ERROR; - } - - uint8_t ra_resp_win_size = 10; // TODO read from config - if (!asn1::number_to_enum(rach_cfg_generic.ra_resp_win, ra_resp_win_size)) { - ERROR("Config Error: Invalid ra_resp_win_size (%d)\n", ra_resp_win_size); - return SRSRAN_ERROR; - } - - uint8_t ra_contention_resolution_timer = 64; // TODO read from config - if (!asn1::number_to_enum(rach_cfg_common.ra_contention_resolution_timer, ra_contention_resolution_timer)) { - ERROR("Config Error: Invalid mac_con_res_timer (%d)\n", ra_contention_resolution_timer); - return SRSRAN_ERROR; - } - - rrc_nr_cfg_->prach_root_seq_idx_type = 839; // TODO read from config - - std::string restricted_set_cfg = "unrestrictedSet"; // TODO read from config - asn1::rrc_nr::rach_cfg_common_s::prach_root_seq_idx_c_::types_opts root_seq_idx_type; - if (!asn1::string_to_enum(rach_cfg_common.restricted_set_cfg, restricted_set_cfg)) { - ERROR("Config Error: Invalid restricted_set_cfg (%s)\n", restricted_set_cfg.c_str()); - return SRSRAN_ERROR; - } - - rach_cfg_common.ssb_per_rach_occasion_and_cb_preambs_per_ssb_present = true; - rach_cfg_common.ssb_per_rach_occasion_and_cb_preambs_per_ssb.set_one(); // TODO read from config - - uint8_t one_opts = 64; // TODO read from config - if (!asn1::number_to_enum(rach_cfg_common.ssb_per_rach_occasion_and_cb_preambs_per_ssb.one(), one_opts)) { - ERROR("Config Error: Invalid one_opts (%d)\n", one_opts); - return SRSRAN_ERROR; - } - // Use helper class to derive NR carrier parameters srsran::srsran_band_helper band_helper; @@ -1515,9 +2135,10 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_nr_cfg_, phy_cfg_t* return SRSRAN_ERROR; } + rrc_nr_cfg_->inactivity_timeout_ms = args_->general.rrc_inactivity_timer; + // Create NR dedicated cell configuration from RRC configuration - for (auto it = rrc_nr_cfg_->cell_list.begin(); it != rrc_nr_cfg_->cell_list.end(); ++it) { - auto& cfg = *it; + for (auto& cfg : rrc_nr_cfg_->cell_list) { cfg.phy_cell.carrier.max_mimo_layers = args_->enb.nof_ports; // NR cells have the same bandwidth as EUTRA cells, adjust PRB sizes @@ -1535,122 +2156,24 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_nr_cfg_, phy_cfg_t* ERROR("The only accepted number of PRB is: 25, 50, 100"); return SRSRAN_ERROR; } - // phy_cell_cfg.root_seq_idx = cfg.root_seq_idx; - cfg.phy_cell.num_ra_preambles = 52; // FIXME: read from config - - if (cfg.phy_cell.dl_freq_hz == 0) { - cfg.phy_cell.dl_freq_hz = band_helper.nr_arfcn_to_freq(cfg.dl_arfcn); - } - if (cfg.phy_cell.ul_freq_hz == 0) { - // auto-detect UL frequency - if (cfg.ul_arfcn == 0) { - // derive UL ARFCN from given DL ARFCN - cfg.ul_arfcn = band_helper.get_ul_arfcn_from_dl_arfcn(cfg.dl_arfcn); - if (cfg.ul_arfcn == 0) { - ERROR("Can't derive UL ARFCN from DL ARFCN %d", cfg.dl_arfcn); - return SRSRAN_ERROR; - } - } - cfg.phy_cell.ul_freq_hz = band_helper.nr_arfcn_to_freq(cfg.ul_arfcn); - } - - // duplex mode - cfg.duplex_mode = band_helper.get_duplex_mode(cfg.band); - - // PRACH - cfg.phy_cell.prach.is_nr = true; - cfg.phy_cell.prach.config_idx = 8; - cfg.phy_cell.prach.root_seq_idx = 0; - cfg.phy_cell.prach.freq_offset = 1; - cfg.phy_cell.prach.num_ra_preambles = cfg.phy_cell.num_ra_preambles; - cfg.phy_cell.prach.hs_flag = phy_cfg_->prach_cnfg.prach_cfg_info.high_speed_flag; - cfg.phy_cell.prach.tdd_config.configured = (cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD); - - // PDCCH - // Configure CORESET ID 1 - cfg.phy_cell.pdcch.coreset_present[1] = true; - cfg.phy_cell.pdcch.coreset[1].id = 1; - cfg.phy_cell.pdcch.coreset[1].duration = 1; - cfg.phy_cell.pdcch.coreset[1].mapping_type = srsran_coreset_mapping_type_non_interleaved; - cfg.phy_cell.pdcch.coreset[1].precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle; - - // Generate frequency resources for the full BW - for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { - cfg.phy_cell.pdcch.coreset[1].freq_resources[i] = i < SRSRAN_FLOOR(cfg.phy_cell.carrier.nof_prb, 6); - } - - // Configure Search Space 1 as common - cfg.phy_cell.pdcch.search_space_present[1] = true; - cfg.phy_cell.pdcch.search_space[1].id = 1; - cfg.phy_cell.pdcch.search_space[1].coreset_id = 1; - cfg.phy_cell.pdcch.search_space[1].duration = 1; - cfg.phy_cell.pdcch.search_space[1].formats[0] = srsran_dci_format_nr_0_0; // DCI format for PUSCH - cfg.phy_cell.pdcch.search_space[1].formats[1] = srsran_dci_format_nr_1_0; // DCI format for PDSCH - cfg.phy_cell.pdcch.search_space[1].nof_formats = 2; - cfg.phy_cell.pdcch.search_space[1].type = srsran_search_space_type_common_3; - - // Generate 1 candidate for each aggregation level if possible - for (uint32_t L = 0; L < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR; L++) { - cfg.phy_cell.pdcch.search_space[1].nof_candidates[L] = - SRSRAN_MIN(2, srsran_pdcch_nr_max_candidates_coreset(&cfg.phy_cell.pdcch.coreset[1], L)); - } - - cfg.phy_cell.pdcch.ra_search_space_present = true; - cfg.phy_cell.pdcch.ra_search_space = cfg.phy_cell.pdcch.search_space[1]; - cfg.phy_cell.pdcch.ra_search_space.type = srsran_search_space_type_common_1; + // phy_cell_cfg.root_seq_idx = cfg.root_seq_idx; // PDSCH - cfg.phy_cell.pdsch.rs_power = phy_cfg_->pdsch_cnfg.ref_sig_pwr; - cfg.phy_cell.pdsch.p_b = phy_cfg_->pdsch_cnfg.p_b; - - // copy center frequencies - cfg.phy_cell.carrier.dl_center_frequency_hz = cfg.phy_cell.dl_freq_hz; - cfg.phy_cell.carrier.ul_center_frequency_hz = cfg.phy_cell.ul_freq_hz; - - cfg.dl_absolute_freq_point_a = band_helper.get_abs_freq_point_a_arfcn(cfg.phy_cell.carrier.nof_prb, cfg.dl_arfcn); - cfg.ul_absolute_freq_point_a = band_helper.get_abs_freq_point_a_arfcn(cfg.phy_cell.carrier.nof_prb, cfg.ul_arfcn); - - // Calculate SSB params depending on band/duplex - cfg.ssb_cfg.duplex_mode = band_helper.get_duplex_mode(cfg.band); - cfg.ssb_cfg.pattern = band_helper.get_ssb_pattern(cfg.band, srsran_subcarrier_spacing_15kHz); - if (cfg.ssb_cfg.pattern == SRSRAN_SSB_PATTERN_A) { - // 15kHz SSB SCS - cfg.ssb_cfg.scs = srsran_subcarrier_spacing_15kHz; - } else { - // try to optain SSB pattern for same band with 30kHz SCS - cfg.ssb_cfg.pattern = band_helper.get_ssb_pattern(cfg.band, srsran_subcarrier_spacing_30kHz); - if (cfg.ssb_cfg.pattern == SRSRAN_SSB_PATTERN_B || cfg.ssb_cfg.pattern == SRSRAN_SSB_PATTERN_C) { - // SSB SCS is 30 kHz - cfg.ssb_cfg.scs = srsran_subcarrier_spacing_30kHz; - } else { - ERROR("Can't derive SSB pattern for band %d", cfg.band); - return SRSRAN_ERROR; - } - } - - // fill remaining SSB fields - cfg.ssb_absolute_freq_point = - band_helper.get_abs_freq_ssb_arfcn(cfg.band, cfg.ssb_cfg.scs, cfg.dl_absolute_freq_point_a); - if (cfg.ssb_absolute_freq_point == 0) { - ERROR("Can't derive SSB freq point for dl_arfcn %d and band %d", cfg.dl_arfcn, cfg.band); - return SRSRAN_ERROR; - } - - // Convert to frequency for PHY - cfg.phy_cell.carrier.ssb_center_freq_hz = band_helper.nr_arfcn_to_freq(cfg.ssb_absolute_freq_point); + cfg.pdsch_rs_power = phy_cfg_->pdsch_cnfg.ref_sig_pwr; + } + rrc_nr_cfg_->enb_id = args_->enb.enb_id; + rrc_nr_cfg_->mcc = args_->stack.s1ap.mcc; + rrc_nr_cfg_->mnc = args_->stack.s1ap.mnc; - cfg.ssb_cfg.center_freq_hz = cfg.phy_cell.carrier.dl_center_frequency_hz; - cfg.ssb_cfg.ssb_freq_hz = cfg.phy_cell.carrier.ssb_center_freq_hz; - cfg.ssb_cfg.periodicity_ms = 10; // TODO: make a param - cfg.ssb_cfg.beta_pss = 0.0; - cfg.ssb_cfg.beta_sss = 0.0; - cfg.ssb_cfg.beta_pbch = 0.0; - cfg.ssb_cfg.beta_pbch_dmrs = 0.0; - // set by PHY layer in worker_pool::set_common_cfg - cfg.ssb_cfg.srate_hz = 0.0; - cfg.ssb_cfg.scaling = 0.0; + // Derive cross-dependent cell params + if (set_derived_nr_rrc_params(*rrc_nr_cfg_) != SRSRAN_SUCCESS) { + ERROR("Failed to derive NR cell params."); + return SRSRAN_ERROR; + } + // Update PHY with RRC cell configs + for (auto& cfg : rrc_nr_cfg_->cell_list) { phy_cfg_->phy_cell_cfg_nr.push_back(cfg.phy_cell); } @@ -1658,6 +2181,14 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_nr_cfg_, phy_cfg_t* args_->nr_stack.mac.pcap.enable = args_->stack.mac_pcap.enable; args_->nr_stack.log = args_->stack.log; + // Sanity check for unsupported/untested configuration + for (auto& cfg : rrc_nr_cfg_->cell_list) { + if (cfg.phy_cell.carrier.nof_prb != 52) { + ERROR("Only 10 MHz bandwidth supported."); + return SRSRAN_ERROR; + } + } + return SRSRAN_SUCCESS; } @@ -1676,6 +2207,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); @@ -1722,7 +2260,7 @@ int parse_sib2(std::string filename, sib_type2_s* data) acbarring_data.add_field( make_asn1_enum_number_str_parser("factor", &data->ac_barr_info.ac_barr_for_mo_data.ac_barr_factor)); - acbarring_data.add_field(make_asn1_enum_number_parser("fime", &data->ac_barr_info.ac_barr_for_mo_data.ac_barr_time)); + acbarring_data.add_field(make_asn1_enum_number_parser("time", &data->ac_barr_info.ac_barr_for_mo_data.ac_barr_time)); acbarring_data.add_field(make_asn1_bitstring_number_parser( "for_special_ac", &data->ac_barr_info.ac_barr_for_mo_data.ac_barr_for_special_ac)); @@ -1959,12 +2497,62 @@ int parse_sib4(std::string filename, sib_type4_s* data) return parser::parse_section(std::move(filename), &sib4); } +int parse_sib5(std::string filename, sib_type5_s* data) +{ + parser::section sib5("sib5"); + + // interFreqCarrierFreqList + parser::section inter_freq_carrier_freq_list("inter_freq_carrier_freq_list"); + sib5.add_subsection(&inter_freq_carrier_freq_list); + bool dummy_bool = false; + inter_freq_carrier_freq_list.set_optional(&dummy_bool); + inter_freq_carrier_freq_list.add_field(new field_inter_freq_carrier_freq_list(data)); + + return parser::parse_section(std::move(filename), &sib5); +} + +int parse_sib6(std::string filename, sib_type6_s* data) +{ + parser::section sib6("sib6"); + + // t-ReselectionUTRA + sib6.add_field(new parser::field("t_resel_utra", &data->t_resel_utra)); + + // t-ReselectionUTRA-SF + parser::section t_resel_utra_sf("t_resel_utra_sf"); + sib6.add_subsection(&t_resel_utra_sf); + t_resel_utra_sf.set_optional(&data->t_resel_utra_sf_present); + t_resel_utra_sf.add_field(make_asn1_enum_number_str_parser("sf_medium", &data->t_resel_utra_sf.sf_medium)); + t_resel_utra_sf.add_field(make_asn1_enum_number_str_parser("sf_high", &data->t_resel_utra_sf.sf_high)); + + // carrierFreqListUTRA-FDD + parser::section carrier_freq_list_utra_fdd("carrier_freq_list_utra_fdd"); + sib6.add_subsection(&carrier_freq_list_utra_fdd); + bool dummy_bool = false; + carrier_freq_list_utra_fdd.set_optional(&dummy_bool); + carrier_freq_list_utra_fdd.add_field(new field_carrier_freq_list_utra_fdd(data)); + + // carrierFreqListUTRA-TDD + parser::section carrier_freq_list_utra_tdd("carrier_freq_list_utra_tdd"); + sib6.add_subsection(&carrier_freq_list_utra_tdd); + carrier_freq_list_utra_tdd.set_optional(&dummy_bool); + carrier_freq_list_utra_tdd.add_field(new field_carrier_freq_list_utra_tdd(data)); + + return parser::parse_section(std::move(filename), &sib6); +} + int parse_sib7(std::string filename, sib_type7_s* data) { parser::section sib7("sib7"); sib7.add_field(new parser::field("t_resel_geran", &data->t_resel_geran)); - // TODO: t_resel_geran_sf + + parser::section t_resel_geran_sf("t_resel_geran_sf"); + sib7.add_subsection(&t_resel_geran_sf); + t_resel_geran_sf.set_optional(&data->t_resel_geran_sf_present); + + t_resel_geran_sf.add_field(make_asn1_enum_number_str_parser("sf_medium", &data->t_resel_geran_sf.sf_medium)); + t_resel_geran_sf.add_field(make_asn1_enum_number_str_parser("sf_high", &data->t_resel_geran_sf.sf_high)); data->carrier_freqs_info_list_present = true; parser::section geran_neigh("carrier_freqs_info_list"); @@ -2036,6 +2624,8 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co sib_type2_s* sib2 = &rrc_cfg_->sibs[1].set_sib2(); sib_type3_s* sib3 = &rrc_cfg_->sibs[2].set_sib3(); sib_type4_s* sib4 = &rrc_cfg_->sibs[3].set_sib4(); + sib_type5_s* sib5 = &rrc_cfg_->sibs[4].set_sib5(); + sib_type6_s* sib6 = &rrc_cfg_->sibs[5].set_sib6(); sib_type7_s* sib7 = &rrc_cfg_->sibs[6].set_sib7(); sib_type9_s* sib9 = &rrc_cfg_->sibs[8].set_sib9(); sib_type13_r9_s* sib13 = &rrc_cfg_->sibs[12].set_sib13_v920(); @@ -2057,7 +2647,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()); @@ -2105,6 +2698,20 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co } } + // Generate SIB5 if defined in mapping info + if (sib_is_present(sib1->sched_info_list, sib_type_e::sib_type5)) { + if (sib_sections::parse_sib5(args_->enb_files.sib_config, sib5) != SRSRAN_SUCCESS) { + return SRSRAN_ERROR; + } + } + + // Generate SIB6 if defined in mapping info + if (sib_is_present(sib1->sched_info_list, sib_type_e::sib_type6)) { + if (sib_sections::parse_sib6(args_->enb_files.sib_config, sib6) != SRSRAN_SUCCESS) { + return SRSRAN_ERROR; + } + } + // Generate SIB7 if defined in mapping info if (sib_is_present(sib1->sched_info_list, sib_type_e::sib_type7)) { if (sib_sections::parse_sib7(args_->enb_files.sib_config, sib7) != SRSRAN_SUCCESS) { @@ -2137,9 +2744,9 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co } // namespace sib_sections -namespace drb_sections { +namespace rb_sections { -int parse_drb(all_args_t* args_, rrc_cfg_t* rrc_cfg_) +int parse_rb(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr_cfg_) { parser::section srb1("srb1_config"); bool srb1_present = false; @@ -2160,11 +2767,33 @@ int parse_drb(all_args_t* args_, rrc_cfg_t* rrc_cfg_) parser::section qci("qci_config"); qci.add_field(new field_qci(rrc_cfg_->qci_cfg)); + parser::section srb1_5g("srb1_5g_config"); + bool srb1_5g_present = false; + srb1_5g.set_optional(&srb1_5g_present); + + parser::section srb1_5g_rlc_cfg("rlc_config"); + srb1_5g.add_subsection(&srb1_5g_rlc_cfg); + srb1_5g_rlc_cfg.add_field(new field_5g_srb(rrc_nr_cfg_->srb1_cfg)); + + parser::section srb2_5g("srb2_5g_config"); + bool srb2_5g_present = false; + srb2_5g.set_optional(&srb2_5g_present); + + parser::section srb2_5g_rlc_cfg("rlc_config"); + srb2_5g.add_subsection(&srb2_5g_rlc_cfg); + srb2_5g_rlc_cfg.add_field(new field_5g_srb(rrc_nr_cfg_->srb2_cfg)); + + parser::section five_qi("five_qi_config"); + five_qi.add_field(new field_five_qi(rrc_nr_cfg_->five_qi_cfg)); + // Run parser with two sections parser p(args_->enb_files.rb_config); p.add_section(&srb1); p.add_section(&srb2); p.add_section(&qci); + p.add_section(&srb1_5g); + p.add_section(&srb2_5g); + p.add_section(&five_qi); int ret = p.parse(); if (not srb1_present) { @@ -2174,9 +2803,17 @@ int parse_drb(all_args_t* args_, rrc_cfg_t* rrc_cfg_) rrc_cfg_->srb2_cfg.rlc_cfg.set_default_value(); } + if (!srb1_5g_present || !srb2_5g_present) { + fprintf(stderr, "Optional 5G SRB configuration is not supported yet.\n"); + fprintf(stderr, "Please specify 5G SRB1 and SRB2 configuration.\n"); + return SRSRAN_ERROR; + } + rrc_nr_cfg_->srb1_cfg.present = srb1_5g_present; + rrc_nr_cfg_->srb2_cfg.present = srb1_5g_present; + return ret; } -} // namespace drb_sections +} // namespace rb_sections } // namespace srsenb diff --git a/srsenb/src/enb_cfg_parser.h b/srsenb/src/enb_cfg_parser.h index 193594dbf2..7cc3b9abd1 100644 --- a/srsenb/src/enb_cfg_parser.h +++ b/srsenb/src/enb_cfg_parser.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -31,6 +31,7 @@ #include #include "srsenb/hdr/stack/rrc/rrc.h" +#include "srsgnb/hdr/stack/rrc/rrc_nr_config.h" #include "srsran/asn1/asn1_utils.h" namespace srsenb { @@ -50,6 +51,8 @@ int parse_cell_cfg(all_args_t* args_, srsran_cell_t* cell); int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_cfg_nr_, phy_cfg_t* phy_cfg_); int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_, const srsran_cell_t& cell_cfg_); int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_nr_cfg_, phy_cfg_t* phy_cfg_); +bool is_valid_arfcn(uint32_t band, uint32_t dl_arfcn); +std::string valid_arfcns_to_string(uint32_t band); } // namespace enb_conf_sections @@ -60,6 +63,8 @@ int parse_sib1(std::string filename, asn1::rrc::sib_type1_s* data); int parse_sib2(std::string filename, asn1::rrc::sib_type2_s* data); int parse_sib3(std::string filename, asn1::rrc::sib_type3_s* data); int parse_sib4(std::string filename, asn1::rrc::sib_type4_s* data); +int parse_sib5(std::string filename, asn1::rrc::sib_type5_s* data); +int parse_sib6(std::string filename, asn1::rrc::sib_type6_s* data); int parse_sib7(std::string filename, asn1::rrc::sib_type7_s* data); int parse_sib9(std::string filename, asn1::rrc::sib_type9_s* data); int parse_sib13(std::string filename, asn1::rrc::sib_type13_r9_s* data); @@ -67,11 +72,12 @@ int parse_sibs(all_args_t* args_, rrc_cfg_t* rrc_cfg_, srsenb::phy_cfg_t* phy_co } // namespace sib_sections -// drb.conf parsing -namespace drb_sections { +// rb.conf parsing +namespace rb_sections { -int parse_drb(all_args_t* args, rrc_cfg_t* rrc_cfg); -} // namespace drb_sections +int parse_rb(all_args_t* args, rrc_cfg_t* rrc_cfg, rrc_nr_cfg_t* rrc_nr_cfg); + +} // namespace rb_sections // rr.conf parsing namespace rr_sections { @@ -112,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: @@ -145,6 +162,61 @@ class field_intra_black_cell_list final : public parser::field_itf asn1::rrc::sib_type4_s* data; }; +class field_inter_freq_carrier_freq_list final : public parser::field_itf +{ +public: + explicit field_inter_freq_carrier_freq_list(asn1::rrc::sib_type5_s* data_) { data = data_; } + int parse(Setting& root) override; + const char* get_name() override { return "inter_freq_carrier_freq_list"; } + +private: + asn1::rrc::sib_type5_s* data; +}; + +class field_inter_freq_neigh_cell_list final : public parser::field_itf +{ +public: + explicit field_inter_freq_neigh_cell_list(asn1::rrc::inter_freq_carrier_freq_info_s* data_) { data = data_; } + int parse(Setting& root) override; + const char* get_name() override { return "inter_freq_neigh_cell_list"; } + +private: + asn1::rrc::inter_freq_carrier_freq_info_s* data; +}; + +class field_inter_freq_black_cell_list final : public parser::field_itf +{ +public: + explicit field_inter_freq_black_cell_list(asn1::rrc::inter_freq_carrier_freq_info_s* data_) { data = data_; } + int parse(Setting& root) override; + const char* get_name() override { return "inter_freq_black_cell_list"; } + +private: + asn1::rrc::inter_freq_carrier_freq_info_s* data; +}; + +class field_carrier_freq_list_utra_fdd final : public parser::field_itf +{ +public: + explicit field_carrier_freq_list_utra_fdd(asn1::rrc::sib_type6_s* data_) { data = data_; } + int parse(Setting& root) override; + const char* get_name() override { return "carrier_freq_list_utra_fdd"; } + +private: + asn1::rrc::sib_type6_s* data; +}; + +class field_carrier_freq_list_utra_tdd final : public parser::field_itf +{ +public: + explicit field_carrier_freq_list_utra_tdd(asn1::rrc::sib_type6_s* data_) { data = data_; } + int parse(Setting& root) override; + const char* get_name() override { return "carrier_freq_list_utra_tdd"; } + +private: + asn1::rrc::sib_type6_s* data; +}; + class field_carrier_freqs_info_list final : public parser::field_itf { public: @@ -190,7 +262,7 @@ class field_qci final : public parser::field_itf { public: explicit field_qci(std::map& cfg_) : cfg(cfg_) {} - const char* get_name() override { return "field_cqi"; } + const char* get_name() override { return "field_qci"; } int parse(Setting& root) override; @@ -198,6 +270,29 @@ class field_qci final : public parser::field_itf std::map& cfg; }; +class field_5g_srb final : public parser::field_itf +{ +public: + explicit field_5g_srb(srb_5g_cfg_t& cfg_) : cfg(cfg_) {} + const char* get_name() override { return "field_5g_srb"; } + + int parse(Setting& root) override; + +private: + srb_5g_cfg_t& cfg; +}; + +class field_five_qi final : public parser::field_itf +{ +public: + explicit field_five_qi(std::map& cfg_) : cfg(cfg_) {} + const char* get_name() override { return "field_five_qi"; } + + int parse(Setting& root) override; + +private: + std::map& cfg; +}; // ASN1 parsers class field_asn1 : public parser::field_itf diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 8841958652..2c7d19e24c 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -44,6 +44,7 @@ #include "srsenb/hdr/enb.h" #include "srsenb/hdr/metrics_csv.h" +#include "srsenb/hdr/metrics_e2.h" #include "srsenb/hdr/metrics_json.h" #include "srsenb/hdr/metrics_stdout.h" #include "srsran/common/enb_events.h" @@ -65,6 +66,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) string mcc; string mnc; string enb_id; + string cfr_mode; bool use_standard_lte_rates = false; // Command line only options @@ -142,10 +144,12 @@ void parse_args(all_args_t* args, int argc, char* argv[]) /* PCAP */ ("pcap.enable", bpo::value(&args->stack.mac_pcap.enable)->default_value(false), "Enable MAC packet captures for wireshark") - ("pcap.filename", bpo::value(&args->stack.mac_pcap.filename)->default_value("enb_mac.pcap"), "MAC layer capture filename") - ("pcap.nr_filename", bpo::value(&args->nr_stack.mac.pcap.filename)->default_value("enb_mac_nr.pcap"), "NR MAC layer capture filename") + ("pcap.filename", bpo::value(&args->stack.mac_pcap.filename)->default_value("/tmp/enb_mac.pcap"), "MAC layer capture filename") + ("pcap.nr_filename", bpo::value(&args->nr_stack.mac.pcap.filename)->default_value("/tmp/enb_mac_nr.pcap"), "NR MAC layer capture filename") ("pcap.s1ap_enable", bpo::value(&args->stack.s1ap_pcap.enable)->default_value(false), "Enable S1AP packet captures for wireshark") - ("pcap.s1ap_filename", bpo::value(&args->stack.s1ap_pcap.filename)->default_value("enb_s1ap.pcap"), "S1AP layer capture filename") + ("pcap.s1ap_filename", bpo::value(&args->stack.s1ap_pcap.filename)->default_value("/tmp/enb_s1ap.pcap"), "S1AP layer capture filename") + ("pcap.ngap_enable", bpo::value(&args->nr_stack.ngap_pcap.enable)->default_value(false), "Enable NGAP packet captures for wireshark") + ("pcap.ngap_filename", bpo::value(&args->nr_stack.ngap_pcap.filename)->default_value("/tmp/enb_ngap.pcap"), "NGAP layer capture filename") ("pcap.mac_net_enable", bpo::value(&args->stack.mac_pcap_net.enable)->default_value(false), "Enable MAC network captures") ("pcap.bind_ip", bpo::value(&args->stack.mac_pcap_net.bind_ip)->default_value("0.0.0.0"), "Bind IP address for MAC network trace") ("pcap.bind_port", bpo::value(&args->stack.mac_pcap_net.bind_port)->default_value(5687), "Bind port for MAC network trace") @@ -178,7 +182,13 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("scheduler.max_sib_coderate", bpo::value(&args->stack.mac.sched.max_sib_coderate)->default_value(0.8), "Upper bound on SIB and RAR grants coderate") ("scheduler.pdcch_cqi_offset", bpo::value(&args->stack.mac.sched.pdcch_cqi_offset)->default_value(0), "CQI offset in derivation of PDCCH aggregation level") - + /*Slicing conifguration*/ + ("slicing.enable_eMBB", bpo::value(&args->nr_stack.ngap.nssai[0].active)->default_value(true), "Enables enhanced mobile broadband (eMBB) slice in the gNodeB") + ("slicing.enable_URLLC", bpo::value(&args->nr_stack.ngap.nssai[1].active)->default_value(false), "Enables Ultra Reliable Low Latency Communications (URLLC) slice in the gNodeB") + ("slicing.enable_MIoT", bpo::value(&args->nr_stack.ngap.nssai[2].active)->default_value(false), "Enables Massive Internet of Things (MIoT) slice in the gNodeB") + ("slicing.eMBB_sd", bpo::value(&args->nr_stack.ngap.nssai[0].sd)->default_value(0), " eMBB slice differentiator") + ("slicing.URLLC_sd", bpo::value(&args->nr_stack.ngap.nssai[1].sd)->default_value(0), " URLLC slice differentiator") + ("slicing.MIoT_sd", bpo::value(&args->nr_stack.ngap.nssai[2].sd)->default_value(0), " slice differentiator") /* Downlink Channel emulator section */ ("channel.dl.enable", bpo::value(&args->phy.dl_channel_args.enable)->default_value(false), "Enable/Disable internal Downlink channel emulator") @@ -219,7 +229,24 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("channel.ul.hst.fd_hz", bpo::value(&args->phy.ul_channel_args.hst_fd_hz)->default_value(+750.0f), "Doppler frequency in Hz") ("channel.ul.hst.init_time_s", bpo::value(&args->phy.ul_channel_args.hst_init_time_s)->default_value(0), "Initial time in seconds") - /* Expert section */ + /* CFR section */ + ("cfr.enable", bpo::value(&args->phy.cfr_args.enable)->default_value(args->phy.cfr_args.enable), "CFR enable") + ("cfr.mode", bpo::value(&cfr_mode)->default_value("manual"), "CFR mode") + ("cfr.manual_thres", bpo::value(&args->phy.cfr_args.manual_thres)->default_value(args->phy.cfr_args.manual_thres), "Fixed manual clipping threshold for CFR manual mode") + ("cfr.strength", bpo::value(&args->phy.cfr_args.strength)->default_value(args->phy.cfr_args.strength), "CFR ratio between amplitude-limited vs original signal (0 to 1)") + ("cfr.auto_target_papr", bpo::value(&args->phy.cfr_args.auto_target_papr)->default_value(args->phy.cfr_args.auto_target_papr), "Signal PAPR target (in dB) in CFR auto modes") + ("cfr.ema_alpha", bpo::value(&args->phy.cfr_args.ema_alpha)->default_value(args->phy.cfr_args.ema_alpha), "Alpha coefficient for the power average in auto_ema mode (0 to 1)") + + /* RIC section */ + ("e2_agent.enable", bpo::value(&args->e2_agent.enable)->default_value(false), "Enables the E2 agent") + ("e2_agent.ric_ip", bpo::value(&args->e2_agent.ric_ip)->default_value("127.0.0.1"), "RIC IP address") + ("e2_agent.ric_port", bpo::value(&args->e2_agent.ric_port)->default_value(36421), "RIC port") + ("e2_agent.ric_bind_ip", bpo::value(&args->e2_agent.ric_bind_ip)->default_value("127.0.0.1"), "Local IP address to bind for RIC connection") + ("e2_agent.ric_bind_port", bpo::value(&args->e2_agent.ric_bind_port)->default_value(36425), "Local port to bind for RIC connection") + ("e2_agent.max_ric_setup_retries", bpo::value(&args->e2_agent.max_ric_setup_retries)->default_value(-1), "Max RIC setup retries") + ("e2_agent.ric_connect_timer", bpo::value(&args->e2_agent.ric_connect_timer)->default_value(10), "Connection Retry Timer for RIC connection (seconds)") + + /* Expert section */ ("expert.metrics_period_secs", bpo::value(&args->general.metrics_period_secs)->default_value(1.0), "Periodicity for metrics in seconds.") ("expert.metrics_csv_enable", bpo::value(&args->general.metrics_csv_enable)->default_value(false), "Write metrics to CSV file.") ("expert.metrics_csv_filename", bpo::value(&args->general.metrics_csv_filename)->default_value("/tmp/enb_metrics.csv"), "Metrics CSV filename.") @@ -257,6 +284,15 @@ 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.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.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") + // eMBMS section ("embms.enable", bpo::value(&args->stack.embms.enable)->default_value(false), "Enables MBMS in the eNB") ("embms.m1u_multiaddr", bpo::value(&args->stack.embms.m1u_multiaddr)->default_value("239.255.0.1"), "M1-U Multicast address the eNB joins.") @@ -267,13 +303,6 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("scheduler.nr_pdsch_mcs", bpo::value(&args->nr_stack.mac.sched_cfg.fixed_dl_mcs)->default_value(28), "Fixed NR DL MCS (-1 for dynamic).") ("scheduler.nr_pusch_mcs", bpo::value(&args->nr_stack.mac.sched_cfg.fixed_ul_mcs)->default_value(28), "Fixed NR UL MCS (-1 for dynamic).") ("expert.nr_pusch_max_its", bpo::value(&args->phy.nr_pusch_max_its)->default_value(10), "Maximum number of LDPC iterations for NR.") - - // VNF params - ("vnf.type", bpo::value(&args->phy.vnf_args.type)->default_value("gnb"), "VNF instance type [gnb,ue].") - ("vnf.addr", bpo::value(&args->phy.vnf_args.bind_addr)->default_value("localhost"), "Address to bind VNF interface.") - ("vnf.port", bpo::value(&args->phy.vnf_args.bind_port)->default_value(3333), "Bind port.") - ("log.vnf_level", bpo::value(&args->phy.vnf_args.log_level), "VNF log level.") - ("log.vnf_hex_limit", bpo::value(&args->phy.vnf_args.log_hex_limit), "VNF log hex dump limit.") ; // Positional options - config file location @@ -344,6 +373,12 @@ void parse_args(all_args_t* args, int argc, char* argv[]) if (!srsran::string_to_mnc(mnc, &args->stack.s1ap.mnc)) { cout << "Error parsing enb.mnc:" << mnc << " - must be a 2 or 3-digit string." << endl; } + if (!srsran::string_to_mcc(mcc, &args->nr_stack.ngap.mcc)) { + cout << "Error parsing enb.mcc:" << mcc << " - must be a 3-digit string." << endl; + } + if (!srsran::string_to_mnc(mnc, &args->nr_stack.ngap.mnc)) { + cout << "Error parsing enb.mnc:" << mnc << " - must be a 2 or 3-digit string." << endl; + } if (args->stack.embms.enable) { if (args->stack.mac.sched.max_nof_ctrl_symbols == 3) { @@ -366,7 +401,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) // Convert eNB Id std::size_t pos = {}; try { - args->enb.enb_id = std::stoi(enb_id, &pos, 0); + args->enb.enb_id = std::stoul(enb_id, &pos, 0); } catch (...) { cout << "Error parsing enb.enb_id: " << enb_id << "." << endl; exit(1); @@ -376,6 +411,13 @@ void parse_args(all_args_t* args, int argc, char* argv[]) exit(1); } + // parse the CFR mode string + args->phy.cfr_args.mode = srsran_cfr_str2mode(cfr_mode.c_str()); + if (args->phy.cfr_args.mode == SRSRAN_CFR_THR_INVALID) { + cout << "Error, invalid CFR mode: " << cfr_mode << endl; + exit(1); + } + // Apply all_level to any unset layers if (vm.count("log.all_level")) { if (!vm.count("log.rf_level")) { @@ -450,7 +492,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) } if (!config_exists(args->enb_files.rb_config, "rb.conf")) { - cout << "Failed to read DRB configuration file " << args->enb_files.rb_config << " - exiting" << endl; + cout << "Failed to read RB configuration file " << args->enb_files.rb_config << " - exiting" << endl; exit(1); } @@ -472,6 +514,9 @@ static void execute_cmd(metrics_stdout* metrics, srsenb::enb_command_interface* cout << "Enter t to restart trace." << endl; } metrics->toggle_print(do_metrics); + } else if (cmd[0] == "m") { + // Trigger cell measurements + control->cmd_cell_measure(); } else if (cmd[0] == "sleep") { if (cmd.size() != 2) { cout << "Usage: " << cmd[0] << " [number of seconds]" << endl; @@ -514,6 +559,7 @@ static void execute_cmd(metrics_stdout* metrics, srsenb::enb_command_interface* } else { cout << "Available commands: " << endl; cout << " t: starts console trace" << endl; + cout << " m: downlink signal measurements" << endl; cout << " q: quit srsenb" << endl; cout << " cell_gain: set relative cell gain" << endl; cout << " sleep: pauses the commmand line operation for a given time in seconds" << endl; @@ -641,16 +687,19 @@ int main(int argc, char* argv[]) metricshub.add_listener(&metrics_screen); metrics_screen.set_handle(enb.get()); - srsenb::metrics_csv metrics_file(args.general.metrics_csv_filename); + srsenb::metrics_csv metrics_file(args.general.metrics_csv_filename, enb.get()); if (args.general.metrics_csv_enable) { metricshub.add_listener(&metrics_file); - metrics_file.set_handle(enb.get()); } srsenb::metrics_json json_metrics(json_channel, enb.get()); if (args.general.report_json_enable) { metricshub.add_listener(&json_metrics); } + srsenb::metrics_e2 e2_metrics(enb.get()); + if (args.e2_agent.enable) { + metricshub.add_listener(&e2_metrics); + } // create input thread std::thread input(&input_loop, &metrics_screen, (enb_command_interface*)enb.get()); @@ -659,6 +708,11 @@ int main(int argc, char* argv[]) if (args.gui.enable) { enb->start_plot(); } + if (args.e2_agent.enable) { + if (enb->enable_e2_agent(&e2_metrics)) { + srslog::fetch_basic_logger("E2_AGENT").error("Failed to enable E2 Agent"); + } + } } int cnt = 0; int ts_cnt = 0; diff --git a/srsenb/src/metrics_csv.cc b/srsenb/src/metrics_csv.cc index 2ce0ede81e..8a7fef4f27 100644 --- a/srsenb/src/metrics_csv.cc +++ b/srsenb/src/metrics_csv.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -36,7 +36,8 @@ using namespace std; namespace srsenb { -metrics_csv::metrics_csv(std::string filename) : n_reports(0), metrics_report_period(1.0), enb(NULL) +metrics_csv::metrics_csv(std::string filename, enb_metrics_interface* enb_) : + n_reports(0), metrics_report_period(1.0), enb(enb_) { file.open(filename.c_str(), std::ios_base::out); } @@ -46,11 +47,6 @@ metrics_csv::~metrics_csv() stop(); } -void metrics_csv::set_handle(enb_metrics_interface* enb_) -{ - enb = enb_; -} - void metrics_csv::stop() { if (file.is_open()) { diff --git a/srsenb/src/metrics_e2.cc b/srsenb/src/metrics_e2.cc new file mode 100644 index 0000000000..0f9609de7c --- /dev/null +++ b/srsenb/src/metrics_e2.cc @@ -0,0 +1,68 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsenb/hdr/metrics_e2.h" +#include "srsran/phy/utils/vector.h" + +using namespace srsenb; + +void metrics_e2::set_metrics(const enb_metrics_t& m, const uint32_t period_usec) +{ + if (metrics_queue.size() > METRICS_BUFFER_SIZE) { + metrics_queue.pop(); + metrics_queue.push(m); + } else { + metrics_queue.push(m); + } + + // send new enb metrics to all registered SMs + for (auto sm_ : e2sm_vec) { + sm_->receive_e2_metrics_callback(m); + } +} + +bool metrics_e2::register_e2sm(e2sm* sm) +{ + e2sm_vec.push_back(sm); + return true; +} + +bool metrics_e2::unregister_e2sm(e2sm* sm) +{ + auto it = std::find(e2sm_vec.begin(), e2sm_vec.end(), sm); + if (it != e2sm_vec.end()) { + e2sm_vec.erase(it); + return true; + } + return false; +} + +bool metrics_e2::pull_metrics(enb_metrics_t* m) +{ + if (enb != nullptr) { + if (!metrics_queue.empty()) { + *m = metrics_queue.front(); + metrics_queue.pop(); + return true; + } + } + return false; +} diff --git a/srsenb/src/metrics_json.cc b/srsenb/src/metrics_json.cc index 9945c29d1b..138f7c89d6 100644 --- a/srsenb/src/metrics_json.cc +++ b/srsenb/src/metrics_json.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -54,6 +54,13 @@ DECLARE_METRIC("dl_bitrate", metric_dl_bitrate, float, ""); DECLARE_METRIC("dl_bler", metric_dl_bler, float, ""); DECLARE_METRIC("ul_snr", metric_ul_snr, float, ""); DECLARE_METRIC("ul_mcs", metric_ul_mcs, float, ""); +DECLARE_METRIC("ul_pusch_rssi", metric_ul_pusch_rssi, float, ""); +DECLARE_METRIC("ul_pucch_rssi", metric_ul_pucch_rssi, float, ""); +DECLARE_METRIC("ul_pucch_ni", metric_ul_pucch_ni, float, ""); +DECLARE_METRIC("ul_pusch_tpc", metric_ul_pusch_tpc, int64_t, ""); +DECLARE_METRIC("ul_pucch_tpc", metric_ul_pucch_tpc, int64_t, ""); +DECLARE_METRIC("dl_cqi_offset", metric_dl_cqi_offset, float, ""); +DECLARE_METRIC("ul_snr_offset", metric_ul_snr_offset, float, ""); DECLARE_METRIC("ul_bitrate", metric_ul_bitrate, float, ""); DECLARE_METRIC("ul_bler", metric_ul_bler, float, ""); DECLARE_METRIC("ul_phr", metric_ul_phr, float, ""); @@ -64,6 +71,13 @@ DECLARE_METRIC_SET("ue_container", metric_ue_rnti, metric_dl_cqi, metric_dl_mcs, + metric_ul_pusch_rssi, + metric_ul_pucch_rssi, + metric_ul_pucch_ni, + metric_ul_pusch_tpc, + metric_ul_pucch_tpc, + metric_dl_cqi_offset, + metric_ul_snr_offset, metric_dl_bitrate, metric_dl_bler, metric_ul_snr, @@ -97,24 +111,40 @@ static void fill_ue_metrics(mset_ue_container& ue, const enb_metrics_t& m, unsig ue.write(m.stack.mac.ues[i].rnti); ue.write(std::max(0.1f, m.stack.mac.ues[i].dl_cqi)); if (!std::isnan(m.phy[i].dl.mcs)) { - ue.write(std::max(0.1f, m.phy[i].dl.mcs)); + ue.write(m.phy[i].dl.mcs); } if (m.stack.mac.ues[i].tx_brate > 0 && m.stack.mac.ues[i].nof_tti > 0) { ue.write( std::max(0.1f, (float)m.stack.mac.ues[i].tx_brate / (m.stack.mac.ues[i].nof_tti * 0.001f))); } if (m.stack.mac.ues[i].tx_pkts > 0 && m.stack.mac.ues[i].tx_errors > 0) { - ue.write(std::max(0.1f, (float)100 * m.stack.mac.ues[i].tx_errors / m.stack.mac.ues[i].tx_pkts)); + ue.write((float)100 * m.stack.mac.ues[i].tx_errors / m.stack.mac.ues[i].tx_pkts); } if (!std::isnan(m.phy[i].ul.pusch_sinr)) { - ue.write(std::max(0.1f, m.phy[i].ul.pusch_sinr)); + ue.write(m.phy[i].ul.pusch_sinr); + } + if (!std::isnan(m.phy[i].ul.pusch_rssi)) { + ue.write(m.phy[i].ul.pusch_rssi); + } + if (!std::isnan(m.phy[i].ul.pucch_rssi)) { + ue.write(m.phy[i].ul.pucch_rssi); + } + if (!std::isnan(m.phy[i].ul.pucch_ni)) { + ue.write(m.phy[i].ul.pucch_ni); + } + ue.write(m.phy[i].ul.pusch_tpc); + ue.write(m.phy[i].dl.pucch_tpc); + if (!std::isnan(m.stack.mac.ues[i].dl_cqi_offset)) { + ue.write(m.stack.mac.ues[i].dl_cqi_offset); + } + if (!std::isnan(m.stack.mac.ues[i].ul_snr_offset)) { + ue.write(m.stack.mac.ues[i].ul_snr_offset); } if (!std::isnan(m.phy[i].ul.mcs)) { - ue.write(std::max(0.1f, m.phy[i].ul.mcs)); + ue.write(m.phy[i].ul.mcs); } if (m.stack.mac.ues[i].rx_brate > 0 && m.stack.mac.ues[i].nof_tti > 0) { - ue.write( - std::max(0.1f, (float)m.stack.mac.ues[i].rx_brate / (m.stack.mac.ues[i].nof_tti * 0.001f))); + ue.write((float)m.stack.mac.ues[i].rx_brate / (m.stack.mac.ues[i].nof_tti * 0.001f)); } if (m.stack.mac.ues[i].rx_pkts > 0 && m.stack.mac.ues[i].rx_errors > 0) { ue.write(std::max(0.1f, (float)100 * m.stack.mac.ues[i].rx_errors / m.stack.mac.ues[i].rx_pkts)); diff --git a/srsenb/src/metrics_stdout.cc b/srsenb/src/metrics_stdout.cc index 2887073830..54a0b63f14 100644 --- a/srsenb/src/metrics_stdout.cc +++ b/srsenb/src/metrics_stdout.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -98,6 +98,7 @@ void metrics_stdout::set_metrics_helper(uint32_t num_ue } fmt::print("{:>3.5}", (is_nr) ? "nr" : "lte"); + fmt::print(" {:>4}", mac.ues[i].pci); fmt::print("{:>5x}", mac.ues[i].rnti); if (not iszero(mac.ues[i].dl_cqi)) { fmt::print(" {:>3}", int(mac.ues[i].dl_cqi)); @@ -187,15 +188,17 @@ void metrics_stdout::set_metrics(const enb_metrics_t& metrics, const uint32_t pe fmt::print("RF status: O={}, U={}, L={}\n", metrics.rf.rf_o, metrics.rf.rf_u, metrics.rf.rf_l); } - if (metrics.stack.rrc.ues.size() == 0) { + if (metrics.stack.rrc.ues.size() == 0 && metrics.nr_stack.mac.ues.size() == 0) { return; } if (++n_reports > 10) { n_reports = 0; fmt::print("\n"); - fmt::print(" -----------------DL----------------|-------------------------UL-------------------------\n"); - fmt::print("rat rnti cqi ri mcs brate ok nok (%) | pusch pucch phr mcs brate ok nok (%) bsr\n"); + fmt::print( + " -----------------DL----------------|-------------------------UL-------------------------\n"); + fmt::print( + "rat pci rnti cqi ri mcs brate ok nok (%) | pusch pucch phr mcs brate ok nok (%) bsr\n"); } set_metrics_helper(metrics.stack.rrc.ues.size(), metrics.stack.mac, metrics.phy, false); diff --git a/srsenb/src/parser.cc b/srsenb/src/parser.cc index ae51ab8a64..75b9bef656 100644 --- a/srsenb/src/parser.cc +++ b/srsenb/src/parser.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/src/phy/CMakeLists.txt b/srsenb/src/phy/CMakeLists.txt index a0fa5d026e..5d854dbc03 100644 --- a/srsenb/src/phy/CMakeLists.txt +++ b/srsenb/src/phy/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsenb/src/phy/lte/cc_worker.cc b/srsenb/src/phy/lte/cc_worker.cc index 4eb3e45433..8495baf31f 100644 --- a/srsenb/src/phy/lte/cc_worker.cc +++ b/srsenb/src/phy/lte/cc_worker.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,6 +19,8 @@ * */ +#include + #include "srsran/common/threads.h" #include "srsran/srsran.h" @@ -86,11 +88,12 @@ FILE* f; void cc_worker::init(phy_common* phy_, uint32_t cc_idx_) { - phy = phy_; - cc_idx = cc_idx_; - srsran_cell_t cell = phy_->get_cell(cc_idx); - uint32_t nof_prb = phy_->get_nof_prb(cc_idx); - uint32_t sf_len = SRSRAN_SF_LEN_PRB(nof_prb); + phy = phy_; + cc_idx = cc_idx_; + srsran_cell_t cell = phy_->get_cell(cc_idx); + uint32_t nof_prb = phy_->get_nof_prb(cc_idx); + uint32_t sf_len = SRSRAN_SF_LEN_PRB(nof_prb); + srsran_cfr_cfg_t cfr_config = phy_->get_cfr_config(); // Init cell here for (uint32_t p = 0; p < phy->get_nof_ports(cc_idx); p++) { @@ -115,6 +118,10 @@ void cc_worker::init(phy_common* phy_, uint32_t cc_idx_) ERROR("Error initiating ENB DL (cc=%d)", cc_idx); return; } + if (srsran_enb_dl_set_cfr(&enb_dl, &cfr_config) < SRSRAN_SUCCESS) { + ERROR("Error setting the CFR"); + return; + } if (srsran_enb_ul_init(&enb_ul, signal_buffer_rx[0], nof_prb)) { ERROR("Error initiating ENB UL"); return; @@ -260,6 +267,20 @@ void cc_worker::work_dl(const srsran_dl_sf_cfg_t& dl_sf_cfg, srsran_vec_sc_prod_cfc(signal_buffer_tx[i], scale, signal_buffer_tx[i], sf_len); } } + + // Measure PAPR if flag was triggered + bool cell_meas_flag = phy->get_cell_measure_trigger(cc_idx); + if (cell_meas_flag) { + uint32_t sf_len = SRSRAN_SF_LEN_PRB(enb_dl.cell.nof_prb); + for (uint32_t i = 0; i < enb_dl.cell.nof_ports; i++) { + // PAPR measure + float papr_db = 10.0f * log10(srsran_vec_papr_c(signal_buffer_tx[i], sf_len)); + std::cout << "Cell #" << cc_idx << " port #" << i << " PAPR = " << std::setprecision(4) << papr_db << " dB " + << std::endl; + } + // clear measurement flag on cell + phy->clear_cell_measure_trigger(cc_idx); + } } bool cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_grant, @@ -351,7 +372,10 @@ bool cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_ // Save statistics only if data was provided if (ul_grant.data != nullptr) { // Save metrics stats - ue_db[rnti]->metrics_ul(ul_grant.dci.tb.mcs_idx, 0, enb_ul.chest_res.snr_db, pusch_res.avg_iterations_block); + ue_db[rnti]->metrics_ul(ul_grant.dci.tb.mcs_idx, + enb_ul.chest_res.epre_dBfs - phy->params.rx_gain_offset, + enb_ul.chest_res.snr_db, + pusch_res.avg_iterations_block); } return true; } @@ -439,7 +463,11 @@ int cc_worker::decode_pucch() } // Save metrics - ue_db[rnti]->metrics_ul_pucch(pucch_res.snr_db); + if (pucch_res.detected) { + ue_db[rnti]->metrics_ul_pucch(pucch_res.rssi_dbFs - phy->params.rx_gain_offset, + pucch_res.ni_dbFs - -phy->params.rx_gain_offset, + pucch_res.snr_db); + } } } } @@ -643,7 +671,7 @@ void cc_worker::ue::metrics_read(phy_metrics_t* metrics_) if (metrics_) { *metrics_ = metrics; } - bzero(&metrics, sizeof(phy_metrics_t)); + metrics = {}; } void cc_worker::ue::metrics_dl(uint32_t mcs) @@ -654,15 +682,23 @@ void cc_worker::ue::metrics_dl(uint32_t mcs) void cc_worker::ue::metrics_ul(uint32_t mcs, float rssi, float sinr, float turbo_iters) { + if (isnan(rssi)) { + rssi = 0; + } metrics.ul.mcs = SRSRAN_VEC_CMA((float)mcs, metrics.ul.mcs, metrics.ul.n_samples); metrics.ul.pusch_sinr = SRSRAN_VEC_CMA((float)sinr, metrics.ul.pusch_sinr, metrics.ul.n_samples); - metrics.ul.rssi = SRSRAN_VEC_CMA((float)rssi, metrics.ul.rssi, metrics.ul.n_samples); + metrics.ul.pusch_rssi = SRSRAN_VEC_CMA((float)rssi, metrics.ul.pusch_rssi, metrics.ul.n_samples); metrics.ul.turbo_iters = SRSRAN_VEC_CMA((float)turbo_iters, metrics.ul.turbo_iters, metrics.ul.n_samples); metrics.ul.n_samples++; } -void cc_worker::ue::metrics_ul_pucch(float sinr) +void cc_worker::ue::metrics_ul_pucch(float rssi, float ni, float sinr) { + if (isnan(rssi)) { + rssi = 0; + } + metrics.ul.pucch_rssi = SRSRAN_VEC_CMA((float)rssi, metrics.ul.pucch_rssi, metrics.ul.n_samples_pucch); + metrics.ul.pucch_ni = SRSRAN_VEC_CMA((float)ni, metrics.ul.pucch_ni, metrics.ul.n_samples_pucch); metrics.ul.pucch_sinr = SRSRAN_VEC_CMA((float)sinr, metrics.ul.pucch_sinr, metrics.ul.n_samples_pucch); metrics.ul.n_samples_pucch++; } diff --git a/srsenb/src/phy/lte/sf_worker.cc b/srsenb/src/phy/lte/sf_worker.cc index f0eda324fb..2671c316a9 100644 --- a/srsenb/src/phy/lte/sf_worker.cc +++ b/srsenb/src/phy/lte/sf_worker.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -277,15 +277,19 @@ uint32_t sf_worker::get_metrics(std::vector& metrics) for (uint32_t r = 0; r < cnt; r++) { phy_metrics_t* m = &metrics[r]; phy_metrics_t* m_ = &metrics_[r]; - m->dl.mcs = SRSRAN_VEC_PMA(m->dl.mcs, m->dl.n_samples, m_->dl.mcs, m_->dl.n_samples); + m->dl.mcs = SRSRAN_VEC_SAFE_PMA(m->dl.mcs, m->dl.n_samples, m_->dl.mcs, m_->dl.n_samples); m->dl.n_samples += m_->dl.n_samples; - m->ul.n = SRSRAN_VEC_PMA(m->ul.n, m->ul.n_samples, m_->ul.n, m_->ul.n_samples); - m->ul.pusch_sinr = SRSRAN_VEC_PMA(m->ul.pusch_sinr, m->ul.n_samples, m_->ul.pusch_sinr, m_->ul.n_samples); + m->ul.n = SRSRAN_VEC_SAFE_PMA(m->ul.n, m->ul.n_samples, m_->ul.n, m_->ul.n_samples); + m->ul.pusch_sinr = SRSRAN_VEC_SAFE_PMA(m->ul.pusch_sinr, m->ul.n_samples, m_->ul.pusch_sinr, m_->ul.n_samples); m->ul.pucch_sinr = - SRSRAN_VEC_PMA(m->ul.pucch_sinr, m->ul.n_samples_pucch, m_->ul.pucch_sinr, m_->ul.n_samples_pucch); - m->ul.mcs = SRSRAN_VEC_PMA(m->ul.mcs, m->ul.n_samples, m_->ul.mcs, m_->ul.n_samples); - m->ul.rssi = SRSRAN_VEC_PMA(m->ul.rssi, m->ul.n_samples, m_->ul.rssi, m_->ul.n_samples); - m->ul.turbo_iters = SRSRAN_VEC_PMA(m->ul.turbo_iters, m->ul.n_samples, m_->ul.turbo_iters, m_->ul.n_samples); + SRSRAN_VEC_SAFE_PMA(m->ul.pucch_sinr, m->ul.n_samples_pucch, m_->ul.pucch_sinr, m_->ul.n_samples_pucch); + m->ul.mcs = SRSRAN_VEC_SAFE_PMA(m->ul.mcs, m->ul.n_samples, m_->ul.mcs, m_->ul.n_samples); + m->ul.pusch_rssi = SRSRAN_VEC_SAFE_PMA(m->ul.pusch_rssi, m->ul.n_samples, m_->ul.pusch_rssi, m_->ul.n_samples); + m->ul.pucch_rssi = + SRSRAN_VEC_SAFE_PMA(m->ul.pucch_rssi, m->ul.n_samples_pucch, m_->ul.pucch_rssi, m_->ul.n_samples_pucch); + m->ul.pucch_ni = + SRSRAN_VEC_SAFE_PMA(m->ul.pucch_ni, m->ul.n_samples_pucch, m_->ul.pucch_ni, m_->ul.n_samples_pucch); + m->ul.turbo_iters = SRSRAN_VEC_SAFE_PMA(m->ul.turbo_iters, m->ul.n_samples, m_->ul.turbo_iters, m_->ul.n_samples); m->ul.n_samples += m_->ul.n_samples; m->ul.n_samples_pucch += m_->ul.n_samples_pucch; } diff --git a/srsenb/src/phy/lte/worker_pool.cc b/srsenb/src/phy/lte/worker_pool.cc index cdcf1df1ee..59e0cef7c4 100644 --- a/srsenb/src/phy/lte/worker_pool.cc +++ b/srsenb/src/phy/lte/worker_pool.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index bfd3fdea85..0ded9e70a9 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,6 +23,14 @@ #include "srsran/common/buffer_pool.h" #include "srsran/common/common.h" +//#define DEBUG_WRITE_FILE + +#ifdef DEBUG_WRITE_FILE +FILE* f; +static uint32_t num_slots = 0; +static uint32_t slots_to_dump = 10; +#endif + namespace srsenb { namespace nr { slot_worker::slot_worker(srsran::phy_common_interface& common_, @@ -81,13 +89,14 @@ bool slot_worker::init(const args_t& args) } // Prepare UL arguments - srsran_gnb_ul_args_t ul_args = {}; - ul_args.pusch.measure_time = true; - ul_args.pusch.measure_evm = true; - ul_args.pusch.max_layers = args.nof_rx_ports; - ul_args.pusch.max_prb = args.nof_max_prb; - ul_args.nof_max_prb = args.nof_max_prb; - ul_args.pusch_min_snr_dB = args.pusch_min_snr_dB; + srsran_gnb_ul_args_t ul_args = {}; + ul_args.pusch.measure_time = true; + ul_args.pusch.measure_evm = true; + ul_args.pusch.max_layers = args.nof_rx_ports; + ul_args.pusch.sch.max_nof_iter = args.pusch_max_its; + ul_args.pusch.max_prb = args.nof_max_prb; + ul_args.nof_max_prb = args.nof_max_prb; + ul_args.pusch_min_snr_dB = args.pusch_min_snr_dB; // Initialise UL if (srsran_gnb_ul_init(&gnb_ul, rx_buffer[0], &ul_args) < SRSRAN_SUCCESS) { @@ -95,6 +104,12 @@ bool slot_worker::init(const args_t& args) return false; } +#ifdef DEBUG_WRITE_FILE + const char* filename = "nr_baseband.dat"; + printf("Opening %s to dump baseband\n", filename); + f = fopen(filename, "w"); +#endif + return true; } @@ -151,13 +166,13 @@ void slot_worker::set_context(const srsran::phy_common_interface::worker_context bool slot_worker::work_ul() { - stack_interface_phy_nr::ul_sched_t ul_sched = {}; - if (stack.get_ul_sched(ul_slot_cfg, ul_sched) < SRSRAN_SUCCESS) { + stack_interface_phy_nr::ul_sched_t* ul_sched = stack.get_ul_sched(ul_slot_cfg); + if (ul_sched == nullptr) { logger.error("Error retrieving UL scheduling"); return false; } - if (ul_sched.pucch.empty() && ul_sched.pusch.empty()) { + if (ul_sched->pucch.empty() && ul_sched->pusch.empty()) { // early exit if nothing has been scheduled return true; } @@ -169,7 +184,7 @@ bool slot_worker::work_ul() } // For each PUCCH... - for (stack_interface_phy_nr::pucch_t& pucch : ul_sched.pucch) { + for (stack_interface_phy_nr::pucch_t& pucch : ul_sched->pucch) { srsran::bounded_vector pucch_info(pucch.candidates.size()); @@ -220,7 +235,7 @@ bool slot_worker::work_ul() } // For each PUSCH... - for (stack_interface_phy_nr::pusch_t& pusch : ul_sched.pusch) { + for (stack_interface_phy_nr::pusch_t& pusch : ul_sched->pusch) { // Prepare PUSCH stack_interface_phy_nr::pusch_info_t pusch_info = {}; pusch_info.uci_cfg = pusch.sch.uci; @@ -274,25 +289,23 @@ bool slot_worker::work_dl() sync.wait(this); // Retrieve Scheduling for the current processing DL slot - stack_interface_phy_nr::dl_sched_t dl_sched = {}; - bool dl_sched_fail = stack.get_dl_sched(dl_slot_cfg, dl_sched) < SRSRAN_SUCCESS; + const stack_interface_phy_nr::dl_sched_t* dl_sched_ptr = stack.get_dl_sched(dl_slot_cfg); // Releases synchronization lock and allow next worker to retrieve scheduling results sync.release(); - // Abort if the scheduling failed - if (dl_sched_fail) { - logger.error("Error retrieving DL scheduling"); + // Abort DL processing if the scheduling returned an invalid pointer + if (dl_sched_ptr == nullptr) { return false; } if (srsran_gnb_dl_base_zero(&gnb_dl) < SRSRAN_SUCCESS) { - logger.error("Error zeroeing RE grid"); + logger.error("Error zeroing RE grid"); return false; } // Encode PDCCH for DL transmissions - for (const stack_interface_phy_nr::pdcch_dl_t& pdcch : dl_sched.pdcch_dl) { + for (const stack_interface_phy_nr::pdcch_dl_t& pdcch : dl_sched_ptr->pdcch_dl) { // Set PDCCH configuration, including DCI dedicated if (srsran_gnb_dl_set_pdcch_config(&gnb_dl, &pdcch_cfg, &pdcch.dci_cfg) < SRSRAN_SUCCESS) { logger.error("PDCCH: Error setting DL configuration"); @@ -314,7 +327,7 @@ bool slot_worker::work_dl() } // Encode PDCCH for UL transmissions - for (const stack_interface_phy_nr::pdcch_ul_t& pdcch : dl_sched.pdcch_ul) { + for (const stack_interface_phy_nr::pdcch_ul_t& pdcch : dl_sched_ptr->pdcch_ul) { // Set PDCCH configuration, including DCI dedicated if (srsran_gnb_dl_set_pdcch_config(&gnb_dl, &pdcch_cfg, &pdcch.dci_cfg) < SRSRAN_SUCCESS) { logger.error("PDCCH: Error setting DL configuration"); @@ -336,7 +349,7 @@ bool slot_worker::work_dl() } // Encode PDSCH - for (stack_interface_phy_nr::pdsch_t& pdsch : dl_sched.pdsch) { + for (const stack_interface_phy_nr::pdsch_t& pdsch : dl_sched_ptr->pdsch) { // convert MAC to PHY buffer data structures uint8_t* data[SRSRAN_MAX_TB] = {}; for (uint32_t i = 0; i < SRSRAN_MAX_TB; ++i) { @@ -367,7 +380,7 @@ bool slot_worker::work_dl() } // Put NZP-CSI-RS - for (srsran_csi_rs_nzp_resource_t& nzp_csi_rs : dl_sched.nzp_csi_rs) { + for (const srsran_csi_rs_nzp_resource_t& nzp_csi_rs : dl_sched_ptr->nzp_csi_rs) { if (srsran_gnb_dl_nzp_csi_rs_put(&gnb_dl, &dl_slot_cfg, &nzp_csi_rs) < SRSRAN_SUCCESS) { logger.error("NZP-CSI-RS: Error putting signal"); return false; @@ -378,7 +391,7 @@ bool slot_worker::work_dl() srsran_gnb_dl_gen_signal(&gnb_dl); // Add SSB to the baseband signal - for (const stack_interface_phy_nr::ssb_t& ssb : dl_sched.ssb) { + for (const stack_interface_phy_nr::ssb_t& ssb : dl_sched_ptr->ssb) { if (srsran_gnb_dl_add_ssb(&gnb_dl, &ssb.pbch_msg, dl_slot_cfg.idx) < SRSRAN_SUCCESS) { logger.error("SSB: Error putting signal"); return false; @@ -417,6 +430,16 @@ void slot_worker::work_imp() } common.worker_end(context, true, tx_rf_buffer); + +#ifdef DEBUG_WRITE_FILE + if (num_slots++ < slots_to_dump) { + printf("Writing slot %d\n", dl_slot_cfg.idx); + fwrite(tx_rf_buffer.get(0), tx_rf_buffer.get_nof_samples() * sizeof(cf_t), 1, f); + } else if (num_slots == slots_to_dump) { + printf("Baseband signaled dump finished. Please close app.\n"); + fclose(f); + } +#endif } bool slot_worker::set_common_cfg(const srsran_carrier_nr_t& carrier, diff --git a/srsenb/src/phy/nr/worker_pool.cc b/srsenb/src/phy/nr/worker_pool.cc index e6eb27d136..0d596f4ccf 100644 --- a/srsenb/src/phy/nr/worker_pool.cc +++ b/srsenb/src/phy/nr/worker_pool.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -147,6 +147,13 @@ int worker_pool::set_common_cfg(const phy_interface_rrc_nr::common_cfg_t& common ssb_cfg.scaling = srsran_convert_dB_to_amplitude(srsran_gnb_dl_get_maximum_signal_power_dBfs(common_cfg.carrier.nof_prb)); + // Print SSB configuration, helps debugging gNb and UE + if (logger.info.enabled()) { + std::array ssb_cfg_str = {}; + srsran_ssb_cfg_to_str(&ssb_cfg, ssb_cfg_str.data(), (uint32_t)ssb_cfg_str.size()); + logger.info("Setting SSB configuration %s", ssb_cfg_str.data()); + } + // For each worker set configuration for (uint32_t i = 0; i < pool.get_nof_workers(); i++) { // Reserve worker from pool diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index de61f7f309..f5710b34d2 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -94,7 +94,7 @@ void phy::parse_common_config(const phy_cfg_t& cfg) prach_cfg.root_seq_idx = cfg.prach_cnfg.root_seq_idx; prach_cfg.zero_corr_zone = cfg.prach_cnfg.prach_cfg_info.zero_correlation_zone_cfg; prach_cfg.freq_offset = cfg.prach_cnfg.prach_cfg_info.prach_freq_offset; - prach_cfg.num_ra_preambles = cfg.phy_cell_cfg.at(0).num_ra_preambles; + prach_cfg.num_ra_preambles = cfg.phy_cell_cfg.empty() ? 0 : cfg.phy_cell_cfg.at(0).num_ra_preambles; // DMRS workers_common.dmrs_pusch_cfg.cyclic_shift = cfg.pusch_cnfg.ul_ref_sigs_pusch.cyclic_shift; workers_common.dmrs_pusch_cfg.delta_ss = cfg.pusch_cnfg.ul_ref_sigs_pusch.group_assign_pusch; @@ -169,11 +169,14 @@ int phy::init_lte(const phy_args_t& args, phy_log.set_hex_dump_max_size(args.log.phy_hex_limit); radio = radio_; - nof_workers = args.nof_phy_threads; + nof_workers = cfg.phy_cell_cfg.empty() ? 0 : args.nof_phy_threads; workers_common.params = args; workers_common.init(cfg.phy_cell_cfg, cfg.phy_cell_cfg_nr, radio, stack_lte_); + if (cfg.cfr_config.cfr_enable) { + workers_common.set_cfr_config(cfg.cfr_config); + } parse_common_config(cfg); @@ -258,20 +261,28 @@ void phy::get_metrics(std::vector& metrics) metrics[j].ul.n_samples_pucch += metrics_tmp[j].ul.n_samples_pucch; metrics[j].ul.mcs += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.mcs; metrics[j].ul.n += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.n; - metrics[j].ul.rssi += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.rssi; + metrics[j].ul.pusch_rssi += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.pusch_rssi; metrics[j].ul.pusch_sinr += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.pusch_sinr; + metrics[j].ul.pucch_rssi += metrics_tmp[j].ul.n_samples_pucch * metrics_tmp[j].ul.pucch_rssi; + metrics[j].ul.pucch_ni += metrics_tmp[j].ul.n_samples_pucch * metrics_tmp[j].ul.pucch_ni; metrics[j].ul.pucch_sinr += metrics_tmp[j].ul.n_samples_pucch * metrics_tmp[j].ul.pucch_sinr; metrics[j].ul.turbo_iters += metrics_tmp[j].ul.n_samples * metrics_tmp[j].ul.turbo_iters; } } for (uint32_t j = 0; j < metrics.size(); j++) { - metrics[j].dl.mcs /= metrics[j].dl.n_samples; - metrics[j].ul.mcs /= metrics[j].ul.n_samples; - metrics[j].ul.n /= metrics[j].ul.n_samples; - metrics[j].ul.rssi /= metrics[j].ul.n_samples; - metrics[j].ul.pusch_sinr /= metrics[j].ul.n_samples; - metrics[j].ul.pucch_sinr /= metrics[j].ul.n_samples_pucch; - metrics[j].ul.turbo_iters /= metrics[j].ul.n_samples; + if (metrics[j].dl.n_samples > 0) { + metrics[j].dl.mcs /= metrics[j].dl.n_samples; + } + if (metrics[j].ul.n_samples > 0) { + metrics[j].ul.mcs /= metrics[j].ul.n_samples; + metrics[j].ul.n /= metrics[j].ul.n_samples; + metrics[j].ul.pusch_rssi /= metrics[j].ul.n_samples; + metrics[j].ul.pusch_sinr /= metrics[j].ul.n_samples; + metrics[j].ul.pucch_rssi /= metrics[j].ul.n_samples_pucch; + metrics[j].ul.pucch_ni /= metrics[j].ul.n_samples_pucch; + metrics[j].ul.pucch_sinr /= metrics[j].ul.n_samples_pucch; + metrics[j].ul.turbo_iters /= metrics[j].ul.n_samples; + } } } @@ -281,6 +292,11 @@ void phy::cmd_cell_gain(uint32_t cell_id, float gain_db) workers_common.set_cell_gain(cell_id, gain_db); } +void phy::cmd_cell_measure() +{ + workers_common.set_cell_measure_trigger(); +} + /***** RRC->PHY interface **********/ void phy::set_config(uint16_t rnti, const phy_rrc_cfg_list_t& phy_cfg_list) @@ -342,7 +358,9 @@ void phy::configure_mbsfn(srsran::sib2_mbms_t* sib2, srsran::sib13_t* sib13, con // Start GUI void phy::start_plot() { - lte_workers[0]->start_plot(); + if (lte_workers.get_nof_workers() > 0) { + lte_workers[0]->start_plot(); + } } int phy::init_nr(const phy_args_t& args, const phy_cfg_t& cfg, stack_interface_phy_nr& stack) diff --git a/srsenb/src/phy/phy_common.cc b/srsenb/src/phy/phy_common.cc index 93abfbf078..e0242007c2 100644 --- a/srsenb/src/phy/phy_common.cc +++ b/srsenb/src/phy/phy_common.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -50,15 +50,14 @@ bool phy_common::init(const phy_cell_cfg_list_t& cell_list_, cell_list_lte = cell_list_; cell_list_nr = cell_list_nr_; - pthread_mutex_init(&mtch_mutex, nullptr); - pthread_cond_init(&mtch_cvar, nullptr); // Instantiate DL channel emulator if (params.dl_channel_args.enable) { + int channel_prbs = (cell_list_lte.empty()) ? cell_list_nr[0].carrier.nof_prb : cell_list_lte[0].cell.nof_prb; dl_channel = srsran::channel_ptr( new srsran::channel(params.dl_channel_args, get_nof_rf_channels(), srslog::fetch_basic_logger("PHY"))); - dl_channel->set_srate((uint32_t)srsran_sampling_freq_hz(cell_list_lte[0].cell.nof_prb)); - dl_channel->set_signal_power_dBfs(srsran_enb_dl_get_maximum_signal_power_dBfs(cell_list_lte[0].cell.nof_prb)); + dl_channel->set_srate((uint32_t)srsran_sampling_freq_hz(channel_prbs)); + dl_channel->set_signal_power_dBfs(srsran_enb_dl_get_maximum_signal_power_dBfs(channel_prbs)); } // Create grants @@ -67,10 +66,15 @@ bool phy_common::init(const phy_cell_cfg_list_t& cell_list_, } // Set UE PHY data-base stack and configuration - ue_db.init(stack, params, cell_list_lte); - if (mcch_configured) { - build_mch_table(); - build_mcch_table(); + if (!cell_list_lte.empty()) { + ue_db.init(stack, params, cell_list_lte); + } + { + std::lock_guard lock(mbsfn_mutex); + if (mcch_configured) { + build_mch_table(); + build_mcch_table(); + } } reset(); @@ -168,15 +172,15 @@ void phy_common::worker_end(const worker_context_t& w_ctx, const bool& tx_enable void phy_common::set_mch_period_stop(uint32_t stop) { - pthread_mutex_lock(&mtch_mutex); + std::lock_guard lock(mtch_mutex); have_mtch_stop = true; mch_period_stop = stop; - pthread_cond_signal(&mtch_cvar); - pthread_mutex_unlock(&mtch_mutex); + mtch_cvar.notify_one(); } void phy_common::configure_mbsfn(srsran::phy_cfg_mbsfn_t* cfg) { + std::lock_guard lock(mbsfn_mutex); mbsfn = *cfg; sib13_configured = true; mcch_configured = true; @@ -292,9 +296,11 @@ bool phy_common::is_mch_subframe(srsran_mbsfn_cfg_t* cfg, uint32_t phy_tti) uint32_t mbsfn_per_frame = mbsfn.mcch.pmch_info_list[0].sf_alloc_end / +enum_to_number(mbsfn.mcch.pmch_info_list[0].mch_sched_period); uint32_t sf_alloc_idx = frame_alloc_idx * mbsfn_per_frame + ((sf < 4) ? sf - 1 : sf - 3); + std::unique_lock lock(mtch_mutex); while (!have_mtch_stop) { - pthread_cond_wait(&mtch_cvar, &mtch_mutex); + mtch_cvar.wait(lock); } + lock.unlock(); for (uint32_t i = 0; i < mbsfn.mcch.nof_pmch_info; i++) { if (sf_alloc_idx <= mch_period_stop) { cfg->mbsfn_mcs = mbsfn.mcch.pmch_info_list[i].data_mcs; diff --git a/srsenb/src/phy/phy_ue_db.cc b/srsenb/src/phy/phy_ue_db.cc index 1945d81f87..93b64bfd4c 100644 --- a/srsenb/src/phy/phy_ue_db.cc +++ b/srsenb/src/phy/phy_ue_db.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -793,7 +793,7 @@ int phy_ue_db::set_ul_grant_available(uint32_t tti, const stack_interface_phy_lt // Check that eNb Cell/Carrier is active for the given RNTI if (_assert_active_enb_cc(rnti, enb_cc_idx) != SRSRAN_SUCCESS) { ret = SRSRAN_ERROR; - srslog::fetch_basic_logger("PHY").error("Error setting grant for rnti=0x%x, cc=%d\n", rnti, enb_cc_idx); + srslog::fetch_basic_logger("PHY").info("Error setting grant for rnti=0x%x, cc=%d", rnti, enb_cc_idx); continue; } // Rise Grant available flag diff --git a/srsenb/src/phy/prach_worker.cc b/srsenb/src/phy/prach_worker.cc index d513327845..f447b1e5c9 100644 --- a/srsenb/src/phy/prach_worker.cc +++ b/srsenb/src/phy/prach_worker.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/src/phy/txrx.cc b/srsenb/src/phy/txrx.cc index a55ccca66f..65c98082c0 100644 --- a/srsenb/src/phy/txrx.cc +++ b/srsenb/src/phy/txrx.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,11 +21,11 @@ #include +#include "srsenb/hdr/phy/txrx.h" +#include "srsran/common/band_helper.h" #include "srsran/common/threads.h" #include "srsran/srsran.h" -#include "srsenb/hdr/phy/txrx.h" - #define Error(fmt, ...) \ if (SRSRAN_DEBUG_ENABLED) \ logger.error(fmt, ##__VA_ARGS__) @@ -94,6 +94,8 @@ void txrx::run_thread() float samp_rate = srsran_sampling_freq_hz(worker_com->get_nof_prb(0)); + srsran::srsran_band_helper band_helper; + // Configure radio radio_h->set_rx_srate(samp_rate); radio_h->set_tx_srate(samp_rate); @@ -103,11 +105,23 @@ void txrx::run_thread() double tx_freq_hz = worker_com->get_dl_freq_hz(cc_idx); double rx_freq_hz = worker_com->get_ul_freq_hz(cc_idx); uint32_t rf_port = worker_com->get_rf_port(cc_idx); - srsran::console("Setting frequency: DL=%.1f Mhz, UL=%.1f MHz for cc_idx=%d nof_prb=%d\n", - tx_freq_hz / 1e6f, - rx_freq_hz / 1e6f, - cc_idx, - worker_com->get_nof_prb(cc_idx)); + if (cc_idx < worker_com->get_nof_carriers_lte()) { + srsran::console("Setting frequency: DL=%.1f Mhz, UL=%.1f MHz for cc_idx=%d nof_prb=%d\n", + tx_freq_hz / 1e6f, + rx_freq_hz / 1e6f, + cc_idx, + worker_com->get_nof_prb(cc_idx)); + } else { + srsran::console( + "Setting frequency: DL=%.1f Mhz, DL_SSB=%.2f Mhz (SSB-ARFCN=%d), UL=%.1f MHz for cc_idx=%d nof_prb=%d\n", + tx_freq_hz / 1e6f, + worker_com->get_ssb_freq_hz(cc_idx) / 1e6f, + band_helper.freq_to_nr_arfcn(worker_com->get_ssb_freq_hz(cc_idx)), + rx_freq_hz / 1e6f, + cc_idx, + worker_com->get_nof_prb(cc_idx)); + } + radio_h->set_tx_freq(rf_port, tx_freq_hz); radio_h->set_rx_freq(rf_port, rx_freq_hz); } @@ -185,7 +199,7 @@ void txrx::run_thread() tti, timestamp.get(0).full_secs, timestamp.get(0).frac_secs, - lte_worker->get_id()); + lte_worker ? lte_worker->get_id() : 0); // Trigger prach worker execution for (uint32_t cc = 0; cc < worker_com->get_nof_carriers_lte(); cc++) { diff --git a/srsenb/src/stack/CMakeLists.txt b/srsenb/src/stack/CMakeLists.txt index 9c47324c14..09343dd20c 100644 --- a/srsenb/src/stack/CMakeLists.txt +++ b/srsenb/src/stack/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -21,13 +21,8 @@ add_subdirectory(mac) add_subdirectory(rrc) add_subdirectory(s1ap) -add_subdirectory(ngap) add_subdirectory(upper) set(SOURCES enb_stack_lte.cc) -add_library(srsenb_stack STATIC ${SOURCES}) -target_link_libraries(srsenb_stack) - -add_library(srsgnb_stack STATIC gnb_stack_nr.cc) -target_link_libraries(srsgnb_stack srsue_upper) +add_library(srsenb_stack STATIC ${SOURCES}) \ No newline at end of file diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 9429607131..2c981a21ea 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,6 +22,7 @@ #include "srsenb/hdr/stack/enb_stack_lte.h" #include "srsenb/hdr/common/rnti_pool.h" #include "srsenb/hdr/enb.h" +#include "srsenb/hdr/stack/upper/gtpu_pdcp_adapter.h" #include "srsran/interfaces/enb_metrics_interface.h" #include "srsran/interfaces/enb_x2_interfaces.h" #include "srsran/rlc/bearer_mem_pool.h" @@ -31,60 +32,6 @@ using namespace srsran; namespace srsenb { -class gtpu_pdcp_adapter final : public gtpu_interface_pdcp, public pdcp_interface_gtpu -{ -public: - gtpu_pdcp_adapter(srslog::basic_logger& logger_, - pdcp* pdcp_lte, - pdcp_interface_gtpu* pdcp_x2, - gtpu* gtpu_, - enb_bearer_manager& bearers_) : - logger(logger_), pdcp_obj(pdcp_lte), pdcp_x2_obj(pdcp_x2), gtpu_obj(gtpu_), bearers(&bearers_) - {} - - /// Converts LCID to EPS-BearerID and sends corresponding PDU to GTPU - void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override - { - auto bearer = bearers->get_lcid_bearer(rnti, lcid); - if (not bearer.is_valid()) { - logger.error("Bearer rnti=0x%x, lcid=%d not found", rnti, lcid); - return; - } - gtpu_obj->write_pdu(rnti, bearer.eps_bearer_id, std::move(pdu)); - } - void write_sdu(uint16_t rnti, uint32_t eps_bearer_id, srsran::unique_byte_buffer_t sdu, int pdcp_sn = -1) override - { - auto bearer = bearers->get_radio_bearer(rnti, eps_bearer_id); - // route SDU to PDCP entity - if (bearer.rat == srsran_rat_t::lte) { - pdcp_obj->write_sdu(rnti, bearer.lcid, std::move(sdu), pdcp_sn); - } else if (bearer.rat == srsran_rat_t::nr) { - pdcp_x2_obj->write_sdu(rnti, bearer.lcid, std::move(sdu), pdcp_sn); - } else { - logger.warning("Can't deliver SDU for EPS bearer %d. Dropping it.", eps_bearer_id); - } - } - std::map get_buffered_pdus(uint16_t rnti, uint32_t eps_bearer_id) override - { - auto bearer = bearers->get_radio_bearer(rnti, eps_bearer_id); - // route SDU to PDCP entity - if (bearer.rat == srsran_rat_t::lte) { - return pdcp_obj->get_buffered_pdus(rnti, bearer.lcid); - } else if (bearer.rat == srsran_rat_t::nr) { - return pdcp_x2_obj->get_buffered_pdus(rnti, bearer.lcid); - } - logger.error("Bearer rnti=0x%x, eps-BearerID=%d not found", rnti, eps_bearer_id); - return {}; - } - -private: - srslog::basic_logger& logger; - gtpu* gtpu_obj = nullptr; - pdcp* pdcp_obj = nullptr; - pdcp_interface_gtpu* pdcp_x2_obj = nullptr; - enb_bearer_manager* bearers = nullptr; -}; - enb_stack_lte::enb_stack_lte(srslog::sink& log_sink) : thread("STACK"), mac_logger(srslog::fetch_basic_logger("MAC", log_sink)), @@ -98,8 +45,8 @@ enb_stack_lte::enb_stack_lte(srslog::sink& log_sink) : pdcp(&task_sched, pdcp_logger), mac(&task_sched, mac_logger), rlc(rlc_logger), - gtpu(&task_sched, gtpu_logger, &rx_sockets), - s1ap(&task_sched, s1ap_logger, &rx_sockets), + gtpu(&task_sched, gtpu_logger, srsran::srsran_rat_t::lte, &get_rx_io_manager()), + s1ap(&task_sched, s1ap_logger, &get_rx_io_manager()), rrc(&task_sched, bearers), mac_pcap(), pending_stack_metrics(64) @@ -238,7 +185,7 @@ void enb_stack_lte::stop() void enb_stack_lte::stop_impl() { - rx_sockets.stop(); + get_rx_io_manager().stop(); s1ap.stop(); gtpu.stop(); diff --git a/srsenb/src/stack/mac/CMakeLists.txt b/srsenb/src/stack/mac/CMakeLists.txt index ad865183c8..3ab32ec847 100644 --- a/srsenb/src/stack/mac/CMakeLists.txt +++ b/srsenb/src/stack/mac/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -27,6 +27,4 @@ set(SOURCES mac.cc ue.cc sched.cc sched_carrier.cc sched_grid.cc sched_ue_ctrl/s sched_phy_ch/sf_cch_allocator.cc sched_phy_ch/sched_dci.cc sched_phy_ch/sched_phy_resource.cc sched_helpers.cc) add_library(srsenb_mac STATIC ${SOURCES} $) -target_link_libraries(srsenb_mac srsenb_mac_common) - -add_subdirectory(nr) \ No newline at end of file +target_link_libraries(srsenb_mac srsenb_mac_common) \ No newline at end of file diff --git a/srsenb/src/stack/mac/common/CMakeLists.txt b/srsenb/src/stack/mac/common/CMakeLists.txt index 5331c69e55..55505cd661 100644 --- a/srsenb/src/stack/mac/common/CMakeLists.txt +++ b/srsenb/src/stack/mac/common/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -18,5 +18,5 @@ # and at http://www.gnu.org/licenses/. # -set(SOURCES ue_buffer_manager.cc) +set(SOURCES base_ue_buffer_manager.cc) add_library(srsenb_mac_common STATIC ${SOURCES}) diff --git a/srsenb/src/stack/mac/common/ue_buffer_manager.cc b/srsenb/src/stack/mac/common/base_ue_buffer_manager.cc similarity index 74% rename from srsenb/src/stack/mac/common/ue_buffer_manager.cc rename to srsenb/src/stack/mac/common/base_ue_buffer_manager.cc index 21ee60e9ca..b80cc34407 100644 --- a/srsenb/src/stack/mac/common/ue_buffer_manager.cc +++ b/srsenb/src/stack/mac/common/base_ue_buffer_manager.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,22 +19,26 @@ * */ -#include "srsenb/hdr/stack/mac/common/ue_buffer_manager.h" +#include "srsenb/hdr/stack/mac/common/base_ue_buffer_manager.h" #include "srsran/adt/bounded_vector.h" #include "srsran/common/string_helpers.h" #include "srsran/srslog/bundled/fmt/format.h" #include "srsran/srslog/bundled/fmt/ranges.h" +extern "C" { +#include "srsran/config.h" +} namespace srsenb { template -ue_buffer_manager::ue_buffer_manager(uint16_t rnti_, srslog::basic_logger& logger_) : logger(logger_), rnti(rnti_) +base_ue_buffer_manager::base_ue_buffer_manager(uint16_t rnti_, srslog::basic_logger& logger_) : + logger(logger_), rnti(rnti_) { std::fill(lcg_bsr.begin(), lcg_bsr.end(), 0); } template -void ue_buffer_manager::config_lcids(srsran::const_span bearer_cfg_list) +void base_ue_buffer_manager::config_lcids(srsran::const_span bearer_cfg_list) { bool log_enabled = logger.info.enabled(); srsran::bounded_vector changed_list; @@ -64,7 +68,7 @@ void ue_buffer_manager::config_lcids(srsran::const_span b } template -void ue_buffer_manager::config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg) +void base_ue_buffer_manager::config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg) { bool cfg_changed = config_lcid_internal(lcid, bearer_cfg); if (cfg_changed) { @@ -83,7 +87,7 @@ void ue_buffer_manager::config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& * @return true if the lcid was updated with new parameters. False in case of case of error or no update. */ template -bool ue_buffer_manager::config_lcid_internal(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg) +bool base_ue_buffer_manager::config_lcid_internal(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg) { if (not is_lcid_valid(lcid)) { logger.warning("SCHED: Configuring rnti=0x%x bearer with invalid lcid=%d", rnti, lcid); @@ -111,7 +115,7 @@ bool ue_buffer_manager::config_lcid_internal(uint32_t lcid, const mac_lc_c } template -int ue_buffer_manager::get_dl_tx_total() const +int base_ue_buffer_manager::get_dl_tx_total() const { int sum = 0; for (size_t lcid = 0; is_lcid_valid(lcid); ++lcid) { @@ -121,7 +125,7 @@ int ue_buffer_manager::get_dl_tx_total() const } template -bool ue_buffer_manager::is_lcg_active(uint32_t lcg) const +bool base_ue_buffer_manager::is_lcg_active(uint32_t lcg) const { if (lcg == 0) { return true; @@ -135,13 +139,13 @@ bool ue_buffer_manager::is_lcg_active(uint32_t lcg) const } template -int ue_buffer_manager::get_bsr(uint32_t lcg) const +int base_ue_buffer_manager::get_bsr(uint32_t lcg) const { return is_lcg_active(lcg) ? lcg_bsr[lcg] : 0; } template -int ue_buffer_manager::get_bsr() const +int base_ue_buffer_manager::get_bsr() const { uint32_t count = 0; for (uint32_t lcg = 0; is_lcg_valid(lcg); ++lcg) { @@ -153,41 +157,30 @@ int ue_buffer_manager::get_bsr() const } template -void ue_buffer_manager::ul_bsr(uint32_t lcg_id, uint32_t val) +int base_ue_buffer_manager::ul_bsr(uint32_t lcg_id, uint32_t val) { if (not is_lcg_valid(lcg_id)) { logger.warning("SCHED: The provided lcg_id=%d for rnti=0x%x is not valid", lcg_id, rnti); - return; + return SRSRAN_ERROR; } lcg_bsr[lcg_id] = val; - - if (logger.debug.enabled()) { - fmt::memory_buffer str_buffer; - fmt::format_to(str_buffer, "{}", lcg_bsr); - logger.debug( - "SCHED: rnti=0x%x, lcg_id=%d, bsr=%d. Current state=%s", rnti, lcg_id, val, srsran::to_c_str(str_buffer)); - } + return SRSRAN_SUCCESS; } template -void ue_buffer_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue) +int base_ue_buffer_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue) { if (not is_lcid_valid(lcid)) { logger.warning("The provided lcid=%d is not valid", lcid); - return; - } - if (lcid <= MAX_SRB_LC_ID and - (channels[lcid].buf_tx != (int)tx_queue or channels[lcid].buf_prio_tx != (int)prio_tx_queue)) { - logger.info("SCHED: rnti=0x%x DL lcid=%d buffer_state=%d,%d", rnti, lcid, tx_queue, prio_tx_queue); - } else { - logger.debug("SCHED: rnti=0x%x DL lcid=%d buffer_state=%d,%d", rnti, lcid, tx_queue, prio_tx_queue); + return SRSRAN_ERROR; } channels[lcid].buf_prio_tx = prio_tx_queue; channels[lcid].buf_tx = tx_queue; + return SRSRAN_SUCCESS; } // Explicit instantiation -template class ue_buffer_manager; -template class ue_buffer_manager; +template class base_ue_buffer_manager; +template class base_ue_buffer_manager; } // namespace srsenb diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index f9a2b0465c..241e6894e8 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,7 +29,7 @@ #include "srsran/common/time_prof.h" #include "srsran/interfaces/enb_phy_interfaces.h" #include "srsran/interfaces/enb_rlc_interfaces.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" +#include "srsran/interfaces/enb_rrc_interface_mac.h" #include "srsran/srslog/event_trace.h" // #define WRITE_SIB_PCAP @@ -139,17 +139,20 @@ void mac::start_pcap_net(srsran::mac_pcap_net* pcap_net_) int mac::rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) { - srsran::rwlock_read_guard lock(rwlock); int ret = -1; if (check_ue_active(rnti)) { if (rnti != SRSRAN_MRNTI) { + srsran::rwlock_read_guard lock(rwlock); ret = scheduler.dl_rlc_buffer_state(rnti, lc_id, tx_queue, retx_queue); } else { - for (uint32_t i = 0; i < mch.num_mtch_sched; i++) { - if (lc_id == mch.mtch_sched[i].lcid) { - mch.mtch_sched[i].lcid_buffer_size = tx_queue; + task_sched.defer_callback(0, [this, tx_queue, lc_id]() { + srsran::rwlock_read_guard lock(rwlock); + for (uint32_t i = 0; i < mch.num_mtch_sched; i++) { + if (lc_id == mch.mtch_sched[i].lcid) { + mch.mtch_sched[i].lcid_buffer_size = tx_queue; + } } - } + }); ret = 0; } } @@ -250,7 +253,11 @@ void mac::get_metrics(mac_metrics_t& metrics) continue; } metrics.ues.emplace_back(); - u.second->metrics_read(&metrics.ues.back()); + auto& ue_metrics = metrics.ues.back(); + + u.second->metrics_read(&ue_metrics); + scheduler.metrics_read(u.first, ue_metrics); + ue_metrics.pci = (ue_metrics.cc_idx < cell_config.size()) ? cell_config[ue_metrics.cc_idx].cell.id : 0; } metrics.cc_info.resize(detected_rachs.size()); for (unsigned cc = 0, e = detected_rachs.size(); cc != e; ++cc) { @@ -464,10 +471,6 @@ bool mac::is_valid_rnti_unprotected(uint16_t rnti) logger.info("RACH ignored as eNB is being shutdown"); return false; } - if (ue_db.full()) { - logger.warning("Maximum number of connected UEs %zd connected to the eNB. Ignoring PRACH", SRSENB_MAX_UES); - return false; - } if (not ue_db.has_space(rnti)) { logger.info("Failed to allocate rnti=0x%x. Attempting a different rnti.", rnti); return false; @@ -487,6 +490,10 @@ uint16_t mac::allocate_ue(uint32_t enb_cc_idx) // Pre-check if rnti is valid { srsran::rwlock_read_guard read_lock(rwlock); + if (ue_db.full()) { + logger.warning("Maximum number of connected UEs %zd connected to the eNB. Ignoring PRACH", SRSENB_MAX_UES); + return SRSRAN_INVALID_RNTI; + } if (not is_valid_rnti_unprotected(rnti)) { continue; } @@ -521,6 +528,21 @@ uint16_t mac::allocate_ue(uint32_t enb_cc_idx) return rnti; } +bool mac::is_pending_pdcch_order_prach(const uint32_t preamble_idx, uint16_t& rnti) +{ + for (auto it = pending_po_prachs.begin(); it != pending_po_prachs.end();) { + auto& pending_po_prach = *it; + if (pending_po_prach.preamble_idx == preamble_idx) { + rnti = pending_po_prach.crnti; + // delete pending PDCCH PRACH from vector + it = pending_po_prachs.erase(it); + return true; + } + ++it; + } + return false; +} + uint16_t mac::reserve_new_crnti(const sched_interface::ue_cfg_t& uecfg) { uint16_t rnti = allocate_ue(uecfg.supported_cc_list[0].enb_cc_idx); @@ -542,9 +564,14 @@ void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx auto rach_tprof_meas = rach_tprof.start(); stack_task_queue.push([this, tti, enb_cc_idx, preamble_idx, time_adv, rach_tprof_meas]() mutable { - uint16_t rnti = allocate_ue(enb_cc_idx); - if (rnti == SRSRAN_INVALID_RNTI) { - return; + uint16_t rnti = 0; + // check if this is a PRACH from a PDCCH order + bool is_po_prach = is_pending_pdcch_order_prach(preamble_idx, rnti); + if (!is_po_prach) { + rnti = allocate_ue(enb_cc_idx); + if (rnti == SRSRAN_INVALID_RNTI) { + return; + } } rach_tprof_meas.defer_stop(); @@ -559,31 +586,50 @@ void mac::rach_detected(uint32_t tti, uint32_t enb_cc_idx, uint32_t preamble_idx // Log this event. ++detected_rachs[enb_cc_idx]; - // Add new user to the scheduler so that it can RX/TX SRB0 - sched_interface::ue_cfg_t uecfg = {}; - uecfg.supported_cc_list.emplace_back(); - uecfg.supported_cc_list.back().active = true; - uecfg.supported_cc_list.back().enb_cc_idx = enb_cc_idx; - uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; - uecfg.supported_cc_list[0].dl_cfg.tm = SRSRAN_TM1; - if (ue_cfg(rnti, &uecfg) != SRSRAN_SUCCESS) { - return; + // If this is a PRACH from a PDCCH order, the user already exists + if (not is_po_prach) { + // Add new user to the scheduler so that it can RX/TX SRB0 + sched_interface::ue_cfg_t uecfg = {}; + uecfg.supported_cc_list.emplace_back(); + uecfg.supported_cc_list.back().active = true; + uecfg.supported_cc_list.back().enb_cc_idx = enb_cc_idx; + uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; + uecfg.supported_cc_list[0].dl_cfg.tm = SRSRAN_TM1; + if (ue_cfg(rnti, &uecfg) != SRSRAN_SUCCESS) { + return; + } + + // Register new user in RRC + if (rrc_h->add_user(rnti, uecfg) == SRSRAN_ERROR) { + ue_rem(rnti); + return; + } } - // Register new user in RRC - if (rrc_h->add_user(rnti, uecfg) == SRSRAN_ERROR) { + // Trigger scheduler RACH + if (scheduler.dl_rach_info(enb_cc_idx, rar_info) != SRSRAN_SUCCESS) { ue_rem(rnti); return; } - // Trigger scheduler RACH - scheduler.dl_rach_info(enb_cc_idx, rar_info); - - logger.info( - "RACH: tti=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x", tti, enb_cc_idx, preamble_idx, time_adv, rnti); - srsran::console("RACH: tti=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x\n", + auto get_pci = [this, enb_cc_idx]() { + srsran::rwlock_read_guard lock(rwlock); + return (enb_cc_idx < cell_config.size()) ? cell_config[enb_cc_idx].cell.id : 0; + }; + uint32_t pci = get_pci(); + logger.info("%sRACH: tti=%d, cc=%d, pci=%d, preamble=%d, offset=%d, temp_crnti=0x%x", + (is_po_prach) ? "PDCCH order " : "", + tti, + enb_cc_idx, + pci, + preamble_idx, + time_adv, + rnti); + srsran::console("%sRACH: tti=%d, cc=%d, pci=%d, preamble=%d, offset=%d, temp_crnti=0x%x\n", + (is_po_prach) ? "PDCCH order " : "", tti, enb_cc_idx, + pci, preamble_idx, time_adv, rnti); @@ -596,7 +642,7 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list) return 0; } - trace_threshold_complete_event("mac::run_slot", "total_time", std::chrono::microseconds(100)); + trace_threshold_complete_event("mac::get_dl_sched", "total_time", std::chrono::microseconds(100)); logger.set_context(TTI_SUB(tti_tx_dl, FDD_HARQ_DELAY_UL_MS)); if (do_padding) { add_padding(); @@ -664,7 +710,7 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list) tb_count++; } - // Count transmission if at least one TB has succesfully added + // Count transmission if at least one TB has successfully added if (tb_count > 0) { n++; } @@ -743,6 +789,24 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list) n++; } + // Copy PDCCH order grants + for (uint32_t i = 0; i < sched_result.po.size(); i++) { + uint16_t rnti = sched_result.po[i].dci.rnti; + if (ue_db.contains(rnti)) { + // Copy dci info + dl_sched_res->pdsch[n].dci = sched_result.po[i].dci; + if (pcap) { + pcap->write_dl_pch(dl_sched_res->pdsch[n].data[0], sched_result.po[i].tbs, true, tti_tx_dl, enb_cc_idx); + } + if (pcap_net) { + pcap_net->write_dl_pch(dl_sched_res->pdsch[n].data[0], sched_result.po[i].tbs, true, tti_tx_dl, enb_cc_idx); + } + n++; + } else { + logger.warning("Invalid PDCCH order scheduling result. User 0x%x does not exist", rnti); + } + } + dl_sched_res->nof_grants = n; // Number of CCH symbols @@ -823,7 +887,6 @@ int mac::get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res ue_db[SRSRAN_MRNTI]->metrics_tx(true, mcs.tbs); dl_sched_res->pdsch[0].data[0] = ue_db[SRSRAN_MRNTI]->generate_mch_pdu(tti % SRSRAN_FDD_NOF_HARQ, mch, mch.num_mtch_sched + 1, mcs.tbs / 8); - } else { uint32_t current_lcid = 1; uint32_t mtch_index = 0; @@ -876,6 +939,9 @@ uint8_t* mac::assemble_rar(sched_interface::dl_sched_rar_grant_t* grants, srsran::rar_pdu* pdu = &rar_pdu_msg[rar_idx]; rar_payload[enb_cc_idx][rar_idx].clear(); pdu->init_tx(&rar_payload[enb_cc_idx][rar_idx], pdu_len); + if (args.prach_bi > 0 and args.prach_bi <= 12) { + pdu->set_backoff(args.prach_bi); + } for (uint32_t i = 0; i < nof_grants; i++) { srsran_dci_rar_pack(&grants[i].grant, grant_buffer); if (pdu->new_subh()) { @@ -959,7 +1025,6 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list) } else { logger.warning("Invalid UL scheduling result. User 0x%x does not exist", rnti); } - } else { logger.warning("Grant %d for rnti=0x%x has zero TBS", i, sched_result.pusch[i].dci.rnti); } @@ -994,7 +1059,7 @@ void mac::write_mcch(const srsran::sib2_mbms_t* sib2_, sib2 = *sib2_; sib13 = *sib13_; memcpy(mcch_payload_buffer, mcch_payload, mcch_payload_length * sizeof(uint8_t)); - current_mcch_length = mcch_payload_length; + current_mcch_length = mcch_payload_length; unique_rnti_ptr ue_ptr = make_rnti_obj( SRSRAN_MRNTI, SRSRAN_MRNTI, 0, &scheduler, rrc_h, rlc_h, phy_h, logger, cells.size(), softbuffer_pool.get()); @@ -1003,7 +1068,6 @@ void mac::write_mcch(const srsran::sib2_mbms_t* sib2_, if (!ret) { logger.info("Failed to allocate rnti=0x%x.for eMBMS", SRSRAN_MRNTI); } - rrc_h->add_user(SRSRAN_MRNTI, {}); } // Internal helper function, caller must hold UE DB rwlock diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc deleted file mode 100644 index 237874b8ec..0000000000 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ /dev/null @@ -1,257 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsenb/hdr/stack/mac/nr/sched_nr.h" -#include "srsenb/hdr/stack/mac/common/mac_metrics.h" -#include "srsenb/hdr/stack/mac/nr/harq_softbuffer.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_cell.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_worker.h" -#include "srsran/common/thread_pool.h" - -namespace srsenb { - -using namespace sched_nr_impl; - -static int assert_ue_cfg_valid(uint16_t rnti, const sched_nr_interface::ue_cfg_t& uecfg); - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -class ul_sched_result_buffer -{ -public: - explicit ul_sched_result_buffer(uint32_t nof_cc_) - { - for (auto& v : results) { - v.resize(nof_cc_); - } - } - - ul_sched_t& add_ul_result(slot_point tti, uint32_t cc) - { - if (not has_ul_result(tti, cc)) { - results[tti.to_uint()][cc].slot_ul = tti; - results[tti.to_uint()][cc].ul_res = {}; - } - return results[tti.to_uint()][cc].ul_res; - } - - bool has_ul_result(slot_point tti, uint32_t cc) const { return results[tti.to_uint()][cc].slot_ul == tti; } - - ul_sched_t pop_ul_result(slot_point tti, uint32_t cc) - { - if (has_ul_result(tti, cc)) { - results[tti.to_uint()][cc].slot_ul.clear(); - return results[tti.to_uint()][cc].ul_res; - } - return {}; - } - -private: - struct slot_result_t { - slot_point slot_ul; - ul_sched_t ul_res; - }; - - srsran::circular_array, TTIMOD_SZ> results; -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -sched_nr::sched_nr() : logger(&srslog::fetch_basic_logger("MAC-NR")) {} - -sched_nr::~sched_nr() {} - -int sched_nr::config(const sched_args_t& sched_cfg, srsran::const_span cell_list) -{ - cfg = sched_params{sched_cfg}; - logger = &srslog::fetch_basic_logger(sched_cfg.logger_name); - - // Initiate Common Sched Configuration - cfg.cells.reserve(cell_list.size()); - for (uint32_t cc = 0; cc < cell_list.size(); ++cc) { - cfg.cells.emplace_back(cc, cell_list[cc], cfg.sched_cfg); - } - - // Initiate cell-specific schedulers - cells.reserve(cell_list.size()); - for (uint32_t cc = 0; cc < cell_list.size(); ++cc) { - cells.emplace_back(new serv_cell_manager{cfg.cells[cc]}); - } - - pending_results.reset(new ul_sched_result_buffer(cell_list.size())); - sched_workers.reset(new sched_nr_impl::sched_worker_manager(ue_db, cfg, cells)); - - return SRSRAN_SUCCESS; -} - -void sched_nr::ue_cfg(uint16_t rnti, const ue_cfg_t& uecfg) -{ - srsran_assert(assert_ue_cfg_valid(rnti, uecfg) == SRSRAN_SUCCESS, "Invalid UE configuration"); - sched_workers->enqueue_event(rnti, [this, rnti, uecfg]() { ue_cfg_impl(rnti, uecfg); }); -} - -void sched_nr::ue_rem(uint16_t rnti) -{ - sched_workers->enqueue_event(rnti, [this, rnti]() { - auto ue_it = ue_db.find(rnti); - if (ue_it == ue_db.end()) { - logger->warning("SCHED: ue_rem(rnti) called for inexistent rnti=0x%x", rnti); - return; - } - ue_db.erase(rnti); - }); -} - -bool sched_nr::ue_exists(uint16_t rnti) -{ - return ue_db.contains(rnti); -} - -void sched_nr::ue_cfg_impl(uint16_t rnti, const ue_cfg_t& uecfg) -{ - if (not ue_db.contains(rnti)) { - auto ret = ue_db.insert(rnti, std::unique_ptr(new ue{rnti, uecfg, cfg})); - if (ret.has_value()) { - logger->info("SCHED: New user rnti=0x%x, cc=%d", rnti, cfg.cells[0].cc); - } else { - logger->error("SCHED: Failed to create new user rnti=0x%x", rnti); - } - } else { - ue_db[rnti]->set_cfg(uecfg); - } -} - -/// Generate {pdcch_slot,cc} scheduling decision -int sched_nr::run_slot(slot_point slot_dl, uint32_t cc, dl_res_t& result) -{ - // Copy UL results to intermediate buffer - ul_res_t& ul_res = pending_results->add_ul_result(slot_dl, cc); - - // Generate {slot_idx,cc} result - sched_workers->run_slot(slot_dl, cc, result, ul_res); - - return SRSRAN_SUCCESS; -} - -/// Fetch {ul_slot,cc} UL scheduling decision -int sched_nr::get_ul_sched(slot_point slot_ul, uint32_t cc, ul_res_t& result) -{ - if (not pending_results->has_ul_result(slot_ul, cc)) { - // sched result hasn't been generated - result.pucch.clear(); - result.pusch.clear(); - return SRSRAN_SUCCESS; - } - - result = pending_results->pop_ul_result(slot_ul, cc); - return SRSRAN_SUCCESS; -} - -void sched_nr::get_metrics(mac_metrics_t& metrics) -{ - sched_workers->get_metrics(metrics); -} - -int sched_nr::dl_rach_info(uint32_t cc, const rar_info_t& rar_info) -{ - sched_workers->enqueue_cc_event(cc, [this, cc, rar_info]() { cells[cc]->bwps[0].ra.dl_rach_info(rar_info); }); - return SRSRAN_SUCCESS; -} - -void sched_nr::dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) -{ - sched_workers->enqueue_cc_feedback(rnti, cc, [this, pid, tb_idx, ack](ue_carrier& ue_cc) { - int tbs = ue_cc.harq_ent.dl_ack_info(pid, tb_idx, ack); - if (tbs >= 0) { - std::lock_guard lock(ue_cc.metrics_mutex); - if (ack) { - ue_cc.metrics.tx_brate += tbs; - } else { - ue_cc.metrics.tx_errors++; - } - ue_cc.metrics.tx_pkts++; - } else { - logger->warning("SCHED: rnti=0x%x, received DL HARQ-ACK for empty pid=%d", ue_cc.rnti, pid); - } - }); -} - -void sched_nr::ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) -{ - sched_workers->enqueue_cc_feedback(rnti, cc, [this, pid, crc](ue_carrier& ue_cc) { - if (ue_cc.harq_ent.ul_crc_info(pid, crc) < 0) { - logger->warning("SCHED: rnti=0x%x, received CRC for empty pid=%d", ue_cc.rnti, pid); - } - }); -} - -void sched_nr::ul_sr_info(uint16_t rnti) -{ - sched_workers->enqueue_event(rnti, [this, rnti]() { - if (ue_db.contains(rnti)) { - ue_db[rnti]->ul_sr_info(); - } else { - logger->warning("Received SR for inexistent rnti=0x%x", rnti); - } - }); -} - -void sched_nr::ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) -{ - sched_workers->enqueue_event(rnti, [this, rnti, lcg_id, bsr]() { - if (ue_db.contains(rnti)) { - ue_db[rnti]->ul_bsr(lcg_id, bsr); - } else { - logger->warning("Received BSR=%d for inexistent rnti=0x%x", bsr, rnti); - } - }); -} - -void sched_nr::dl_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t newtx, uint32_t retx) -{ - sched_workers->enqueue_event(rnti, [this, rnti, lcid, newtx, retx]() { - if (ue_db.contains(rnti)) { - ue_db[rnti]->rlc_buffer_state(lcid, newtx, retx); - } else { - logger->warning("Received DL buffer state=%d/%d for inexistent rnti=0x%x", newtx, retx, rnti); - } - }); -} - -#define VERIFY_INPUT(cond, msg, ...) \ - do { \ - if (not(cond)) { \ - srslog::fetch_basic_logger("MAC").warning(msg, ##__VA_ARGS__); \ - return SRSRAN_ERROR; \ - } \ - } while (0) - -int assert_ue_cfg_valid(uint16_t rnti, const sched_nr_interface::ue_cfg_t& uecfg) -{ - VERIFY_INPUT(std::count(&uecfg.phy_cfg.pdcch.coreset_present[0], - &uecfg.phy_cfg.pdcch.coreset_present[SRSRAN_UE_DL_NR_MAX_NOF_CORESET], - true) > 0, - "Provided rnti=0x%x configuration does not contain any coreset", - rnti); - return SRSRAN_SUCCESS; -} - -} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc deleted file mode 100644 index 8446277cf2..0000000000 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ /dev/null @@ -1,441 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_cell.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_helpers.h" - -namespace srsenb { -namespace sched_nr_impl { - -bwp_slot_grid::bwp_slot_grid(const bwp_params_t& bwp_cfg_, uint32_t slot_idx_) : - dl_prbs(bwp_cfg_.cfg.rb_width, bwp_cfg_.cfg.start_rb, bwp_cfg_.cfg.pdsch.rbg_size_cfg_1), - ul_prbs(bwp_cfg_.cfg.rb_width, bwp_cfg_.cfg.start_rb, bwp_cfg_.cfg.pdsch.rbg_size_cfg_1), - slot_idx(slot_idx_), - cfg(&bwp_cfg_), - rar_softbuffer(harq_softbuffer_pool::get_instance().get_tx(bwp_cfg_.cfg.rb_width)) -{ - for (uint32_t cs_idx = 0; cs_idx < SRSRAN_UE_DL_NR_MAX_NOF_CORESET; ++cs_idx) { - if (cfg->cfg.pdcch.coreset_present[cs_idx]) { - uint32_t cs_id = cfg->cfg.pdcch.coreset[cs_idx].id; - coresets[cs_id].emplace(*cfg, cs_id, slot_idx_, dl_pdcchs, ul_pdcchs); - } - } -} - -void bwp_slot_grid::reset() -{ - for (auto& coreset : coresets) { - if (coreset.has_value()) { - coreset->reset(); - } - } - dl_prbs.reset(); - ul_prbs.reset(); - dl_pdcchs.clear(); - ul_pdcchs.clear(); - pdschs.clear(); - puschs.clear(); - pending_acks.clear(); - pucch.clear(); - ssb.clear(); - nzp_csi_rs.clear(); - rar.clear(); -} - -bwp_res_grid::bwp_res_grid(const bwp_params_t& bwp_cfg_) : cfg(&bwp_cfg_) -{ - for (uint32_t sl = 0; sl < slots.capacity(); ++sl) { - slots.emplace_back(*cfg, sl % static_cast(SRSRAN_NSLOTS_PER_FRAME_NR(0u))); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -bwp_slot_allocator::bwp_slot_allocator(bwp_res_grid& bwp_grid_) : - logger(bwp_grid_.cfg->logger), cfg(*bwp_grid_.cfg), bwp_grid(bwp_grid_) -{} - -alloc_result bwp_slot_allocator::alloc_si(uint32_t aggr_idx, uint32_t si_idx, uint32_t si_ntx, const prb_interval& prbs) -{ - bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot]; - if (not bwp_pdcch_slot.is_dl()) { - logger.warning("SCHED: Trying to allocate PDSCH in TDD non-DL slot index=%d", bwp_pdcch_slot.slot_idx); - return alloc_result::no_sch_space; - } - pdcch_dl_list_t& pdsch_grants = bwp_pdcch_slot.dl_pdcchs; - if (pdsch_grants.full()) { - logger.warning("SCHED: Maximum number of DL allocations reached"); - return alloc_result::no_grant_space; - } - if (bwp_pdcch_slot.dl_prbs.collides(prbs)) { - return alloc_result::sch_collision; - } - - // TODO: Allocate PDCCH and PDSCH - - return alloc_result::success; -} - -alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t ra_rnti, - uint32_t aggr_idx, - prb_interval interv, - srsran::const_span pending_rars) -{ - static const uint32_t msg3_nof_prbs = 3, m = 0; - - bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot]; - if (not bwp_pdcch_slot.ssb.empty()) { - // TODO: support concurrent PDSCH and SSB - logger.info("SCHED: skipping ra-rnti=0x%x RAR allocation. Cause: concurrent PDSCH and SSB not yet supported", - ra_rnti); - return alloc_result::no_sch_space; - } - slot_point msg3_slot = pdcch_slot + cfg.pusch_ra_list[m].msg3_delay; - bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_slot]; - alloc_result ret = verify_pusch_space(bwp_msg3_slot, nullptr); - if (ret != alloc_result::success) { - return ret; - } - ret = verify_pdsch_space(bwp_pdcch_slot, bwp_pdcch_slot); - if (ret != alloc_result::success) { - return ret; - } - if (bwp_pdcch_slot.rar.full()) { - return alloc_result::no_grant_space; - } - if (pending_rars.size() > MAX_GRANTS) { - logger.error("SCHED: Trying to allocate too many Msg3 grants in a single slot (%zd)", pending_rars.size()); - return alloc_result::invalid_grant_params; - } - for (auto& rar : pending_rars) { - if (not slot_ues->contains(rar.temp_crnti)) { - logger.info("SCHED: Postponing rnti=0x%x RAR allocation. Cause: The ue object not yet fully created", - rar.temp_crnti); - return alloc_result::no_rnti_opportunity; - } - } - - // Check DL RB collision - if (bwp_pdcch_slot.dl_prbs.collides(interv)) { - logger.debug("SCHED: Provided RBG mask collides with allocation previously made."); - return alloc_result::sch_collision; - } - - // Check Msg3 RB collision - uint32_t total_ul_nof_prbs = msg3_nof_prbs * pending_rars.size(); - uint32_t total_ul_nof_rbgs = srsran::ceil_div(total_ul_nof_prbs, get_P(bwp_grid.nof_prbs(), false)); - prb_interval msg3_rbs = find_empty_interval_of_length(bwp_msg3_slot.ul_prbs.prbs(), total_ul_nof_rbgs); - if (msg3_rbs.length() < total_ul_nof_rbgs) { - logger.debug("SCHED: No space in PUSCH for Msg3."); - return alloc_result::sch_collision; - } - - // Find PDCCH position - const uint32_t coreset_id = cfg.cfg.pdcch.ra_search_space.coreset_id; - const uint32_t search_space_id = cfg.cfg.pdcch.ra_search_space.id; - if (not bwp_pdcch_slot.coresets[coreset_id]->alloc_dci(pdcch_grant_type_t::rar, aggr_idx, search_space_id, nullptr)) { - // Could not find space in PDCCH - logger.debug("SCHED: No space in PDCCH for DL tx."); - return alloc_result::no_cch_space; - } - - // RAR allocation successful. - bwp_pdcch_slot.dl_prbs |= interv; - // Generate DCI for RAR with given RA-RNTI - pdcch_dl_t& pdcch = bwp_pdcch_slot.dl_pdcchs.back(); - if (not fill_dci_rar(interv, ra_rnti, *bwp_grid.cfg, pdcch.dci)) { - // Cancel on-going PDCCH allocation - bwp_pdcch_slot.coresets[coreset_id]->rem_last_dci(); - return alloc_result::invalid_coderate; - } - auto& phy_cfg = (*slot_ues)[pending_rars[0].temp_crnti].cfg->phy(); - pdcch.dci_cfg = phy_cfg.get_dci_cfg(); - // Generate RAR PDSCH - // TODO: Properly fill Msg3 grants - bwp_pdcch_slot.pdschs.emplace_back(); - pdsch_t& pdsch = bwp_pdcch_slot.pdschs.back(); - srsran_slot_cfg_t slot_cfg; - slot_cfg.idx = pdcch_slot.to_uint(); - bool success = phy_cfg.get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch); - srsran_assert(success, "Error converting DCI to grant"); - pdsch.sch.grant.tb[0].softbuffer.tx = bwp_pdcch_slot.rar_softbuffer->get(); - - // Generate Msg3 grants in PUSCH - uint32_t last_msg3 = msg3_rbs.start(); - const int mcs = 0, max_harq_msg3_retx = 4; - slot_cfg.idx = msg3_slot.to_uint(); - bwp_pdcch_slot.rar.emplace_back(); - sched_nr_interface::rar_t& rar_out = bwp_pdcch_slot.rar.back(); - for (const dl_sched_rar_info_t& grant : pending_rars) { - slot_ue& ue = (*slot_ues)[grant.temp_crnti]; - - // Generate RAR grant - rar_out.grants.emplace_back(); - auto& rar_grant = rar_out.grants.back(); - rar_grant.data = grant; - prb_interval msg3_interv{last_msg3, last_msg3 + msg3_nof_prbs}; - last_msg3 += msg3_nof_prbs; - ue.h_ul = ue.harq_ent->find_empty_ul_harq(); - success = ue.h_ul->new_tx(msg3_slot, msg3_slot, msg3_interv, mcs, max_harq_msg3_retx); - srsran_assert(success, "Failed to allocate Msg3"); - fill_dci_msg3(ue, *bwp_grid.cfg, rar_grant.msg3_dci); - - // Generate PUSCH - bwp_msg3_slot.puschs.emplace_back(); - pusch_t& pusch = bwp_msg3_slot.puschs.back(); - success = ue.cfg->phy().get_pusch_cfg(slot_cfg, rar_grant.msg3_dci, pusch.sch); - srsran_assert(success, "Error converting DCI to PUSCH grant"); - pusch.sch.grant.tb[0].softbuffer.rx = ue.h_ul->get_softbuffer().get(); - ue.h_ul->set_tbs(pusch.sch.grant.tb[0].tbs); - } - bwp_msg3_slot.ul_prbs.add(msg3_rbs); - - return alloc_result::success; -} - -// ue is the UE (1 only) that will be allocated -// func computes the grant allocation for this UE -alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant) -{ - if (ue.cfg->active_bwp().bwp_id != bwp_grid.cfg->bwp_id) { - logger.warning( - "SCHED: Trying to allocate PDSCH for rnti=0x%x in inactive BWP id=%d", ue.rnti, ue.cfg->active_bwp().bwp_id); - return alloc_result::no_rnti_opportunity; - } - if (ue.h_dl == nullptr) { - logger.warning("SCHED: Trying to allocate PDSCH for rnti=0x%x with no available HARQs", ue.rnti); - return alloc_result::no_rnti_opportunity; - } - bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot]; - bwp_slot_grid& bwp_pdsch_slot = bwp_grid[ue.pdsch_slot]; - bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_slot]; // UCI : UL control info - alloc_result result = verify_pdsch_space(bwp_pdsch_slot, bwp_pdcch_slot); - if (result != alloc_result::success) { - return result; - } - if (bwp_uci_slot.pending_acks.full()) { - logger.warning("SCHED: PDSCH allocation for rnti=0x%x failed due to lack of space for respective ACK", ue.rnti); - return alloc_result::no_grant_space; - } - if (bwp_pdsch_slot.dl_prbs.collides(dl_grant)) { - return alloc_result::sch_collision; - } - if (not bwp_pdcch_slot.ssb.empty()) { - // TODO: support concurrent PDSCH and SSB - logger.info("SCHED: skipping rnti=0x%x PDSCH allocation. Cause: concurrent PDSCH and SSB not yet supported", - ue.rnti); - return alloc_result::no_sch_space; - } - - // Find space in PUCCH - // TODO - - // Find space and allocate PDCCH - const uint32_t aggr_idx = 2; - // Choose the ss_id the highest number of candidates - uint32_t ss_id = 0, max_nof_candidates = 0; - for (uint32_t i = 0; i < 3; ++i) { - uint32_t nof_candidates = ue.cfg->cce_pos_list(i, pdcch_slot.slot_idx(), aggr_idx).size(); - if (nof_candidates > max_nof_candidates) { - ss_id = i; - max_nof_candidates = nof_candidates; - } - } - uint32_t coreset_id = ue.cfg->phy().pdcch.search_space[ss_id].coreset_id; - if (not bwp_pdcch_slot.coresets[coreset_id]->alloc_dci(pdcch_grant_type_t::dl_data, aggr_idx, ss_id, &ue)) { - // Could not find space in PDCCH - return alloc_result::no_cch_space; - } - - // Allocate HARQ - int mcs = ue.cfg->fixed_pdsch_mcs(); - if (ue.h_dl->empty()) { - bool ret = ue.h_dl->new_tx(ue.pdsch_slot, ue.uci_slot, dl_grant, mcs, 4); - srsran_assert(ret, "Failed to allocate DL HARQ"); - } else { - bool ret = ue.h_dl->new_retx(ue.pdsch_slot, ue.uci_slot, dl_grant); - mcs = ue.h_dl->mcs(); - srsran_assert(ret, "Failed to allocate DL HARQ retx"); - } - - // Allocation Successful - - const static float max_R = 0.93; - while (true) { - // Generate PDCCH - pdcch_dl_t& pdcch = bwp_pdcch_slot.dl_pdcchs.back(); - fill_dl_dci_ue_fields(ue, *bwp_grid.cfg, ss_id, pdcch.dci.ctx.location, pdcch.dci); - pdcch.dci.pucch_resource = 0; - pdcch.dci.dai = std::count_if(bwp_uci_slot.pending_acks.begin(), - bwp_uci_slot.pending_acks.end(), - [&ue](const harq_ack_t& p) { return p.res.rnti == ue.rnti; }); - pdcch.dci.dai %= 4; - pdcch.dci_cfg = ue.cfg->phy().get_dci_cfg(); - - // Generate PUCCH - bwp_uci_slot.pending_acks.emplace_back(); - bwp_uci_slot.pending_acks.back().phy_cfg = &ue.cfg->phy(); - srsran_assert(ue.cfg->phy().get_pdsch_ack_resource(pdcch.dci, bwp_uci_slot.pending_acks.back().res), - "Error getting ack resource"); - - // Generate PDSCH - bwp_pdsch_slot.dl_prbs |= dl_grant; - bwp_pdsch_slot.pdschs.emplace_back(); - pdsch_t& pdsch = bwp_pdsch_slot.pdschs.back(); - srsran_slot_cfg_t slot_cfg; - slot_cfg.idx = ue.pdsch_slot.to_uint(); - bool ret = ue.cfg->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch); - srsran_assert(ret, "Error converting DCI to grant"); - - pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get(); - pdsch.data[0] = ue.h_dl->get_tx_pdu()->get(); - if (ue.h_dl->nof_retx() == 0) { - ue.h_dl->set_tbs(pdsch.sch.grant.tb[0].tbs); // update HARQ with correct TBS - } else { - srsran_assert(pdsch.sch.grant.tb[0].tbs == (int)ue.h_dl->tbs(), "The TBS did not remain constant in retx"); - } - if (ue.h_dl->nof_retx() > 0 or bwp_pdsch_slot.pdschs.back().sch.grant.tb[0].R_prime < max_R or mcs <= 0) { - break; - } - // Decrease MCS if first tx and rate is too high - mcs--; - ue.h_dl->set_mcs(mcs); - bwp_pdsch_slot.pdschs.pop_back(); - bwp_uci_slot.pending_acks.pop_back(); - } - if (mcs == 0) { - logger.warning("Couldn't find mcs that leads to R<0.9"); - } - - return alloc_result::success; -} - -alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_prbs) -{ - auto& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot]; - auto& bwp_pusch_slot = bwp_grid[ue.pusch_slot]; - alloc_result ret = verify_pusch_space(bwp_pusch_slot, &bwp_pdcch_slot); - if (ret != alloc_result::success) { - return ret; - } - - if (ue.h_ul == nullptr) { - logger.warning("SCHED: Trying to allocate PUSCH for rnti=0x%x with no available HARQs", ue.rnti); - return alloc_result::no_rnti_opportunity; - } - pdcch_ul_list_t& pdcchs = bwp_pdcch_slot.ul_pdcchs; - if (bwp_pusch_slot.ul_prbs.collides(ul_prbs)) { - return alloc_result::sch_collision; - } - const uint32_t aggr_idx = 2; - // Choose the ss_id the highest number of candidates - uint32_t ss_id = 0, max_nof_candidates = 0; - for (uint32_t i = 0; i < 3; ++i) { - uint32_t nof_candidates = ue.cfg->cce_pos_list(i, pdcch_slot.slot_idx(), aggr_idx).size(); - if (nof_candidates > max_nof_candidates) { - ss_id = i; - max_nof_candidates = nof_candidates; - } - } - uint32_t coreset_id = ue.cfg->phy().pdcch.search_space[ss_id].coreset_id; - if (not bwp_pdcch_slot.coresets[coreset_id].value().alloc_dci(pdcch_grant_type_t::ul_data, aggr_idx, ss_id, &ue)) { - // Could not find space in PDCCH - return alloc_result::no_cch_space; - } - - if (ue.h_ul->empty()) { - int mcs = ue.cfg->fixed_pusch_mcs(); - int tbs = 100; - bool success = ue.h_ul->new_tx(ue.pusch_slot, ue.pusch_slot, ul_prbs, mcs, ue.cfg->ue_cfg()->maxharq_tx); - srsran_assert(success, "Failed to allocate UL HARQ"); - } else { - bool success = ue.h_ul->new_retx(ue.pusch_slot, ue.pusch_slot, ul_prbs); - srsran_assert(success, "Failed to allocate UL HARQ retx"); - } - - // Allocation Successful - // Generate PDCCH - pdcch_ul_t& pdcch = pdcchs.back(); - fill_ul_dci_ue_fields(ue, *bwp_grid.cfg, ss_id, pdcch.dci.ctx.location, pdcch.dci); - pdcch.dci_cfg = ue.cfg->phy().get_dci_cfg(); - // Generate PUSCH - bwp_pusch_slot.ul_prbs |= ul_prbs; - bwp_pusch_slot.puschs.emplace_back(); - pusch_t& pusch = bwp_pusch_slot.puschs.back(); - srsran_slot_cfg_t slot_cfg; - slot_cfg.idx = ue.pusch_slot.to_uint(); - pusch.pid = ue.h_ul->pid; - bool success = ue.cfg->phy().get_pusch_cfg(slot_cfg, pdcch.dci, pusch.sch); - srsran_assert(success, "Error converting DCI to PUSCH grant"); - pusch.sch.grant.tb[0].softbuffer.rx = ue.h_ul->get_softbuffer().get(); - if (ue.h_ul->nof_retx() == 0) { - ue.h_ul->set_tbs(pusch.sch.grant.tb[0].tbs); // update HARQ with correct TBS - } else { - srsran_assert(pusch.sch.grant.tb[0].tbs == (int)ue.h_ul->tbs(), "The TBS did not remain constant in retx"); - } - - return alloc_result::success; -} - -alloc_result bwp_slot_allocator::verify_pdsch_space(bwp_slot_grid& bwp_pdsch, bwp_slot_grid& bwp_pdcch) const -{ - if (not bwp_pdsch.is_dl() or not bwp_pdcch.is_dl()) { - logger.warning("SCHED: Trying to allocate PDSCH in TDD non-DL slot index=%d", bwp_pdsch.slot_idx); - return alloc_result::no_sch_space; - } - if (bwp_pdcch.dl_pdcchs.full()) { - logger.warning("SCHED: Maximum number of DL PDCCH allocations reached"); - return alloc_result::no_cch_space; - } - if (bwp_pdsch.pdschs.full()) { - logger.warning("SCHED: Maximum number of DL PDSCH grants reached"); - return alloc_result::no_sch_space; - } - return alloc_result::success; -} - -alloc_result bwp_slot_allocator::verify_pusch_space(bwp_slot_grid& pusch_grid, bwp_slot_grid* pdcch_grid) const -{ - if (not pusch_grid.is_ul()) { - logger.warning("SCHED: Trying to allocate PUSCH in TDD non-UL slot index=%d", pusch_grid.slot_idx); - return alloc_result::no_sch_space; - } - if (pdcch_grid != nullptr) { - // DCI needed - if (not pdcch_grid->is_dl()) { - logger.warning("SCHED: Trying to allocate PDCCH in TDD non-DL slot index=%d", pdcch_grid->slot_idx); - return alloc_result::no_sch_space; - } - if (pdcch_grid->ul_pdcchs.full()) { - logger.warning("SCHED: Maximum number of PUSCH allocations reached"); - return alloc_result::no_grant_space; - } - } - if (pusch_grid.puschs.full()) { - logger.warning("SCHED: Maximum number of PUSCH allocations reached"); - return alloc_result::no_grant_space; - } - return alloc_result::success; -} - -} // namespace sched_nr_impl -} // namespace srsenb \ No newline at end of file diff --git a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc deleted file mode 100644 index 0b5a95e566..0000000000 --- a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc +++ /dev/null @@ -1,227 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsenb/hdr/stack/mac/nr/sched_nr_helpers.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_harq.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_ue.h" -#include "srsran/common/string_helpers.h" - -namespace srsenb { -namespace sched_nr_impl { - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -template -void fill_dci_common(const slot_ue& ue, const bwp_params_t& bwp_cfg, DciDlOrUl& dci) -{ - const static uint32_t rv_idx[4] = {0, 2, 3, 1}; - - dci.bwp_id = ue.cfg->active_bwp().bwp_id; - dci.cc_id = ue.cc; - dci.tpc = 1; - // harq - harq_proc* h = std::is_same::value ? static_cast(ue.h_dl) - : static_cast(ue.h_ul); - dci.pid = h->pid; - dci.ndi = h->ndi(); - dci.mcs = h->mcs(); - dci.rv = rv_idx[h->nof_retx() % 4]; - // PRB assignment - const prb_grant& grant = h->prbs(); - if (grant.is_alloc_type0()) { - dci.freq_domain_assigment = grant.rbgs().to_uint64(); - } else { - dci.freq_domain_assigment = - srsran_ra_nr_type1_riv(bwp_cfg.cfg.rb_width, grant.prbs().start(), grant.prbs().length()); - } - dci.time_domain_assigment = 0; -} - -bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci) -{ - dci.mcs = 5; - dci.ctx.format = srsran_dci_format_nr_1_0; - dci.ctx.ss_type = srsran_search_space_type_common_1; - dci.ctx.rnti_type = srsran_rnti_type_ra; - dci.ctx.rnti = ra_rnti; - dci.ctx.coreset_id = bwp_cfg.cfg.pdcch.ra_search_space.coreset_id; - dci.freq_domain_assigment = srsran_ra_nr_type1_riv(bwp_cfg.cfg.rb_width, interv.start(), interv.length()); - dci.time_domain_assigment = 0; - dci.tpc = 1; - dci.bwp_id = bwp_cfg.bwp_id; - dci.cc_id = bwp_cfg.cc; - // TODO: Fill - - return true; -} - -bool fill_dci_msg3(const slot_ue& ue, const bwp_params_t& bwp_cfg, srsran_dci_ul_nr_t& msg3_dci) -{ - fill_dci_common(ue, bwp_cfg, msg3_dci); - msg3_dci.ctx.coreset_id = ue.cfg->phy().pdcch.ra_search_space.coreset_id; - msg3_dci.ctx.rnti_type = srsran_rnti_type_tc; - msg3_dci.ctx.rnti = ue.rnti; - msg3_dci.ctx.ss_type = srsran_search_space_type_rar; - if (ue.h_ul->nof_retx() == 0) { - msg3_dci.ctx.format = srsran_dci_format_nr_rar; - } else { - msg3_dci.ctx.format = srsran_dci_format_nr_0_0; - } - - return true; -} - -void fill_dl_dci_ue_fields(const slot_ue& ue, - const bwp_params_t& bwp_cfg, - uint32_t ss_id, - srsran_dci_location_t dci_pos, - srsran_dci_dl_nr_t& dci) -{ - // Note: DCI location may not be the final one, as scheduler may rellocate the UE PDCCH. However, the remaining DCI - // params are independent of the exact DCI location - bool ret = ue.cfg->phy().get_dci_ctx_pdsch_rnti_c(ss_id, dci_pos, ue.rnti, dci.ctx); - srsran_assert(ret, "Invalid DL DCI format"); - - fill_dci_common(ue, bwp_cfg, dci); - if (dci.ctx.format == srsran_dci_format_nr_1_0) { - dci.harq_feedback = (ue.uci_slot - ue.pdsch_slot) - 1; - } else { - dci.harq_feedback = ue.pdsch_slot.slot_idx(); - } -} - -void fill_ul_dci_ue_fields(const slot_ue& ue, - const bwp_params_t& bwp_cfg, - uint32_t ss_id, - srsran_dci_location_t dci_pos, - srsran_dci_ul_nr_t& dci) -{ - bool ret = ue.cfg->phy().get_dci_ctx_pusch_rnti_c(ss_id, dci_pos, ue.rnti, dci.ctx); - srsran_assert(ret, "Invalid DL DCI format"); - - fill_dci_common(ue, bwp_cfg, dci); -} - -void log_sched_slot_ues(srslog::basic_logger& logger, slot_point pdcch_slot, uint32_t cc, const slot_ue_map_t& slot_ues) -{ - if (not logger.debug.enabled() or slot_ues.empty()) { - return; - } - - fmt::memory_buffer fmtbuf; - fmt::format_to(fmtbuf, "SCHED: UE candidates, pdcch_tti={}, cc={}: [", pdcch_slot, cc); - - const char* use_comma = ""; - for (const auto& ue_pair : slot_ues) { - auto& ue = ue_pair->second; - - fmt::format_to( - fmtbuf, "{}{{rnti=0x{:x}, dl_bs={}, ul_bs={}}}", use_comma, ue.rnti, ue.dl_pending_bytes, ue.ul_pending_bytes); - use_comma = ", "; - } - - logger.debug("%s]", srsran::to_c_str(fmtbuf)); -} - -void log_sched_bwp_result(srslog::basic_logger& logger, - slot_point pdcch_slot, - const bwp_res_grid& res_grid, - const slot_ue_map_t& slot_ues) -{ - const bwp_slot_grid& bwp_slot = res_grid[pdcch_slot]; - size_t rar_count = 0; - for (const pdcch_dl_t& pdcch : bwp_slot.dl_pdcchs) { - fmt::memory_buffer fmtbuf; - if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) { - const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; - fmt::format_to(fmtbuf, - "SCHED: DL {}, cc={}, rnti=0x{:x}, pid={}, cs={}, f={}, prbs={}, nrtx={}, dai={}, " - "tbs={}, bs={}, pdsch_slot={}, tti_ack={}", - ue.h_dl->nof_retx() == 0 ? "tx" : "retx", - res_grid.cfg->cc, - ue.rnti, - pdcch.dci.pid, - pdcch.dci.ctx.coreset_id, - srsran_dci_format_nr_string(pdcch.dci.ctx.format), - ue.h_dl->prbs(), - ue.h_dl->nof_retx(), - pdcch.dci.dai, - ue.h_dl->tbs() / 8u, - ue.dl_pending_bytes, - ue.pdsch_slot, - ue.uci_slot); - } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_ra) { - const pdsch_t& pdsch = bwp_slot.pdschs[std::distance(bwp_slot.dl_pdcchs.data(), &pdcch)]; - srsran::const_span prbs{pdsch.sch.grant.prb_idx, pdsch.sch.grant.prb_idx + pdsch.sch.grant.nof_prb}; - uint32_t start_idx = std::distance(prbs.begin(), std::find(prbs.begin(), prbs.end(), true)); - uint32_t end_idx = std::distance(prbs.begin(), std::find(prbs.begin() + start_idx, prbs.end(), false)); - fmt::format_to(fmtbuf, - "SCHED: RAR, cc={}, ra-rnti=0x{:x}, prbs={}, pdsch_slot={}, msg3_slot={}, nof_grants={}", - res_grid.cfg->cc, - pdcch.dci.ctx.rnti, - srsran::interval{start_idx, end_idx}, - pdcch_slot, - pdcch_slot + res_grid.cfg->pusch_ra_list[0].msg3_delay, - bwp_slot.rar[rar_count].grants.size()); - rar_count++; - } else { - fmt::format_to(fmtbuf, "SCHED: unknown format"); - } - - logger.info("%s", srsran::to_c_str(fmtbuf)); - } - for (const pdcch_ul_t& pdcch : bwp_slot.ul_pdcchs) { - fmt::memory_buffer fmtbuf; - if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) { - const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; - fmt::format_to(fmtbuf, - "SCHED: UL {}, cc={}, rnti=0x{:x}, pid={}, cs={}, f={}, nrtx={}, tbs={}, bs={}, tti_pusch={}", - ue.h_ul->nof_retx() == 0 ? "tx" : "retx", - res_grid.cfg->cc, - ue.rnti, - pdcch.dci.pid, - pdcch.dci.ctx.coreset_id, - srsran_dci_format_nr_string(pdcch.dci.ctx.format), - ue.h_ul->nof_retx(), - ue.h_ul->tbs() / 8u, - ue.ul_pending_bytes, - ue.pusch_slot); - } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_tc) { - const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; - fmt::format_to(fmtbuf, - "SCHED: UL Msg3, cc={}, tc-rnti=0x{:x}, pid={}, nrtx={}, f={}, tti_pusch={}", - res_grid.cfg->cc, - ue.rnti, - pdcch.dci.pid, - ue.h_ul->nof_retx(), - srsran_dci_format_nr_string(pdcch.dci.ctx.format), - ue.pusch_slot); - } else { - fmt::format_to(fmtbuf, "SCHED: unknown rnti format"); - } - - logger.info("%s", srsran::to_c_str(fmtbuf)); - } -} - -} // namespace sched_nr_impl -} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc b/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc deleted file mode 100644 index 78b4bdc4fb..0000000000 --- a/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_ue.h" - -namespace srsenb { -namespace sched_nr_impl { - -coreset_region::coreset_region(const bwp_params_t& bwp_cfg_, - uint32_t coreset_id_, - uint32_t slot_idx_, - pdcch_dl_list_t& dl_list_, - pdcch_ul_list_t& ul_list_) : - coreset_cfg(&bwp_cfg_.cfg.pdcch.coreset[coreset_id_]), - coreset_id(coreset_id_), - slot_idx(slot_idx_), - pdcch_dl_list(dl_list_), - pdcch_ul_list(ul_list_), - rar_cce_list(bwp_cfg_.rar_cce_list) -{ - const bool* res_active = &coreset_cfg->freq_resources[0]; - nof_freq_res = std::count(res_active, res_active + SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE, true); - srsran_assert(get_td_symbols() <= SRSRAN_CORESET_DURATION_MAX, - "Possible number of time-domain OFDM symbols in CORESET must be within {1,2,3}"); - srsran_assert(nof_freq_res <= bwp_cfg_.cell_cfg.carrier.nof_prb, - "The number of frequency resources=%d of coreset_id=%d exceeds BWP bandwidth", - nof_freq_res, - coreset_id); -} - -void coreset_region::reset() -{ - dfs_tree.clear(); - saved_dfs_tree.clear(); - dci_list.clear(); - pdcch_dl_list.clear(); - pdcch_ul_list.clear(); -} - -bool coreset_region::alloc_dci(pdcch_grant_type_t alloc_type, - uint32_t aggr_idx, - uint32_t search_space_id, - slot_ue* user) -{ - srsran_assert(aggr_idx <= 4, "Invalid DCI aggregation level=%d", 1U << aggr_idx); - srsran_assert((user == nullptr) xor - (alloc_type == pdcch_grant_type_t::dl_data or alloc_type == pdcch_grant_type_t::ul_data), - "UE should be only provided for DL or UL data allocations"); - srsran_assert(not dci_list.full(), "SCHED: Unable to allocate DCI"); - saved_dfs_tree.clear(); - - alloc_record record; - record.ue = user; - record.aggr_idx = aggr_idx; - record.ss_id = search_space_id; - record.alloc_type = alloc_type; - if (record.alloc_type == pdcch_grant_type_t::ul_data) { - record.idx = pdcch_ul_list.size(); - pdcch_ul_list.emplace_back(); - } else { - record.idx = pdcch_dl_list.size(); - pdcch_dl_list.emplace_back(); - } - - // Try to allocate grant. If it fails, attempt the same grant, but using a different permutation of past grant DCI - // positions - do { - bool success = alloc_dfs_node(record, 0); - if (success) { - // DCI record allocation successful - dci_list.push_back(record); - return true; - } - if (saved_dfs_tree.empty()) { - saved_dfs_tree = dfs_tree; - } - } while (get_next_dfs()); - - // Revert steps to initial state, before dci record allocation was attempted - dfs_tree.swap(saved_dfs_tree); - if (record.alloc_type == pdcch_grant_type_t::ul_data) { - pdcch_ul_list.pop_back(); - } else { - pdcch_dl_list.pop_back(); - } - return false; -} - -void coreset_region::rem_last_dci() -{ - srsran_assert(not dci_list.empty(), "%s called when no PDCCH have yet been allocated", __FUNCTION__); - - // Remove DCI record - dfs_tree.pop_back(); - if (dci_list.back().alloc_type == pdcch_grant_type_t::ul_data) { - pdcch_ul_list.pop_back(); - } else { - pdcch_dl_list.pop_back(); - } - dci_list.pop_back(); -} - -bool coreset_region::get_next_dfs() -{ - do { - if (dfs_tree.empty()) { - // If we reach root, the allocation failed - return false; - } - // Attempt to re-add last tree node, but with a higher node child index - uint32_t start_child_idx = dfs_tree.back().dci_pos_idx + 1; - dfs_tree.pop_back(); - while (dfs_tree.size() < dci_list.size() and alloc_dfs_node(dci_list[dfs_tree.size()], start_child_idx)) { - start_child_idx = 0; - } - } while (dfs_tree.size() < dci_list.size()); - - // Finished computation of next DFS node - return true; -} - -bool coreset_region::alloc_dfs_node(const alloc_record& record, uint32_t start_dci_idx) -{ - alloc_tree_dfs_t& alloc_dfs = dfs_tree; - // Get DCI Location Table - auto cce_locs = get_cce_loc_table(record); - if (start_dci_idx >= cce_locs.size()) { - return false; - } - - tree_node node; - node.dci_pos_idx = start_dci_idx; - node.dci_pos.L = record.aggr_idx; - node.rnti = record.ue != nullptr ? record.ue->rnti : SRSRAN_INVALID_RNTI; - node.current_mask.resize(nof_cces()); - // get cumulative pdcch bitmap - if (not alloc_dfs.empty()) { - node.total_mask = alloc_dfs.back().total_mask; - } else { - node.total_mask.resize(nof_cces()); - } - - for (; node.dci_pos_idx < cce_locs.size(); ++node.dci_pos_idx) { - node.dci_pos.ncce = cce_locs[node.dci_pos_idx]; - - node.current_mask.reset(); - node.current_mask.fill(node.dci_pos.ncce, node.dci_pos.ncce + (1U << record.aggr_idx)); - if ((node.total_mask & node.current_mask).any()) { - // there is a PDCCH collision. Try another CCE position - continue; - } - - // Allocation successful - node.total_mask |= node.current_mask; - alloc_dfs.push_back(node); - if (record.alloc_type == pdcch_grant_type_t::ul_data) { - pdcch_ul_t& pdcch_ul = pdcch_ul_list[record.idx]; - pdcch_ul.dci.ctx.location = node.dci_pos; - } else { - pdcch_dl_t& pdcch_dl = pdcch_dl_list[record.idx]; - pdcch_dl.dci.ctx.location = node.dci_pos; - } - return true; - } - - return false; -} - -srsran::span coreset_region::get_cce_loc_table(const alloc_record& record) const -{ - switch (record.alloc_type) { - case pdcch_grant_type_t::dl_data: - return record.ue->cfg->cce_pos_list(record.ss_id, slot_idx, record.aggr_idx); - case pdcch_grant_type_t::ul_data: - return record.ue->cfg->cce_pos_list(record.ss_id, slot_idx, record.aggr_idx); - case pdcch_grant_type_t::rar: - return rar_cce_list[slot_idx][record.aggr_idx]; - default: - break; - } - return {}; -} - -} // namespace sched_nr_impl -} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_signalling.cc b/srsenb/src/stack/mac/nr/sched_nr_signalling.cc deleted file mode 100644 index dd2aabeb45..0000000000 --- a/srsenb/src/stack/mac/nr/sched_nr_signalling.cc +++ /dev/null @@ -1,114 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsenb/hdr/stack/mac/nr/sched_nr_signalling.h" - -#define POS_IN_BURST_FIRST_BIT_IDX 0 -#define POS_IN_BURST_SECOND_BIT_IDX 1 -#define POS_IN_BURST_THIRD_BIT_IDX 2 -#define POS_IN_BURST_FOURTH_BIT_IDX 3 - -#define DEFAULT_SSB_PERIODICITY 5 - -namespace srsenb { -namespace sched_nr_impl { - -void sched_nzp_csi_rs(srsran::const_span nzp_csi_rs_sets_cfg, - const srsran_slot_cfg_t& slot_cfg, - nzp_csi_rs_list& csi_rs_list) -{ - for (const srsran_csi_rs_nzp_set_t& set : nzp_csi_rs_sets_cfg) { - // For each NZP-CSI-RS resource available in the set - for (uint32_t i = 0; i < set.count; ++i) { - // Select resource - const srsran_csi_rs_nzp_resource_t& nzp_csi_resource = set.data[i]; - - // Check if the resource is scheduled for this slot - if (srsran_csi_rs_send(&nzp_csi_resource.periodicity, &slot_cfg)) { - if (csi_rs_list.full()) { - srslog::fetch_basic_logger("MAC-NR").error("SCHED: Failed to allocate NZP-CSI RS"); - return; - } - csi_rs_list.push_back(nzp_csi_resource); - } - } - } -} - -void sched_ssb_basic(const slot_point& sl_point, uint32_t ssb_periodicity, ssb_list& ssb_list) -{ - if (ssb_list.full()) { - srslog::fetch_basic_logger("MAC-NR").error("SCHED: Failed to allocate SSB"); - return; - } - // If the periodicity is 0, it means that the parameter was not passed by the upper layers. - // In that case, we use default value of 5ms (see Clause 4.1, TS 38.213) - if (ssb_periodicity == 0) { - ssb_periodicity = DEFAULT_SSB_PERIODICITY; - } - - uint32_t sl_cnt = sl_point.to_uint(); - // Perform mod operation of slot index by ssb_periodicity; - // "ssb_periodicity * nof_slots_per_subframe" gives the number of slots in 1 ssb_periodicity time interval - uint32_t sl_point_mod = sl_cnt % (ssb_periodicity * (uint32_t)sl_point.nof_slots_per_subframe()); - - // code below is simplified, it assumes 15kHz subcarrier spacing and sub 3GHz carrier - if (sl_point_mod == 0) { - ssb_t ssb_msg = {}; - srsran_mib_nr_t mib_msg = {}; - mib_msg.sfn = sl_point.sfn(); - mib_msg.hrf = (sl_point.slot_idx() % SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) >= - SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) / 2); - // This corresponds to "Position in Burst" = 1000 - mib_msg.ssb_idx = 0; - // Setting the following 4 parameters is redundant, but it makes it explicit what values are passed to PHY - mib_msg.dmrs_typeA_pos = srsran_dmrs_sch_typeA_pos_2; - mib_msg.scs_common = srsran_subcarrier_spacing_15kHz; - mib_msg.coreset0_idx = 0; - mib_msg.ss0_idx = 0; - - // Pack mib message to be sent to PHY - int packing_ret_code = srsran_pbch_msg_nr_mib_pack(&mib_msg, &ssb_msg.pbch_msg); - srsran_assert(packing_ret_code == SRSRAN_SUCCESS, "SSB packing returned en error"); - ssb_list.push_back(ssb_msg); - } -} - -void sched_dl_signalling(const bwp_params_t& bwp_params, - slot_point sl_pdcch, - ssb_list& ssb_list, - nzp_csi_rs_list& nzp_csi_rs) -{ - srsran_slot_cfg_t cfg; - cfg.idx = sl_pdcch.to_uint(); - - // Schedule SSB - sched_ssb_basic(sl_pdcch, bwp_params.cell_cfg.ssb.periodicity_ms, ssb_list); - - // Schedule NZP-CSI-RS - sched_nzp_csi_rs(bwp_params.cfg.pdsch.nzp_csi_rs_sets, cfg, nzp_csi_rs); - - // Schedule SIBs - // TODO -} - -} // namespace sched_nr_impl -} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc deleted file mode 100644 index 631832905c..0000000000 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsenb/hdr/stack/mac/nr/sched_nr_ue.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h" -#include "srsran/common/string_helpers.h" - -namespace srsenb { -namespace sched_nr_impl { - -slot_ue::slot_ue(uint16_t rnti_, slot_point slot_rx_, uint32_t cc_) : rnti(rnti_), slot_rx(slot_rx_), cc(cc_) {} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -ue_carrier::ue_carrier(uint16_t rnti_, const ue_cfg_t& uecfg_, const cell_params_t& cell_params_) : - rnti(rnti_), - cc(cell_params_.cc), - bwp_cfg(rnti_, cell_params_.bwps[0], uecfg_), - cell_params(cell_params_), - harq_ent(rnti_, cell_params_.nof_prb(), SCHED_NR_MAX_HARQ, cell_params_.bwps[0].logger) -{} - -void ue_carrier::set_cfg(const ue_cfg_t& ue_cfg) -{ - bwp_cfg = bwp_ue_cfg(rnti, cell_params.bwps[0], ue_cfg); -} - -void ue_carrier::new_slot(slot_point slot_tx) -{ - harq_ent.new_slot(slot_tx - TX_ENB_DELAY); -} - -slot_ue ue_carrier::try_reserve(slot_point pdcch_slot, uint32_t dl_pending_bytes, uint32_t ul_pending_bytes) -{ - slot_point slot_rx = pdcch_slot - TX_ENB_DELAY; - - // copy cc-specific parameters and find available HARQs - slot_ue sfu(rnti, slot_rx, cc); - sfu.cfg = &bwp_cfg; - sfu.pdcch_slot = pdcch_slot; - sfu.harq_ent = &harq_ent; - const uint32_t k0 = 0; - sfu.pdsch_slot = sfu.pdcch_slot + k0; - uint32_t k1 = sfu.cfg->get_k1(sfu.pdsch_slot); - sfu.uci_slot = sfu.pdsch_slot + k1; - uint32_t k2 = bwp_cfg.active_bwp().pusch_ra_list[0].K; - sfu.pusch_slot = sfu.pdcch_slot + k2; - sfu.dl_cqi = dl_cqi; - sfu.ul_cqi = ul_cqi; - - // set UE-common parameters - sfu.dl_pending_bytes = dl_pending_bytes; - sfu.ul_pending_bytes = ul_pending_bytes; - - const srsran_duplex_config_nr_t& tdd_cfg = cell_params.cfg.duplex; - if (srsran_duplex_nr_is_dl(&tdd_cfg, 0, sfu.pdsch_slot.slot_idx())) { - // If DL enabled - sfu.h_dl = harq_ent.find_pending_dl_retx(); - if (sfu.h_dl == nullptr and sfu.dl_pending_bytes > 0) { - sfu.h_dl = harq_ent.find_empty_dl_harq(); - } - } - if (srsran_duplex_nr_is_ul(&tdd_cfg, 0, sfu.pusch_slot.slot_idx())) { - // If UL enabled - sfu.h_ul = harq_ent.find_pending_ul_retx(); - if (sfu.h_ul == nullptr and sfu.ul_pending_bytes > 0) { - sfu.h_ul = harq_ent.find_empty_ul_harq(); - } - } - - return sfu; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -ue::ue(uint16_t rnti_, const ue_cfg_t& cfg, const sched_params& sched_cfg_) : - rnti(rnti_), sched_cfg(sched_cfg_), buffers(rnti_, srslog::fetch_basic_logger(sched_cfg_.sched_cfg.logger_name)) -{ - set_cfg(cfg); -} - -void ue::set_cfg(const ue_cfg_t& cfg) -{ - ue_cfg = cfg; - for (auto& ue_cc_cfg : cfg.carriers) { - if (ue_cc_cfg.active) { - if (carriers[ue_cc_cfg.cc] == nullptr) { - carriers[ue_cc_cfg.cc].reset(new ue_carrier(rnti, ue_cfg, sched_cfg.cells[ue_cc_cfg.cc])); - } else { - carriers[ue_cc_cfg.cc]->set_cfg(ue_cfg); - } - } - } - - buffers.config_lcids(cfg.ue_bearers); -} - -void ue::new_slot(slot_point pdcch_slot) -{ - last_pdcch_slot = pdcch_slot; - - // Compute pending DL/UL bytes for {rnti, pdcch_slot} - if (sched_cfg.sched_cfg.auto_refill_buffer) { - dl_pending_bytes = 1000000; - ul_pending_bytes = 1000000; - } else { - dl_pending_bytes = buffers.get_dl_tx_total(); - ul_pending_bytes = buffers.get_bsr(); - for (auto& ue_cc_cfg : ue_cfg.carriers) { - auto& cc = carriers[ue_cc_cfg.cc]; - if (cc != nullptr) { - // Discount UL HARQ pending bytes to BSR - for (uint32_t pid = 0; pid < cc->harq_ent.nof_ul_harqs(); ++pid) { - if (not cc->harq_ent.ul_harq(pid).empty()) { - ul_pending_bytes -= cc->harq_ent.ul_harq(pid).tbs(); - if (last_sr_slot.valid() and cc->harq_ent.ul_harq(pid).harq_slot_tx() > last_sr_slot) { - last_sr_slot.clear(); - } - } - } - } - } - ul_pending_bytes = std::max(0, ul_pending_bytes); - if (ul_pending_bytes == 0 and last_sr_slot.valid()) { - // If unanswered SR is pending - ul_pending_bytes = 512; - } - } -} - -slot_ue ue::try_reserve(slot_point pdcch_slot, uint32_t cc) -{ - srsran_assert(carriers[cc] != nullptr, "try_reserve() called for inexistent rnti=0x%x,cc=%d", rnti, cc); - return carriers[cc]->try_reserve(pdcch_slot, dl_pending_bytes, ul_pending_bytes); -} - -} // namespace sched_nr_impl -} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc deleted file mode 100644 index 936eaad469..0000000000 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ /dev/null @@ -1,404 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsenb/hdr/stack/mac/nr/sched_nr_worker.h" -#include "srsenb/hdr/stack/mac/common/mac_metrics.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_signalling.h" -#include "srsran/common/string_helpers.h" - -namespace srsenb { -namespace sched_nr_impl { - -slot_cc_worker::slot_cc_worker(serv_cell_manager& cc_sched) : - cell(cc_sched), - cfg(cc_sched.cfg), - bwp_alloc(cc_sched.bwps[0].grid), - logger(srslog::fetch_basic_logger(cc_sched.cfg.sched_args.logger_name)) -{} - -void slot_cc_worker::enqueue_cc_event(srsran::move_callback ev) -{ - std::lock_guard lock(feedback_mutex); - pending_events.emplace_back(); - pending_events.back() = std::move(ev); -} - -void slot_cc_worker::enqueue_cc_feedback(uint16_t rnti, feedback_callback_t fdbk) -{ - std::lock_guard lock(feedback_mutex); - pending_feedback.emplace_back(); - pending_feedback.back().rnti = rnti; - pending_feedback.back().fdbk = std::move(fdbk); -} - -void slot_cc_worker::run_feedback(ue_map_t& ue_db) -{ - { - std::lock_guard lock(feedback_mutex); - tmp_feedback_to_run.swap(pending_feedback); - tmp_events_to_run.swap(pending_events); - } - - for (srsran::move_callback& ev : tmp_events_to_run) { - ev(); - } - tmp_events_to_run.clear(); - - for (feedback_t& f : tmp_feedback_to_run) { - if (ue_db.contains(f.rnti) and ue_db[f.rnti]->carriers[cfg.cc] != nullptr) { - f.fdbk(*ue_db[f.rnti]->carriers[cfg.cc]); - } else { - logger.info("SCHED: feedback received for rnti=0x%x, cc=%d that has been removed.", f.rnti, cfg.cc); - } - } - tmp_feedback_to_run.clear(); -} - -/// Called within a locked context, to generate {slot, cc} scheduling decision -void slot_cc_worker::run(slot_point pdcch_slot, ue_map_t& ue_db) -{ - srsran_assert(not running(), "scheduler worker::start() called for active worker"); - slot_rx = pdcch_slot - TX_ENB_DELAY; - - // Run pending cell feedback (process feedback) - run_feedback(ue_db); - - // Reserve UEs for this worker slot (select candidate UEs) - for (auto& ue_pair : ue_db) { - uint16_t rnti = ue_pair.first; - ue& u = *ue_pair.second; - if (u.carriers[cfg.cc] == nullptr) { - continue; - } - - // Update UE CC state - u.carriers[cfg.cc]->new_slot(pdcch_slot); - - // info for a given UE on a slot to be process - slot_ues.insert(rnti, u.try_reserve(pdcch_slot, cfg.cc)); - if (slot_ues[rnti].empty()) { - // Failed to generate slot UE because UE has no conditions for DL/UL tx - slot_ues.erase(rnti); - continue; - } - // UE acquired successfully for scheduling in this {slot, cc} - } - - // Create an BWP allocator object that will passed along to RA, SI, Data schedulers - bwp_alloc.new_slot(slot_rx + TX_ENB_DELAY, slot_ues); - - // Log UEs state for slot - log_sched_slot_ues(logger, bwp_alloc.get_pdcch_tti(), cfg.cc, slot_ues); - - // Allocate pending RARs - cell.bwps[0].ra.run_slot(bwp_alloc); - - // TODO: Prioritize PDCCH scheduling for DL and UL data in a Round-Robin fashion - alloc_dl_ues(); - alloc_ul_ues(); - - // Post-processing of scheduling decisions - postprocess_decisions(); - - // Log CC scheduler result - log_sched_bwp_result(logger, bwp_alloc.get_pdcch_tti(), cell.bwps[0].grid, slot_ues); - - // releases UE resources - slot_ues.clear(); - slot_rx = {}; -} - -void slot_cc_worker::alloc_dl_ues() -{ - if (not cfg.sched_args.pdsch_enabled) { - return; - } - cell.bwps[0].data_sched->sched_dl_users(slot_ues, bwp_alloc); -} - -void slot_cc_worker::alloc_ul_ues() -{ - if (not cfg.sched_args.pusch_enabled) { - return; - } - cell.bwps[0].data_sched->sched_ul_users(slot_ues, bwp_alloc); -} - -void slot_cc_worker::postprocess_decisions() -{ - auto& bwp_slot = cell.bwps[0].grid[bwp_alloc.get_pdcch_tti()]; - srsran_slot_cfg_t slot_cfg{}; - slot_cfg.idx = bwp_alloc.get_pdcch_tti().to_uint(); - - for (auto& ue_pair : slot_ues) { - auto& ue = ue_pair.second; - // Group pending HARQ ACKs - srsran_pdsch_ack_nr_t ack = {}; - - for (auto& h_ack : bwp_slot.pending_acks) { - if (h_ack.res.rnti == ue.rnti) { - ack.nof_cc = 1; - - srsran_harq_ack_m_t ack_m = {}; - ack_m.resource = h_ack.res; - ack_m.present = true; - srsran_harq_ack_insert_m(&ack, &ack_m); - } - } - - srsran_uci_cfg_nr_t uci_cfg = {}; - if (not ue.cfg->phy().get_uci_cfg(slot_cfg, ack, uci_cfg)) { - logger.error("Error getting UCI configuration"); - continue; - } - - if (uci_cfg.ack.count == 0 and uci_cfg.nof_csi == 0 and uci_cfg.o_sr == 0) { - continue; - } - - bool has_pusch = false; - for (auto& pusch : bwp_slot.puschs) { - if (pusch.sch.grant.rnti == ue.rnti) { - // Put UCI configuration in PUSCH config - has_pusch = true; - - // If has PUSCH, no SR shall be received - uci_cfg.o_sr = 0; - - if (not ue.cfg->phy().get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { - logger.error("Error setting UCI configuration in PUSCH"); - continue; - } - break; - } - } - if (not has_pusch) { - // If any UCI information is triggered, schedule PUCCH - if (bwp_slot.pucch.full()) { - logger.warning("SCHED: Cannot fit pending UCI into PUCCH"); - continue; - } - bwp_slot.pucch.emplace_back(); - mac_interface_phy_nr::pucch_t& pucch = bwp_slot.pucch.back(); - - uci_cfg.pucch.rnti = ue.rnti; - pucch.candidates.emplace_back(); - pucch.candidates.back().uci_cfg = uci_cfg; - if (not ue.cfg->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { - logger.error("Error getting UCI CFG"); - continue; - } - - // If this slot has a SR opportunity and the selected PUCCH format is 1, consider positive SR. - if (uci_cfg.o_sr > 0 and uci_cfg.ack.count > 0 and - pucch.candidates.back().resource.format == SRSRAN_PUCCH_NR_FORMAT_1) { - // Set SR negative - if (uci_cfg.o_sr > 0) { - uci_cfg.sr_positive_present = false; - } - - // Append new resource - pucch.candidates.emplace_back(); - pucch.candidates.back().uci_cfg = uci_cfg; - if (not ue.cfg->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { - logger.error("Error getting UCI CFG"); - continue; - } - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -sched_worker_manager::sched_worker_manager(ue_map_t& ue_db_, - const sched_params& cfg_, - srsran::span > cells_) : - cfg(cfg_), ue_db(ue_db_), logger(srslog::fetch_basic_logger(cfg_.sched_cfg.logger_name)), cells(cells_) -{ - cc_worker_list.reserve(cfg.cells.size()); - for (uint32_t cc = 0; cc < cfg.cells.size(); ++cc) { - cc_worker_list.emplace_back(new cc_context{*cells[cc]}); - } -} - -sched_worker_manager::~sched_worker_manager() = default; - -void sched_worker_manager::enqueue_event(uint16_t rnti, srsran::move_callback ev) -{ - std::lock_guard lock(event_mutex); - next_slot_events.push_back(ue_event_t{rnti, std::move(ev)}); -} - -void sched_worker_manager::enqueue_cc_event(uint32_t cc, srsran::move_callback ev) -{ - cc_worker_list[cc]->worker.enqueue_cc_event(std::move(ev)); -} - -/** - * Update UEs state that is non-CC specific (e.g. SRs, buffer status, UE configuration) - * @param slot_tx - * @param locked_context to update only UEs with CA enabled or not - */ -void sched_worker_manager::update_ue_db(slot_point slot_tx, bool locked_context) -{ - // process non-cc specific feedback if pending (e.g. SRs, buffer updates, UE config) - for (ue_event_t& ev : slot_events) { - if ((locked_context and not ue_db.contains(ev.rnti)) or - (ue_db.contains(ev.rnti) and ue_db[ev.rnti]->has_ca() == locked_context)) { - ev.callback(); - } - } - - // prepare UEs internal state for new slot - for (auto& u : ue_db) { - if (u.second->has_ca() == locked_context) { - u.second->new_slot(slot_tx); - } - } -} - -void sched_worker_manager::run_slot(slot_point slot_tx, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res) -{ - // Fill DL signalling messages that do not depend on UEs state - serv_cell_manager& serv_cell = *cells[cc]; - bwp_slot_grid& bwp_slot = serv_cell.bwps[0].grid[slot_tx]; - sched_dl_signalling(*serv_cell.bwps[0].cfg, slot_tx, bwp_slot.ssb, bwp_slot.nzp_csi_rs); - - // Synchronization point between CC workers, to avoid concurrency in UE state access - srsran::bounded_vector waiting_cvars; - { - std::unique_lock lock(slot_mutex); - while (current_slot.valid() and current_slot != slot_tx) { - // Wait for previous slot to finish - cc_worker_list[cc]->waiting++; - cc_worker_list[cc]->cvar.wait(lock); - cc_worker_list[cc]->waiting--; - } - if (not current_slot.valid()) { - /* First Worker to start slot */ - - // process non-cc specific feedback if pending for UEs with CA - // NOTE: there is no parallelism in these operations - slot_events.clear(); - { - std::lock_guard ev_lock(event_mutex); - next_slot_events.swap(slot_events); - } - update_ue_db(slot_tx, true); - - // mark the start of slot. awake remaining workers if locking on the mutex - current_slot = slot_tx; - worker_count.store(static_cast(cc_worker_list.size()), std::memory_order_relaxed); - for (auto& w : cc_worker_list) { - if (w->waiting > 0) { - waiting_cvars.push_back(&w->cvar); - } - } - lock.unlock(); - for (auto& w : waiting_cvars) { - w->notify_one(); - } - waiting_cvars.clear(); - } - } - - /* Parallel Region */ - - // process non-cc specific feedback if pending (e.g. SRs, buffer updates, UE config) for UEs without CA - update_ue_db(slot_tx, false); - - // process pending feedback, generate {slot, cc} scheduling decision - cc_worker_list[cc]->worker.run(slot_tx, ue_db); - - // decrement the number of active workers - int rem_workers = worker_count.fetch_sub(1, std::memory_order_release) - 1; - srsran_assert(rem_workers >= 0, "invalid number of calls to run_slot(slot, cc)"); - if (rem_workers == 0) { - /* Last Worker to finish slot */ - - // Signal the release of slot if it is the last worker that finished its own generation - std::unique_lock lock(slot_mutex); - current_slot = {}; - - // All the workers of the same slot have finished. Synchronize scheduling decisions with UEs state - for (auto& c : cc_worker_list) { - if (c->waiting > 0) { - waiting_cvars.push_back(&c->cvar); - } - } - - // Awake waiting workers - lock.unlock(); - for (auto& c : waiting_cvars) { - c->notify_one(); - } - } - - // Post-process and copy results to intermediate buffer - save_sched_result(slot_tx, cc, dl_res, ul_res); -} - -void sched_worker_manager::get_metrics(mac_metrics_t& metrics) -{ - std::unique_lock lock(slot_mutex); - get_metrics_nolocking(metrics); -} - -bool sched_worker_manager::save_sched_result(slot_point pdcch_slot, - uint32_t cc, - dl_sched_res_t& dl_res, - ul_sched_t& ul_res) -{ - // NOTE: Unlocked region - auto& bwp_slot = cells[cc]->bwps[0].grid[pdcch_slot]; - - dl_res.dl_sched.pdcch_dl = bwp_slot.dl_pdcchs; - dl_res.dl_sched.pdcch_ul = bwp_slot.ul_pdcchs; - dl_res.dl_sched.pdsch = bwp_slot.pdschs; - dl_res.rar = bwp_slot.rar; - dl_res.dl_sched.ssb = bwp_slot.ssb; - dl_res.dl_sched.nzp_csi_rs = bwp_slot.nzp_csi_rs; - ul_res.pusch = bwp_slot.puschs; - ul_res.pucch = bwp_slot.pucch; - - // clear up BWP slot - bwp_slot.reset(); - - return true; -} - -void sched_worker_manager::get_metrics_nolocking(mac_metrics_t& metrics) -{ - for (mac_ue_metrics_t& ue_metric : metrics.ues) { - if (ue_db.contains(ue_metric.rnti) and ue_db[ue_metric.rnti]->carriers[0] != nullptr) { - auto& ue_cc = *ue_db[ue_metric.rnti]->carriers[0]; - std::lock_guard lock(ue_cc.metrics_mutex); - ue_metric.tx_brate = ue_cc.metrics.tx_brate; - ue_metric.tx_errors = ue_cc.metrics.tx_errors; - ue_metric.tx_pkts = ue_cc.metrics.tx_pkts; - ue_cc.metrics = {}; - } - } -} - -} // namespace sched_nr_impl -} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc deleted file mode 100644 index 8a3a16f501..0000000000 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ /dev/null @@ -1,370 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include -#include -#include -#include - -#include "srsenb/hdr/stack/mac/nr/ue_nr.h" -#include "srsran/common/buffer_pool.h" -#include "srsran/common/string_helpers.h" -#include "srsran/interfaces/gnb_interfaces.h" - -namespace srsenb { - -ue_nr::ue_nr(uint16_t rnti_, - uint32_t enb_cc_idx, - sched_nr_interface* sched_, - rrc_interface_mac_nr* rrc_, - rlc_interface_mac* rlc_, - phy_interface_stack_nr* phy_, - srslog::basic_logger& logger_) : - rnti(rnti_), - sched(sched_), - rrc(rrc_), - rlc(rlc_), - phy(phy_), - logger(logger_), - ue_rlc_buffer(srsran::make_byte_buffer()) -{} - -ue_nr::~ue_nr() {} - -void ue_nr::reset() -{ - { - std::lock_guard lock(metrics_mutex); - ue_metrics = {}; - } - nof_failures = 0; -} - -void ue_nr::ue_cfg(const sched_interface::ue_cfg_t& ue_cfg) -{ - // nop -} - -void ue_nr::set_tti(uint32_t tti) -{ - last_tti = tti; -} - -int ue_nr::process_pdu(srsran::unique_byte_buffer_t pdu) -{ - logger.debug(pdu->msg, pdu->N_bytes, "Handling MAC PDU (%d B)", pdu->N_bytes); - - mac_pdu_ul.init_rx(true); - if (mac_pdu_ul.unpack(pdu->msg, pdu->N_bytes) != SRSRAN_SUCCESS) { - return SRSRAN_ERROR; - } - - if (logger.info.enabled()) { - fmt::memory_buffer str_buffer; - mac_pdu_ul.to_string(str_buffer); - logger.info("Rx PDU: rnti=0x%x, %s", rnti, srsran::to_c_str(str_buffer)); - } - - // First, process MAC CEs in reverse order (CE like C-RNTI get handled first) - for (uint32_t n = mac_pdu_ul.get_num_subpdus(), i = mac_pdu_ul.get_num_subpdus() - 1; n > 0; --n, i = n - 1) { - srsran::mac_sch_subpdu_nr subpdu = mac_pdu_ul.get_subpdu(i); - if (not subpdu.is_sdu()) { - if (process_ce_subpdu(subpdu) != SRSRAN_SUCCESS) { - return SRSRAN_ERROR; - } - } - } - - // Second, handle all SDUs in order to avoid unnecessary reordering at higher layers - for (uint32_t i = 0; i < mac_pdu_ul.get_num_subpdus(); ++i) { - srsran::mac_sch_subpdu_nr subpdu = mac_pdu_ul.get_subpdu(i); - if (subpdu.is_sdu()) { - rrc->set_activity_user(rnti); - rlc->write_pdu(rnti, subpdu.get_lcid(), subpdu.get_sdu(), subpdu.get_sdu_length()); - } - } - - return SRSRAN_SUCCESS; -} - -int ue_nr::process_ce_subpdu(srsran::mac_sch_subpdu_nr& subpdu) -{ - // Handle MAC CEs - switch (subpdu.get_lcid()) { - case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CRNTI: { - uint16_t c_rnti = subpdu.get_c_rnti(); - if (true /*sched->ue_exists(c_crnti)*/) { - rrc->update_user(rnti, c_rnti); - rnti = c_rnti; - sched->ul_sr_info(rnti); // provide UL grant regardless of other BSR content for UE to complete RA - } else { - logger.warning("Updating user C-RNTI: rnti=0x%x already released.", c_rnti); - // Disable scheduling for all bearers. The new rnti will be removed on msg3 timer expiry in the RRC - for (uint32_t lcid = 0; lcid < sched_interface::MAX_LC; ++lcid) { - // sched->bearer_ue_rem(rnti, lcid); - } - } - } break; - case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::SHORT_BSR: - case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::SHORT_TRUNC_BSR: { - srsran::mac_sch_subpdu_nr::lcg_bsr_t sbsr = subpdu.get_sbsr(); - uint32_t buffer_size_bytes = buff_size_field_to_bytes(sbsr.buffer_size, srsran::SHORT_BSR); - // Assume all LCGs are 0 if reported SBSR is 0 - if (buffer_size_bytes == 0) { - for (uint32_t j = 0; j <= SCHED_NR_MAX_LC_GROUP; j++) { - sched->ul_bsr(rnti, j, 0); - } - } else { - sched->ul_bsr(rnti, sbsr.lcg_id, buffer_size_bytes); - } - } break; - case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_BSR: - case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_TRUNC_BSR: { - srsran::mac_sch_subpdu_nr::lbsr_t lbsr = subpdu.get_lbsr(); - for (auto& lb : lbsr.list) { - sched->ul_bsr(rnti, lb.lcg_id, buff_size_field_to_bytes(lb.buffer_size, srsran::LONG_BSR)); - } - } break; - case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::PADDING: - break; - default: - logger.warning("Unhandled subPDU with LCID=%d", subpdu.get_lcid()); - } - - return SRSRAN_SUCCESS; -} - -uint32_t ue_nr::read_pdu(uint32_t lcid, uint8_t* payload, uint32_t requested_bytes) -{ - return rlc->read_pdu(rnti, lcid, payload, requested_bytes); -} - -int ue_nr::generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size) -{ - std::lock_guard lock(mutex); - - if (mac_pdu_dl.init_tx(pdu, grant_size) != SRSRAN_SUCCESS) { - logger.error("Couldn't initialize MAC PDU buffer"); - return SRSRAN_ERROR; - } - - bool drb_activity = false; // inform RRC about user activity if true - int lcid = 4; // only supporting single DRB right now - - int32_t remaining_len = mac_pdu_dl.get_remaing_len(); - - logger.debug("Adding MAC PDU for RNTI=%d (max %d B)", rnti, remaining_len); - while (remaining_len >= MIN_RLC_PDU_LEN) { - // clear read buffer - ue_rlc_buffer->clear(); - - // Determine space for RLC - remaining_len -= remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2; - - // read RLC PDU - int pdu_len = rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, remaining_len); - - if (pdu_len > remaining_len) { - logger.error("Can't add SDU of %d B. Available space %d B", pdu_len, remaining_len); - break; - } else { - // Add SDU if RLC has something to tx - if (pdu_len > 0) { - ue_rlc_buffer->N_bytes = pdu_len; - logger.debug(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC", ue_rlc_buffer->N_bytes); - - // add to MAC PDU and pack - if (mac_pdu_dl.add_sdu(lcid, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes) != SRSRAN_SUCCESS) { - logger.error("Error packing MAC PDU"); - break; - } - - // set DRB activity flag but only notify RRC once - if (lcid > 3) { - drb_activity = true; - } - } else { - break; - } - - remaining_len -= pdu_len; - logger.debug("%d B remaining PDU", remaining_len); - } - } - - mac_pdu_dl.pack(); - - if (drb_activity) { - // Indicate DRB activity in DL to RRC - rrc->set_activity_user(rnti); - logger.debug("DL activity rnti=0x%x", rnti); - } - - if (logger.info.enabled()) { - fmt::memory_buffer str_buffer; - mac_pdu_dl.to_string(str_buffer); - logger.info("0x%x %s", rnti, srsran::to_c_str(str_buffer)); - } - return SRSRAN_SUCCESS; -} - -/******* METRICS interface ***************/ -void ue_nr::metrics_read(mac_ue_metrics_t* metrics_) -{ - uint32_t ul_buffer = 0; // sched->get_ul_buffer(rnti); - uint32_t dl_buffer = 0; // sched->get_dl_buffer(rnti); - - std::lock_guard lock(metrics_mutex); - ue_metrics.rnti = rnti; - ue_metrics.ul_buffer = ul_buffer; - ue_metrics.dl_buffer = dl_buffer; - - // set PCell sector id - std::array cc_list; //= sched->get_enb_ue_cc_map(rnti); - auto it = std::find(cc_list.begin(), cc_list.end(), 0); - ue_metrics.cc_idx = std::distance(cc_list.begin(), it); - - *metrics_ = ue_metrics; - phr_counter = 0; - dl_cqi_valid_counter = 0; - pucch_sinr_counter = 0; - pusch_sinr_counter = 0; - ue_metrics = {}; -} - -void ue_nr::metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi) -{ - std::lock_guard lock(metrics_mutex); - - // Process CQI - for (uint32_t i = 0; i < cfg_.nof_csi; i++) { - // Skip if invalid or not supported CSI report - if (cfg_.csi[i].cfg.quantity != SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI or - cfg_.csi[i].cfg.freq_cfg != SRSRAN_CSI_REPORT_FREQ_WIDEBAND) { - continue; - } - - // Add statistics - ue_metrics.dl_cqi = SRSRAN_VEC_SAFE_CMA(dl_cqi, ue_metrics.dl_cqi, dl_cqi_valid_counter); - dl_cqi_valid_counter++; - } -} - -void ue_nr::metrics_rx(bool crc, uint32_t tbs) -{ - std::lock_guard lock(metrics_mutex); - if (crc) { - ue_metrics.rx_brate += tbs * 8; - } else { - ue_metrics.rx_errors++; - } - ue_metrics.rx_pkts++; -} - -void ue_nr::metrics_tx(bool crc, uint32_t tbs) -{ - std::lock_guard lock(metrics_mutex); - if (crc) { - ue_metrics.tx_brate += tbs * 8; - } else { - ue_metrics.tx_errors++; - } - ue_metrics.tx_pkts++; -} - -void ue_nr::metrics_dl_mcs(uint32_t mcs) -{ - std::lock_guard lock(metrics_mutex); - ue_metrics.dl_mcs = SRSRAN_VEC_CMA((float)mcs, ue_metrics.dl_mcs, ue_metrics.dl_mcs_samples); - ue_metrics.dl_mcs_samples++; -} - -void ue_nr::metrics_ul_mcs(uint32_t mcs) -{ - std::lock_guard lock(metrics_mutex); - ue_metrics.ul_mcs = SRSRAN_VEC_CMA((float)mcs, ue_metrics.ul_mcs, ue_metrics.ul_mcs_samples); - ue_metrics.ul_mcs_samples++; -} - -void ue_nr::metrics_cnt() -{ - std::lock_guard lock(metrics_mutex); - ue_metrics.nof_tti++; -} - -void ue_nr::metrics_pucch_sinr(float sinr) -{ - std::lock_guard lock(metrics_mutex); - // discard nan or inf values for average SINR - if (!std::isinf(sinr) && !std::isnan(sinr)) { - ue_metrics.pucch_sinr = SRSRAN_VEC_SAFE_CMA((float)sinr, ue_metrics.pucch_sinr, pucch_sinr_counter); - pucch_sinr_counter++; - } -} - -void ue_nr::metrics_pusch_sinr(float sinr) -{ - std::lock_guard lock(metrics_mutex); - // discard nan or inf values for average SINR - if (!std::isinf(sinr) && !std::isnan(sinr)) { - ue_metrics.pusch_sinr = SRSRAN_VEC_SAFE_CMA((float)sinr, ue_metrics.pusch_sinr, pusch_sinr_counter); - pusch_sinr_counter++; - } -} - -/** Converts the buffer size field of a BSR (5 or 8-bit Buffer Size field) into Bytes - * @param buff_size_field The buffer size field contained in the MAC PDU - * @param format The BSR format that determines the buffer size field length - * @return uint32_t The actual buffer size level in Bytes - */ -uint32_t ue_nr::buff_size_field_to_bytes(uint32_t buff_size_index, const srsran::bsr_format_nr_t& format) -{ - using namespace srsran; - - // early exit - if (buff_size_index == 0) { - return 0; - } - - const uint32_t max_offset = 1; // make the reported value bigger than the 2nd biggest - - switch (format) { - case SHORT_BSR: - case SHORT_TRUNC_BSR: - if (buff_size_index >= buffer_size_levels_5bit_max_idx) { - return buffer_size_levels_5bit[buffer_size_levels_5bit_max_idx] + max_offset; - } else { - return buffer_size_levels_5bit[buff_size_index]; - } - break; - case LONG_BSR: - case LONG_TRUNC_BSR: - if (buff_size_index > buffer_size_levels_8bit_max_idx) { - return buffer_size_levels_8bit[buffer_size_levels_8bit_max_idx] + max_offset; - } else { - return buffer_size_levels_8bit[buff_size_index]; - } - break; - } - return 0; -} - -} // namespace srsenb diff --git a/srsenb/src/stack/mac/sched.cc b/srsenb/src/stack/mac/sched.cc index b2823b7aec..4dc5758f07 100644 --- a/srsenb/src/stack/mac/sched.cc +++ b/srsenb/src/stack/mac/sched.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -301,6 +301,12 @@ std::array sched::get_enb_ue_activ_cc_map(uint16_t rnt return ret; } +int sched::set_pdcch_order(uint32_t enb_cc_idx, dl_sched_po_info_t pdcch_order_info) +{ + std::lock_guard lock(sched_mutex); + return carrier_schedulers[enb_cc_idx]->pdcch_order_info(pdcch_order_info); +} + /******************************************************* * * Main sched functions @@ -370,6 +376,12 @@ bool sched::is_generated(srsran::tti_point tti_rx, uint32_t enb_cc_idx) const return sched_results.has_sf(tti_rx) and sched_results.get_sf(tti_rx)->is_generated(enb_cc_idx); } +int sched::metrics_read(uint16_t rnti, mac_ue_metrics_t& metrics) +{ + return ue_db_access_locked( + rnti, [&metrics](sched_ue& ue) { ue.metrics_read(metrics); }, "metrics_read"); +} + // Common way to access ue_db elements in a read locking way template int sched::ue_db_access_locked(uint16_t rnti, Func&& f, const char* func_name, bool log_fail) diff --git a/srsenb/src/stack/mac/sched_carrier.cc b/srsenb/src/stack/mac/sched_carrier.cc index 246edc6cb7..c5e6cfa38e 100644 --- a/srsenb/src/stack/mac/sched_carrier.cc +++ b/srsenb/src/stack/mac/sched_carrier.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -25,7 +25,7 @@ #include "srsenb/hdr/stack/mac/schedulers/sched_time_rr.h" #include "srsran/common/standard_streams.h" #include "srsran/common/string_helpers.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" +#include "srsran/interfaces/enb_rrc_interface_mac.h" namespace srsenb { @@ -37,7 +37,8 @@ using srsran::tti_point; bc_sched::bc_sched(const sched_cell_params_t& cfg_, srsenb::rrc_interface_mac* rrc_) : cc_cfg(&cfg_), rrc(rrc_), logger(srslog::fetch_basic_logger("MAC")) -{} +{ +} void bc_sched::dl_sched(sf_sched* tti_sched) { @@ -178,8 +179,9 @@ void bc_sched::reset() *******************************************************/ ra_sched::ra_sched(const sched_cell_params_t& cfg_, sched_ue_list& ue_db_) : - cc_cfg(&cfg_), logger(srslog::fetch_basic_logger("MAC")), ue_db(&ue_db_) -{} + cc_cfg(&cfg_), logger(srslog::fetch_basic_logger("MAC")), ue_db(&ue_db_), pending_rars(16) +{ +} alloc_result ra_sched::allocate_pending_rar(sf_sched* tti_sched, const pending_rar_t& rar, uint32_t& nof_grants_alloc) { @@ -214,8 +216,10 @@ void ra_sched::dl_sched(sf_sched* tti_sched) tti_point tti_tx_dl = tti_sched->get_tti_tx_dl(); rar_aggr_level = 2; - for (auto it = pending_rars.begin(); it != pending_rars.end();) { - auto& rar = *it; + for (auto& rar : pending_rars) { + if (rar.msg3_grant.empty()) { + continue; + } // In case of RAR outside RAR window: // - if window has passed, discard RAR @@ -232,7 +236,7 @@ void ra_sched::dl_sched(sf_sched* tti_sched) tti_tx_dl); srsran::console("%s\n", srsran::to_c_str(str_buffer)); logger.warning("%s", srsran::to_c_str(str_buffer)); - it = pending_rars.erase(it); + rar.msg3_grant.clear(); // mark as handled. continue; } return; @@ -248,7 +252,7 @@ void ra_sched::dl_sched(sf_sched* tti_sched) // - otherwise, erase only Msg3 grants that were allocated, and stop iteration if (nof_rar_allocs == rar.msg3_grant.size()) { - it = pending_rars.erase(it); + rar.msg3_grant.clear(); // mark as handled. } else { std::copy(rar.msg3_grant.begin() + nof_rar_allocs, rar.msg3_grant.end(), rar.msg3_grant.begin()); rar.msg3_grant.resize(rar.msg3_grant.size() - nof_rar_allocs); @@ -261,9 +265,13 @@ void ra_sched::dl_sched(sf_sched* tti_sched) if (ret != alloc_result::no_cch_space) { break; } - ++it; } } + + // Pop elements at the front that have been handled. + while (not pending_rars.empty() and pending_rars.begin()->msg3_grant.empty()) { + pending_rars.pop(); + } } int ra_sched::dl_rach_info(dl_sched_rar_info_t rar_info) @@ -296,7 +304,11 @@ int ra_sched::dl_rach_info(dl_sched_rar_info_t rar_info) p.ra_rnti = ra_rnti; p.prach_tti = tti_point{rar_info.prach_tti}; p.msg3_grant.push_back(rar_info); - pending_rars.push_back(p); + if (not pending_rars.try_push(p)) { + logger.warning("SCHED: Unable to handle RAR ra-rnti=0x%x, as the maximum number of pending RARs has been reached", + ra_rnti); + return SRSRAN_ERROR; + } return SRSRAN_SUCCESS; } @@ -349,6 +361,7 @@ void sched::carrier_sched::reset() { ra_sched_ptr.reset(); bc_sched_ptr.reset(); + pending_pdcch_orders.clear(); } void sched::carrier_sched::carrier_cfg(const sched_cell_params_t& cell_params_) @@ -411,6 +424,9 @@ const cc_sched_result& sched::carrier_sched::generate_tti_result(tti_point tti_r /* Schedule Msg3 */ sf_sched* sf_msg3_sched = get_sf_sched(tti_rx + MSG3_DELAY_MS); ra_sched_ptr->ul_sched(tti_sched, sf_msg3_sched); + + /* Schedule PDCCH orders */ + pdcch_order_sched(tti_sched); } /* Prioritize PDCCH scheduling for DL and UL data in a RoundRobin fashion */ @@ -490,4 +506,38 @@ int sched::carrier_sched::dl_rach_info(dl_sched_rar_info_t rar_info) return ra_sched_ptr->dl_rach_info(rar_info); } +int sched::carrier_sched::pdcch_order_info(dl_sched_po_info_t pdcch_order_info) +{ + logger.info("SCHED: New PDCCH order preamble=%d, prach_mask_idx=%d crnti=0x%x", + pdcch_order_info.preamble_idx, + pdcch_order_info.prach_mask_idx, + pdcch_order_info.crnti); + + // create new PDCCH order + pending_pdcch_orders.push_back(pdcch_order_info); + + return SRSRAN_SUCCESS; +} + +void sched::carrier_sched::pdcch_order_sched(sf_sched* tti_sched) +{ + for (auto it = pending_pdcch_orders.begin(); it != pending_pdcch_orders.end();) { + auto& pending_pdcch_order = *it; + + alloc_result ret = alloc_result::no_sch_space; + + rbg_interval rbg_interv = find_empty_rbg_interval(1, tti_sched->get_dl_mask()); + if (rbg_interv.length() == 1) { + ret = tti_sched->alloc_pdcch_order(pending_pdcch_order, po_aggr_level, rbg_interv); + } + + if (ret == alloc_result::success) { + it = pending_pdcch_orders.erase(it); + } else { + logger.warning("SCHED: Could not allocate PDCCH order, cause=%s", to_string(ret)); + ++it; + } + } +} + } // namespace srsenb diff --git a/srsenb/src/stack/mac/sched_grid.cc b/srsenb/src/stack/mac/sched_grid.cc index d59cf43078..1e22227b8f 100644 --- a/srsenb/src/stack/mac/sched_grid.cc +++ b/srsenb/src/stack/mac/sched_grid.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -87,8 +87,8 @@ void sf_grid_t::init(const sched_cell_params_t& cell_params_) // Compute reserved PRBs for CQI, SR and HARQ-ACK, and store it in a bitmask pucch_mask.resize(cc_cfg->nof_prb()); - pucch_nrb = (cc_cfg->cfg.nrb_pucch > 0) ? (uint32_t)cc_cfg->cfg.nrb_pucch : 0; - srsran_pucch_cfg_t pucch_cfg = cell_params_.pucch_cfg_common; + pucch_nrb = (cc_cfg->cfg.nrb_pucch > 0) ? (uint32_t)cc_cfg->cfg.nrb_pucch : 0; + srsran_pucch_cfg_t pucch_cfg = cell_params_.pucch_cfg_common; uint32_t harq_pucch = 0; if (cc_cfg->sched_cfg->pucch_harq_max_rb > 0) { harq_pucch = cc_cfg->sched_cfg->pucch_harq_max_rb; @@ -168,7 +168,7 @@ alloc_result sf_grid_t::alloc_dl(uint32_t aggr_idx, alloc_result sf_grid_t::alloc_dl_ctrl(uint32_t aggr_idx, rbg_interval rbg_range, alloc_type_t alloc_type) { if (alloc_type != alloc_type_t::DL_RAR and alloc_type != alloc_type_t::DL_BC and - alloc_type != alloc_type_t::DL_PCCH) { + alloc_type != alloc_type_t::DL_PCCH and alloc_type != alloc_type_t::DL_PDCCH_ORDER) { logger.error("SCHED: DL control allocations must be RAR/BC/PDCCH"); return alloc_result::other_cause; } @@ -325,6 +325,7 @@ void sf_sched::new_tti(tti_point tti_rx_, sf_sched_result* cc_results_) // reset internal state bc_allocs.clear(); rar_allocs.clear(); + po_allocs.clear(); data_allocs.clear(); ul_data_allocs.clear(); @@ -447,11 +448,45 @@ alloc_result sf_sched::alloc_rar(uint32_t aggr_lvl, const pending_rar_t& rar, rb rar_alloc.alloc_data.rbg_range = rbgs; rar_alloc.alloc_data.req_bytes = buf_rar; rar_allocs.push_back(rar_alloc); - last_msg3_prb += total_ul_nof_prbs * nof_grants; + last_msg3_prb += total_ul_nof_prbs; return ret; } +alloc_result +sf_sched::alloc_pdcch_order(const sched_interface::dl_sched_po_info_t& po_cfg, uint32_t aggr_lvl, rbg_interval rbgs) +{ + if (po_allocs.full()) { + logger.warning("SCHED: Maximum number of PDCCH order allocations per TTI reached."); + return alloc_result::no_grant_space; + } + + uint32_t buf_pdcch_order = 7; // TODO get actual size + + // Allocate RBGs and PDCCH + alloc_result ret = tti_alloc.alloc_dl_ctrl(aggr_lvl, rbgs, alloc_type_t::DL_PDCCH_ORDER); + if (ret != alloc_result::success) { + return ret; + } + + po_alloc_t po_alloc; + po_alloc.po_grant.crnti = po_cfg.crnti; + po_alloc.po_grant.preamble_idx = po_cfg.preamble_idx; + po_alloc.po_grant.prach_mask_idx = po_cfg.prach_mask_idx; + po_alloc.po_grant.tbs = buf_pdcch_order; + + // Generate DCI for PDCCH order message + generate_pdcch_order_dci(po_alloc.po_grant, get_tti_tx_dl(), *cc_cfg, tti_alloc.get_cfi()); + + // Allocation Successful + po_alloc.dci_idx = tti_alloc.get_pdcch_grid().nof_allocs() - 1; + po_alloc.rbg_range = rbgs; + po_alloc.req_bytes = buf_pdcch_order; + po_allocs.push_back(po_alloc); + + return alloc_result::success; +} + bool is_periodic_cqi_expected(const sched_interface::ue_cfg_t& ue_cfg, tti_point tti_tx_ul) { for (const sched_interface::ue_cfg_t::cc_cfg_t& cc : ue_cfg.supported_cc_list) { @@ -831,13 +866,13 @@ void sf_sched::set_ul_sched_result(const sf_cch_allocator::alloc_result_t& dci_r sched_interface::ul_sched_data_t& pusch = ul_result->pusch.back(); uint32_t total_data_before = user->get_pending_ul_data_total(get_tti_tx_ul(), cc_cfg->enb_cc_idx); int tbs = user->generate_format0(&pusch, - get_tti_tx_ul(), - cc_cfg->enb_cc_idx, - ul_alloc.alloc, - ul_alloc.needs_pdcch(), - cce_range, - ul_alloc.msg3_mcs, - uci_type); + get_tti_tx_ul(), + cc_cfg->enb_cc_idx, + ul_alloc.alloc, + ul_alloc.needs_pdcch(), + cce_range, + ul_alloc.msg3_mcs, + uci_type); ul_harq_proc* h = user->get_ul_harq(get_tti_tx_ul(), cc_cfg->enb_cc_idx); uint32_t new_pending_bytes = user->get_pending_ul_new_data(get_tti_tx_ul(), cc_cfg->enb_cc_idx); @@ -863,23 +898,24 @@ void sf_sched::set_ul_sched_result(const sf_cch_allocator::alloc_result_t& dci_r uint32_t old_pending_bytes = user->get_pending_ul_old_data(); if (logger.info.enabled()) { fmt::memory_buffer str_buffer; - fmt::format_to( - str_buffer, - "SCHED: {} {} rnti=0x{:x}, cc={}, pid={}, dci=({},{}), prb={}, n_rtx={}, cfi={}, tbs={}, bsr={} ({}-{})", - ul_alloc.is_msg3 ? "Msg3" : "UL", - ul_alloc.is_retx() ? "retx" : "tx", - user->get_rnti(), - cc_cfg->enb_cc_idx, - h->get_id(), - pusch.dci.location.L, - pusch.dci.location.ncce, - ul_alloc.alloc, - h->nof_retx(0), - tti_alloc.get_cfi(), - tbs, - new_pending_bytes, - total_data_before, - old_pending_bytes); + fmt::format_to(str_buffer, + "SCHED: {} {} rnti=0x{:x}, cc={}, pid={}, dci=({},{}), prb={}, n_rtx={}, cfi={}, tbs={}, bsr={} " + "({}-{}), tti_tx_ul={}", + ul_alloc.is_msg3 ? "Msg3" : "UL", + ul_alloc.is_retx() ? "retx" : "tx", + user->get_rnti(), + cc_cfg->enb_cc_idx, + h->get_id(), + pusch.dci.location.L, + pusch.dci.location.ncce, + ul_alloc.alloc, + h->nof_retx(0), + tti_alloc.get_cfi(), + tbs, + new_pending_bytes, + total_data_before, + old_pending_bytes, + get_tti_tx_ul().to_uint()); logger.info("%s", srsran::to_c_str(str_buffer)); } @@ -950,6 +986,12 @@ void sf_sched::generate_sched_results(sched_ue_list& ue_db) log_rar_allocation(cc_result->dl_sched_result.rar.back(), rar_alloc.alloc_data.rbg_range); } + for (const auto& po_alloc : po_allocs) { + cc_result->dl_sched_result.po.emplace_back(po_alloc.po_grant); + cc_result->dl_sched_result.po.back().dci.location = dci_result[po_alloc.dci_idx]->dci_pos; + log_po_allocation(cc_result->dl_sched_result.po.back(), po_alloc.rbg_range, *cc_cfg); + } + set_dl_data_sched_result(dci_result, &cc_result->dl_sched_result, ue_db); set_ul_sched_result(dci_result, &cc_result->ul_sched_result, ue_db); diff --git a/srsenb/src/stack/mac/sched_helpers.cc b/srsenb/src/stack/mac/sched_helpers.cc index 2947e4b699..2001fb68aa 100644 --- a/srsenb/src/stack/mac/sched_helpers.cc +++ b/srsenb/src/stack/mac/sched_helpers.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/src/stack/mac/sched_phy_ch/sched_dci.cc b/srsenb/src/stack/mac/sched_phy_ch/sched_dci.cc index 499245a7a1..1161558a8e 100644 --- a/srsenb/src/stack/mac/sched_phy_ch/sched_dci.cc +++ b/srsenb/src/stack/mac/sched_phy_ch/sched_dci.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -331,6 +331,22 @@ bool generate_rar_dci(sched_interface::dl_sched_rar_t& rar, return true; } +void generate_pdcch_order_dci(sched_interface::dl_sched_po_t& pdcch_order, + tti_point tti_tx_dl, + const sched_cell_params_t& cell_params, + uint32_t current_cfi) +{ + // Generate DCI Format1A PDCCH order content + pdcch_order.dci.format = SRSRAN_DCI_FORMAT1A; + pdcch_order.dci.alloc_type = SRSRAN_RA_ALLOC_TYPE2; // TODO: is this correct? + pdcch_order.dci.rnti = pdcch_order.crnti; + pdcch_order.dci.is_pdcch_order = true; + pdcch_order.dci.preamble_idx = pdcch_order.preamble_idx; + pdcch_order.dci.prach_mask_idx = pdcch_order.prach_mask_idx; + + get_mac_logger().debug("PDCCH order: rnti=0x%x", pdcch_order.dci.rnti); +} + void log_broadcast_allocation(const sched_interface::dl_sched_bc_t& bc, rbg_interval rbg_range, const sched_cell_params_t& cell_params) @@ -393,4 +409,24 @@ void log_rar_allocation(const sched_interface::dl_sched_rar_t& rar, rbg_interval srsran::to_c_str(str_buffer2)); } +void log_po_allocation(const sched_interface::dl_sched_po_t& pdcch_order, + rbg_interval rbg_range, + const sched_cell_params_t& cell_params) +{ + if (not get_mac_logger().info.enabled()) { + return; + } + + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, "{}", rbg_range); + + get_mac_logger().info("SCHED: PDCCH order, cc=%d, rbgs=%s, dci=(%d,%d), tbs=%d, mcs=%d", + cell_params.enb_cc_idx, + srsran::to_c_str(str_buffer), + pdcch_order.dci.location.L, + pdcch_order.dci.location.ncce, + pdcch_order.tbs, + pdcch_order.dci.tb[0].mcs_idx); +} + } // namespace srsenb diff --git a/srsenb/src/stack/mac/sched_phy_ch/sched_phy_resource.cc b/srsenb/src/stack/mac/sched_phy_ch/sched_phy_resource.cc index a6e95519f5..2d9e8b4b46 100644 --- a/srsenb/src/stack/mac/sched_phy_ch/sched_phy_resource.cc +++ b/srsenb/src/stack/mac/sched_phy_ch/sched_phy_resource.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc b/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc index 6b024c74f4..501c3a3f06 100644 --- a/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc +++ b/srsenb/src/stack/mac/sched_phy_ch/sf_cch_allocator.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -61,6 +61,8 @@ sf_cch_allocator::get_cce_loc_table(alloc_type_t alloc_type, sched_ue* user, uin return &cc_cfg->common_locations[cfix]; case alloc_type_t::DL_RAR: return &cc_cfg->rar_locations[to_tx_dl(tti_rx).sf_idx()][cfix]; + case alloc_type_t::DL_PDCCH_ORDER: + return &cc_cfg->common_locations[cfix]; case alloc_type_t::DL_DATA: case alloc_type_t::UL_DATA: return user->get_locations(cc_cfg->enb_cc_idx, cfix + 1, to_tx_dl(tti_rx).sf_idx()); diff --git a/srsenb/src/stack/mac/sched_ue.cc b/srsenb/src/stack/mac/sched_ue.cc index 673d3c1a94..12c787104f 100644 --- a/srsenb/src/stack/mac/sched_ue.cc +++ b/srsenb/src/stack/mac/sched_ue.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -173,6 +173,13 @@ void sched_ue::unset_sr() sr = false; } +void sched_ue::metrics_read(mac_ue_metrics_t& metrics) +{ + sched_ue_cell& pcell = cells[cfg.supported_cc_list[0].enb_cc_idx]; + metrics.ul_snr_offset = pcell.get_ul_snr_offset(); + metrics.dl_cqi_offset = pcell.get_dl_cqi_offset(); +} + tti_point prev_meas_gap_start(tti_point tti, uint32_t period, uint32_t offset) { return tti_point{static_cast(floor(static_cast((tti - offset).to_uint()) / period)) * period + @@ -741,8 +748,9 @@ rbg_interval sched_ue::get_required_dl_rbgs(uint32_t enb_cc_idx) int pending_prbs = get_required_prb_dl(cells[enb_cc_idx], to_tx_dl(current_tti), get_dci_format(), req_bytes.start()); if (pending_prbs < 0) { // Cannot fit allocation in given PRBs - logger.error("SCHED: DL CQI does now allow fitting %d non-segmentable DL tx bytes into the cell bandwidth. " + logger.error("SCHED: DL CQI=%d does now allow fitting %d non-segmentable DL tx bytes into the cell bandwidth. " "Consider increasing initial CQI value.", + cells[enb_cc_idx].get_dl_cqi(), req_bytes.start()); return {cellparams->nof_prb(), cellparams->nof_prb()}; } diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_dl_cqi.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_dl_cqi.cc index 23679b3903..e5ddb5d52b 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_dl_cqi.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_dl_cqi.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc index c0f005615d..6c3c2dfa7a 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_harq.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc index 4d3f54bb88..fec8d30585 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -82,6 +82,25 @@ void lch_ue_manager::new_tti() } } +void lch_ue_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue) +{ + if (base_type::dl_buffer_state(lcid, tx_queue, prio_tx_queue) == SRSRAN_SUCCESS) { + logger.debug("SCHED: rnti=0x%x DL lcid=%d buffer_state=%d,%d", rnti, lcid, tx_queue, prio_tx_queue); + } +} + +void lch_ue_manager::ul_bsr(uint32_t lcg_id, uint32_t val) +{ + if (base_type::ul_bsr(lcg_id, val) == SRSRAN_SUCCESS) { + if (logger.debug.enabled()) { + fmt::memory_buffer str_buffer; + fmt::format_to(str_buffer, "{}", lcg_bsr); + logger.debug( + "SCHED: rnti=0x%x, lcg_id=%d, bsr=%d. Current state=%s", rnti, lcg_id, val, srsran::to_c_str(str_buffer)); + } + } +} + void lch_ue_manager::ul_buffer_add(uint8_t lcid, uint32_t bytes) { if (lcid >= sched_interface::MAX_LC) { @@ -244,18 +263,34 @@ uint32_t allocate_mac_sdus(sched_interface::dl_sched_data_t* data, uint32_t total_tbs, uint32_t tbidx) { - uint32_t rem_tbs = total_tbs; + uint32_t rem_tbs = total_tbs; + auto& pdu = data->pdu[tbidx]; + uint32_t& nof_pdu_elems = data->nof_pdu_elems[tbidx]; // if we do not have enough bytes to fit MAC subheader, skip MAC SDU allocation // NOTE: we do not account RLC header because some LCIDs (e.g. CCCH) do not need them + uint32_t first_pdu_idx = nof_pdu_elems; while (rem_tbs > MAC_MAX_HEADER_SIZE and data->nof_pdu_elems[tbidx] < sched_interface::MAX_RLC_PDU_LIST) { uint32_t max_sdu_bytes = rem_tbs - get_mac_subheader_size(rem_tbs - MAC_MIN_HEADER_SIZE); - uint32_t alloc_sdu_bytes = lch_handler.alloc_rlc_pdu(&data->pdu[tbidx][data->nof_pdu_elems[tbidx]], max_sdu_bytes); + uint32_t alloc_sdu_bytes = lch_handler.alloc_rlc_pdu(&pdu[nof_pdu_elems], max_sdu_bytes); if (alloc_sdu_bytes == 0) { break; } rem_tbs -= get_mac_sdu_and_subheader_size(alloc_sdu_bytes); // account for MAC sub-header - data->nof_pdu_elems[tbidx]++; + + // In case the same LCID got reallocated (e.g. retx and newtx), merge with previous SDU. + // Otherwise, increment number of scheduled SDUs + uint32_t prev_same_lcid_idx = first_pdu_idx; + for (; prev_same_lcid_idx < nof_pdu_elems; ++prev_same_lcid_idx) { + if (pdu[prev_same_lcid_idx].lcid == pdu[nof_pdu_elems].lcid) { + pdu[prev_same_lcid_idx].nbytes += pdu[nof_pdu_elems].nbytes; + pdu[nof_pdu_elems].nbytes = 0; + break; + } + } + if (prev_same_lcid_idx == nof_pdu_elems) { + nof_pdu_elems++; + } } return total_tbs - rem_tbs; diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc index 6f843426c9..0221d1f34e 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/src/stack/mac/schedulers/CMakeLists.txt b/srsenb/src/stack/mac/schedulers/CMakeLists.txt index a3b488c133..66d2a4e44a 100644 --- a/srsenb/src/stack/mac/schedulers/CMakeLists.txt +++ b/srsenb/src/stack/mac/schedulers/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsenb/src/stack/mac/schedulers/sched_base.cc b/srsenb/src/stack/mac/schedulers/sched_base.cc index 0d0bdf9639..2a9d37fcad 100644 --- a/srsenb/src/stack/mac/schedulers/sched_base.cc +++ b/srsenb/src/stack/mac/schedulers/sched_base.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/src/stack/mac/schedulers/sched_time_pf.cc b/srsenb/src/stack/mac/schedulers/sched_time_pf.cc index 62e144c741..841bda6ab6 100644 --- a/srsenb/src/stack/mac/schedulers/sched_time_pf.cc +++ b/srsenb/src/stack/mac/schedulers/sched_time_pf.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -70,7 +70,13 @@ void sched_time_pf::new_tti(sched_ue_list& ue_db, sf_sched* tti_sched) dl_queue.push(&it->second); } if (it->second.ul_h != nullptr) { - ul_queue.push(&it->second); + // Allocate only if UL carrier is enabled + for (auto& i : u.second->get_ue_cfg().supported_cc_list) { + if (i.enb_cc_idx == cc_cfg->enb_cc_idx and not i.ul_disabled) { + ul_queue.push(&it->second); + break; + } + } } } } diff --git a/srsenb/src/stack/mac/schedulers/sched_time_rr.cc b/srsenb/src/stack/mac/schedulers/sched_time_rr.cc index 73e50a4132..fbce8ad995 100644 --- a/srsenb/src/stack/mac/schedulers/sched_time_rr.cc +++ b/srsenb/src/stack/mac/schedulers/sched_time_rr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -130,6 +130,18 @@ void sched_time_rr::sched_ul_newtxs(sched_ue_list& ue_db, sf_sched* tti_sched, s iter = ue_db.begin(); // wrap around } sched_ue& user = *iter->second; + // Allocate only if UL carrier is enabled + bool ul_disabled = false; + for (auto& i : user.get_ue_cfg().supported_cc_list) { + if (i.enb_cc_idx == cc_cfg->enb_cc_idx) { + ul_disabled = i.ul_disabled; + break; + } + } + if (ul_disabled) { + continue; + } + const ul_harq_proc* h = get_ul_newtx_harq(user, tti_sched); // Check if there is a empty harq if (h == nullptr) { diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index 7a67ef1b3b..ce065b3abd 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -28,7 +28,7 @@ #include "srsran/common/string_helpers.h" #include "srsran/interfaces/enb_phy_interfaces.h" #include "srsran/interfaces/enb_rlc_interfaces.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" +#include "srsran/interfaces/enb_rrc_interface_mac.h" namespace srsenb { diff --git a/srsenb/src/stack/rrc/CMakeLists.txt b/srsenb/src/stack/rrc/CMakeLists.txt index ca7c8b8724..c57cd98694 100644 --- a/srsenb/src/stack/rrc/CMakeLists.txt +++ b/srsenb/src/stack/rrc/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -20,6 +20,4 @@ set(SOURCES rrc.cc rrc_ue.cc rrc_mobility.cc rrc_cell_cfg.cc rrc_bearer_cfg.cc mac_controller.cc ue_rr_cfg.cc ue_meas_cfg.cc rrc_endc.cc) add_library(srsenb_rrc STATIC ${SOURCES}) - -set(SOURCES rrc_nr.cc nr/cell_asn1_config.cc) -add_library(srsgnb_rrc STATIC ${SOURCES}) + \ No newline at end of file diff --git a/srsenb/src/stack/rrc/mac_controller.cc b/srsenb/src/stack/rrc/mac_controller.cc index 53b4b0ead9..ec84907d22 100644 --- a/srsenb/src/stack/rrc/mac_controller.cc +++ b/srsenb/src/stack/rrc/mac_controller.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -146,6 +146,9 @@ int mac_controller::handle_crnti_ce(uint32_t temp_crnti) current_sched_ue_cfg.ue_bearers[i] = next_sched_ue_cfg.ue_bearers[i]; } + // keep SRB2 disabled until RRCReconfComplete is received + set_srb2_activation(false); + return mac->ue_set_crnti(temp_crnti, rnti, current_sched_ue_cfg); } @@ -229,7 +232,10 @@ void mac_controller::handle_con_reconf_complete() { current_sched_ue_cfg = next_sched_ue_cfg; - // Setup all bearers + // Setup SRB2 + set_srb2_activation(true); + + // Setup all data bearers apply_current_bearers_cfg(); // Apply SCell+Bearer changes to MAC @@ -265,7 +271,9 @@ void mac_controller::handle_target_enb_ho_cmd(const asn1::rrc::rrc_conn_recfg_r8 ue_cfg_apply_capabilities(next_sched_ue_cfg, *rrc_cfg, uecaps); ue_cfg_apply_reconf_complete_updates(next_sched_ue_cfg, conn_recfg, ue_cell_list); - // Temporarily freeze new allocations for DRBs (SRBs are needed to send RRC Reconf Message) + // Temporarily freeze SRB2 and DRBs. SRB1 is needed to send + // RRC Reconfiguration and receive RRC Reconfiguration Complete + set_srb2_activation(false); set_drb_activation(false); // Apply changes to MAC scheduler @@ -277,10 +285,11 @@ void mac_controller::handle_intraenb_ho_cmd(const asn1::rrc::rrc_conn_recfg_r8_i const srsran::rrc_ue_capabilities_t& uecaps) { next_sched_ue_cfg = current_sched_ue_cfg; - next_sched_ue_cfg.supported_cc_list.resize(1); - next_sched_ue_cfg.supported_cc_list[0].active = true; next_sched_ue_cfg.supported_cc_list[0].enb_cc_idx = cell_common_list.get_pci(conn_recfg.mob_ctrl_info.target_pci)->enb_cc_idx; + for (uint32_t i = 0; i < next_sched_ue_cfg.supported_cc_list.size(); ++i) { + next_sched_ue_cfg.supported_cc_list[0].active = true; + } ue_cfg_apply_conn_reconf(next_sched_ue_cfg, conn_recfg, *rrc_cfg); ue_cfg_apply_capabilities(next_sched_ue_cfg, *rrc_cfg, uecaps); ue_cfg_apply_reconf_complete_updates(next_sched_ue_cfg, conn_recfg, ue_cell_list); @@ -328,6 +337,12 @@ void mac_controller::set_scell_activation(const std::bitset } } +void mac_controller::set_srb2_activation(bool active) +{ + current_sched_ue_cfg.ue_bearers[srb_to_lcid(lte_srb::srb2)].direction = + active ? mac_lc_ch_cfg_t::BOTH : mac_lc_ch_cfg_t::IDLE; +} + void mac_controller::set_drb_activation(bool active) { for (const drb_to_add_mod_s& drb : bearer_list.get_established_drbs()) { @@ -451,9 +466,10 @@ void ue_cfg_apply_reconf_complete_updates(ue_cfg_t& ue_cfg, if (scell.scell_idx_r10 >= ue_cfg.supported_cc_list.size()) { ue_cfg.supported_cc_list.resize(scell.scell_idx_r10 + 1); } - auto& mac_scell = ue_cfg.supported_cc_list[scell.scell_idx_r10]; - mac_scell.active = true; - mac_scell.enb_cc_idx = ue_cell_list.get_ue_cc_idx(scell.scell_idx_r10)->cell_common->enb_cc_idx; + auto& mac_scell = ue_cfg.supported_cc_list[scell.scell_idx_r10]; + mac_scell.active = true; + mac_scell.ul_disabled = !scell.rr_cfg_common_scell_r10.ul_cfg_r10.ul_freq_info_r10.ul_carrier_freq_r10_present; + mac_scell.enb_cc_idx = ue_cell_list.get_ue_cc_idx(scell.scell_idx_r10)->cell_common->enb_cc_idx; if (scell.rr_cfg_ded_scell_r10_present and scell.rr_cfg_ded_scell_r10.phys_cfg_ded_scell_r10_present and scell.rr_cfg_ded_scell_r10.phys_cfg_ded_scell_r10.ul_cfg_r10_present) { diff --git a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc b/srsenb/src/stack/rrc/nr/cell_asn1_config.cc deleted file mode 100644 index 336d742d60..0000000000 --- a/srsenb/src/stack/rrc/nr/cell_asn1_config.cc +++ /dev/null @@ -1,602 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsenb/hdr/stack/rrc/nr/cell_asn1_config.h" -#include - -using namespace asn1::rrc_nr; - -#define HANDLE_ERROR(ret) \ - if ((ret) != SRSRAN_SUCCESS) { \ - return SRSRAN_ERROR; \ - } - -namespace srsenb { - -srslog::basic_logger& get_logger(const rrc_nr_cfg_t& cfg) -{ - static srslog::basic_logger& log_obj = srslog::fetch_basic_logger(cfg.log_name); - return log_obj; -} - -/// Fill list of CSI-ReportConfig with gNB config -int fill_csi_report_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) -{ - csi_meas_cfg.csi_report_cfg_to_add_mod_list_present = true; - csi_meas_cfg.csi_report_cfg_to_add_mod_list.resize(1); - - auto& csi_report = csi_meas_cfg.csi_report_cfg_to_add_mod_list[0]; - csi_report.report_cfg_id = 0; - csi_report.res_for_ch_meas = 0; - csi_report.csi_im_res_for_interference_present = true; - csi_report.csi_im_res_for_interference = 1; - csi_report.report_cfg_type.set_periodic(); - csi_report.report_cfg_type.periodic().report_slot_cfg.set_slots80(); - csi_report.report_cfg_type.periodic().pucch_csi_res_list.resize(1); - csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].ul_bw_part_id = 0; - csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].pucch_res = 1; // was 17 in orig PCAP - csi_report.report_quant.set_cri_ri_pmi_cqi(); - // Report freq config (optional) - csi_report.report_freq_cfg_present = true; - csi_report.report_freq_cfg.cqi_format_ind_present = true; - csi_report.report_freq_cfg.cqi_format_ind = - asn1::rrc_nr::csi_report_cfg_s::report_freq_cfg_s_::cqi_format_ind_opts::wideband_cqi; - csi_report.time_restrict_for_ch_meass = asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_ch_meass_opts::not_cfgured; - csi_report.time_restrict_for_interference_meass = - asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_interference_meass_opts::not_cfgured; - csi_report.group_based_beam_report.set_disabled(); - // Skip CQI table (optional) - csi_report.cqi_table_present = true; - csi_report.cqi_table = asn1::rrc_nr::csi_report_cfg_s::cqi_table_opts::table2; - csi_report.subband_size = asn1::rrc_nr::csi_report_cfg_s::subband_size_opts::value1; - - if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 5; - } else { - csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 7; - } - - return SRSRAN_SUCCESS; -} - -/// Fill lists of NZP-CSI-RS-Resource and NZP-CSI-RS-ResourceSet with gNB config -void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) -{ - csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list_present = true; - if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(5); - auto& nzp_csi_res = csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list; - // item 0 - nzp_csi_res[0].nzp_csi_rs_res_id = 0; - nzp_csi_res[0].res_map.freq_domain_alloc.set_row2(); - nzp_csi_res[0].res_map.freq_domain_alloc.row2().from_number(0b100000000000); - nzp_csi_res[0].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; - nzp_csi_res[0].res_map.first_ofdm_symbol_in_time_domain = 4; - nzp_csi_res[0].res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; - nzp_csi_res[0].res_map.density.set_one(); - nzp_csi_res[0].res_map.freq_band.start_rb = 0; - nzp_csi_res[0].res_map.freq_band.nrof_rbs = 52; - nzp_csi_res[0].pwr_ctrl_offset = 0; - // Skip pwr_ctrl_offset_ss_present - nzp_csi_res[0].scrambling_id = cfg.cell_list[0].phy_cell.cell_id; - nzp_csi_res[0].periodicity_and_offset_present = true; - nzp_csi_res[0].periodicity_and_offset.set_slots80(); - nzp_csi_res[0].periodicity_and_offset.slots80() = 1; - // optional - nzp_csi_res[0].qcl_info_periodic_csi_rs_present = true; - nzp_csi_res[0].qcl_info_periodic_csi_rs = 0; - // item 1 - nzp_csi_res[1] = nzp_csi_res[0]; - nzp_csi_res[1].nzp_csi_rs_res_id = 1; - nzp_csi_res[1].res_map.freq_domain_alloc.set_row1(); - nzp_csi_res[1].res_map.freq_domain_alloc.row1().from_number(0b0001); - nzp_csi_res[1].res_map.first_ofdm_symbol_in_time_domain = 4; - nzp_csi_res[1].res_map.density.set_three(); - nzp_csi_res[1].periodicity_and_offset.set_slots40(); - nzp_csi_res[1].periodicity_and_offset.slots40() = 11; - // item 2 - nzp_csi_res[2] = nzp_csi_res[1]; - nzp_csi_res[2].nzp_csi_rs_res_id = 2; - nzp_csi_res[2].res_map.first_ofdm_symbol_in_time_domain = 8; - nzp_csi_res[2].periodicity_and_offset.set_slots40(); - nzp_csi_res[2].periodicity_and_offset.slots40() = 11; - // item 3 - nzp_csi_res[3] = nzp_csi_res[1]; - nzp_csi_res[3].nzp_csi_rs_res_id = 3; - nzp_csi_res[3].res_map.first_ofdm_symbol_in_time_domain = 4; - nzp_csi_res[3].periodicity_and_offset.set_slots40(); - nzp_csi_res[3].periodicity_and_offset.slots40() = 12; - // item 4 - nzp_csi_res[4] = nzp_csi_res[1]; - nzp_csi_res[4].nzp_csi_rs_res_id = 4; - nzp_csi_res[4].res_map.first_ofdm_symbol_in_time_domain = 8; - nzp_csi_res[4].periodicity_and_offset.set_slots40(); - nzp_csi_res[4].periodicity_and_offset.slots40() = 12; - } else { - csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(1); - auto& nzp_csi_res = csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list; - nzp_csi_res[0].nzp_csi_rs_res_id = 0; - nzp_csi_res[0].res_map.freq_domain_alloc.set_row2(); - nzp_csi_res[0].res_map.freq_domain_alloc.row2().from_number(0b100000000000); - nzp_csi_res[0].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; - nzp_csi_res[0].res_map.first_ofdm_symbol_in_time_domain = 4; - nzp_csi_res[0].res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; - nzp_csi_res[0].res_map.density.set_one(); - nzp_csi_res[0].res_map.freq_band.start_rb = 0; - nzp_csi_res[0].res_map.freq_band.nrof_rbs = 52; - nzp_csi_res[0].pwr_ctrl_offset = 0; - // Skip pwr_ctrl_offset_ss_present - nzp_csi_res[0].periodicity_and_offset_present = true; - nzp_csi_res[0].periodicity_and_offset.set_slots80() = 0; - // optional - nzp_csi_res[0].qcl_info_periodic_csi_rs_present = true; - nzp_csi_res[0].qcl_info_periodic_csi_rs = 0; - } - - // Fill NZP-CSI Resource Sets - csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list_present = true; - if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(2); - auto& nzp_csi_res_set = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list; - // item 0 - nzp_csi_res_set[0].nzp_csi_res_set_id = 0; - nzp_csi_res_set[0].nzp_csi_rs_res.resize(1); - nzp_csi_res_set[0].nzp_csi_rs_res[0] = 0; - // item 1 - nzp_csi_res_set[1].nzp_csi_res_set_id = 1; - nzp_csi_res_set[1].nzp_csi_rs_res.resize(4); - nzp_csi_res_set[1].nzp_csi_rs_res[0] = 1; - nzp_csi_res_set[1].nzp_csi_rs_res[1] = 2; - nzp_csi_res_set[1].nzp_csi_rs_res[2] = 3; - nzp_csi_res_set[1].nzp_csi_rs_res[3] = 4; - // // Skip TRS info - } else { - csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(1); - auto& nzp_csi_res_set = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list; - nzp_csi_res_set[0].nzp_csi_res_set_id = 0; - nzp_csi_res_set[0].nzp_csi_rs_res.resize(1); - nzp_csi_res_set[0].nzp_csi_rs_res[0] = 0; - // Skip TRS info - } -} - -/// Fill csi-ResoureConfigToAddModList -void fill_csi_resource_cfg_to_add(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) -{ - if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - csi_meas_cfg.csi_res_cfg_to_add_mod_list_present = true; - csi_meas_cfg.csi_res_cfg_to_add_mod_list.resize(3); - - csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].csi_res_cfg_id = 0; - auto& nzp = csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].csi_rs_res_set_list.set_nzp_csi_rs_ssb(); - nzp.nzp_csi_rs_res_set_list_present = true; - nzp.nzp_csi_rs_res_set_list.push_back(0); - csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].bwp_id = 0; - csi_meas_cfg.csi_res_cfg_to_add_mod_list[0].res_type.value = csi_res_cfg_s::res_type_opts::periodic; - - csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].csi_res_cfg_id = 1; - auto& imres = csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].csi_rs_res_set_list.set_csi_im_res_set_list(); - imres.push_back(0); - csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].bwp_id = 0; - csi_meas_cfg.csi_res_cfg_to_add_mod_list[1].res_type.value = csi_res_cfg_s::res_type_opts::periodic; - - csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].csi_res_cfg_id = 2; - auto& nzp2 = csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].csi_rs_res_set_list.set_nzp_csi_rs_ssb(); - nzp2.nzp_csi_rs_res_set_list_present = true; - nzp2.nzp_csi_rs_res_set_list.push_back(1); - csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].bwp_id = 0; - csi_meas_cfg.csi_res_cfg_to_add_mod_list[2].res_type.value = csi_res_cfg_s::res_type_opts::periodic; - } -} - -/// Fill CSI-MeasConfig with gNB config -int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) -{ - // // Fill CSI Report - // if (fill_csi_report_from_enb_cfg(cfg, csi_meas_cfg) != SRSRAN_SUCCESS) { - // get_logger(cfg).error("Failed to configure eNB CSI Report"); - // return SRSRAN_ERROR; - // } - - // Fill CSI resource config - fill_csi_resource_cfg_to_add(cfg, csi_meas_cfg); - - // Fill NZP-CSI Resources - fill_nzp_csi_rs_from_enb_cfg(cfg, csi_meas_cfg); - - // CSI IM config - // TODO: add csi im config - - // CSI resource config - // TODO: add csi resource config - - return SRSRAN_SUCCESS; -} - -/// Fill InitDlBwp with gNB config -int fill_pdcch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pdcch_cfg_s& pdcch_cfg) -{ - auto& cell_cfg = cfg.cell_list.at(cc); - - for (uint32_t cs_idx = 0; cs_idx < SRSRAN_UE_DL_NR_MAX_NOF_CORESET; cs_idx++) { - if (cell_cfg.phy_cell.pdcch.coreset_present[cs_idx]) { - auto& coreset_cfg = cell_cfg.phy_cell.pdcch.coreset[cs_idx]; - - pdcch_cfg.ctrl_res_set_to_add_mod_list_present = true; - - uint8_t cs_mod_list_idx = pdcch_cfg.ctrl_res_set_to_add_mod_list.size(); - pdcch_cfg.ctrl_res_set_to_add_mod_list.resize(cs_mod_list_idx + 1); - auto& ctrl_res_items = pdcch_cfg.ctrl_res_set_to_add_mod_list; - ctrl_res_items[cs_mod_list_idx].ctrl_res_set_id = coreset_cfg.id; - - std::bitset freq_domain_res; - for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { - freq_domain_res[SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE - 1 - i] = coreset_cfg.freq_resources[i]; - } - - ctrl_res_items[cs_mod_list_idx].freq_domain_res.from_number(freq_domain_res.to_ulong()); - ctrl_res_items[cs_mod_list_idx].dur = coreset_cfg.duration; - - if (coreset_cfg.mapping_type == srsran_coreset_mapping_type_non_interleaved) { - ctrl_res_items[cs_mod_list_idx].cce_reg_map_type.set_non_interleaved(); - } else { - ctrl_res_items[cs_mod_list_idx].cce_reg_map_type.set_interleaved(); - } - - if (coreset_cfg.precoder_granularity == srsran_coreset_precoder_granularity_reg_bundle) { - ctrl_res_items[cs_mod_list_idx].precoder_granularity = - asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; - } else { - ctrl_res_items[cs_mod_list_idx].precoder_granularity = - asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::all_contiguous_rbs; - } - } - } - - for (uint32_t ss_idx = 0; ss_idx < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE; ss_idx++) { - if (cell_cfg.phy_cell.pdcch.search_space_present[ss_idx]) { - // search spaces - auto& search_space_cfg = cell_cfg.phy_cell.pdcch.search_space[ss_idx]; - pdcch_cfg.search_spaces_to_add_mod_list_present = true; - - uint8_t ss_mod_list_idx = pdcch_cfg.search_spaces_to_add_mod_list.size(); - pdcch_cfg.search_spaces_to_add_mod_list.resize(ss_mod_list_idx + 1); - auto& search_spaces = pdcch_cfg.search_spaces_to_add_mod_list; - search_spaces[ss_mod_list_idx].search_space_id = search_space_cfg.id; - search_spaces[ss_mod_list_idx].ctrl_res_set_id_present = true; - search_spaces[ss_mod_list_idx].ctrl_res_set_id = search_space_cfg.coreset_id; - search_spaces[ss_mod_list_idx].monitoring_slot_periodicity_and_offset_present = true; - search_spaces[ss_mod_list_idx].monitoring_slot_periodicity_and_offset.set_sl1(); - search_spaces[ss_mod_list_idx].monitoring_symbols_within_slot_present = true; - search_spaces[ss_mod_list_idx].monitoring_symbols_within_slot.from_number(0b10000000000000); - search_spaces[ss_mod_list_idx].nrof_candidates_present = true; - search_spaces[ss_mod_list_idx].nrof_candidates.aggregation_level1 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level1_opts::n0; - search_spaces[ss_mod_list_idx].nrof_candidates.aggregation_level2 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level2_opts::n2; - search_spaces[ss_mod_list_idx].nrof_candidates.aggregation_level4 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level4_opts::n2; - search_spaces[ss_mod_list_idx].nrof_candidates.aggregation_level8 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level8_opts::n0; - search_spaces[ss_mod_list_idx].nrof_candidates.aggregation_level16 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level16_opts::n0; - search_spaces[ss_mod_list_idx].search_space_type_present = true; - - if ((search_space_cfg.type == srsran_search_space_type_common_0) or - (search_space_cfg.type == srsran_search_space_type_common_0A) or - (search_space_cfg.type == srsran_search_space_type_common_1) or - (search_space_cfg.type == srsran_search_space_type_common_2) or - (search_space_cfg.type == srsran_search_space_type_common_3)) { - search_spaces[0].search_space_type.set_common(); - - if ((search_space_cfg.formats[0] == srsran_dci_format_nr_0_0) and - (search_space_cfg.formats[1] == srsran_dci_format_nr_1_0)) { - search_spaces[ss_mod_list_idx].search_space_type.common().dci_format0_minus0_and_format1_minus0_present = - true; - } else { - get_logger(cfg).error("Config Error: Unsupported dci nr formats."); - return SRSRAN_ERROR; - } - } else { - get_logger(cfg).error("Config Error: Unsupported search space type."); - return SRSRAN_ERROR; - } - } - } - return SRSRAN_SUCCESS; -} - -/// Fill InitDlBwp with gNB config -int fill_init_dl_bwp_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, bwp_dl_ded_s& init_dl_bwp) -{ - init_dl_bwp.pdcch_cfg_present = true; - HANDLE_ERROR(fill_pdcch_cfg_from_enb_cfg(cfg, cc, init_dl_bwp.pdcch_cfg.set_setup())); - - // TODO: ADD missing fields - - return SRSRAN_SUCCESS; -} - -/// Fill ServingCellConfig with gNB config -int fill_serv_cell_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, serving_cell_cfg_s& serv_cell) -{ - serv_cell.csi_meas_cfg_present = true; - HANDLE_ERROR(fill_csi_meas_from_enb_cfg(cfg, serv_cell.csi_meas_cfg.set_setup())); - - serv_cell.init_dl_bwp_present = true; - fill_init_dl_bwp_from_enb_cfg(cfg, cc, serv_cell.init_dl_bwp); - - // TODO: remaining fields - - return SRSRAN_SUCCESS; -} - -int fill_pdcch_cfg_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pdcch_cfg_common_s& pdcch_cfg_common) -{ - pdcch_cfg_common.common_ctrl_res_set_present = true; - pdcch_cfg_common.common_ctrl_res_set.ctrl_res_set_id = 1; - pdcch_cfg_common.common_ctrl_res_set.freq_domain_res.from_number(0b111111110000000000000000000000000000000000000); - pdcch_cfg_common.common_ctrl_res_set.dur = 1; - pdcch_cfg_common.common_ctrl_res_set.cce_reg_map_type.set_non_interleaved(); - pdcch_cfg_common.common_ctrl_res_set.precoder_granularity = - asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; - - // common search space list - pdcch_cfg_common.common_search_space_list_present = true; - pdcch_cfg_common.common_search_space_list.resize(1); - pdcch_cfg_common.common_search_space_list[0].search_space_id = 1; - pdcch_cfg_common.common_search_space_list[0].ctrl_res_set_id_present = true; - pdcch_cfg_common.common_search_space_list[0].ctrl_res_set_id = 1; - pdcch_cfg_common.common_search_space_list[0].search_space_type_present = true; - pdcch_cfg_common.common_search_space_list[0].search_space_type.set_common(); - pdcch_cfg_common.common_search_space_list[0] - .search_space_type.common() - .dci_format0_minus0_and_format1_minus0_present = true; - pdcch_cfg_common.common_search_space_list[0].nrof_candidates_present = true; - pdcch_cfg_common.common_search_space_list[0].nrof_candidates.aggregation_level1 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level1_opts::n1; - pdcch_cfg_common.common_search_space_list[0].nrof_candidates.aggregation_level2 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level2_opts::n1; - pdcch_cfg_common.common_search_space_list[0].nrof_candidates.aggregation_level4 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level4_opts::n1; - pdcch_cfg_common.common_search_space_list[0].nrof_candidates.aggregation_level8 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level8_opts::n0; - pdcch_cfg_common.common_search_space_list[0].nrof_candidates.aggregation_level16 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level16_opts::n0; - pdcch_cfg_common.common_search_space_list[0].monitoring_slot_periodicity_and_offset_present = true; - pdcch_cfg_common.common_search_space_list[0].monitoring_slot_periodicity_and_offset.set_sl1(); - pdcch_cfg_common.common_search_space_list[0].monitoring_symbols_within_slot_present = true; - pdcch_cfg_common.common_search_space_list[0].monitoring_symbols_within_slot.from_number(0b10000000000000); - pdcch_cfg_common.ra_search_space_present = true; - pdcch_cfg_common.ra_search_space = 1; - - if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { - pdcch_cfg_common.ext = false; - } - - return SRSRAN_SUCCESS; -} - -/// Fill FrequencyInfoDL with gNB config -int fill_freq_info_dl_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, freq_info_dl_s& freq_info_dl) -{ - auto& cell_cfg = cfg.cell_list.at(cc); - - freq_info_dl.freq_band_list.push_back(cell_cfg.band); - freq_info_dl.absolute_freq_point_a = cell_cfg.dl_absolute_freq_point_a; - freq_info_dl.absolute_freq_ssb_present = true; - freq_info_dl.absolute_freq_ssb = cell_cfg.ssb_absolute_freq_point; - - freq_info_dl.scs_specific_carrier_list.resize(1); - auto& dl_carrier = freq_info_dl.scs_specific_carrier_list[0]; - dl_carrier.offset_to_carrier = cell_cfg.phy_cell.carrier.offset_to_carrier; - - if (!asn1::number_to_enum(dl_carrier.subcarrier_spacing, - SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs) / 1000)) { - get_logger(cfg).error("Config Error: Invalid subcarrier spacing (%d).\n", - SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs)); - return SRSRAN_ERROR; - } - - dl_carrier.carrier_bw = cell_cfg.phy_cell.carrier.nof_prb; - - return SRSRAN_SUCCESS; -} - -/// Fill InitDlBwp with gNB config -int fill_init_dl_bwp_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, bwp_dl_common_s& init_dl_bwp) -{ - init_dl_bwp.pdcch_cfg_common_present = true; - HANDLE_ERROR(fill_pdcch_cfg_common_from_enb_cfg(cfg, cc, init_dl_bwp.pdcch_cfg_common.set_setup())); - // TODO: ADD missing fields - - return SRSRAN_SUCCESS; -} - -/// Fill DLCellConfigCommon with gNB config -int fill_dl_cfg_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, dl_cfg_common_s& dl_cfg_common) -{ - dl_cfg_common.freq_info_dl_present = true; - HANDLE_ERROR(fill_freq_info_dl_from_enb_cfg(cfg, cc, dl_cfg_common.freq_info_dl)); - - dl_cfg_common.init_dl_bwp_present = true; - HANDLE_ERROR(fill_init_dl_bwp_common_from_enb_cfg(cfg, cc, dl_cfg_common.init_dl_bwp)); - - // TODO: ADD missing fields - - return SRSRAN_SUCCESS; -} - -/// Fill FrequencyInfoUL with gNB config -int fill_freq_info_ul_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, freq_info_ul_s& freq_info_ul) -{ - auto& cell_cfg = cfg.cell_list.at(cc); - - freq_info_ul.freq_band_list_present = true; - freq_info_ul.freq_band_list.push_back(cell_cfg.band); - freq_info_ul.absolute_freq_point_a_present = true; - freq_info_ul.absolute_freq_point_a = cell_cfg.ul_absolute_freq_point_a; - freq_info_ul.scs_specific_carrier_list.resize(1); - - auto& ul_carrier = freq_info_ul.scs_specific_carrier_list[0]; - ul_carrier.offset_to_carrier = cell_cfg.phy_cell.carrier.offset_to_carrier; - - if (!asn1::number_to_enum(ul_carrier.subcarrier_spacing, - SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs) / 1000)) { - get_logger(cfg).error("Config Error: Invalid subcarrier spacing (%d).\n", - SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs)); - return SRSRAN_ERROR; - } - - ul_carrier.carrier_bw = cell_cfg.phy_cell.carrier.nof_prb; - - return SRSRAN_SUCCESS; -} - -/// Fill RachConfigCommon with gNB config -int fill_rach_cfg_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, rach_cfg_common_s& rach_cfg_common) -{ - auto& cell_cfg = cfg.cell_list.at(cc); - - rach_cfg_common = cfg.rach_cfg_common; - - rach_cfg_common.rach_cfg_generic.msg1_freq_start = cell_cfg.phy_cell.prach.freq_offset; - rach_cfg_common.rach_cfg_generic.prach_cfg_idx = cell_cfg.phy_cell.prach.config_idx; - rach_cfg_common.rach_cfg_generic.zero_correlation_zone_cfg = cell_cfg.phy_cell.prach.zero_corr_zone; - - if (cfg.prach_root_seq_idx_type == 139) { - rach_cfg_common.prach_root_seq_idx.set_l139() = cell_cfg.phy_cell.prach.root_seq_idx; - } else if (cfg.prach_root_seq_idx_type == 839) { - rach_cfg_common.prach_root_seq_idx.set_l839() = cell_cfg.phy_cell.prach.root_seq_idx; - } else { - get_logger(cfg).error("Config Error: Invalid prach_root_seq_idx_type (%d)\n", cfg.prach_root_seq_idx_type); - return SRSRAN_ERROR; - } - - return SRSRAN_SUCCESS; -} - -/// Fill InitUlBwp with gNB config -int fill_init_ul_bwp_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, bwp_ul_common_s& init_ul_bwp) -{ - init_ul_bwp.rach_cfg_common_present = true; - fill_rach_cfg_common_from_enb_cfg(cfg, cc, init_ul_bwp.rach_cfg_common.set_setup()); - - // TODO: Add missing fields - - return SRSRAN_SUCCESS; -} - -/// Fill ULCellConfigCommon with gNB config -int fill_ul_cfg_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, ul_cfg_common_s& ul_cfg_common) -{ - ul_cfg_common.dummy = time_align_timer_opts::ms500; - - ul_cfg_common.freq_info_ul_present = true; - HANDLE_ERROR(fill_freq_info_ul_from_enb_cfg(cfg, cc, ul_cfg_common.freq_info_ul)); - - ul_cfg_common.init_ul_bwp_present = true; - fill_init_ul_bwp_from_enb_cfg(cfg, cc, ul_cfg_common.init_ul_bwp); - - // TODO: Add missing fields - - return SRSRAN_SUCCESS; -} - -/// Fill ServingCellConfigCommon with gNB config -int fill_serv_cell_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, serving_cell_cfg_common_s& serv_common) -{ - auto& cell_cfg = cfg.cell_list.at(cc); - - serv_common.ss_pbch_block_pwr = cell_cfg.phy_cell.pdsch.rs_power; - serv_common.n_timing_advance_offset_present = true; - serv_common.n_timing_advance_offset = asn1::rrc_nr::serving_cell_cfg_common_s::n_timing_advance_offset_opts::n0; - serv_common.n_timing_advance_offset_present = true; - serv_common.dmrs_type_a_position = asn1::rrc_nr::serving_cell_cfg_common_s::dmrs_type_a_position_opts::pos2; - - serv_common.pci_present = true; - serv_common.pci = cell_cfg.phy_cell.carrier.pci; - - serv_common.ssb_periodicity_serving_cell_present = true; - if (not asn1::number_to_enum(serv_common.ssb_periodicity_serving_cell, cell_cfg.ssb_cfg.periodicity_ms)) { - get_logger(cfg).error("Config Error: Invalid SSB periodicity = %d\n", cell_cfg.ssb_cfg.periodicity_ms); - return SRSRAN_ERROR; - } - - // Fill SSB config - serv_common.ssb_positions_in_burst_present = true; - if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - serv_common.ssb_positions_in_burst.set_short_bitmap().from_number(0b1000); - } else { - serv_common.ssb_positions_in_burst.set_medium_bitmap().from_number(0b10000000); - } - - // Set SSB SCS - serv_common.ssb_subcarrier_spacing_present = true; - if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - serv_common.ssb_subcarrier_spacing = subcarrier_spacing_opts::khz15; - } else { - serv_common.ssb_subcarrier_spacing = subcarrier_spacing_opts::khz30; - } - - if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { - // TDD UL-DL config - serv_common.tdd_ul_dl_cfg_common_present = true; - auto& tdd_config = serv_common.tdd_ul_dl_cfg_common; - tdd_config.ref_subcarrier_spacing = subcarrier_spacing_e::khz15; - tdd_config.pattern1.dl_ul_tx_periodicity = asn1::rrc_nr::tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10; - tdd_config.pattern1.nrof_dl_slots = 6; - tdd_config.pattern1.nrof_dl_symbols = 0; - tdd_config.pattern1.nrof_ul_slots = 4; - tdd_config.pattern1.nrof_ul_symbols = 0; - } - - serv_common.ul_cfg_common_present = true; - fill_ul_cfg_common_from_enb_cfg(cfg, cc, serv_common.ul_cfg_common); - - serv_common.dl_cfg_common_present = true; - fill_dl_cfg_common_from_enb_cfg(cfg, cc, serv_common.dl_cfg_common); - - return SRSRAN_SUCCESS; -} - -/// Fill reconfigurationWithSync with gNB config -int fill_recfg_with_sync_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, recfg_with_sync_s& sync) -{ - sync.sp_cell_cfg_common_present = true; - HANDLE_ERROR(fill_serv_cell_common_from_enb_cfg(cfg, cc, sync.sp_cell_cfg_common)); - - return SRSRAN_SUCCESS; -} - -/// Fill spCellConfig with gNB config -int fill_sp_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, sp_cell_cfg_s& sp_cell) -{ - sp_cell.recfg_with_sync_present = true; - HANDLE_ERROR(fill_recfg_with_sync_from_enb_cfg(cfg, cc, sp_cell.recfg_with_sync)); - - sp_cell.sp_cell_cfg_ded_present = true; - HANDLE_ERROR(fill_serv_cell_from_enb_cfg(cfg, cc, sp_cell.sp_cell_cfg_ded)); - - return SRSRAN_SUCCESS; -} - -} // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index bdcb5ce2cd..59611d2c0c 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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() {} @@ -643,7 +644,7 @@ void rrc::sgnb_release_ack(uint16_t eutra_rnti) void rrc::parse_ul_ccch(ue& ue, srsran::unique_byte_buffer_t pdu) { - srsran_assert(pdu != nullptr, "parse_ul_ccch called for empty message"); + srsran_assert(pdu != nullptr, "handle_ul_ccch called for empty message"); ul_ccch_msg_s ul_ccch_msg; asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); @@ -676,7 +677,7 @@ void rrc::parse_ul_ccch(ue& ue, srsran::unique_byte_buffer_t pdu) ///< User mutex must be hold by caller void rrc::parse_ul_dcch(ue& ue, uint32_t lcid, srsran::unique_byte_buffer_t pdu) { - srsran_assert(pdu != nullptr, "parse_ul_dcch called for empty message"); + srsran_assert(pdu != nullptr, "handle_ul_dcch called for empty message"); ue.parse_ul_dcch(lcid, std::move(pdu)); } @@ -959,6 +960,7 @@ void rrc::configure_mbsfn_sibs() task_sched.defer_task([this, sibs2, sibs13, mcch_t]() mutable { phy->configure_mbsfn(&sibs2, &sibs13, mcch_t); mac->write_mcch(&sibs2, &sibs13, &mcch_t, mcch_payload_buffer, current_mcch_length); + add_user(SRSRAN_MRNTI, {}); }); } @@ -1036,7 +1038,7 @@ void rrc::tti_clock() if (p.pdu != nullptr) { log_rx_pdu_fail(p.rnti, p.lcid, *p.pdu, "unknown rnti"); } else { - logger.warning("Ignoring rnti=0x%x command. Cause: unknown rnti", p.rnti); + logger.warning("Ignoring rnti=0x%x command %d arg %d. Cause: unknown rnti", p.rnti, p.lcid, p.arg); } continue; } diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index a70e58b373..c68627471b 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,8 +21,8 @@ #include "srsenb/hdr/stack/rrc/rrc_bearer_cfg.h" #include "srsenb/hdr/common/common_enb.h" +#include "srsran/asn1/obj_id_cmp_utils.h" #include "srsran/asn1/rrc_utils.h" -#include "srsran/rrc/rrc_cfg_utils.h" namespace srsenb { @@ -221,12 +221,12 @@ void bearer_cfg_handler::reestablish_bearers(bearer_cfg_handler&& old_rnti_beare old_rnti_bearers.current_drbs.clear(); } -int bearer_cfg_handler::add_erab(uint8_t erab_id, - const asn1::s1ap::erab_level_qos_params_s& qos, - const asn1::bounded_bitstring<1, 160, true, true>& addr, - uint32_t teid_out, - srsran::const_span nas_pdu, - asn1::s1ap::cause_c& cause) +int bearer_cfg_handler::addmod_erab(uint8_t erab_id, + const asn1::s1ap::erab_level_qos_params_s& qos, + const asn1::bounded_bitstring<1, 160, true, true>& addr, + uint32_t teid_out, + srsran::const_span nas_pdu, + asn1::s1ap::cause_c& cause) { if (erab_id < 5) { logger->error("ERAB id=%d is invalid", erab_id); @@ -290,6 +290,16 @@ int bearer_cfg_handler::add_erab(uint8_t } } + // If it is an E-RAB modification, remove previous DRB object + if (erabs.count(erab_id) > 0) { + for (auto& drb : current_drbs) { + if (drb.eps_bearer_id_present and drb.eps_bearer_id == erab_id) { + srsran::rem_rrc_obj_id(current_drbs, drb.drb_id); + break; + } + } + } + // Consider ERAB as accepted erabs[erab_id].id = erab_id; erabs[erab_id].lcid = lcid; @@ -361,8 +371,7 @@ int bearer_cfg_handler::modify_erab(uint8_t e } auto address = erab_it->second.address; uint32_t teid_out = erab_it->second.teid_out; - release_erab(erab_id); - return add_erab(erab_id, qos, address, teid_out, nas_pdu, cause); + return addmod_erab(erab_id, qos, address, teid_out, nas_pdu, cause); } int bearer_cfg_handler::add_gtpu_bearer(uint32_t erab_id) @@ -414,17 +423,11 @@ void bearer_cfg_handler::rem_gtpu_bearer(uint32_t erab_id) void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg) { - // Add space for NAS messages - uint8_t n_nas = erab_info_list.size(); - if (n_nas > 0) { - msg->ded_info_nas_list_present = true; - msg->ded_info_nas_list.resize(n_nas); - } - - uint32_t idx = 0; // DRBs have already been configured in GTPU during bearer setup // Add E-RAB info message for the E-RABs if (msg->rr_cfg_ded.drb_to_add_mod_list_present) { + erab_ids_with_pending_nas_pdus.clear(); + for (const drb_to_add_mod_s& drb : msg->rr_cfg_ded.drb_to_add_mod_list) { uint32_t lcid = drb_to_lcid((lte_drb)drb.drb_id); auto erab_it = std::find_if( @@ -434,15 +437,30 @@ void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_ if (info_it != erab_info_list.end()) { const std::vector& erab_info = info_it->second; logger->info(&erab_info[0], erab_info.size(), "connection_reconf erab_info -> nas_info rnti 0x%x", rnti); - msg->ded_info_nas_list[idx].resize(erab_info.size()); - memcpy(msg->ded_info_nas_list[idx].data(), &erab_info[0], erab_info.size()); - erab_info_list.erase(info_it); + msg->ded_info_nas_list.push_back({}); + msg->ded_info_nas_list.back().resize(erab_info.size()); + memcpy(msg->ded_info_nas_list.back().data(), &erab_info[0], erab_info.size()); + erab_ids_with_pending_nas_pdus.push_back(erab_id); } else { - logger->debug("Not adding NAS message to connection reconfiguration. E-RAB id %d", erab_id); + logger->warning("Not adding NAS message to connection reconfiguration. E-RAB id %d", erab_id); } - idx++; } + msg->ded_info_nas_list_present = msg->ded_info_nas_list.size() > 0; } } +void bearer_cfg_handler::clear_pending_nas_info() +{ + for (uint32_t erab_id : erab_ids_with_pending_nas_pdus) { + auto info_it = erab_info_list.find(erab_id); + if (info_it == erab_info_list.end()) { + logger->warning("NAS PDU with ERAB id={} went missing", erab_id); + continue; + } + erab_info_list.erase(info_it); + } + + erab_ids_with_pending_nas_pdus.clear(); +} + } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_cell_cfg.cc b/srsenb/src/stack/rrc/rrc_cell_cfg.cc index 9d6b8c42fa..fdbc02145e 100644 --- a/srsenb/src/stack/rrc/rrc_cell_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_cell_cfg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -43,6 +43,7 @@ enb_cell_common_list::enb_cell_common_list(const rrc_cfg_t& cfg_) : cfg(cfg_) asn1::number_to_enum(new_cell->mib.dl_bw, cfg.cell.nof_prb); new_cell->mib.phich_cfg.phich_res.value = (phich_cfg_s::phich_res_opts::options)cfg.cell.phich_resources; new_cell->mib.phich_cfg.phich_dur.value = (phich_cfg_s::phich_dur_opts::options)cfg.cell.phich_length; + new_cell->mib.part_earfcn_minus17.set_spare().from_number(0); // Set Cell SIB1 new_cell->sib1 = cfg.sib1; @@ -53,6 +54,12 @@ enb_cell_common_list::enb_cell_common_list(const rrc_cfg_t& cfg_) : cfg(cfg_) // Update DL EARFCN new_cell->sib1.freq_band_ind = (uint8_t)srsran_band_get_band(new_cell->cell_cfg.dl_earfcn); + if (new_cell->cell_cfg.barred) { + cell_access->cell_barred.value = sib_type1_s::cell_access_related_info_s_::cell_barred_opts::barred; + } else { + cell_access->cell_barred.value = sib_type1_s::cell_access_related_info_s_::cell_barred_opts::not_barred; + } + // Set Cell SIB2 // update PRACH root seq index for this cell new_cell->sib2 = cfg.sibs[1].sib2(); diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index fbeebc60ed..6e54397fb0 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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; @@ -319,8 +319,27 @@ void rrc::ue::rrc_endc::start_sgnb_addition() { // Start EN-DC activation using EPS bearer of EUTRA DRB1 rrc_nr_interface_rrc::sgnb_addition_req_params_t params = {}; - params.eps_bearer_id = - rrc_enb->bearer_manager.get_lcid_bearer(rrc_ue->rnti, drb_to_lcid((lte_drb)eutra_drb_id)).eps_bearer_id; + + const auto& drb_list = rrc_ue->bearer_list.get_established_drbs(); + if (drb_list.size() > 0) { + // move first establised DRB to NR cell + const auto& drb1 = drb_list[0]; + const auto& erab_list = rrc_ue->bearer_list.get_erabs(); + auto erab_it = erab_list.find(drb1.eps_bearer_id); + if (erab_it != erab_list.end()) { + params.eps_bearer_id = drb1.eps_bearer_id; + params.five_qi = erab_it->second.qos_params.qci; // use QCI as 5QI + } else { + logger.error("Couldn't find ERAB config for DRB%d. Aborting SgNB addition for E-UTRA rnti=0x%x", + drb1.drb_id, + rrc_ue->rnti); + return; + } + } else { + logger.error("No LTE DRB established. Aborting SgNB addition for E-UTRA rnti=0x%x", rrc_ue->rnti); + return; + } + logger.info("Triggering SgNB addition for E-UTRA rnti=0x%x", rrc_ue->rnti); rrc_enb->rrc_nr->sgnb_addition_request(rrc_ue->rnti, params); diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index 8d1d892810..017f2c295f 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,6 +24,7 @@ #include "srsenb/hdr/stack/rrc/rrc_cell_cfg.h" #include "srsenb/hdr/stack/rrc/ue_meas_cfg.h" #include "srsenb/hdr/stack/rrc/ue_rr_cfg.h" +#include "srsran/asn1/obj_id_cmp_utils.h" #include "srsran/asn1/rrc_utils.h" #include "srsran/common/bcd_helpers.h" #include "srsran/common/common.h" @@ -34,7 +35,6 @@ #include "srsran/interfaces/enb_pdcp_interfaces.h" #include "srsran/interfaces/enb_rlc_interfaces.h" #include "srsran/interfaces/enb_s1ap_interfaces.h" -#include "srsran/rrc/rrc_cfg_utils.h" #include #include @@ -216,7 +216,8 @@ uint16_t rrc::start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& rrc::ue::rrc_mobility::rrc_mobility(rrc::ue* outer_ue) : base_t(outer_ue->parent->logger), rrc_ue(outer_ue), rrc_enb(outer_ue->parent), logger(outer_ue->parent->logger) -{} +{ +} //! Method to add Mobility Info to a RRC Connection Reconfiguration Message bool rrc::ue::rrc_mobility::fill_conn_recfg_no_ho_cmd(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg) @@ -282,9 +283,11 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg, srsr const enb_cell_common* c = rrc_enb->cell_common_list->get_pci(e.pci); if (meas_it != meas_list_cfg.end()) { meas_ev.target_eci = meas_it->eci; + meas_ev.target_tac = meas_it->tac; meas_ev.direct_fwd_path = meas_it->direct_forward_path_available; } else if (c != nullptr) { meas_ev.target_eci = (rrc_enb->cfg.enb_id << 8u) + c->cell_cfg.cell_id; + meas_ev.target_tac = pcell->cell_common->cell_cfg.tac; } else { logger.warning("The PCI=%d inside the MeasReport is not recognized.", e.pci); continue; @@ -305,6 +308,7 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg, srsr * - This struct goes in a transparent container to the S1AP */ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci, + uint16_t target_tac, uint8_t measobj_id, bool fwd_direct_path_available) { @@ -325,8 +329,7 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci, capitem.ue_category = 4; capitem.pdcp_params.max_num_rohc_context_sessions_present = true; capitem.pdcp_params.max_num_rohc_context_sessions = asn1::rrc::pdcp_params_s::max_num_rohc_context_sessions_e_::cs2; - bzero(&capitem.pdcp_params.supported_rohc_profiles, - sizeof(asn1::rrc::rohc_profile_support_list_r15_s)); // TODO: why is it r15? + capitem.pdcp_params.supported_rohc_profiles = {}; capitem.phy_layer_params.ue_specific_ref_sigs_supported = false; capitem.phy_layer_params.ue_tx_ant_sel_supported = false; capitem.rf_params.supported_band_list_eutra.resize(1); @@ -379,6 +382,7 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci, hoprep_r8.as_cfg.source_mib.phich_cfg.phich_res.value = (asn1::rrc::phich_cfg_s::phich_res_e_::options)rrc_enb->cfg.cell.phich_resources; hoprep_r8.as_cfg.source_mib.sys_frame_num.from_number(0); // NOTE: The TS says this can go empty + hoprep_r8.as_cfg.source_mib.part_earfcn_minus17.set_spare().from_number(0); hoprep_r8.as_cfg.source_sib_type1 = src_cell_cfg->sib1; hoprep_r8.as_cfg.source_sib_type2 = src_cell_cfg->sib2; asn1::number_to_enum(hoprep_r8.as_cfg.ant_info_common.ant_ports_count, rrc_enb->cfg.cell.nof_ports); @@ -415,7 +419,7 @@ bool rrc::ue::rrc_mobility::start_ho_preparation(uint32_t target_eci, } return rrc_enb->s1ap->send_ho_required( - rrc_ue->rnti, target_eci, target_plmn, fwd_erabs, std::move(buffer), fwd_direct_path_available); + rrc_ue->rnti, target_eci, target_tac, target_plmn, fwd_erabs, std::move(buffer), fwd_direct_path_available); } /** @@ -443,9 +447,9 @@ void rrc::ue::rrc_mobility::handle_ho_preparation_complete(rrc::ho_prep_result } // Check if any E-RAB that was not admitted. Cancel Handover, in such case. - if (msg.protocol_ies.erab_to_release_list_ho_cmd_present) { + if (msg->erab_to_release_list_ho_cmd_present) { get_logger().warning("E-RAB id=%d was not admitted in target eNB. Cancelling handover...", - msg.protocol_ies.erab_to_release_list_ho_cmd.value[0].value.erab_item().erab_id); + msg->erab_to_release_list_ho_cmd.value[0]->erab_item().erab_id); asn1::s1ap::cause_c cause; cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::no_radio_res_available_in_target_cell; trigger(ho_cancel_ev{cause}); @@ -591,7 +595,8 @@ bool rrc::ue::rrc_mobility::needs_intraenb_ho(idle_st& s, const ho_meas_report_e rrc::ue::rrc_mobility::s1_source_ho_st::s1_source_ho_st(rrc_mobility* parent_) : base_t(parent_), rrc_enb(parent_->rrc_enb), rrc_ue(parent_->rrc_ue), logger(parent_->logger) -{} +{ +} /** * TS 36.413, Section 8.4.6 - eNB Status Transfer @@ -631,11 +636,11 @@ rrc::ue::rrc_mobility::s1_source_ho_st::start_enb_status_transfer(const asn1::s1 } // Setup GTPU forwarding tunnel - if (s1ap_ho_cmd.protocol_ies.erab_subjectto_data_forwarding_list_present) { - const auto& fwd_erab_list = s1ap_ho_cmd.protocol_ies.erab_subjectto_data_forwarding_list.value; + if (s1ap_ho_cmd->erab_subjectto_data_forwarding_list_present) { + const auto& fwd_erab_list = s1ap_ho_cmd->erab_subjectto_data_forwarding_list.value; const auto& erab_list = rrc_ue->bearer_list.get_erabs(); for (const auto& e : fwd_erab_list) { - const auto& fwd_erab = e.value.erab_data_forwarding_item(); + const auto& fwd_erab = e->erab_data_forwarding_item(); auto it = erab_list.find(fwd_erab.erab_id); if (it == erab_list.end()) { Warning("E-RAB id=%d subject to forwarding not found\n", fwd_erab.erab_id); @@ -663,7 +668,8 @@ void rrc::ue::rrc_mobility::s1_source_ho_st::enter(rrc_mobility* f, const ho_mea logger.info("Starting S1 Handover of rnti=0x%x to cellid=0x%x.", rrc_ue->rnti, ev.target_eci); report = ev; - if (not parent_fsm()->start_ho_preparation(report.target_eci, report.meas_obj->meas_obj_id, ev.direct_fwd_path)) { + if (not parent_fsm()->start_ho_preparation( + report.target_eci, report.target_tac, report.meas_obj->meas_obj_id, ev.direct_fwd_path)) { trigger(srsran::failure_ev{}); } } @@ -819,7 +825,7 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& rrc_ue->ue_security_cfg.get_security_algorithm_cfg(); recfg_r8.security_cfg_ho.handov_type.intra_lte().key_change_ind = false; recfg_r8.security_cfg_ho.handov_type.intra_lte().next_hop_chaining_count = - ho_req.ho_req_msg->protocol_ies.security_context.value.next_hop_chaining_count; + (*ho_req.ho_req_msg)->security_context.value.next_hop_chaining_count; /* Prepare Handover Command to be sent via S1AP */ srsran::unique_byte_buffer_t ho_cmd_pdu = srsran::make_byte_buffer(); @@ -860,6 +866,9 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& rrc_ue->mac_ctrl.handle_target_enb_ho_cmd(recfg_r8, rrc_ue->ue_capabilities); // Apply PHY updates rrc_ue->apply_reconf_phy_config(recfg_r8, true); + // Save source UE PCI and RNTI. + get_state()->src_rnti = hoprep_r8.as_cfg.source_ue_id.to_number(); + get_state()->src_pci = hoprep_r8.as_context.reest_info.source_pci; // Set admitted E-RABs std::vector admitted_erabs; @@ -872,16 +881,16 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& // Establish GTPU Forwarding Paths if (ho_req.transparent_container->erab_info_list_present) { const auto& lst = ho_req.transparent_container->erab_info_list; - const auto* it = std::find_if( - lst.begin(), - lst.end(), - [&erab](const asn1::s1ap::protocol_ie_single_container_s& fwd_erab) { - return fwd_erab.value.erab_info_list_item().erab_id == erab.second.id; - }); + const auto* it = + std::find_if(lst.begin(), + lst.end(), + [&erab](const asn1::protocol_ie_single_container_s& fwd_erab) { + return fwd_erab->erab_info_list_item().erab_id == erab.second.id; + }); if (it == lst.end()) { continue; } - const auto& fwd_erab = it->value.erab_info_list_item(); + const auto& fwd_erab = (*it)->erab_info_list_item(); if (fwd_erab.dl_forwarding_present and fwd_erab.dl_forwarding.value == asn1::s1ap::dl_forwarding_opts::dl_forwarding_proposed) { @@ -944,8 +953,8 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& const cell_cfg_t& target_cell_cfg = target_cell->cell_common->cell_cfg; // Establish ERABs/DRBs - for (const auto& erab_item : ho_req_msg.protocol_ies.erab_to_be_setup_list_ho_req.value) { - const auto& erab = erab_item.value.erab_to_be_setup_item_ho_req(); + for (const auto& erab_item : ho_req_msg->erab_to_be_setup_list_ho_req.value) { + const auto& erab = erab_item->erab_to_be_setup_item_ho_req(); if (erab.ext) { get_logger().warning("Not handling E-RABToBeSetupList extensions"); } @@ -961,7 +970,7 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& uint32_t teid_out = 0; srsran::uint8_to_uint32(erab.gtp_teid.data(), &teid_out); asn1::s1ap::cause_c erab_cause; - if (rrc_ue->bearer_list.add_erab( + if (rrc_ue->bearer_list.addmod_erab( erab.erab_id, erab.erab_level_qos_params, erab.transport_layer_address, teid_out, {}, erab_cause) != SRSRAN_SUCCESS) { erabs_failed_to_setup.emplace_back(); @@ -981,13 +990,13 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& // Regenerate AS Keys // See TS 33.401, Sec. 7.2.8.4.3 - if (not rrc_ue->ue_security_cfg.set_security_capabilities(ho_req_msg.protocol_ies.ue_security_cap.value)) { + if (not rrc_ue->ue_security_cfg.set_security_capabilities(ho_req_msg->ue_security_cap.value)) { cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::encryption_and_or_integrity_protection_algorithms_not_supported; return false; } - rrc_ue->ue_security_cfg.set_security_key(ho_req_msg.protocol_ies.security_context.value.next_hop_param); - rrc_ue->ue_security_cfg.set_ncc(ho_req_msg.protocol_ies.security_context.value.next_hop_chaining_count); + rrc_ue->ue_security_cfg.set_security_key(ho_req_msg->security_context.value.next_hop_param); + rrc_ue->ue_security_cfg.set_ncc(ho_req_msg->security_context.value.next_hop_chaining_count); rrc_ue->ue_security_cfg.regenerate_keys_handover(target_cell_cfg.pci, target_cell_cfg.dl_earfcn); // Save UE Capabilities @@ -1003,7 +1012,7 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& rrc_ue->eutra_capabilities.to_json(js); logger.debug("New rnti=0x%x EUTRA capabilities: %s", rrc_ue->rnti, js.to_string().c_str()); } - rrc_ue->ue_capabilities = srsran::make_rrc_ue_capabilities(rrc_ue->eutra_capabilities); + rrc_ue->ue_capabilities = srsran::make_rrc_ue_capabilities(rrc_ue->eutra_capabilities, *target_cell); rrc_ue->eutra_capabilities_unpacked = true; } } @@ -1047,7 +1056,7 @@ void rrc::ue::rrc_mobility::handle_status_transfer(s1_target_ho_st& s, const sta // Set DRBs SNs for (const auto& erab : erabs) { - const auto& erab_item = erab.value.bearers_subject_to_status_transfer_item(); + const auto& erab_item = erab->bearers_subject_to_status_transfer_item(); auto erab_it = rrc_ue->bearer_list.get_erabs().find(erab_item.erab_id); if (erab_it == rrc_ue->bearer_list.get_erabs().end()) { logger.warning("The E-RAB Id=%d is not recognized", erab_item.erab_id); @@ -1184,4 +1193,13 @@ void rrc::ue::rrc_mobility::handle_recfg_complete(intraenb_ho_st& s, const recfg logger.info("User rnti=0x%x successfully handovered to cell_id=0x%x", rrc_ue->rnti, s.target_cell->cell_cfg.cell_id); } +std::pair rrc::ue::rrc_mobility::get_source_ue_rnti_and_pci() +{ + if (not is_ho_running() or (not is_in_state() and not is_in_state())) { + return std::make_pair(SRSRAN_INVALID_RNTI, (uint32_t)0); + } + const s1_target_ho_st* st = get_state(); + return std::make_pair(st->src_rnti, st->src_pci); +} + } // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc deleted file mode 100644 index 92af0651db..0000000000 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ /dev/null @@ -1,1450 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsenb/hdr/stack/rrc/rrc_nr.h" -#include "srsenb/hdr/common/common_enb.h" -#include "srsenb/hdr/stack/rrc/nr/cell_asn1_config.h" -#include "srsenb/test/mac/nr/sched_nr_cfg_generators.h" -#include "srsran/asn1/rrc_nr_utils.h" -#include "srsran/common/common_nr.h" -#include "srsran/common/phy_cfg_nr_default.h" -#include "srsran/common/standard_streams.h" - -using namespace asn1::rrc_nr; - -namespace srsenb { - -rrc_nr::rrc_nr(srsran::task_sched_handle task_sched_) : - logger(srslog::fetch_basic_logger("RRC-NR")), task_sched(task_sched_) -{} - -int rrc_nr::init(const rrc_nr_cfg_t& cfg_, - phy_interface_stack_nr* phy_, - mac_interface_rrc_nr* mac_, - rlc_interface_rrc* rlc_, - pdcp_interface_rrc* pdcp_, - ngap_interface_rrc_nr* ngap_, - gtpu_interface_rrc_nr* gtpu_, - rrc_eutra_interface_rrc_nr* rrc_eutra_) -{ - phy = phy_; - mac = mac_; - rlc = rlc_; - pdcp = pdcp_; - ngap = ngap_; - gtpu = gtpu_; - rrc_eutra = rrc_eutra_; - - // TODO: overwriting because we are not passing config right now - cfg = update_default_cfg(cfg_); - - // derived - slot_dur_ms = 1; - - if (generate_sibs() != SRSRAN_SUCCESS) { - logger.error("Couldn't generate SIB messages."); - return SRSRAN_ERROR; - } - - // Fill base ASN1 cell config. - int ret = fill_sp_cell_cfg_from_enb_cfg(cfg, UE_PSCELL_CC_IDX, base_sp_cell_cfg); - srsran_assert(ret == SRSRAN_SUCCESS, "Failed to configure cell"); - - // Fill rrc_nr_cfg with UE-specific search spaces and coresets - bool ret2 = srsran::fill_phy_pdcch_cfg_common( - base_sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdcch_cfg_common.setup(), - &cfg.cell_list[0].phy_cell.pdcch); - srsran_assert(ret2, "Invalid NR cell configuration."); - ret2 = srsran::fill_phy_pdcch_cfg(base_sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(), - &cfg.cell_list[0].phy_cell.pdcch); - srsran_assert(ret2, "Invalid NR cell configuration."); - - config_phy(); // if PHY is not yet initialized, config will be stored and applied on initialization - config_mac(); - - logger.info("Started"); - - running = true; - - return SRSRAN_SUCCESS; -} - -void rrc_nr::stop() -{ - if (running) { - running = false; - } - users.clear(); -} - -template -void rrc_nr::log_rrc_message(const std::string& source, - const direction_t dir, - const srsran::byte_buffer_t* pdu, - const T& msg) -{ - if (logger.debug.enabled()) { - asn1::json_writer json_writer; - msg.to_json(json_writer); - logger.debug(pdu->msg, - pdu->N_bytes, - "%s - %s %s (%d B)", - source.c_str(), - dir == Tx ? "Tx" : "Rx", - msg.msg.c1().type().to_string(), - pdu->N_bytes); - logger.debug("Content:\n%s", json_writer.to_string().c_str()); - } else if (logger.info.enabled()) { - logger.info( - "%s - %s %s (%d B)", source.c_str(), dir == Tx ? "Tx" : "Rx", msg.msg.c1().type().to_string(), pdu->N_bytes); - } -} - -rrc_nr_cfg_t rrc_nr::update_default_cfg(const rrc_nr_cfg_t& current) -{ - // NOTE: This function is temporary. - rrc_nr_cfg_t cfg_default = current; - - // Fill MIB - cfg_default.mib.sub_carrier_spacing_common.value = mib_s::sub_carrier_spacing_common_opts::scs15or60; - cfg_default.mib.ssb_subcarrier_offset = 0; - cfg_default.mib.intra_freq_resel.value = mib_s::intra_freq_resel_opts::allowed; - cfg_default.mib.cell_barred.value = mib_s::cell_barred_opts::not_barred; - cfg_default.mib.pdcch_cfg_sib1.search_space_zero = 0; - cfg_default.mib.pdcch_cfg_sib1.ctrl_res_set_zero = 0; - cfg_default.mib.dmrs_type_a_position.value = mib_s::dmrs_type_a_position_opts::pos2; - cfg_default.mib.sys_frame_num.from_number(0); - - // Fill SIB1 - cfg_default.sib1.cell_access_related_info.plmn_id_list.resize(1); - cfg_default.sib1.cell_access_related_info.plmn_id_list[0].plmn_id_list.resize(1); - srsran::plmn_id_t plmn; - plmn.from_string("90170"); - srsran::to_asn1(&cfg_default.sib1.cell_access_related_info.plmn_id_list[0].plmn_id_list[0], plmn); - cfg_default.sib1.cell_access_related_info.plmn_id_list[0].cell_id.from_number(1); - cfg_default.sib1.cell_access_related_info.plmn_id_list[0].cell_reserved_for_oper.value = - plmn_id_info_s::cell_reserved_for_oper_opts::not_reserved; - cfg_default.sib1.si_sched_info_present = true; - cfg_default.sib1.si_sched_info.si_request_cfg.rach_occasions_si_present = true; - cfg_default.sib1.si_sched_info.si_request_cfg.rach_occasions_si.rach_cfg_si.ra_resp_win.value = - rach_cfg_generic_s::ra_resp_win_opts::sl8; - cfg_default.sib1.si_sched_info.si_win_len.value = si_sched_info_s::si_win_len_opts::s20; - cfg_default.sib1.si_sched_info.sched_info_list.resize(1); - cfg_default.sib1.si_sched_info.sched_info_list[0].si_broadcast_status.value = - sched_info_s::si_broadcast_status_opts::broadcasting; - cfg_default.sib1.si_sched_info.sched_info_list[0].si_periodicity.value = sched_info_s::si_periodicity_opts::rf16; - cfg_default.sib1.si_sched_info.sched_info_list[0].sib_map_info.resize(1); - // scheduling of SI messages - cfg_default.sib1.si_sched_info.sched_info_list[0].sib_map_info[0].type.value = sib_type_info_s::type_opts::sib_type2; - cfg_default.sib1.si_sched_info.sched_info_list[0].sib_map_info[0].value_tag_present = true; - cfg_default.sib1.si_sched_info.sched_info_list[0].sib_map_info[0].value_tag = 0; - - // Fill SIB2+ - cfg_default.nof_sibs = 1; - sib2_s& sib2 = cfg_default.sibs[0].set_sib2(); - sib2.cell_resel_info_common.q_hyst.value = sib2_s::cell_resel_info_common_s_::q_hyst_opts::db5; - // TODO: Fill SIB2 values - - return cfg_default; -} - -/* @brief PRIVATE function, gets called by sgnb_addition_request - * - * This function WILL NOT TRIGGER the RX MSG3 activity timer - */ -int rrc_nr::add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg, bool start_msg3_timer) -{ - if (users.count(rnti) == 0) { - // If in the ue ctor, "start_msg3_timer" is set to true, this will start the MSG3 RX TIMEOUT at ue creation - users.insert(std::make_pair(rnti, std::unique_ptr(new ue(this, rnti, uecfg, start_msg3_timer)))); - rlc->add_user(rnti); - pdcp->add_user(rnti); - logger.info("Added new user rnti=0x%x", rnti); - return SRSRAN_SUCCESS; - } else { - logger.error("Adding user rnti=0x%x (already exists)", rnti); - return SRSRAN_ERROR; - } -} - -/* @brief PUBLIC function, gets called by mac_nr::rach_detected - * - * This function is called from PRACH worker (can wait) and WILL TRIGGER the RX MSG3 activity timer - */ -int rrc_nr::add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg) -{ - // Set "triggered_by_rach" to true to start the MSG3 RX TIMEOUT - return add_user(rnti, uecfg, true); -} - -void rrc_nr::rem_user(uint16_t rnti) -{ - auto user_it = users.find(rnti); - if (user_it != users.end()) { - // First remove MAC and GTPU to stop processing DL/UL traffic for this user - mac->remove_ue(rnti); // MAC handles PHY - rlc->rem_user(rnti); - pdcp->rem_user(rnti); - users.erase(rnti); - - srsran::console("Disconnecting rnti=0x%x.\n", rnti); - logger.info("Removed user rnti=0x%x", rnti); - } else { - logger.error("Removing user rnti=0x%x (does not exist)", rnti); - } -} - -/* Function called by MAC after the reception of a C-RNTI CE indicating that the UE still has a - * valid RNTI. - */ -int rrc_nr::update_user(uint16_t new_rnti, uint16_t old_rnti) -{ - if (new_rnti == old_rnti) { - logger.warning("rnti=0x%x received MAC CRNTI CE with same rnti", new_rnti); - return SRSRAN_ERROR; - } - - // Remove new_rnti - auto new_ue_it = users.find(new_rnti); - if (new_ue_it != users.end()) { - new_ue_it->second->deactivate_bearers(); - task_sched.defer_task([this, new_rnti]() { rem_user(new_rnti); }); - } - - // Send Reconfiguration to old_rnti if is RRC_CONNECT or RRC Release if already released here - auto old_it = users.find(old_rnti); - if (old_it == users.end()) { - logger.info("rnti=0x%x received MAC CRNTI CE: 0x%x, but old context is unavailable", new_rnti, old_rnti); - return SRSRAN_ERROR; - } - ue* ue_ptr = old_it->second.get(); - - logger.info("Resuming rnti=0x%x RRC connection due to received C-RNTI CE from rnti=0x%x.", old_rnti, new_rnti); - ue_ptr->crnti_ce_received(); - - return SRSRAN_SUCCESS; -} - -void rrc_nr::set_activity_user(uint16_t rnti) -{ - auto it = users.find(rnti); - if (it == users.end()) { - logger.info("rnti=0x%x not found. Can't set activity", rnti); - return; - } - ue* ue_ptr = it->second.get(); - - // inform EUTRA RRC about user activity - if (ue_ptr->is_endc()) { - // Restart inactivity timer for RRC-NR - ue_ptr->set_activity(); - // inform EUTRA RRC about user activity - rrc_eutra->set_activity_user(ue_ptr->get_eutra_rnti()); - } -} - -void rrc_nr::config_phy() -{ - srsenb::phy_interface_rrc_nr::common_cfg_t common_cfg = {}; - common_cfg.carrier = cfg.cell_list[0].phy_cell.carrier; - common_cfg.pdcch = cfg.cell_list[0].phy_cell.pdcch; - common_cfg.prach = cfg.cell_list[0].phy_cell.prach; - common_cfg.duplex_mode = cfg.cell_list[0].duplex_mode; - common_cfg.ssb = cfg.cell_list[0].ssb_cfg; - if (phy->set_common_cfg(common_cfg) < SRSRAN_SUCCESS) { - logger.error("Couldn't set common PHY config"); - return; - } -} - -void rrc_nr::config_mac() -{ - // Fill MAC scheduler configuration for SIBs - // TODO: use parsed cell NR cfg configuration - std::vector sched_cells_cfg = {srsenb::get_default_cells_cfg(1)}; - sched_nr_interface::cell_cfg_t& cell = sched_cells_cfg[0]; - - // Derive cell config from rrc_nr_cfg_t - cell.bwps[0].pdcch = cfg.cell_list[0].phy_cell.pdcch; - // Derive cell config from ASN1 - bool ret2 = srsran::make_pdsch_cfg_from_serv_cell(base_sp_cell_cfg.sp_cell_cfg_ded, &cell.bwps[0].pdsch); - srsran_assert(ret2, "Invalid NR cell configuration."); - ret2 = srsran::make_phy_ssb_cfg( - cfg.cell_list[0].phy_cell.carrier, base_sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, &cell.ssb); - srsran_assert(ret2, "Invalid NR cell configuration."); - ret2 = srsran::make_duplex_cfg_from_serv_cell(base_sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, &cell.duplex); - srsran_assert(ret2, "Invalid NR cell configuration."); - - // FIXME: entire SI configuration, etc needs to be ported to NR - sched_interface::cell_cfg_t cell_cfg; - set_sched_cell_cfg_sib1(&cell_cfg, cfg.sib1); - - // set SIB length - for (uint32_t i = 0; i < nof_si_messages + 1; i++) { - cell_cfg.sibs[i].len = sib_buffer[i]->N_bytes; - } - - // PUCCH width - cell_cfg.nrb_pucch = SRSRAN_MAX(cfg.sr_cfg.nof_prb, /* TODO: where is n_rb2 in NR? */ 0); - logger.info("Allocating %d PRBs for PUCCH", cell_cfg.nrb_pucch); - - // Copy Cell configuration - // cell_cfg.cell = cfg.cell; - - // Configure MAC/scheduler - mac->cell_cfg(sched_cells_cfg); -} - -int32_t rrc_nr::generate_sibs() -{ - // MIB packing - bcch_bch_msg_s mib_msg; - mib_s& mib = mib_msg.msg.set_mib(); - mib = cfg.mib; - { - srsran::unique_byte_buffer_t mib_buf = srsran::make_byte_buffer(); - if (mib_buf == nullptr) { - logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); - return SRSRAN_ERROR; - } - asn1::bit_ref bref(mib_buf->msg, mib_buf->get_tailroom()); - if (mib_msg.pack(bref) != asn1::SRSASN_SUCCESS) { - logger.error("Couldn't pack mib msg"); - return SRSRAN_ERROR; - } - mib_buf->N_bytes = bref.distance_bytes(); - logger.debug(mib_buf->msg, mib_buf->N_bytes, "MIB payload (%d B)", mib_buf->N_bytes); - mib_buffer = std::move(mib_buf); - } - - si_sched_info_s::sched_info_list_l_& sched_info = cfg.sib1.si_sched_info.sched_info_list; - uint32_t nof_messages = cfg.sib1.si_sched_info_present ? cfg.sib1.si_sched_info.sched_info_list.size() : 0; - - // msg is array of SI messages, each SI message msg[i] may contain multiple SIBs - // all SIBs in a SI message msg[i] share the same periodicity - sib_buffer.reserve(nof_messages + 1); - asn1::dyn_array msg(nof_messages + 1); - - // Copy SIB1 to first SI message - msg[0].msg.set_c1().set_sib_type1() = cfg.sib1; - - // Copy rest of SIBs - for (uint32_t sched_info_elem = 0; sched_info_elem < nof_messages; sched_info_elem++) { - uint32_t msg_index = sched_info_elem + 1; // first msg is SIB1, therefore start with second - - msg[msg_index].msg.set_c1().set_sys_info().crit_exts.set_sys_info(); - auto& sib_list = msg[msg_index].msg.c1().sys_info().crit_exts.sys_info().sib_type_and_info; - - for (uint32_t mapping = 0; mapping < sched_info[sched_info_elem].sib_map_info.size(); ++mapping) { - uint32_t sibidx = sched_info[sched_info_elem].sib_map_info[mapping].type; // SIB2 == 0 - sib_list.push_back(cfg.sibs[sibidx]); - } - } - - // Pack payload for all messages - for (uint32_t msg_index = 0; msg_index < nof_messages + 1; msg_index++) { - srsran::unique_byte_buffer_t sib = srsran::make_byte_buffer(); - if (sib == nullptr) { - logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); - return SRSRAN_ERROR; - } - asn1::bit_ref bref(sib->msg, sib->get_tailroom()); - if (msg[msg_index].pack(bref) != asn1::SRSASN_SUCCESS) { - logger.error("Failed to pack SIB message %d", msg_index); - return SRSRAN_ERROR; - } - sib->N_bytes = bref.distance_bytes(); - sib_buffer.push_back(std::move(sib)); - - // Log SIBs in JSON format - fmt::memory_buffer strbuf; - fmt::format_to(strbuf, "SI message={} payload", msg_index); - log_rrc_message(fmt::to_string(strbuf), Tx, sib_buffer.back().get(), msg[msg_index]); - } - - nof_si_messages = sib_buffer.size() - 1; - - return SRSRAN_SUCCESS; -} - -/******************************************************************************* - MAC interface -*******************************************************************************/ - -int rrc_nr::read_pdu_bcch_bch(const uint32_t tti, srsran::unique_byte_buffer_t& buffer) -{ - if (mib_buffer == nullptr || buffer->get_tailroom() < mib_buffer->N_bytes) { - return SRSRAN_ERROR; - } - memcpy(buffer->msg, mib_buffer->msg, mib_buffer->N_bytes); - buffer->N_bytes = mib_buffer->N_bytes; - return SRSRAN_SUCCESS; -} - -int rrc_nr::read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) -{ - if (sib_index >= sib_buffer.size()) { - logger.error("SIB %d is not a configured SIB.", sib_index); - return SRSRAN_ERROR; - } - - if (buffer->get_tailroom() < sib_buffer[sib_index]->N_bytes) { - logger.error("Not enough space to fit SIB %d into buffer (%d < %d)", - sib_index, - buffer->get_tailroom(), - sib_buffer[sib_index]->N_bytes); - return SRSRAN_ERROR; - } - - memcpy(buffer->msg, sib_buffer[sib_index]->msg, sib_buffer[sib_index]->N_bytes); - buffer->N_bytes = sib_buffer[sib_index]->N_bytes; - - return SRSRAN_SUCCESS; -} - -void rrc_nr::get_metrics(srsenb::rrc_metrics_t& m) -{ - if (running) { - for (auto& ue : users) { - rrc_ue_metrics_t ue_metrics; - ue.second->get_metrics(ue_metrics); - m.ues.push_back(ue_metrics); - } - } -} - -void rrc_nr::handle_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) -{ - if (pdu) { - logger.info(pdu->msg, pdu->N_bytes, "Rx %s PDU", get_rb_name(lcid)); - } - - if (users.count(rnti) == 1) { - switch (static_cast(lcid)) { - case srsran::nr_srb::srb0: - // parse_ul_ccch(rnti, std::move(pdu)); - break; - case srsran::nr_srb::srb1: - case srsran::nr_srb::srb2: - // parse_ul_dcch(p.rnti, p.lcid, std::move(p.pdu)); - break; - default: - logger.error("Rx PDU with invalid bearer id: %d", lcid); - break; - } - } else { - logger.warning("Discarding PDU for removed rnti=0x%x", rnti); - } -} - -/******************************************************************************* - PDCP interface -*******************************************************************************/ -void rrc_nr::write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) -{ - handle_pdu(rnti, lcid, std::move(pdu)); -} - -void rrc_nr::notify_pdcp_integrity_error(uint16_t rnti, uint32_t lcid) {} - -/******************************************************************************* - NGAP interface -*******************************************************************************/ - -int rrc_nr::ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) -{ - return SRSRAN_SUCCESS; -} -int rrc_nr::ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) -{ - return SRSRAN_SUCCESS; -} -int rrc_nr::set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) -{ - return SRSRAN_SUCCESS; -} -int rrc_nr::ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) -{ - return SRSRAN_SUCCESS; -} -int rrc_nr::start_security_mode_procedure(uint16_t rnti) -{ - return SRSRAN_SUCCESS; -} -int rrc_nr::establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) -{ - return SRSRAN_SUCCESS; -} - -int rrc_nr::release_bearers(uint16_t rnti) -{ - return SRSRAN_SUCCESS; -} - -int rrc_nr::allocate_lcid(uint16_t rnti) -{ - return SRSRAN_SUCCESS; -} - -void rrc_nr::write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {} - -/******************************************************************************* - Interface for EUTRA RRC -*******************************************************************************/ - -void rrc_nr::sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) -{ - // try to allocate new user - sched_nr_ue_cfg_t uecfg{}; - uecfg.carriers.resize(1); - uecfg.carriers[0].active = true; - uecfg.carriers[0].cc = 0; - uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; - srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{}; - ref_args.duplex = cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_TDD - ? srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4 - : srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; - uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{ref_args}; - uecfg.phy_cfg.csi = {}; // disable CSI until RA is complete - - uint16_t nr_rnti = mac->reserve_rnti(0, uecfg); - if (nr_rnti == SRSRAN_INVALID_RNTI) { - logger.error("Failed to allocate RNTI at MAC"); - rrc_eutra->sgnb_addition_reject(eutra_rnti); - return; - } - - if (add_user(nr_rnti, uecfg, false) != SRSRAN_SUCCESS) { - logger.error("Failed to allocate RNTI at RRC"); - rrc_eutra->sgnb_addition_reject(eutra_rnti); - return; - } - - // new RNTI is now registered at MAC and RRC - auto user_it = users.find(nr_rnti); - if (user_it == users.end()) { - logger.warning("Unrecognised rnti: 0x%x", nr_rnti); - return; - } - user_it->second->handle_sgnb_addition_request(eutra_rnti, params); -} - -void rrc_nr::sgnb_reconfiguration_complete(uint16_t eutra_rnti, const asn1::dyn_octstring& reconfig_response) -{ - // user has completeted the reconfiguration and has acked on 4G side, wait until RA on NR - logger.info("Received Reconfiguration complete for RNTI=0x%x", eutra_rnti); -} - -void rrc_nr::sgnb_release_request(uint16_t nr_rnti) -{ - // remove user - auto it = users.find(nr_rnti); - uint16_t eutra_rnti = it != users.end() ? it->second->get_eutra_rnti() : SRSRAN_INVALID_RNTI; - rem_user(nr_rnti); - if (eutra_rnti != SRSRAN_INVALID_RNTI) { - rrc_eutra->sgnb_release_ack(eutra_rnti); - } -} - -/******************************************************************************* - UE class - - Every function in UE class is called from a mutex environment thus does not - need extra protection. -*******************************************************************************/ -rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg_, bool start_msg3_timer) : - parent(parent_), rnti(rnti_), uecfg(uecfg_) -{ - // Derive UE cfg from rrc_cfg_nr_t - uecfg.phy_cfg.pdcch = parent->cfg.cell_list[0].phy_cell.pdcch; - - // Set timer for MSG3_RX_TIMEOUT or UE_INACTIVITY_TIMEOUT - activity_timer = parent->task_sched.get_unique_timer(); - start_msg3_timer ? set_activity_timeout(MSG3_RX_TIMEOUT) : set_activity_timeout(MSG5_RX_TIMEOUT); -} - -void rrc_nr::ue::set_activity_timeout(activity_timeout_type_t type) -{ - uint32_t deadline_ms = 0; - - switch (type) { - case MSG3_RX_TIMEOUT: - // TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 100ms - deadline_ms = 100; - break; - case MSG5_RX_TIMEOUT: - // TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 1s - deadline_ms = 5000; - break; - case UE_INACTIVITY_TIMEOUT: - // TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 5s - deadline_ms = 10000; - break; - default: - parent->logger.error("Unknown timeout type %d", type); - return; - } - - activity_timer.set(deadline_ms, [this, type](uint32_t tid) { activity_timer_expired(type); }); - parent->logger.debug("Setting timer for %s for rnti=0x%x to %dms", to_string(type).c_str(), rnti, deadline_ms); - - set_activity(); -} - -void rrc_nr::ue::set_activity(bool enabled) -{ - if (not enabled) { - if (activity_timer.is_running()) { - parent->logger.debug("Inactivity timer interrupted for rnti=0x%x", rnti); - } - activity_timer.stop(); - return; - } - - // re-start activity timer with current timeout value - activity_timer.run(); - parent->logger.debug("Activity registered for rnti=0x%x (timeout_value=%dms)", rnti, activity_timer.duration()); -} - -void rrc_nr::ue::activity_timer_expired(const activity_timeout_type_t type) -{ - parent->logger.info("Activity timer for rnti=0x%x expired after %d ms", rnti, activity_timer.time_elapsed()); - - switch (type) { - case MSG5_RX_TIMEOUT: - case UE_INACTIVITY_TIMEOUT: - state = rrc_nr_state_t::RRC_INACTIVE; - parent->rrc_eutra->sgnb_inactivity_timeout(eutra_rnti); - break; - case MSG3_RX_TIMEOUT: { - // MSG3 timeout, no need to notify NGAP or LTE stack. Just remove UE - state = rrc_nr_state_t::RRC_IDLE; - uint32_t rnti_to_rem = rnti; - parent->task_sched.defer_task([this, rnti_to_rem]() { parent->rem_user(rnti_to_rem); }); - break; - } - default: - // Unhandled activity timeout, just remove UE and log an error - parent->rem_user(rnti); - parent->logger.error( - "Unhandled reason for activity timer expiration. rnti=0x%x, cause %d", rnti, static_cast(type)); - } -} - -std::string rrc_nr::ue::to_string(const activity_timeout_type_t& type) -{ - constexpr static const char* options[] = {"Msg3 reception", "UE inactivity", "Msg5 reception"}; - return srsran::enum_to_text(options, (uint32_t)activity_timeout_type_t::nulltype, (uint32_t)type); -} - -void rrc_nr::ue::send_connection_setup() -{ - dl_ccch_msg_s dl_ccch_msg; - dl_ccch_msg.msg.set_c1().set_rrc_setup().rrc_transaction_id = ((transaction_id++) % 4u); - rrc_setup_ies_s& setup = dl_ccch_msg.msg.c1().rrc_setup().crit_exts.set_rrc_setup(); - radio_bearer_cfg_s& rr_cfg = setup.radio_bearer_cfg; - - // Add DRB1 to cfg - rr_cfg.drb_to_add_mod_list_present = true; - rr_cfg.drb_to_add_mod_list.resize(1); - auto& drb_item = rr_cfg.drb_to_add_mod_list[0]; - drb_item.drb_id = 1; - drb_item.pdcp_cfg_present = true; - drb_item.pdcp_cfg.ciphering_disabled_present = true; - // drb_item.cn_assoc_present = true; - // drb_item.cn_assoc.set_eps_bearer_id() = ; - drb_item.recover_pdcp_present = false; - - // TODO: send config to RLC/PDCP - - send_dl_ccch(&dl_ccch_msg); -} - -void rrc_nr::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg) -{ - // Allocate a new PDU buffer, pack the message and send to PDCP - srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); - if (pdu == nullptr) { - parent->logger.error("Allocating pdu"); - } - asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); - if (dl_ccch_msg->pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { - parent->logger.error("Failed to pack DL-CCCH message. Discarding msg."); - } - pdu->N_bytes = bref.distance_bytes(); - - char buf[32] = {}; - sprintf(buf, "SRB0 - rnti=0x%x", rnti); - parent->log_rrc_message(buf, Tx, pdu.get(), *dl_ccch_msg); - parent->rlc->write_sdu(rnti, (uint32_t)srsran::nr_srb::srb0, std::move(pdu)); -} - -int rrc_nr::ue::pack_secondary_cell_group_rlc_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // RLC for DRB1 (with fixed LCID) - cell_group_cfg_pack.rlc_bearer_to_add_mod_list_present = true; - cell_group_cfg_pack.rlc_bearer_to_add_mod_list.resize(1); - auto& rlc_bearer = cell_group_cfg_pack.rlc_bearer_to_add_mod_list[0]; - rlc_bearer.lc_ch_id = drb1_lcid; - rlc_bearer.served_radio_bearer_present = true; - rlc_bearer.served_radio_bearer.set_drb_id(); - rlc_bearer.served_radio_bearer.drb_id() = 1; - rlc_bearer.rlc_cfg_present = true; - rlc_bearer.rlc_cfg.set_um_bi_dir(); - rlc_bearer.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len_present = true; - rlc_bearer.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len = sn_field_len_um_opts::size12; - rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len_present = true; - rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len = sn_field_len_um_opts::size12; - rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.t_reassembly = t_reassembly_opts::ms50; - - // MAC logical channel config - rlc_bearer.mac_lc_ch_cfg_present = true; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params_present = true; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.prio = 11; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.prioritised_bit_rate = - asn1::rrc_nr::lc_ch_cfg_s::ul_specific_params_s_::prioritised_bit_rate_opts::kbps0; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.bucket_size_dur = - asn1::rrc_nr::lc_ch_cfg_s::ul_specific_params_s_::bucket_size_dur_opts::ms100; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.lc_ch_group_present = true; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.lc_ch_group = 6; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.sched_request_id_present = true; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0; - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_secondary_cell_group_mac_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // mac-CellGroup-Config for BSR and SR - cell_group_cfg_pack.mac_cell_group_cfg_present = true; - auto& mac_cell_group = cell_group_cfg_pack.mac_cell_group_cfg; - mac_cell_group.sched_request_cfg_present = true; - mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list_present = true; - mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list.resize(1); - mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list[0].sched_request_id = 0; - mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list[0].sr_trans_max = - asn1::rrc_nr::sched_request_to_add_mod_s::sr_trans_max_opts::n64; - mac_cell_group.bsr_cfg_present = true; - mac_cell_group.bsr_cfg.periodic_bsr_timer = asn1::rrc_nr::bsr_cfg_s::periodic_bsr_timer_opts::sf20; - mac_cell_group.bsr_cfg.retx_bsr_timer = asn1::rrc_nr::bsr_cfg_s::retx_bsr_timer_opts::sf320; - - // Skip TAG and PHR config - mac_cell_group.tag_cfg_present = false; - mac_cell_group.tag_cfg.tag_to_add_mod_list_present = true; - mac_cell_group.tag_cfg.tag_to_add_mod_list.resize(1); - mac_cell_group.tag_cfg.tag_to_add_mod_list[0].tag_id = 0; - mac_cell_group.tag_cfg.tag_to_add_mod_list[0].time_align_timer = time_align_timer_opts::infinity; - - mac_cell_group.phr_cfg_present = false; - mac_cell_group.phr_cfg.set_setup(); - mac_cell_group.phr_cfg.setup().phr_periodic_timer = asn1::rrc_nr::phr_cfg_s::phr_periodic_timer_opts::sf500; - mac_cell_group.phr_cfg.setup().phr_prohibit_timer = asn1::rrc_nr::phr_cfg_s::phr_prohibit_timer_opts::sf200; - mac_cell_group.phr_cfg.setup().phr_tx_pwr_factor_change = asn1::rrc_nr::phr_cfg_s::phr_tx_pwr_factor_change_opts::db3; - mac_cell_group.phr_cfg.setup().multiple_phr = true; - mac_cell_group.phr_cfg.setup().dummy = false; - mac_cell_group.phr_cfg.setup().phr_type2_other_cell = false; - mac_cell_group.phr_cfg.setup().phr_mode_other_cg = asn1::rrc_nr::phr_cfg_s::phr_mode_other_cg_opts::real; - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp_present = true; - - pack_sp_cell_cfg_ded_init_dl_bwp_pdsch_cfg(cell_group_cfg_pack); - pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring(cell_group_cfg_pack); - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.radio_link_monitoring_cfg_present = true; - auto& radio_link_monitoring = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.radio_link_monitoring_cfg; - radio_link_monitoring.set_setup().fail_detection_res_to_add_mod_list_present = true; - - // add resource to detect RLF - radio_link_monitoring.set_setup().fail_detection_res_to_add_mod_list.resize(1); - auto& fail_detec_res_elem = radio_link_monitoring.set_setup().fail_detection_res_to_add_mod_list[0]; - fail_detec_res_elem.radio_link_monitoring_rs_id = 0; - fail_detec_res_elem.purpose = asn1::rrc_nr::radio_link_monitoring_rs_s::purpose_opts::rlf; - fail_detec_res_elem.detection_res.set_ssb_idx() = 0; - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp_pdsch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg_present = true; - auto& pdsch_cfg_dedicated = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg; - - pdsch_cfg_dedicated.set_setup(); - pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a_present = true; - pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a.set_setup(); - pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position_present = true; - pdsch_cfg_dedicated.setup().dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position = - asn1::rrc_nr::dmrs_dl_cfg_s::dmrs_add_position_opts::pos1; - pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list_present = true; - pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list.resize(1); - pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].tci_state_id = 0; - pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].qcl_type1.ref_sig.set_ssb(); - pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].qcl_type1.ref_sig.ssb() = 0; - pdsch_cfg_dedicated.setup().tci_states_to_add_mod_list[0].qcl_type1.qcl_type = - asn1::rrc_nr::qcl_info_s::qcl_type_opts::type_d; - pdsch_cfg_dedicated.setup().res_alloc = pdsch_cfg_s::res_alloc_opts::res_alloc_type1; - pdsch_cfg_dedicated.setup().rbg_size = asn1::rrc_nr::pdsch_cfg_s::rbg_size_opts::cfg1; - pdsch_cfg_dedicated.setup().prb_bundling_type.set_static_bundling(); - pdsch_cfg_dedicated.setup().prb_bundling_type.static_bundling().bundle_size_present = true; - pdsch_cfg_dedicated.setup().prb_bundling_type.static_bundling().bundle_size = - asn1::rrc_nr::pdsch_cfg_s::prb_bundling_type_c_::static_bundling_s_::bundle_size_opts::wideband; - - // ZP-CSI - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list_present = false; - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list.resize(1); - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].zp_csi_rs_res_id = 0; - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.set_row4(); - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.row4().from_number(0b100); - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.nrof_ports = - asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p4; - - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.first_ofdm_symbol_in_time_domain = 8; - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.cdm_type = - asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::fd_cdm2; - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.density.set_one(); - - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.start_rb = 0; - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.nrof_rbs = 52; - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset_present = true; - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset.set_slots80(); - pdsch_cfg_dedicated.setup().zp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset.slots80() = 1; - pdsch_cfg_dedicated.setup().p_zp_csi_rs_res_set_present = false; - pdsch_cfg_dedicated.setup().p_zp_csi_rs_res_set.set_setup(); - pdsch_cfg_dedicated.setup().p_zp_csi_rs_res_set.setup().zp_csi_rs_res_set_id = 0; - pdsch_cfg_dedicated.setup().p_zp_csi_rs_res_set.setup().zp_csi_rs_res_id_list.resize(1); - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pucch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // PUCCH - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pucch_cfg_present = true; - auto& pucch_cfg = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pucch_cfg; - - pucch_cfg.set_setup(); - pucch_cfg.setup().format2_present = true; - pucch_cfg.setup().format2.set_setup(); - pucch_cfg.setup().format2.setup().max_code_rate_present = true; - pucch_cfg.setup().format2.setup().max_code_rate = pucch_max_code_rate_opts::zero_dot25; - - // SR resources - pucch_cfg.setup().sched_request_res_to_add_mod_list_present = true; - pucch_cfg.setup().sched_request_res_to_add_mod_list.resize(1); - auto& sr_res1 = pucch_cfg.setup().sched_request_res_to_add_mod_list[0]; - sr_res1.sched_request_res_id = 1; - sr_res1.sched_request_id = 0; - sr_res1.periodicity_and_offset_present = true; - sr_res1.periodicity_and_offset.set_sl40() = 8; - sr_res1.res_present = true; - sr_res1.res = 2; // PUCCH resource for SR - - // DL data - pucch_cfg.setup().dl_data_to_ul_ack_present = true; - - if (parent->cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - pucch_cfg.setup().dl_data_to_ul_ack.resize(1); - pucch_cfg.setup().dl_data_to_ul_ack[0] = 4; - } else { - pucch_cfg.setup().dl_data_to_ul_ack.resize(6); - pucch_cfg.setup().dl_data_to_ul_ack[0] = 6; - pucch_cfg.setup().dl_data_to_ul_ack[1] = 5; - pucch_cfg.setup().dl_data_to_ul_ack[2] = 4; - pucch_cfg.setup().dl_data_to_ul_ack[3] = 4; - pucch_cfg.setup().dl_data_to_ul_ack[4] = 4; - pucch_cfg.setup().dl_data_to_ul_ack[5] = 4; - } - - // PUCCH Resource for format 1 - srsran_pucch_nr_resource_t resource_small = {}; - resource_small.starting_prb = 0; - resource_small.format = SRSRAN_PUCCH_NR_FORMAT_1; - resource_small.initial_cyclic_shift = 0; - resource_small.nof_symbols = 14; - resource_small.start_symbol_idx = 0; - resource_small.time_domain_occ = 0; - - // PUCCH Resource for format 2 - srsran_pucch_nr_resource_t resource_big = {}; - resource_big.starting_prb = 51; - resource_big.format = SRSRAN_PUCCH_NR_FORMAT_2; - resource_big.nof_prb = 1; - resource_big.nof_symbols = 2; - resource_big.start_symbol_idx = 12; - - // Resource for SR - srsran_pucch_nr_resource_t resource_sr = {}; - resource_sr.starting_prb = 51; - resource_sr.format = SRSRAN_PUCCH_NR_FORMAT_1; - resource_sr.initial_cyclic_shift = 0; - resource_sr.nof_symbols = 14; - resource_sr.start_symbol_idx = 0; - resource_sr.time_domain_occ = 0; - - // Make 3 possible resources - pucch_cfg.setup().res_to_add_mod_list_present = true; - pucch_cfg.setup().res_to_add_mod_list.resize(3); - if (not srsran::make_phy_res_config(resource_small, pucch_cfg.setup().res_to_add_mod_list[0], 0)) { - parent->logger.warning("Failed to create 1-2 bit NR PUCCH resource"); - } - if (not srsran::make_phy_res_config(resource_big, pucch_cfg.setup().res_to_add_mod_list[1], 1)) { - parent->logger.warning("Failed to create >2 bit NR PUCCH resource"); - } - if (not srsran::make_phy_res_config(resource_sr, pucch_cfg.setup().res_to_add_mod_list[2], 2)) { - parent->logger.warning("Failed to create SR NR PUCCH resource"); - } - - // Make 2 PUCCH resource sets - pucch_cfg.setup().res_set_to_add_mod_list_present = true; - pucch_cfg.setup().res_set_to_add_mod_list.resize(2); - - // Make PUCCH resource set for 1-2 bit - pucch_cfg.setup().res_set_to_add_mod_list[0].pucch_res_set_id = 0; - pucch_cfg.setup().res_set_to_add_mod_list[0].res_list.resize(8); - for (auto& e : pucch_cfg.setup().res_set_to_add_mod_list[0].res_list) { - e = 0; - } - - // Make PUCCH resource set for >2 bit - pucch_cfg.setup().res_set_to_add_mod_list[1].pucch_res_set_id = 1; - pucch_cfg.setup().res_set_to_add_mod_list[1].res_list.resize(8); - for (auto& e : pucch_cfg.setup().res_set_to_add_mod_list[1].res_list) { - e = 1; - } - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pusch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // PUSCH config - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pusch_cfg_present = true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pusch_cfg.set_setup(); - auto& pusch_cfg_ded = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pusch_cfg.setup(); - - pusch_cfg_ded.dmrs_ul_for_pusch_map_type_a_present = true; - pusch_cfg_ded.dmrs_ul_for_pusch_map_type_a.set_setup(); - pusch_cfg_ded.dmrs_ul_for_pusch_map_type_a.setup().dmrs_add_position_present = true; - pusch_cfg_ded.dmrs_ul_for_pusch_map_type_a.setup().dmrs_add_position = dmrs_ul_cfg_s::dmrs_add_position_opts::pos1; - // PUSH power control skipped - pusch_cfg_ded.res_alloc = pusch_cfg_s::res_alloc_opts::res_alloc_type1; - - // UCI - pusch_cfg_ded.uci_on_pusch_present = true; - pusch_cfg_ded.uci_on_pusch.set_setup(); - pusch_cfg_ded.uci_on_pusch.setup().beta_offsets_present = true; - pusch_cfg_ded.uci_on_pusch.setup().beta_offsets.set_semi_static(); - auto& beta_offset_semi_static = pusch_cfg_ded.uci_on_pusch.setup().beta_offsets.semi_static(); - beta_offset_semi_static.beta_offset_ack_idx1_present = true; - beta_offset_semi_static.beta_offset_ack_idx1 = 9; - beta_offset_semi_static.beta_offset_ack_idx2_present = true; - beta_offset_semi_static.beta_offset_ack_idx2 = 9; - beta_offset_semi_static.beta_offset_ack_idx3_present = true; - beta_offset_semi_static.beta_offset_ack_idx3 = 9; - beta_offset_semi_static.beta_offset_csi_part1_idx1_present = true; - beta_offset_semi_static.beta_offset_csi_part1_idx1 = 6; - beta_offset_semi_static.beta_offset_csi_part1_idx2_present = true; - beta_offset_semi_static.beta_offset_csi_part1_idx2 = 6; - beta_offset_semi_static.beta_offset_csi_part2_idx1_present = true; - beta_offset_semi_static.beta_offset_csi_part2_idx1 = 6; - beta_offset_semi_static.beta_offset_csi_part2_idx2_present = true; - beta_offset_semi_static.beta_offset_csi_part2_idx2 = 6; - pusch_cfg_ded.uci_on_pusch.setup().scaling = uci_on_pusch_s::scaling_opts::f1; - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp_present = true; - - pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pucch_cfg(cell_group_cfg_pack); - pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pusch_cfg(cell_group_cfg_pack); - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_sp_cell_cfg_ded_ul_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // UL config dedicated - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg_present = true; - - pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp(cell_group_cfg_pack); - - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.first_active_ul_bwp_id_present = true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.first_active_ul_bwp_id = 0; - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_sp_cell_cfg_ded_pdcch_serving_cell_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdcch_serving_cell_cfg_present = true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdcch_serving_cell_cfg.set_setup(); - - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg_present = true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg.set_setup(); - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg.setup().nrof_harq_processes_for_pdsch_present = - true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg.setup().nrof_harq_processes_for_pdsch = - pdsch_serving_cell_cfg_s::nrof_harq_processes_for_pdsch_opts::n16; - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_sp_cell_cfg_ded(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // SP Cell Dedicated config - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded_present = true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id_present = true; - - if (parent->cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id = 0; - } else { - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id = 1; - } - - pack_sp_cell_cfg_ded_ul_cfg(cell_group_cfg_pack); - pack_sp_cell_cfg_ded_init_dl_bwp(cell_group_cfg_pack); - - // Serving cell config (only to setup) - pack_sp_cell_cfg_ded_pdcch_serving_cell_cfg(cell_group_cfg_pack); - - // spCellConfig - if (fill_sp_cell_cfg_from_enb_cfg(parent->cfg, UE_PSCELL_CC_IDX, cell_group_cfg_pack.sp_cell_cfg) != SRSRAN_SUCCESS) { - parent->logger.error("Failed to pack spCellConfig for rnti=0x%x", rnti); - } - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common_phy_cell_group_cfg( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - cell_group_cfg_pack.phys_cell_group_cfg_present = true; - cell_group_cfg_pack.phys_cell_group_cfg.pdsch_harq_ack_codebook = - phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts::dynamic_value; - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdsch_cfg_common( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // PDSCH config common - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp - .pdsch_cfg_common_present = true; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common - .set_setup(); - - auto& pdsch_cfg_common = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp - .pdsch_cfg_common.setup(); - pdsch_cfg_common.pdsch_time_domain_alloc_list_present = true; - pdsch_cfg_common.pdsch_time_domain_alloc_list.resize(1); - pdsch_cfg_common.pdsch_time_domain_alloc_list[0].map_type = pdsch_time_domain_res_alloc_s::map_type_opts::type_a; - pdsch_cfg_common.pdsch_time_domain_alloc_list[0].start_symbol_and_len = 40; - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp_present = true; - auto& init_dl_bwp = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp; - - init_dl_bwp.generic_params.location_and_bw = 14025; - init_dl_bwp.generic_params.subcarrier_spacing = subcarrier_spacing_opts::khz15; - - pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdsch_cfg_common(cell_group_cfg_pack); - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // DL config - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present = true; - - pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common_phy_cell_group_cfg(cell_group_cfg_pack); - pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp(cell_group_cfg_pack); - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp_pusch_cfg_common( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // PUSCH config common - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp - .pusch_cfg_common_present = true; - auto& pusch_cfg_common_pack = - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common; - pusch_cfg_common_pack.set_setup(); - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list_present = true; - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list.resize(2); - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].k2_present = true; - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].k2 = 4; - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].map_type = - asn1::rrc_nr::pusch_time_domain_res_alloc_s::map_type_opts::type_a; - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].start_symbol_and_len = 27; - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[1].k2_present = true; - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[1].k2 = 3; - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[1].map_type = - asn1::rrc_nr::pusch_time_domain_res_alloc_s::map_type_opts::type_a; - pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[1].start_symbol_and_len = 27; - pusch_cfg_common_pack.setup().p0_nominal_with_grant_present = true; - pusch_cfg_common_pack.setup().p0_nominal_with_grant = -60; - - // PUCCH config common - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp - .pucch_cfg_common_present = true; - auto& pucch_cfg_common_pack = - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.pucch_cfg_common; - pucch_cfg_common_pack.set_setup(); - pucch_cfg_common_pack.setup().pucch_group_hop = asn1::rrc_nr::pucch_cfg_common_s::pucch_group_hop_opts::neither; - pucch_cfg_common_pack.setup().p0_nominal_present = true; - pucch_cfg_common_pack.setup().p0_nominal = -60; - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp_present = true; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.generic_params - .location_and_bw = 14025; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.generic_params - .subcarrier_spacing = subcarrier_spacing_opts::khz15; - - pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp_pusch_cfg_common(cell_group_cfg_pack); - - return SRSRAN_ERROR; -} - -int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common( - asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // UL config - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common_present = true; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.dummy = time_align_timer_opts::ms500; - - pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp(cell_group_cfg_pack); - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - auto& pscell_cfg = parent->cfg.cell_list.at(UE_PSCELL_CC_IDX); - - if (pscell_cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.smtc.release(); - } - - // DL config - pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common(cell_group_cfg_pack); - - // UL config - pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common(cell_group_cfg_pack); - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_recfg_with_sync(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - // Reconfig with Sync - cell_group_cfg_pack.cell_group_id = 1; // 0 identifies the MCG. Other values identify SCGs. - - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync_present = true; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.new_ue_id = rnti; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.t304 = recfg_with_sync_s::t304_opts::ms1000; - - pack_recfg_with_sync_sp_cell_cfg_common(cell_group_cfg_pack); - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::pack_secondary_cell_group_sp_cell_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) -{ - cell_group_cfg_pack.sp_cell_cfg_present = true; - cell_group_cfg_pack.sp_cell_cfg.serv_cell_idx_present = true; - cell_group_cfg_pack.sp_cell_cfg.serv_cell_idx = 1; // Serving cell ID of a PSCell. The PCell of the MCG uses ID 0. - - pack_sp_cell_cfg_ded(cell_group_cfg_pack); - pack_recfg_with_sync(cell_group_cfg_pack); - - return SRSRAN_SUCCESS; -} - -// Helper for the RRC Reconfiguration sender to pack hard-coded config -int rrc_nr::ue::pack_secondary_cell_group_cfg(asn1::dyn_octstring& packed_secondary_cell_config) -{ - auto& cell_group_cfg_pack = cell_group_cfg; - - pack_secondary_cell_group_rlc_cfg(cell_group_cfg_pack); - pack_secondary_cell_group_mac_cfg(cell_group_cfg_pack); - pack_secondary_cell_group_sp_cell_cfg(cell_group_cfg_pack); - - // make sufficiant space - packed_secondary_cell_config.resize(256); - asn1::bit_ref bref_pack(packed_secondary_cell_config.data(), packed_secondary_cell_config.size()); - if (cell_group_cfg_pack.pack(bref_pack) != asn1::SRSASN_SUCCESS) { - parent->logger.error("Failed to pack NR secondary cell config"); - return SRSRAN_ERROR; - } - packed_secondary_cell_config.resize(bref_pack.distance_bytes()); - - return SRSRAN_SUCCESS; -} - -// Packs a hard-coded RRC Reconfiguration with fixed params for all layers (for now) -int rrc_nr::ue::pack_rrc_reconfiguration(asn1::dyn_octstring& packed_rrc_reconfig) -{ - rrc_recfg_s reconfig; - reconfig.rrc_transaction_id = ((transaction_id++) % 4u); - rrc_recfg_ies_s& recfg_ies = reconfig.crit_exts.set_rrc_recfg(); - - // add secondary cell group config - recfg_ies.secondary_cell_group_present = true; - - if (pack_secondary_cell_group_cfg(recfg_ies.secondary_cell_group) == SRSRAN_ERROR) { - parent->logger.error("Failed to pack secondary cell group"); - return SRSRAN_ERROR; - } - - // now pack .. - packed_rrc_reconfig.resize(512); - asn1::bit_ref bref_pack(packed_rrc_reconfig.data(), packed_rrc_reconfig.size()); - if (reconfig.pack(bref_pack) != asn1::SRSASN_SUCCESS) { - parent->logger.error("Failed to pack RRC Reconfiguration"); - return SRSRAN_ERROR; - } - packed_rrc_reconfig.resize(bref_pack.distance_bytes()); - - return SRSRAN_SUCCESS; -} - -// Packs a hard-coded NR radio bearer config with fixed params for RLC/PDCP (for now) -int rrc_nr::ue::pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_bearer_config) -{ - // set security config - auto& radio_bearer_cfg_pack = radio_bearer_cfg; - radio_bearer_cfg_pack.security_cfg_present = true; - auto& sec_cfg = radio_bearer_cfg_pack.security_cfg; - sec_cfg.key_to_use_present = true; - sec_cfg.key_to_use = asn1::rrc_nr::security_cfg_s::key_to_use_opts::secondary; - sec_cfg.security_algorithm_cfg_present = true; - sec_cfg.security_algorithm_cfg.ciphering_algorithm = ciphering_algorithm_opts::nea0; - sec_cfg.security_algorithm_cfg.integrity_prot_algorithm_present = true; - sec_cfg.security_algorithm_cfg.integrity_prot_algorithm = integrity_prot_algorithm_opts::nia0; - - // pack it - packed_nr_bearer_config.resize(128); - asn1::bit_ref bref_pack(packed_nr_bearer_config.data(), packed_nr_bearer_config.size()); - if (radio_bearer_cfg_pack.pack(bref_pack) != asn1::SRSASN_SUCCESS) { - parent->logger.error("Failed to pack NR radio bearer config"); - return SRSRAN_ERROR; - } - - // resize to packed length - packed_nr_bearer_config.resize(bref_pack.distance_bytes()); - - return SRSRAN_SUCCESS; -} - -int rrc_nr::ue::handle_sgnb_addition_request(uint16_t eutra_rnti_, const sgnb_addition_req_params_t& req_params) -{ - // Add DRB1 to RLC and PDCP - if (add_drb() != SRSRAN_SUCCESS) { - parent->logger.error("Failed to configure DRB"); - parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); - return SRSRAN_ERROR; - } - - // provide hard-coded NR configs - rrc_eutra_interface_rrc_nr::sgnb_addition_ack_params_t ack_params = {}; - if (pack_rrc_reconfiguration(ack_params.nr_secondary_cell_group_cfg_r15) == SRSRAN_ERROR) { - parent->logger.error("Failed to pack RRC Reconfiguration. Sending SgNB addition reject."); - parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); - return SRSRAN_ERROR; - } - - if (pack_nr_radio_bearer_config(ack_params.nr_radio_bearer_cfg1_r15) == SRSRAN_ERROR) { - parent->logger.error("Failed to pack NR radio bearer config. Sending SgNB addition reject."); - parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); - return SRSRAN_ERROR; - } - - // send response to EUTRA - ack_params.nr_rnti = rnti; - ack_params.eps_bearer_id = req_params.eps_bearer_id; - parent->rrc_eutra->sgnb_addition_ack(eutra_rnti_, ack_params); - - // recognize RNTI as ENDC user - endc = true; - eutra_rnti = eutra_rnti_; - - return SRSRAN_SUCCESS; -} - -void rrc_nr::ue::crnti_ce_received() -{ - // Assume NSA mode active - if (endc) { - // send SgNB addition complete for ENDC users - parent->rrc_eutra->sgnb_addition_complete(eutra_rnti, rnti); - - // stop RX MSG3/MSG5 activity timer on MAC CE RNTI reception - set_activity_timeout(UE_INACTIVITY_TIMEOUT); - parent->logger.debug("Received MAC CE-RNTI for 0x%x - stopping MSG3/MSG5 timer, starting inactivity timer", rnti); - - // Add DRB1 to MAC - for (auto& drb : cell_group_cfg.rlc_bearer_to_add_mod_list) { - uecfg.ue_bearers[drb.lc_ch_id].direction = mac_lc_ch_cfg_t::BOTH; - uecfg.ue_bearers[drb.lc_ch_id].group = drb.mac_lc_ch_cfg.ul_specific_params.lc_ch_group; - } - - // Update UE phy params - srsran::make_pdsch_cfg_from_serv_cell(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded, &uecfg.phy_cfg.pdsch); - srsran::make_csi_cfg_from_serv_cell(cell_group_cfg.sp_cell_cfg.sp_cell_cfg_ded, &uecfg.phy_cfg.csi); - srsran::make_phy_ssb_cfg(parent->cfg.cell_list[0].phy_cell.carrier, - cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, - &uecfg.phy_cfg.ssb); - srsran::make_duplex_cfg_from_serv_cell(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, - &uecfg.phy_cfg.duplex); - - parent->mac->ue_cfg(rnti, uecfg); - } -} - -/** - * @brief Set DRB configuration - * - * The function sets and configures all relavant fields for the DRB configuration (MAC, RLC, PDCP) in the - * cellGroupConfig and also adds the bearer to the local RLC and PDCP entities. - * - * @return int SRSRAN_SUCCESS on success - */ -int rrc_nr::ue::add_drb() -{ - // RLC for DRB1 (with fixed LCID) inside cell_group_cfg - auto& cell_group_cfg_pack = cell_group_cfg; - - cell_group_cfg_pack.rlc_bearer_to_add_mod_list_present = true; - cell_group_cfg_pack.rlc_bearer_to_add_mod_list.resize(1); - auto& rlc_bearer = cell_group_cfg_pack.rlc_bearer_to_add_mod_list[0]; - rlc_bearer.lc_ch_id = drb1_lcid; - rlc_bearer.served_radio_bearer_present = true; - rlc_bearer.served_radio_bearer.set_drb_id(); - rlc_bearer.served_radio_bearer.drb_id() = 1; - rlc_bearer.rlc_cfg_present = true; - rlc_bearer.rlc_cfg.set_um_bi_dir(); - rlc_bearer.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len_present = true; - rlc_bearer.rlc_cfg.um_bi_dir().ul_um_rlc.sn_field_len = sn_field_len_um_opts::size12; - rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len_present = true; - rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.sn_field_len = sn_field_len_um_opts::size12; - rlc_bearer.rlc_cfg.um_bi_dir().dl_um_rlc.t_reassembly = t_reassembly_opts::ms50; - - // add RLC bearer - srsran::rlc_config_t rlc_cfg; - if (srsran::make_rlc_config_t(cell_group_cfg.rlc_bearer_to_add_mod_list[0].rlc_cfg, &rlc_cfg) != SRSRAN_SUCCESS) { - parent->logger.error("Failed to build RLC config"); - return SRSRAN_ERROR; - } - parent->rlc->add_bearer(rnti, drb1_lcid, rlc_cfg); - - // MAC logical channel config - rlc_bearer.mac_lc_ch_cfg_present = true; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params_present = true; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.prio = 11; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.prioritised_bit_rate = - asn1::rrc_nr::lc_ch_cfg_s::ul_specific_params_s_::prioritised_bit_rate_opts::kbps0; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.bucket_size_dur = - asn1::rrc_nr::lc_ch_cfg_s::ul_specific_params_s_::bucket_size_dur_opts::ms100; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.lc_ch_group_present = true; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.lc_ch_group = 3; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.sched_request_id_present = true; - rlc_bearer.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0; - // TODO: add LC config to MAC - - // PDCP config goes into radio_bearer_cfg - auto& radio_bearer_cfg_pack = radio_bearer_cfg; - radio_bearer_cfg_pack.drb_to_add_mod_list_present = true; - radio_bearer_cfg_pack.drb_to_add_mod_list.resize(1); - - // configure fixed DRB1 - auto& drb_item = radio_bearer_cfg_pack.drb_to_add_mod_list[0]; - drb_item.drb_id = 1; - drb_item.cn_assoc_present = true; - drb_item.cn_assoc.set_eps_bearer_id() = 5; - drb_item.pdcp_cfg_present = true; - drb_item.pdcp_cfg.ciphering_disabled_present = true; - drb_item.pdcp_cfg.drb_present = true; - drb_item.pdcp_cfg.drb.pdcp_sn_size_dl_present = true; - drb_item.pdcp_cfg.drb.pdcp_sn_size_dl = asn1::rrc_nr::pdcp_cfg_s::drb_s_::pdcp_sn_size_dl_opts::len18bits; - drb_item.pdcp_cfg.drb.pdcp_sn_size_ul_present = true; - drb_item.pdcp_cfg.drb.pdcp_sn_size_ul = asn1::rrc_nr::pdcp_cfg_s::drb_s_::pdcp_sn_size_ul_opts::len18bits; - drb_item.pdcp_cfg.drb.discard_timer_present = true; - drb_item.pdcp_cfg.drb.discard_timer = asn1::rrc_nr::pdcp_cfg_s::drb_s_::discard_timer_opts::ms100; - drb_item.pdcp_cfg.drb.hdr_compress.set_not_used(); - drb_item.pdcp_cfg.t_reordering_present = true; - drb_item.pdcp_cfg.t_reordering = asn1::rrc_nr::pdcp_cfg_s::t_reordering_opts::ms0; - - // Add DRB1 to PDCP - srsran::pdcp_config_t pdcp_cnfg = srsran::make_drb_pdcp_config_t(drb_item.drb_id, false, drb_item.pdcp_cfg); - parent->pdcp->add_bearer(rnti, rlc_bearer.lc_ch_id, pdcp_cnfg); - - // Note: DRB1 is only activated in the MAC when the C-RNTI CE is received - - return SRSRAN_SUCCESS; -} - -/** - * @brief Deactivate all Bearers (MAC logical channel) for this specific RNTI - * - * The function iterates over the bearers or MAC logical channels and deactivates them by setting each one to IDLE - */ -void rrc_nr::ue::deactivate_bearers() -{ - // Iterate over the bearers (MAC LC CH) and set each of them to IDLE - for (auto& ue_bearer : uecfg.ue_bearers) { - ue_bearer.direction = mac_lc_ch_cfg_t::IDLE; - } - - // No need to check the returned value, as the function ue_cfg will return SRSRAN_SUCCESS (it asserts if it fails) - parent->mac->ue_cfg(rnti, uecfg); -} - -} // namespace srsenb diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 45c2d8f3c9..36f11594e5 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -52,7 +52,8 @@ rrc::ue::ue(rrc* outer_rrc, uint16_t rnti_, const sched_interface::ue_cfg_t& sch bearer_list(rnti_, parent->cfg, outer_rrc->gtpu), ue_security_cfg(parent->cfg), mac_ctrl(rnti, ue_cell_list, bearer_list, parent->cfg, parent->mac, *parent->cell_common_list, sched_ue_cfg) -{} +{ +} rrc::ue::~ue() {} @@ -221,7 +222,8 @@ void rrc::ue::activity_timer_expired(const activity_timeout_type_t type) con_release_result = procedure_result_code::activity_timeout; break; case MSG3_RX_TIMEOUT: - case MSG5_RX_TIMEOUT: + case MSG5_RX_TIMEOUT_T300: + case MSG5_RX_TIMEOUT_T301: // MSG3 timeout, no need to notify S1AP, just remove UE parent->rem_user_thread(rnti); con_release_result = procedure_result_code::msg3_timeout; @@ -301,7 +303,10 @@ void rrc::ue::set_activity_timeout(activity_timeout_type_t type) case UE_INACTIVITY_TIMEOUT: deadline_ms = parent->cfg.inactivity_timeout_ms; break; - case MSG5_RX_TIMEOUT: + case MSG5_RX_TIMEOUT_T300: + deadline_ms = get_ue_cc_cfg(UE_PCELL_CC_IDX)->sib2.ue_timers_and_consts.t300.to_number(); + break; + case MSG5_RX_TIMEOUT_T301: deadline_ms = get_ue_cc_cfg(UE_PCELL_CC_IDX)->sib2.ue_timers_and_consts.t301.to_number(); break; default: @@ -350,6 +355,7 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) case ul_dcch_msg_type_c::c1_c_::types::rrc_conn_setup_complete: save_ul_message(std::move(original_pdu)); handle_rrc_con_setup_complete(&ul_dcch_msg.msg.c1().rrc_conn_setup_complete(), std::move(pdu)); + set_activity_timeout(UE_INACTIVITY_TIMEOUT); set_activity(); break; case ul_dcch_msg_type_c::c1_c_::types::rrc_conn_reest_complete: @@ -429,7 +435,8 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) std::string rrc::ue::to_string(const activity_timeout_type_t& type) { - constexpr static const char* options[] = {"Msg3 reception", "UE inactivity", "UE reestablishment"}; + constexpr static const char* options[] = { + "Msg3 reception", "UE inactivity", "UE establishment", "UE reestablishment"}; return srsran::enum_to_text(options, (uint32_t)activity_timeout_type_t::nulltype, (uint32_t)type); } @@ -483,7 +490,7 @@ void rrc::ue::handle_rrc_con_req(rrc_conn_request_s* msg) send_connection_setup(); state = RRC_STATE_WAIT_FOR_CON_SETUP_COMPLETE; - set_activity_timeout(UE_INACTIVITY_TIMEOUT); + set_activity_timeout(MSG5_RX_TIMEOUT_T300); } void rrc::ue::send_connection_setup() @@ -644,20 +651,29 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) return; } - uint16_t old_pci = msg->crit_exts.rrc_conn_reest_request_r8().ue_id.pci; - const enb_cell_common* old_cell = parent->cell_common_list->get_pci(old_pci); - auto old_ue_it = parent->users.find(old_rnti); - - // Reject unrecognized rntis, and PCIs that do not belong to eNB - if (old_ue_it == parent->users.end() or old_cell == nullptr or - old_ue_it->second->ue_cell_list.get_enb_cc_idx(old_cell->enb_cc_idx) == nullptr) { - send_connection_reest_rej(procedure_result_code::error_unknown_rnti); - parent->logger.info( - "RRCReestablishmentReject for rnti=0x%x. Cause: no rnti=0x%x context available", rnti, old_rnti); - srsran::console("RRCReestablishmentReject for rnti=0x%x. Cause: no context available\n", rnti); - return; + uint16_t old_pci = msg->crit_exts.rrc_conn_reest_request_r8().ue_id.pci; + ue* old_ue = nullptr; + { + const enb_cell_common* old_cell = parent->cell_common_list->get_pci(old_pci); + auto old_ue_it = parent->users.find(old_rnti); + + // Reject unrecognized rntis, and PCIs that do not belong to eNB + if (old_ue_it == parent->users.end() or old_cell == nullptr or + old_ue_it->second->ue_cell_list.get_enb_cc_idx(old_cell->enb_cc_idx) == nullptr) { + // Check if old UE context does not belong to an S1-Handover UE. + old_ue = find_handover_source_ue(old_rnti, old_pci); + if (old_ue == nullptr) { + send_connection_reest_rej(procedure_result_code::error_unknown_rnti); + parent->logger.info( + "RRCReestablishmentReject for rnti=0x%x. Cause: no rnti=0x%x context available", rnti, old_rnti); + srsran::console("RRCReestablishmentReject for rnti=0x%x. Cause: no context available\n", rnti); + return; + } + } else { + old_ue = old_ue_it->second.get(); + } } - ue* old_ue = old_ue_it->second.get(); + bool old_ue_supported_endc = old_ue->endc_handler and old_ue->endc_handler->is_endc_supported(); if (not old_ue_supported_endc and req_r8.reest_cause.value == reest_cause_opts::recfg_fail) { // Reestablishment Reject for ReconfigFailures of LTE-only mode @@ -739,7 +755,7 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) parent->rem_user_thread(old_rnti); state = RRC_STATE_WAIT_FOR_CON_REEST_COMPLETE; - set_activity_timeout(MSG5_RX_TIMEOUT); + set_activity_timeout(MSG5_RX_TIMEOUT_T301); } void rrc::ue::send_connection_reest(uint8_t ncc) @@ -954,6 +970,9 @@ void rrc::ue::handle_rrc_reconf_complete(rrc_conn_recfg_complete_s* msg, srsran: // If performing handover, signal its completion mobility_handler->trigger(*msg); + // Clear pending NAS PDUs + bearer_list.clear_pending_nas_info(); + // 2> if the UE has radio link failure or handover failure information available const auto& complete_r8 = msg->crit_exts.rrc_conn_recfg_complete_r8(); if (complete_r8.non_crit_ext.non_crit_ext.rlf_info_available_r10_present or rlf_info_pending) { @@ -1053,6 +1072,7 @@ int rrc::ue::handle_ue_cap_info(ue_cap_info_s* msg) { parent->logger.info("UECapabilityInformation transaction ID: %d", msg->rrc_transaction_id); ue_cap_info_r8_ies_s* msg_r8 = &msg->crit_exts.c1().ue_cap_info_r8(); + const ue_cell_ded* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); for (uint32_t i = 0; i < msg_r8->ue_cap_rat_container_list.size(); i++) { if (msg_r8->ue_cap_rat_container_list[i].rat_type != rat_type_e::eutra) { @@ -1071,9 +1091,16 @@ int rrc::ue::handle_ue_cap_info(ue_cap_info_s* msg) parent->logger.debug("rnti=0x%x EUTRA capabilities: %s", rnti, js.to_string().c_str()); } eutra_capabilities_unpacked = true; - ue_capabilities = srsran::make_rrc_ue_capabilities(eutra_capabilities); + ue_capabilities = srsran::make_rrc_ue_capabilities(eutra_capabilities, *pcell); parent->logger.info("UE rnti: 0x%x category: %d", rnti, eutra_capabilities.ue_category); + if (ue_capabilities.support_ca_bands and ue_capabilities.support_ul_ca) { + parent->logger.info("UE rnti: 0x%x supports DL and UL CA with the used bands.", rnti); + } else if (ue_capabilities.support_ca_bands and not ue_capabilities.support_ul_ca) { + parent->logger.info("UE rnti: 0x%x supports DL CA with the used bands (no UL CA).", rnti); + } else { + parent->logger.info("UE rnti: 0x%x does not support CA with the used bands.", rnti); + } if (endc_handler != nullptr) { endc_handler->handle_eutra_capabilities(eutra_capabilities); @@ -1145,14 +1172,14 @@ void rrc::ue::send_connection_release() */ void rrc::ue::handle_ue_init_ctxt_setup_req(const asn1::s1ap::init_context_setup_request_s& msg) { - set_bitrates(msg.protocol_ies.ueaggregate_maximum_bitrate.value); - ue_security_cfg.set_security_capabilities(msg.protocol_ies.ue_security_cap.value); - ue_security_cfg.set_security_key(msg.protocol_ies.security_key.value); + set_bitrates(msg->ueaggregate_maximum_bitrate.value); + ue_security_cfg.set_security_capabilities(msg->ue_security_cap.value); + ue_security_cfg.set_security_key(msg->security_key.value); // CSFB - if (msg.protocol_ies.cs_fallback_ind_present) { - if (msg.protocol_ies.cs_fallback_ind.value.value == asn1::s1ap::cs_fallback_ind_opts::cs_fallback_required or - msg.protocol_ies.cs_fallback_ind.value.value == asn1::s1ap::cs_fallback_ind_opts::cs_fallback_high_prio) { + if (msg->cs_fallback_ind_present) { + if (msg->cs_fallback_ind.value.value == asn1::s1ap::cs_fallback_ind_opts::cs_fallback_required or + msg->cs_fallback_ind.value.value == asn1::s1ap::cs_fallback_ind_opts::cs_fallback_high_prio) { is_csfb = true; } } @@ -1163,25 +1190,25 @@ void rrc::ue::handle_ue_init_ctxt_setup_req(const asn1::s1ap::init_context_setup bool rrc::ue::handle_ue_ctxt_mod_req(const asn1::s1ap::ue_context_mod_request_s& msg) { - if (msg.protocol_ies.cs_fallback_ind_present) { - if (msg.protocol_ies.cs_fallback_ind.value.value == asn1::s1ap::cs_fallback_ind_opts::cs_fallback_required || - msg.protocol_ies.cs_fallback_ind.value.value == asn1::s1ap::cs_fallback_ind_opts::cs_fallback_high_prio) { + if (msg->cs_fallback_ind_present) { + if (msg->cs_fallback_ind.value.value == asn1::s1ap::cs_fallback_ind_opts::cs_fallback_required || + msg->cs_fallback_ind.value.value == asn1::s1ap::cs_fallback_ind_opts::cs_fallback_high_prio) { /* Remember that we are in a CSFB right now */ is_csfb = true; } } // UEAggregateMaximumBitrate - if (msg.protocol_ies.ueaggregate_maximum_bitrate_present) { - set_bitrates(msg.protocol_ies.ueaggregate_maximum_bitrate.value); + if (msg->ueaggregate_maximum_bitrate_present) { + set_bitrates(msg->ueaggregate_maximum_bitrate.value); } - if (msg.protocol_ies.ue_security_cap_present) { - ue_security_cfg.set_security_capabilities(msg.protocol_ies.ue_security_cap.value); + if (msg->ue_security_cap_present) { + ue_security_cfg.set_security_capabilities(msg->ue_security_cap.value); } - if (msg.protocol_ies.security_key_present) { - ue_security_cfg.set_security_key(msg.protocol_ies.security_key.value); + if (msg->security_key_present) { + ue_security_cfg.set_security_key(msg->security_key.value); send_security_mode_command(); } @@ -1228,7 +1255,7 @@ int rrc::ue::setup_erab(uint16_t erab_ cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::multiple_erab_id_instances; return SRSRAN_ERROR; } - if (bearer_list.add_erab(erab_id, qos_params, addr, gtpu_teid_out, nas_pdu, cause) != SRSRAN_SUCCESS) { + if (bearer_list.addmod_erab(erab_id, qos_params, addr, gtpu_teid_out, nas_pdu, cause) != SRSRAN_SUCCESS) { parent->logger.error("Couldn't add E-RAB id=%d for rnti=0x%x", erab_id, rnti); return SRSRAN_ERROR; } @@ -1269,6 +1296,13 @@ void rrc::ue::update_scells() parent->logger.info("UE doesn't support CA. Skipping SCell activation"); return; } + if (not ue_capabilities.support_ca_bands) { + parent->logger.info("UE doesn't support used CA bands. Skipping SCell activation"); + return; + } + if (not ue_capabilities.support_ul_ca) { + parent->logger.info("UE supports only DL CA"); + } if (not eutra_capabilities.non_crit_ext_present or not eutra_capabilities.non_crit_ext.non_crit_ext_present or not eutra_capabilities.non_crit_ext.non_crit_ext.non_crit_ext_present or not eutra_capabilities.non_crit_ext.non_crit_ext.non_crit_ext.rf_params_v1020_present or @@ -1640,4 +1674,22 @@ int rrc::ue::get_ri(uint32_t m_ri, uint16_t* ri_idx) return ret; } +rrc::ue* rrc::ue::find_handover_source_ue(uint16_t old_rnti, uint32_t old_pci) +{ + for (auto& ue_pair : parent->users) { + rrc::ue& u = *ue_pair.second; + if (u.mobility_handler != nullptr and u.mobility_handler->is_ho_running()) { + std::pair src_ctxt = u.mobility_handler->get_source_ue_rnti_and_pci(); + if (src_ctxt.first == old_rnti and src_ctxt.second == old_pci) { + parent->logger.info("Found old UE Context RNTI=0x%x,PCI=%d used for Reestablishment. It corresponds to a UE " + "performing handover.", + old_rnti, + old_pci); + return &u; + } + } + } + return nullptr; +} + } // namespace srsenb diff --git a/srsenb/src/stack/rrc/ue_meas_cfg.cc b/srsenb/src/stack/rrc/ue_meas_cfg.cc index 7817eb26db..d5d4488ab5 100644 --- a/srsenb/src/stack/rrc/ue_meas_cfg.cc +++ b/srsenb/src/stack/rrc/ue_meas_cfg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,8 @@ #include "srsenb/hdr/stack/rrc/ue_meas_cfg.h" #include "srsenb/hdr/stack/rrc/rrc_cell_cfg.h" -#include "srsran/rrc/rrc_cfg_utils.h" +#include "srsran/asn1/obj_id_cmp_utils.h" +#include "srsran/asn1/rrc_utils.h" using namespace asn1::rrc; @@ -433,8 +434,7 @@ bool apply_meascfg_updates(meas_cfg_s& meascfg, for (auto it = current_meascfg.meas_id_to_add_mod_list.begin(); it != current_meascfg.meas_id_to_add_mod_list.end();) { if (it->meas_obj_id == found_src_obj->meas_obj_id) { - auto rit = it++; - current_meascfg.meas_id_to_add_mod_list.erase(rit); + it = current_meascfg.meas_id_to_add_mod_list.erase(it); } else { ++it; } diff --git a/srsenb/src/stack/rrc/ue_rr_cfg.cc b/srsenb/src/stack/rrc/ue_rr_cfg.cc index 93d8c1ee2d..2acac5d860 100644 --- a/srsenb/src/stack/rrc/ue_rr_cfg.cc +++ b/srsenb/src/stack/rrc/ue_rr_cfg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,8 +23,8 @@ #include "srsenb/hdr/stack/rrc/rrc_bearer_cfg.h" #include "srsenb/hdr/stack/rrc/rrc_cell_cfg.h" #include "srsenb/hdr/stack/rrc/rrc_config.h" +#include "srsran/asn1/obj_id_cmp_utils.h" #include "srsran/asn1/rrc_utils.h" -#include "srsran/rrc/rrc_cfg_utils.h" #define SET_OPT_FIELD(fieldname, out, in) \ if (in.fieldname##_present) { \ @@ -435,6 +435,9 @@ void fill_scells_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, } } + const ue_cell_ded* pcell = ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); + const enb_cell_common* pcell_cfg = pcell->cell_common; + scell_to_add_mod_list_r10_l target_scells(ue_cell_list.nof_cells() - 1); for (size_t ue_cc_idx = 1; ue_cc_idx < ue_cell_list.nof_cells(); ++ue_cc_idx) { const ue_cell_ded& scell = *ue_cell_list.get_ue_cc_idx(ue_cc_idx); @@ -456,18 +459,29 @@ void fill_scells_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, nonul_cfg.phich_cfg_r10 = scell_cfg.mib.phich_cfg; nonul_cfg.pdsch_cfg_common_r10 = cc_cfg_sib.pdsch_cfg_common; // RadioResourceConfigCommonSCell-r10::ul-Configuration-r10 - asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10_present = true; - auto& ul_cfg = asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10; - ul_cfg.ul_freq_info_r10.ul_carrier_freq_r10_present = true; - ul_cfg.ul_freq_info_r10.ul_carrier_freq_r10 = scell_cfg.cell_cfg.ul_earfcn; - ul_cfg.p_max_r10_present = cell_sib1.p_max_present; - ul_cfg.p_max_r10 = cell_sib1.p_max; - ul_cfg.ul_freq_info_r10.add_spec_emission_scell_r10 = 1; - ul_cfg.ul_pwr_ctrl_common_scell_r10.p0_nominal_pusch_r10 = cc_cfg_sib.ul_pwr_ctrl_common.p0_nominal_pusch; - ul_cfg.ul_pwr_ctrl_common_scell_r10.alpha_r10.value = cc_cfg_sib.ul_pwr_ctrl_common.alpha; - ul_cfg.srs_ul_cfg_common_r10 = cc_cfg_sib.srs_ul_cfg_common; - ul_cfg.ul_cp_len_r10.value = cc_cfg_sib.ul_cp_len.value; - ul_cfg.pusch_cfg_common_r10 = cc_cfg_sib.pusch_cfg_common; + bool ul_allowed = false; + for (const auto& scell_tmp : pcell_cfg->cell_cfg.scell_list) { + if (scell_tmp.cell_id == scell.cell_common->cell_cfg.cell_id) { + ul_allowed = scell_tmp.ul_allowed; + break; + } + } + if (ue_caps.support_ul_ca and ul_allowed) { + asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10_present = true; + auto& ul_cfg = asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10; + ul_cfg.ul_freq_info_r10.ul_carrier_freq_r10_present = true; + ul_cfg.ul_freq_info_r10.ul_carrier_freq_r10 = scell_cfg.cell_cfg.ul_earfcn; + ul_cfg.p_max_r10_present = cell_sib1.p_max_present; + ul_cfg.p_max_r10 = cell_sib1.p_max; + ul_cfg.ul_freq_info_r10.add_spec_emission_scell_r10 = 1; + ul_cfg.ul_pwr_ctrl_common_scell_r10.p0_nominal_pusch_r10 = cc_cfg_sib.ul_pwr_ctrl_common.p0_nominal_pusch; + ul_cfg.ul_pwr_ctrl_common_scell_r10.alpha_r10.value = cc_cfg_sib.ul_pwr_ctrl_common.alpha; + ul_cfg.srs_ul_cfg_common_r10 = cc_cfg_sib.srs_ul_cfg_common; + ul_cfg.ul_cp_len_r10.value = cc_cfg_sib.ul_cp_len.value; + ul_cfg.pusch_cfg_common_r10 = cc_cfg_sib.pusch_cfg_common; + } else { + asn1cell.rr_cfg_common_scell_r10.ul_cfg_r10_present = false; + } // RadioResourceConfigDedicatedSCell-r10 asn1cell.rr_cfg_ded_scell_r10_present = true; asn1cell.rr_cfg_ded_scell_r10.phys_cfg_ded_scell_r10_present = true; diff --git a/srsenb/src/stack/s1ap/CMakeLists.txt b/srsenb/src/stack/s1ap/CMakeLists.txt index e9ce343e89..ea853eca76 100644 --- a/srsenb/src/stack/s1ap/CMakeLists.txt +++ b/srsenb/src/stack/s1ap/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsenb/src/stack/s1ap/s1ap.cc b/srsenb/src/stack/s1ap/s1ap.cc index 7713f0b451..85e5a9eb70 100644 --- a/srsenb/src/stack/s1ap/s1ap.cc +++ b/srsenb/src/stack/s1ap/s1ap.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -25,7 +25,7 @@ #include "srsran/common/enb_events.h" #include "srsran/common/int_helpers.h" #include "srsran/common/standard_streams.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" +#include "srsran/interfaces/enb_rrc_interface_s1ap.h" #include //for inet_ntop() #include @@ -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 { \ @@ -117,7 +118,7 @@ void fill_erab_failed_setup_list(OutList& output_list, const s1ap::erab_item_lis output_list.resize(input_list.size()); for (size_t i = 0; i < input_list.size(); ++i) { output_list[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); - output_list[i].value.erab_item() = input_list[i]; + output_list[i]->erab_item() = input_list[i]; } } @@ -127,6 +128,7 @@ void fill_erab_failed_setup_list(OutList& output_list, const s1ap::erab_item_lis s1ap::ue::ho_prep_proc_t::ho_prep_proc_t(s1ap::ue* ue_) : ue_ptr(ue_), s1ap_ptr(ue_->s1ap_ptr) {} srsran::proc_outcome_t s1ap::ue::ho_prep_proc_t::init(uint32_t target_eci_, + uint16_t target_tac_, srsran::plmn_id_t target_plmn_, srsran::span fwd_erabs, srsran::unique_byte_buffer_t rrc_container_, @@ -134,11 +136,12 @@ srsran::proc_outcome_t s1ap::ue::ho_prep_proc_t::init(uint32_t { ho_cmd_msg = nullptr; target_eci = target_eci_; + target_tac = target_tac_; target_plmn = target_plmn_; procInfo("Sending HandoverRequired to MME id=%d", ue_ptr->ctxt.mme_ue_s1ap_id.value()); if (not ue_ptr->send_ho_required( - target_eci, target_plmn, fwd_erabs, std::move(rrc_container_), has_direct_fwd_path)) { + target_eci, target_tac, target_plmn, fwd_erabs, std::move(rrc_container_), has_direct_fwd_path)) { procError("Failed to send HORequired to cell 0x%x", target_eci); return srsran::proc_outcome_t::error; } @@ -158,7 +161,7 @@ srsran::proc_outcome_t s1ap::ue::ho_prep_proc_t::react(const ho_prep_fail_s& msg { ue_ptr->ts1_reloc_prep.stop(); - std::string cause = s1ap_ptr->get_cause(msg.protocol_ies.cause.value); + std::string cause = s1ap_ptr->get_cause(msg->cause.value); procError("HO preparation Failure. Cause: %s", cause.c_str()); srsran::console("HO preparation Failure. Cause: %s\n", cause.c_str()); @@ -176,16 +179,16 @@ srsran::proc_outcome_t s1ap::ue::ho_prep_proc_t::react(const asn1::s1ap::ho_cmd_ ue_ptr->ts1_reloc_overall.run(); // Check for unsupported S1AP fields - if (msg.ext or msg.protocol_ies.target_to_source_transparent_container_secondary_present or - msg.protocol_ies.handov_type.value.value != handov_type_opts::intralte or - msg.protocol_ies.crit_diagnostics_present or msg.protocol_ies.nas_security_paramsfrom_e_utran_present) { + if (msg.ext or msg->target_to_source_transparent_container_secondary_present or + msg->handov_type.value.value != handov_type_opts::intralte or msg->crit_diagnostics_present or + msg->nas_security_paramsfrom_e_utran_present) { procWarning("Not handling HandoverCommand extensions and non-intraLTE params"); } // In case of intra-system Handover, Target to Source Transparent Container IE shall be encoded as // Target eNB to Source eNB Transparent Container IE - asn1::cbit_ref bref(msg.protocol_ies.target_to_source_transparent_container.value.data(), - msg.protocol_ies.target_to_source_transparent_container.value.size()); + asn1::cbit_ref bref(msg->target_to_source_transparent_container.value.data(), + msg->target_to_source_transparent_container.value.size()); asn1::s1ap::targetenb_to_sourceenb_transparent_container_s container; if (container.unpack(bref) != asn1::SRSASN_SUCCESS) { procError("Failed to decode TargeteNBToSourceeNBTransparentContainer"); @@ -229,6 +232,7 @@ void s1ap::ue::ho_prep_proc_t::then(const srsran::proc_state_t& result) srsran::proc_outcome_t s1ap::s1_setup_proc_t::init() { procInfo("Starting new MME connection."); + connect_count++; return start_mme_connection(); } @@ -243,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()) { @@ -274,7 +296,7 @@ srsran::proc_outcome_t s1ap::s1_setup_proc_t::react(const srsenb::s1ap::s1_setup return srsran::proc_outcome_t::error; } -void s1ap::s1_setup_proc_t::then(const srsran::proc_state_t& result) const +void s1ap::s1_setup_proc_t::then(const srsran::proc_state_t& result) { if (result.is_error()) { procInfo("Failed to initiate S1 connection. Attempting reconnection in %d seconds", @@ -285,7 +307,13 @@ void s1ap::s1_setup_proc_t::then(const srsran::proc_state_t& result) const s1ap_ptr->mme_socket.close(); procInfo("S1AP socket closed."); s1ap_ptr->mme_connect_timer.run(); + if (s1ap_ptr->args.max_s1_setup_retries > 0 && connect_count > s1ap_ptr->args.max_s1_setup_retries) { + s1ap_ptr->alarms_channel("s1apError"); + srsran_terminate("Error connecting to MME"); + } // Try again with in 10 seconds + } else { + connect_count = 0; } } @@ -296,7 +324,11 @@ void s1ap::s1_setup_proc_t::then(const srsran::proc_state_t& result) const s1ap::s1ap(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, srsran::socket_manager_itf* rx_socket_handler_) : - s1setup_proc(this), logger(logger), task_sched(task_sched_), rx_socket_handler(rx_socket_handler_) + s1setup_proc(this), + logger(logger), + task_sched(task_sched_), + rx_socket_handler(rx_socket_handler_), + alarms_channel(srslog::fetch_log_channel("alarms")) { mme_task_queue = task_sched.make_task_queue(); } @@ -312,11 +344,11 @@ int s1ap::init(const s1ap_args_t& args_, rrc_interface_s1ap* rrc_) mme_connect_timer = task_sched.get_unique_timer(); auto mme_connect_run = [this](uint32_t tid) { if (s1setup_proc.is_busy()) { - logger.error("Failed to initiate S1Setup procedure."); + logger.error("Failed to initiate S1Setup procedure: procedure is busy."); } 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; @@ -330,7 +362,7 @@ int s1ap::init(const s1ap_args_t& args_, rrc_interface_s1ap* rrc_) running = true; // starting MME connection if (not s1setup_proc.launch()) { - logger.error("Failed to initiate S1Setup procedure."); + logger.error("Failed to initiate S1Setup procedure: error launching procedure."); } return SRSRAN_SUCCESS; @@ -487,9 +519,39 @@ bool s1ap::connect_mme() using namespace srsran::net_utils; logger.info("Connecting to MME %s:%d", args.mme_addr.c_str(), int(MME_PORT)); - // Init SCTP socket and bind it - if (not srsran::net_utils::sctp_init_socket( - &mme_socket, socket_type::seqpacket, args.s1c_bind_addr.c_str(), args.s1c_bind_port)) { + // Open SCTP socket + if (not mme_socket.open_socket( + srsran::net_utils::addr_family::ipv4, socket_type::seqpacket, srsran::net_utils::protocol_type::SCTP)) { + return false; + } + + // Set SO_REUSE_ADDR if necessary + if (args.sctp_reuse_addr) { + if (not mme_socket.reuse_addr()) { + mme_socket.close(); + return false; + } + } + + // Subscribe to shutdown events + if (not mme_socket.sctp_subscribe_to_events()) { + mme_socket.close(); + return false; + } + + // Set SRTO_MAX + if (not mme_socket.sctp_set_rto_opts(args.sctp_rto_max)) { + return false; + } + + // Set SCTP init options + if (not mme_socket.sctp_set_init_msg_opts(args.sctp_init_max_attempts, args.sctp_max_init_timeo)) { + return false; + } + + // Bind socket + if (not mme_socket.bind_addr(args.s1c_bind_addr.c_str(), args.s1c_bind_port)) { + mme_socket.close(); return false; } logger.info("SCTP socket opened. fd=%d", mme_socket.fd()); @@ -526,25 +588,25 @@ bool s1ap::setup_s1() s1ap_pdu_c pdu; pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_S1_SETUP); - s1_setup_request_ies_container& container = pdu.init_msg().value.s1_setup_request().protocol_ies; - container.global_enb_id.value.plm_nid[0] = ((uint8_t*)&plmn)[1]; - container.global_enb_id.value.plm_nid[1] = ((uint8_t*)&plmn)[2]; - container.global_enb_id.value.plm_nid[2] = ((uint8_t*)&plmn)[3]; + s1_setup_request_s& container = pdu.init_msg().value.s1_setup_request(); + container->global_enb_id.value.plm_nid[0] = ((uint8_t*)&plmn)[1]; + container->global_enb_id.value.plm_nid[1] = ((uint8_t*)&plmn)[2]; + container->global_enb_id.value.plm_nid[2] = ((uint8_t*)&plmn)[3]; - container.global_enb_id.value.enb_id.set_macro_enb_id().from_number(args.enb_id); + container->global_enb_id.value.enb_id.set_macro_enb_id().from_number(args.enb_id); - container.enbname_present = true; - container.enbname.value.from_string(args.enb_name); + container->enbname_present = true; + container->enbname.value.from_string(args.enb_name); - container.supported_tas.value.resize(1); + container->supported_tas.value.resize(1); tmp16 = htons(args.tac); - memcpy(container.supported_tas.value[0].tac.data(), (uint8_t*)&tmp16, 2); - container.supported_tas.value[0].broadcast_plmns.resize(1); - container.supported_tas.value[0].broadcast_plmns[0][0] = ((uint8_t*)&plmn)[1]; - container.supported_tas.value[0].broadcast_plmns[0][1] = ((uint8_t*)&plmn)[2]; - container.supported_tas.value[0].broadcast_plmns[0][2] = ((uint8_t*)&plmn)[3]; + memcpy(container->supported_tas.value[0].tac.data(), (uint8_t*)&tmp16, 2); + container->supported_tas.value[0].broadcast_plmns.resize(1); + container->supported_tas.value[0].broadcast_plmns[0][0] = ((uint8_t*)&plmn)[1]; + container->supported_tas.value[0].broadcast_plmns[0][1] = ((uint8_t*)&plmn)[2]; + container->supported_tas.value[0].broadcast_plmns[0][2] = ((uint8_t*)&plmn)[3]; - container.default_paging_drx.value.value = asn1::s1ap::paging_drx_opts::v128; // Todo: add to args, config file + container->default_paging_drx.value.value = asn1::s1ap::paging_drx_opts::v128; // Todo: add to args, config file return sctp_send_s1ap_pdu(pdu, 0, "s1SetupRequest"); } @@ -573,6 +635,10 @@ bool s1ap::handle_mme_rx_msg(srsran::unique_byte_buffer_t pdu, logger.info("SCTP peer addres unreachable. Association: %d", sri.sinfo_assoc_id); srsran::console("SCTP peer address unreachable. Association: %d\n", sri.sinfo_assoc_id); restart_s1 = true; + } else if (notification->sn_header.sn_type == SCTP_REMOTE_ERROR) { + logger.info("SCTP remote error. Association: %d", sri.sinfo_assoc_id); + srsran::console("SCTP remote error. Association: %d\n", sri.sinfo_assoc_id); + restart_s1 = true; } else if (notification->sn_header.sn_type == SCTP_ASSOC_CHANGE) { logger.info("SCTP association changed. Association: %d", sri.sinfo_assoc_id); srsran::console("SCTP association changed. Association: %d\n", sri.sinfo_assoc_id); @@ -706,6 +772,13 @@ bool s1ap::handle_unsuccessfuloutcome(const unsuccessful_outcome_s& msg) bool s1ap::handle_s1setupresponse(const asn1::s1ap::s1_setup_resp_s& msg) { + if (s1setup_proc.is_idle()) { + asn1::s1ap::cause_c cause; + cause.set_protocol().value = cause_protocol_opts::msg_not_compatible_with_receiver_state; + send_error_indication(cause); + return false; + } + s1setupresponse = msg; mme_connected = true; s1_setup_proc_t::s1setupresult res; @@ -719,16 +792,15 @@ bool s1ap::handle_dlnastransport(const dl_nas_transport_s& msg) if (msg.ext) { logger.warning("Not handling S1AP message extension"); } - ue* u = - handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); + ue* u = handle_s1apmsg_ue_id(msg->enb_ue_s1ap_id.value.value, msg->mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; } - if (msg.protocol_ies.ho_restrict_list_present) { + if (msg->ho_restrict_list_present) { logger.warning("Not handling HandoverRestrictionList"); } - if (msg.protocol_ies.subscriber_profile_idfor_rfp_present) { + if (msg->subscriber_profile_idfor_rfp_present) { logger.warning("Not handling SubscriberProfileIDforRFP"); } @@ -737,35 +809,41 @@ bool s1ap::handle_dlnastransport(const dl_nas_transport_s& msg) logger.error("Fatal Error: Couldn't allocate buffer in s1ap::run_thread()."); return false; } - memcpy(pdu->msg, msg.protocol_ies.nas_pdu.value.data(), msg.protocol_ies.nas_pdu.value.size()); - pdu->N_bytes = msg.protocol_ies.nas_pdu.value.size(); + memcpy(pdu->msg, msg->nas_pdu.value.data(), msg->nas_pdu.value.size()); + pdu->N_bytes = msg->nas_pdu.value.size(); rrc->write_dl_info(u->ctxt.rnti, std::move(pdu)); return true; } bool s1ap::handle_initialctxtsetuprequest(const init_context_setup_request_s& msg) { - const auto& prot_ies = msg.protocol_ies; WarnUnsupportFeature(msg.ext, "message extension"); - WarnUnsupportFeature(prot_ies.add_cs_fallback_ind_present, "AdditionalCSFallbackIndicator"); - WarnUnsupportFeature(prot_ies.csg_membership_status_present, "CSGMembershipStatus"); - WarnUnsupportFeature(prot_ies.gummei_id_present, "GUMMEI_ID"); - WarnUnsupportFeature(prot_ies.ho_restrict_list_present, "HandoverRestrictionList"); - WarnUnsupportFeature(prot_ies.management_based_mdt_allowed_present, "ManagementBasedMDTAllowed"); - WarnUnsupportFeature(prot_ies.management_based_mdtplmn_list_present, "ManagementBasedMDTPLMNList"); - WarnUnsupportFeature(prot_ies.mme_ue_s1ap_id_minus2_present, "MME_UE_S1AP_ID_2"); - WarnUnsupportFeature(prot_ies.registered_lai_present, "RegisteredLAI"); - WarnUnsupportFeature(prot_ies.srvcc_operation_possible_present, "SRVCCOperationPossible"); - WarnUnsupportFeature(prot_ies.subscriber_profile_idfor_rfp_present, "SubscriberProfileIDforRFP"); - WarnUnsupportFeature(prot_ies.trace_activation_present, "TraceActivation"); - WarnUnsupportFeature(prot_ies.ue_radio_cap_present, "UERadioCapability"); - - ue* u = - handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); + WarnUnsupportFeature(msg->add_cs_fallback_ind_present, "AdditionalCSFallbackIndicator"); + WarnUnsupportFeature(msg->csg_membership_status_present, "CSGMembershipStatus"); + WarnUnsupportFeature(msg->gummei_id_present, "GUMMEI_ID"); + WarnUnsupportFeature(msg->ho_restrict_list_present, "HandoverRestrictionList"); + WarnUnsupportFeature(msg->management_based_mdt_allowed_present, "ManagementBasedMDTAllowed"); + WarnUnsupportFeature(msg->management_based_mdtplmn_list_present, "ManagementBasedMDTPLMNList"); + WarnUnsupportFeature(msg->mme_ue_s1ap_id_minus2_present, "MME_UE_S1AP_ID_2"); + WarnUnsupportFeature(msg->registered_lai_present, "RegisteredLAI"); + WarnUnsupportFeature(msg->srvcc_operation_possible_present, "SRVCCOperationPossible"); + WarnUnsupportFeature(msg->subscriber_profile_idfor_rfp_present, "SubscriberProfileIDforRFP"); + WarnUnsupportFeature(msg->trace_activation_present, "TraceActivation"); + WarnUnsupportFeature(msg->ue_radio_cap_present, "UERadioCapability"); + + ue* u = handle_s1apmsg_ue_id(msg->enb_ue_s1ap_id.value.value, msg->mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; } + if (u->get_state() == s1ap_proc_id_t::init_context_setup_request) { + logger.warning("Initial Context Setup Request already in progress. Ignoring ICS request."); + asn1::s1ap::cause_c cause; + cause.set_protocol().value = cause_protocol_opts::msg_not_compatible_with_receiver_state; + send_error_indication(cause, msg->enb_ue_s1ap_id.value.value, msg->mme_ue_s1ap_id.value.value); + return false; + } + // Setup UE ctxt in RRC if (not rrc->setup_ue_ctxt(u->ctxt.rnti, msg)) { return false; @@ -774,10 +852,10 @@ bool s1ap::handle_initialctxtsetuprequest(const init_context_setup_request_s& ms // Update E-RABs erab_id_list updated_erabs; erab_item_list failed_cfg_erabs; - add_repeated_erab_ids(prot_ies.erab_to_be_setup_list_ctxt_su_req.value, failed_cfg_erabs); + add_repeated_erab_ids(msg->erab_to_be_setup_list_ctxt_su_req.value, failed_cfg_erabs); - for (const auto& item : msg.protocol_ies.erab_to_be_setup_list_ctxt_su_req.value) { - const auto& erab = item.value.erab_to_be_setup_item_ctxt_su_req(); + for (const auto& item : msg->erab_to_be_setup_list_ctxt_su_req.value) { + const auto& erab = item->erab_to_be_setup_item_ctxt_su_req(); if (contains_erab_id(failed_cfg_erabs, erab.erab_id)) { // E-RAB is duplicate continue; @@ -810,9 +888,9 @@ bool s1ap::handle_initialctxtsetuprequest(const init_context_setup_request_s& ms } /* Ideally the check below would be "if (users[rnti].is_csfb)" */ - if (msg.protocol_ies.cs_fallback_ind_present) { - if (msg.protocol_ies.cs_fallback_ind.value.value == cs_fallback_ind_opts::cs_fallback_required || - msg.protocol_ies.cs_fallback_ind.value.value == cs_fallback_ind_opts::cs_fallback_high_prio) { + if (msg->cs_fallback_ind_present) { + if (msg->cs_fallback_ind.value.value == cs_fallback_ind_opts::cs_fallback_required || + msg->cs_fallback_ind.value.value == cs_fallback_ind_opts::cs_fallback_high_prio) { // Send RRC Release (cs-fallback-triggered) to MME cause_c cause; cause.set_radio_network().value = cause_radio_network_opts::cs_fallback_triggered; @@ -832,8 +910,8 @@ bool s1ap::handle_paging(const asn1::s1ap::paging_s& msg) { WarnUnsupportFeature(msg.ext, "S1AP message extension"); - uint32_t ueid = msg.protocol_ies.ue_id_idx_value.value.to_number(); - rrc->add_paging_id(ueid, msg.protocol_ies.ue_paging_id.value); + uint32_t ueid = msg->ue_id_idx_value.value.to_number(); + rrc->add_paging_id(ueid, msg->ue_paging_id.value); return true; } @@ -841,22 +919,21 @@ bool s1ap::handle_erabsetuprequest(const erab_setup_request_s& msg) { WarnUnsupportFeature(msg.ext, "S1AP message extension"); - ue* u = - handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); + ue* u = handle_s1apmsg_ue_id(msg->enb_ue_s1ap_id.value.value, msg->mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; } - if (msg.protocol_ies.ueaggregate_maximum_bitrate_present) { - rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg.protocol_ies.ueaggregate_maximum_bitrate.value); + if (msg->ueaggregate_maximum_bitrate_present) { + rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg->ueaggregate_maximum_bitrate.value); } erab_id_list updated_erabs; erab_item_list failed_cfg_erabs; - add_repeated_erab_ids(msg.protocol_ies.erab_to_be_setup_list_bearer_su_req.value, failed_cfg_erabs); + add_repeated_erab_ids(msg->erab_to_be_setup_list_bearer_su_req.value, failed_cfg_erabs); - for (const auto& item : msg.protocol_ies.erab_to_be_setup_list_bearer_su_req.value) { - const auto& erab = item.value.erab_to_be_setup_item_bearer_su_req(); + for (const auto& item : msg->erab_to_be_setup_list_bearer_su_req.value) { + const auto& erab = item->erab_to_be_setup_item_bearer_su_req(); if (contains_erab_id(failed_cfg_erabs, erab.erab_id)) { // E-RAB is duplicate continue; @@ -901,22 +978,21 @@ bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg) { WarnUnsupportFeature(msg.ext, "S1AP message extension"); - ue* u = - handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); + ue* u = handle_s1apmsg_ue_id(msg->enb_ue_s1ap_id.value.value, msg->mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; } - if (msg.protocol_ies.ueaggregate_maximum_bitrate_present) { - rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg.protocol_ies.ueaggregate_maximum_bitrate.value); + if (msg->ueaggregate_maximum_bitrate_present) { + rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg->ueaggregate_maximum_bitrate.value); } erab_id_list updated_erabs; erab_item_list failed_cfg_erabs; - add_repeated_erab_ids(msg.protocol_ies.erab_to_be_modified_list_bearer_mod_req.value, failed_cfg_erabs); + add_repeated_erab_ids(msg->erab_to_be_modified_list_bearer_mod_req.value, failed_cfg_erabs); - for (const auto& item : msg.protocol_ies.erab_to_be_modified_list_bearer_mod_req.value) { - const auto& erab = item.value.erab_to_be_modified_item_bearer_mod_req(); + for (const auto& item : msg->erab_to_be_modified_list_bearer_mod_req.value) { + const auto& erab = item->erab_to_be_modified_item_bearer_mod_req(); if (contains_erab_id(failed_cfg_erabs, erab.erab_id)) { // E-RAB is duplicate continue; @@ -956,8 +1032,7 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg) { WarnUnsupportFeature(msg.ext, "S1AP message extension"); - ue* u = - handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); + ue* u = handle_s1apmsg_ue_id(msg->enb_ue_s1ap_id.value.value, msg->mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; } @@ -971,8 +1046,8 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg) return e.erab_id == erab_id; })); }; - for (const auto& item : msg.protocol_ies.erab_to_be_released_list.value) { - const auto& erab = item.value.erab_item(); + for (const auto& item : msg->erab_to_be_released_list.value) { + const auto& erab = item->erab_item(); if (is_repeated_erab_id(erab.erab_id)) { // TS 36.413, 8.2.3.3 - ignore the duplication of E-RAB ID IEs @@ -990,7 +1065,7 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg) // Notify RRC of E-RAB update. (RRC reconf message is going to be sent. if (not updated_erabs.empty()) { - rrc->notify_ue_erab_updates(u->ctxt.rnti, msg.protocol_ies.nas_pdu.value); + rrc->notify_ue_erab_updates(u->ctxt.rnti, msg->nas_pdu.value); } // Send E-RAB release response back to the MME @@ -1006,13 +1081,12 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg) bool s1ap::handle_uecontextmodifyrequest(const ue_context_mod_request_s& msg) { WarnUnsupportFeature(msg.ext, "S1AP message extension"); - WarnUnsupportFeature(msg.protocol_ies.add_cs_fallback_ind_present, "AdditionalCSFallbackIndicator"); - WarnUnsupportFeature(msg.protocol_ies.csg_membership_status_present, "CSGMembershipStatus"); - WarnUnsupportFeature(msg.protocol_ies.registered_lai_present, "RegisteredLAI"); - WarnUnsupportFeature(msg.protocol_ies.subscriber_profile_idfor_rfp_present, "SubscriberProfileIDforRFP"); + WarnUnsupportFeature(msg->add_cs_fallback_ind_present, "AdditionalCSFallbackIndicator"); + WarnUnsupportFeature(msg->csg_membership_status_present, "CSGMembershipStatus"); + WarnUnsupportFeature(msg->registered_lai_present, "RegisteredLAI"); + WarnUnsupportFeature(msg->subscriber_profile_idfor_rfp_present, "SubscriberProfileIDforRFP"); - ue* u = - handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); + ue* u = handle_s1apmsg_ue_id(msg->enb_ue_s1ap_id.value.value, msg->mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; } @@ -1028,9 +1102,9 @@ bool s1ap::handle_uecontextmodifyrequest(const ue_context_mod_request_s& msg) u->send_uectxtmodifyresp(); /* Ideally the check below would be "if (users[rnti].is_csfb)" */ - if (msg.protocol_ies.cs_fallback_ind_present) { - if (msg.protocol_ies.cs_fallback_ind.value.value == cs_fallback_ind_opts::cs_fallback_required || - msg.protocol_ies.cs_fallback_ind.value.value == cs_fallback_ind_opts::cs_fallback_high_prio) { + if (msg->cs_fallback_ind_present) { + if (msg->cs_fallback_ind.value.value == cs_fallback_ind_opts::cs_fallback_required || + msg->cs_fallback_ind.value.value == cs_fallback_ind_opts::cs_fallback_high_prio) { // Send RRC Release (cs-fallback-triggered) to MME cause_c cause; cause.set_radio_network().value = cause_radio_network_opts::cs_fallback_triggered; @@ -1047,8 +1121,8 @@ bool s1ap::handle_uectxtreleasecommand(const ue_context_release_cmd_s& msg) WarnUnsupportFeature(msg.ext, "S1AP message extension"); ue* u = nullptr; - if (msg.protocol_ies.ue_s1ap_ids.value.type().value == ue_s1ap_ids_c::types_opts::ue_s1ap_id_pair) { - const auto& idpair = msg.protocol_ies.ue_s1ap_ids.value.ue_s1ap_id_pair(); + if (msg->ue_s1ap_ids.value.type().value == ue_s1ap_ids_c::types_opts::ue_s1ap_id_pair) { + const auto& idpair = msg->ue_s1ap_ids.value.ue_s1ap_id_pair(); if (idpair.ext) { logger.warning("Not handling S1AP message extension"); @@ -1061,7 +1135,7 @@ bool s1ap::handle_uectxtreleasecommand(const ue_context_release_cmd_s& msg) return false; } } else { - uint32_t mme_ue_id = msg.protocol_ies.ue_s1ap_ids.value.mme_ue_s1ap_id(); + uint32_t mme_ue_id = msg->ue_s1ap_ids.value.mme_ue_s1ap_id(); u = users.find_ue_mmeid(mme_ue_id); if (u == nullptr) { logger.warning("UE for mme_ue_s1ap_id:%d not found - discarding message", mme_ue_id); @@ -1080,7 +1154,18 @@ bool s1ap::handle_uectxtreleasecommand(const ue_context_release_cmd_s& msg) bool s1ap::handle_s1setupfailure(const asn1::s1ap::s1_setup_fail_s& msg) { - std::string cause = get_cause(msg.protocol_ies.cause.value); + if (s1setup_proc.is_idle()) { + asn1::s1ap::cause_c cause; + cause.set_protocol().value = cause_protocol_opts::msg_not_compatible_with_receiver_state; + send_error_indication(cause); + return false; + } + + s1_setup_proc_t::s1setupresult res; + res.success = false; + s1setup_proc.trigger(res); + + std::string cause = get_cause(msg->cause.value); logger.error("S1 Setup Failure. Cause: %s", cause.c_str()); srsran::console("S1 Setup Failure. Cause: %s\n", cause.c_str()); return true; @@ -1088,22 +1173,35 @@ bool s1ap::handle_s1setupfailure(const asn1::s1ap::s1_setup_fail_s& msg) bool s1ap::handle_handover_preparation_failure(const ho_prep_fail_s& msg) { - ue* u = - handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); + ue* u = handle_s1apmsg_ue_id(msg->enb_ue_s1ap_id.value.value, msg->mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; } + + if (u->ho_prep_proc.is_idle()) { + asn1::s1ap::cause_c cause; + cause.set_protocol().value = cause_protocol_opts::msg_not_compatible_with_receiver_state; + send_error_indication(cause); + return false; + } + u->ho_prep_proc.trigger(msg); return true; } bool s1ap::handle_handover_command(const asn1::s1ap::ho_cmd_s& msg) { - ue* u = - handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); + ue* u = handle_s1apmsg_ue_id(msg->enb_ue_s1ap_id.value.value, msg->mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; } + + if (u->ho_prep_proc.is_idle()) { + asn1::s1ap::cause_c cause; + cause.set_protocol().value = cause_protocol_opts::msg_not_compatible_with_receiver_state; + send_error_indication(cause); + return false; + } u->ho_prep_proc.trigger(msg); return true; } @@ -1115,15 +1213,15 @@ bool s1ap::handle_handover_command(const asn1::s1ap::ho_cmd_s& msg) bool s1ap::handle_handover_request(const asn1::s1ap::ho_request_s& msg) { uint16_t rnti = SRSRAN_INVALID_RNTI; - uint32_t mme_ue_s1ap_id = msg.protocol_ies.mme_ue_s1ap_id.value.value; + uint32_t mme_ue_s1ap_id = msg->mme_ue_s1ap_id.value.value; asn1::s1ap::cause_c cause; cause.set_misc().value = cause_misc_opts::unspecified; - if (msg.ext or msg.protocol_ies.ho_restrict_list_present) { + if (msg.ext or msg->ho_restrict_list_present) { logger.warning("Not handling S1AP Handover Request extensions or Handover Restriction List"); } - if (msg.protocol_ies.handov_type.value.value != handov_type_opts::intralte) { + if (msg->handov_type.value.value != handov_type_opts::intralte) { logger.error("Not handling S1AP non-intra LTE handovers"); cause.set_radio_network().value = cause_radio_network_opts::interrat_redirection; send_ho_failure(mme_ue_s1ap_id, cause); @@ -1131,9 +1229,9 @@ bool s1ap::handle_handover_request(const asn1::s1ap::ho_request_s& msg) } // Confirm the UE does not exist in TeNB - if (users.find_ue_mmeid(msg.protocol_ies.mme_ue_s1ap_id.value.value) != nullptr) { + if (users.find_ue_mmeid(msg->mme_ue_s1ap_id.value.value) != nullptr) { logger.error("The provided MME_UE_S1AP_ID=%" PRIu64 " is already connected to the cell", - msg.protocol_ies.mme_ue_s1ap_id.value.value); + msg->mme_ue_s1ap_id.value.value); cause.set_radio_network().value = cause_radio_network_opts::unknown_mme_ue_s1ap_id; send_ho_failure(mme_ue_s1ap_id, cause); return false; @@ -1141,13 +1239,13 @@ bool s1ap::handle_handover_request(const asn1::s1ap::ho_request_s& msg) // Create user ctxt object and associated MME context std::unique_ptr ue_ptr{new ue{this}}; - ue_ptr->ctxt.mme_ue_s1ap_id = msg.protocol_ies.mme_ue_s1ap_id.value.value; + ue_ptr->ctxt.mme_ue_s1ap_id = msg->mme_ue_s1ap_id.value.value; srsran_assert(users.add_user(std::move(ue_ptr)) != nullptr, "Unexpected failure to create S1AP UE"); // Unpack Transparent Container sourceenb_to_targetenb_transparent_container_s container; - asn1::cbit_ref bref{msg.protocol_ies.source_to_target_transparent_container.value.data(), - msg.protocol_ies.source_to_target_transparent_container.value.size()}; + asn1::cbit_ref bref{msg->source_to_target_transparent_container.value.data(), + msg->source_to_target_transparent_container.value.size()}; if (container.unpack(bref) != asn1::SRSASN_SUCCESS) { logger.warning("Failed to unpack SourceToTargetTransparentContainer"); cause.set_protocol().value = cause_protocol_opts::transfer_syntax_error; @@ -1174,10 +1272,10 @@ void s1ap::send_ho_failure(uint32_t mme_ue_s1ap_id, const asn1::s1ap::cause_c& c s1ap_pdu_c tx_pdu; tx_pdu.set_unsuccessful_outcome().load_info_obj(ASN1_S1AP_ID_HO_RES_ALLOC); - ho_fail_ies_container& container = tx_pdu.unsuccessful_outcome().value.ho_fail().protocol_ies; + ho_fail_s& container = tx_pdu.unsuccessful_outcome().value.ho_fail(); - container.mme_ue_s1ap_id.value = mme_ue_s1ap_id; - container.cause.value = cause; + container->mme_ue_s1ap_id.value = mme_ue_s1ap_id; + container->cause.value = cause; sctp_send_s1ap_pdu(tx_pdu, SRSRAN_INVALID_RNTI, "HandoverFailure"); } @@ -1191,24 +1289,24 @@ bool s1ap::send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, { s1ap_pdu_c tx_pdu; tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_HO_RES_ALLOC); - ho_request_ack_ies_container& container = tx_pdu.successful_outcome().value.ho_request_ack().protocol_ies; + ho_request_ack_s& container = tx_pdu.successful_outcome().value.ho_request_ack(); - ue* ue_ptr = users.find_ue_mmeid(msg.protocol_ies.mme_ue_s1ap_id.value.value); + ue* ue_ptr = users.find_ue_mmeid(msg->mme_ue_s1ap_id.value.value); if (ue_ptr == nullptr) { - logger.error("The MME-S1AP-UE-ID=%ld is not valid", msg.protocol_ies.mme_ue_s1ap_id.value.value); + logger.error("The MME-S1AP-UE-ID=%ld is not valid", msg->mme_ue_s1ap_id.value.value); return false; } ue_ptr->ctxt.rnti = rnti; ue_ptr->ctxt.enb_cc_idx = enb_cc_idx; - container.mme_ue_s1ap_id.value = msg.protocol_ies.mme_ue_s1ap_id.value.value; - container.enb_ue_s1ap_id.value = ue_ptr->ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = msg->mme_ue_s1ap_id.value.value; + container->enb_ue_s1ap_id.value = ue_ptr->ctxt.enb_ue_s1ap_id; // Add admitted E-RABs - container.erab_admitted_list.value.resize(admitted_bearers.size()); + container->erab_admitted_list.value.resize(admitted_bearers.size()); for (size_t i = 0; i < admitted_bearers.size(); ++i) { - container.erab_admitted_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ADMITTED_ITEM); - auto& c = container.erab_admitted_list.value[i].value.erab_admitted_item(); + container->erab_admitted_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ADMITTED_ITEM); + auto& c = container->erab_admitted_list.value[i]->erab_admitted_item(); c = admitted_bearers[i]; if (!args.gtp_advertise_addr.empty()) { c.transport_layer_address = addr_to_asn1(args.gtp_advertise_addr.c_str()); @@ -1229,12 +1327,12 @@ bool s1ap::send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, // Add failed to Setup E-RABs if (not not_admitted_bearers.empty()) { - container.erab_failed_to_setup_list_ho_req_ack_present = true; - container.erab_failed_to_setup_list_ho_req_ack.value.resize(not_admitted_bearers.size()); + container->erab_failed_to_setup_list_ho_req_ack_present = true; + container->erab_failed_to_setup_list_ho_req_ack.value.resize(not_admitted_bearers.size()); for (size_t i = 0; i < not_admitted_bearers.size(); ++i) { - container.erab_failed_to_setup_list_ho_req_ack.value[i].load_info_obj( + container->erab_failed_to_setup_list_ho_req_ack.value[i].load_info_obj( ASN1_S1AP_ID_ERAB_FAILEDTO_SETUP_ITEM_HO_REQ_ACK); - auto& erab = container.erab_failed_to_setup_list_ho_req_ack.value[i].value.erab_failedto_setup_item_ho_req_ack(); + auto& erab = container->erab_failed_to_setup_list_ho_req_ack.value[i]->erab_failedto_setup_item_ho_req_ack(); erab.erab_id = not_admitted_bearers[i].erab_id; erab.cause = not_admitted_bearers[i].cause; } @@ -1251,23 +1349,21 @@ bool s1ap::send_ho_req_ack(const asn1::s1ap::ho_request_s& msg, logger.error("Failed to pack TargeteNBToSourceeNBTransparentContainer"); return false; } - container.target_to_source_transparent_container.value.resize(bref.distance_bytes()); - memcpy(container.target_to_source_transparent_container.value.data(), pdu->msg, bref.distance_bytes()); + container->target_to_source_transparent_container.value.resize(bref.distance_bytes()); + memcpy(container->target_to_source_transparent_container.value.data(), pdu->msg, bref.distance_bytes()); return sctp_send_s1ap_pdu(tx_pdu, rnti, "HandoverRequestAcknowledge"); } bool s1ap::handle_mme_status_transfer(const asn1::s1ap::mme_status_transfer_s& msg) { - ue* u = - handle_s1apmsg_ue_id(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value); + ue* u = handle_s1apmsg_ue_id(msg->enb_ue_s1ap_id.value.value, msg->mme_ue_s1ap_id.value.value); if (u == nullptr) { return false; } - rrc->set_erab_status( - u->ctxt.rnti, - msg.protocol_ies.enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list); + rrc->set_erab_status(u->ctxt.rnti, + msg->enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list); return true; } @@ -1281,14 +1377,14 @@ void s1ap::send_ho_notify(uint16_t rnti, uint64_t target_eci) s1ap_pdu_c tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_HO_NOTIF); - ho_notify_ies_container& container = tx_pdu.init_msg().value.ho_notify().protocol_ies; + ho_notify_s& container = tx_pdu.init_msg().value.ho_notify(); - container.mme_ue_s1ap_id.value = user_ptr->ctxt.mme_ue_s1ap_id.value(); - container.enb_ue_s1ap_id.value = user_ptr->ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = user_ptr->ctxt.mme_ue_s1ap_id.value(); + container->enb_ue_s1ap_id.value = user_ptr->ctxt.enb_ue_s1ap_id; - container.eutran_cgi.value = eutran_cgi; - container.eutran_cgi.value.cell_id.from_number(target_eci); - container.tai.value = tai; + container->eutran_cgi.value = eutran_cgi; + container->eutran_cgi.value.cell_id.from_number(target_eci); + container->tai.value = tai; sctp_send_s1ap_pdu(tx_pdu, rnti, "HandoverNotify"); } @@ -1301,16 +1397,7 @@ void s1ap::send_ho_cancel(uint16_t rnti, const asn1::s1ap::cause_c& cause) return; } - s1ap_pdu_c tx_pdu; - - tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_HO_CANCEL); - ho_cancel_ies_container& container = tx_pdu.init_msg().value.ho_cancel().protocol_ies; - - container.mme_ue_s1ap_id.value = user_ptr->ctxt.mme_ue_s1ap_id.value(); - container.enb_ue_s1ap_id.value = user_ptr->ctxt.enb_ue_s1ap_id; - container.cause.value = cause; - - sctp_send_s1ap_pdu(tx_pdu, rnti, "HandoverCancel"); + user_ptr->send_ho_cancel(cause); } bool s1ap::release_erabs(uint16_t rnti, const std::vector& erabs_successfully_released) @@ -1341,24 +1428,24 @@ bool s1ap::send_error_indication(const asn1::s1ap::cause_c& cause, s1ap_pdu_c tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_ERROR_IND); - auto& container = tx_pdu.init_msg().value.error_ind().protocol_ies; + auto& container = tx_pdu.init_msg().value.error_ind(); - uint16_t rnti = SRSRAN_INVALID_RNTI; - container.enb_ue_s1ap_id_present = enb_ue_s1ap_id.has_value(); + uint16_t rnti = SRSRAN_INVALID_RNTI; + container->enb_ue_s1ap_id_present = enb_ue_s1ap_id.has_value(); if (enb_ue_s1ap_id.has_value()) { - container.enb_ue_s1ap_id.value = enb_ue_s1ap_id.value(); - ue* user_ptr = users.find_ue_enbid(enb_ue_s1ap_id.value()); - rnti = user_ptr != nullptr ? user_ptr->ctxt.rnti : SRSRAN_INVALID_RNTI; + container->enb_ue_s1ap_id.value = enb_ue_s1ap_id.value(); + ue* user_ptr = users.find_ue_enbid(enb_ue_s1ap_id.value()); + rnti = user_ptr != nullptr ? user_ptr->ctxt.rnti : SRSRAN_INVALID_RNTI; } - container.mme_ue_s1ap_id_present = mme_ue_s1ap_id.has_value(); + container->mme_ue_s1ap_id_present = mme_ue_s1ap_id.has_value(); if (mme_ue_s1ap_id.has_value()) { - container.mme_ue_s1ap_id.value = mme_ue_s1ap_id.value(); + container->mme_ue_s1ap_id.value = mme_ue_s1ap_id.value(); } - container.s_tmsi_present = false; + container->s_tmsi_present = false; - container.cause_present = true; - container.cause.value = cause; + container->cause_present = true; + container->cause.value = cause; return sctp_send_s1ap_pdu(tx_pdu, rnti, "Error Indication"); } @@ -1379,30 +1466,30 @@ bool s1ap::ue::send_initialuemessage(asn1::s1ap::rrc_establishment_cause_e cause s1ap_pdu_c tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_INIT_UE_MSG); - init_ue_msg_ies_container& container = tx_pdu.init_msg().value.init_ue_msg().protocol_ies; + init_ue_msg_s& container = tx_pdu.init_msg().value.init_ue_msg(); // S_TMSI if (has_tmsi) { - container.s_tmsi_present = true; - uint32_to_uint8(m_tmsi, container.s_tmsi.value.m_tmsi.data()); - container.s_tmsi.value.mmec[0] = mmec; + container->s_tmsi_present = true; + uint32_to_uint8(m_tmsi, container->s_tmsi.value.m_tmsi.data()); + container->s_tmsi.value.mmec[0] = mmec; } // ENB_UE_S1AP_ID - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; // NAS_PDU - container.nas_pdu.value.resize(pdu->N_bytes); - memcpy(container.nas_pdu.value.data(), pdu->msg, pdu->N_bytes); + container->nas_pdu.value.resize(pdu->N_bytes); + memcpy(container->nas_pdu.value.data(), pdu->msg, pdu->N_bytes); // TAI - container.tai.value = s1ap_ptr->tai; + container->tai.value = s1ap_ptr->tai; // EUTRAN_CGI - container.eutran_cgi.value = s1ap_ptr->eutran_cgi; + container->eutran_cgi.value = s1ap_ptr->eutran_cgi; // RRC Establishment Cause - container.rrc_establishment_cause.value = cause; + container->rrc_establishment_cause.value = cause; return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "InitialUEMessage"); } @@ -1416,19 +1503,19 @@ bool s1ap::ue::send_ulnastransport(srsran::unique_byte_buffer_t pdu) s1ap_pdu_c tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_UL_NAS_TRANSPORT); - asn1::s1ap::ul_nas_transport_ies_container& container = tx_pdu.init_msg().value.ul_nas_transport().protocol_ies; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + ul_nas_transport_s& container = tx_pdu.init_msg().value.ul_nas_transport(); + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; // NAS PDU - container.nas_pdu.value.resize(pdu->N_bytes); - memcpy(container.nas_pdu.value.data(), pdu->msg, pdu->N_bytes); + container->nas_pdu.value.resize(pdu->N_bytes); + memcpy(container->nas_pdu.value.data(), pdu->msg, pdu->N_bytes); // EUTRAN CGI - container.eutran_cgi.value = s1ap_ptr->eutran_cgi; + container->eutran_cgi.value = s1ap_ptr->eutran_cgi; // TAI - container.tai.value = s1ap_ptr->tai; + container->tai.value = s1ap_ptr->tai; return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UplinkNASTransport"); } @@ -1459,13 +1546,12 @@ bool s1ap::ue::send_uectxtreleaserequest(const cause_c& cause) s1ap_pdu_c tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_UE_CONTEXT_RELEASE_REQUEST); - ue_context_release_request_ies_container& container = - tx_pdu.init_msg().value.ue_context_release_request().protocol_ies; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + ue_context_release_request_s& container = tx_pdu.init_msg().value.ue_context_release_request(); + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; // Cause - container.cause.value = cause; + container->cause.value = cause; release_requested = s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextReleaseRequest"); if (not release_requested) { @@ -1488,9 +1574,9 @@ bool s1ap::ue::send_uectxtreleasecomplete() s1ap_pdu_c tx_pdu; tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_UE_CONTEXT_RELEASE); - auto& container = tx_pdu.successful_outcome().value.ue_context_release_complete().protocol_ies; - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + auto& container = tx_pdu.successful_outcome().value.ue_context_release_complete(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); // Stop TS1 Reloc Overall ts1_reloc_overall.stop(); @@ -1526,17 +1612,17 @@ void s1ap::ue::ue_ctxt_setup_complete() if (updated_erabs.empty()) { // It is ICS Failure tx_pdu.set_unsuccessful_outcome().load_info_obj(ASN1_S1AP_ID_INIT_CONTEXT_SETUP); - auto& container = tx_pdu.unsuccessful_outcome().value.init_context_setup_fail().protocol_ies; + auto& container = tx_pdu.unsuccessful_outcome().value.init_context_setup_fail(); - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); if (not failed_cfg_erabs.empty()) { - container.cause.value = failed_cfg_erabs.front().cause; + container->cause.value = failed_cfg_erabs.front().cause; } else { logger.warning("Procedure %s,rnti=0x%x - no specified cause for failed configuration", s1ap_elem_procs_o::init_msg_c::types_opts{current_state}.to_string(), ctxt.rnti); - container.cause.value.set_misc().value = cause_misc_opts::unspecified; + container->cause.value.set_misc().value = cause_misc_opts::unspecified; } s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextModificationFailure"); return; @@ -1544,23 +1630,23 @@ void s1ap::ue::ue_ctxt_setup_complete() // It is ICS Response tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_INIT_CONTEXT_SETUP); - auto& container = tx_pdu.successful_outcome().value.init_context_setup_resp().protocol_ies; + auto& container = tx_pdu.successful_outcome().value.init_context_setup_resp(); // Fill in the MME and eNB IDs - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; // Add list of E-RABs that were not setup if (not failed_cfg_erabs.empty()) { - container.erab_failed_to_setup_list_ctxt_su_res_present = true; - fill_erab_failed_setup_list(container.erab_failed_to_setup_list_ctxt_su_res.value, failed_cfg_erabs); + container->erab_failed_to_setup_list_ctxt_su_res_present = true; + fill_erab_failed_setup_list(container->erab_failed_to_setup_list_ctxt_su_res.value, failed_cfg_erabs); } // Add setup E-RABs - container.erab_setup_list_ctxt_su_res.value.resize(updated_erabs.size()); + container->erab_setup_list_ctxt_su_res.value.resize(updated_erabs.size()); for (size_t i = 0; i < updated_erabs.size(); ++i) { - container.erab_setup_list_ctxt_su_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_CTXT_SU_RES); - auto& item = container.erab_setup_list_ctxt_su_res.value[i].value.erab_setup_item_ctxt_su_res(); + container->erab_setup_list_ctxt_su_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_CTXT_SU_RES); + auto& item = container->erab_setup_list_ctxt_su_res.value[i]->erab_setup_item_ctxt_su_res(); item.erab_id = updated_erabs[i]; get_erab_addr(item.erab_id, item.transport_layer_address, item.gtp_teid); } @@ -1578,21 +1664,21 @@ bool s1ap::ue::send_erab_setup_response(const erab_id_list& erabs_setup, const e erab_setup_resp_s& res = tx_pdu.successful_outcome().value.erab_setup_resp(); // Fill in the MME and eNB IDs - res.protocol_ies.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); - res.protocol_ies.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + res->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + res->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; // Add list of E-RABs that were not setup if (not erabs_failed.empty()) { - res.protocol_ies.erab_failed_to_setup_list_bearer_su_res_present = true; - fill_erab_failed_setup_list(res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value, erabs_failed); + res->erab_failed_to_setup_list_bearer_su_res_present = true; + fill_erab_failed_setup_list(res->erab_failed_to_setup_list_bearer_su_res.value, erabs_failed); } if (not erabs_setup.empty()) { - res.protocol_ies.erab_setup_list_bearer_su_res_present = true; - res.protocol_ies.erab_setup_list_bearer_su_res.value.resize(erabs_setup.size()); + res->erab_setup_list_bearer_su_res_present = true; + res->erab_setup_list_bearer_su_res.value.resize(erabs_setup.size()); for (size_t i = 0; i < erabs_setup.size(); ++i) { - res.protocol_ies.erab_setup_list_bearer_su_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_BEARER_SU_RES); - auto& item = res.protocol_ies.erab_setup_list_bearer_su_res.value[i].value.erab_setup_item_bearer_su_res(); + res->erab_setup_list_bearer_su_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_BEARER_SU_RES); + auto& item = res->erab_setup_list_bearer_su_res.value[i]->erab_setup_item_bearer_su_res(); item.erab_id = erabs_setup[i]; get_erab_addr(item.erab_id, item.transport_layer_address, item.gtp_teid); } @@ -1609,10 +1695,10 @@ bool s1ap::ue::send_uectxtmodifyresp() s1ap_pdu_c tx_pdu; tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_UE_CONTEXT_MOD); - auto& container = tx_pdu.successful_outcome().value.ue_context_mod_resp().protocol_ies; + auto& container = tx_pdu.successful_outcome().value.ue_context_mod_resp(); - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextModificationResponse"); } @@ -1625,11 +1711,11 @@ bool s1ap::ue::send_uectxtmodifyfailure(const cause_c& cause) s1ap_pdu_c tx_pdu; tx_pdu.set_unsuccessful_outcome().load_info_obj(ASN1_S1AP_ID_UE_CONTEXT_MOD); - auto& container = tx_pdu.unsuccessful_outcome().value.ue_context_mod_fail().protocol_ies; + auto& container = tx_pdu.unsuccessful_outcome().value.ue_context_mod_fail(); - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); - container.cause.value = cause; + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container->cause.value = cause; return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextModificationFailure"); } @@ -1646,26 +1732,26 @@ bool s1ap::ue::send_erab_release_response(const erab_id_list& erabs_released, co asn1::s1ap::s1ap_pdu_c tx_pdu; tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_ERAB_RELEASE); - auto& container = tx_pdu.successful_outcome().value.erab_release_resp().protocol_ies; - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + auto& container = tx_pdu.successful_outcome().value.erab_release_resp(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); // Fill in which E-RABs were successfully released if (not erabs_released.empty()) { - container.erab_release_list_bearer_rel_comp_present = true; - container.erab_release_list_bearer_rel_comp.value.resize(erabs_released.size()); + container->erab_release_list_bearer_rel_comp_present = true; + container->erab_release_list_bearer_rel_comp.value.resize(erabs_released.size()); for (size_t i = 0; i < erabs_released.size(); ++i) { - container.erab_release_list_bearer_rel_comp.value[i].load_info_obj( + container->erab_release_list_bearer_rel_comp.value[i].load_info_obj( ASN1_S1AP_ID_ERAB_RELEASE_ITEM_BEARER_REL_COMP); - container.erab_release_list_bearer_rel_comp.value[i].value.erab_release_item_bearer_rel_comp().erab_id = + container->erab_release_list_bearer_rel_comp.value[i]->erab_release_item_bearer_rel_comp().erab_id = erabs_released[i]; } } // Fill in which E-RABs were *not* successfully released if (not erabs_failed.empty()) { - container.erab_failed_to_release_list_present = true; - fill_erab_failed_setup_list(container.erab_failed_to_release_list.value, erabs_failed); + container->erab_failed_to_release_list_present = true; + fill_erab_failed_setup_list(container->erab_failed_to_release_list.value, erabs_failed); } return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E-RABReleaseResponse"); @@ -1676,25 +1762,25 @@ bool s1ap::ue::send_erab_modify_response(const erab_id_list& erabs_modified, con asn1::s1ap::s1ap_pdu_c tx_pdu; tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_ERAB_MODIFY); - auto& container = tx_pdu.successful_outcome().value.erab_modify_resp().protocol_ies; - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + auto& container = tx_pdu.successful_outcome().value.erab_modify_resp(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); // Fill in which E-RABs were successfully released if (not erabs_modified.empty()) { - container.erab_modify_list_bearer_mod_res_present = true; - container.erab_modify_list_bearer_mod_res.value.resize(erabs_modified.size()); - for (uint32_t i = 0; i < container.erab_modify_list_bearer_mod_res.value.size(); i++) { - container.erab_modify_list_bearer_mod_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_MODIFY_ITEM_BEARER_MOD_RES); - container.erab_modify_list_bearer_mod_res.value[i].value.erab_modify_item_bearer_mod_res().erab_id = + container->erab_modify_list_bearer_mod_res_present = true; + container->erab_modify_list_bearer_mod_res.value.resize(erabs_modified.size()); + for (uint32_t i = 0; i < container->erab_modify_list_bearer_mod_res.value.size(); i++) { + container->erab_modify_list_bearer_mod_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_MODIFY_ITEM_BEARER_MOD_RES); + container->erab_modify_list_bearer_mod_res.value[i]->erab_modify_item_bearer_mod_res().erab_id = erabs_modified[i]; } } // Fill in which E-RABs were *not* successfully released if (not erabs_failed.empty()) { - container.erab_failed_to_modify_list_present = true; - fill_erab_failed_setup_list(container.erab_failed_to_modify_list.value, erabs_failed); + container->erab_failed_to_modify_list_present = true; + fill_erab_failed_setup_list(container->erab_failed_to_modify_list.value, erabs_failed); } return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E-RABModifyResponse"); @@ -1709,16 +1795,16 @@ bool s1ap::ue::send_erab_release_indication(const std::vector& erabs_s asn1::s1ap::s1ap_pdu_c tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_ERAB_RELEASE_IND); - erab_release_ind_ies_container& container = tx_pdu.init_msg().value.erab_release_ind().protocol_ies; + erab_release_ind_s& container = tx_pdu.init_msg().value.erab_release_ind(); - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); // Fill in which E-RABs were successfully released - container.erab_released_list.value.resize(erabs_successfully_released.size()); - for (size_t i = 0; i < container.erab_released_list.value.size(); ++i) { - container.erab_released_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); - container.erab_released_list.value[i].value.erab_item().erab_id = erabs_successfully_released[i]; + container->erab_released_list.value.resize(erabs_successfully_released.size()); + for (size_t i = 0; i < container->erab_released_list.value.size(); ++i) { + container->erab_released_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); + container->erab_released_list.value[i]->erab_item().erab_id = erabs_successfully_released[i]; } return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E-RABReleaseIndication"); @@ -1728,17 +1814,35 @@ bool s1ap::ue::send_ue_cap_info_indication(srsran::unique_byte_buffer_t ue_radio { asn1::s1ap::s1ap_pdu_c tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_UE_CAP_INFO_IND); - ue_cap_info_ind_ies_container& container = tx_pdu.init_msg().value.ue_cap_info_ind().protocol_ies; + ue_cap_info_ind_s& container = tx_pdu.init_msg().value.ue_cap_info_ind(); - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); - container.ue_radio_cap.value.resize(ue_radio_cap->N_bytes); - memcpy(container.ue_radio_cap.value.data(), ue_radio_cap->msg, ue_radio_cap->N_bytes); + container->ue_radio_cap.value.resize(ue_radio_cap->N_bytes); + memcpy(container->ue_radio_cap.value.data(), ue_radio_cap->msg, ue_radio_cap->N_bytes); return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UECapabilityInfoIndication"); } +void s1ap::ue::send_ho_cancel(const asn1::s1ap::cause_c& cause) +{ + // Stop handover timers + ts1_reloc_prep.stop(); + ts1_reloc_overall.stop(); + + // Send S1AP Handover Cancel + s1ap_pdu_c tx_pdu; + tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_HO_CANCEL); + ho_cancel_s& container = tx_pdu.init_msg().value.ho_cancel(); + + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->cause.value = cause; + + s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "HandoverCancel"); +} + void s1ap::ue::set_state(s1ap_proc_id_t next_state, const erab_id_list& erabs_updated, const erab_item_list& erabs_failed_to_modify) @@ -1781,6 +1885,7 @@ void s1ap::ue::get_erab_addr(uint16_t erab_id, transp_addr_t& transp_addr, asn1: bool s1ap::send_ho_required(uint16_t rnti, uint32_t target_eci, + uint16_t target_tac, srsran::plmn_id_t target_plmn, srsran::span fwd_erabs, srsran::unique_byte_buffer_t rrc_container, @@ -1795,7 +1900,8 @@ bool s1ap::send_ho_required(uint16_t rnti, } // launch procedure - if (not u->ho_prep_proc.launch(target_eci, target_plmn, fwd_erabs, std::move(rrc_container), has_direct_fwd_path)) { + if (not u->ho_prep_proc.launch( + target_eci, target_tac, target_plmn, fwd_erabs, std::move(rrc_container), has_direct_fwd_path)) { logger.error("Failed to initiate an HandoverPreparation procedure for user rnti=0x%x", u->ctxt.rnti); return false; } @@ -1889,7 +1995,7 @@ bool s1ap::sctp_send_s1ap_pdu(const asn1::s1ap::s1ap_pdu_c& tx_pdu, uint32_t rnt return false; } - // Reset the state if it is a successful or unsucessfull message + // Reset the state if it is a successful or unsuccessfull message if (tx_pdu.type() == s1ap_pdu_c::types_opts::successful_outcome || tx_pdu.type() == s1ap_pdu_c::types_opts::unsuccessful_outcome) { if (rnti != SRSRAN_INVALID_RNTI) { @@ -1958,6 +2064,9 @@ s1ap::ue* s1ap::handle_s1apmsg_ue_id(uint32_t enb_id, uint32_t mme_id) ue* user_ptr = users.find_ue_enbid(enb_id); ue* user_mme_ptr = nullptr; cause_c cause; + + logger.info("Checking UE S1 logical connection. eNB UE S1AP ID=%d, MME UE S1AP ID=%d", enb_id, mme_id); + if (user_ptr != nullptr) { if (user_ptr->ctxt.mme_ue_s1ap_id == mme_id) { // No ID inconsistency found @@ -2058,6 +2167,7 @@ s1ap::ue::ue(s1ap* s1ap_ptr_) : s1ap_ptr(s1ap_ptr_), ho_prep_proc(this), logger( } bool s1ap::ue::send_ho_required(uint32_t target_eci, + uint16_t target_tac, srsran::plmn_id_t target_plmn, srsran::span fwd_erabs, srsran::unique_byte_buffer_t rrc_container, @@ -2066,29 +2176,29 @@ bool s1ap::ue::send_ho_required(uint32_t target_eci, /*** Setup S1AP PDU as HandoverRequired ***/ s1ap_pdu_c tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_HO_PREP); - ho_required_ies_container& container = tx_pdu.init_msg().value.ho_required().protocol_ies; + ho_required_s& container = tx_pdu.init_msg().value.ho_required(); /*** fill HO Required message ***/ - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); - container.handov_type.value.value = handov_type_opts::intralte; // NOTE: only intra-LTE HO supported - container.cause.value.set_radio_network().value = cause_radio_network_opts::ho_desirable_for_radio_reason; - - container.direct_forwarding_path_availability_present = has_direct_fwd_path; - if (container.direct_forwarding_path_availability_present) { - container.direct_forwarding_path_availability.value.value = + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container->handov_type.value.value = handov_type_opts::intralte; // NOTE: only intra-LTE HO supported + container->cause.value.set_radio_network().value = cause_radio_network_opts::ho_desirable_for_radio_reason; + + container->direct_forwarding_path_availability_present = has_direct_fwd_path; + if (container->direct_forwarding_path_availability_present) { + container->direct_forwarding_path_availability.value.value = asn1::s1ap::direct_forwarding_path_availability_opts::direct_path_available; } /*** set the target eNB ***/ - container.csg_id_present = false; // NOTE: CSG/hybrid target cell not supported - container.cell_access_mode_present = false; // only for hybrid cells + container->csg_id_present = false; // NOTE: CSG/hybrid target cell not supported + container->cell_access_mode_present = false; // only for hybrid cells // no GERAN/UTRAN/PS - auto& targetenb = container.target_id.value.set_targetenb_id(); + auto& targetenb = container->target_id.value.set_targetenb_id(); // set PLMN and TAI of target // NOTE: Only HO without TAU supported. uint16_t tmp16; - tmp16 = htons(s1ap_ptr->args.tac); + tmp16 = htons(target_tac); memcpy(targetenb.sel_tai.tac.data(), &tmp16, sizeof(uint16_t)); target_plmn.to_s1ap_plmn_bytes(targetenb.sel_tai.plm_nid.data()); // NOTE: Only HO to different Macro eNB is supported. @@ -2097,7 +2207,7 @@ bool s1ap::ue::send_ho_required(uint32_t target_eci, macroenb.from_number(target_eci >> 8U); /*** fill the transparent container ***/ - container.source_to_target_transparent_container_secondary_present = false; + container->source_to_target_transparent_container_secondary_present = false; sourceenb_to_targetenb_transparent_container_s transparent_cntr; transparent_cntr.subscriber_profile_idfor_rfp_present = false; // TODO: CHECK @@ -2105,9 +2215,9 @@ bool s1ap::ue::send_ho_required(uint32_t target_eci, transparent_cntr.erab_info_list.resize(fwd_erabs.size()); for (uint32_t i = 0; i < fwd_erabs.size(); ++i) { transparent_cntr.erab_info_list[i].load_info_obj(ASN1_S1AP_ID_ERAB_INFO_LIST_ITEM); - transparent_cntr.erab_info_list[i].value.erab_info_list_item().erab_id = fwd_erabs[i]; - transparent_cntr.erab_info_list[i].value.erab_info_list_item().dl_forwarding_present = true; - transparent_cntr.erab_info_list[i].value.erab_info_list_item().dl_forwarding.value = + transparent_cntr.erab_info_list[i]->erab_info_list_item().erab_id = fwd_erabs[i]; + transparent_cntr.erab_info_list[i]->erab_info_list_item().dl_forwarding_present = true; + transparent_cntr.erab_info_list[i]->erab_info_list_item().dl_forwarding.value = dl_forwarding_opts::dl_forwarding_proposed; } // - set target cell ID @@ -2143,8 +2253,8 @@ bool s1ap::ue::send_ho_required(uint32_t target_eci, logger.error("Failed to pack transparent container of HO Required message"); return false; } - container.source_to_target_transparent_container.value.resize(bref.distance_bytes()); - memcpy(container.source_to_target_transparent_container.value.data(), buffer->msg, bref.distance_bytes()); + container->source_to_target_transparent_container.value.resize(bref.distance_bytes()); + memcpy(container->source_to_target_transparent_container.value.data(), buffer->msg, bref.distance_bytes()); // Send to HandoverRequired message to MME return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "Handover Required"); @@ -2158,17 +2268,17 @@ bool s1ap::ue::send_enb_status_transfer_proc(std::vector& be s1ap_pdu_c tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_ENB_STATUS_TRANSFER); - enb_status_transfer_ies_container& container = tx_pdu.init_msg().value.enb_status_transfer().protocol_ies; + enb_status_transfer_s& container = tx_pdu.init_msg().value.enb_status_transfer(); - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container->enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container->mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); /* Create StatusTransfer transparent container with all the bearer ctxt to transfer */ - auto& list = container.enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list; + auto& list = container->enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list; list.resize(bearer_status_list.size()); for (uint32_t i = 0; i < list.size(); ++i) { list[i].load_info_obj(ASN1_S1AP_ID_BEARERS_SUBJECT_TO_STATUS_TRANSFER_ITEM); - auto& asn1bearer = list[i].value.bearers_subject_to_status_transfer_item(); + auto& asn1bearer = list[i]->bearers_subject_to_status_transfer_item(); bearer_status_info& item = bearer_status_list[i]; asn1bearer.erab_id = item.erab_id; diff --git a/srsenb/src/stack/upper/CMakeLists.txt b/srsenb/src/stack/upper/CMakeLists.txt index 13d222aece..fd740ae4be 100644 --- a/srsenb/src/stack/upper/CMakeLists.txt +++ b/srsenb/src/stack/upper/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -20,7 +20,4 @@ set(SOURCES gtpu.cc pdcp.cc rlc.cc) add_library(srsenb_upper STATIC ${SOURCES}) -target_link_libraries(srsenb_upper srsran_asn1 srsran_gtpu) - -set(SOURCES sdap.cc) -add_library(srsgnb_upper STATIC ${SOURCES}) \ No newline at end of file +target_link_libraries(srsenb_upper srsran_asn1 srsran_gtpu) \ No newline at end of file diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 6b4148f542..6261cb500c 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,6 +21,7 @@ #include "srsran/upper/gtpu.h" #include "srsenb/hdr/stack/upper/gtpu.h" +#include "srsran/common/common_nr.h" #include "srsran/common/network_utils.h" #include "srsran/common/standard_streams.h" #include "srsran/common/string_helpers.h" @@ -41,9 +42,12 @@ namespace srsenb { #define TEID_IN_FMT "TEID In=0x%x" #define TEID_OUT_FMT "TEID Out=0x%x" -gtpu_tunnel_manager::gtpu_tunnel_manager(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger) : - logger(logger), task_sched(task_sched_), tunnels(1) -{} +gtpu_tunnel_manager::gtpu_tunnel_manager(srsran::task_sched_handle task_sched_, + srslog::basic_logger& logger, + srsran::srsran_rat_t ran_type_) : + logger(logger), ran_type(ran_type_), task_sched(task_sched_), tunnels(1) +{ +} void gtpu_tunnel_manager::init(const gtpu_args_t& args, pdcp_interface_gtpu* pdcp_) { @@ -66,10 +70,14 @@ gtpu_tunnel_manager::ue_bearer_tunnel_list* gtpu_tunnel_manager::find_rnti_tunne srsran::span gtpu_tunnel_manager::find_rnti_bearer_tunnels(uint16_t rnti, uint32_t eps_bearer_id) { - if (not is_lte_rb(eps_bearer_id)) { + if (ran_type == srsran::srsran_rat_t::lte and not is_eps_bearer_id(eps_bearer_id)) { logger.warning("Searching for bearer with invalid eps-BearerID=%d", eps_bearer_id); return {}; } + if (ran_type == srsran::srsran_rat_t::nr and not is_nr_pdu_session_id(eps_bearer_id)) { + logger.warning("Searching for bearer with invalid PDU Session Id=%d", eps_bearer_id); + return {}; + } auto* ue_ptr = find_rnti_tunnels(rnti); if (ue_ptr == nullptr) { return {}; @@ -83,10 +91,14 @@ gtpu_tunnel_manager::find_rnti_bearer_tunnels(uint16_t rnti, uint32_t eps_bearer const gtpu_tunnel* gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t eps_bearer_id, uint32_t teidout, uint32_t spgw_addr) { - if (not is_lte_rb(eps_bearer_id)) { + if (ran_type == srsran::srsran_rat_t::lte and not is_eps_bearer_id(eps_bearer_id)) { logger.warning("Adding TEID with invalid eps-BearerID=%d", eps_bearer_id); return nullptr; } + if (ran_type == srsran::srsran_rat_t::nr and not is_nr_pdu_session_id(eps_bearer_id)) { + logger.warning("Adding TEID with invalid PDU Session Id=%d", eps_bearer_id); + return nullptr; + } auto ret_pair = tunnels.insert(tunnel()); if (not ret_pair) { logger.warning("Unable to create new GTPU TEID In"); @@ -360,11 +372,14 @@ void gtpu_tunnel_manager::setup_forwarding(uint32_t rx_teid, uint32_t tx_teid) gtpu::gtpu(srsran::task_sched_handle task_sched_, srslog::basic_logger& logger, + srsran::srsran_rat_t ran_type_, srsran::socket_manager_itf* rx_socket_handler_) : m1u(this), task_sched(task_sched_), logger(logger), - tunnels(task_sched_, logger), + ran_type(ran_type_), + tunnels(task_sched_, logger, ran_type), + rx_socket_handler(rx_socket_handler_) { gtpu_queue = task_sched.make_task_queue(); @@ -439,7 +454,7 @@ void gtpu::write_pdu(uint16_t rnti, uint32_t eps_bearer_id, srsran::unique_byte_ { srsran::span teids = tunnels.find_rnti_bearer_tunnels(rnti, eps_bearer_id); if (teids.empty()) { - logger.warning("The rnti=0x%x,eps-BearerID=%d does not have any pdcp_active tunnel", rnti, eps_bearer_id); + logger.warning("The rnti=0x%x, eps-BearerID=%d does not have any pdcp_active tunnel", rnti, eps_bearer_id); return; } const gtpu_tunnel& tx_tun = *tunnels.find_tunnel(teids[0].teid); diff --git a/srsenb/src/stack/upper/pdcp.cc b/srsenb/src/stack/upper/pdcp.cc index 3e4ced87b8..cc30f39d90 100644 --- a/srsenb/src/stack/upper/pdcp.cc +++ b/srsenb/src/stack/upper/pdcp.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,7 +23,7 @@ #include "srsenb/hdr/common/common_enb.h" #include "srsran/interfaces/enb_gtpu_interfaces.h" #include "srsran/interfaces/enb_rlc_interfaces.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" +#include "srsran/interfaces/enb_rrc_interface_pdcp.h" namespace srsenb { diff --git a/srsenb/src/stack/upper/rlc.cc b/srsenb/src/stack/upper/rlc.cc index 758152506f..28714d3b27 100644 --- a/srsenb/src/stack/upper/rlc.cc +++ b/srsenb/src/stack/upper/rlc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,7 +23,7 @@ #include "srsenb/hdr/common/common_enb.h" #include "srsran/interfaces/enb_mac_interfaces.h" #include "srsran/interfaces/enb_pdcp_interfaces.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" +#include "srsran/interfaces/enb_rrc_interface_rlc.h" namespace srsenb { @@ -84,14 +84,17 @@ void rlc::add_user(uint16_t rnti) void rlc::rem_user(uint16_t rnti) { - pthread_rwlock_wrlock(&rwlock); + pthread_rwlock_rdlock(&rwlock); if (users.count(rnti)) { users[rnti].rlc->stop(); - users.erase(rnti); } else { logger.error("Removing rnti=0x%x. Already removed", rnti); } pthread_rwlock_unlock(&rwlock); + + pthread_rwlock_wrlock(&rwlock); + users.erase(rnti); + pthread_rwlock_unlock(&rwlock); } void rlc::clear_buffer(uint16_t rnti) @@ -109,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)) { @@ -122,7 +125,7 @@ void rlc::add_bearer_mrb(uint16_t rnti, uint32_t lcid) { pthread_rwlock_rdlock(&rwlock); if (users.count(rnti)) { - users[rnti].rlc->add_bearer_mrb(lcid); + users[rnti].rlc->add_bearer_mrb(0, lcid); } pthread_rwlock_unlock(&rwlock); } diff --git a/srsenb/test/CMakeLists.txt b/srsenb/test/CMakeLists.txt index f654b44368..18cb86918c 100644 --- a/srsenb/test/CMakeLists.txt +++ b/srsenb/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -23,7 +23,6 @@ add_subdirectory(phy) add_subdirectory(upper) add_subdirectory(rrc) add_subdirectory(s1ap) -add_subdirectory(ngap) add_executable(enb_metrics_test enb_metrics_test.cc ../src/metrics_stdout.cc ../src/metrics_csv.cc) target_link_libraries(enb_metrics_test srsran_phy srsran_common) diff --git a/srsenb/test/common/dummy_classes.h b/srsenb/test/common/dummy_classes.h index 98b9de557a..64a0e65371 100644 --- a/srsenb/test/common/dummy_classes.h +++ b/srsenb/test/common/dummy_classes.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -27,7 +27,7 @@ #include "srsran/interfaces/enb_mac_interfaces.h" #include "srsran/interfaces/enb_phy_interfaces.h" #include "srsran/interfaces/enb_rlc_interfaces.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" +#include "srsran/interfaces/enb_rrc_interface_s1ap.h" #include "srsran/interfaces/enb_s1ap_interfaces.h" namespace srsenb { @@ -76,6 +76,7 @@ class s1ap_dummy : public s1ap_interface_rrc bool is_mme_connected() override { return true; } bool send_ho_required(uint16_t rnti, uint32_t target_eci, + uint16_t target_tac, srsran::plmn_id_t target_plmn, srsran::span fwd_erabs, srsran::unique_byte_buffer_t rrc_container, diff --git a/srsenb/test/common/dummy_classes_common.h b/srsenb/test/common/dummy_classes_common.h index 4314155419..edb022b6a1 100644 --- a/srsenb/test/common/dummy_classes_common.h +++ b/srsenb/test/common/dummy_classes_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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/common/rlc_test_dummy.h b/srsenb/test/common/rlc_test_dummy.h index b8be467a81..69efea4c25 100644 --- a/srsenb/test/common/rlc_test_dummy.h +++ b/srsenb/test/common/rlc_test_dummy.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/enb_metrics_test.cc b/srsenb/test/enb_metrics_test.cc index 1a0e6bb522..19027f6f97 100644 --- a/srsenb/test/enb_metrics_test.cc +++ b/srsenb/test/enb_metrics_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -62,8 +62,8 @@ class enb_dummy : public enb_metrics_interface metrics[0].stack.mac.ues[0].dl_pmi = 1.0; metrics[0].stack.mac.ues[0].phr = 12.0; metrics[0].phy.resize(2); - metrics[0].phy[0].dl.mcs = 28.0; - metrics[0].phy[0].ul.mcs = 20.2; + metrics[0].phy[0].dl.mcs = 28.0; + metrics[0].phy[0].ul.mcs = 20.2; metrics[0].phy[0].ul.pucch_sinr = 14.2; metrics[0].phy[0].ul.pusch_sinr = 14.2; @@ -105,8 +105,8 @@ class enb_dummy : public enb_metrics_interface metrics[1].stack.mac.ues[0].dl_pmi = 1.0; metrics[1].stack.mac.ues[0].phr = 99.1; metrics[1].phy.resize(1); - metrics[1].phy[0].dl.mcs = 6.2; - metrics[1].phy[0].ul.mcs = 28.0; + metrics[1].phy[0].dl.mcs = 6.2; + metrics[1].phy[0].ul.mcs = 28.0; metrics[1].phy[0].ul.pucch_sinr = 22.2; metrics[1].phy[0].ul.pusch_sinr = 22.2; @@ -128,8 +128,8 @@ class enb_dummy : public enb_metrics_interface metrics[2].stack.mac.ues[0].dl_pmi = 1.0; metrics[2].stack.mac.ues[0].phr = 12.0; metrics[2].phy.resize(1); - metrics[2].phy[0].dl.mcs = 28.0; - metrics[2].phy[0].ul.mcs = 20.2; + metrics[2].phy[0].dl.mcs = 28.0; + metrics[2].phy[0].ul.mcs = 20.2; metrics[2].phy[0].ul.pusch_sinr = 14.2; metrics[2].phy[0].ul.pucch_sinr = 14.2; @@ -210,8 +210,7 @@ int main(int argc, char** argv) metrics_screen.set_handle(&enb); // the CSV file writer - metrics_csv metrics_file(csv_file_name); - metrics_file.set_handle(&enb); + metrics_csv metrics_file(csv_file_name, &enb); // create metrics hub and register metrics for stdout srsran::metrics_hub metricshub; diff --git a/srsenb/test/mac/CMakeLists.txt b/srsenb/test/mac/CMakeLists.txt index 83659c2da1..203b22038f 100644 --- a/srsenb/test/mac/CMakeLists.txt +++ b/srsenb/test/mac/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -85,6 +85,4 @@ add_test(sched_cqi_test sched_cqi_test) add_executable(sched_phy_resource_test sched_phy_resource_test.cc) target_link_libraries(sched_phy_resource_test srsran_common srsenb_mac srsran_mac sched_test_common) -add_test(sched_phy_resource_test sched_phy_resource_test) - -add_subdirectory(nr) \ No newline at end of file +add_test(sched_phy_resource_test sched_phy_resource_test) \ No newline at end of file diff --git a/srsenb/test/mac/nr/CMakeLists.txt b/srsenb/test/mac/nr/CMakeLists.txt deleted file mode 100644 index 1dfc119816..0000000000 --- a/srsenb/test/mac/nr/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -# -# Copyright 2013-2021 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/. -# - -add_library(sched_nr_test_suite sched_nr_common_test.cc sched_nr_ue_ded_test_suite.cc) - -add_executable(sched_nr_test sched_nr_test.cc sched_nr_sim_ue.cc) -target_link_libraries(sched_nr_test - srsgnb_mac - sched_nr_test_suite - srsran_common - ${CMAKE_THREAD_LIBS_INIT} - ${Boost_LIBRARIES}) -add_nr_test(sched_nr_test sched_nr_test) - -add_executable(sched_nr_prb_test sched_nr_prb_test.cc) -target_link_libraries(sched_nr_prb_test - srsgnb_mac - srsran_common - ${CMAKE_THREAD_LIBS_INIT} - ${Boost_LIBRARIES}) -add_nr_test(sched_nr_prb_test sched_nr_prb_test) - -add_executable(sched_nr_rar_test sched_nr_rar_test.cc) -target_link_libraries(sched_nr_rar_test srsgnb_mac sched_nr_test_suite srsran_common) -add_nr_test(sched_nr_rar_test sched_nr_rar_test) \ No newline at end of file diff --git a/srsenb/test/mac/nr/sched_nr_cfg_generators.h b/srsenb/test/mac/nr/sched_nr_cfg_generators.h deleted file mode 100644 index a2f6500415..0000000000 --- a/srsenb/test/mac/nr/sched_nr_cfg_generators.h +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#ifndef SRSRAN_SCHED_NR_CFG_GENERATORS_H -#define SRSRAN_SCHED_NR_CFG_GENERATORS_H - -#include "srsenb/hdr/stack/mac/nr/sched_nr_interface.h" -#include "srsran/common/phy_cfg_nr_default.h" - -namespace srsenb { - -inline srsran_coreset_t get_default_coreset0(uint32_t nof_prb) -{ - srsran_coreset_t coreset{}; - coreset.id = 0; - coreset.duration = 1; - coreset.precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle; - for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; ++i) { - coreset.freq_resources[i] = i < (nof_prb / 6); - } - return coreset; -} - -inline sched_nr_interface::cell_cfg_t get_default_cell_cfg( - const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}) -{ - sched_nr_interface::cell_cfg_t cell_cfg{}; - - cell_cfg.carrier = phy_cfg.carrier; - cell_cfg.duplex = phy_cfg.duplex; - cell_cfg.ssb = phy_cfg.ssb; - - cell_cfg.bwps.resize(1); - cell_cfg.bwps[0].pdcch = phy_cfg.pdcch; - cell_cfg.bwps[0].pdsch = phy_cfg.pdsch; - cell_cfg.bwps[0].pusch = phy_cfg.pusch; - cell_cfg.bwps[0].rb_width = phy_cfg.carrier.nof_prb; - - cell_cfg.bwps[0].pdcch.coreset_present[0] = true; - cell_cfg.bwps[0].pdcch.coreset[0] = get_default_coreset0(phy_cfg.carrier.nof_prb); - cell_cfg.bwps[0].pdcch.search_space_present[0] = true; - auto& ss = cell_cfg.bwps[0].pdcch.search_space[0]; - ss.id = 0; - ss.coreset_id = 0; - ss.duration = 1; - ss.type = srsran_search_space_type_common_0; - ss.nof_candidates[0] = 1; - ss.nof_candidates[1] = 1; - ss.nof_candidates[2] = 1; - ss.nof_candidates[3] = 0; - ss.nof_candidates[4] = 0; - ss.nof_formats = 1; - ss.formats[0] = srsran_dci_format_nr_1_0; - cell_cfg.bwps[0].pdcch.ra_search_space_present = true; - cell_cfg.bwps[0].pdcch.ra_search_space = cell_cfg.bwps[0].pdcch.search_space[1]; - - return cell_cfg; -} - -inline std::vector get_default_cells_cfg( - uint32_t nof_sectors, - const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}) -{ - std::vector cells; - cells.reserve(nof_sectors); - for (uint32_t i = 0; i < nof_sectors; ++i) { - cells.push_back(get_default_cell_cfg(phy_cfg)); - } - return cells; -} - -inline sched_nr_interface::ue_cfg_t get_rach_ue_cfg(uint32_t cc) -{ - sched_nr_interface::ue_cfg_t uecfg{}; - - // set Pcell - uecfg.carriers.resize(1); - uecfg.carriers[0].active = true; - uecfg.carriers[0].cc = cc; - - // set SRB0 as active - uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; - - // set basic PHY config - uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}; - uecfg.phy_cfg.csi = {}; - - return uecfg; -} - -inline sched_nr_interface::ue_cfg_t get_default_ue_cfg( - uint32_t nof_cc, - const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}) -{ - sched_nr_interface::ue_cfg_t uecfg{}; - uecfg.carriers.resize(nof_cc); - for (uint32_t cc = 0; cc < nof_cc; ++cc) { - uecfg.carriers[cc].cc = cc; - uecfg.carriers[cc].active = true; - } - uecfg.phy_cfg = phy_cfg; - uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; - - return uecfg; -} - -} // namespace srsenb - -#endif // SRSRAN_SCHED_NR_CFG_GENERATORS_H diff --git a/srsenb/test/mac/nr/sched_nr_common_test.cc b/srsenb/test/mac/nr/sched_nr_common_test.cc deleted file mode 100644 index 9f5551ed35..0000000000 --- a/srsenb/test/mac/nr/sched_nr_common_test.cc +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "sched_nr_common_test.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_cfg.h" -#include "srsran/support/srsran_test.h" - -namespace srsenb { - -void test_dl_pdcch_consistency(srsran::const_span dl_pdcchs) -{ - for (const auto& pdcch : dl_pdcchs) { - if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_ra) { - TESTASSERT_EQ(pdcch.dci.ctx.format, srsran_dci_format_nr_1_0); - TESTASSERT_EQ(pdcch.dci.ctx.ss_type, srsran_search_space_type_common_1); - TESTASSERT(pdcch.dci.ctx.location.L > 0); - } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) { - TESTASSERT(pdcch.dci.ctx.format == srsran_dci_format_nr_1_0 or pdcch.dci.ctx.format == srsran_dci_format_nr_1_1); - } - } -} - -void test_pdsch_consistency(srsran::const_span pdschs) -{ - for (const mac_interface_phy_nr::pdsch_t& pdsch : pdschs) { - TESTASSERT(pdsch.sch.grant.nof_layers > 0); - if (pdsch.sch.grant.rnti_type == srsran_rnti_type_c) { - TESTASSERT(pdsch.sch.grant.tb[0].softbuffer.tx != nullptr); - TESTASSERT(pdsch.sch.grant.tb[0].softbuffer.tx->buffer_b != nullptr); - TESTASSERT(pdsch.sch.grant.tb[0].softbuffer.tx->max_cb > 0); - } - } -} - -void test_ssb_scheduled_grant( - const srsran::slot_point& sl_point, - const sched_nr_interface::cell_cfg_t& cell_cfg, - const srsran::bounded_vector& ssb_list) -{ - /* - * Verify that, with correct SSB periodicity, dl_res has: - * 1) SSB grant - * 2) 4 LSBs of SFN in packed MIB message are correct - * 3) SSB index is 0 - */ - if (sl_point.to_uint() % (cell_cfg.ssb.periodicity_ms * (uint32_t)sl_point.nof_slots_per_subframe()) == 0) { - TESTASSERT(ssb_list.size() == 1); - auto& ssb_item = ssb_list.back(); - TESTASSERT(ssb_item.pbch_msg.sfn_4lsb == ((uint8_t)sl_point.sfn() & 0b1111)); - bool expected_hrf = sl_point.slot_idx() % SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) >= - SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) / 2; - TESTASSERT(ssb_item.pbch_msg.hrf == expected_hrf); - TESTASSERT(ssb_item.pbch_msg.ssb_idx == 0); - } - // Verify that, outside SSB periodicity, there is NO SSB grant - else { - TESTASSERT(ssb_list.size() == 0); - } -} - -} // namespace srsenb diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.cc b/srsenb/test/mac/nr/sched_nr_sim_ue.cc deleted file mode 100644 index 144f700279..0000000000 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.cc +++ /dev/null @@ -1,349 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "sched_nr_sim_ue.h" -#include "sched_nr_common_test.h" -#include "sched_nr_ue_ded_test_suite.h" -#include "srsran/common/test_common.h" -#include "srsran/common/thread_pool.h" - -namespace srsenb { - -sched_nr_ue_sim::sched_nr_ue_sim(uint16_t rnti_, - const sched_nr_interface::ue_cfg_t& ue_cfg_, - slot_point prach_slot_rx, - uint32_t preamble_idx) : - logger(srslog::fetch_basic_logger("MAC")) -{ - ctxt.rnti = rnti_; - ctxt.prach_slot_rx = prach_slot_rx; - ctxt.preamble_idx = preamble_idx; - ctxt.ue_cfg = ue_cfg_; - - ctxt.cc_list.resize(ue_cfg_.carriers.size()); - for (auto& cc : ctxt.cc_list) { - for (size_t pid = 0; pid < SCHED_NR_MAX_HARQ; ++pid) { - cc.ul_harqs[pid].pid = pid; - cc.dl_harqs[pid].pid = pid; - } - } -} - -int sched_nr_ue_sim::update(const sched_nr_cc_result_view& cc_out) -{ - update_dl_harqs(cc_out); - - for (uint32_t i = 0; i < cc_out.dl_cc_result.dl_sched.pdcch_dl.size(); ++i) { - const auto& data = cc_out.dl_cc_result.dl_sched.pdcch_dl[i]; - if (data.dci.ctx.rnti != ctxt.rnti) { - continue; - } - slot_point pdcch_slot = cc_out.slot; - uint32_t k1 = ctxt.ue_cfg.phy_cfg.harq_ack - .dl_data_to_ul_ack[pdcch_slot.slot_idx() % ctxt.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack]; - slot_point uci_slot = pdcch_slot + k1; - - ctxt.cc_list[cc_out.cc].pending_acks[uci_slot.to_uint()]++; - } - - // clear up old slots - ctxt.cc_list[cc_out.cc].pending_acks[(cc_out.slot - 1).to_uint()] = 0; - - return SRSRAN_SUCCESS; -} - -void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_result_view& cc_out) -{ - uint32_t cc = cc_out.cc; - for (uint32_t i = 0; i < cc_out.dl_cc_result.dl_sched.pdcch_dl.size(); ++i) { - const auto& data = cc_out.dl_cc_result.dl_sched.pdcch_dl[i]; - if (data.dci.ctx.rnti != ctxt.rnti) { - continue; - } - auto& h = ctxt.cc_list[cc].dl_harqs[data.dci.pid]; - if (h.nof_txs == 0 or h.ndi != data.dci.ndi) { - // It is newtx - h.nof_retxs = 0; - h.ndi = data.dci.ndi; - h.first_slot_tx = cc_out.slot; - h.dci_loc = data.dci.ctx.location; - h.tbs = 100; // TODO - } else { - // it is retx - h.nof_retxs++; - } - h.active = true; - h.last_slot_tx = cc_out.slot; - h.last_slot_ack = - h.last_slot_tx + - ctxt.ue_cfg.phy_cfg.harq_ack - .dl_data_to_ul_ack[h.last_slot_tx.slot_idx() % ctxt.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack]; - h.nof_txs++; - } -} - -sched_nr_base_tester::sched_nr_base_tester(const sched_nr_interface::sched_args_t& sched_args, - const std::vector& cell_cfg_list, - std::string test_name_, - uint32_t nof_workers) : - logger(srslog::fetch_basic_logger("TEST")), - mac_logger(srslog::fetch_basic_logger("MAC")), - sched_ptr(new sched_nr()), - test_name(std::move(test_name_)) -{ - sem_init(&slot_sem, 0, 1); - - printf("\n=========== Start %s ===========\n", test_name.c_str()); - cell_params.reserve(cell_cfg_list.size()); - for (uint32_t cc = 0; cc < cell_cfg_list.size(); ++cc) { - cell_params.emplace_back(cc, cell_cfg_list[cc], sched_args); - } - sched_ptr->config(sched_args, cell_cfg_list); // call parent cfg - - cc_workers.resize(nof_workers - 1); - for (uint32_t i = 0; i < cc_workers.size(); ++i) { - fmt::memory_buffer fmtbuf; - fmt::format_to(fmtbuf, "worker{}", i + 1); - cc_workers[i].reset(new srsran::task_worker{to_string(fmtbuf), 10}); - } - - cc_results.resize(cell_params.size()); - - TESTASSERT(cell_params.size() > 0); -} - -sched_nr_base_tester::~sched_nr_base_tester() -{ - stop(); -} - -void sched_nr_base_tester::stop() -{ - bool stopping = not stopped.exchange(true); - if (stopping) { - sem_wait(&slot_sem); - sem_post(&slot_sem); - for (auto& worker : cc_workers) { - worker->stop(); - } - sem_destroy(&slot_sem); - printf("============ End %s ===========\n", test_name.c_str()); - } -} - -int sched_nr_base_tester::add_user(uint16_t rnti, - const sched_nr_interface::ue_cfg_t& ue_cfg_, - slot_point tti_rx, - uint32_t preamble_idx) -{ - sem_wait(&slot_sem); - sched_ptr->ue_cfg(rnti, ue_cfg_); - - TESTASSERT(ue_db.count(rnti) == 0); - - ue_db.insert(std::make_pair(rnti, sched_nr_ue_sim(rnti, ue_cfg_, current_slot_tx, preamble_idx))); - - sched_nr_interface::rar_info_t rach_info{}; - rach_info.temp_crnti = rnti; - rach_info.prach_slot = tti_rx; - rach_info.preamble_idx = preamble_idx; - rach_info.msg3_size = 7; - sched_ptr->dl_rach_info(ue_cfg_.carriers[0].cc, rach_info); - - sem_post(&slot_sem); - - return SRSRAN_SUCCESS; -} - -void sched_nr_base_tester::run_slot(slot_point slot_tx) -{ - srsran_assert(not stopped.load(std::memory_order_relaxed), "Running scheduler when it has already been stopped"); - // Block concurrent or out-of-order calls to the scheduler - sem_wait(&slot_sem); - current_slot_tx = slot_tx; - nof_cc_remaining = cell_params.size(); - - logger.set_context(slot_tx.to_uint()); - mac_logger.set_context(slot_tx.to_uint()); - - // Clear previous slot results - for (uint32_t cc = 0; cc < cc_results.size(); ++cc) { - cc_results[cc] = {}; - } - logger.info("---------------- TTI=%d ---------------", slot_tx.to_uint()); - - // Process pending feedback - for (auto& ue : ue_db) { - ue_nr_slot_events events; - set_default_slot_events(ue.second.get_ctxt(), events); - set_external_slot_events(ue.second.get_ctxt(), events); - apply_slot_events(ue.second.get_ctxt(), events); - } - - slot_ctxt = get_enb_ctxt(); - slot_start_tp = std::chrono::steady_clock::now(); - - // Generate CC result (parallel or serialized) - uint32_t worker_idx = 0; - for (uint32_t cc = 0; cc < cell_params.size(); ++cc) { - if (worker_idx == cc_workers.size()) { - generate_cc_result(cc); - } else { - cc_workers[worker_idx]->push_task([this, cc]() { generate_cc_result(cc); }); - } - worker_idx = (worker_idx + 1) % (cc_workers.size() + 1); - } -} - -void sched_nr_base_tester::generate_cc_result(uint32_t cc) -{ - // Run scheduler - sched_nr_interface::dl_res_t dl_sched(cc_results[cc].rar, cc_results[cc].dl_res); - sched_ptr->run_slot(current_slot_tx, cc, dl_sched); - cc_results[cc].rar = dl_sched.rar; - sched_ptr->get_ul_sched(current_slot_tx, cc, cc_results[cc].ul_res); - auto tp2 = std::chrono::steady_clock::now(); - cc_results[cc].cc_latency_ns = std::chrono::duration_cast(tp2 - slot_start_tp); - - if (--nof_cc_remaining > 0) { - // there are still missing CC results - return; - } - - // Run tests and update UE state - process_results(); - - // Notify awaiting new slot worker - sem_post(&slot_sem); -} - -void sched_nr_base_tester::process_results() -{ - // Derived class-defined tests - process_slot_result(slot_ctxt, cc_results); - - for (uint32_t cc = 0; cc < cell_params.size(); ++cc) { - sched_nr_cc_result_view cc_out{ - current_slot_tx, cc, cc_results[cc].rar, cc_results[cc].dl_res, cc_results[cc].ul_res}; - - // Run common tests - test_dl_pdcch_consistency(cc_out.dl_cc_result.dl_sched.pdcch_dl); - test_pdsch_consistency(cc_out.dl_cc_result.dl_sched.pdsch); - test_ssb_scheduled_grant(cc_out.slot, cell_params[cc_out.cc].cfg, cc_out.dl_cc_result.dl_sched.ssb); - - // Run UE-dedicated tests - test_dl_sched_result(slot_ctxt, cc_out); - - // Update UE state - for (auto& u : ue_db) { - u.second.update(cc_out); - } - } -} - -int sched_nr_base_tester::set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events) -{ - pending_events.cc_list.clear(); - pending_events.cc_list.resize(cell_params.size()); - pending_events.slot_rx = current_slot_tx; - - for (uint32_t enb_cc_idx = 0; enb_cc_idx < pending_events.cc_list.size(); ++enb_cc_idx) { - auto& cc_feedback = pending_events.cc_list[enb_cc_idx]; - - cc_feedback.configured = true; - for (uint32_t pid = 0; pid < SCHED_NR_MAX_HARQ; ++pid) { - auto& dl_h = ue_ctxt.cc_list[enb_cc_idx].dl_harqs[pid]; - auto& ul_h = ue_ctxt.cc_list[enb_cc_idx].ul_harqs[pid]; - - // Set default DL ACK - if (dl_h.active and (dl_h.last_slot_ack) == current_slot_tx) { - cc_feedback.dl_acks.push_back(ue_nr_slot_events::ack_t{pid, true}); - } - - // Set default UL ACK - if (ul_h.active and (ul_h.last_slot_tx + 8) == current_slot_tx) { - cc_feedback.ul_acks.emplace_back(ue_nr_slot_events::ack_t{pid, true}); - } - - // TODO: other CSI - } - } - - return SRSRAN_SUCCESS; -} - -int sched_nr_base_tester::apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_slot_events& events) -{ - for (uint32_t enb_cc_idx = 0; enb_cc_idx < events.cc_list.size(); ++enb_cc_idx) { - const auto& cc_feedback = events.cc_list[enb_cc_idx]; - if (not cc_feedback.configured) { - continue; - } - - for (auto& ack : cc_feedback.dl_acks) { - auto& h = ue_ctxt.cc_list[enb_cc_idx].dl_harqs[ack.pid]; - - if (ack.ack) { - logger.info( - "DL ACK rnti=0x%x slot_dl_tx=%u cc=%d pid=%d", ue_ctxt.rnti, h.last_slot_tx.to_uint(), enb_cc_idx, ack.pid); - } - - // update scheduler - sched_ptr->dl_ack_info(ue_ctxt.rnti, enb_cc_idx, h.pid, 0, ack.ack); - - // update UE sim context - if (ack.ack or ue_ctxt.is_last_dl_retx(enb_cc_idx, h.pid)) { - h.active = false; - } - } - - for (auto& ack : cc_feedback.ul_acks) { - auto& h = ue_ctxt.cc_list[enb_cc_idx].ul_harqs[ack.pid]; - - if (ack.ack) { - logger.info( - "UL ACK rnti=0x%x, slot_ul_tx=%u, cc=%d pid=%d", ue_ctxt.rnti, h.last_slot_tx.to_uint(), enb_cc_idx, h.pid); - } - - // // update scheduler - // if (sched_ptr->ul_crc_info(events.slot_rx.to_uint(), ue_ctxt.rnti, enb_cc_idx, cc_feedback.ul_ack) < 0) { - // logger.error("The ACKed UL Harq pid=%d does not exist.", cc_feedback.ul_pid); - // error_counter++; - // } - } - } - - return SRSRAN_SUCCESS; -} - -sim_nr_enb_ctxt_t sched_nr_base_tester::get_enb_ctxt() const -{ - sim_nr_enb_ctxt_t ctxt; - ctxt.cell_params = cell_params; - - for (auto& ue_pair : ue_db) { - ctxt.ue_db.insert(std::make_pair(ue_pair.first, &ue_pair.second.get_ctxt())); - } - - return ctxt; -} - -} // namespace srsenb \ No newline at end of file diff --git a/srsenb/test/mac/sched_benchmark.cc b/srsenb/test/mac/sched_benchmark.cc index 46743f4674..5b81142171 100644 --- a/srsenb/test/mac/sched_benchmark.cc +++ b/srsenb/test/mac/sched_benchmark.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_ca_test.cc b/srsenb/test/mac/sched_ca_test.cc index d9f85aa7ea..67efea64c5 100644 --- a/srsenb/test/mac/sched_ca_test.cc +++ b/srsenb/test/mac/sched_ca_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_common_test_suite.cc b/srsenb/test/mac/sched_common_test_suite.cc index 6b7d52504c..98e4abf230 100644 --- a/srsenb/test/mac/sched_common_test_suite.cc +++ b/srsenb/test/mac/sched_common_test_suite.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_common_test_suite.h b/srsenb/test/mac/sched_common_test_suite.h index f5c3ebb627..0aa0a5cf8f 100644 --- a/srsenb/test/mac/sched_common_test_suite.h +++ b/srsenb/test/mac/sched_common_test_suite.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_cqi_test.cc b/srsenb/test/mac/sched_cqi_test.cc index fc349d69a3..01c05726b4 100644 --- a/srsenb/test/mac/sched_cqi_test.cc +++ b/srsenb/test/mac/sched_cqi_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_dci_test.cc b/srsenb/test/mac/sched_dci_test.cc index 44f74410a5..45a8c522d7 100644 --- a/srsenb/test/mac/sched_dci_test.cc +++ b/srsenb/test/mac/sched_dci_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_grid_test.cc b/srsenb/test/mac/sched_grid_test.cc index e6ffb8f81e..7c815a7e79 100644 --- a/srsenb/test/mac/sched_grid_test.cc +++ b/srsenb/test/mac/sched_grid_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_lc_ch_test.cc b/srsenb/test/mac/sched_lc_ch_test.cc index a782d62e10..306b7f4358 100644 --- a/srsenb/test/mac/sched_lc_ch_test.cc +++ b/srsenb/test/mac/sched_lc_ch_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_phy_resource_test.cc b/srsenb/test/mac/sched_phy_resource_test.cc index 79c38e16d6..b76b41bb03 100644 --- a/srsenb/test/mac/sched_phy_resource_test.cc +++ b/srsenb/test/mac/sched_phy_resource_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_sim_ue.cc b/srsenb/test/mac/sched_sim_ue.cc index 18da3bacf3..f74ec25fe4 100644 --- a/srsenb/test/mac/sched_sim_ue.cc +++ b/srsenb/test/mac/sched_sim_ue.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_sim_ue.h b/srsenb/test/mac/sched_sim_ue.h index 8374966e2d..276fe54ec9 100644 --- a/srsenb/test/mac/sched_sim_ue.h +++ b/srsenb/test/mac/sched_sim_ue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_test_common.cc b/srsenb/test/mac/sched_test_common.cc index b8b22452c7..41367c7483 100644 --- a/srsenb/test/mac/sched_test_common.cc +++ b/srsenb/test/mac/sched_test_common.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_test_common.h b/srsenb/test/mac/sched_test_common.h index b3ff3c2d96..ac82740ab1 100644 --- a/srsenb/test/mac/sched_test_common.h +++ b/srsenb/test/mac/sched_test_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -25,7 +25,7 @@ #include "sched_sim_ue.h" #include "sched_test_utils.h" #include "srsenb/hdr/stack/mac/sched.h" -#include "srsran/interfaces/enb_rrc_interfaces.h" +#include "srsran/interfaces/enb_rrc_interface_mac.h" #include "srsran/srslog/srslog.h" #include diff --git a/srsenb/test/mac/sched_test_rand.cc b/srsenb/test/mac/sched_test_rand.cc index 28f58e18d9..3c4a40d431 100644 --- a/srsenb/test/mac/sched_test_rand.cc +++ b/srsenb/test/mac/sched_test_rand.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -137,7 +137,7 @@ void sched_tester::before_sched() for (auto& it : ue_db) { uint16_t rnti = it.first; srsenb::sched_ue* user = it.second.get(); - tester_user_results d; + tester_user_results d = {}; tti_data.ue_data.insert(std::make_pair(rnti, d)); // NOTE: ACK might have just cleared the harq for tti_info.tti_params.tti_tx_ul diff --git a/srsenb/test/mac/sched_test_utils.h b/srsenb/test/mac/sched_test_utils.h index 00e098c162..09690f99ed 100644 --- a/srsenb/test/mac/sched_test_utils.h +++ b/srsenb/test/mac/sched_test_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_tpc_test.cc b/srsenb/test/mac/sched_tpc_test.cc index 5569c4a109..f242ed0a37 100644 --- a/srsenb/test/mac/sched_tpc_test.cc +++ b/srsenb/test/mac/sched_tpc_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_ue_cell_test.cc b/srsenb/test/mac/sched_ue_cell_test.cc index fb126d0041..0556443b9e 100644 --- a/srsenb/test/mac/sched_ue_cell_test.cc +++ b/srsenb/test/mac/sched_ue_cell_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_ue_ded_test_suite.cc b/srsenb/test/mac/sched_ue_ded_test_suite.cc index 33b1f5559f..ce5f4a0adf 100644 --- a/srsenb/test/mac/sched_ue_ded_test_suite.cc +++ b/srsenb/test/mac/sched_ue_ded_test_suite.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/mac/sched_ue_ded_test_suite.h b/srsenb/test/mac/sched_ue_ded_test_suite.h index ad84501e2b..acd6636cf5 100644 --- a/srsenb/test/mac/sched_ue_ded_test_suite.h +++ b/srsenb/test/mac/sched_ue_ded_test_suite.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/test/ngap/ngap_test.cc b/srsenb/test/ngap/ngap_test.cc deleted file mode 100644 index 6efada1762..0000000000 --- a/srsenb/test/ngap/ngap_test.cc +++ /dev/null @@ -1,191 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsenb/hdr/stack/ngap/ngap.h" -#include "srsran/common/network_utils.h" -#include "srsran/common/test_common.h" - -using namespace srsenb; - -struct amf_dummy { - amf_dummy(const char* addr_str_, int port_) : addr_str(addr_str_), port(port_) - { - srsran::net_utils::set_sockaddr(&amf_sockaddr, addr_str, port); - { - using namespace srsran::net_utils; - fd = open_socket(addr_family::ipv4, socket_type::seqpacket, protocol_type::SCTP); - TESTASSERT(fd > 0); - TESTASSERT(bind_addr(fd, amf_sockaddr)); - } - - int success = listen(fd, SOMAXCONN); - srsran_assert(success == 0, "Failed to listen to incoming SCTP connections"); - } - - ~amf_dummy() - { - if (fd > 0) { - close(fd); - } - } - - srsran::unique_byte_buffer_t read_msg(sockaddr_in* sockfrom = nullptr) - { - srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); - sockaddr_in from = {}; - socklen_t fromlen = sizeof(from); - sctp_sndrcvinfo sri = {}; - int flags = 0; - ssize_t n_recv = sctp_recvmsg(fd, pdu->msg, pdu->get_tailroom(), (struct sockaddr*)&from, &fromlen, &sri, &flags); - if (n_recv > 0) { - if (sockfrom != nullptr) { - *sockfrom = from; - } - pdu->N_bytes = n_recv; - } - return pdu; - } - - const char* addr_str; - int port; - struct sockaddr_in amf_sockaddr = {}; - int fd; - srsran::unique_byte_buffer_t last_sdu; -}; - -class rrc_nr_dummy : public rrc_interface_ngap_nr -{ -public: - int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) - { - return SRSRAN_SUCCESS; - } - int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) - { - return SRSRAN_SUCCESS; - } - int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) - { - return SRSRAN_SUCCESS; - } - int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) - { - return SRSRAN_SUCCESS; - } - int start_security_mode_procedure(uint16_t rnti) { return SRSRAN_SUCCESS; } - int establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) - { - return SRSRAN_SUCCESS; - } - int release_bearers(uint16_t rnti) { return SRSRAN_SUCCESS; } - int allocate_lcid(uint16_t rnti) { return SRSRAN_SUCCESS; } - void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {} -}; -struct dummy_socket_manager : public srsran::socket_manager_itf { - dummy_socket_manager() : srsran::socket_manager_itf(srslog::fetch_basic_logger("TEST")) {} - - /// Register (fd, callback). callback is called within socket thread when fd has data. - bool add_socket_handler(int fd, recv_callback_t handler) final - { - if (s1u_fd > 0) { - return false; - } - s1u_fd = fd; - callback = std::move(handler); - return true; - } - - /// remove registered socket fd - bool remove_socket(int fd) final - { - if (s1u_fd < 0) { - return false; - } - s1u_fd = -1; - return true; - } - - int s1u_fd = 0; - recv_callback_t callback; -}; - -void run_ng_setup(ngap& ngap_obj, amf_dummy& amf) -{ - asn1::ngap_nr::ngap_pdu_c ngap_pdu; - - // gNB -> AMF: NG Setup Request - srsran::unique_byte_buffer_t sdu = amf.read_msg(); - TESTASSERT(sdu->N_bytes > 0); - asn1::cbit_ref cbref(sdu->msg, sdu->N_bytes); - TESTASSERT(ngap_pdu.unpack(cbref) == asn1::SRSASN_SUCCESS); - TESTASSERT(ngap_pdu.type().value == asn1::ngap_nr::ngap_pdu_c::types_opts::init_msg); - TESTASSERT(ngap_pdu.init_msg().proc_code == ASN1_NGAP_NR_ID_NG_SETUP); - - // AMF -> gNB: ng Setup Response - sockaddr_in amf_addr = {}; - sctp_sndrcvinfo rcvinfo = {}; - int flags = 0; - - uint8_t ng_setup_resp[] = {0x20, 0x15, 0x00, 0x55, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x31, 0x17, 0x00, 0x61, 0x6d, - 0x61, 0x72, 0x69, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x61, 0x6d, 0x66, 0x2e, 0x35, 0x67, 0x63, - 0x2e, 0x6d, 0x6e, 0x63, 0x30, 0x30, 0x31, 0x2e, 0x6d, 0x63, 0x63, 0x30, 0x30, 0x31, 0x2e, - 0x33, 0x67, 0x70, 0x70, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x6f, 0x72, 0x67, - 0x00, 0x60, 0x00, 0x08, 0x00, 0x00, 0x00, 0xf1, 0x10, 0x80, 0x01, 0x01, 0x00, 0x56, 0x40, - 0x01, 0x32, 0x00, 0x50, 0x00, 0x08, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x00, 0x00, 0x08}; - memcpy(sdu->msg, ng_setup_resp, sizeof(ng_setup_resp)); - sdu->N_bytes = sizeof(ng_setup_resp); - TESTASSERT(ngap_obj.handle_amf_rx_msg(std::move(sdu), amf_addr, rcvinfo, flags)); -} - -int main(int argc, char** argv) -{ - // Setup logging. - auto& logger = srslog::fetch_basic_logger("NGAP"); - logger.set_level(srslog::basic_levels::debug); - logger.set_hex_dump_max_size(-1); - - srsran::task_scheduler task_sched; - dummy_socket_manager rx_sockets; - ngap ngap_obj(&task_sched, logger, &rx_sockets); - - const char* amf_addr_str = "127.0.0.1"; - const uint32_t AMF_PORT = 38412; - amf_dummy amf(amf_addr_str, AMF_PORT); - - ngap_args_t args = {}; - args.cell_id = 0x01; - args.gnb_id = 0x19B; - args.mcc = 907; - args.mnc = 70; - args.ngc_bind_addr = "127.0.0.100"; - args.tac = 7; - args.gtp_bind_addr = "127.0.0.100"; - args.amf_addr = "127.0.0.1"; - args.gnb_name = "srsgnb01"; - - rrc_nr_dummy rrc; - gtpu_interface_rrc* gtpu = nullptr; - ngap_obj.init(args, &rrc, gtpu); - - // Start the log backend. - srsran::test_init(argc, argv); - run_ng_setup(ngap_obj, amf); -} \ No newline at end of file diff --git a/srsenb/test/phy/CMakeLists.txt b/srsenb/test/phy/CMakeLists.txt index eae7d98df5..6e7f536368 100644 --- a/srsenb/test/phy/CMakeLists.txt +++ b/srsenb/test/phy/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsenb/test/phy/enb_phy_test.cc b/srsenb/test/phy/enb_phy_test.cc index d90a87b240..d5bc3ead3a 100644 --- a/srsenb/test/phy/enb_phy_test.cc +++ b/srsenb/test/phy/enb_phy_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -1218,8 +1218,8 @@ class phy_test_bench : public srsenb::enb_time_interface srslog::basic_logger& logger; args_t args = {}; ///< Test arguments - srsenb::phy_args_t phy_args; ///< PHY arguments - srsenb::phy_cfg_t phy_cfg; ///< eNb Cell/Carrier configuration + srsenb::phy_args_t phy_args = {}; ///< PHY arguments + srsenb::phy_cfg_t phy_cfg = {}; ///< eNb Cell/Carrier configuration srsenb::phy_interface_rrc_lte::phy_rrc_cfg_list_t phy_rrc_cfg; ///< UE PHY configuration uint64_t tti_counter = 0; diff --git a/srsenb/test/rrc/CMakeLists.txt b/srsenb/test/rrc/CMakeLists.txt index 53f008b4d8..b07a2b3f31 100644 --- a/srsenb/test/rrc/CMakeLists.txt +++ b/srsenb/test/rrc/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -18,13 +18,9 @@ # and at http://www.gnu.org/licenses/. # -add_library(test_helpers test_helpers.cc) +add_library(test_helpers STATIC test_helpers.cc) target_link_libraries(test_helpers srsenb_rrc srsenb_common rrc_asn1 rrc_nr_asn1 s1ap_asn1 srsran_common enb_cfg_parser ${LIBCONFIGPP_LIBRARIES}) -add_executable(rrc_nr_test rrc_nr_test.cc) -target_link_libraries(rrc_nr_test srsgnb_rrc test_helpers ${ATOMIC_LIBS}) -add_test(rrc_nr_test rrc_nr_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..) - add_executable(rrc_meascfg_test rrc_meascfg_test.cc) target_link_libraries(rrc_meascfg_test test_helpers ${ATOMIC_LIBS}) @@ -34,6 +30,10 @@ target_link_libraries(erab_setup_test test_helpers ${LIBCONFIGPP_LIBRARIES} ${AT add_executable(rrc_mobility_test rrc_mobility_test.cc) target_link_libraries(rrc_mobility_test srsran_asn1 test_helpers ${ATOMIC_LIBS}) +add_executable(rrc_paging_test rrc_paging_test.cc) +target_link_libraries(rrc_paging_test srsran_asn1 test_helpers) + add_test(rrc_mobility_test rrc_mobility_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..) add_test(erab_setup_test erab_setup_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..) add_test(rrc_meascfg_test rrc_meascfg_test -i ${CMAKE_CURRENT_SOURCE_DIR}/../..) +add_test(rrc_paging_test rrc_paging_test) diff --git a/srsenb/test/rrc/erab_setup_test.cc b/srsenb/test/rrc/erab_setup_test.cc index 3b72bb5447..9c67ac17a2 100644 --- a/srsenb/test/rrc/erab_setup_test.cc +++ b/srsenb/test/rrc/erab_setup_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -53,7 +53,7 @@ int test_erab_setup(srsran::log_sink_spy& spy, bool qci_exists) rrc.init(cfg, &phy, &mac, &rlc, &pdcp, &s1ap, >pu); uint16_t rnti = 0x46; - sched_interface::ue_cfg_t ue_cfg; + sched_interface::ue_cfg_t ue_cfg = {}; ue_cfg.supported_cc_list.resize(1); ue_cfg.supported_cc_list[0].active = true; ue_cfg.supported_cc_list[0].enb_cc_idx = 0; @@ -98,12 +98,12 @@ int test_erab_setup(srsran::log_sink_spy& spy, bool qci_exists) asn1::cbit_ref bref(byte_buf.msg, byte_buf.N_bytes); TESTASSERT(s1ap_pdu.unpack(bref) == asn1::SRSASN_SUCCESS); - const auto& setupmsg = s1ap_pdu.init_msg().value.erab_setup_request().protocol_ies; - if (setupmsg.ueaggregate_maximum_bitrate_present) { - rrc.set_aggregate_max_bitrate(rnti, setupmsg.ueaggregate_maximum_bitrate.value); + const auto& setupmsg = s1ap_pdu.init_msg().value.erab_setup_request(); + if (setupmsg->ueaggregate_maximum_bitrate_present) { + rrc.set_aggregate_max_bitrate(rnti, setupmsg->ueaggregate_maximum_bitrate.value); } - for (const auto& item : setupmsg.erab_to_be_setup_list_bearer_su_req.value) { - const auto& erab = item.value.erab_to_be_setup_item_bearer_su_req(); + for (const auto& item : setupmsg->erab_to_be_setup_list_bearer_su_req.value) { + const auto& erab = item->erab_to_be_setup_item_bearer_su_req(); asn1::s1ap::cause_c cause; int ret = rrc.setup_erab(rnti, erab.erab_id, diff --git a/srsenb/test/rrc/rrc_meascfg_test.cc b/srsenb/test/rrc/rrc_meascfg_test.cc index f141e77542..878150da93 100644 --- a/srsenb/test/rrc/rrc_meascfg_test.cc +++ b/srsenb/test/rrc/rrc_meascfg_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,10 +21,10 @@ #include "srsenb/hdr/enb.h" #include "srsenb/hdr/stack/rrc/ue_meas_cfg.h" +#include "srsran/asn1/obj_id_cmp_utils.h" #include "srsran/asn1/rrc_utils.h" #include "srsran/common/test_common.h" #include "srsran/interfaces/enb_rrc_interface_types.h" -#include "srsran/rrc/rrc_cfg_utils.h" #include "test_helpers.h" using namespace asn1::rrc; diff --git a/srsenb/test/rrc/rrc_mobility_test.cc b/srsenb/test/rrc/rrc_mobility_test.cc index a6f711b3ac..243adc799e 100644 --- a/srsenb/test/rrc/rrc_mobility_test.cc +++ b/srsenb/test/rrc/rrc_mobility_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -281,14 +281,14 @@ int test_s1ap_tenb_mobility(test_event test_params) /* TeNB receives S1AP Handover Request */ asn1::s1ap::ho_request_s ho_req; - ho_req.protocol_ies.erab_to_be_setup_list_ho_req.value.resize(1); - auto& erab = ho_req.protocol_ies.erab_to_be_setup_list_ho_req.value[0].value.erab_to_be_setup_item_ho_req(); - erab.erab_id = 5; + ho_req->erab_to_be_setup_list_ho_req.value.resize(1); + auto& erab = ho_req->erab_to_be_setup_list_ho_req.value[0]->erab_to_be_setup_item_ho_req(); + erab.erab_id = 5; erab.erab_level_qos_params.qci = 9; if (test_params == test_event::unknown_qci) { erab.erab_level_qos_params.qci = 10; } - ho_req.protocol_ies.ue_security_cap.value.integrity_protection_algorithms.set(14, true); + ho_req->ue_security_cap.value.integrity_protection_algorithms.set(14, true); asn1::s1ap::sourceenb_to_targetenb_transparent_container_s container; container.target_cell_id.cell_id.from_number(0x19C02); if (test_params == test_event::wrong_target_cell) { @@ -297,9 +297,9 @@ int test_s1ap_tenb_mobility(test_event test_params) container.erab_info_list_present = true; container.erab_info_list.resize(1); container.erab_info_list[0].load_info_obj(ASN1_S1AP_ID_ERAB_INFO_LIST_ITEM); - container.erab_info_list[0].value.erab_info_list_item().erab_id = 5; - container.erab_info_list[0].value.erab_info_list_item().dl_forwarding_present = true; - container.erab_info_list[0].value.erab_info_list_item().dl_forwarding.value = + container.erab_info_list[0]->erab_info_list_item().erab_id = 5; + container.erab_info_list[0]->erab_info_list_item().dl_forwarding_present = true; + container.erab_info_list[0]->erab_info_list_item().dl_forwarding.value = asn1::s1ap::dl_forwarding_opts::dl_forwarding_proposed; uint8_t ho_prep_container[] = { 0x0a, 0x10, 0x0b, 0x81, 0x80, 0x00, 0x01, 0x80, 0x00, 0xf3, 0x02, 0x08, 0x00, 0x00, 0x15, 0x80, 0x00, 0x14, @@ -327,21 +327,32 @@ int test_s1ap_tenb_mobility(test_event test_params) TESTASSERT(tester.rrc.get_nof_users() == 0); return SRSRAN_SUCCESS; } + TESTASSERT(tester.mac.ue_db.count(0x46)); + auto& mac_ue = tester.mac.ue_db[0x46]; + TESTASSERT(mac_ue.supported_cc_list[0].active); + TESTASSERT(mac_ue.supported_cc_list[0].enb_cc_idx == 0); + TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb0)].direction == mac_lc_ch_cfg_t::BOTH); + TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb1)].direction == mac_lc_ch_cfg_t::BOTH); + TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb2)].direction == mac_lc_ch_cfg_t::IDLE); + TESTASSERT(mac_ue.ue_bearers[drb_to_lcid(lte_drb::drb1)].direction == mac_lc_ch_cfg_t::IDLE); + tester.tic(); TESTASSERT(tester.rrc.get_nof_users() == 1); TESTASSERT(tester.mac.ue_db.count(0x46)); - auto& mac_ue = tester.mac.ue_db[0x46]; TESTASSERT(mac_ue.supported_cc_list[0].active); TESTASSERT(mac_ue.supported_cc_list[0].enb_cc_idx == 0); TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb0)].direction == mac_lc_ch_cfg_t::BOTH); + TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb1)].direction == mac_lc_ch_cfg_t::BOTH); + TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb2)].direction == mac_lc_ch_cfg_t::IDLE); + TESTASSERT(mac_ue.ue_bearers[drb_to_lcid(lte_drb::drb1)].direction == mac_lc_ch_cfg_t::IDLE); // Check Security Configuration TESTASSERT(tester.pdcp.bearers.count(0x46)); TESTASSERT(tester.pdcp.bearers[0x46].count(srb_to_lcid(lte_srb::srb1)) and tester.pdcp.bearers[0x46].count(srb_to_lcid(lte_srb::srb2))); TESTASSERT(tester.pdcp.bearers[0x46][srb_to_lcid(lte_srb::srb1)].enable_encryption); TESTASSERT(tester.pdcp.bearers[0x46][srb_to_lcid(lte_srb::srb1)].enable_integrity); - sec_cfg.set_security_capabilities(ho_req.protocol_ies.ue_security_cap.value); - sec_cfg.set_security_key(ho_req.protocol_ies.security_context.value.next_hop_param); + sec_cfg.set_security_capabilities(ho_req->ue_security_cap.value); + sec_cfg.set_security_key(ho_req->security_context.value.next_hop_param); sec_cfg.regenerate_keys_handover(tester.cfg.cell_list[0].pci, tester.cfg.cell_list[0].dl_earfcn); srsran::as_security_config_t as_sec_cfg = sec_cfg.get_as_sec_cfg(); TESTASSERT(tester.pdcp.bearers[0x46][srb_to_lcid(lte_srb::srb1)].sec_cfg.k_rrc_int == as_sec_cfg.k_rrc_int); @@ -350,11 +361,14 @@ int test_s1ap_tenb_mobility(test_event test_params) TESTASSERT(tester.pdcp.bearers[0x46][srb_to_lcid(lte_srb::srb1)].sec_cfg.cipher_algo == as_sec_cfg.cipher_algo); TESTASSERT(tester.pdcp.bearers[0x46][srb_to_lcid(lte_srb::srb1)].sec_cfg.integ_algo == as_sec_cfg.integ_algo); + TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb1)].direction == mac_lc_ch_cfg_t::BOTH); + TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb2)].direction == mac_lc_ch_cfg_t::IDLE); + TESTASSERT(mac_ue.ue_bearers[drb_to_lcid(lte_drb::drb1)].direction == mac_lc_ch_cfg_t::IDLE); + // Check if S1AP Handover Request ACK send is called TESTASSERT(tester.s1ap.last_ho_req_ack.rnti == 0x46); TESTASSERT(tester.s1ap.last_ho_req_ack.ho_cmd_pdu != nullptr); - TESTASSERT(tester.s1ap.last_ho_req_ack.admitted_bearers.size() == - ho_req.protocol_ies.erab_to_be_setup_list_ho_req.value.size()); + TESTASSERT(tester.s1ap.last_ho_req_ack.admitted_bearers.size() == ho_req->erab_to_be_setup_list_ho_req.value.size()); ho_cmd_s ho_cmd; asn1::cbit_ref bref{tester.s1ap.last_ho_req_ack.ho_cmd_pdu->msg, tester.s1ap.last_ho_req_ack.ho_cmd_pdu->N_bytes}; TESTASSERT(ho_cmd.unpack(bref) == asn1::SRSASN_SUCCESS); @@ -366,14 +380,18 @@ int test_s1ap_tenb_mobility(test_event test_params) TESTASSERT(dl_dcch_msg.msg.c1().type().value == dl_dcch_msg_type_c::c1_c_::types_opts::rrc_conn_recfg); auto& recfg_r8 = dl_dcch_msg.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8(); + TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb1)].direction == mac_lc_ch_cfg_t::BOTH); + TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb2)].direction == mac_lc_ch_cfg_t::IDLE); + TESTASSERT(mac_ue.ue_bearers[drb_to_lcid(lte_drb::drb1)].direction == mac_lc_ch_cfg_t::IDLE); + // Receives MMEStatusTransfer asn1::s1ap::bearers_subject_to_status_transfer_list_l bearers; bearers.resize(1); - bearers[0].value.bearers_subject_to_status_transfer_item().erab_id = 5; - bearers[0].value.bearers_subject_to_status_transfer_item().dl_coun_tvalue.pdcp_sn = 100; - bearers[0].value.bearers_subject_to_status_transfer_item().dl_coun_tvalue.hfn = 3; - bearers[0].value.bearers_subject_to_status_transfer_item().ul_coun_tvalue.pdcp_sn = 120; - bearers[0].value.bearers_subject_to_status_transfer_item().ul_coun_tvalue.hfn = 4; + bearers[0]->bearers_subject_to_status_transfer_item().erab_id = 5; + bearers[0]->bearers_subject_to_status_transfer_item().dl_coun_tvalue.pdcp_sn = 100; + bearers[0]->bearers_subject_to_status_transfer_item().dl_coun_tvalue.hfn = 3; + bearers[0]->bearers_subject_to_status_transfer_item().ul_coun_tvalue.pdcp_sn = 120; + bearers[0]->bearers_subject_to_status_transfer_item().ul_coun_tvalue.hfn = 4; tester.rrc.set_erab_status(0x46, bearers); TESTASSERT(tester.pdcp.bearers.count(0x46)); TESTASSERT(tester.pdcp.bearers[0x46].count(3)); @@ -382,6 +400,10 @@ int test_s1ap_tenb_mobility(test_event test_params) TESTASSERT(tester.pdcp.bearers[0x46][3].state.next_pdcp_rx_sn == 120); TESTASSERT(tester.pdcp.bearers[0x46][3].state.rx_hfn == 4); + TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb1)].direction == mac_lc_ch_cfg_t::BOTH); + TESTASSERT(mac_ue.ue_bearers[srb_to_lcid(lte_srb::srb2)].direction == mac_lc_ch_cfg_t::IDLE); + TESTASSERT(mac_ue.ue_bearers[drb_to_lcid(lte_drb::drb1)].direction == mac_lc_ch_cfg_t::IDLE); + // user PRACHs and sends C-RNTI CE sched_interface::ue_cfg_t ue_cfg{}; ue_cfg.supported_cc_list.resize(1); @@ -497,7 +519,8 @@ int test_intraenb_mobility(srsran::log_sink_spy& spy, test_event test_params) TESTASSERT(tester.phy.last_cfg[0].enb_cc_idx == ue_cfg->supported_cc_list[0].enb_cc_idx); TESTASSERT(ue_cfg->ue_bearers[srb_to_lcid(lte_srb::srb0)].direction == srsenb::mac_lc_ch_cfg_t::BOTH); TESTASSERT(ue_cfg->ue_bearers[srb_to_lcid(lte_srb::srb1)].direction == srsenb::mac_lc_ch_cfg_t::BOTH); - TESTASSERT(ue_cfg->ue_bearers[srb_to_lcid(lte_srb::srb2)].direction == srsenb::mac_lc_ch_cfg_t::BOTH); + TESTASSERT(ue_cfg->ue_bearers[srb_to_lcid(lte_srb::srb2)].direction == srsenb::mac_lc_ch_cfg_t::IDLE); + TESTASSERT(ue_cfg->ue_bearers[drb_to_lcid(lte_drb::drb1)].direction == srsenb::mac_lc_ch_cfg_t::IDLE); /* Test Case: The UE receives a duplicate C-RNTI CE. Nothing should happen */ if (test_params == test_event::duplicate_crnti_ce) { @@ -511,7 +534,8 @@ int test_intraenb_mobility(srsran::log_sink_spy& spy, test_event test_params) /* Test Case: Terminate first Handover. No extra messages should be sent DL. SR/CQI resources match recfg message */ uint8_t recfg_complete[] = {0x10, 0x00}; copy_msg_to_buffer(pdu, recfg_complete); - tester.rrc.write_pdu(tester.rnti, srb_to_lcid(lte_srb::srb2), std::move(pdu)); + tester.rrc.write_pdu(tester.rnti, srb_to_lcid(lte_srb::srb1), std::move(pdu)); + tester.tic(); TESTASSERT(tester.pdcp.last_sdu.sdu == nullptr); ue_cfg = &tester.mac.ue_db[tester.rnti]; TESTASSERT(ue_cfg->pucch_cfg.sr_configured); @@ -520,6 +544,10 @@ int test_intraenb_mobility(srsran::log_sink_spy& spy, test_event test_params) TESTASSERT(ue_cfg->supported_cc_list[0].dl_cfg.cqi_report.pmi_idx == phy_cfg_ded.cqi_report_cfg.cqi_report_periodic.setup().cqi_pmi_cfg_idx); TESTASSERT(ue_cfg->pucch_cfg.n_pucch == phy_cfg_ded.cqi_report_cfg.cqi_report_periodic.setup().cqi_pucch_res_idx); + TESTASSERT(ue_cfg->ue_bearers[srb_to_lcid(lte_srb::srb0)].direction == srsenb::mac_lc_ch_cfg_t::BOTH); + TESTASSERT(ue_cfg->ue_bearers[srb_to_lcid(lte_srb::srb1)].direction == srsenb::mac_lc_ch_cfg_t::BOTH); + TESTASSERT(ue_cfg->ue_bearers[srb_to_lcid(lte_srb::srb2)].direction == srsenb::mac_lc_ch_cfg_t::BOTH); + TESTASSERT(ue_cfg->ue_bearers[drb_to_lcid(lte_drb::drb1)].direction == srsenb::mac_lc_ch_cfg_t::BOTH); /* Test Case: The RRC should be able to start a new handover */ uint8_t meas_report[] = {0x08, 0x10, 0x38, 0x74, 0x00, 0x05, 0xBC, 0x80}; // PCI == 1 diff --git a/srsenb/test/rrc/rrc_nr_test.cc b/srsenb/test/rrc/rrc_nr_test.cc deleted file mode 100644 index ed35e82e61..0000000000 --- a/srsenb/test/rrc/rrc_nr_test.cc +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsenb/hdr/enb.h" -#include "srsenb/hdr/stack/rrc/rrc_nr.h" -#include "srsenb/test/common/dummy_classes_common.h" -#include "srsenb/test/common/dummy_classes_nr.h" -#include "srsenb/test/rrc/test_helpers.h" -#include "srsran/common/test_common.h" -#include "srsran/interfaces/gnb_rrc_nr_interfaces.h" -#include - -using namespace asn1::rrc_nr; - -namespace srsenb { - -int test_cell_cfg(const srsenb::sched_interface::cell_cfg_t& cellcfg) -{ - // SIB1 must exist and have period 16rf - TESTASSERT(cellcfg.sibs[0].len > 0); - TESTASSERT(cellcfg.sibs[0].period_rf == 16); - - TESTASSERT(cellcfg.si_window_ms > 0); - return SRSRAN_SUCCESS; -} - -/* - * Test 1 - Test default SIB generation - * Description: Check whether the SIBs were set correctly - */ -int test_sib_generation() -{ - srsran::task_scheduler task_sched; - - mac_nr_dummy mac_obj; - rlc_dummy rlc_obj; - pdcp_dummy pdcp_obj; - rrc_nr rrc_obj(&task_sched); - - // set cfg - rrc_nr_cfg_t default_cfg = {}; - rrc_nr_cfg_t rrc_cfg = rrc_obj.update_default_cfg(default_cfg); - auto& sched_elem = rrc_cfg.sib1.si_sched_info.sched_info_list[0]; - - TESTASSERT(rrc_obj.init(rrc_cfg, nullptr, &mac_obj, &rlc_obj, &pdcp_obj, nullptr, nullptr, nullptr) == - SRSRAN_SUCCESS); - - TESTASSERT(test_cell_cfg(mac_obj.cellcfgobj) == SRSRAN_SUCCESS); - // TEMP tests - TESTASSERT(mac_obj.cellcfgobj.sibs[1].len > 0); - TESTASSERT(mac_obj.cellcfgobj.sibs[1].period_rf == sched_elem.si_periodicity.to_number()); - for (int i = 2; i < 16; ++i) { - TESTASSERT(mac_obj.cellcfgobj.sibs[i].len == 0); - } - TESTASSERT(mac_obj.cellcfgobj.cell.nof_prb == 25); - - return SRSRAN_SUCCESS; -} - -int test_rrc_setup() -{ - srsran::task_scheduler task_sched; - - phy_nr_dummy phy_obj; - mac_nr_dummy mac_obj; - rlc_dummy rlc_obj; - pdcp_dummy pdcp_obj; - rrc_nr rrc_obj(&task_sched); - - // set cfg - all_args_t args{}; - phy_cfg_t phy_cfg{}; - rrc_nr_cfg_t rrc_cfg_nr = rrc_obj.update_default_cfg(rrc_nr_cfg_t{}); - rrc_cfg_nr.cell_list.emplace_back(); - rrc_cfg_nr.cell_list[0].phy_cell.carrier.pci = 500; - rrc_cfg_nr.cell_list[0].dl_arfcn = 634240; - rrc_cfg_nr.cell_list[0].band = 78; - args.enb.n_prb = 50; - enb_conf_sections::set_derived_args_nr(&args, &rrc_cfg_nr, &phy_cfg); - TESTASSERT(rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, nullptr, nullptr, nullptr) == - SRSRAN_SUCCESS); - - for (uint32_t n = 0; n < 2; ++n) { - uint32_t timeout = 5500; - for (uint32_t i = 0; i < timeout and rlc_obj.last_sdu == nullptr; ++i) { - task_sched.tic(); - } - // TODO: trigger proper RRC Setup procedure (not timer based) - // TESTASSERT(rlc_obj.last_sdu != nullptr); - } - return SRSRAN_SUCCESS; -} - -} // namespace srsenb - -int main(int argc, char** argv) -{ - auto& logger = srslog::fetch_basic_logger("ASN1"); - logger.set_level(srslog::basic_levels::info); - - srslog::init(); - - if (argc < 3) { - argparse::usage(argv[0]); - return -1; - } - argparse::parse_args(argc, argv); - - // FIXME: disabled temporarily until SIB generation is fixed - // TESTASSERT(srsenb::test_sib_generation() == SRSRAN_SUCCESS); - TESTASSERT(srsenb::test_rrc_setup() == SRSRAN_SUCCESS); - - return SRSRAN_SUCCESS; -} diff --git a/srsenb/test/rrc/rrc_paging_test.cc b/srsenb/test/rrc/rrc_paging_test.cc new file mode 100644 index 0000000000..da39de0d3f --- /dev/null +++ b/srsenb/test/rrc/rrc_paging_test.cc @@ -0,0 +1,57 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsenb/hdr/stack/rrc/rrc_paging.h" +#include "srsran/common/test_common.h" + +using namespace srsenb; + +void test_paging() +{ + unsigned paging_cycle = 32; + float nb = 1; + paging_manager pcch_manager{paging_cycle, nb}; + + unsigned ue_id = 4780; + unsigned mmec = 10; + uint8_t m_tmsi[] = {0x64, 0x04, 0x00, 0x02}; + + pcch_manager.add_tmsi_paging(ue_id, mmec, m_tmsi); + + // \remark: See TS 36.304, section 7.1. + unsigned N = std::min(paging_cycle, (unsigned)std::round(nb * paging_cycle)); + unsigned Ns = std::max(1, (int)nb); + unsigned i_s = (ue_id / N) % Ns; + TESTASSERT_EQ(0, i_s); + tti_point t{0}; + for (unsigned count = 0; count < 1024 * 10; ++count, ++t) { + if (pcch_manager.pending_pcch_bytes(t) > 0) { + fmt::print("[{}]\n", t); + TESTASSERT_EQ((paging_cycle / N) * (ue_id % N), (t.sfn() % paging_cycle)); + TESTASSERT_EQ(9, t.sf_idx()); // PO when i_s == 0. + } + } +} + +int main() +{ + test_paging(); +} \ No newline at end of file diff --git a/srsenb/test/rrc/test_helpers.cc b/srsenb/test/rrc/test_helpers.cc index aba507217e..059edc6f24 100644 --- a/srsenb/test/rrc/test_helpers.cc +++ b/srsenb/test/rrc/test_helpers.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,6 +23,8 @@ #include "srsenb/hdr/enb.h" #include "srsran/common/test_common.h" +using namespace asn1::rrc; + namespace argparse { std::string repository_dir; @@ -135,9 +137,8 @@ int bring_rrc_to_reconf_state(srsenb::rrc& rrc, srsran::timer_handler& timers, u asn1::cbit_ref bref(byte_buf.msg, byte_buf.N_bytes); TESTASSERT(s1ap_pdu.unpack(bref) == asn1::SRSASN_SUCCESS); rrc.setup_ue_ctxt(rnti, s1ap_pdu.init_msg().value.init_context_setup_request()); - for (auto& item : - s1ap_pdu.init_msg().value.init_context_setup_request().protocol_ies.erab_to_be_setup_list_ctxt_su_req.value) { - const auto& erab = item.value.erab_to_be_setup_item_ctxt_su_req(); + for (auto& item : s1ap_pdu.init_msg().value.init_context_setup_request()->erab_to_be_setup_list_ctxt_su_req.value) { + const auto& erab = item->erab_to_be_setup_item_ctxt_su_req(); asn1::s1ap::cause_c cause; TESTASSERT(rrc.setup_erab(rnti, erab.erab_id, diff --git a/srsenb/test/rrc/test_helpers.h b/srsenb/test/rrc/test_helpers.h index 70c5770229..e07ba9d639 100644 --- a/srsenb/test/rrc/test_helpers.h +++ b/srsenb/test/rrc/test_helpers.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -28,7 +28,6 @@ #include "srsran/adt/span.h" using namespace srsenb; -using namespace asn1::rrc; namespace argparse { @@ -91,6 +90,7 @@ class s1ap_mobility_dummy : public s1ap_dummy bool send_ho_required(uint16_t rnti, uint32_t target_eci, + uint16_t target_tac, srsran::plmn_id_t target_plmn, srsran::span fwd_erabs, srsran::unique_byte_buffer_t rrc_container, @@ -238,9 +238,9 @@ namespace srsenb { meas_cell_cfg_t generate_cell1(); -report_cfg_eutra_s generate_rep1(); +asn1::rrc::report_cfg_eutra_s generate_rep1(); -bool is_cell_cfg_equal(const meas_cell_cfg_t& cfg, const cells_to_add_mod_s& cell); +bool is_cell_cfg_equal(const meas_cell_cfg_t& cfg, const asn1::rrc::cells_to_add_mod_s& cell); } // namespace srsenb diff --git a/srsenb/test/s1ap/CMakeLists.txt b/srsenb/test/s1ap/CMakeLists.txt index abed327da8..6a5adb94c5 100644 --- a/srsenb/test/s1ap/CMakeLists.txt +++ b/srsenb/test/s1ap/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsenb/test/s1ap/s1ap_test.cc b/srsenb/test/s1ap/s1ap_test.cc index b5fc247bee..c4eb39be46 100644 --- a/srsenb/test/s1ap/s1ap_test.cc +++ b/srsenb/test/s1ap/s1ap_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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); @@ -201,9 +201,9 @@ void add_rnti(s1ap& s1ap_obj, mme_dummy& mme) TESTASSERT(s1ap_pdu.unpack(cbref) == SRSRAN_SUCCESS); TESTASSERT(s1ap_pdu.type().value == asn1::s1ap::s1ap_pdu_c::types_opts::successful_outcome); TESTASSERT(s1ap_pdu.successful_outcome().proc_code == ASN1_S1AP_ID_INIT_CONTEXT_SETUP); - const auto& resp = s1ap_pdu.successful_outcome().value.init_context_setup_resp().protocol_ies; - TESTASSERT(resp.erab_setup_list_ctxt_su_res.value.size() > 0); - TESTASSERT(not resp.erab_failed_to_setup_list_ctxt_su_res_present); + const auto& resp = s1ap_pdu.successful_outcome().value.init_context_setup_resp(); + TESTASSERT(resp->erab_setup_list_ctxt_su_res.value.size() > 0); + TESTASSERT(not resp->erab_failed_to_setup_list_ctxt_su_res_present); } enum class test_event { success, wrong_erabid_mod, wrong_mme_s1ap_id, repeated_erabid_mod }; @@ -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); @@ -244,13 +247,13 @@ void test_s1ap_erab_setup(test_event event) int flags = 0; asn1::s1ap::s1ap_pdu_c mod_req_pdu; mod_req_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_ERAB_MODIFY); - auto& protocols = mod_req_pdu.init_msg().value.erab_modify_request().protocol_ies; - protocols.enb_ue_s1ap_id.value = 1; - protocols.mme_ue_s1ap_id.value = event == test_event::wrong_mme_s1ap_id ? 2 : 1; - auto& erab_list = protocols.erab_to_be_modified_list_bearer_mod_req.value; + auto& protocols = mod_req_pdu.init_msg().value.erab_modify_request(); + protocols->enb_ue_s1ap_id.value = 1; + protocols->mme_ue_s1ap_id.value = event == test_event::wrong_mme_s1ap_id ? 2 : 1; + auto& erab_list = protocols->erab_to_be_modified_list_bearer_mod_req.value; erab_list.resize(2); erab_list[0].load_info_obj(ASN1_S1AP_ID_ERAB_TO_BE_MODIFIED_ITEM_BEARER_MOD_REQ); - auto* erab_ptr = &erab_list[0].value.erab_to_be_modified_item_bearer_mod_req(); + auto* erab_ptr = &erab_list[0]->erab_to_be_modified_item_bearer_mod_req(); erab_ptr->erab_id = 5; erab_ptr->erab_level_qos_params.qci = 9; erab_ptr->erab_level_qos_params.alloc_retention_prio.prio_level = 15; @@ -261,7 +264,7 @@ void test_s1ap_erab_setup(test_event event) erab_ptr->nas_pdu.resize(1); erab_ptr->nas_pdu[0] = 0; erab_list[1] = erab_list[0]; - erab_ptr = &erab_list[1].value.erab_to_be_modified_item_bearer_mod_req(); + erab_ptr = &erab_list[1]->erab_to_be_modified_item_bearer_mod_req(); erab_ptr->erab_id = event == test_event::repeated_erabid_mod ? 5 : 6; if (event == test_event::wrong_erabid_mod) { rrc.next_erabs_failed_to_modify.push_back(6); @@ -282,34 +285,33 @@ void test_s1ap_erab_setup(test_event event) // See TS 36.413, Section 10.6 - Handling of AP ID TESTASSERT(s1ap_pdu.type().value == asn1::s1ap::s1ap_pdu_c::types_opts::init_msg); TESTASSERT(s1ap_pdu.init_msg().proc_code == ASN1_S1AP_ID_ERROR_IND); - auto& protocol_ies = s1ap_pdu.init_msg().value.error_ind().protocol_ies; - TESTASSERT(protocol_ies.mme_ue_s1ap_id_present and protocol_ies.mme_ue_s1ap_id.value.value == 2); - TESTASSERT(protocol_ies.enb_ue_s1ap_id_present and protocol_ies.enb_ue_s1ap_id.value.value == 1); + auto& err_ind = s1ap_pdu.init_msg().value.error_ind(); + TESTASSERT(err_ind->mme_ue_s1ap_id_present and err_ind->mme_ue_s1ap_id.value.value == 2); + TESTASSERT(err_ind->enb_ue_s1ap_id_present and err_ind->enb_ue_s1ap_id.value.value == 1); TESTASSERT(rrc.last_released_rnti == 0x46); return; } TESTASSERT(s1ap_pdu.type().value == asn1::s1ap::s1ap_pdu_c::types_opts::successful_outcome); TESTASSERT(s1ap_pdu.successful_outcome().proc_code == ASN1_S1AP_ID_ERAB_MODIFY); - auto& protocol_ies = s1ap_pdu.successful_outcome().value.erab_modify_resp().protocol_ies; + auto& erab_mod = s1ap_pdu.successful_outcome().value.erab_modify_resp(); if (event == test_event::wrong_erabid_mod) { - TESTASSERT(protocol_ies.erab_modify_list_bearer_mod_res_present); - TESTASSERT(protocol_ies.erab_modify_list_bearer_mod_res.value.size() == 1); - TESTASSERT(protocol_ies.erab_modify_list_bearer_mod_res.value[0].value.erab_modify_item_bearer_mod_res().erab_id == - 5); - TESTASSERT(protocol_ies.erab_failed_to_modify_list_present); - TESTASSERT(protocol_ies.erab_failed_to_modify_list.value.size() == 1); - auto& erab_item = protocol_ies.erab_failed_to_modify_list.value[0].value.erab_item(); + TESTASSERT(erab_mod->erab_modify_list_bearer_mod_res_present); + TESTASSERT(erab_mod->erab_modify_list_bearer_mod_res.value.size() == 1); + TESTASSERT(erab_mod->erab_modify_list_bearer_mod_res.value[0]->erab_modify_item_bearer_mod_res().erab_id == 5); + TESTASSERT(erab_mod->erab_failed_to_modify_list_present); + TESTASSERT(erab_mod->erab_failed_to_modify_list.value.size() == 1); + auto& erab_item = erab_mod->erab_failed_to_modify_list.value[0]->erab_item(); TESTASSERT(erab_item.erab_id == 6); TESTASSERT(erab_item.cause.type().value == asn1::s1ap::cause_c::types_opts::radio_network); TESTASSERT(erab_item.cause.radio_network().value == asn1::s1ap::cause_radio_network_opts::unknown_erab_id); return; } if (event == test_event::repeated_erabid_mod) { - TESTASSERT(not protocol_ies.erab_modify_list_bearer_mod_res_present); - TESTASSERT(protocol_ies.erab_failed_to_modify_list_present); - TESTASSERT(protocol_ies.erab_failed_to_modify_list.value.size() == 1); - auto& erab_item = protocol_ies.erab_failed_to_modify_list.value[0].value.erab_item(); + TESTASSERT(not erab_mod->erab_modify_list_bearer_mod_res_present); + TESTASSERT(erab_mod->erab_failed_to_modify_list_present); + TESTASSERT(erab_mod->erab_failed_to_modify_list.value.size() == 1); + auto& erab_item = erab_mod->erab_failed_to_modify_list.value[0]->erab_item(); TESTASSERT(erab_item.erab_id == 5); TESTASSERT(erab_item.cause.type().value == asn1::s1ap::cause_c::types_opts::radio_network); TESTASSERT(erab_item.cause.radio_network().value == @@ -317,10 +319,10 @@ void test_s1ap_erab_setup(test_event event) return; } - TESTASSERT(protocol_ies.erab_modify_list_bearer_mod_res_present); - TESTASSERT(not protocol_ies.erab_failed_to_modify_list_present); - TESTASSERT(protocol_ies.erab_modify_list_bearer_mod_res.value.size() == 2); - auto& erab_item = protocol_ies.erab_modify_list_bearer_mod_res.value[0].value.erab_modify_item_bearer_mod_res(); + TESTASSERT(erab_mod->erab_modify_list_bearer_mod_res_present); + TESTASSERT(not erab_mod->erab_failed_to_modify_list_present); + TESTASSERT(erab_mod->erab_modify_list_bearer_mod_res.value.size() == 2); + auto& erab_item = erab_mod->erab_modify_list_bearer_mod_res.value[0]->erab_modify_item_bearer_mod_res(); TESTASSERT(erab_item.erab_id == 5); } diff --git a/srsenb/test/upper/CMakeLists.txt b/srsenb/test/upper/CMakeLists.txt index 3b5e1fd145..c1880ca1c3 100644 --- a/srsenb/test/upper/CMakeLists.txt +++ b/srsenb/test/upper/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsenb/test/upper/gtpu_test.cc b/srsenb/test/upper/gtpu_test.cc index 87d8637d70..de8d3f5893 100644 --- a/srsenb/test/upper/gtpu_test.cc +++ b/srsenb/test/upper/gtpu_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -167,7 +167,7 @@ void test_gtpu_tunnel_manager() srsran::task_scheduler task_sched; gtpu_args_t gtpu_args = {}; - gtpu_tunnel_manager tunnels(&task_sched, srslog::fetch_basic_logger("GTPU")); + gtpu_tunnel_manager tunnels(&task_sched, srslog::fetch_basic_logger("GTPU"), srsran::srsran_rat_t::lte); tunnels.init(gtpu_args, nullptr); TESTASSERT(tunnels.find_tunnel(0) == nullptr); TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_eps_bearer_id).empty()); @@ -244,9 +244,10 @@ int test_gtpu_direct_tunneling(tunnel_test_event event) logger2.set_hex_dump_max_size(2048); srsran::task_scheduler task_sched; dummy_socket_manager senb_rx_sockets, tenb_rx_sockets; - srsenb::gtpu senb_gtpu(&task_sched, logger1, &senb_rx_sockets), tenb_gtpu(&task_sched, logger2, &tenb_rx_sockets); - pdcp_tester senb_pdcp, tenb_pdcp; - gtpu_args_t gtpu_args; + srsenb::gtpu senb_gtpu(&task_sched, logger1, srsran::srsran_rat_t::lte, &senb_rx_sockets), + tenb_gtpu(&task_sched, logger2, srsran::srsran_rat_t::lte, &tenb_rx_sockets); + pdcp_tester senb_pdcp, tenb_pdcp; + gtpu_args_t gtpu_args; gtpu_args.gtp_bind_addr = senb_addr_str; gtpu_args.mme_addr = sgw_addr_str; gtpu_args.indirect_tunnel_timeout_msec = std::uniform_int_distribution{500, 2000}(g); @@ -272,7 +273,7 @@ int test_gtpu_direct_tunneling(tunnel_test_event event) props.flush_before_teidin = tenb_teid_in; uint32_t addr_in3; uint32_t dl_tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1_bearer_id, senb_addr, 0, addr_in3, &props).value(); - props = {}; + props = {}; props.forward_from_teidin_present = true; props.forward_from_teidin = senb_teid_in; uint32_t addr_in4; diff --git a/srsenb/test/upper/plmn_test.cc b/srsenb/test/upper/plmn_test.cc index 439257db08..9c6ecd04b1 100644 --- a/srsenb/test/upper/plmn_test.cc +++ b/srsenb/test/upper/plmn_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/CMakeLists.txt b/srsepc/CMakeLists.txt index 47df8d5b8e..f118644498 100644 --- a/srsepc/CMakeLists.txt +++ b/srsepc/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsepc/epc.conf.example b/srsepc/epc.conf.example index 1099891fde..e0aa153939 100644 --- a/srsepc/epc.conf.example +++ b/srsepc/epc.conf.example @@ -10,6 +10,8 @@ # tac: 16-bit Tracking Area Code. # mcc: Mobile Country Code # mnc: Mobile Network Code +# full_net_name Display Name of the Network +# short_net_name Short Display Name of the Network # apn: Set Access Point Name (APN) # mme_bind_addr: IP bind addr to listen for eNB S1-MME connnections # dns_addr: DNS server address for the UEs @@ -19,6 +21,7 @@ # (supported: EIA0 (rejected by most UEs), EIA1 (default), EIA2, EIA3 # paging_timer: Value of paging timer in seconds (T3413) # request_imeisv: Request UE's IMEI-SV in security mode command +# lac: 16-bit Location Area Code. # ##################################################################### [mme] @@ -34,6 +37,7 @@ encryption_algo = EEA0 integrity_algo = EIA1 paging_timer = 2 request_imeisv = false +lac = 0x0006 ##################################################################### # HSS configuration diff --git a/srsepc/hdr/hss/hss.h b/srsepc/hdr/hss/hss.h index 4eeb74bb33..356ef398a8 100644 --- a/srsepc/hdr/hss/hss.h +++ b/srsepc/hdr/hss/hss.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/mbms-gw/mbms-gw.h b/srsepc/hdr/mbms-gw/mbms-gw.h index 6391a13179..5ff701b7c6 100644 --- a/srsepc/hdr/mbms-gw/mbms-gw.h +++ b/srsepc/hdr/mbms-gw/mbms-gw.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/mme/mme.h b/srsepc/hdr/mme/mme.h index c8043d9fbe..00a701c209 100644 --- a/srsepc/hdr/mme/mme.h +++ b/srsepc/hdr/mme/mme.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/mme/mme_gtpc.h b/srsepc/hdr/mme/mme_gtpc.h index 53a5e4b1d7..d6714eca38 100644 --- a/srsepc/hdr/mme/mme_gtpc.h +++ b/srsepc/hdr/mme/mme_gtpc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/mme/nas.h b/srsepc/hdr/mme/nas.h index ba9c6c894e..88364cdcd9 100644 --- a/srsepc/hdr/mme/nas.h +++ b/srsepc/hdr/mme/nas.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -142,6 +142,7 @@ typedef struct { srsran::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; srsran::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; bool request_imeisv; + uint16_t lac; } nas_init_t; typedef struct { @@ -225,6 +226,7 @@ class nas /* Uplink NAS messages handling */ bool handle_attach_request(srsran::byte_buffer_t* nas_rx); + bool handle_pdn_connectivity_request(srsran::byte_buffer_t* nas_rx); bool handle_authentication_response(srsran::byte_buffer_t* nas_rx); bool handle_security_mode_complete(srsran::byte_buffer_t* nas_rx); bool handle_attach_complete(srsran::byte_buffer_t* nas_rx); @@ -246,7 +248,7 @@ class nas bool pack_attach_accept(srsran::byte_buffer_t* nas_buffer); /* Security functions */ - bool integrity_check(srsran::byte_buffer_t* pdu); + bool integrity_check(srsran::byte_buffer_t* pdu, bool warn_failure = true); bool short_integrity_check(srsran::byte_buffer_t* pdu); void integrity_generate(srsran::byte_buffer_t* pdu, uint8_t* mac); void cipher_decrypt(srsran::byte_buffer_t* pdu); @@ -279,6 +281,7 @@ class nas std::string m_full_net_name; std::string m_short_net_name; bool m_request_imeisv = false; + uint16_t m_lac = 0; // Timers timeout values uint16_t m_t3413 = 0; diff --git a/srsepc/hdr/mme/s1ap.h b/srsepc/hdr/mme/s1ap.h index 34d798baa1..4039953bf3 100644 --- a/srsepc/hdr/mme/s1ap.h +++ b/srsepc/hdr/mme/s1ap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index 101a89562e..4c2897bba4 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -52,6 +52,7 @@ typedef struct { srsran::CIPHERING_ALGORITHM_ID_ENUM encryption_algo; srsran::INTEGRITY_ALGORITHM_ID_ENUM integrity_algo; bool request_imeisv; + uint16_t lac; } s1ap_args_t; typedef struct { diff --git a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h index f2243b930d..6cf4b1fc73 100644 --- a/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_ctx_mngmt_proc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h b/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h index e5b8958cf1..863d6ba411 100644 --- a/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_erab_mngmt_proc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/mme/s1ap_mngmt_proc.h b/srsepc/hdr/mme/s1ap_mngmt_proc.h index a469b4848e..c827caf914 100644 --- a/srsepc/hdr/mme/s1ap_mngmt_proc.h +++ b/srsepc/hdr/mme/s1ap_mngmt_proc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/mme/s1ap_nas_transport.h b/srsepc/hdr/mme/s1ap_nas_transport.h index e7fd5fb0f1..ba8dfc5d88 100644 --- a/srsepc/hdr/mme/s1ap_nas_transport.h +++ b/srsepc/hdr/mme/s1ap_nas_transport.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/mme/s1ap_paging.h b/srsepc/hdr/mme/s1ap_paging.h index 7c868f0c0b..bcd0d0640a 100644 --- a/srsepc/hdr/mme/s1ap_paging.h +++ b/srsepc/hdr/mme/s1ap_paging.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/spgw/gtpc.h b/srsepc/hdr/spgw/gtpc.h index 93bf033b73..42b99bdd3b 100644 --- a/srsepc/hdr/spgw/gtpc.h +++ b/srsepc/hdr/spgw/gtpc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/spgw/gtpu.h b/srsepc/hdr/spgw/gtpu.h index a605a627bb..7c7370c77a 100644 --- a/srsepc/hdr/spgw/gtpu.h +++ b/srsepc/hdr/spgw/gtpu.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/hdr/spgw/spgw.h b/srsepc/hdr/spgw/spgw.h index 0a31c071e1..affdafdaa8 100644 --- a/srsepc/hdr/spgw/spgw.h +++ b/srsepc/hdr/spgw/spgw.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/src/CMakeLists.txt b/srsepc/src/CMakeLists.txt index 8c05a87f2b..bc16d976b7 100644 --- a/srsepc/src/CMakeLists.txt +++ b/srsepc/src/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -76,5 +76,5 @@ else(NOT ${BUILDEPC_CMD} STREQUAL "") message(STATUS "No post-build-EPC command defined") endif (NOT ${BUILDEPC_CMD} STREQUAL "") -install(TARGETS srsepc DESTINATION ${RUNTIME_DIR}) -install(TARGETS srsmbms DESTINATION ${RUNTIME_DIR}) +install(TARGETS srsepc DESTINATION ${RUNTIME_DIR} OPTIONAL) +install(TARGETS srsmbms DESTINATION ${RUNTIME_DIR} OPTIONAL) diff --git a/srsepc/src/hss/CMakeLists.txt b/srsepc/src/hss/CMakeLists.txt index 7385b7a9ae..edc044074d 100644 --- a/srsepc/src/hss/CMakeLists.txt +++ b/srsepc/src/hss/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsepc/src/hss/hss.cc b/srsepc/src/hss/hss.cc index 2af7a5cfb5..24e9190e13 100644 --- a/srsepc/src/hss/hss.cc +++ b/srsepc/src/hss/hss.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index ee1c3c734c..10dc8cf19f 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -97,6 +97,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) string hss_db_file; string hss_auth_algo; string log_filename; + string lac; // Command line only options bpo::options_description general("General options"); @@ -124,6 +125,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("mme.integrity_algo", bpo::value(&integrity_algo)->default_value("EIA1"), "Set preferred integrity protection algorithm for NAS") ("mme.paging_timer", bpo::value(&paging_timer)->default_value(2), "Set paging timer value in seconds (T3413)") ("mme.request_imeisv", bpo::value(&request_imeisv)->default_value(false), "Enable IMEISV request in Security mode command") + ("mme.lac", bpo::value(&lac)->default_value("0x01"), "Location Area Code") ("hss.db_file", bpo::value(&hss_db_file)->default_value("ue_db.csv"), ".csv file that stores UE's keys") ("spgw.gtpu_bind_addr", bpo::value(&spgw_bind_addr)->default_value("127.0.0.1"), "IP address of SP-GW for the S1-U connection") ("spgw.sgi_if_addr", bpo::value(&sgi_if_addr)->default_value("176.16.0.1"), "IP address of TUN interface for the SGi connection") @@ -209,7 +211,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) exit(1); } - // Concert hex strings + // Convert hex strings { std::stringstream sstr; sstr << std::hex << vm["mme.mme_group"].as(); @@ -222,11 +224,8 @@ void parse_args(all_args_t* args, int argc, char* argv[]) sstr >> tmp; args->mme_args.s1ap_args.mme_code = tmp; } - { - std::stringstream sstr; - sstr << std::hex << vm["mme.tac"].as(); - sstr >> args->mme_args.s1ap_args.tac; - } + args->mme_args.s1ap_args.tac = std::stoi(vm["mme.tac"].as(), nullptr, 0); + args->mme_args.s1ap_args.lac = std::stoi(vm["mme.lac"].as(), nullptr, 0); // Convert MCC/MNC strings if (!srsran::string_to_mcc(mcc, &args->mme_args.s1ap_args.mcc)) { @@ -393,7 +392,7 @@ int main(int argc, char* argv[]) cout << endl << "--- Software Radio Systems EPC ---" << endl << endl; srsran_debug_handle_crash(argc, argv); - all_args_t args; + all_args_t args = {}; parse_args(&args, argc, argv); // Setup logging. diff --git a/srsepc/src/mbms-gw/CMakeLists.txt b/srsepc/src/mbms-gw/CMakeLists.txt index 0ec89b729f..41953b534f 100644 --- a/srsepc/src/mbms-gw/CMakeLists.txt +++ b/srsepc/src/mbms-gw/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsepc/src/mbms-gw/main.cc b/srsepc/src/mbms-gw/main.cc index d4dceced00..12b423adfd 100644 --- a/srsepc/src/mbms-gw/main.cc +++ b/srsepc/src/mbms-gw/main.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/src/mbms-gw/mbms-gw.cc b/srsepc/src/mbms-gw/mbms-gw.cc index 1028b838ba..4171d04c95 100644 --- a/srsepc/src/mbms-gw/mbms-gw.cc +++ b/srsepc/src/mbms-gw/mbms-gw.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/src/mme/CMakeLists.txt b/srsepc/src/mme/CMakeLists.txt index 530c67e864..f5e884702d 100644 --- a/srsepc/src/mme/CMakeLists.txt +++ b/srsepc/src/mme/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsepc/src/mme/mme.cc b/srsepc/src/mme/mme.cc index 5d36810e4e..5ccedc2d49 100644 --- a/srsepc/src/mme/mme.cc +++ b/srsepc/src/mme/mme.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/src/mme/mme_gtpc.cc b/srsepc/src/mme/mme_gtpc.cc index b52afca6a8..ce09199a00 100644 --- a/srsepc/src/mme/mme_gtpc.cc +++ b/srsepc/src/mme/mme_gtpc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -183,13 +183,13 @@ bool mme_gtpc::send_create_session_request(uint64_t imsi) } // Save RX Control TEID - m_mme_ctr_teid_to_imsi.insert(std::pair(cs_req->sender_f_teid.teid, imsi)); + m_mme_ctr_teid_to_imsi.emplace(cs_req->sender_f_teid.teid, imsi); // Save GTP-C context gtpc_ctx_t gtpc_ctx; std::memset(>pc_ctx, 0, sizeof(gtpc_ctx_t)); gtpc_ctx.mme_ctr_fteid = cs_req->sender_f_teid; - m_imsi_to_gtpc_ctx.insert(std::pair(imsi, gtpc_ctx)); + m_imsi_to_gtpc_ctx.emplace(imsi, gtpc_ctx); // Send msg to SPGW send_s11_pdu(cs_req_pdu); diff --git a/srsepc/src/mme/nas.cc b/srsepc/src/mme/nas.cc index 1408a2b571..7e9834d06a 100644 --- a/srsepc/src/mme/nas.cc +++ b/srsepc/src/mme/nas.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -46,7 +46,8 @@ nas::nas(const nas_init_t& args, const nas_if_t& itf) : m_full_net_name(args.full_net_name), m_short_net_name(args.short_net_name), m_t3413(args.paging_timer), - m_request_imeisv(args.request_imeisv) + m_request_imeisv(args.request_imeisv), + m_lac(args.lac) { m_sec_ctx.integ_algo = args.integ_algo; m_sec_ctx.cipher_algo = args.cipher_algo; @@ -644,8 +645,6 @@ bool nas::handle_service_request(uint32_t m_tmsi, srsran::console("Service Request -- Short MAC valid\n"); nas_logger.info("Service Request -- Short MAC valid"); if (ecm_ctx->state == ECM_STATE_CONNECTED) { - nas_logger.error("Service Request -- User is ECM CONNECTED"); - // Release previous context nas_logger.info("Service Request -- Releasing previouse ECM context. eNB S1AP Id %d, MME UE S1AP Id %d", ecm_ctx->enb_ue_s1ap_id, @@ -697,8 +696,6 @@ bool nas::handle_service_request(uint32_t m_tmsi, srsran::console("Service Request -- Short MAC invalid\n"); nas_logger.info("Service Request -- Short MAC invalid"); if (ecm_ctx->state == ECM_STATE_CONNECTED) { - nas_logger.error("Service Request -- User is ECM CONNECTED"); - // Release previous context nas_logger.info("Service Request -- Releasing previouse ECM context. eNB S1AP Id %d, MME UE S1AP Id %d", ecm_ctx->enb_ue_s1ap_id, @@ -965,8 +962,8 @@ bool nas::handle_attach_request(srsran::byte_buffer_t* nas_rx) m_s1ap->send_downlink_nas_transport( m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri); - m_logger.info("Downlink NAS: Sending Authentication Request"); - srsran::console("Downlink NAS: Sending Authentication Request\n"); + m_logger.info("DL NAS: Sending Authentication Request"); + srsran::console("DL NAS: Sending Authentication Request\n"); return true; } else { m_logger.error("Attach request from known UE"); @@ -974,6 +971,47 @@ bool nas::handle_attach_request(srsran::byte_buffer_t* nas_rx) return true; } +bool nas::handle_pdn_connectivity_request(srsran::byte_buffer_t* nas_rx) +{ + LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req = {}; + + // Get PDN connectivity request messages + LIBLTE_ERROR_ENUM err = + liblte_mme_unpack_pdn_connectivity_request_msg((LIBLTE_BYTE_MSG_STRUCT*)nas_rx->msg, &pdn_con_req); + if (err != LIBLTE_SUCCESS) { + m_logger.error("Error unpacking NAS PDN Connectivity Request. Error: %s", liblte_error_text[err]); + return false; + } + + // Send PDN connectivity reject + srsran::unique_byte_buffer_t nas_tx = srsran::make_byte_buffer(); + if (nas_tx == nullptr) { + m_logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return false; + } + + LIBLTE_MME_PDN_CONNECTIVITY_REJECT_MSG_STRUCT pdn_con_reject = {}; + pdn_con_reject.eps_bearer_id = pdn_con_req.eps_bearer_id; + pdn_con_reject.proc_transaction_id = pdn_con_req.proc_transaction_id; + pdn_con_reject.esm_cause = LIBLTE_MME_ESM_CAUSE_SERVICE_OPTION_NOT_SUPPORTED; + + err = liblte_mme_pack_pdn_connectivity_reject_msg(&pdn_con_reject, (LIBLTE_BYTE_MSG_STRUCT*)nas_tx.get()); + if (err != LIBLTE_SUCCESS) { + m_logger.error("Error packing PDN connectivity reject"); + srsran::console("Error packing PDN connectivity reject\n"); + return false; + } + + // Send reply to eNB + m_s1ap->send_downlink_nas_transport( + m_ecm_ctx.enb_ue_s1ap_id, m_ecm_ctx.mme_ue_s1ap_id, nas_tx.get(), m_ecm_ctx.enb_sri); + + m_logger.info("DL NAS: Sending PDN Connectivity Reject"); + srsran::console("DL NAS: Sending PDN Connectivity Reject\n"); + + return true; +} + bool nas::handle_authentication_response(srsran::byte_buffer_t* nas_rx) { LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_resp = {}; @@ -1395,8 +1433,8 @@ bool nas::pack_security_mode_command(srsran::byte_buffer_t* nas_buffer) sm_cmd.imeisv_req = LIBLTE_MME_IMEISV_REQUESTED; } - sm_cmd.nonce_ue_present = false; - sm_cmd.nonce_mme_present = false; + sm_cmd.nonce_ue_present = false; + sm_cmd.nonce_mme_present = false; uint8_t sec_hdr_type = 3; LIBLTE_ERROR_ENUM err = liblte_mme_pack_security_mode_command_msg( @@ -1513,7 +1551,7 @@ bool nas::pack_attach_accept(srsran::byte_buffer_t* nas_buffer) attach_accept.lai_present = true; attach_accept.lai.mcc = mcc; attach_accept.lai.mnc = mnc; - attach_accept.lai.lac = 001; + attach_accept.lai.lac = m_lac; attach_accept.ms_id_present = true; attach_accept.ms_id.type_of_id = LIBLTE_MME_MOBILE_ID_TYPE_TMSI; @@ -1773,7 +1811,7 @@ bool nas::short_integrity_check(srsran::byte_buffer_t* pdu) return true; } -bool nas::integrity_check(srsran::byte_buffer_t* pdu) +bool nas::integrity_check(srsran::byte_buffer_t* pdu, bool warn_failure) { uint8_t exp_mac[4] = {}; const uint8_t* mac = &pdu->msg[1]; @@ -1816,20 +1854,21 @@ bool nas::integrity_check(srsran::byte_buffer_t* pdu) // Check if expected mac equals the sent mac for (int i = 0; i < 4; i++) { if (exp_mac[i] != mac[i]) { - m_logger.warning("Integrity check failure. Algorithm=EIA%d", (int)m_sec_ctx.integ_algo); - m_logger.warning("UL Local: est_count=%d, old_count=%d, MAC=[%02x %02x %02x %02x], " - "Received: UL count=%d, MAC=[%02x %02x %02x %02x]", - estimated_count, - m_sec_ctx.ul_nas_count, - exp_mac[0], - exp_mac[1], - exp_mac[2], - exp_mac[3], - pdu->msg[5], - mac[0], - mac[1], - mac[2], - mac[3]); + srslog::log_channel& channel = warn_failure ? m_logger.warning : m_logger.info; + channel("Integrity check failure. Algorithm=EIA%d", (int)m_sec_ctx.integ_algo); + channel("UL Local: est_count=%d, old_count=%d, MAC=[%02x %02x %02x %02x], " + "Received: UL count=%d, MAC=[%02x %02x %02x %02x]", + estimated_count, + m_sec_ctx.ul_nas_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; } } diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index 44fd10f5ea..ae07fb21c3 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -317,9 +317,9 @@ void s1ap::add_new_enb_ctx(const enb_ctx_t& enb_ctx, const struct sctp_sndrcvinf std::set ue_set; enb_ctx_t* enb_ptr = new enb_ctx_t; *enb_ptr = enb_ctx; - m_active_enbs.insert(std::pair(enb_ptr->enb_id, enb_ptr)); - m_sctp_to_enb_id.insert(std::pair(enb_sri->sinfo_assoc_id, enb_ptr->enb_id)); - m_enb_assoc_to_ue_ids.insert(std::pair >(enb_sri->sinfo_assoc_id, ue_set)); + m_active_enbs.emplace(enb_ptr->enb_id, enb_ptr); + m_sctp_to_enb_id.emplace(enb_sri->sinfo_assoc_id, enb_ptr->enb_id); + m_enb_assoc_to_ue_ids.emplace(enb_sri->sinfo_assoc_id, ue_set); } enb_ctx_t* s1ap::find_enb_ctx(uint16_t enb_id) @@ -371,7 +371,7 @@ bool s1ap::add_nas_ctx_to_imsi_map(nas* nas_ctx) return false; } } - m_imsi_to_nas_ctx.insert(std::pair(nas_ctx->m_emm_ctx.imsi, nas_ctx)); + m_imsi_to_nas_ctx.emplace(nas_ctx->m_emm_ctx.imsi, nas_ctx); m_logger.debug("Saved UE context corresponding to IMSI %015" PRIu64 "", nas_ctx->m_emm_ctx.imsi); return true; } @@ -394,7 +394,7 @@ bool s1ap::add_nas_ctx_to_mme_ue_s1ap_id_map(nas* nas_ctx) return false; } } - m_mme_ue_s1ap_id_to_nas_ctx.insert(std::pair(nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_ctx)); + m_mme_ue_s1ap_id_to_nas_ctx.emplace(nas_ctx->m_ecm_ctx.mme_ue_s1ap_id, nas_ctx); m_logger.debug("Saved UE context corresponding to MME UE S1AP Id %d", nas_ctx->m_ecm_ctx.mme_ue_s1ap_id); return true; } @@ -560,7 +560,7 @@ uint32_t s1ap::allocate_m_tmsi(uint64_t imsi) uint32_t m_tmsi = m_next_m_tmsi; m_next_m_tmsi = (m_next_m_tmsi + 1) % UINT32_MAX; - m_tmsi_to_imsi.insert(std::pair(m_tmsi, imsi)); + m_tmsi_to_imsi.emplace(m_tmsi, imsi); m_logger.debug("Allocated M-TMSI 0x%x to IMSI %015" PRIu64 ",", m_tmsi, imsi); return m_tmsi; } diff --git a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc index b36940408b..e170b30c8d 100644 --- a/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_ctx_mngmt_proc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -25,7 +25,6 @@ #include "srsran/common/buffer_pool.h" #include "srsran/common/int_helpers.h" #include "srsran/common/liblte_security.h" -#include namespace srsepc { @@ -83,24 +82,23 @@ bool s1ap_ctx_mngmt_proc::send_initial_context_setup_request(nas* nas_ctx, uint1 s1ap_pdu_t tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_INIT_CONTEXT_SETUP); - asn1::s1ap::init_context_setup_request_ies_container& in_ctx_req = - tx_pdu.init_msg().value.init_context_setup_request().protocol_ies; + asn1::s1ap::init_context_setup_request_s& in_ctx_req = tx_pdu.init_msg().value.init_context_setup_request(); // Add MME and eNB S1AP Ids - in_ctx_req.mme_ue_s1ap_id.value = ecm_ctx->mme_ue_s1ap_id; - in_ctx_req.enb_ue_s1ap_id.value = ecm_ctx->enb_ue_s1ap_id; + in_ctx_req->mme_ue_s1ap_id.value = ecm_ctx->mme_ue_s1ap_id; + in_ctx_req->enb_ue_s1ap_id.value = ecm_ctx->enb_ue_s1ap_id; // UE-AMBR - in_ctx_req.ueaggregate_maximum_bitrate.value.ueaggregate_maximum_bit_rate_dl = 1000000000; - in_ctx_req.ueaggregate_maximum_bitrate.value.ueaggregate_maximum_bit_rate_ul = 1000000000; + in_ctx_req->ueaggregate_maximum_bitrate.value.ueaggregate_maximum_bit_rate_dl = 1000000000; + in_ctx_req->ueaggregate_maximum_bitrate.value.ueaggregate_maximum_bit_rate_ul = 1000000000; // Number of E-RABs to be setup - in_ctx_req.erab_to_be_setup_list_ctxt_su_req.value.resize(1); - in_ctx_req.erab_to_be_setup_list_ctxt_su_req.value[0].load_info_obj(ASN1_S1AP_ID_ERAB_TO_BE_SETUP_ITEM_CTXT_SU_REQ); + in_ctx_req->erab_to_be_setup_list_ctxt_su_req.value.resize(1); + in_ctx_req->erab_to_be_setup_list_ctxt_su_req.value[0].load_info_obj(ASN1_S1AP_ID_ERAB_TO_BE_SETUP_ITEM_CTXT_SU_REQ); // Setup eRAB context asn1::s1ap::erab_to_be_setup_item_ctxt_su_req_s& erab_ctx_req = - in_ctx_req.erab_to_be_setup_list_ctxt_su_req.value[0].value.erab_to_be_setup_item_ctxt_su_req(); + in_ctx_req->erab_to_be_setup_list_ctxt_su_req.value[0]->erab_to_be_setup_item_ctxt_su_req(); erab_ctx_req.erab_id = esm_ctx->erab_id; // Setup E-RAB QoS parameters @@ -121,21 +119,21 @@ bool s1ap_ctx_mngmt_proc::send_initial_context_setup_request(nas* nas_ctx, uint1 // Set UE security capabilities and k_enb for (int i = 0; i < 3; i++) { if (sec_ctx->ue_network_cap.eea[i + 1] == true) { - in_ctx_req.ue_security_cap.value.encryption_algorithms.set(16 - i, true); // EEA supported + in_ctx_req->ue_security_cap.value.encryption_algorithms.set(16 - i, true); // EEA supported } else { - in_ctx_req.ue_security_cap.value.encryption_algorithms.set(16 - i, false); // EEA not supported + in_ctx_req->ue_security_cap.value.encryption_algorithms.set(16 - i, false); // EEA not supported } if (sec_ctx->ue_network_cap.eia[i + 1] == true) { - in_ctx_req.ue_security_cap.value.integrity_protection_algorithms.set(16 - i, true); // EIA supported + in_ctx_req->ue_security_cap.value.integrity_protection_algorithms.set(16 - i, true); // EIA supported } else { - in_ctx_req.ue_security_cap.value.integrity_protection_algorithms.set(16 - i, false); // EIA not supported + in_ctx_req->ue_security_cap.value.integrity_protection_algorithms.set(16 - i, false); // EIA not supported } } // Get K eNB - // memcpy(in_ctx_req.security_key.value.data(),sec_ctx->k_enb, 32); + // memcpy(in_ctx_req->security_key.value.data(),sec_ctx->k_enb, 32); for (uint8_t i = 0; i < 32; ++i) { - in_ctx_req.security_key.value.data()[31 - i] = sec_ctx->k_enb[i]; + in_ctx_req->security_key.value.data()[31 - i] = sec_ctx->k_enb[i]; } m_logger.info(sec_ctx->k_enb, 32, "Initial Context Setup Request -- Key eNB (k_enb)"); @@ -166,8 +164,8 @@ bool s1ap_ctx_mngmt_proc::send_initial_context_setup_request(nas* nas_ctx, uint1 m_logger.info( "Initial Context -- S1-U TEID 0x%" PRIx64 ". IP %s ", erab_ctx_req.gtp_teid.to_number(), inet_ntoa(addr)); m_logger.info("Initial Context Setup Request -- eNB UE S1AP Id %d, MME UE S1AP Id %" PRIu64 "", - in_ctx_req.enb_ue_s1ap_id.value.value, - in_ctx_req.mme_ue_s1ap_id.value.value); + in_ctx_req->enb_ue_s1ap_id.value.value, + in_ctx_req->mme_ue_s1ap_id.value.value); m_logger.info("Initial Context Setup Request -- E-RAB id %d", erab_ctx_req.erab_id); m_logger.info("Initial Context Setup Request -- S1-U TEID 0x%" PRIu64 ". IP %s ", erab_ctx_req.gtp_teid.to_number(), @@ -182,7 +180,7 @@ bool s1ap_ctx_mngmt_proc::send_initial_context_setup_request(nas* nas_ctx, uint1 bool s1ap_ctx_mngmt_proc::handle_initial_context_setup_response( const asn1::s1ap::init_context_setup_resp_s& in_ctxt_resp) { - uint32_t mme_ue_s1ap_id = in_ctxt_resp.protocol_ies.mme_ue_s1ap_id.value.value; + uint32_t mme_ue_s1ap_id = in_ctxt_resp->mme_ue_s1ap_id.value.value; nas* nas_ctx = m_s1ap->find_nas_ctx_from_mme_ue_s1ap_id(mme_ue_s1ap_id); if (nas_ctx == nullptr) { m_logger.error("Could not find UE's context in active UE's map"); @@ -195,12 +193,11 @@ bool s1ap_ctx_mngmt_proc::handle_initial_context_setup_response( srsran::console("Received Initial Context Setup Response\n"); // Setup E-RABs - for (const asn1::s1ap::protocol_ie_single_container_s& ie_container : - in_ctxt_resp.protocol_ies.erab_setup_list_ctxt_su_res.value) { + for (const asn1::protocol_ie_single_container_s& ie_container : + in_ctxt_resp->erab_setup_list_ctxt_su_res.value) { // Get E-RAB setup context item and E-RAB Id - const asn1::s1ap::erab_setup_item_ctxt_su_res_s& erab_setup_item_ctxt = - ie_container.value.erab_setup_item_ctxt_su_res(); - uint8_t erab_id = erab_setup_item_ctxt.erab_id; + const asn1::s1ap::erab_setup_item_ctxt_su_res_s& erab_setup_item_ctxt = ie_container->erab_setup_item_ctxt_su_res(); + uint8_t erab_id = erab_setup_item_ctxt.erab_id; // Make sure we requested the context setup esm_ctx_t* esm_ctx = &nas_ctx->m_esm_ctx[erab_id]; @@ -241,7 +238,7 @@ bool s1ap_ctx_mngmt_proc::handle_initial_context_setup_response( bool s1ap_ctx_mngmt_proc::handle_ue_context_release_request(const asn1::s1ap::ue_context_release_request_s& ue_rel, struct sctp_sndrcvinfo* enb_sri) { - uint32_t mme_ue_s1ap_id = ue_rel.protocol_ies.mme_ue_s1ap_id.value.value; + uint32_t mme_ue_s1ap_id = ue_rel->mme_ue_s1ap_id.value.value; m_logger.info("Received UE Context Release Request. MME-UE S1AP Id: %d", mme_ue_s1ap_id); srsran::console("Received UE Context Release Request. MME-UE S1AP Id %d\n", mme_ue_s1ap_id); @@ -313,14 +310,13 @@ bool s1ap_ctx_mngmt_proc::send_ue_context_release_command(nas* nas_ctx) s1ap_pdu_t tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_UE_CONTEXT_RELEASE); - asn1::s1ap::ue_context_release_cmd_ies_container& ctx_rel_cmd = - tx_pdu.init_msg().value.ue_context_release_cmd().protocol_ies; - ctx_rel_cmd.ue_s1ap_ids.value.set(asn1::s1ap::ue_s1ap_ids_c::types_opts::ue_s1ap_id_pair); - ctx_rel_cmd.ue_s1ap_ids.value.ue_s1ap_id_pair().mme_ue_s1ap_id = nas_ctx->m_ecm_ctx.mme_ue_s1ap_id; - ctx_rel_cmd.ue_s1ap_ids.value.ue_s1ap_id_pair().enb_ue_s1ap_id = nas_ctx->m_ecm_ctx.enb_ue_s1ap_id; + asn1::s1ap::ue_context_release_cmd_s& ctx_rel_cmd = tx_pdu.init_msg().value.ue_context_release_cmd(); + ctx_rel_cmd->ue_s1ap_ids.value.set(asn1::s1ap::ue_s1ap_ids_c::types_opts::ue_s1ap_id_pair); + ctx_rel_cmd->ue_s1ap_ids.value.ue_s1ap_id_pair().mme_ue_s1ap_id = nas_ctx->m_ecm_ctx.mme_ue_s1ap_id; + ctx_rel_cmd->ue_s1ap_ids.value.ue_s1ap_id_pair().enb_ue_s1ap_id = nas_ctx->m_ecm_ctx.enb_ue_s1ap_id; - ctx_rel_cmd.cause.value.set(asn1::s1ap::cause_c::types_opts::nas); - ctx_rel_cmd.cause.value.nas().value = asn1::s1ap::cause_nas_opts::options::normal_release; + ctx_rel_cmd->cause.value.set(asn1::s1ap::cause_c::types_opts::nas); + ctx_rel_cmd->cause.value.nas().value = asn1::s1ap::cause_nas_opts::options::normal_release; // Send Reply to eNB if (!m_s1ap->s1ap_tx_pdu(tx_pdu, &nas_ctx->m_ecm_ctx.enb_sri)) { @@ -333,7 +329,7 @@ bool s1ap_ctx_mngmt_proc::send_ue_context_release_command(nas* nas_ctx) bool s1ap_ctx_mngmt_proc::handle_ue_context_release_complete(const asn1::s1ap::ue_context_release_complete_s& rel_comp) { - uint32_t mme_ue_s1ap_id = rel_comp.protocol_ies.mme_ue_s1ap_id.value.value; + uint32_t mme_ue_s1ap_id = rel_comp->mme_ue_s1ap_id.value.value; m_logger.info("Received UE Context Release Complete. MME-UE S1AP Id: %d", mme_ue_s1ap_id); srsran::console("Received UE Context Release Complete. MME-UE S1AP Id %d\n", mme_ue_s1ap_id); diff --git a/srsepc/src/mme/s1ap_erab_mngmt_proc.cc b/srsepc/src/mme/s1ap_erab_mngmt_proc.cc index 7d678bcbff..c76fa57a57 100644 --- a/srsepc/src/mme/s1ap_erab_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_erab_mngmt_proc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -79,19 +79,19 @@ bool s1ap_erab_mngmt_proc::send_erab_release_command(uint32_t enb_ s1ap_pdu_t tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_ERAB_RELEASE); - asn1::s1ap::erab_release_cmd_ies_container& erab_rel_cmd = tx_pdu.init_msg().value.erab_release_cmd().protocol_ies; + asn1::s1ap::erab_release_cmd_s& erab_rel_cmd = tx_pdu.init_msg().value.erab_release_cmd(); // Add MME and eNB S1AP Ids - erab_rel_cmd.mme_ue_s1ap_id.value = mme_ue_s1ap_id; - erab_rel_cmd.enb_ue_s1ap_id.value = enb_ue_s1ap_id; + erab_rel_cmd->mme_ue_s1ap_id.value = mme_ue_s1ap_id; + erab_rel_cmd->enb_ue_s1ap_id.value = enb_ue_s1ap_id; // Number of E-RABs to be setup - erab_rel_cmd.erab_to_be_released_list.value.resize(erabs_to_release.size()); - for (uint32_t i = 0; i < erab_rel_cmd.erab_to_be_released_list.value.size(); i++) { - erab_rel_cmd.erab_to_be_released_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); - erab_rel_cmd.erab_to_be_released_list.value[i].value.erab_item().erab_id = erabs_to_release[i]; - erab_rel_cmd.erab_to_be_released_list.value[i].value.erab_item().cause.set(asn1::s1ap::cause_c::types::misc); - erab_rel_cmd.erab_to_be_released_list.value[i].value.erab_item().cause.misc() = + erab_rel_cmd->erab_to_be_released_list.value.resize(erabs_to_release.size()); + for (uint32_t i = 0; i < erab_rel_cmd->erab_to_be_released_list.value.size(); i++) { + erab_rel_cmd->erab_to_be_released_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); + erab_rel_cmd->erab_to_be_released_list.value[i]->erab_item().erab_id = erabs_to_release[i]; + erab_rel_cmd->erab_to_be_released_list.value[i]->erab_item().cause.set(asn1::s1ap::cause_c::types::misc); + erab_rel_cmd->erab_to_be_released_list.value[i]->erab_item().cause.misc() = asn1::s1ap::cause_misc_opts::unspecified; m_logger.info("Sending release comman to %d", erabs_to_release[i]); } @@ -115,21 +115,20 @@ bool s1ap_erab_mngmt_proc::send_erab_modify_request(uint32_t s1ap_pdu_t tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_ERAB_MODIFY); - asn1::s1ap::erab_modify_request_ies_container& erab_mod_req = - tx_pdu.init_msg().value.erab_modify_request().protocol_ies; + asn1::s1ap::erab_modify_request_s& erab_mod_req = tx_pdu.init_msg().value.erab_modify_request(); // Add MME and eNB S1AP Ids - erab_mod_req.enb_ue_s1ap_id.value = enb_ue_s1ap_id; - erab_mod_req.mme_ue_s1ap_id.value = mme_ue_s1ap_id; + erab_mod_req->enb_ue_s1ap_id.value = enb_ue_s1ap_id; + erab_mod_req->mme_ue_s1ap_id.value = mme_ue_s1ap_id; // Number of E-RABs to be setup - erab_mod_req.erab_to_be_modified_list_bearer_mod_req.value.resize(erabs_to_modify.size()); + erab_mod_req->erab_to_be_modified_list_bearer_mod_req.value.resize(erabs_to_modify.size()); uint32_t i = 0; for (auto erab_it = erabs_to_modify.begin(); erab_it != erabs_to_modify.end(); erab_it++) { - erab_mod_req.erab_to_be_modified_list_bearer_mod_req.value[i].load_info_obj( + erab_mod_req->erab_to_be_modified_list_bearer_mod_req.value[i].load_info_obj( ASN1_S1AP_ID_ERAB_TO_BE_MODIFIED_ITEM_BEARER_MOD_REQ); asn1::s1ap::erab_to_be_modified_item_bearer_mod_req_s& erab_to_mod = - erab_mod_req.erab_to_be_modified_list_bearer_mod_req.value[i].value.erab_to_be_modified_item_bearer_mod_req(); + erab_mod_req->erab_to_be_modified_list_bearer_mod_req.value[i]->erab_to_be_modified_item_bearer_mod_req(); erab_to_mod.erab_id = erab_it->first; erab_to_mod.erab_level_qos_params.qci = erab_it->second; erab_to_mod.erab_level_qos_params.alloc_retention_prio.prio_level = 15; // lowest diff --git a/srsepc/src/mme/s1ap_mngmt_proc.cc b/srsepc/src/mme/s1ap_mngmt_proc.cc index 3db5675538..8f274d540f 100644 --- a/srsepc/src/mme/s1ap_mngmt_proc.cc +++ b/srsepc/src/mme/s1ap_mngmt_proc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -126,36 +126,35 @@ bool s1ap_mngmt_proc::handle_s1_setup_request(const asn1::s1ap::s1_setup_request */ bool s1ap_mngmt_proc::unpack_s1_setup_request(const asn1::s1ap::s1_setup_request_s& msg, enb_ctx_t* enb_ctx) { - uint8_t enb_id_bits[32]; uint32_t plmn = 0; uint16_t tac, bplmn; uint32_t tmp32 = 0; - const asn1::s1ap::s1_setup_request_ies_container& s1_req = msg.protocol_ies; + const asn1::s1ap::s1_setup_request_s& s1_req = msg; // eNB Name - enb_ctx->enb_name_present = s1_req.enbname_present; - if (s1_req.enbname_present) { - enb_ctx->enb_name = s1_req.enbname.value.to_string(); + enb_ctx->enb_name_present = s1_req->enbname_present; + if (s1_req->enbname_present) { + enb_ctx->enb_name = s1_req->enbname.value.to_string(); } // eNB Id - enb_ctx->enb_id = s1_req.global_enb_id.value.enb_id.macro_enb_id().to_number(); + enb_ctx->enb_id = s1_req->global_enb_id.value.enb_id.macro_enb_id().to_number(); // PLMN Id - ((uint8_t*)&plmn)[1] = s1_req.global_enb_id.value.plm_nid[0]; - ((uint8_t*)&plmn)[2] = s1_req.global_enb_id.value.plm_nid[1]; - ((uint8_t*)&plmn)[3] = s1_req.global_enb_id.value.plm_nid[2]; + ((uint8_t*)&plmn)[1] = s1_req->global_enb_id.value.plm_nid[0]; + ((uint8_t*)&plmn)[2] = s1_req->global_enb_id.value.plm_nid[1]; + ((uint8_t*)&plmn)[3] = s1_req->global_enb_id.value.plm_nid[2]; enb_ctx->plmn = ntohl(plmn); srsran::s1ap_plmn_to_mccmnc(enb_ctx->plmn, &enb_ctx->mcc, &enb_ctx->mnc); // SupportedTAs - enb_ctx->nof_supported_ta = s1_req.supported_tas.value.size(); + enb_ctx->nof_supported_ta = s1_req->supported_tas.value.size(); for (uint16_t i = 0; i < enb_ctx->nof_supported_ta; i++) { - const asn1::s1ap::supported_tas_item_s& tas = s1_req.supported_tas.value[i]; + const asn1::s1ap::supported_tas_item_s& tas = s1_req->supported_tas.value[i]; // TAC ((uint8_t*)&enb_ctx->tacs[i])[0] = tas.tac[0]; ((uint8_t*)&enb_ctx->tacs[i])[1] = tas.tac[1]; @@ -172,7 +171,7 @@ bool s1ap_mngmt_proc::unpack_s1_setup_request(const asn1::s1ap::s1_setup_request } // Default Paging DRX - enb_ctx->drx.value = s1_req.default_paging_drx.value; + enb_ctx->drx.value = s1_req->default_paging_drx.value; return true; } @@ -182,10 +181,10 @@ bool s1ap_mngmt_proc::send_s1_setup_failure(asn1::s1ap::cause_misc_opts::options s1ap_pdu_t tx_pdu; tx_pdu.set_unsuccessful_outcome().load_info_obj(ASN1_S1AP_ID_S1_SETUP); - asn1::s1ap::s1_setup_fail_ies_container& s1_fail = tx_pdu.unsuccessful_outcome().value.s1_setup_fail().protocol_ies; + asn1::s1ap::s1_setup_fail_s& s1_fail = tx_pdu.unsuccessful_outcome().value.s1_setup_fail(); - s1_fail.cause.value.set(asn1::s1ap::cause_c::types_opts::misc); - s1_fail.cause.value.misc().value = cause; + s1_fail->cause.value.set(asn1::s1ap::cause_c::types_opts::misc); + s1_fail->cause.value.misc().value = cause; m_s1ap->s1ap_tx_pdu(tx_pdu, enb_sri); return true; @@ -198,20 +197,20 @@ bool s1ap_mngmt_proc::send_s1_setup_response(const s1ap_args_t& s1ap_args, struc s1ap_pdu_t tx_pdu; tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_S1_SETUP); - asn1::s1ap::s1_setup_resp_ies_container& s1_resp = tx_pdu.successful_outcome().value.s1_setup_resp().protocol_ies; + asn1::s1ap::s1_setup_resp_s& s1_resp = tx_pdu.successful_outcome().value.s1_setup_resp(); // MME Name - s1_resp.mm_ename_present = true; - s1_resp.mm_ename.value.from_string(s1ap_args.mme_name); + s1_resp->mm_ename_present = true; + s1_resp->mm_ename.value.from_string(s1ap_args.mme_name); // Served GUMEIs - s1_resp.served_gummeis.value.resize(1); // TODO Only one served GUMMEI supported + s1_resp->served_gummeis.value.resize(1); // TODO Only one served GUMMEI supported uint32_t plmn = 0; srsran::s1ap_mccmnc_to_plmn(s1ap_args.mcc, s1ap_args.mnc, &plmn); plmn = htonl(plmn); - asn1::s1ap::served_gummeis_item_s& serv_gummei = s1_resp.served_gummeis.value[0]; + asn1::s1ap::served_gummeis_item_s& serv_gummei = s1_resp->served_gummeis.value[0]; serv_gummei.served_plmns.resize(1); serv_gummei.served_plmns[0][0] = ((uint8_t*)&plmn)[1]; @@ -224,7 +223,7 @@ bool s1ap_mngmt_proc::send_s1_setup_response(const s1ap_args_t& s1ap_args, struc serv_gummei.served_mmecs.resize(1); // Only one MMEC served serv_gummei.served_mmecs[0].from_number(s1ap_args.mme_code); - s1_resp.relative_mme_capacity.value = 255; + s1_resp->relative_mme_capacity.value = 255; if (!m_s1ap->s1ap_tx_pdu(tx_pdu, enb_sri)) { m_logger.error("Error sending S1 Setup Response."); diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index e4a89a8c99..dea0b2c73d 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -68,19 +68,20 @@ void s1ap_nas_transport::init() m_s1ap = s1ap::get_instance(); // Init NAS args - m_nas_init.mcc = m_s1ap->m_s1ap_args.mcc; - m_nas_init.mnc = m_s1ap->m_s1ap_args.mnc; - m_nas_init.mme_code = m_s1ap->m_s1ap_args.mme_code; - m_nas_init.mme_group = m_s1ap->m_s1ap_args.mme_group; - m_nas_init.tac = m_s1ap->m_s1ap_args.tac; - m_nas_init.apn = m_s1ap->m_s1ap_args.mme_apn; - m_nas_init.dns = m_s1ap->m_s1ap_args.dns_addr; + m_nas_init.mcc = m_s1ap->m_s1ap_args.mcc; + m_nas_init.mnc = m_s1ap->m_s1ap_args.mnc; + m_nas_init.mme_code = m_s1ap->m_s1ap_args.mme_code; + m_nas_init.mme_group = m_s1ap->m_s1ap_args.mme_group; + m_nas_init.tac = m_s1ap->m_s1ap_args.tac; + m_nas_init.apn = m_s1ap->m_s1ap_args.mme_apn; + m_nas_init.dns = m_s1ap->m_s1ap_args.dns_addr; m_nas_init.full_net_name = m_s1ap->m_s1ap_args.full_net_name; m_nas_init.short_net_name = m_s1ap->m_s1ap_args.short_net_name; - m_nas_init.paging_timer = m_s1ap->m_s1ap_args.paging_timer; - m_nas_init.integ_algo = m_s1ap->m_s1ap_args.integrity_algo; - m_nas_init.cipher_algo = m_s1ap->m_s1ap_args.encryption_algo; + m_nas_init.paging_timer = m_s1ap->m_s1ap_args.paging_timer; + m_nas_init.integ_algo = m_s1ap->m_s1ap_args.integrity_algo; + m_nas_init.cipher_algo = m_s1ap->m_s1ap_args.encryption_algo; m_nas_init.request_imeisv = m_s1ap->m_s1ap_args.request_imeisv; + m_nas_init.lac = m_s1ap->m_s1ap_args.lac; // Init NAS interface m_nas_if.s1ap = s1ap::get_instance(); @@ -95,19 +96,19 @@ bool s1ap_nas_transport::handle_initial_ue_message(const asn1::s1ap::init_ue_msg bool err, mac_valid; uint8_t pd, msg_type, sec_hdr_type; srsran::unique_byte_buffer_t nas_msg = srsran::make_byte_buffer(); - memcpy(nas_msg->msg, init_ue.protocol_ies.nas_pdu.value.data(), init_ue.protocol_ies.nas_pdu.value.size()); - nas_msg->N_bytes = init_ue.protocol_ies.nas_pdu.value.size(); + memcpy(nas_msg->msg, init_ue->nas_pdu.value.data(), init_ue->nas_pdu.value.size()); + nas_msg->N_bytes = init_ue->nas_pdu.value.size(); uint64_t imsi = 0; uint32_t m_tmsi = 0; - uint32_t enb_ue_s1ap_id = init_ue.protocol_ies.enb_ue_s1ap_id.value.value; + uint32_t enb_ue_s1ap_id = init_ue->enb_ue_s1ap_id.value.value; liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg.get(), &pd, &msg_type); srsran::console("Initial UE message: %s\n", liblte_nas_msg_type_to_string(msg_type)); m_logger.info("Initial UE message: %s", liblte_nas_msg_type_to_string(msg_type)); - if (init_ue.protocol_ies.s_tmsi_present) { - srsran::uint8_to_uint32(init_ue.protocol_ies.s_tmsi.value.m_tmsi.data(), &m_tmsi); + if (init_ue->s_tmsi_present) { + srsran::uint8_to_uint32(init_ue->s_tmsi.value.m_tmsi.data(), &m_tmsi); } switch (msg_type) { @@ -144,8 +145,8 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr struct sctp_sndrcvinfo* enb_sri) { uint8_t pd, msg_type, sec_hdr_type; - uint32_t enb_ue_s1ap_id = ul_xport.protocol_ies.enb_ue_s1ap_id.value.value; - uint32_t mme_ue_s1ap_id = ul_xport.protocol_ies.mme_ue_s1ap_id.value.value; + uint32_t enb_ue_s1ap_id = ul_xport->enb_ue_s1ap_id.value.value; + uint32_t mme_ue_s1ap_id = ul_xport->mme_ue_s1ap_id.value.value; bool mac_valid = false; bool increase_ul_nas_cnt = true; @@ -163,8 +164,8 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr // Parse NAS message header srsran::unique_byte_buffer_t nas_msg = srsran::make_byte_buffer(); - memcpy(nas_msg->msg, ul_xport.protocol_ies.nas_pdu.value.data(), ul_xport.protocol_ies.nas_pdu.value.size()); - nas_msg->N_bytes = ul_xport.protocol_ies.nas_pdu.value.size(); + memcpy(nas_msg->msg, ul_xport->nas_pdu.value.data(), ul_xport->nas_pdu.value.size()); + nas_msg->N_bytes = ul_xport->nas_pdu.value.size(); bool msg_encrypted = false; // Parse the message security header @@ -179,17 +180,28 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr m_logger.error("Unhandled security header type in Uplink NAS Transport: %d", sec_hdr_type); return false; } - // Todo: Check on count mismatch of uplink count and do resync nas counter... + + // Some messages may have invalid MAC. Check wether we need to warn about MAC failures. + bool warn_integrity_fail = true; + if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY || + sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT) { + // Avoid unecessary warnings for identity response and authentication response. + liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)nas_msg.get(), &pd, &msg_type); + if (msg_type == LIBLTE_MME_MSG_TYPE_IDENTITY_RESPONSE || msg_type == LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE) { + warn_integrity_fail = false; + } + } // Check MAC if message is integrity protected if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY || - sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT || + sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED || sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) { - mac_valid = nas_ctx->integrity_check(nas_msg.get()); - if (mac_valid == false) { - m_logger.warning("Invalid MAC message. Even if security header indicates integrity protection (Maybe: " - "Identity Response or Authentication Response)"); + mac_valid = nas_ctx->integrity_check(nas_msg.get(), warn_integrity_fail); + if (not mac_valid) { + srslog::log_channel& channel = warn_integrity_fail ? m_logger.warning : m_logger.info; + channel("Invalid MAC message. Even if security header indicates integrity protection (Maybe: " + "Identity Response or Authentication Response)"); } } @@ -317,6 +329,11 @@ bool s1ap_nas_transport::handle_uplink_nas_transport(const asn1::s1ap::ul_nas_tr srsran::console("UL NAS: Tracking Area Update Request\n"); nas_ctx->handle_tracking_area_update_request(nas_msg.get()); break; + case LIBLTE_MME_MSG_TYPE_PDN_CONNECTIVITY_REQUEST: + m_logger.info("UL NAS: PDN Connectivity Request"); + srsran::console("UL NAS: PDN Connectivity Request\n"); + nas_ctx->handle_pdn_connectivity_request(nas_msg.get()); + break; default: m_logger.warning("Unhandled NAS integrity protected message %s", liblte_nas_msg_type_to_string(msg_type)); srsran::console("Unhandled NAS integrity protected message %s\n", liblte_nas_msg_type_to_string(msg_type)); @@ -346,13 +363,13 @@ bool s1ap_nas_transport::send_downlink_nas_transport(uint32_t enb_ tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_DL_NAS_TRANSPORT); // Setup Dw NAS structure - asn1::s1ap::dl_nas_transport_ies_container& dw_nas = tx_pdu.init_msg().value.dl_nas_transport().protocol_ies; - dw_nas.enb_ue_s1ap_id.value = enb_ue_s1ap_id; - dw_nas.mme_ue_s1ap_id.value = mme_ue_s1ap_id; + asn1::s1ap::dl_nas_transport_s& dw_nas = tx_pdu.init_msg().value.dl_nas_transport(); + dw_nas->enb_ue_s1ap_id.value = enb_ue_s1ap_id; + dw_nas->mme_ue_s1ap_id.value = mme_ue_s1ap_id; // Copy NAS PDU to Downlink NAS Trasport message buffer - dw_nas.nas_pdu.value.resize(nas_msg->N_bytes); - memcpy(dw_nas.nas_pdu.value.data(), nas_msg->msg, nas_msg->N_bytes); + dw_nas->nas_pdu.value.resize(nas_msg->N_bytes); + memcpy(dw_nas->nas_pdu.value.data(), nas_msg->msg, nas_msg->N_bytes); // Send Downlink NAS Transport Message m_s1ap->s1ap_tx_pdu(tx_pdu, &enb_sri); diff --git a/srsepc/src/mme/s1ap_paging.cc b/srsepc/src/mme/s1ap_paging.cc index bdf4728eae..8b4f973cc8 100644 --- a/srsepc/src/mme/s1ap_paging.cc +++ b/srsepc/src/mme/s1ap_paging.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -47,7 +47,7 @@ bool s1ap_paging::send_paging(uint64_t imsi, uint16_t erab_to_setup) // Prepare reply PDU s1ap_pdu_t tx_pdu; tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_PAGING); - asn1::s1ap::paging_ies_container& paging = tx_pdu.init_msg().value.paging().protocol_ies; + asn1::s1ap::paging_s& paging = tx_pdu.init_msg().value.paging(); // Getting UE NAS Context nas* nas_ctx = m_s1ap->find_nas_ctx_from_imsi(imsi); @@ -58,25 +58,25 @@ bool s1ap_paging::send_paging(uint64_t imsi, uint16_t erab_to_setup) // UE Identity Index uint16_t ue_index = imsi % 1024; - paging.ue_id_idx_value.value.from_number(ue_index); + paging->ue_id_idx_value.value.from_number(ue_index); // UE Paging Id - paging.ue_paging_id.value.set_s_tmsi(); - paging.ue_paging_id.value.s_tmsi().mmec.from_number(m_s1ap->m_s1ap_args.mme_code); - paging.ue_paging_id.value.s_tmsi().m_tmsi.from_number(nas_ctx->m_sec_ctx.guti.m_tmsi); + paging->ue_paging_id.value.set_s_tmsi(); + paging->ue_paging_id.value.s_tmsi().mmec.from_number(m_s1ap->m_s1ap_args.mme_code); + paging->ue_paging_id.value.s_tmsi().m_tmsi.from_number(nas_ctx->m_sec_ctx.guti.m_tmsi); // CMDomain - paging.cn_domain.value = asn1::s1ap::cn_domain_opts::ps; + paging->cn_domain.value = asn1::s1ap::cn_domain_opts::ps; // TAI List - paging.tai_list.value.resize(1); - paging.tai_list.value[0].load_info_obj(ASN1_S1AP_ID_TAI_ITEM); + paging->tai_list.value.resize(1); + paging->tai_list.value[0].load_info_obj(ASN1_S1AP_ID_TAI_ITEM); uint32_t plmn = m_s1ap->get_plmn(); - paging.tai_list.value[0].value.tai_item().tai.plm_nid.from_number(plmn); + paging->tai_list.value[0]->tai_item().tai.plm_nid.from_number(plmn); uint16_t tac = m_s1ap->m_s1ap_args.tac; - paging.tai_list.value[0].value.tai_item().tai.tac.from_number(tac); + paging->tai_list.value[0]->tai_item().tai.tac.from_number(tac); // Start T3413 if (!nas_ctx->start_timer(T_3413)) { diff --git a/srsepc/src/spgw/CMakeLists.txt b/srsepc/src/spgw/CMakeLists.txt index df4a51dbb6..5339ec1bb7 100644 --- a/srsepc/src/spgw/CMakeLists.txt +++ b/srsepc/src/spgw/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsepc/src/spgw/gtpc.cc b/srsepc/src/spgw/gtpc.cc index 17e4826733..c681310d55 100644 --- a/srsepc/src/spgw/gtpc.cc +++ b/srsepc/src/spgw/gtpc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -464,8 +464,8 @@ spgw_tunnel_ctx_t* spgw::gtpc::create_gtpc_ctx(const struct srsran::gtpc_create_ tunnel_ctx->dw_ctrl_fteid.ipv4 = cs_req.sender_f_teid.ipv4; std::memset(&tunnel_ctx->dw_user_fteid, 0, sizeof(srsran::gtp_fteid_t)); - m_teid_to_tunnel_ctx.insert(std::pair(spgw_uplink_ctrl_teid, tunnel_ctx)); - m_imsi_to_ctr_teid.insert(std::pair(cs_req.imsi, spgw_uplink_ctrl_teid)); + m_teid_to_tunnel_ctx.emplace(spgw_uplink_ctrl_teid, tunnel_ctx); + m_imsi_to_ctr_teid.emplace(cs_req.imsi, spgw_uplink_ctrl_teid); return tunnel_ctx; } diff --git a/srsepc/src/spgw/gtpu.cc b/srsepc/src/spgw/gtpu.cc index b8df8e53aa..0ddf2bcdaf 100644 --- a/srsepc/src/spgw/gtpu.cc +++ b/srsepc/src/spgw/gtpu.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/src/spgw/spgw.cc b/srsepc/src/spgw/spgw.cc index aa97eb48d7..c224210af6 100644 --- a/srsepc/src/spgw/spgw.cc +++ b/srsepc/src/spgw/spgw.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsepc/srsepc_if_masq.sh b/srsepc/srsepc_if_masq.sh index e62a0c8772..2873195df4 100755 --- a/srsepc/srsepc_if_masq.sh +++ b/srsepc/srsepc_if_masq.sh @@ -1,7 +1,7 @@ #!/bin/bash # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -26,7 +26,7 @@ sudo -v || exit #Check if outbound interface was specified if [ ! $# -eq 1 ] then - echo "Usage :'sudo ./if_masq.sh ' " + echo "Usage :'sudo ./srsepc_if_masq.sh ' " exit fi diff --git a/srsgnb/CMakeLists.txt b/srsgnb/CMakeLists.txt new file mode 100644 index 0000000000..5faaddf0e2 --- /dev/null +++ b/srsgnb/CMakeLists.txt @@ -0,0 +1,21 @@ +# +# Copyright 2013-2023 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/. +# + +add_subdirectory(src) \ No newline at end of file diff --git a/srsgnb/hdr/phy/phy_nr_interfaces.h b/srsgnb/hdr/phy/phy_nr_interfaces.h new file mode 100644 index 0000000000..3b461b90f2 --- /dev/null +++ b/srsgnb/hdr/phy/phy_nr_interfaces.h @@ -0,0 +1,42 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_PHY_NR_INTERFACES_H +#define SRSRAN_PHY_NR_INTERFACES_H + +#include "srsran/srsran.h" +#include + +namespace srsenb { + +struct phy_cell_cfg_nr_t { + srsran_carrier_nr_t carrier; + uint32_t rf_port; + uint32_t cell_id; + float gain_db; + bool dl_measure; +}; + +using phy_cell_cfg_list_nr_t = std::vector; + +} // namespace srsenb + +#endif // SRSRAN_PHY_NR_INTERFACES_H diff --git a/srsenb/test/common/dummy_classes_nr.h b/srsgnb/hdr/stack/common/test/dummy_nr_classes.h similarity index 52% rename from srsenb/test/common/dummy_classes_nr.h rename to srsgnb/hdr/stack/common/test/dummy_nr_classes.h index d1381a028b..bb57c3da7d 100644 --- a/srsenb/test/common/dummy_classes_nr.h +++ b/srsgnb/hdr/stack/common/test/dummy_nr_classes.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,15 +24,38 @@ #include "srsran/interfaces/gnb_interfaces.h" #include "srsran/interfaces/gnb_mac_interfaces.h" +#include "srsran/interfaces/gnb_ngap_interfaces.h" namespace srsenb { +class ngap_dummy : public ngap_interface_rrc_nr +{ + void initial_ue(uint16_t rnti, + uint32_t gnb_cc_idx, + asn1::ngap::rrcestablishment_cause_e cause, + srsran::const_byte_span pdu) + {} + void initial_ue(uint16_t rnti, + uint32_t gnb_cc_idx, + asn1::ngap::rrcestablishment_cause_e cause, + srsran::const_byte_span pdu, + uint32_t m_tmsi) + {} + + void write_pdu(uint16_t rnti, srsran::const_byte_span pdu) {} + bool user_exists(uint16_t rnti) { return true; } + void user_mod(uint16_t old_rnti, uint16_t new_rnti) {} + void user_release_request(uint16_t rnti, asn1::ngap::cause_radio_network_e cause_radio) {} + bool is_amf_connected() { return true; } + void ue_notify_rrc_reconf_complete(uint16_t rnti, bool outcome) {} +}; + class rrc_nr_dummy : public rrc_interface_mac_nr { public: - int read_pdu_bcch_bch(const uint32_t tti, srsran::unique_byte_buffer_t& buffer) { return SRSRAN_SUCCESS; } - int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) { return SRSRAN_SUCCESS; } - int add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg) { return SRSRAN_SUCCESS; } + int read_pdu_bcch_bch(const uint32_t tti, srsran::byte_buffer_t& buffer) { return SRSRAN_SUCCESS; } + int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::byte_buffer_t& buffer) { return SRSRAN_SUCCESS; } + int add_user(uint16_t rnti, uint32_t pcell_cc_idx) { return SRSRAN_SUCCESS; } int update_user(uint16_t new_rnti, uint16_t old_rnti) { return SRSRAN_SUCCESS; } void set_activity_user(uint16_t rnti) {} }; @@ -48,14 +71,25 @@ class rlc_nr_dummy : public rlc_interface_mac_nr class mac_nr_dummy : public mac_interface_rrc_nr { public: - int cell_cfg(const std::vector& nr_cells) override { return SRSRAN_SUCCESS; } + int cell_cfg(const std::vector& nr_cells_) override + { + nr_cells = nr_cells_; + return SRSRAN_SUCCESS; + } uint16_t reserve_rnti(uint32_t enb_cc_idx, const sched_nr_ue_cfg_t& uecfg) override { return 0x4601; } - int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) override { return SRSRAN_SUCCESS; } + int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) override + { + last_ue_cfg_rnti = rnti; + last_ue_cfg = ue_cfg; + return SRSRAN_SUCCESS; + } int remove_ue(uint16_t rnti) override { return SRSRAN_SUCCESS; } - srsenb::sched_interface::cell_cfg_t cellcfgobj; + std::vector nr_cells; + uint16_t last_ue_cfg_rnti = SRSRAN_INVALID_RNTI; + sched_nr_interface::ue_cfg_t last_ue_cfg{}; }; class phy_nr_dummy : public phy_interface_stack_nr diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsgnb/hdr/stack/gnb_stack_nr.h similarity index 76% rename from srsenb/hdr/stack/gnb_stack_nr.h rename to srsgnb/hdr/stack/gnb_stack_nr.h index aa2fa1c928..2d63db9ce4 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsgnb/hdr/stack/gnb_stack_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -27,20 +27,29 @@ #ifndef SRSRAN_GNB_STACK_NR_H #define SRSRAN_GNB_STACK_NR_H -#include "srsenb/hdr/stack/mac/nr/mac_nr.h" -#include "srsenb/hdr/stack/rrc/rrc_nr.h" -#include "upper/pdcp.h" -#include "upper/rlc.h" -#include "upper/sdap.h" +#include "srsenb/hdr/stack/upper/pdcp.h" +#include "srsenb/hdr/stack/upper/rlc.h" +#include "srsgnb/hdr/stack/mac/mac_nr.h" +#include "srsgnb/hdr/stack/rrc/rrc_nr.h" +#include "srsgnb/hdr/stack/sdap/sdap.h" -#include "enb_stack_base.h" +#include "srsenb/hdr/stack/enb_stack_base.h" #include "srsran/interfaces/gnb_interfaces.h" +#include "srsran/common/ngap_pcap.h" + namespace srsenb { +class ngap; +class gtpu; +class enb_bearer_manager; +class gtpu_pdcp_adapter; + struct gnb_stack_args_t { stack_log_args_t log; mac_nr_args_t mac; + ngap_args_t ngap; + pcap_args_t ngap_pcap; }; class gnb_stack_nr final : public srsenb::enb_stack_base, @@ -80,12 +89,12 @@ class gnb_stack_nr final : public srsenb::enb_stack_base, void toggle_padding() override {} - int slot_indication(const srsran_slot_cfg_t& slot_cfg) override; - int get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) override; - int get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) override; - int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) override; - int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) override; - void rach_detected(const rach_info_t& rach_info) override; + int slot_indication(const srsran_slot_cfg_t& slot_cfg) override; + dl_sched_t* get_dl_sched(const srsran_slot_cfg_t& slot_cfg) override; + ul_sched_t* get_ul_sched(const srsran_slot_cfg_t& slot_cfg) override; + int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) override; + int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) override; + void rach_detected(const rach_info_t& rach_info) override; // X2 interface @@ -130,8 +139,12 @@ class gnb_stack_nr final : public srsenb::enb_stack_base, srslog::basic_logger& mac_logger; srslog::basic_logger& rlc_logger; srslog::basic_logger& pdcp_logger; + srslog::basic_logger& ngap_logger; + srslog::basic_logger& gtpu_logger; srslog::basic_logger& stack_logger; + srsran::ngap_pcap ngap_pcap; + // task scheduling static const int STACK_MAIN_THREAD_PRIO = 4; srsran::task_scheduler task_sched; @@ -142,13 +155,18 @@ class gnb_stack_nr final : public srsenb::enb_stack_base, std::mutex metrics_mutex; std::condition_variable metrics_cvar; - // derived - srsenb::mac_nr mac; - srsenb::rlc rlc; - srsenb::pdcp pdcp; - srsenb::rrc_nr rrc; + // layers + srsenb::mac_nr mac; + srsenb::rlc rlc; + srsenb::pdcp pdcp; + srsenb::rrc_nr rrc; + std::unique_ptr ngap; + std::unique_ptr gtpu; // std::unique_ptr m_sdap; + std::unique_ptr bearer_manager; + std::unique_ptr gtpu_adapter; + // state std::atomic running = {false}; }; diff --git a/srsenb/hdr/stack/mac/nr/harq_softbuffer.h b/srsgnb/hdr/stack/mac/harq_softbuffer.h similarity index 98% rename from srsenb/hdr/stack/mac/nr/harq_softbuffer.h rename to srsgnb/hdr/stack/mac/harq_softbuffer.h index 65aa2e0db5..02eb664d30 100644 --- a/srsenb/hdr/stack/mac/nr/harq_softbuffer.h +++ b/srsgnb/hdr/stack/mac/harq_softbuffer.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsgnb/hdr/stack/mac/mac_nr.h similarity index 68% rename from srsenb/hdr/stack/mac/nr/mac_nr.h rename to srsgnb/hdr/stack/mac/mac_nr.h index aefdc613a2..5e33b10c32 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsgnb/hdr/stack/mac/mac_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -27,8 +27,7 @@ #include "srsenb/hdr/common/rnti_pool.h" #include "srsenb/hdr/stack/enb_stack_base.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr.h" -#include "srsenb/hdr/stack/mac/nr/ue_nr.h" +#include "srsgnb/hdr/stack/mac/ue_nr.h" #include "srsran/common/task_scheduler.h" #include "srsran/interfaces/enb_metrics_interface.h" #include "srsran/interfaces/enb_rlc_interfaces.h" @@ -44,7 +43,13 @@ struct mac_nr_args_t { srsenb::pcap_args_t pcap; }; -class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, public mac_interface_rlc_nr +class sched_nr; +class mac_nr_rx; + +class mac_nr final : public mac_interface_phy_nr, + public mac_interface_rrc_nr, + public mac_interface_rlc_nr, + public mac_interface_pdu_demux_nr { public: explicit mac_nr(srsran::task_sched_handle task_sched_); @@ -61,7 +66,7 @@ class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, p void get_metrics(srsenb::mac_metrics_t& metrics); // MAC interface for RRC - int cell_cfg(const std::vector& nr_cells) override; + int cell_cfg(const std::vector& nr_cells) override; uint16_t reserve_rnti(uint32_t enb_cc_idx, const sched_nr_interface::ue_cfg_t& uecfg) override; int read_pdu_bcch_bch(uint8_t* payload); int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) override; @@ -71,12 +76,15 @@ class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, p int rlc_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t tx_queue, uint32_t retx_queue) override; // Interface for PHY - int slot_indication(const srsran_slot_cfg_t& slot_cfg) override; - int get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) override; - int get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) override; - int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) override; - int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) override; - void rach_detected(const rach_info_t& rach_info) override; + int slot_indication(const srsran_slot_cfg_t& slot_cfg) override; + dl_sched_t* get_dl_sched(const srsran_slot_cfg_t& slot_cfg) override; + ul_sched_t* get_ul_sched(const srsran_slot_cfg_t& slot_cfg) override; + int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) override; + int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) override; + void rach_detected(const rach_info_t& rach_info) override; + + // MAC-internal interface + void store_msg3(uint16_t rnti, srsran::unique_byte_buffer_t pdu) override; // Test interface void ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr); @@ -90,17 +98,15 @@ class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, p bool is_rnti_active_nolock(uint16_t rnti); // handle UCI data from either PUCCH or PUSCH - bool handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg, const srsran_uci_value_nr_t& value); - - // PDU processing - int handle_pdu(srsran::unique_byte_buffer_t pdu); + bool handle_uci_data(uint16_t rnti, const srsran_uci_cfg_nr_t& cfg, const srsran_uci_value_nr_t& value); // Metrics processing void get_metrics_nolock(srsenb::mac_metrics_t& metrics); // Encoding - srsran::byte_buffer_t* assemble_rar(srsran::const_span grants); - srsran::unique_byte_buffer_t rar_pdu_buffer = nullptr; + srsran::byte_buffer_t* assemble_rar(srsran::const_span grants); + + srsran::unique_byte_buffer_t rar_pdu_buffer; // Interaction with other components phy_interface_stack_nr* phy = nullptr; @@ -109,18 +115,21 @@ class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, p rrc_interface_mac_nr* rrc = nullptr; // args - srsran::task_sched_handle task_sched; - srsran::task_multiqueue::queue_handle stack_task_queue; + srsran::task_sched_handle task_sched; + srsran::task_queue_handle stack_task_queue; + mac_nr_args_t args = {}; + srslog::basic_logger& logger; + + // initial UE config, before RRC setup (without UE-dedicated) + srsran::phy_cfg_nr_t default_ue_phy_cfg; std::unique_ptr pcap = nullptr; - mac_nr_args_t args = {}; - srslog::basic_logger& logger; std::atomic started = {false}; - const static uint32_t NUMEROLOGY_IDX = 0; /// only 15kHz supported at this stage - srsenb::sched_nr sched; - std::vector cell_config; + const static uint32_t NUMEROLOGY_IDX = 0; /// only 15kHz supported at this stage + std::unique_ptr sched; + std::vector cell_config; // Map of active UEs pthread_rwlock_t rwmutex = {}; @@ -140,6 +149,9 @@ class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, p // Number of rach preambles detected for a CC std::vector detected_rachs; + + // Decoding of UL PDUs + std::unique_ptr rx; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/nr/sched_nr.h b/srsgnb/hdr/stack/mac/sched_nr.h similarity index 58% rename from srsenb/hdr/stack/mac/nr/sched_nr.h rename to srsgnb/hdr/stack/mac/sched_nr.h index f0606df114..8f8d0e24ef 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr.h +++ b/srsgnb/hdr/stack/mac/sched_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -26,6 +26,7 @@ #include "sched_nr_interface.h" #include "sched_nr_ue.h" #include "srsran/adt/pool/cached_alloc.h" +#include "srsran/adt/pool/circular_stack_pool.h" #include "srsran/common/slot_point.h" #include extern "C" { @@ -35,54 +36,66 @@ extern "C" { namespace srsenb { namespace sched_nr_impl { -class sched_worker_manager; -class serv_cell_manager; -} // namespace sched_nr_impl -class ul_sched_result_buffer; +class cc_worker; + +} // namespace sched_nr_impl class sched_nr final : public sched_nr_interface { public: explicit sched_nr(); ~sched_nr() override; - int config(const sched_args_t& sched_cfg, srsran::const_span cell_list) override; + + void stop(); + int config(const sched_args_t& sched_cfg, srsran::const_span cell_list) override; void ue_cfg(uint16_t rnti, const ue_cfg_t& cfg) override; void ue_rem(uint16_t rnti) override; - bool ue_exists(uint16_t rnti) override; - int dl_rach_info(uint32_t cc, const rar_info_t& rar_info); + int dl_rach_info(const rar_info_t& rar_info); void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) override; void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) override; void ul_sr_info(uint16_t rnti) override; void ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) override; void dl_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t newtx, uint32_t retx); + void dl_mac_ce(uint16_t rnti, uint32_t ce_lcid) override; + void dl_cqi_info(uint16_t rnti, uint32_t cc, uint32_t cqi_value); - int run_slot(slot_point pdsch_tti, uint32_t cc, dl_res_t& result) override; - int get_ul_sched(slot_point pusch_tti, uint32_t cc, ul_res_t& result) override; + /// Called once per slot in a non-concurrent fashion + void slot_indication(slot_point slot_tx) override; + dl_res_t* get_dl_sched(slot_point pdsch_tti, uint32_t cc) override; + ul_res_t* get_ul_sched(slot_point pusch_tti, uint32_t cc) override; void get_metrics(mac_metrics_t& metrics); private: - void ue_cfg_impl(uint16_t rnti, const ue_cfg_t& cfg); + int ue_cfg_impl(uint16_t rnti, const ue_cfg_t& cfg); + int add_ue_impl(uint16_t rnti, sched_nr_impl::unique_ue_ptr u); // args - sched_nr_impl::sched_params cfg; - srslog::basic_logger* logger = nullptr; + sched_nr_impl::sched_params_t cfg; + srslog::basic_logger* logger = nullptr; + + // slot-specific + slot_point current_slot_tx; + std::atomic worker_count{0}; - using sched_worker_manager = sched_nr_impl::sched_worker_manager; - std::unique_ptr sched_workers; + using slot_cc_worker = sched_nr_impl::cc_worker; + std::vector > cc_workers; + // UE Database + std::unique_ptr > ue_pool; using ue_map_t = sched_nr_impl::ue_map_t; - std::mutex ue_db_mutex; - ue_map_t ue_db; + ue_map_t ue_db; - // management of Sched Result buffering - std::unique_ptr pending_results; + // Feedback management + class event_manager; + std::unique_ptr pending_events; - // management of cell resources - std::vector > cells; + // metrics extraction + class ue_metrics_manager; + std::unique_ptr metrics_handler; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cell.h b/srsgnb/hdr/stack/mac/sched_nr_bwp.h similarity index 56% rename from srsenb/hdr/stack/mac/nr/sched_nr_cell.h rename to srsgnb/hdr/stack/mac/sched_nr_bwp.h index cbbb26e54b..ff611d3a70 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cell.h +++ b/srsgnb/hdr/stack/mac/sched_nr_bwp.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,41 +19,18 @@ * */ -#ifndef SRSRAN_SCHED_NR_CELL_H -#define SRSRAN_SCHED_NR_CELL_H +#ifndef SRSRAN_SCHED_NR_BWP_H +#define SRSRAN_SCHED_NR_BWP_H #include "sched_nr_cfg.h" #include "sched_nr_grant_allocator.h" +#include "sched_nr_signalling.h" #include "sched_nr_time_rr.h" #include "srsran/adt/pool/cached_alloc.h" namespace srsenb { namespace sched_nr_impl { -/// SIB scheduler -class si_sched -{ -public: - explicit si_sched(const bwp_params_t& bwp_cfg_); - - void run_slot(bwp_slot_allocator& slot_alloc); - -private: - const bwp_params_t* bwp_cfg = nullptr; - srslog::basic_logger& logger; - - struct sched_si_t { - uint32_t n = 0; - uint32_t len = 0; - uint32_t win_len = 0; - uint32_t period = 0; - uint32_t n_tx = 0; - alloc_result result = alloc_result::invalid_coderate; - slot_point win_start; - }; - srsran::bounded_vector pending_sis; -}; - using dl_sched_rar_info_t = sched_nr_interface::rar_info_t; /// RAR/Msg3 scheduler @@ -73,10 +50,10 @@ class ra_sched private: struct pending_rar_t { - uint16_t ra_rnti = 0; - slot_point prach_slot; - slot_interval rar_win; - srsran::bounded_vector msg3_grant; + uint16_t ra_rnti = 0; + slot_point prach_slot; + slot_interval rar_win; + srsran::bounded_vector msg3_grant; }; alloc_result @@ -88,14 +65,15 @@ class ra_sched srsran::deque pending_rars; }; -class bwp_ctxt +class bwp_manager { public: - explicit bwp_ctxt(const bwp_params_t& bwp_cfg); + explicit bwp_manager(const bwp_params_t& bwp_cfg); const bwp_params_t* cfg; // channel-specific schedulers + si_sched si; ra_sched ra; std::unique_ptr data_sched; @@ -103,21 +81,7 @@ class bwp_ctxt bwp_res_grid grid; }; -class serv_cell_manager -{ -public: - using feedback_callback_t = srsran::move_callback; - - explicit serv_cell_manager(const cell_params_t& cell_cfg_); - - srsran::bounded_vector bwps; - const cell_params_t& cfg; - -private: - srslog::basic_logger& logger; -}; - } // namespace sched_nr_impl } // namespace srsenb -#endif // SRSRAN_SCHED_NR_CELL_H +#endif // SRSRAN_SCHED_NR_BWP_H diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h b/srsgnb/hdr/stack/mac/sched_nr_cfg.h similarity index 50% rename from srsenb/hdr/stack/mac/nr/sched_nr_cfg.h rename to srsgnb/hdr/stack/mac/sched_nr_cfg.h index fe4fe2bfdf..b5f10226c0 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h +++ b/srsgnb/hdr/stack/mac/sched_nr_cfg.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,16 +22,14 @@ #ifndef SRSRAN_SCHED_NR_CFG_H #define SRSRAN_SCHED_NR_CFG_H -#include "sched_nr_interface.h" +#include "sched_nr_interface_utils.h" #include "sched_nr_rb.h" #include "srsenb/hdr/common/common_enb.h" +#include "srsran/adt/optional_array.h" namespace srsenb { -const static size_t SCHED_NR_MAX_USERS = SRSENB_MAX_UES; -const static size_t SCHED_NR_NOF_SUBFRAMES = 10; -const static size_t SCHED_NR_NOF_HARQS = 16; -static const size_t MAX_NOF_AGGR_LEVELS = 5; +static const size_t MAX_NOF_AGGR_LEVELS = 5; namespace sched_nr_impl { @@ -44,15 +42,14 @@ using pusch_t = mac_interface_phy_nr::pusch_t; using pucch_t = mac_interface_phy_nr::pucch_t; using pdcch_dl_list_t = srsran::bounded_vector; using pdcch_ul_list_t = srsran::bounded_vector; +using pdsch_list_t = srsran::bounded_vector; using pucch_list_t = srsran::bounded_vector; using pusch_list_t = srsran::bounded_vector; using nzp_csi_rs_list = srsran::bounded_vector; using ssb_t = mac_interface_phy_nr::ssb_t; using ssb_list = srsran::bounded_vector; using sched_args_t = sched_nr_interface::sched_args_t; -using cell_cfg_t = sched_nr_interface::cell_cfg_t; -using bwp_cfg_t = sched_nr_interface::bwp_cfg_t; -using ue_cfg_t = sched_nr_interface::ue_cfg_t; +using bwp_cfg_t = sched_nr_bwp_cfg_t; using ue_cc_cfg_t = sched_nr_interface::ue_cc_cfg_t; using pdcch_cce_pos_list = srsran::bounded_vector; using bwp_cce_pos_list = std::array, SRSRAN_NOF_SF_X_FRAME>; @@ -68,20 +65,23 @@ void get_dci_locs(const srsran_coreset_t& coreset, /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +struct cell_config_manager; + /// Structure that extends the sched_nr_interface::bwp_cfg_t passed by upper layers with other /// derived BWP-specific params struct bwp_params_t { - const uint32_t bwp_id; - const uint32_t cc; - const bwp_cfg_t& cfg; - const cell_cfg_t& cell_cfg; - const sched_args_t& sched_cfg; + const uint32_t bwp_id; + const uint32_t cc; + const bwp_cfg_t cfg; + const cell_config_manager& cell_cfg; + const sched_args_t& sched_cfg; + sched_nr_bwp_cfg_t bwp_cfg; // derived params srslog::basic_logger& logger; uint32_t P; uint32_t N_rbg; - uint32_t nof_prb() const { return cell_cfg.carrier.nof_prb; } + uint32_t nof_prb; /// Table specifying if a slot has DL or UL enabled struct slot_cfg { @@ -100,106 +100,59 @@ struct bwp_params_t { bwp_cce_pos_list rar_cce_list; - bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg_, uint32_t cc, uint32_t bwp_id); -}; - -/// Structure packing a single cell config params, and sched args -struct cell_params_t { - const uint32_t cc; - const cell_cfg_t cfg; - const sched_args_t& sched_args; - std::vector bwps; - - cell_params_t(uint32_t cc_, const cell_cfg_t& cell, const sched_args_t& sched_cfg_); + srsran::optional_vector common_cce_list; - uint32_t nof_prb() const { return cfg.carrier.nof_prb; } -}; + bwp_params_t(const cell_config_manager& cell, uint32_t bwp_id, const sched_nr_bwp_cfg_t& bwp_cfg); -/// Structure packing both the sched args and all gNB NR cell configurations -struct sched_params { - sched_args_t sched_cfg; - std::vector cells; + prb_interval coreset_prb_range(uint32_t cs_id) const { return coresets[cs_id].prb_limits; } + prb_interval dci_fmt_1_0_prb_lims(uint32_t cs_id) const { return coresets[cs_id].dci_1_0_prb_limits; } + bwp_rb_bitmap dci_fmt_1_0_excluded_prbs(uint32_t cs_id) const { return coresets[cs_id].usable_common_ss_prb_mask; } - sched_params() = default; - explicit sched_params(const sched_args_t& sched_cfg_); -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/// Configuration of a UE for a given BWP -class bwp_ue_cfg -{ -public: - bwp_ue_cfg() = default; - explicit bwp_ue_cfg(uint16_t rnti, const bwp_params_t& bwp_cfg, const ue_cfg_t& uecfg_); - - const ue_cfg_t* ue_cfg() const { return cfg_; } - const srsran::phy_cfg_nr_t& phy() const { return cfg_->phy_cfg; } - const bwp_params_t& active_bwp() const { return *bwp_cfg; } - srsran::const_span cce_pos_list(uint32_t search_id, uint32_t slot_idx, uint32_t aggr_idx) const - { - if (cce_positions_list.size() > ss_id_to_cce_idx[search_id]) { - auto& lst = cce_pos_list(search_id); - return lst[slot_idx][aggr_idx]; - } - return srsran::const_span{}; - } - const bwp_cce_pos_list& cce_pos_list(uint32_t search_id) const - { - return cce_positions_list[ss_id_to_cce_idx[search_id]]; - } - uint32_t get_k1(slot_point pdsch_slot) const + const srsran_search_space_t* get_ss(uint32_t ss_id) const { - if (phy().duplex.mode == SRSRAN_DUPLEX_MODE_TDD) { - return phy().harq_ack.dl_data_to_ul_ack[pdsch_slot.to_uint() % phy().duplex.tdd.pattern1.period_ms]; - } - return phy().harq_ack.dl_data_to_ul_ack[pdsch_slot.to_uint() % phy().harq_ack.nof_dl_data_to_ul_ack]; + return cfg.pdcch.search_space_present[ss_id] ? &cfg.pdcch.search_space[ss_id] : nullptr; } - int fixed_pdsch_mcs() const { return bwp_cfg->sched_cfg.fixed_dl_mcs; } - int fixed_pusch_mcs() const { return bwp_cfg->sched_cfg.fixed_ul_mcs; } private: - uint16_t rnti = SRSRAN_INVALID_RNTI; - const ue_cfg_t* cfg_ = nullptr; - const bwp_params_t* bwp_cfg = nullptr; - - std::vector cce_positions_list; - std::array ss_id_to_cce_idx; -}; - -class ue_cfg_extended : public ue_cfg_t -{ -public: - struct search_space_params { - const srsran_search_space_t* cfg; - bwp_cce_pos_list cce_positions; - }; - struct coreset_params { - srsran_coreset_t* cfg = nullptr; - std::vector ss_list; - }; - struct bwp_params { - std::array, SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE> ss_list; - std::vector coresets; - }; - struct cc_params { - srsran::bounded_vector bwps; + bwp_rb_bitmap cached_empty_prb_mask; + struct coreset_cached_params { + prb_interval prb_limits; + prb_interval dci_1_0_prb_limits; /// See TS 38.214, section 5.1.2.2 + bwp_rb_bitmap usable_common_ss_prb_mask; }; + srsran::optional_vector coresets; +}; - ue_cfg_extended() = default; - explicit ue_cfg_extended(uint16_t rnti, const ue_cfg_t& uecfg); +/// Structure packing a single cell config params, and sched args +struct cell_config_manager { + const uint32_t cc; + srsran_carrier_nr_t carrier = {}; + srsran_mib_nr_t mib; + srsran::phy_cfg_nr_t::ssb_cfg_t ssb = {}; + std::vector bwps; // idx0 for BWP-common + std::vector sibs; + asn1::copy_ptr dl_cfg_common; + asn1::copy_ptr ul_cfg_common; + srsran_duplex_config_nr_t duplex = {}; + const sched_args_t& sched_args; + const srsran::phy_cfg_nr_t default_ue_phy_cfg; + + cell_config_manager(uint32_t cc_, const sched_nr_cell_cfg_t& cell, const sched_args_t& sched_args_); + + uint32_t nof_prb() const { return carrier.nof_prb; } +}; - const bwp_cce_pos_list& get_dci_pos_list(uint32_t cc, uint32_t bwp_id, uint32_t search_space_id) const - { - return cc_params[cc].bwps[bwp_id].ss_list[search_space_id]->cce_positions; - } +/// Structure packing both the sched args and all gNB NR cell configurations +struct sched_params_t { + sched_args_t sched_cfg; + std::vector cells; - uint16_t rnti; - std::vector cc_params; + sched_params_t() = default; + explicit sched_params_t(const sched_args_t& sched_cfg_); }; +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } // namespace sched_nr_impl - } // namespace srsenb #endif // SRSRAN_SCHED_NR_CFG_H diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h b/srsgnb/hdr/stack/mac/sched_nr_grant_allocator.h similarity index 65% rename from srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h rename to srsgnb/hdr/stack/mac/sched_nr_grant_allocator.h index 91704bfcde..b7baf316b5 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h +++ b/srsgnb/hdr/stack/mac/sched_nr_grant_allocator.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,12 +22,13 @@ #ifndef SRSRAN_SCHED_NR_GRANT_ALLOCATOR_H #define SRSRAN_SCHED_NR_GRANT_ALLOCATOR_H -#include "../sched_common.h" #include "lib/include/srsran/adt/circular_array.h" #include "sched_nr_helpers.h" #include "sched_nr_interface.h" #include "sched_nr_pdcch.h" +#include "sched_nr_sch.h" #include "sched_nr_ue.h" +#include "srsenb/hdr/stack/mac/sched_common.h" namespace srsenb { namespace sched_nr_impl { @@ -37,9 +38,6 @@ using dl_sched_rar_info_t = sched_nr_interface::rar_info_t; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -const static size_t MAX_CORESET_PER_BWP = 3; -using slot_coreset_list = std::array, MAX_CORESET_PER_BWP>; - using pdsch_list_t = srsran::bounded_vector; using sched_rar_list_t = sched_nr_interface::sched_rar_list_t; using pucch_list_t = srsran::bounded_vector; @@ -56,25 +54,20 @@ struct bwp_slot_grid { uint32_t slot_idx = 0; const bwp_params_t* cfg = nullptr; - bwp_rb_bitmap dl_prbs; - bwp_rb_bitmap ul_prbs; - ssb_list ssb; - nzp_csi_rs_list nzp_csi_rs; - pdcch_dl_list_t dl_pdcchs; - pdcch_ul_list_t ul_pdcchs; - pdsch_list_t pdschs; - pucch_list_t pucch; - sched_rar_list_t rar; - slot_coreset_list coresets; - pusch_list_t puschs; - harq_ack_list_t pending_acks; + dl_sched_res_t dl; + ul_sched_t ul; + harq_ack_list_t pending_acks; + bwp_pdcch_allocator pdcchs; /// slot PDCCH resource allocator + pdsch_allocator pdschs; /// slot PDSCH resource allocator + pusch_allocator puschs; /// slot PUSCH resource allocator srsran::unique_pool_ptr rar_softbuffer; - bwp_slot_grid() = default; explicit bwp_slot_grid(const bwp_params_t& bwp_params, uint32_t slot_idx_); void reset(); + void reserve_pdsch(const prb_grant& grant) { pdschs.reserve_prbs(grant); } + bool is_dl() const { return cfg->slots[slot_idx].is_dl; } bool is_ul() const { return cfg->slots[slot_idx].is_ul; } }; @@ -103,39 +96,46 @@ struct bwp_res_grid { class bwp_slot_allocator { public: - explicit bwp_slot_allocator(bwp_res_grid& bwp_grid_); - - void new_slot(slot_point pdcch_slot_, slot_ue_map_t& ues_) - { - pdcch_slot = pdcch_slot_; - slot_ues = &ues_; - } + explicit bwp_slot_allocator(bwp_res_grid& bwp_grid_, slot_point pdcch_slot_, slot_ue_map_t& ues_); - alloc_result alloc_si(uint32_t aggr_idx, uint32_t si_idx, uint32_t si_ntx, const prb_interval& prbs); + alloc_result alloc_si(uint32_t aggr_idx, + uint32_t si_idx, + uint32_t si_ntx, + const prb_interval& prbs, + tx_harq_softbuffer& softbuffer); alloc_result alloc_rar_and_msg3(uint16_t ra_rnti, uint32_t aggr_idx, prb_interval interv, srsran::const_span pending_rars); - alloc_result alloc_pdsch(slot_ue& ue, const prb_grant& dl_grant); - alloc_result alloc_pusch(slot_ue& ue, const prb_grant& dl_mask); + alloc_result alloc_pdsch(slot_ue& ue, uint32_t ss_id, const prb_grant& dl_grant); + alloc_result alloc_pusch(slot_ue& ue, const prb_grant& grant); - slot_point get_pdcch_tti() const { return pdcch_slot; } - slot_point get_tti_rx() const { return pdcch_slot - TX_ENB_DELAY; } - const bwp_res_grid& res_grid() const { return bwp_grid; } + slot_point get_pdcch_tti() const { return pdcch_slot; } + slot_point get_tti_rx() const { return pdcch_slot - TX_ENB_DELAY; } + const bwp_res_grid& res_grid() const { return bwp_grid; } + const bwp_slot_grid& tx_slot_grid() const { return bwp_grid[pdcch_slot]; } + bwp_slot_grid& tx_slot_grid() { return bwp_grid[pdcch_slot]; } - const bwp_params_t& cfg; + prb_bitmap occupied_dl_prbs(slot_point sl_tx, uint32_t ss_id, srsran_dci_format_nr_t dci_fmt) const + { + return bwp_grid[sl_tx].pdschs.occupied_prbs(ss_id, dci_fmt); + } + const prb_bitmap& occupied_ul_prbs(slot_point sl_tx) const { return bwp_grid[sl_tx].puschs.occupied_prbs(); } + + srslog::basic_logger& logger; + const bwp_params_t& cfg; private: - alloc_result verify_pdsch_space(bwp_slot_grid& pdsch_grid, bwp_slot_grid& pdcch_grid) const; - alloc_result verify_pusch_space(bwp_slot_grid& pusch_grid, bwp_slot_grid* pdcch_grid = nullptr) const; + alloc_result verify_uci_space(const bwp_slot_grid& uci_grid) const; - srslog::basic_logger& logger; - bwp_res_grid& bwp_grid; + bwp_res_grid& bwp_grid; slot_point pdcch_slot; - slot_ue_map_t* slot_ues = nullptr; + slot_ue_map_t& slot_ues; }; +prb_grant find_optimal_dl_grant(bwp_slot_allocator& slot_alloc, const slot_ue& ue, uint32_t ss_id); + } // namespace sched_nr_impl } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_harq.h b/srsgnb/hdr/stack/mac/sched_nr_harq.h similarity index 87% rename from srsenb/hdr/stack/mac/nr/sched_nr_harq.h rename to srsgnb/hdr/stack/mac/sched_nr_harq.h index 8123799711..5eb2c40c89 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_harq.h +++ b/srsgnb/hdr/stack/mac/sched_nr_harq.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,7 +23,7 @@ #define SRSRAN_SCHED_NR_HARQ_H #include "sched_nr_cfg.h" -#include "srsenb/hdr/stack/mac/nr/harq_softbuffer.h" +#include "srsgnb/hdr/stack/mac/harq_softbuffer.h" #include "srsran/common/slot_point.h" #include @@ -57,8 +57,6 @@ class harq_proc bool clear_if_maxretx(slot_point slot_rx); void reset(); - bool new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, uint32_t max_retx); - bool new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant); bool new_retx(slot_point slot_tx, slot_point slot_ack); // NOTE: Has to be used before first tx is dispatched @@ -67,7 +65,10 @@ class harq_proc const uint32_t pid; -private: +protected: + bool new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, uint32_t max_retx); + bool new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant); + struct tb_t { bool active = false; bool ack_state = false; @@ -92,9 +93,18 @@ class dl_harq_proc : public harq_proc tx_harq_softbuffer& get_softbuffer() { return *softbuffer; } srsran::unique_byte_buffer_t* get_tx_pdu() { return &pdu; } - bool new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, uint32_t max_retx); + bool new_tx(slot_point slot_tx, + slot_point slot_ack, + const prb_grant& grant, + uint32_t mcs, + uint32_t max_retx, + srsran_dci_dl_nr_t& dci); + + bool new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, srsran_dci_dl_nr_t& dci); private: + void fill_dci(srsran_dci_dl_nr_t& dci); + srsran::unique_pool_ptr softbuffer; srsran::unique_byte_buffer_t pdu; }; @@ -106,6 +116,10 @@ class ul_harq_proc : public harq_proc harq_proc(id_), softbuffer(harq_softbuffer_pool::get_instance().get_rx(nprb)) {} + bool new_tx(slot_point slot_tx, const prb_grant& grant, uint32_t mcs, uint32_t max_retx, srsran_dci_ul_nr_t& dci); + + bool new_retx(slot_point slot_tx, const prb_grant& grant, srsran_dci_ul_nr_t& dci); + rx_harq_softbuffer& get_softbuffer() { return *softbuffer; } bool set_tbs(uint32_t tbs) @@ -115,6 +129,8 @@ class ul_harq_proc : public harq_proc } private: + void fill_dci(srsran_dci_ul_nr_t& dci); + srsran::unique_pool_ptr softbuffer; }; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_helpers.h b/srsgnb/hdr/stack/mac/sched_nr_helpers.h similarity index 58% rename from srsenb/hdr/stack/mac/nr/sched_nr_helpers.h rename to srsgnb/hdr/stack/mac/sched_nr_helpers.h index 5f2274b890..7f4c0177c3 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_helpers.h +++ b/srsgnb/hdr/stack/mac/sched_nr_helpers.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,6 +24,7 @@ #include "sched_nr_cfg.h" #include "sched_nr_ue.h" +#include "srsran/adt/optional_array.h" namespace srsenb { namespace sched_nr_impl { @@ -32,25 +33,29 @@ class slot_ue; class ul_harq_proc; struct bwp_res_grid; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -bool fill_dci_rar(prb_interval interv, uint16_t ra_rnti, const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci); - -bool fill_dci_msg3(const slot_ue& ue, const bwp_params_t& bwp_cfg, srsran_dci_ul_nr_t& dci); - -/// Generate PDCCH DL DCI fields -void fill_dl_dci_ue_fields(const slot_ue& ue, - const bwp_params_t& bwp_cfg, - uint32_t ss_id, - srsran_dci_location_t dci_pos, - srsran_dci_dl_nr_t& dci); - -/// Generate PDCCH UL DCI fields -void fill_ul_dci_ue_fields(const slot_ue& ue, - const bwp_params_t& bwp_cfg, - uint32_t ss_id, - srsran_dci_location_t dci_pos, - srsran_dci_ul_nr_t& dci); +/// Helper function to verify if RNTI type can be placed in specified search space +/// Based on 38.213, Section 10.1 +inline bool is_rnti_type_valid_in_search_space(srsran_rnti_type_t rnti_type, srsran_search_space_type_t ss_type) +{ + switch (ss_type) { + case srsran_search_space_type_common_0: // fall-through + case srsran_search_space_type_common_0A: // Other SIBs + return rnti_type == srsran_rnti_type_si; + case srsran_search_space_type_common_1: + return rnti_type == srsran_rnti_type_ra or rnti_type == srsran_rnti_type_tc or + /* in case of Pcell -> */ rnti_type == srsran_rnti_type_c; + case srsran_search_space_type_common_2: + return rnti_type == srsran_rnti_type_p; + case srsran_search_space_type_common_3: + return rnti_type == srsran_rnti_type_c; // TODO: Fix + case srsran_search_space_type_ue: + return rnti_type == srsran_rnti_type_c or rnti_type == srsran_rnti_type_cs or + rnti_type == srsran_rnti_type_sp_csi; + default: + break; + } + return false; +} /// Log UE state for slot being scheduled void log_sched_slot_ues(srslog::basic_logger& logger, diff --git a/srsgnb/hdr/stack/mac/sched_nr_interface.h b/srsgnb/hdr/stack/mac/sched_nr_interface.h new file mode 100644 index 0000000000..c81f880328 --- /dev/null +++ b/srsgnb/hdr/stack/mac/sched_nr_interface.h @@ -0,0 +1,198 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_SCHED_NR_INTERFACE_H +#define SRSRAN_SCHED_NR_INTERFACE_H + +#include "srsenb/hdr/stack/mac/common/sched_config.h" +#include "srsran/adt/bounded_vector.h" +#include "srsran/adt/optional.h" +#include "srsran/adt/span.h" +#include "srsran/asn1/rrc_nr.h" +#include "srsran/common/common_nr.h" +#include "srsran/common/phy_cfg_nr.h" +#include "srsran/common/slot_point.h" +#include "srsran/interfaces/gnb_interfaces.h" +#include "srsran/phy/phch/dci_nr.h" + +namespace srsenb { + +const static size_t SCHED_NR_MAX_CARRIERS = 4; +const static uint16_t SCHED_NR_INVALID_RNTI = 0; +const static size_t SCHED_NR_MAX_NOF_RBGS = 18; +const static size_t SCHED_NR_MAX_TB = 1; +const static size_t SCHED_NR_MAX_HARQ = SRSRAN_DEFAULT_HARQ_PROC_DL_NR; +const static size_t SCHED_NR_MAX_BWP_PER_CELL = 2; +const static size_t SCHED_NR_MAX_LCID = srsran::MAX_NR_NOF_BEARERS; +const static size_t SCHED_NR_MAX_LC_GROUP = 7; + +struct sched_nr_ue_cc_cfg_t { + bool active = false; + uint32_t cc = 0; +}; + +struct sched_nr_ue_lc_ch_cfg_t { + uint32_t lcid; // 1..32 + mac_lc_ch_cfg_t cfg; +}; + +struct sched_nr_ue_cfg_t { + uint32_t maxharq_tx = 4; + srsran::bounded_vector carriers; + srsran::phy_cfg_nr_t phy_cfg = {}; + asn1::copy_ptr mac_cell_group_cfg; + asn1::copy_ptr phy_cell_group_cfg; + asn1::copy_ptr sp_cell_cfg; + std::vector lc_ch_to_add; + std::vector lc_ch_to_rem; +}; + +struct sched_nr_bwp_cfg_t { + uint32_t start_rb = 0; + uint32_t rb_width = 100; + srsran_pdcch_cfg_nr_t pdcch = {}; + srsran_sch_hl_cfg_nr_t pdsch = {}; + srsran_sch_hl_cfg_nr_t pusch = {}; + srsran_pucch_nr_hl_cfg_t pucch = {}; + srsran_harq_ack_cfg_hl_t harq_ack = {}; + uint32_t rar_window_size = 10; // See TS 38.331, ra-ResponseWindow: {1, 2, 4, 8, 10, 20, 40, 80} + uint32_t numerology_idx = 0; +}; + +struct sched_nr_cell_cfg_sib_t { + uint32_t len; + uint32_t period_rf; + uint32_t si_window_slots; +}; + +struct sched_nr_cell_cfg_t { + static const size_t MAX_SIBS = 2; + using ssb_positions_in_burst_t = asn1::rrc_nr::serving_cell_cfg_common_sib_s::ssb_positions_in_burst_s_; + + uint32_t nof_layers; + uint32_t pci; + uint32_t ssb_offset; + uint32_t dl_cell_nof_prb; + uint32_t ul_cell_nof_prb; + asn1::rrc_nr::dl_cfg_common_sib_s dl_cfg_common; + asn1::rrc_nr::ul_cfg_common_sib_s ul_cfg_common; + srsran::optional tdd_ul_dl_cfg_common; + ssb_positions_in_burst_t ssb_positions_in_burst; + uint32_t ssb_periodicity_ms = 0; + asn1::rrc_nr::mib_s::dmrs_type_a_position_e_ dmrs_type_a_position; + asn1::rrc_nr::subcarrier_spacing_e ssb_scs; + asn1::rrc_nr::pdcch_cfg_sib1_s pdcch_cfg_sib1; + int ss_pbch_block_power = 0; + // Extras + std::vector bwps{1}; // idx0 for BWP-common + std::vector sibs; + double dl_center_frequency_hz; + double ul_center_frequency_hz; + double ssb_center_freq_hz; +}; + +class sched_nr_interface +{ +public: + static const size_t MAX_GRANTS = mac_interface_phy_nr::MAX_GRANTS; + static const size_t MAX_SUBPDUS = 8; + + ///// Configuration ///// + struct sched_args_t { + bool pdsch_enabled = true; + bool pusch_enabled = true; + bool auto_refill_buffer = false; + int fixed_dl_mcs = 28; + int fixed_ul_mcs = 28; + std::string logger_name = "MAC-NR"; + }; + + using ue_cc_cfg_t = sched_nr_ue_cc_cfg_t; + using ue_cfg_t = sched_nr_ue_cfg_t; + + ////// RA signalling ////// + + struct rar_info_t { + uint32_t msg3_size = 7; + uint32_t cc; + uint16_t temp_crnti; + slot_point prach_slot; + uint32_t ofdm_symbol_idx; + uint32_t freq_idx; + uint32_t preamble_idx; + uint32_t ta_cmd; + }; + struct msg3_grant_t { + rar_info_t data; + srsran_dci_ul_nr_t msg3_dci = {}; + }; + struct rar_t { + srsran::bounded_vector grants; + }; + + ////// DL data signalling ////// + + struct dl_pdu_t { + srsran::bounded_vector subpdus; + }; + + ///// Sched Result ///// + + using dl_sched_t = mac_interface_phy_nr::dl_sched_t; + using ul_res_t = mac_interface_phy_nr::ul_sched_t; + + using sched_sib_list_t = srsran::bounded_vector; /// list of SI indexes + using sched_rar_list_t = srsran::bounded_vector; + using sched_dl_pdu_list_t = srsran::bounded_vector; + struct dl_res_t { + dl_sched_t phy; + sched_dl_pdu_list_t data; + sched_rar_list_t rar; + sched_sib_list_t sib_idxs; + }; + + virtual ~sched_nr_interface() = default; + virtual int config(const sched_args_t& sched_cfg, srsran::const_span ue_cfg) = 0; + virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; + virtual void ue_rem(uint16_t rnti) = 0; + + virtual void slot_indication(slot_point slot_tx) = 0; + virtual dl_res_t* get_dl_sched(slot_point slot_rx, uint32_t cc) = 0; + virtual ul_res_t* get_ul_sched(slot_point slot_rx, uint32_t cc) = 0; + + virtual void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) = 0; + virtual void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) = 0; + virtual void ul_sr_info(uint16_t rnti) = 0; + virtual void ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) = 0; + + /** + * Enqueue MAC CEs for DL transmission + * + * @param rnti user rnti + * @param ce_lcid lcid of the MAC CE + * @return error code + */ + virtual void dl_mac_ce(uint16_t rnti, uint32_t ce_lcid) = 0; +}; + +} // namespace srsenb + +#endif // SRSRAN_SCHED_NR_INTERFACE_H diff --git a/srsgnb/hdr/stack/mac/sched_nr_interface_utils.h b/srsgnb/hdr/stack/mac/sched_nr_interface_utils.h new file mode 100644 index 0000000000..8cdf162169 --- /dev/null +++ b/srsgnb/hdr/stack/mac/sched_nr_interface_utils.h @@ -0,0 +1,79 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_SCHED_NR_INTERFACE_HELPERS_H +#define SRSRAN_SCHED_NR_INTERFACE_HELPERS_H + +#include "sched_nr_interface.h" +#include "srsran/adt/optional_array.h" + +namespace srsenb { + +//////////////////////////////////// Search Space Helpers //////////////////////////////////////////// + +/// Get a range of active search spaces in a PDCCH configuration +inline srsran::split_optional_span view_active_search_spaces(srsran_pdcch_cfg_nr_t& pdcch) +{ + return srsran::split_optional_span{pdcch.search_space, pdcch.search_space_present}; +} +inline srsran::split_optional_span +view_active_search_spaces(const srsran_pdcch_cfg_nr_t& pdcch) +{ + return srsran::split_optional_span{pdcch.search_space, pdcch.search_space_present}; +} + +inline bool contains_dci_format(const srsran_search_space_t& ss, srsran_dci_format_nr_t dci_fmt) +{ + auto is_dci_fmt = [dci_fmt](const srsran_dci_format_nr_t& f) { return f == dci_fmt; }; + return std::any_of(&ss.formats[0], &ss.formats[ss.nof_formats], is_dci_fmt); +} + +//////////////////////////////////// CORESET Helpers //////////////////////////////////////////// + +/// Get a range of active coresets in a PDCCH configuration +inline srsran::split_optional_span view_active_coresets(srsran_pdcch_cfg_nr_t& pdcch) +{ + return srsran::split_optional_span{pdcch.coreset, pdcch.coreset_present}; +} +inline srsran::split_optional_span view_active_coresets(const srsran_pdcch_cfg_nr_t& pdcch) +{ + return srsran::split_optional_span{pdcch.coreset, pdcch.coreset_present}; +} + +/// Get number of CCEs available in CORESET for PDCCH +uint32_t coreset_nof_cces(const srsran_coreset_t& coreset); + +//////////////////////////////////// Sched Output Helpers //////////////////////////////////////////// + +inline bool operator==(srsran_dci_location_t lhs, srsran_dci_location_t rhs) +{ + return lhs.ncce == rhs.ncce and lhs.L == rhs.L; +} + +//////////////////////////////////// UE configuration Helpers //////////////////////////////////////////// + +void make_mib_cfg(const sched_nr_cell_cfg_t& cfg, srsran_mib_nr_t* mib); +void make_ssb_cfg(const sched_nr_cell_cfg_t& cfg, srsran::phy_cfg_nr_t::ssb_cfg_t* ssb); +srsran::phy_cfg_nr_t get_common_ue_phy_cfg(const sched_nr_cell_cfg_t& cfg); + +} // namespace srsenb + +#endif // SRSRAN_SCHED_NR_INTERFACE_HELPERS_H diff --git a/srsgnb/hdr/stack/mac/sched_nr_pdcch.h b/srsgnb/hdr/stack/mac/sched_nr_pdcch.h new file mode 100644 index 0000000000..0d29394624 --- /dev/null +++ b/srsgnb/hdr/stack/mac/sched_nr_pdcch.h @@ -0,0 +1,216 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_SCHED_NR_PDCCH_H +#define SRSRAN_SCHED_NR_PDCCH_H + +#include "srsenb/hdr/stack/mac/sched_common.h" +#include "srsgnb/hdr/stack/mac/sched_nr_cfg.h" +#include "srsgnb/hdr/stack/mac/sched_ue/ue_cfg_manager.h" +#include "srsran/adt/bounded_bitset.h" +#include "srsran/adt/bounded_vector.h" +#include "srsran/phy/common/phy_common_nr.h" +#include "srsran/phy/phch/dci.h" + +namespace srsenb { + +namespace sched_nr_impl { + +/// Helper function to fill DCI with BWP params +void fill_dci_from_cfg(const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci); +void fill_dci_from_cfg(const bwp_params_t& bwp_cfg, srsran_dci_ul_nr_t& dci); + +using coreset_bitmap = srsran::bounded_bitset; + +class coreset_region +{ +public: + coreset_region(const bwp_params_t& bwp_cfg_, uint32_t coreset_id_, uint32_t slot_idx); + void reset(); + + bool alloc_pdcch(srsran_rnti_type_t rnti_type, + bool is_dl, + uint32_t aggr_idx, + uint32_t search_space_id, + const ue_carrier_params_t* user, + srsran_dci_ctx_t& dci); + + void rem_last_pdcch(); + + uint32_t get_td_symbols() const { return coreset_cfg->duration; } + uint32_t get_freq_resources() const { return nof_freq_res; } + uint32_t nof_cces() const { return nof_freq_res * get_td_symbols(); } + size_t nof_allocs() const { return dfs_tree.size(); } + + void print_allocations(fmt::memory_buffer& fmtbuf) const; + +private: + const srsran_coreset_t* coreset_cfg; + uint32_t coreset_id; + uint32_t slot_idx; + uint32_t nof_freq_res = 0; + + const bwp_cce_pos_list& rar_cce_list; + const srsran::optional_vector& common_cce_list; + + // List of PDCCH grants + struct alloc_record { + uint32_t aggr_idx; + uint32_t ss_id; + srsran_dci_ctx_t* dci; + bool is_dl; + const ue_carrier_params_t* ue; + }; + srsran::bounded_vector dci_list; + + // DFS decision tree of PDCCH grants + struct tree_node { + uint16_t rnti = SRSRAN_INVALID_RNTI; + uint32_t record_idx = 0; + uint32_t dci_pos_idx = 0; + srsran_dci_location_t dci_pos = {0, 0}; + /// Accumulation of all PDCCH masks for the current solution (DFS path) + coreset_bitmap total_mask, current_mask; + }; + using alloc_tree_dfs_t = std::vector; + alloc_tree_dfs_t dfs_tree, saved_dfs_tree; + + srsran::span get_cce_loc_table(const alloc_record& record) const; + bool alloc_dfs_node(const alloc_record& record, uint32_t dci_idx); + bool get_next_dfs(); +}; + +using pdcch_dl_alloc_result = srsran::expected; +using pdcch_ul_alloc_result = srsran::expected; + +/** + * Class to handle the allocation of REs for a BWP PDCCH in a specific slot + */ +class bwp_pdcch_allocator +{ +public: + bwp_pdcch_allocator(const bwp_params_t& bwp_cfg_, + uint32_t slot_idx, + pdcch_dl_list_t& pdcch_dl_list, + pdcch_ul_list_t& pdcch_ul_list); + + /** + * Clear current slot allocations + */ + void reset(); + + /** + * Allocates RE space for RAR DCI in PDCCH, avoiding in the process collisions with other PDCCH allocations + * Fills DCI context with RAR PDCCH allocation information + * @param ra_rnti RA-RNTI of RAR allocation + * @param aggr_idx Aggregation level index (0..4) + * @return PDCCH object with dci context filled if the allocation was successful. nullptr otherwise + */ + pdcch_dl_alloc_result alloc_rar_pdcch(uint16_t ra_rnti, uint32_t aggr_idx); + + /** + * Allocates RE space for SI DCI in PDCCH, avoiding in the process collisions with other PDCCH allocations + * Fills DCI context with SI PDCCH allocation information + * @param ss_id Search space ID + * @param aggr_idx Aggregation level index (0..4) + * @return PDCCH object with dci context filled if the allocation was successful. nullptr otherwise + */ + pdcch_dl_alloc_result alloc_si_pdcch(uint32_t ss_id, uint32_t aggr_idx); + + /** + * Allocates RE space for UE DL DCI in PDCCH, avoiding in the process collisions with other PDCCH allocations + * Fills DCI context with PDCCH allocation information + * @param rnti_type type of UE RNTI (e.g. C, TC) + * @param ss_id Search space ID + * @param aggr_idx Aggregation level index (0..4) + * @param user UE object parameters + * @return PDCCH object with dci context filled if the allocation was successful. nullptr otherwise + */ + pdcch_dl_alloc_result + alloc_dl_pdcch(srsran_rnti_type_t rnti_type, uint32_t ss_id, uint32_t aggr_idx, const ue_carrier_params_t& user); + + /** + * @brief Allocates RE space for UL DCI in PDCCH, avoiding in the process collisions with other PDCCH allocations + * Fills DCI context with PDCCH allocation information + * @param ss_id Search space ID + * @param aggr_idx Aggregation level index (0..4) + * @param user UE object parameters + * @return PDCCH object with dci context filled if the allocation was successful. nullptr otherwise + */ + pdcch_ul_alloc_result alloc_ul_pdcch(uint32_t ss_id, uint32_t aggr_idx, const ue_carrier_params_t& user); + + /** + * Cancel and remove last PDCCH allocation. It should only be called once after each alloc_dl_pdcch/alloc_ul_pdcch + */ + void cancel_last_pdcch(); + + /// Returns the number of PDCCH allocations made in the slot + uint32_t nof_allocations() const; + + /// Number of CCEs in given coreset + uint32_t nof_cces(uint32_t coreset_id) const; + + void print_allocations(fmt::memory_buffer& fmtbuf) const; + std::string print_allocations() const; + +private: + using slot_coreset_list = srsran::optional_array; + + pdcch_dl_alloc_result alloc_dl_pdcch_common(srsran_rnti_type_t rnti_type, + uint16_t rnti, + uint32_t ss_id, + uint32_t aggr_idx, + srsran_dci_format_nr_t dci_fmt, + const ue_carrier_params_t* user = nullptr); + + /// Helper function to verify valid inputs + alloc_result check_args_valid(srsran_rnti_type_t rnti_type, + uint16_t rnti, + uint32_t ss_id, + uint32_t aggr_idx, + srsran_dci_format_nr_t dci_fmt, + const ue_carrier_params_t* user, + bool is_dl) const; + + /// Fill DCI context of allocated PDCCH + void fill_dci_ctx_common(srsran_dci_ctx_t& dci, + srsran_rnti_type_t rnti_type, + uint16_t rnti, + const srsran_search_space_t& ss, + srsran_dci_format_nr_t dci_fmt, + const ue_carrier_params_t* ue); + + // args + const bwp_params_t& bwp_cfg; + srslog::basic_logger& logger; + const uint32_t slot_idx; + + pdcch_dl_list_t& pdcch_dl_list; + pdcch_ul_list_t& pdcch_ul_list; + slot_coreset_list coresets; + const srsran_dci_ctx_t* pending_dci = nullptr; /// Saves last PDCCH allocation, in case it needs to be aborted +}; + +} // namespace sched_nr_impl + +} // namespace srsenb + +#endif // SRSRAN_SCHED_NR_PDCCH_H diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_rb.h b/srsgnb/hdr/stack/mac/sched_nr_rb.h similarity index 90% rename from srsenb/hdr/stack/mac/nr/sched_nr_rb.h rename to srsgnb/hdr/stack/mac/sched_nr_rb.h index 1374fde3d0..15e634cefe 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_rb.h +++ b/srsgnb/hdr/stack/mac/sched_nr_rb.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,7 +22,7 @@ #ifndef SRSRAN_SCHED_NR_RB_H #define SRSRAN_SCHED_NR_RB_H -#include "srsenb/hdr/stack/mac/nr/sched_nr_interface.h" +#include "srsgnb/hdr/stack/mac/sched_nr_interface.h" #include "srsran/adt/bounded_bitset.h" #include "srsran/phy/common/phy_common_nr.h" @@ -115,6 +115,16 @@ struct prb_grant { return alloc.interv; } + prb_grant& operator&=(const prb_interval interv) + { + if (is_alloc_type0()) { + alloc.rbgs &= rbg_bitmap{alloc.rbgs.size()}.fill(interv.start(), interv.stop()); + } else { + alloc.interv.intersect(interv); + } + return *this; + } + private: bool alloc_type_0 = false; union alloc_t { @@ -197,6 +207,23 @@ struct bwp_rb_bitmap { uint32_t prb_to_rbg_idx(uint32_t prb_idx) const; + bwp_rb_bitmap& operator|=(const bwp_rb_bitmap& other) + { + prbs_ |= other.prbs_; + rbgs_ |= other.rbgs_; + return *this; + } + bwp_rb_bitmap& operator|=(const rbg_bitmap& other) + { + add(other); + return *this; + } + bwp_rb_bitmap& operator|=(const prb_bitmap& other) + { + add(other); + return *this; + } + private: prb_bitmap prbs_; rbg_bitmap rbgs_; @@ -209,6 +236,12 @@ struct bwp_rb_bitmap { void add_rbgs_to_prbs(const rbg_bitmap& grant); }; +template +bwp_rb_bitmap operator|(const bwp_rb_bitmap& lhs, const Other& rhs) +{ + return bwp_rb_bitmap(lhs) |= rhs; +} + inline prb_interval find_next_empty_interval(const prb_bitmap& mask, size_t start_prb_idx = 0, size_t last_prb_idx = SRSRAN_MAX_PRB_NR) { diff --git a/srsgnb/hdr/stack/mac/sched_nr_sch.h b/srsgnb/hdr/stack/mac/sched_nr_sch.h new file mode 100644 index 0000000000..bc66a11e79 --- /dev/null +++ b/srsgnb/hdr/stack/mac/sched_nr_sch.h @@ -0,0 +1,193 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_SCHED_NR_SCH_H +#define SRSRAN_SCHED_NR_SCH_H + +#include "srsenb/hdr/stack/mac/sched_common.h" +#include "srsgnb/hdr/stack/mac/sched_nr_cfg.h" +#include "srsgnb/hdr/stack/mac/sched_ue/ue_cfg_manager.h" + +namespace srsenb { + +namespace sched_nr_impl { + +using pdsch_alloc_result = srsran::expected; + +class pdsch_allocator +{ +public: + pdsch_allocator(const bwp_params_t& cfg_, uint32_t sl_index, pdsch_list_t& pdsch_lst); + + /// Get available RBGs for allocation + rbg_bitmap occupied_rbgs() const + { + // Note: in case, RBGs are used, dci format is not 1_0 + return dl_prbs.rbgs(); + } + /// Get available PRBs for allocation + prb_bitmap occupied_prbs(uint32_t ss_id, srsran_dci_format_nr_t dci_fmt) const + { + if (dci_fmt == srsran_dci_format_nr_1_0) { + const srsran_search_space_t* ss = bwp_cfg.get_ss(ss_id); + if (ss != nullptr and SRSRAN_SEARCH_SPACE_IS_COMMON(ss->type)) { + return (dl_prbs | bwp_cfg.dci_fmt_1_0_excluded_prbs(ss->coreset_id)).prbs(); + } + } + return dl_prbs.prbs(); + } + + /// Marks a range of PRBS as occupied, preventing further allocations + void reserve_prbs(const prb_grant& grant) { dl_prbs |= grant; } + + /// Verifies if the input arguments are valid for an SI allocation and grant doesnt collide with other grants + alloc_result is_si_grant_valid(uint32_t ss_id, const prb_grant& grant) const; + + /// Verifies if the input arguments are valid for an RAR allocation and grant doesnt collide with other grants + alloc_result is_rar_grant_valid(const prb_grant& grant) const; + + /// Verifies if the input arguments are valid for an UE allocation and grant doesnt collide with other grants + alloc_result is_ue_grant_valid(const ue_carrier_params_t& ue, + uint32_t ss_id, + srsran_dci_format_nr_t dci_fmt, + const prb_grant& grant) const; + + /** + * @brief Tries to allocate UE PDSCH grant. Ensures that there are no collisions with other previous PDSCH allocations + * @param ss_id[in] SearchSpaceId used for allocation + * @param dci_fmt[in] Chosen DL DCI format + * @param grant[in] PRBs used for the grant + * @param ue[in] UE carrier parameters + * @param dci[out] DCI where frequency_assignment and time_assignment get stored. + * @return pdsch_t* of allocated PDSCH in case of success. alloc_result error code in case of failure + */ + pdsch_alloc_result alloc_ue_pdsch(uint32_t ss_id, + srsran_dci_format_nr_t dci_fmt, + const prb_grant& grant, + const ue_carrier_params_t& ue, + srsran_dci_dl_nr_t& dci); + + /// Similar to alloc_ue_pdsch, but it doesn't verify if input parameters are valid + pdsch_t& alloc_ue_pdsch_unchecked(uint32_t ss_id, + srsran_dci_format_nr_t dci_fmt, + const prb_grant& grant, + const ue_carrier_params_t& ue, + srsran_dci_dl_nr_t& dci); + + /** + * @brief Tries to allocate SI PDSCH grant. Ensures that there are no collisions with other previous PDSCH allocations + * @param ss_id[in] SearchSpaceId used for allocation + * @param grant[in] PRBs used for the grant + * @param dci[out] DCI where frequency_assignment and time_assignment get stored. + * @return pdsch_t* of allocated PDSCH in case of success. alloc_result error code in case of failure + */ + pdsch_alloc_result alloc_si_pdsch(uint32_t ss_id, const prb_grant& grant, srsran_dci_dl_nr_t& dci); + /// Similar to alloc_si_pdsch, but it doesn't verify if input parameters are valid + pdsch_t& alloc_si_pdsch_unchecked(uint32_t ss_id, const prb_grant& grant, srsran_dci_dl_nr_t& dci); + + /** + * @brief Tries to allocate RAR PDSCH grant. Ensures that there are no collisions with other previous PDSCH + * allocations + * @param grant[in] PRBs used for the grant + * @param dci[out] DCI where frequency_assignment and time_assignment get stored. + * @return pdsch_t* of allocated PDSCH in case of success. alloc_result error code in case of failure + */ + pdsch_alloc_result alloc_rar_pdsch(const prb_grant& grant, srsran_dci_dl_nr_t& dci); + /// Similar to alloc_rar_pdsch, but it doesn't verify if input parameters are valid + pdsch_t& alloc_rar_pdsch_unchecked(const prb_grant& grant, srsran_dci_dl_nr_t& dci); + + /// Cancel last PDSCH allocation + void cancel_last_pdsch(); + + /// Clear all PDSCHs + void reset(); + +private: + alloc_result is_grant_valid_common(srsran_search_space_type_t ss_type, + srsran_dci_format_nr_t dci_fmt, + uint32_t coreset_id, + const prb_grant& grant) const; + pdsch_t& alloc_pdsch_unchecked(uint32_t coreset_id, + srsran_search_space_type_t ss_type, + srsran_dci_format_nr_t dci_fmt, + const prb_grant& grant, + srsran_dci_dl_nr_t& dci); + + const bwp_params_t& bwp_cfg; + uint32_t slot_idx = 0; + + pdsch_list_t& pdschs; + bwp_rb_bitmap dl_prbs; +}; + +using pusch_alloc_result = srsran::expected; + +class pusch_allocator +{ +public: + pusch_allocator(const bwp_params_t& cfg_, uint32_t sl_index, pusch_list_t& pusch_lst); + + /// Get available RBGs for allocation + const rbg_bitmap& occupied_rbgs() const { return ul_prbs.rbgs(); } + /// Get available PRBs for allocation + const prb_bitmap& occupied_prbs() const { return ul_prbs.prbs(); } + + alloc_result has_grant_space(uint32_t nof_grants = 1, bool verbose = true) const; + + /// Checks if provided PDSCH arguments produce a valid PDSCH that fits into cell PRBs and does not collide with other + /// allocations + alloc_result is_grant_valid(srsran_search_space_type_t ss_type, const prb_grant& grant, bool verbose = true) const; + + /** + * @brief Tries to allocate PDSCH grant. Ensures that there are no collisions with other previous PDSCH allocations + * @param ss_type[in] PDCCH chosen search space type + * @param grant[in] PRBs used for the grant + * @param pdcch[out] DCI where frequency_assignment and time_assignment get stored. + * @return pdsch_t object pointer in case of success. alloc_result error code in case of failure + */ + pusch_alloc_result + alloc_pusch(const srsran_search_space_type_t ss_type, const prb_grant& grant, srsran_dci_ul_nr_t& dci); + + /** + * @brief Allocates PDSCH grant without verifying for collisions. Useful to avoid redundant is_grant_valid(...) calls + * @param dci_ctx[in] PDCCH DL DCI context information + * @param grant[in] PRBs used for the grant + * @param pdcch[out] DCI where frequency and time assignment get stored. + */ + pusch_t& alloc_pusch_unchecked(const prb_grant& grant, srsran_dci_ul_nr_t& dci); + + void cancel_last_pusch(); + + void reset(); + +private: + const bwp_params_t& bwp_cfg; + uint32_t slot_idx = 0; + + pusch_list_t& puschs; + bwp_rb_bitmap ul_prbs; +}; + +} // namespace sched_nr_impl + +} // namespace srsenb + +#endif // SRSRAN_SCHED_NR_SCH_H diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_signalling.h b/srsgnb/hdr/stack/mac/sched_nr_signalling.h similarity index 52% rename from srsenb/hdr/stack/mac/nr/sched_nr_signalling.h rename to srsgnb/hdr/stack/mac/sched_nr_signalling.h index c6b392f8cd..5cccfa37a1 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_signalling.h +++ b/srsgnb/hdr/stack/mac/sched_nr_signalling.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,12 +22,16 @@ #ifndef SRSRAN_SCHED_NR_SIGNALLING_H #define SRSRAN_SCHED_NR_SIGNALLING_H +#include "harq_softbuffer.h" #include "sched_nr_cfg.h" #include "sched_nr_interface.h" +#include "srsenb/hdr/stack/mac/sched_common.h" namespace srsenb { namespace sched_nr_impl { +class bwp_slot_allocator; + /// Schedule NZP-CSI-RS resources for given slot void sched_nzp_csi_rs(srsran::const_span nzp_csi_rs_sets, const srsran_slot_cfg_t& slot_cfg, @@ -41,20 +45,52 @@ void sched_nzp_csi_rs(srsran::const_span nzp_csi_rs_set * * @param[in] sl_point Slot point carrying information about current slot. * @param[in] ssb_periodicity Periodicity of SSB in ms. - * @param[out] ssb_list List of SSB messages to be sent to PHY. + * @param[in] mib MIB message content + * @param[out] ssb_list List of SSB messages to be sent to PHY. * * @remark This function a is basic scheduling function that uses the following simplified assumption: * 1) Subcarrier spacing: 15kHz * 2) Frequency below 3GHz * 3) Position in Burst is 1000, i.e., Only the first SSB of the 4 opportunities gets scheduled */ -void sched_ssb_basic(const slot_point& sl_point, uint32_t ssb_periodicity, ssb_list& ssb_list); +void sched_ssb_basic(const slot_point& sl_point, + uint32_t ssb_periodicity, + const srsran_mib_nr_t& mib, + ssb_list& ssb_list); + +/// Fill DCI fields with SIB info +bool fill_dci_sib(prb_interval interv, uint32_t sib_idx, const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci); /// For a given BWP and slot, schedule SSB, NZP CSI RS and SIBs -void sched_dl_signalling(const bwp_params_t& bwp_params, - slot_point sl_pdcch, - ssb_list& ssb_list, - nzp_csi_rs_list& nzp_csi_rs); +void sched_dl_signalling(bwp_slot_allocator& bwp_alloc); + +/// scheduler for SIBs +class si_sched +{ +public: + explicit si_sched(const bwp_params_t& bwp_cfg_); + + void run_slot(bwp_slot_allocator& slot_alloc); + +private: + const bwp_params_t* bwp_cfg = nullptr; + srslog::basic_logger& logger; + + struct si_msg_ctxt_t { + // args + uint32_t n = 0; /// 0 for SIB1, n/index in schedulingInfoList in si-SchedulingInfo in SIB1 + uint32_t len_bytes = 0; /// length in bytes of SIB1 / SI message + uint32_t win_len_slots = 0; /// window length in slots + uint32_t period_frames = 0; /// periodicity of SIB1/SI window in frames + + // state + uint32_t n_tx = 0; /// nof transmissions of the same SIB1 / SI message + alloc_result result = alloc_result::invalid_coderate; /// last attempt to schedule SI + slot_point win_start; /// start of SI window, invalid if outside + srsran::unique_pool_ptr si_softbuffer; + }; + srsran::bounded_vector pending_sis; /// configured SIB1 and SI messages +}; } // namespace sched_nr_impl } // namespace srsenb diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_time_rr.h b/srsgnb/hdr/stack/mac/sched_nr_time_rr.h similarity index 96% rename from srsenb/hdr/stack/mac/nr/sched_nr_time_rr.h rename to srsgnb/hdr/stack/mac/sched_nr_time_rr.h index 1744f3d57a..888414a927 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_time_rr.h +++ b/srsgnb/hdr/stack/mac/sched_nr_time_rr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsgnb/hdr/stack/mac/sched_nr_ue.h b/srsgnb/hdr/stack/mac/sched_nr_ue.h new file mode 100644 index 0000000000..55338cd082 --- /dev/null +++ b/srsgnb/hdr/stack/mac/sched_nr_ue.h @@ -0,0 +1,229 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_SCHED_NR_UE_H +#define SRSRAN_SCHED_NR_UE_H + +#include "sched_nr_cfg.h" +#include "sched_nr_harq.h" +#include "sched_nr_interface.h" +#include "sched_ue/ue_cfg_manager.h" +#include "srsenb/hdr/stack/mac/common/base_ue_buffer_manager.h" +#include "srsenb/hdr/stack/mac/common/mac_metrics.h" +#include "srsran/adt/circular_map.h" +#include "srsran/adt/move_callback.h" +#include "srsran/adt/pool/cached_alloc.h" +#include "srsran/adt/pool/pool_interface.h" + +namespace srsenb { + +namespace sched_nr_impl { + +class ue_buffer_manager : public base_ue_buffer_manager +{ + using base_type = base_ue_buffer_manager; + +public: + // Inherited methods from base_ue_buffer_manager base class + using base_type::base_type; + using base_type::config_lcid; + using base_type::dl_buffer_state; + using base_type::get_bsr; + using base_type::get_bsr_state; + using base_type::get_dl_prio_tx; + using base_type::get_dl_tx; + using base_type::get_dl_tx_total; + using base_type::is_bearer_active; + using base_type::is_bearer_dl; + using base_type::is_bearer_ul; + using base_type::is_lcg_active; + using base_type::ul_bsr; + + int get_dl_tx_total() const; + + // Control Element Command queue + struct ce_t { + uint32_t lcid; + uint32_t cc; + }; + srsran::deque pending_ces; + + /// Protected, thread-safe interface of "ue_buffer_manager" for "slot_ue" + struct pdu_builder { + pdu_builder() = default; + explicit pdu_builder(uint32_t cc_, ue_buffer_manager& parent_) : cc(cc_), parent(&parent_) {} + bool alloc_subpdus(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu); + uint32_t pending_bytes(uint32_t lcid) const { return parent->get_dl_tx(lcid); } + + private: + uint32_t cc = SRSRAN_MAX_CARRIERS; + ue_buffer_manager* parent = nullptr; + }; +}; + +/// Class containing context of UE that is common to all carriers +struct ue_context_common { + uint32_t pending_dl_bytes = 0; + uint32_t pending_ul_bytes = 0; +}; + +class slot_ue; + +class ue_carrier +{ +public: + ue_carrier(uint16_t rnti, + const ue_cfg_manager& cfg, + const cell_config_manager& cell_params_, + const ue_context_common& ctxt, + const ue_buffer_manager::pdu_builder& pdu_builder_); + + void set_cfg(const ue_cfg_manager& ue_cfg); + const ue_carrier_params_t& cfg() const { return bwp_cfg; } + + int dl_ack_info(uint32_t pid, uint32_t tb_idx, bool ack); + int ul_crc_info(uint32_t pid, bool crc); + + const uint16_t rnti; + const uint32_t cc; + const cell_config_manager& cell_params; + + // Channel state + uint32_t dl_cqi = 1; + uint32_t ul_cqi = 0; + + harq_entity harq_ent; + + ue_buffer_manager::pdu_builder pdu_builder; + + // metrics + mac_ue_metrics_t metrics = {}; + + // common context + const ue_context_common& common_ctxt; + +private: + friend class slot_ue; + + srslog::basic_logger& logger; + ue_carrier_params_t bwp_cfg; +}; + +class ue +{ +public: + ue(uint16_t rnti, uint32_t cc, const sched_params_t& sched_cfg_); + ue(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg, const sched_params_t& sched_cfg_); + + void new_slot(slot_point pdcch_slot); + + slot_ue make_slot_ue(slot_point pdcch_slot, uint32_t cc); + + /// Update UE CC configuration + void set_cfg(const sched_nr_ue_cfg_t& cfg); + const ue_cfg_manager& cfg() const { return ue_cfg; } + + void add_dl_mac_ce(uint32_t ce_lcid, uint32_t nof_cmds = 1); + void rlc_buffer_state(uint32_t lcid, uint32_t newtx, uint32_t retx); + + /// UE state feedback + void ul_bsr(uint32_t lcg, uint32_t bsr_val) { buffers.ul_bsr(lcg, bsr_val); } + void ul_sr_info() { last_sr_slot = last_tx_slot - TX_ENB_DELAY; } + + bool has_ca() const + { + return ue_cfg.carriers.size() > 1 and std::count_if(ue_cfg.carriers.begin() + 1, + ue_cfg.carriers.end(), + [](const ue_cc_cfg_t& cc) { return cc.active; }) > 0; + } + uint32_t pcell_cc() const { return ue_cfg.carriers[0].cc; } + + std::array, SCHED_NR_MAX_CARRIERS> carriers; + + const uint16_t rnti; + +private: + const sched_params_t& sched_cfg; + + ue_cfg_manager ue_cfg; + + slot_point last_tx_slot; + slot_point last_sr_slot; + ue_context_common common_ctxt; + + ue_buffer_manager buffers; +}; + +class slot_ue +{ +public: + slot_ue() = default; + explicit slot_ue(ue_carrier& ue, slot_point slot_tx_); + slot_ue(slot_ue&&) noexcept = default; + slot_ue& operator=(slot_ue&&) noexcept = default; + bool empty() const { return ue == nullptr; } + void release() { ue = nullptr; } + + const ue_carrier_params_t& cfg() const { return ue->bwp_cfg; } + const ue_carrier_params_t* operator->() const { return &ue->bwp_cfg; } + + /// Find available HARQs + dl_harq_proc* find_empty_dl_harq() { return ue->harq_ent.find_empty_dl_harq(); } + ul_harq_proc* find_empty_ul_harq() { return ue->harq_ent.find_empty_ul_harq(); } + + /// Build PDU with MAC CEs and MAC SDUs + bool build_pdu(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu, bool reset_buf_states = false) + { + return ue->pdu_builder.alloc_subpdus(rem_bytes, pdu); + } + + bool get_pending_bytes(uint32_t lcid) const { return ue->pdu_builder.pending_bytes(lcid); } + + /// Channel Information Getters + uint32_t dl_cqi() const { return ue->dl_cqi; } + uint32_t ul_cqi() const { return ue->ul_cqi; } + + // UE parameters common to all sectors + uint32_t dl_bytes = 0, ul_bytes = 0; + + // UE parameters that are sector specific + bool dl_active; + bool ul_active; + slot_point pdcch_slot; + slot_point pdsch_slot; + slot_point pusch_slot; + slot_point uci_slot; + dl_harq_proc* h_dl = nullptr; + ul_harq_proc* h_ul = nullptr; + +private: + ue_carrier* ue = nullptr; +}; + +using unique_ue_ptr = srsran::unique_pool_ptr; +using ue_map_t = rnti_map_t; +using slot_ue_map_t = rnti_map_t; + +} // namespace sched_nr_impl + +} // namespace srsenb + +#endif // SRSRAN_SCHED_NR_UE_H diff --git a/srsgnb/hdr/stack/mac/sched_nr_worker.h b/srsgnb/hdr/stack/mac/sched_nr_worker.h new file mode 100644 index 0000000000..dceae993e5 --- /dev/null +++ b/srsgnb/hdr/stack/mac/sched_nr_worker.h @@ -0,0 +1,73 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_SCHED_NR_WORKER_H +#define SRSRAN_SCHED_NR_WORKER_H + +#include "sched_nr_bwp.h" +#include "sched_nr_cfg.h" +#include "sched_nr_grant_allocator.h" +#include "sched_nr_ue.h" +#include "srsran/adt/circular_array.h" +#include "srsran/adt/optional.h" +#include "srsran/adt/pool/cached_alloc.h" +#include "srsran/adt/span.h" +#include +#include + +namespace srsenb { + +struct mac_metrics_t; + +namespace sched_nr_impl { + +class cc_worker +{ +public: + explicit cc_worker(const cell_config_manager& params); + + void dl_rach_info(const sched_nr_interface::rar_info_t& rar_info); + + dl_sched_res_t* run_slot(slot_point pdcch_slot, ue_map_t& ue_db_); + ul_sched_t* get_ul_sched(slot_point sl); + + // const params + const cell_config_manager& cfg; + srslog::basic_logger& logger; + + // cc-specific resources + srsran::bounded_vector bwps; + +private: + void alloc_dl_ues(bwp_slot_allocator& bwp_alloc); + void alloc_ul_ues(bwp_slot_allocator& bwp_alloc); + void postprocess_decisions(bwp_slot_allocator& bwp_alloc); + + // {slot,cc} specific variables + slot_ue_map_t slot_ues; + + slot_point last_tx_sl; +}; + +} // namespace sched_nr_impl +} // namespace srsenb + +#endif // SRSRAN_SCHED_NR_WORKER_H diff --git a/srsgnb/hdr/stack/mac/sched_ue/ue_cfg_manager.h b/srsgnb/hdr/stack/mac/sched_ue/ue_cfg_manager.h new file mode 100644 index 0000000000..6f9129979b --- /dev/null +++ b/srsgnb/hdr/stack/mac/sched_ue/ue_cfg_manager.h @@ -0,0 +1,107 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_UE_CFG_MANAGER_H +#define SRSRAN_UE_CFG_MANAGER_H + +#include "../sched_nr_cfg.h" + +namespace srsenb { +namespace sched_nr_impl { + +using ue_cc_cfg_list = srsran::bounded_vector; + +struct ue_cfg_manager { + uint32_t maxharq_tx = 4; + ue_cc_cfg_list carriers; + std::array ue_bearers = {}; + srsran::phy_cfg_nr_t phy_cfg = {}; + + explicit ue_cfg_manager(uint32_t enb_cc_idx = 0); + explicit ue_cfg_manager(const sched_nr_ue_cfg_t& cfg_req); + int apply_config_request(const sched_nr_ue_cfg_t& cfg_req); +}; + +/// Semi-static configuration of a UE for a given CC. +class ue_carrier_params_t +{ +public: + ue_carrier_params_t() = default; + explicit ue_carrier_params_t(uint16_t rnti, const bwp_params_t& active_bwp_cfg, const ue_cfg_manager& uecfg_); + + uint16_t rnti = SRSRAN_INVALID_RNTI; + uint32_t cc = SRSRAN_MAX_CARRIERS; + + const ue_cfg_manager& ue_cfg() const { return *cfg_; } + const srsran::phy_cfg_nr_t& phy() const { return cfg_->phy_cfg; } + const bwp_params_t& active_bwp() const { return *bwp_cfg; } + + /// Get SearchSpace based on SearchSpaceId + const srsran_search_space_t* get_ss(uint32_t ss_id) const + { + if (phy().pdcch.search_space_present[ss_id]) { + // UE-dedicated SearchSpace + return &bwp_cfg->cfg.pdcch.search_space[ss_id]; + } + return nullptr; + } + + srsran::const_span cce_pos_list(uint32_t search_id, uint32_t slot_idx, uint32_t aggr_idx) const + { + if (cce_positions_list.size() > ss_id_to_cce_idx[search_id]) { + auto& lst = cce_pos_list(search_id); + return lst[slot_idx][aggr_idx]; + } + return srsran::const_span{}; + } + const bwp_cce_pos_list& cce_pos_list(uint32_t search_id) const + { + return cce_positions_list[ss_id_to_cce_idx[search_id]]; + } + + uint32_t get_k1(slot_point pdsch_slot) const + { + if (phy().duplex.mode == SRSRAN_DUPLEX_MODE_TDD) { + return phy().harq_ack.dl_data_to_ul_ack[pdsch_slot.to_uint() % phy().duplex.tdd.pattern1.period_ms]; + } + return phy().harq_ack.dl_data_to_ul_ack[pdsch_slot.to_uint() % phy().harq_ack.nof_dl_data_to_ul_ack]; + } + int fixed_pdsch_mcs() const { return bwp_cfg->sched_cfg.fixed_dl_mcs; } + int fixed_pusch_mcs() const { return bwp_cfg->sched_cfg.fixed_ul_mcs; } + + const srsran_dci_cfg_nr_t& get_dci_cfg() const { return cached_dci_cfg; } + + int find_ss_id(srsran_dci_format_nr_t dci_fmt) const; + +private: + const ue_cfg_manager* cfg_ = nullptr; + const bwp_params_t* bwp_cfg = nullptr; + + // derived + std::vector cce_positions_list; + std::array ss_id_to_cce_idx; + srsran_dci_cfg_nr_t cached_dci_cfg; +}; + +} // namespace sched_nr_impl +} // namespace srsenb + +#endif // SRSRAN_UE_CFG_MANAGER_H diff --git a/srsenb/hdr/stack/mac/nr/ue_nr.h b/srsgnb/hdr/stack/mac/ue_nr.h similarity index 90% rename from srsenb/hdr/stack/mac/nr/ue_nr.h rename to srsgnb/hdr/stack/mac/ue_nr.h index fc90d6e5d5..0481818d40 100644 --- a/srsenb/hdr/stack/mac/nr/ue_nr.h +++ b/srsgnb/hdr/stack/mac/ue_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,7 +23,7 @@ #define SRSENB_UE_NR_H #include "srsenb/hdr/stack/mac/common/mac_metrics.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_interface.h" +#include "srsgnb/hdr/stack/mac/sched_nr_interface.h" #include "srsran/common/block_queue.h" #include "srsran/common/interfaces_common.h" #include "srsran/interfaces/enb_rlc_interfaces.h" @@ -51,15 +51,15 @@ class ue_nr : public srsran::read_pdu_interface virtual ~ue_nr(); void reset(); - void ue_cfg(const sched_interface::ue_cfg_t& ue_cfg); + void ue_cfg(const sched_nr_interface::ue_cfg_t& ue_cfg); void set_tti(uint32_t tti); uint16_t get_rnti() const { return rnti; } void set_active(bool active) { active_state.store(active, std::memory_order_relaxed); } bool is_active() const { return active_state.load(std::memory_order_relaxed); } + void store_msg3(srsran::unique_byte_buffer_t pdu); - int generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size); - int process_pdu(srsran::unique_byte_buffer_t pdu); + int generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size, srsran::const_span subpdu_lcids); std::mutex metrics_mutex = {}; void metrics_read(mac_ue_metrics_t* metrics_); @@ -78,10 +78,6 @@ class ue_nr : public srsran::read_pdu_interface uint32_t read_pdu(uint32_t lcid, uint8_t* payload, uint32_t requested_bytes) final; private: - // helper methods - uint32_t buff_size_field_to_bytes(uint32_t buff_size_index, const srsran::bsr_format_nr_t& format); - int process_ce_subpdu(srsran::mac_sch_subpdu_nr& subpdu); - rlc_interface_mac* rlc = nullptr; rrc_interface_mac_nr* rrc = nullptr; phy_interface_stack_nr* phy = nullptr; @@ -112,6 +108,8 @@ class ue_nr : public srsran::read_pdu_interface ue_rx_pdu_queue; ///< currently only DCH PDUs supported (add BCH, PCH, etc) srsran::unique_byte_buffer_t ue_rlc_buffer; + srsran::unique_byte_buffer_t last_msg3; ///< holds UE ID received in Msg3 for ConRes CE + static constexpr int32_t MIN_RLC_PDU_LEN = 5; ///< minimum bytes that need to be available in a MAC PDU for attempting to add another RLC SDU diff --git a/srsenb/hdr/stack/ngap/ngap.h b/srsgnb/hdr/stack/ngap/ngap.h similarity index 64% rename from srsenb/hdr/stack/ngap/ngap.h rename to srsgnb/hdr/stack/ngap/ngap.h index 72c816bcf2..ffffa3224f 100644 --- a/srsenb/hdr/stack/ngap/ngap.h +++ b/srsgnb/hdr/stack/ngap/ngap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -31,20 +31,21 @@ #include "srsran/common/buffer_pool.h" #include "srsran/common/common.h" #include "srsran/common/network_utils.h" +#include "srsran/common/ngap_pcap.h" #include "srsran/common/stack_procedure.h" #include "srsran/common/standard_streams.h" #include "srsran/common/task_scheduler.h" #include "srsran/common/threads.h" +#include "srsran/interfaces/enb_gtpu_interfaces.h" #include "srsran/interfaces/gnb_ngap_interfaces.h" #include "srsran/interfaces/gnb_rrc_nr_interfaces.h" -#include "srsran/interfaces/enb_gtpu_interfaces.h" #include "srsran/srslog/srslog.h" #include #include namespace srsenb { -class ngap : public ngap_interface_rrc_nr +class ngap final : public ngap_interface_rrc_nr { public: class ue; @@ -56,25 +57,28 @@ class ngap : public ngap_interface_rrc_nr void stop(); // RRC NR interface - void initial_ue(uint16_t rnti, - uint32_t gnb_cc_idx, - asn1::ngap_nr::rrcestablishment_cause_e cause, - srsran::unique_byte_buffer_t pdu); - void initial_ue(uint16_t rnti, - uint32_t gnb_cc_idx, - asn1::ngap_nr::rrcestablishment_cause_e cause, - srsran::unique_byte_buffer_t pdu, - uint32_t s_tmsi); - - void write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu); - bool user_exists(uint16_t rnti) { return true; }; - void user_mod(uint16_t old_rnti, uint16_t new_rnti){}; - bool user_release(uint16_t rnti, asn1::ngap_nr::cause_radio_network_e cause_radio) { return true; }; - bool is_amf_connected(); - bool send_error_indication(const asn1::ngap_nr::cause_c& cause, - srsran::optional ran_ue_ngap_id = {}, - srsran::optional amf_ue_ngap_id = {}); - void ue_notify_rrc_reconf_complete(uint16_t rnti, bool outcome); + void initial_ue(uint16_t rnti, + uint32_t gnb_cc_idx, + asn1::ngap::rrcestablishment_cause_e cause, + srsran::const_byte_span pdu) override; + void initial_ue(uint16_t rnti, + uint32_t gnb_cc_idx, + asn1::ngap::rrcestablishment_cause_e cause, + srsran::const_byte_span pdu, + uint32_t s_tmsi) override; + + void write_pdu(uint16_t rnti, srsran::const_byte_span pdu) override; + bool user_exists(uint16_t rnti) override { return true; }; + void user_mod(uint16_t old_rnti, uint16_t new_rnti) override {} + + // TS 38.413 - Section 8.3.2 - UE Context Release Request + void user_release_request(uint16_t rnti, asn1::ngap::cause_radio_network_e cause_radio) override; + + bool is_amf_connected() override; + bool send_error_indication(const asn1::ngap::cause_c& cause, + srsran::optional ran_ue_ngap_id = {}, + srsran::optional amf_ue_ngap_id = {}); + void ue_notify_rrc_reconf_complete(uint16_t rnti, bool outcome) override; bool send_pdu_session_resource_setup_response(); // Stack interface @@ -83,6 +87,13 @@ class ngap : public ngap_interface_rrc_nr void get_metrics(ngap_metrics_t& m); void get_args(ngap_args_t& args_); + // PCAP + void start_pcap(srsran::ngap_pcap* pcap_); + + // Logging + typedef enum { Rx = 0, Tx } direction_t; + void log_ngap_message(const asn1::ngap::ngap_pdu_c& msg, const direction_t dir, srsran::const_byte_span pdu); + private: static const int AMF_PORT = 38412; static const int ADDR_FAMILY = AF_INET; @@ -107,35 +118,41 @@ class ngap : public ngap_interface_rrc_nr uint32_t next_gnb_ue_ngap_id = 1; // Next GNB-side UE identifier uint16_t next_ue_stream_id = 1; // Next UE SCTP stream identifier srsran::unique_timer amf_connect_timer, ngsetup_timeout; + std::vector nssai_allowed_list; // Protocol IEs sent with every UL NGAP message - asn1::ngap_nr::tai_s tai; - asn1::ngap_nr::nr_cgi_s nr_cgi; + asn1::ngap::tai_s tai; + asn1::ngap::nr_cgi_s nr_cgi; - asn1::ngap_nr::ng_setup_resp_s ngsetupresponse; + asn1::ngap::ng_setup_resp_s ngsetupresponse; int build_tai_cgi(); bool connect_amf(); bool setup_ng(); - bool sctp_send_ngap_pdu(const asn1::ngap_nr::ngap_pdu_c& tx_pdu, uint32_t rnti, const char* procedure_name); + bool sctp_send_ngap_pdu(const asn1::ngap::ngap_pdu_c& tx_pdu, uint32_t rnti, const char* procedure_name); bool handle_ngap_rx_pdu(srsran::byte_buffer_t* pdu); - bool handle_successful_outcome(const asn1::ngap_nr::successful_outcome_s& msg); - bool handle_unsuccessful_outcome(const asn1::ngap_nr::unsuccessful_outcome_s& msg); - bool handle_initiating_message(const asn1::ngap_nr::init_msg_s& msg); + bool handle_successful_outcome(const asn1::ngap::successful_outcome_s& msg); + bool handle_unsuccessful_outcome(const asn1::ngap::unsuccessful_outcome_s& msg); + bool handle_initiating_message(const asn1::ngap::init_msg_s& msg); // TS 38.413 - Section 8.6.2 - Downlink NAS Transport - bool handle_dl_nas_transport(const asn1::ngap_nr::dl_nas_transport_s& msg); + bool handle_dl_nas_transport(const asn1::ngap::dl_nas_transport_s& msg); // TS 38.413 - Section 9.2.6.2 - NG Setup Response - bool handle_ng_setup_response(const asn1::ngap_nr::ng_setup_resp_s& msg); + bool handle_ng_setup_response(const asn1::ngap::ng_setup_resp_s& msg); // TS 38.413 - Section 9.2.6.3 - NG Setup Failure - bool handle_ng_setup_failure(const asn1::ngap_nr::ng_setup_fail_s& msg); + bool handle_ng_setup_failure(const asn1::ngap::ng_setup_fail_s& msg); // TS 38.413 - Section 9.2.2.5 - UE Context Release Command - bool handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cmd_s& msg); + bool handle_ue_context_release_cmd(const asn1::ngap::ue_context_release_cmd_s& msg); // TS 38.413 - Section 9.2.2.1 - Initial Context Setup Request - bool handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg); + bool handle_initial_ctxt_setup_request(const asn1::ngap::init_context_setup_request_s& msg); // TS 38.413 - Section 9.2.1.1 - PDU Session Resource Setup Request - bool handle_ue_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg); + bool handle_ue_pdu_session_res_setup_request(const asn1::ngap::pdu_session_res_setup_request_s& msg); + // TS 38.413 - Section 9.2.4.1 - Paging + bool handle_paging(const asn1::ngap::paging_s& msg); + + // PCAP + srsran::ngap_pcap* pcap = nullptr; class user_list { @@ -147,7 +164,7 @@ class ngap : public ngap_interface_rrc_nr ue* find_ue_rnti(uint16_t rnti); ue* find_ue_gnbid(uint32_t gnbid); - ue* find_ue_amfid(uint32_t amfid); + ue* find_ue_amfid(uint64_t amfid); ue* add_user(value_type user); void erase(ue* ue_ptr); iterator begin() { return users.begin(); } @@ -183,12 +200,12 @@ class ngap : public ngap_interface_rrc_nr ngap* ngap_ptr = nullptr; }; - ue* handle_ngapmsg_ue_id(uint32_t gnb_id, uint32_t amf_id); + ue* handle_ngapmsg_ue_id(uint32_t gnb_id, uint64_t amf_id); srsran::proc_t ngsetup_proc; - std::string get_cause(const asn1::ngap_nr::cause_c& c); - void log_ngap_msg(const asn1::ngap_nr::ngap_pdu_c& msg, srsran::const_span sdu, bool is_rx); + std::string get_cause(const asn1::ngap::cause_c& c); + void log_ngap_msg(const asn1::ngap::ngap_pdu_c& msg, srsran::const_span sdu, bool is_rx); }; } // namespace srsenb diff --git a/srsenb/hdr/stack/ngap/ngap_interfaces.h b/srsgnb/hdr/stack/ngap/ngap_interfaces.h similarity index 96% rename from srsenb/hdr/stack/ngap/ngap_interfaces.h rename to srsgnb/hdr/stack/ngap/ngap_interfaces.h index f4180017d9..aff7e88840 100644 --- a/srsenb/hdr/stack/ngap/ngap_interfaces.h +++ b/srsgnb/hdr/stack/ngap/ngap_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/ngap/ngap_metrics.h b/srsgnb/hdr/stack/ngap/ngap_metrics.h similarity index 95% rename from srsenb/hdr/stack/ngap/ngap_metrics.h rename to srsgnb/hdr/stack/ngap/ngap_metrics.h index 8e0b4e55c8..2f16111b49 100644 --- a/srsenb/hdr/stack/ngap/ngap_metrics.h +++ b/srsgnb/hdr/stack/ngap/ngap_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsenb/hdr/stack/ngap/ngap_ue.h b/srsgnb/hdr/stack/ngap/ngap_ue.h similarity index 77% rename from srsenb/hdr/stack/ngap/ngap_ue.h rename to srsgnb/hdr/stack/ngap/ngap_ue.h index f4d11ed76e..05f566e6ca 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue.h +++ b/srsgnb/hdr/stack/ngap/ngap_ue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -39,16 +39,16 @@ class ngap::ue : public ngap_interface_ngap_proc srslog::basic_logger& logger_); virtual ~ue(); // TS 38.413 - Section 9.2.5.1 - Initial UE Message - bool send_initial_ue_message(asn1::ngap_nr::rrcestablishment_cause_e cause, - srsran::unique_byte_buffer_t pdu, - bool has_tmsi, - uint32_t s_tmsi = 0); + bool send_initial_ue_message(asn1::ngap::rrcestablishment_cause_e cause, + srsran::const_byte_span pdu, + bool has_tmsi, + uint32_t s_tmsi = 0); // TS 38.413 - Section 9.2.5.3 - Uplink NAS Transport - bool send_ul_nas_transport(srsran::unique_byte_buffer_t pdu); + bool send_ul_nas_transport(srsran::const_byte_span pdu); // TS 38.413 - Section 9.2.2.2 - Initial Context Setup Response bool send_initial_ctxt_setup_response(); // TS 38.413 - Section 9.2.2.3 - Initial Context Setup Failure - bool send_initial_ctxt_setup_failure(asn1::ngap_nr::cause_c cause); + bool send_initial_ctxt_setup_failure(asn1::ngap::cause_c cause); // TS 38.413 - Section 9.2.1.2 - PDU Session Resource Setup Response bool send_pdu_session_resource_setup_response(uint16_t pdu_session_id, uint32_t teid_in, @@ -56,13 +56,16 @@ class ngap::ue : public ngap_interface_ngap_proc // TS 38.413 - Section 9.2.1.2 - UE Context Release Complete bool send_ue_ctxt_release_complete(); // TS 38.413 - Section 9.2.2.1 - Initial Context Setup Request - bool handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg); + bool handle_initial_ctxt_setup_request(const asn1::ngap::init_context_setup_request_s& msg); + // TS 38.413 - Section 9.2.2.4 - UE Context Release Request + bool send_ue_context_release_request(asn1::ngap::cause_c cause); // TS 38.413 - Section 9.2.2.5 - UE Context Release Command - bool handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cmd_s& msg); + bool handle_ue_context_release_cmd(const asn1::ngap::ue_context_release_cmd_s& msg); // TS 38.413 - Section 9.2.1.1 - PDU Session Resource Setup Request - bool handle_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg); + bool handle_pdu_session_res_setup_request(const asn1::ngap::pdu_session_res_setup_request_s& msg); - bool was_uectxtrelease_requested() const { return release_requested; } + /// Checks if a UE Context Release Request was already sent + bool was_ue_context_release_requested() const { return release_requested; } void notify_rrc_reconf_complete(const bool reconf_complete_outcome); ngap_ue_ctxt_t ctxt = {}; @@ -86,4 +89,4 @@ class ngap::ue : public ngap_interface_ngap_proc }; } // namespace srsenb -#endif \ No newline at end of file +#endif diff --git a/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h b/srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h similarity index 63% rename from srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h rename to srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h index a7617ce74c..5b5c44ba72 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h +++ b/srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -44,10 +44,10 @@ class ngap_ue_bearer_manager asn1::bounded_bitstring<1, 160, true, true> address_out; asn1::bounded_bitstring<1, 160, true, true> address_in; }; - uint8_t id = 0; - uint8_t lcid = 0; - asn1::ngap_nr::qos_flow_level_qos_params_s qos_params; - std::vector tunnels; + uint8_t id = 0; + uint8_t lcid = 0; + asn1::ngap::qos_flow_level_qos_params_s qos_params; + std::vector tunnels; }; ngap_ue_bearer_manager(gtpu_interface_rrc* gtpu_, srslog::basic_logger& logger_); @@ -55,28 +55,32 @@ class ngap_ue_bearer_manager int add_pdu_session(uint16_t rnti, uint8_t pdu_session_id, - const asn1::ngap_nr::qos_flow_level_qos_params_s& qos, + const asn1::ngap::qos_flow_level_qos_params_s& qos, const asn1::bounded_bitstring<1, 160, true, true>& addr, uint32_t teid_out, uint16_t& lcid, asn1::bounded_bitstring<1, 160, true, true>& addr_in, uint32_t& teid_in, - asn1::ngap_nr::cause_c& cause); + asn1::ngap::cause_c& cause); int reset_pdu_sessions(uint16_t rnti); + using pdu_session_list_t = std::map; + const pdu_session_list_t& pdu_sessions() const { return pdu_session_list; } + private: - gtpu_interface_rrc* gtpu = nullptr; - std::map pdu_session_list; - srslog::basic_logger& logger; + gtpu_interface_rrc* gtpu = nullptr; + pdu_session_list_t pdu_session_list; + srslog::basic_logger& logger; - int add_gtpu_bearer(uint16_t rnti, - uint32_t pdu_session_id, - uint32_t teid_out, - asn1::bounded_bitstring<1, 160, true, true> address, - pdu_session_t::gtpu_tunnel& tunnel, // out parameter - const gtpu_interface_rrc::bearer_props* props = nullptr); - void rem_gtpu_bearer(uint16_t rnti, uint32_t pdu_session_id); + int add_gtpu_bearer(uint16_t rnti, + uint32_t pdu_session_id, + uint32_t teid_out, + asn1::bounded_bitstring<1, 160, true, true> address, + pdu_session_t::gtpu_tunnel& tunnel, // out parameter + const gtpu_interface_rrc::bearer_props* props = nullptr); + void rem_gtpu_bearer(uint16_t rnti, uint32_t pdu_session_id); + uint8_t allocate_lcid(uint32_t rnti); }; } // namespace srsenb -#endif // SRSENB_NGAP_UE_BEARER_MANAGER_H \ No newline at end of file +#endif // SRSENB_NGAP_UE_BEARER_MANAGER_H diff --git a/srsenb/hdr/stack/ngap/ngap_ue_proc.h b/srsgnb/hdr/stack/ngap/ngap_ue_proc.h similarity index 81% rename from srsenb/hdr/stack/ngap/ngap_ue_proc.h rename to srsgnb/hdr/stack/ngap/ngap_ue_proc.h index ff6308b269..bdc6af5e97 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue_proc.h +++ b/srsgnb/hdr/stack/ngap/ngap_ue_proc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -25,7 +25,7 @@ #include "ngap_interfaces.h" #include "ngap_ue_utils.h" -#include "srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h" +#include "srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h" #include "srsran/asn1/asn1_utils.h" #include "srsran/asn1/ngap.h" #include "srsran/common/buffer_pool.h" @@ -37,8 +37,33 @@ namespace srsenb { -// TS 38.413 - Section 8.3 - UE Context Management Procedures +/* + * TS 38.413 - Section 8.2 - PDU Session Management Procedures + */ +// TS 38.413 - Section 8.2.1 PDU Session Resource Setup +class ngap_ue_pdu_session_res_setup_proc +{ +public: + explicit ngap_ue_pdu_session_res_setup_proc(ngap_interface_ngap_proc* parent_, + rrc_interface_ngap_nr* rrc_, + ngap_ue_ctxt_t* ue_ctxt, + ngap_ue_bearer_manager* bearer_manager, + srslog::basic_logger& logger_); + srsran::proc_outcome_t init(const asn1::ngap::pdu_session_res_setup_request_s& msg); + srsran::proc_outcome_t step(); + static const char* name() { return "UE PDU Session Resource Setup"; } + +private: + ngap_ue_ctxt_t* ue_ctxt; + ngap_interface_ngap_proc* parent; + ngap_ue_bearer_manager* bearer_manager; + rrc_interface_ngap_nr* rrc = nullptr; + srslog::basic_logger& logger; +}; +/* + * TS 38.413 - Section 8.3 - UE Context Management Procedures + */ // TS 38.413 - Section 8.3.1 - Initial Context Setup class ngap_ue_initial_context_setup_proc { @@ -47,7 +72,7 @@ class ngap_ue_initial_context_setup_proc rrc_interface_ngap_nr* rrc_, ngap_ue_ctxt_t* ue_ctxt, srslog::basic_logger& logger_); - srsran::proc_outcome_t init(const asn1::ngap_nr::init_context_setup_request_s& msg); + srsran::proc_outcome_t init(const asn1::ngap::init_context_setup_request_s& msg); srsran::proc_outcome_t react(const bool rrc_reconf_outcome); srsran::proc_outcome_t step(); static const char* name() { return "Initial Context Setup"; } @@ -68,7 +93,7 @@ class ngap_ue_ue_context_release_proc ngap_ue_ctxt_t* ue_ctxt, ngap_ue_bearer_manager* bearer_manager, srslog::basic_logger& logger_); - srsran::proc_outcome_t init(const asn1::ngap_nr::ue_context_release_cmd_s& msg); + srsran::proc_outcome_t init(const asn1::ngap::ue_context_release_cmd_s& msg); srsran::proc_outcome_t step(); static const char* name() { return "UE Context Release"; } @@ -80,39 +105,6 @@ class ngap_ue_ue_context_release_proc srslog::basic_logger& logger; }; -// TS 38.413 - Section 8.3.4 - UE Context Modification -class ngap_ue_ue_context_modification_proc -{ -public: - explicit ngap_ue_ue_context_modification_proc(ngap_interface_ngap_proc* parent_, srslog::basic_logger& logger_); - srsran::proc_outcome_t init(); - srsran::proc_outcome_t step(); - static const char* name() { return "UE Context Modification"; } - -private: - ngap_interface_ngap_proc* parent; -}; - -class ngap_ue_pdu_session_res_setup_proc -{ -public: - explicit ngap_ue_pdu_session_res_setup_proc(ngap_interface_ngap_proc* parent_, - rrc_interface_ngap_nr* rrc_, - ngap_ue_ctxt_t* ue_ctxt, - ngap_ue_bearer_manager* bearer_manager, - srslog::basic_logger& logger_); - srsran::proc_outcome_t init(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg); - srsran::proc_outcome_t step(); - static const char* name() { return "UE PDU Session Resource Setup"; } - -private: - ngap_ue_ctxt_t* ue_ctxt; - ngap_interface_ngap_proc* parent; - ngap_ue_bearer_manager* bearer_manager; - rrc_interface_ngap_nr* rrc = nullptr; - srslog::basic_logger& logger; -}; - } // namespace srsenb -#endif \ No newline at end of file +#endif diff --git a/srsenb/hdr/stack/ngap/ngap_ue_utils.h b/srsgnb/hdr/stack/ngap/ngap_ue_utils.h similarity index 93% rename from srsenb/hdr/stack/ngap/ngap_ue_utils.h rename to srsgnb/hdr/stack/ngap/ngap_ue_utils.h index 2f657b53b6..f7aba0362d 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue_utils.h +++ b/srsgnb/hdr/stack/ngap/ngap_ue_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -33,7 +33,7 @@ struct ngap_ue_ctxt_t { uint16_t rnti = SRSRAN_INVALID_RNTI; uint32_t ran_ue_ngap_id = invalid_gnb_id; - srsran::optional amf_ue_ngap_id; + srsran::optional amf_ue_ngap_id; uint32_t gnb_cc_idx = 0; struct timeval init_timestamp = {}; diff --git a/srsgnb/hdr/stack/ric/e2_agent.h b/srsgnb/hdr/stack/ric/e2_agent.h new file mode 100644 index 0000000000..e76e1261a0 --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2_agent.h @@ -0,0 +1,142 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef E2_AGENT_H +#define E2_AGENT_H + +#include "srsgnb/hdr/stack/ric/e2ap.h" +#include "srsran/common/network_utils.h" +#include "srsran/common/stack_procedure.h" +#include "srsran/common/task_scheduler.h" +#include "srsran/common/threads.h" +#include "srsran/interfaces/e2_metrics_interface.h" +#include "srsran/srsran.h" + +static const int e2ap_ppid = 70; + +enum e2_msg_type_t { + E2_SETUP_REQUEST, + E2_SUB_RESPONSE, + E2_SUB_DEL_RESPONSE, + E2_INDICATION, + E2_RESET, + E2_RESET_RESPONSE +}; + +struct e2_agent_args_t { + bool enable; + std::string ric_ip; + uint32_t ric_port; + std::string ric_bind_ip; + uint32_t ric_bind_port; + int32_t max_ric_setup_retries; + uint32_t ric_connect_timer; +}; + +namespace srsenb { +class e2_agent : public srsran::thread +{ +public: + e2_agent(srslog::basic_logger& logger, srsenb::e2_interface_metrics* _gnb_metrics); + ~e2_agent() = default; + + // Initiate and Stop + bool init(e2_agent_args_t args); + void stop(); + void run_thread(); + void tic(); + bool is_ric_connected(); + + // Send messages to RIC + bool send_sctp(srsran::unique_byte_buffer_t& buf); + bool send_e2_msg(e2_msg_type_t msg_type); + bool queue_send_e2ap_pdu(e2_ap_pdu_c send_pdu); + bool send_e2ap_pdu(e2_ap_pdu_c send_pdu); + bool send_reset_response(); + + // Handle messages received from RIC + bool + handle_ric_rx_msg(srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags); + bool handle_e2_rx_pdu(srsran::byte_buffer_t* pdu); + bool handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg); + bool handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& successful_outcome); + bool handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome); + bool handle_e2_setup_response(e2setup_resp_s setup_response); + bool handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request); + bool handle_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request); + bool handle_subscription_modification_request(uint32_t ric_subscription_modification_request); + bool handle_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm); + bool handle_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse); + + bool handle_reset_response(reset_resp_s& reset_response); + bool handle_reset_request(reset_request_s& reset_request); + +private: + bool connect_ric(); + bool setup_e2(); + + e2_agent_args_t _args; + srsran::task_scheduler task_sched; + srsran::task_queue_handle ric_rece_task_queue; + srsran::unique_socket ric_socket; + srsran::socket_manager rx_sockets; + srslog::basic_logger& logger; + struct sockaddr_in ric_addr = {}; // RIC address + bool running = false; + bool ric_connected = false; + srsran::unique_timer ric_connect_timer; + srsran::unique_timer e2_setup_timeout; + + srsenb::e2_interface_metrics* gnb_metrics = nullptr; + e2ap e2ap_; + + // procedures + class e2_setup_proc_t + { + public: + struct e2setupresult { + bool success = false; + enum class cause_t { timeout, failure } cause; + }; + struct e2connectresult { + bool success = false; + }; + + explicit e2_setup_proc_t(e2_agent* e2_agent_) : e2_agent_ptr(e2_agent_) {} + srsran::proc_outcome_t init(); + srsran::proc_outcome_t step() { return srsran::proc_outcome_t::yield; } + srsran::proc_outcome_t react(const e2connectresult& event); + srsran::proc_outcome_t react(const e2setupresult& event); + void then(const srsran::proc_state_t& result); + const char* name() const { return "RIC Connection"; } + uint16_t connect_count = 0; + + private: + srsran::proc_outcome_t start_ric_connection(); + + e2_agent* e2_agent_ptr = nullptr; + }; + + srsran::proc_t e2_setup_proc; +}; +} // namespace srsenb + +#endif /* E2_AGENT_H */ diff --git a/srsgnb/hdr/stack/ric/e2ap.h b/srsgnb/hdr/stack/ric/e2ap.h new file mode 100644 index 0000000000..c2818070bb --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2ap.h @@ -0,0 +1,130 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "e2sm_kpm.h" +#include "srsran/asn1/e2ap.h" +#include "srsran/common/task_scheduler.h" +#include "srsran/common/timers.h" +#include "srsran/interfaces/e2_metrics_interface.h" +#include "srsran/interfaces/enb_metrics_interface.h" +#include "srsran/srsran.h" + +#ifndef RIC_E2AP_H +#define RIC_E2AP_H + +namespace srsenb { +using namespace asn1::e2ap; +using namespace asn1::e2sm_kpm; + +typedef struct { + uint16_t ric_id; + uint16_t plmn_id; +} global_ric_id_t; + +typedef struct { + e2node_component_interface_type_e interface_type; + std::string amf_name; + std::string request_part; + std::string response_part; +} e2_node_component_t; + +typedef struct { + uint32_t ric_requestor_id; + uint32_t ric_instance_id; + uint32_t ra_nfunction_id; + std::vector admitted_actions; + std::vector not_admitted_actions; +} ric_subscription_reponse_t; + +class e2_agent; + +class e2ap +{ +public: + e2ap(srslog::basic_logger& logger, + e2_agent* _e2_agent, + srsenb::e2_interface_metrics* _gnb_metrics, + srsran::task_scheduler* _task_sched_ptr); + ~e2ap(); + + e2_ap_pdu_c generate_setup_request(); + int process_setup_response(e2setup_resp_s setup_response); + int process_setup_failure(); + int process_subscription_request(ricsubscription_request_s ric_subscription_request); + int process_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request); + int process_subscription_modification_request(uint32_t ric_subscription_modification_request); + int process_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm); + int process_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse); + e2_ap_pdu_c generate_subscription_response(ric_subscription_reponse_t ric_subscription_reponse); + e2_ap_pdu_c generate_subscription_failure(ric_subscription_reponse_t ric_subscription_reponse); + e2_ap_pdu_c generate_subscription_delete_response(ric_subscription_reponse_t ric_subscription_reponse); + e2_ap_pdu_c generate_subscription_delete_failure(ric_subscription_reponse_t ric_subscription_reponse); + e2_ap_pdu_c generate_subscription_delete_required(ric_subscription_reponse_t ric_subscription_reponse); + e2_ap_pdu_c generate_subscription_modification_response(); + e2_ap_pdu_c generate_subscription_modification_failure(); + e2_ap_pdu_c generate_subscription_modification_required(); + + e2_ap_pdu_c generate_indication(ric_indication_t& ric_indication); + e2_ap_pdu_c generate_reset_request(); + e2_ap_pdu_c generate_reset_response(); + int process_reset_request(reset_request_s reset_request); + int process_reset_response(reset_resp_s reset_response); + + int process_e2_setup_failure(e2setup_fail_s e2setup_failure); + int process_ric_service_update_failure(ricservice_upd_fail_s ric_service_update_failure); + int process_e2_node_config_update_failure(e2node_cfg_upd_fail_s e2node_config_update_failure); + int process_e2_removal_failure(e2_removal_fail_s e2_remove_failure); + + bool queue_send_e2ap_pdu(e2_ap_pdu_c e2ap_pdu); + + int get_reset_id(); + bool get_func_desc(uint32_t ran_func_id, RANfunction_description& fdesc); + bool send_setup_request() { return !e2_established && pending_e2_setup; } + + class ric_subscription; + +private: + srslog::basic_logger& logger; + e2_agent* _e2_agent; + e2sm_kpm e2sm_; + bool e2_established = false; + srsran::unique_timer e2_procedure_timeout; + bool pending_e2_setup = true; + bool pending_e2_node_config_update = false; + bool pending_ric_service_update = false; + bool pending_e2_removal = false; + + int setup_procedure_transaction_id = 0; + uint64_t plmn_id = 0x05f510; + uint64_t gnb_id = 1; + global_ric_id_t global_ric_id = {}; + std::map ran_functions; + srsenb::e2_interface_metrics* gnb_metrics = nullptr; + srsran::task_scheduler* task_sched_ptr = nullptr; + bool reset_response_received = false; + int reset_transaction_id = 1; + cause_c reset_cause = cause_c(); + int reset_id = 1; + + std::vector > active_subscriptions; +}; +} // namespace srsenb +#endif /* RIC_E2AP_H */ diff --git a/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h b/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h new file mode 100644 index 0000000000..c3288326cd --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2ap_ric_subscription.h @@ -0,0 +1,73 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_E2AP_RIC_SUBSCRIPTION_H +#define SRSRAN_E2AP_RIC_SUBSCRIPTION_H + +#include "e2ap.h" +#include "srsran/common/task_scheduler.h" +#include "srsran/common/threads.h" +#include "srsran/srsran.h" + +namespace srsenb { + +class e2ap::ric_subscription +{ +public: + ric_subscription(e2ap* e2ap, ricsubscription_request_s ric_subscription_request); + virtual ~ric_subscription() { parent = nullptr; }; + + uint32_t get_ric_requestor_id() { return ric_requestor_id; }; + uint32_t get_ric_instance_id() { return ric_instance_id; }; + bool is_initialized() { return initialized; }; + + void start_subscription(); + void delete_subscription(); + + bool process_subscription_modification_request(uint32_t ric_subscription_modification_request); + bool process_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm); + bool process_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse); + +private: + void _send_subscription_response(); + void _send_subscription_failure(); + void _send_ric_indication(); + uint32_t _generate_ric_indication_sn(); + + e2ap* parent = nullptr; + bool initialized = false; + + uint32_t ric_requestor_id; + uint32_t ric_instance_id; + uint16_t ra_nfunction_id; + + e2sm* sm_ptr = nullptr; + uint32_t reporting_period = 0; // ms + srsran::unique_timer reporting_timer; // for RIC indication reporting + + std::vector admitted_actions; + std::vector not_admitted_actions; + + uint32_t _ric_indication_sn_gen = 0; +}; + +} // namespace srsenb +#endif // SRSRAN_E2AP_RIC_SUBSCRIPTION_H diff --git a/srsgnb/hdr/stack/ric/e2sm.h b/srsgnb/hdr/stack/ric/e2sm.h new file mode 100644 index 0000000000..225f18d0f4 --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2sm.h @@ -0,0 +1,115 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/asn1/e2ap.h" +#include "srsran/common/byte_buffer.h" +#include "srsran/common/task_scheduler.h" +#include "srsran/interfaces/enb_metrics_interface.h" +#include "srsran/srsran.h" + +#ifndef SRSRAN_E2SM_H +#define SRSRAN_E2SM_H + +using namespace asn1::e2ap; +using namespace srsenb; + +struct RANfunction_description; + +typedef struct { + enum e2sm_event_trigger_type_t { E2SM_REPORT, E2SM_INSERT, E2SM_POLICY, UNKNOWN_TRIGGER }; + e2sm_event_trigger_type_t type; + uint64_t report_period; +} RIC_event_trigger_definition_t; + +typedef struct { + uint16_t ric_action_id; + ri_caction_type_e ric_action_type; + uint32_t sm_local_ric_action_id; +} E2AP_RIC_action_t; + +typedef struct { + uint32_t ric_requestor_id; + uint32_t ric_instance_id; + uint32_t ra_nfunction_id; + uint32_t ri_caction_id; + bool ri_indication_sn_present; + uint32_t ri_indication_sn; + ri_cind_type_e indication_type; + srsran::unique_byte_buffer_t ri_cind_hdr; + srsran::unique_byte_buffer_t ri_cind_msg; +} ric_indication_t; + +class e2sm +{ +public: + e2sm(); + e2sm(std::string short_name, + std::string oid, + std::string func_description, + uint32_t revision, + srsran::task_scheduler* _task_sched_ptr) : + _short_name(short_name), + _oid(oid), + _func_description(func_description), + _revision(revision), + task_sched_ptr(_task_sched_ptr){}; + virtual ~e2sm() = default; + + std::string get_short_name() { return _short_name; }; + std::string get_oid() { return _oid; }; + std::string get_func_description() { return _func_description; }; + uint32_t get_revision() { return _revision; }; + + virtual bool generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func) = 0; + virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, + RIC_event_trigger_definition_t& event_def) = 0; + virtual bool process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, + E2AP_RIC_action_t& action_entry) = 0; + virtual bool remove_ric_action_definition(E2AP_RIC_action_t& action_entry) = 0; + virtual bool generate_ric_indication_content(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication) = 0; + + virtual void receive_e2_metrics_callback(const enb_metrics_t& m) = 0; + +protected: + uint32_t _get_local_action_id() { return _registered_action_id_gen; }; + uint32_t _generate_new_local_action_id() { return _registered_action_id_gen++; }; + + srsran::task_scheduler* task_sched_ptr = nullptr; + +private: + const std::string _short_name; + const std::string _oid; + const std::string _func_description; + const uint32_t _revision = 0; + + uint32_t _registered_action_id_gen = 1000; +}; + +struct RANfunction_description { + bool accepted = false; + int function_instance = 0; + e2sm* sm_ptr = nullptr; + std::string function_shortname; + std::string function_e2_sm_oid; + std::string function_desc; +}; + +#endif // SRSRAN_E2SM_H diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm.h b/srsgnb/hdr/stack/ric/e2sm_kpm.h new file mode 100644 index 0000000000..de40c6f976 --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2sm_kpm.h @@ -0,0 +1,84 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "e2sm.h" +#include "e2sm_kpm_common.h" +#include "srsran/asn1/e2ap.h" +#include "srsran/asn1/e2sm.h" +#include "srsran/asn1/e2sm_kpm_v2.h" +#include "srsran/srsran.h" + +#ifndef RIC_E2SM_KPM_H +#define RIC_E2SM_KPM_H + +using namespace asn1::e2ap; +using namespace asn1::e2sm_kpm; + +class e2sm_kpm_report_service; + +class e2sm_kpm : public e2sm +{ +public: + static const std::string short_name; + static const std::string oid; + static const std::string func_description; + static const uint32_t revision; + + e2sm_kpm(srslog::basic_logger& logger_, srsran::task_scheduler* _task_sched_ptr); + ~e2sm_kpm(); + + virtual bool generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func); + virtual bool process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, + RIC_event_trigger_definition_t& event_def); + virtual bool process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action_t& action_entry); + virtual bool remove_ric_action_definition(E2AP_RIC_action_t& action_entry); + virtual bool generate_ric_indication_content(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication); + + virtual void receive_e2_metrics_callback(const enb_metrics_t& m); + + friend class e2sm_kpm_report_service; + friend class e2sm_kpm_report_service_style1; + friend class e2sm_kpm_report_service_style2; + friend class e2sm_kpm_report_service_style3; + friend class e2sm_kpm_report_service_style4; + friend class e2sm_kpm_report_service_style5; + +private: + bool _generate_indication_header(e2_sm_kpm_ind_hdr_s& hdr, srsran::unique_byte_buffer_t& buf); + bool _generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::unique_byte_buffer_t& buf); + bool _get_meas_definition(std::string meas_name, e2sm_kpm_metric_t& def); + std::vector _get_supported_meas(uint32_t level_mask); + + bool _collect_meas_value(e2sm_kpm_meas_def_t& meas_value, meas_record_item_c& item); + bool + _extract_integer_type_meas_value(e2sm_kpm_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, uint32_t& value); + bool _extract_real_type_meas_value(e2sm_kpm_meas_def_t& meas_value, const enb_metrics_t& enb_metrics, float& value); + + srslog::basic_logger& logger; + std::vector supported_meas_types; + std::map registered_actions_data; + + srsran_random_t random_gen; + + enb_metrics_t last_enb_metrics; +}; + +#endif /*E2SM_KPM*/ diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_common.h b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h new file mode 100644 index 0000000000..63bd309c99 --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_common.h @@ -0,0 +1,80 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/asn1/e2ap.h" +#include "srsran/asn1/e2sm.h" +#include "srsran/asn1/e2sm_kpm_v2.h" +#include "srsran/srsran.h" + +#ifndef SRSRAN_E2SM_KPM_COMMON_H +#define SRSRAN_E2SM_KPM_COMMON_H + +using namespace asn1::e2ap; +using namespace asn1::e2sm_kpm; + +enum e2_metric_data_type_t { INTEGER, REAL }; + +typedef struct { + std::string name; + bool supported; + e2_metric_data_type_t data_type; + std::string units; + bool min_val_present; + double min_val; + bool max_val_present; + double max_val; + uint32_t supported_labels; + uint32_t supported_scopes; +} e2sm_kpm_metric_t; + +// TODO: define all labels and scopes + +/* Labels supported for a metric */ +enum e2sm_kpm_label_enum { + NO_LABEL = 0x0001, + MIN_LABEL = 0x0002, + MAX_LABEL = 0x0004, + AVG_LABEL = 0x0008, + SUM_LABEL = 0x0010, + UNKNOWN_LABEL = 0x8000 +}; + +std::string e2sm_kpm_label_2_str(e2sm_kpm_label_enum label); + +/* Scopes supported for a metric */ +enum e2sm_kpm_metric_scope_enum { + ENB_LEVEL = 0x0001, + CELL_LEVEL = 0x0002, + UE_LEVEL = 0x0004, + BEARER_LEVEL = 0x0008, + UNKNOWN_LEVEL = 0xffff +}; + +typedef struct { + std::string name; + e2sm_kpm_label_enum label; + e2sm_kpm_metric_scope_enum scope; + meas_record_item_c::types data_type; + uint32_t ue_id; // TODO: do we need to use type ueid_c? or we translate to local RNTI? + uint32_t cell_id; // TODO: do we need to use type cgi_c? or we translate to local cell_id? +} e2sm_kpm_meas_def_t; + +#endif // SRSRAN_E2SM_KPM_COMMON_H diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h new file mode 100644 index 0000000000..9511b3d5e0 --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h @@ -0,0 +1,73 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_E2SM_KPM_METRICS_H +#define SRSRAN_E2SM_KPM_METRICS_H + +#include "e2sm_kpm_common.h" +#include "srsran/srsran.h" + +// clang-format off +// Measurements defined in 3GPP TS 28.552 +std::vector get_e2sm_kpm_28_552_metrics() +{ + // TODO: add all metrics from 3GPP TS 28.552 + std::vector metrics; + // not supported metrics + metrics.push_back({"RRU.PrbTotDl", false, REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, CELL_LEVEL | UE_LEVEL }); + metrics.push_back({"RRU.PrbTotUl", false, REAL, "%", true, 0, true, 100, NO_LABEL | AVG_LABEL, CELL_LEVEL | UE_LEVEL }); + // not supported metrics + metrics.push_back({"RRU.RachPreambleDedMean", false, REAL, "-", false, 0, false, 100, NO_LABEL, CELL_LEVEL | UE_LEVEL }); + return metrics; +} + +// Measurements defined in 3GPP TS 32.425 +std::vector get_e2sm_kpm_34_425_metrics() +{ + // TODO: add all metrics from 3GPP TS 32.425 + std::vector metrics; + return metrics; +} + +// E2SM_KPM O-RAN specific Measurements +std::vector e2sm_kpm_oran_metrics() +{ + // TODO: add all E2SM_KPM O-RAN specific Measurements + std::vector metrics; + return metrics; +} + +// Custom Measurements +std::vector e2sm_kpm_custom_metrics() +{ + std::vector metrics; + // supported metrics + metrics.push_back({"test", true, INTEGER, "", true, 0, true, 100, NO_LABEL, ENB_LEVEL | CELL_LEVEL | UE_LEVEL }); + metrics.push_back({"random_int", true, INTEGER, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL }); + metrics.push_back({"cpu0_load", true, REAL, "", true, 0, true, 100, NO_LABEL, ENB_LEVEL }); + metrics.push_back({"cpu_load", true, REAL, "", true, 0, true, 100, MIN_LABEL|MAX_LABEL|AVG_LABEL, ENB_LEVEL }); + // not supported metrics + metrics.push_back({"test123", false, REAL, "", true, 0, true, 100, NO_LABEL, CELL_LEVEL | UE_LEVEL }); + return metrics; +} + +// clang-format on +#endif // SRSRAN_E2SM_KPM_METRICS_H diff --git a/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h new file mode 100644 index 0000000000..1257e39b03 --- /dev/null +++ b/srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h @@ -0,0 +1,181 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/ric/e2sm_kpm.h" +#include "srsgnb/hdr/stack/ric/e2sm_kpm_common.h" +#include "srsran/asn1/e2ap.h" +#include "srsran/asn1/e2sm.h" +#include "srsran/asn1/e2sm_kpm_v2.h" +#include "srsran/common/timers.h" +#include "srsran/srsran.h" + +#ifndef SRSRAN_E2SM_KPM_ACTION_DATA_H +#define SRSRAN_E2SM_KPM_ACTION_DATA_H + +using namespace asn1::e2ap; +using namespace asn1::e2sm_kpm; + +class e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service() = delete; + e2sm_kpm_report_service(e2sm_kpm* e2sm_kpm, uint16_t action_id, e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service() = default; + + virtual bool _initialize_ric_ind_hdr(); + virtual bool _initialize_ric_ind_msg() = 0; + virtual bool _collect_meas_data() = 0; + virtual bool is_ric_ind_ready() = 0; + virtual bool clear_collected_data() = 0; + + virtual bool _start_meas_collection(); + bool stop(); + virtual bool _stop_meas_collection(); + virtual bool _reschedule_meas_collection(); + + std::vector _get_present_labels(const meas_info_item_s& action_meas_info_item); + meas_record_item_c::types + _get_meas_data_type(std::string meas_name, e2sm_kpm_label_enum label, meas_record_l& meas_record_list); + + e2_sm_kpm_ind_hdr_s& get_ind_hdr() { return ric_ind_header_generic; }; + e2_sm_kpm_ind_msg_s& get_ind_msg() { return ric_ind_message_generic; }; + + e2sm_kpm* parent; + uint16_t action_id; + e2_sm_kpm_action_definition_s action_def_generic; + e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types ind_msg_format; + e2_sm_kpm_ind_hdr_s ric_ind_header_generic; + e2_sm_kpm_ind_msg_s ric_ind_message_generic; + + bool cell_global_id_present = false; + cgi_c cell_global_id; + + // hdr format 1 in base class, as all types use it + e2_sm_kpm_ind_hdr_format1_s& ric_ind_header; + + uint32_t granul_period = 0; + srsran::unique_timer meas_collection_timer; // for measurements collection +}; + +class e2sm_kpm_report_service_style1 : public e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service_style1(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service_style1() = default; + + static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); + + virtual bool _initialize_ric_ind_msg(); + virtual bool _collect_meas_data(); + virtual bool is_ric_ind_ready(); + virtual bool clear_collected_data(); + +private: + meas_data_item_s& + _get_meas_data_item(std::string meas_name, e2sm_kpm_label_enum label, uint32_t ue_id, bool& ref_found); + + e2_sm_kpm_action_definition_format1_s& action_def; + e2_sm_kpm_ind_msg_format1_s& ric_ind_message; +}; + +class e2sm_kpm_report_service_style2 : public e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service_style2(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service_style2() = default; + + static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); + + virtual bool _initialize_ric_ind_msg(); + virtual bool _collect_meas_data(); + virtual bool is_ric_ind_ready(); + virtual bool clear_collected_data(); + +private: + e2_sm_kpm_action_definition_format2_s& action_def; + e2_sm_kpm_ind_msg_format1_s& ric_ind_message; +}; + +class e2sm_kpm_report_service_style3 : public e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service_style3(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service_style3() = default; + + static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); + + virtual bool _initialize_ric_ind_msg(); + virtual bool _collect_meas_data(); + virtual bool is_ric_ind_ready(); + virtual bool clear_collected_data(); + +private: + e2_sm_kpm_action_definition_format3_s& action_def; + e2_sm_kpm_ind_msg_format2_s& ric_ind_message; +}; + +class e2sm_kpm_report_service_style4 : public e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service_style4(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service_style4() = default; + + static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); + + virtual bool _initialize_ric_ind_msg(); + virtual bool _collect_meas_data(); + virtual bool is_ric_ind_ready(); + virtual bool clear_collected_data(); + +private: + e2_sm_kpm_action_definition_format4_s& action_def; + e2_sm_kpm_ind_msg_format3_s& ric_ind_message; +}; + +class e2sm_kpm_report_service_style5 : public e2sm_kpm_report_service +{ +public: + e2sm_kpm_report_service_style5(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition); + virtual ~e2sm_kpm_report_service_style5() = default; + + static bool process_ric_action_definition(e2sm_kpm* e2sm_kpm, e2_sm_kpm_action_definition_s& action_definition); + + virtual bool _initialize_ric_ind_msg(); + virtual bool _collect_meas_data(); + virtual bool is_ric_ind_ready(); + virtual bool clear_collected_data(); + +private: + e2_sm_kpm_action_definition_format5_s& action_def; + e2_sm_kpm_ind_msg_format3_s& ric_ind_message; +}; + +#endif // SRSRAN_E2SM_KPM_ACTION_DATA_H diff --git a/srsgnb/hdr/stack/rrc/cell_asn1_config.h b/srsgnb/hdr/stack/rrc/cell_asn1_config.h new file mode 100644 index 0000000000..3a42456380 --- /dev/null +++ b/srsgnb/hdr/stack/rrc/cell_asn1_config.h @@ -0,0 +1,64 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_CELL_ASN1_CONFIG_H +#define SRSRAN_CELL_ASN1_CONFIG_H + +#include "rrc_nr_config.h" +#include "srsran/asn1/rrc_nr.h" +#include "srsran/common/bearer_manager.h" +#include "srsran/common/common_nr.h" + +namespace srsenb { + +using rlc_bearer_list_t = asn1::rrc_nr::cell_group_cfg_s::rlc_bearer_to_add_mod_list_l_; + +// PHY helpers +void set_search_space_from_phy_cfg(const srsran_search_space_t& ss, asn1::rrc_nr::search_space_s& out); + +// NSA helpers +int fill_sp_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::sp_cell_cfg_s& sp_cell); + +// SA helpers +int fill_master_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::cell_group_cfg_s& out); + +int fill_mib_from_enb_cfg(const rrc_cell_cfg_nr_t& cell_cfg, asn1::rrc_nr::mib_s& mib); +int fill_sib1_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::sib1_s& sib1); + +/** + * Based on the previous and new radio bearer config, generate ASN1 diff + * @return if a change was detected + */ +bool compute_diff_radio_bearer_cfg(const rrc_nr_cfg_t& cfg, + const asn1::rrc_nr::radio_bearer_cfg_s& prev_bearers, + const asn1::rrc_nr::radio_bearer_cfg_s& next_bearers, + asn1::rrc_nr::radio_bearer_cfg_s& diff); + +/// Apply radioBearerConfig updates to CellGroupConfig +int fill_cellgroup_with_radio_bearer_cfg(const rrc_nr_cfg_t& cfg, + uint32_t rnti, + const enb_bearer_manager& bearer_mapper, + const asn1::rrc_nr::radio_bearer_cfg_s& bearers, + asn1::rrc_nr::cell_group_cfg_s& out); + +} // namespace srsenb + +#endif // SRSRAN_CELL_ASN1_CONFIG_H diff --git a/srsgnb/hdr/stack/rrc/rrc_nr.h b/srsgnb/hdr/stack/rrc/rrc_nr.h new file mode 100644 index 0000000000..80aa8edf71 --- /dev/null +++ b/srsgnb/hdr/stack/rrc/rrc_nr.h @@ -0,0 +1,208 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSENB_RRC_NR_H +#define SRSENB_RRC_NR_H + +#include "srsenb/hdr/stack/enb_stack_base.h" +#include "srsenb/hdr/stack/rrc/rrc_config_common.h" +#include "srsenb/hdr/stack/rrc/rrc_metrics.h" +#include "srsgnb/hdr/stack/rrc/rrc_nr_config.h" +#include "srsran/asn1/rrc_nr.h" +#include "srsran/common/block_queue.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/common/common.h" +#include "srsran/common/task_scheduler.h" +#include "srsran/common/threads.h" +#include "srsran/common/timeout.h" +#include "srsran/interfaces/enb_pdcp_interfaces.h" +#include "srsran/interfaces/enb_rlc_interfaces.h" +#include "srsran/interfaces/enb_x2_interfaces.h" +#include "srsran/interfaces/gnb_interfaces.h" +#include "srsran/interfaces/gnb_mac_interfaces.h" +#include "srsran/interfaces/gnb_ngap_interfaces.h" +#include "srsran/interfaces/gnb_rrc_nr_interfaces.h" +#include +#include + +namespace srsenb { + +class enb_bearer_manager; +class du_config_manager; + +enum class rrc_nr_state_t { RRC_IDLE, RRC_INACTIVE, RRC_CONNECTED }; + +class rrc_nr final : public rrc_interface_pdcp_nr, + public rrc_interface_mac_nr, + public rrc_interface_rlc_nr, + public rrc_interface_ngap_nr, + public rrc_nr_interface_rrc +{ +public: + explicit rrc_nr(srsran::task_sched_handle task_sched_); + ~rrc_nr(); + + int32_t init(const rrc_nr_cfg_t& cfg, + phy_interface_stack_nr* phy, + mac_interface_rrc_nr* mac, + rlc_interface_rrc* rlc, + pdcp_interface_rrc* pdcp, + ngap_interface_rrc_nr* ngap_, + gtpu_interface_rrc* gtpu_, + enb_bearer_manager& bearer_mapper_, + rrc_eutra_interface_rrc_nr* rrc_eutra_); + + void stop(); + + void get_metrics(srsenb::rrc_metrics_t& m); + + void config_phy(); + void config_mac(); + int32_t generate_sibs(); + int read_pdu_bcch_bch(const uint32_t tti, srsran::byte_buffer_t& buffer) final; + int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::byte_buffer_t& buffer) final; + + /// User management + int add_user(uint16_t rnti, uint32_t pcell_cc_idx) final; + void rem_user(uint16_t rnti); + int update_user(uint16_t new_rnti, uint16_t old_rnti) final; + void set_activity_user(uint16_t rnti) final; + int rrc_release(uint16_t rnti); + + // RLC interface + // TODO + void read_pdu_pcch(uint8_t* payload, uint32_t payload_size) final {} + void max_retx_attempted(uint16_t rnti) final {} + void protocol_failure(uint16_t rnti) final {} + const char* get_rb_name(uint32_t lcid) final { return "invalid"; } + + // PDCP interface + void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) final; + void notify_pdcp_integrity_error(uint16_t rnti, uint32_t lcid) final; + + // Interface for EUTRA RRC + void sgnb_addition_request(uint16_t rnti, const sgnb_addition_req_params_t& params) final; + void sgnb_reconfiguration_complete(uint16_t rnti, const asn1::dyn_octstring& reconfig_response) final; + void sgnb_release_request(uint16_t nr_rnti) final; + + // Interfaces for NGAP + int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) final; + int ue_set_bitrates(uint16_t rnti, const asn1::ngap::ue_aggregate_maximum_bit_rate_s& rates) final; + int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap::ue_security_cap_s& caps) final; + int start_security_mode_procedure(uint16_t rnti, srsran::unique_byte_buffer_t nas_pdu) final; + int establish_rrc_bearer(uint16_t rnti, + uint16_t pdu_session_id, + srsran::const_byte_span nas_pdu, + uint32_t lcid, + uint32_t five_qi) final; + int release_bearers(uint16_t rnti) final; + void release_user(uint16_t rnti) final; + void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) final; + int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap::ue_aggregate_maximum_bit_rate_s& rates) final; + int allocate_lcid(uint16_t rnti) final; + + // logging + typedef enum { Rx = 0, Tx } direction_t; + template + void log_rrc_message(const char* source, + const direction_t dir, + srsran::const_byte_span pdu, + const T& msg, + const char* msg_type); + + class ue; + +private: + static constexpr uint32_t UE_PSCELL_CC_IDX = 0; // first NR cell is always Primary Secondary Cell for UE + rrc_nr_cfg_t cfg = {}; + + // interfaces + phy_interface_stack_nr* phy = nullptr; + mac_interface_rrc_nr* mac = nullptr; + rlc_interface_rrc* rlc = nullptr; + pdcp_interface_rrc* pdcp = nullptr; + ngap_interface_rrc_nr* ngap = nullptr; + gtpu_interface_rrc* gtpu = nullptr; + rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr; + enb_bearer_manager* bearer_mapper = nullptr; + + // args + srsran::task_sched_handle task_sched; + + // derived + uint32_t slot_dur_ms = 0; + srslog::basic_logger& logger; + + // vars + std::unique_ptr du_cfg; + struct cell_ctxt_t { + asn1::rrc_nr::sys_info_ies_s::sib_type_and_info_l_ sibs; + std::vector sib_buffer; + std::unique_ptr master_cell_group; + srsran::phy_cfg_nr_t default_phy_ue_cfg_nr; + }; + std::unique_ptr cell_ctxt; + rnti_map_t > users; + bool running = false; + + /// Private Methods + void handle_pdu(uint16_t rnti, uint32_t lcid, srsran::const_byte_span pdu); + void handle_ul_ccch(uint16_t rnti, srsran::const_byte_span pdu); + void handle_ul_dcch(uint16_t rnti, uint32_t lcid, srsran::const_byte_span pdu); + + // TS 38.331, 5.3.3 - RRC connection establishment + void handle_rrc_setup_request(uint16_t rnti, const asn1::rrc_nr::rrc_setup_request_s& msg); + + // TS 38.331, 5.3.7 RRC connection reestablishment + void handle_rrc_reest_request(uint16_t rnti, const asn1::rrc_nr::rrc_reest_request_s& msg); + + /// This gets called by rrc_nr::sgnb_addition_request and WILL NOT TRIGGER the RX MSG3 activity timer + int add_user(uint16_t rnti, uint32_t pcell_cc_idx, bool start_msg3_timer); + + // Helper to create PDU from RRC message + template + srsran::unique_byte_buffer_t pack_into_pdu(const T& msg, const char* context_name = nullptr) + { + context_name = context_name == nullptr ? __FUNCTION__ : context_name; + // Allocate a new PDU buffer and pack the + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (pdu == nullptr) { + logger.error("Couldn't allocate PDU in %s.", context_name); + return nullptr; + } + asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); + if (msg.pack(bref) == asn1::SRSASN_ERROR_ENCODE_FAIL) { + logger.error("Failed to pack message in %s. Discarding it.", context_name); + return nullptr; + } + pdu->N_bytes = bref.distance_bytes(); + return pdu; + } + void log_rx_pdu_fail(uint16_t rnti, + uint32_t lcid, + srsran::const_byte_span pdu, + const char* cause_str, + bool log_hex = true); +}; + +} // namespace srsenb + +#endif // SRSENB_RRC_NR_H diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_config.h b/srsgnb/hdr/stack/rrc/rrc_nr_config.h new file mode 100644 index 0000000000..d3ee0568b4 --- /dev/null +++ b/srsgnb/hdr/stack/rrc/rrc_nr_config.h @@ -0,0 +1,92 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_RRC_NR_CONFIG_H +#define SRSRAN_RRC_NR_CONFIG_H + +#include "srsenb/hdr/stack/rrc/rrc_config_common.h" +#include "srsgnb/hdr/phy/phy_nr_interfaces.h" +#include "srsran/asn1/rrc_nr.h" +#include "srsran/common/security.h" +#include "srsran/interfaces/gnb_rrc_nr_interfaces.h" + +namespace srsenb { + +// Cell/Sector configuration for NR cells +struct rrc_cell_cfg_nr_t { + phy_cell_cfg_nr_t phy_cell; // already contains all PHY-related parameters (i.e. RF port, PCI, etc.) + uint32_t tac; // Tracking area code + uint32_t dl_arfcn; // DL freq already included in carrier + uint32_t ul_arfcn; // UL freq also in carrier + uint32_t dl_absolute_freq_point_a; // derived from DL ARFCN + uint32_t ul_absolute_freq_point_a; // derived from UL ARFCN + uint32_t band; + uint32_t prach_root_seq_idx; + uint32_t num_ra_preambles; + uint32_t coreset0_idx; // Table 13-{1,...15} row index + srsran_duplex_mode_t duplex_mode; + double ssb_freq_hz; + uint32_t ssb_absolute_freq_point; // derived from DL ARFCN (SSB arfcn) + uint32_t ssb_offset; + srsran_subcarrier_spacing_t ssb_scs; + srsran_ssb_pattern_t ssb_pattern; + asn1::rrc_nr::pdcch_cfg_common_s pdcch_cfg_common; + asn1::rrc_nr::pdcch_cfg_s pdcch_cfg_ded; + int8_t pdsch_rs_power; +}; + +typedef std::vector rrc_cell_list_nr_t; + +struct srb_5g_cfg_t { + bool present = false; + asn1::rrc_nr::rlc_cfg_c rlc_cfg; +}; + +struct rrc_nr_cfg_five_qi_t { + bool configured = false; + asn1::rrc_nr::pdcp_cfg_s pdcp_cfg; + asn1::rrc_nr::rlc_cfg_c rlc_cfg; +}; + +struct rrc_nr_cfg_t { + rrc_cell_list_nr_t cell_list; + uint32_t inactivity_timeout_ms = 100000; + uint32_t enb_id; + uint16_t mcc; + uint16_t mnc; + bool is_standalone; + + srb_5g_cfg_t srb1_cfg; + srb_5g_cfg_t srb2_cfg; + + std::map five_qi_cfg; + + std::array nea_preference_list; + std::array nia_preference_list; + + std::string log_name = "RRC-NR"; + std::string log_level; + uint32_t log_hex_limit; +}; + +} // namespace srsenb + +#endif // SRSRAN_RRC_NR_CONFIG_H diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h b/srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h new file mode 100644 index 0000000000..714c053ad2 --- /dev/null +++ b/srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h @@ -0,0 +1,44 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_RRC_NR_CONFIG_DEFAULT_H +#define SRSRAN_RRC_NR_CONFIG_DEFAULT_H + +#include "rrc_nr_config.h" + +namespace srsenb { + +// Helper methods +uint32_t coreset_get_bw(const asn1::rrc_nr::ctrl_res_set_s& coreset); +int coreset_get_pdcch_nr_max_candidates(const asn1::rrc_nr::ctrl_res_set_s& coreset, uint32_t aggregation_level); + +void generate_default_nr_cell(rrc_cell_cfg_nr_t& cell); + +int set_derived_nr_cell_params(bool is_sa, rrc_cell_cfg_nr_t& cell); +int set_derived_nr_rrc_params(rrc_nr_cfg_t& rrc_cfg); + +// Tests to ensure validity of config + +int check_nr_pdcch_cfg_valid(const srsran_pdcch_cfg_nr_t& pdcch); + +} // namespace srsenb + +#endif // SRSRAN_RRC_NR_CONFIG_DEFAULT_H diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_du_manager.h b/srsgnb/hdr/stack/rrc/rrc_nr_du_manager.h new file mode 100644 index 0000000000..ff23fa538f --- /dev/null +++ b/srsgnb/hdr/stack/rrc/rrc_nr_du_manager.h @@ -0,0 +1,85 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_RRC_NR_DU_MANAGER_H +#define SRSRAN_RRC_NR_DU_MANAGER_H + +#include "rrc_nr_config.h" +#include "srsgnb/hdr/stack/mac/sched_nr_interface.h" +#include "srsran/asn1/rrc_nr.h" + +namespace srsenb { + +class du_cell_config +{ +public: + uint32_t cc; + uint32_t pci; + + asn1::rrc_nr::mib_s mib; + srsran::unique_byte_buffer_t packed_mib; + + asn1::rrc_nr::sib1_s sib1; + srsran::unique_byte_buffer_t packed_sib1; + + asn1::rrc_nr::subcarrier_spacing_e ssb_scs; + srsran_ssb_pattern_t ssb_pattern; + double ssb_center_freq_hz; + double dl_freq_hz; + bool is_standalone; + + const asn1::rrc_nr::serving_cell_cfg_common_sib_s& serv_cell_cfg_common() const + { + return sib1.serving_cell_cfg_common; + } + + /// SI messages (index=0 for SIB1) + srsran::const_byte_span packed_si_msg(uint32_t idx) { return srsran::make_span(packed_sib1); } + size_t nof_si_msgs() const { return 1; } +}; + +class du_config_manager +{ +public: + explicit du_config_manager(const rrc_nr_cfg_t& cfg); + ~du_config_manager(); + + const rrc_nr_cfg_t& cfg; + + int add_cell(); + + const du_cell_config& cell(uint32_t cc) const + { + srsran_assert(cc < cells.size(), "Unknown DU Cell Index=%d", cc); + return *cells[cc]; + } + +private: + srslog::basic_logger& logger; + + std::vector > cells; +}; + +void fill_phy_pdcch_cfg_common(const du_cell_config& cell, srsran_pdcch_cfg_nr_t* pdcch); + +} // namespace srsenb + +#endif // SRSRAN_RRC_NR_DU_MANAGER_H diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_security_context.h b/srsgnb/hdr/stack/rrc/rrc_nr_security_context.h new file mode 100644 index 0000000000..1af24d2da8 --- /dev/null +++ b/srsgnb/hdr/stack/rrc/rrc_nr_security_context.h @@ -0,0 +1,81 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_RRC_NR_SECURITY_CONTEXT_H +#define SRSRAN_RRC_NR_SECURITY_CONTEXT_H + +#include "srsgnb/hdr/stack/rrc/rrc_nr_config.h" +#include "srsran/asn1/ngap.h" +#include "srsran/interfaces/gnb_interfaces.h" +#include "srsran/srslog/srslog.h" + +namespace srsgnb { + +class nr_security_context +{ +public: + explicit nr_security_context(const srsenb::rrc_nr_cfg_t& cfg_) : + cfg(cfg_), logger(srslog::fetch_basic_logger("RRC-NR")) + {} + + nr_security_context(const nr_security_context& other) : cfg(other.cfg), logger(srslog::fetch_basic_logger("RRC-NR")) + { + k_gnb_present = other.k_gnb_present; + security_capabilities = other.security_capabilities; + std::copy(other.k_gnb, other.k_gnb + 32, k_gnb); + sec_cfg = other.sec_cfg; + ncc = other.ncc; + } + + nr_security_context& operator=(const nr_security_context& other) + { + k_gnb_present = other.k_gnb_present; + security_capabilities = other.security_capabilities; + std::copy(other.k_gnb, other.k_gnb + 32, k_gnb); + sec_cfg = other.sec_cfg; + ncc = other.ncc; + return *this; + } + + bool set_security_capabilities(const asn1::ngap::ue_security_cap_s& caps); + void set_security_key(const asn1::fixed_bitstring<256, false, true>& key); + void set_ncc(uint8_t ncc_) { ncc = ncc_; } + + asn1::rrc_nr::security_algorithm_cfg_s get_security_algorithm_cfg() const; + const srsran::nr_as_security_config_t& get_as_sec_cfg() const { return sec_cfg; } + uint8_t get_ncc() const { return ncc; } + bool is_as_sec_cfg_valid() const { return k_gnb_present; } + + void regenerate_keys_handover(uint32_t new_pci, uint32_t new_dl_earfcn); + +private: + void generate_as_keys(); + + srslog::basic_logger& logger; + const srsenb::rrc_nr_cfg_t& cfg; + bool k_gnb_present = false; + asn1::ngap::ue_security_cap_s security_capabilities = {}; + uint8_t k_gnb[32] = {}; // Provided by MME + srsran::nr_as_security_config_t sec_cfg = {}; + uint8_t ncc = 0; +}; +} // namespace srsgnb +#endif diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_ue.h b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h new file mode 100644 index 0000000000..18cea4007f --- /dev/null +++ b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h @@ -0,0 +1,217 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_RRC_NR_UE_H +#define SRSRAN_RRC_NR_UE_H + +#include "rrc_nr.h" +#include "rrc_nr_security_context.h" + +namespace srsenb { + +class rrc_nr::ue +{ +public: + enum activity_timeout_type_t { + MSG3_RX_TIMEOUT = 0, ///< Msg3 has its own timeout to quickly remove fake UEs from random PRACHs + UE_INACTIVITY_TIMEOUT, ///< (currently unused) UE inactivity timeout (usually bigger than reestablishment timeout) + MSG5_RX_TIMEOUT, ///< (currently unused) for receiving RRCConnectionSetupComplete/RRCReestablishmentComplete + nulltype + }; + + /// @param [in] start_msg3_timer: indicates whether the UE is created as part of a RACH process + ue(rrc_nr* parent_, uint16_t rnti_, uint32_t pcell_cc_idx, bool start_msg3_timer = true); + ~ue(); + + int handle_sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params); + void crnti_ce_received(); + + // getters + bool is_connected() { return state == rrc_nr_state_t::RRC_CONNECTED; } + bool is_idle() { return state == rrc_nr_state_t::RRC_IDLE; } + bool is_inactive() { return state == rrc_nr_state_t::RRC_INACTIVE; } + bool is_endc() { return endc; } + uint16_t get_eutra_rnti() { return eutra_rnti; } + void get_metrics(rrc_ue_metrics_t& ue_metrics) { ue_metrics = {}; /*TODO fill RRC metrics*/ }; + + // setters + void set_security_key(const asn1::fixed_bitstring<256, false, true>& key) { sec_ctx.set_security_key(key); } + void set_security_capabilities(const asn1::ngap::ue_security_cap_s& caps) { sec_ctx.set_security_capabilities(caps); } + + void deactivate_bearers(); + + /// methods to handle activity timer + std::string to_string(const activity_timeout_type_t& type); + void set_activity_timeout(activity_timeout_type_t type); + void set_activity(bool enabled = true); + void activity_timer_expired(const activity_timeout_type_t type); + + /** TS 38.331 - 5.3.3 RRC connection establishment */ + void handle_rrc_setup_request(const asn1::rrc_nr::rrc_setup_request_s& msg); + void handle_rrc_setup_complete(const asn1::rrc_nr::rrc_setup_complete_s& msg); + + /** TS 38.331 - 5.3.4 Initial AS security activation */ + void handle_security_mode_complete(const asn1::rrc_nr::security_mode_complete_s& msg); + + /** TS 38.331 - 5.3.5 RRC reconfiguration */ + void handle_rrc_reconfiguration_complete(const asn1::rrc_nr::rrc_recfg_complete_s& msg); + + /** TS 38.331 - 5.3.7 RRC connection reestablishment */ + void handle_rrc_reestablishment_request(const asn1::rrc_nr::rrc_reest_request_s& msg); + void handle_rrc_reestablishment_complete(const asn1::rrc_nr::rrc_reest_complete_s& msg); + + /** TS 38.331 - 5.3.8 Connection Release */ + void send_rrc_release(); + + /* TS 38.331 - 5.6.1 UE capability transfer */ + void handle_ue_capability_information(const asn1::rrc_nr::ue_cap_info_s& msg); + + /** TS 38.331 - 5.7.1 DL information transfer */ + void send_dl_information_transfer(srsran::unique_byte_buffer_t sdu); + + /** TS 38.331 - 5.7.2 UL information transfer */ + void handle_ul_information_transfer(const asn1::rrc_nr::ul_info_transfer_s& msg); + + // NGAP interface + void establish_eps_bearer(uint32_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid, uint32_t five_qi); + + /* TS 38.331 - 5.3.4 Initial AS security activation */ + void send_security_mode_command(srsran::unique_byte_buffer_t nas_pdu); + + /* TS 38.331 - 5.3.5 RRC reconfiguration */ + void send_rrc_reconfiguration(); + + /* TS 38.331 - 5.6.1 UE capability transfer */ + int send_ue_capability_enquiry(); + +private: + int send_dl_ccch(const asn1::rrc_nr::dl_ccch_msg_s& dl_ccch_msg); + int send_dl_dcch(srsran::nr_srb srb, const asn1::rrc_nr::dl_dcch_msg_s& dl_dcch_msg); + + /** TS 38.331 - 5.3.3 RRC connection establishment */ + void send_rrc_setup(); + void send_rrc_reject(uint8_t reject_wait_time_secs); + + /** TS 38.331 - 5.3.7 RRC connection reestablishment */ + void send_connection_reest(uint8_t ncc); + + /// Update PDCP bearers based on ASN1 structs passed to the UE + int update_pdcp_bearers(const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_diff, + const asn1::rrc_nr::cell_group_cfg_s& cell_group_diff); + + /// Update RLC bearers based on ASN1 structs passed to the UE + int update_rlc_bearers(const asn1::rrc_nr::cell_group_cfg_s& cell_group_diff); + + /// Update MAC based on ASN1 message + int update_mac(const asn1::rrc_nr::cell_group_cfg_s& cell_group_config, bool is_config_complete); + + /// Update AS security config on active RB + int update_as_security(uint32_t lcid, bool enable_integrity, bool enable_ciphering); + + int pack_rrc_reconfiguration(asn1::dyn_octstring& packed_rrc_reconfig); + int pack_secondary_cell_group_cfg(asn1::dyn_octstring& packed_secondary_cell_config); + + int pack_secondary_cell_group_mac_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + + int pack_secondary_cell_group_sp_cell_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + + int pack_sp_cell_cfg_ded(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + + int pack_sp_cell_cfg_ded_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + int pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + + int pack_sp_cell_cfg_ded_ul_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + int pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + int pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pucch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + int pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pusch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + + int pack_sp_cell_cfg_ded_pdcch_serving_cell_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + + int pack_recfg_with_sync(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + int pack_recfg_with_sync_sp_cell_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common_phy_cell_group_cfg( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + + int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + int pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdsch_cfg_common( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + + int pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + int pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + int pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp_pusch_cfg_common( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack); + + int pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_bearer_config); + + int add_drb(uint32_t five_qi); + + bool init_pucch(); + + // logging helpers + template + void log_rrc_message(srsran::nr_srb srb, + const direction_t dir, + srsran::const_byte_span pdu, + const M& msg, + const char* msg_type); + template + void log_rrc_container(const direction_t dir, srsran::const_byte_span pdu, const M& msg, const char* msg_type); + + // args + rrc_nr* parent = nullptr; + srslog::basic_logger& logger; + uint16_t rnti = SRSRAN_INVALID_RNTI; + + // state + rrc_nr_state_t state = rrc_nr_state_t::RRC_IDLE; + uint8_t transaction_id = 0; + srsran::unique_timer activity_timer; /// for basic DL/UL activity timeout + + // RRC configs for UEs + asn1::rrc_nr::cell_group_cfg_s cell_group_cfg, next_cell_group_cfg; + asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg, next_radio_bearer_cfg; + std::vector nas_pdu_queue; + + // MAC controller + sched_nr_interface::ue_cfg_t uecfg{}; + + const uint32_t drb1_lcid = 4; + uint32_t drb1_five_qi = 0; /// selected by 5GC + + // Security helper + srsgnb::nr_security_context sec_ctx; + + // SA specific variables + struct ctxt_t { + uint64_t setup_ue_id = -1; + asn1::rrc_nr::establishment_cause_opts connection_cause; + } ctxt; + + // NSA specific variables + bool endc = false; + uint16_t eutra_rnti = SRSRAN_INVALID_RNTI; +}; + +} // namespace srsenb + +#endif // SRSRAN_RRC_NR_UE_H diff --git a/srsenb/hdr/stack/upper/sdap.h b/srsgnb/hdr/stack/sdap/sdap.h similarity index 96% rename from srsenb/hdr/stack/upper/sdap.h rename to srsgnb/hdr/stack/sdap/sdap.h index cee33237e9..525aa993f9 100644 --- a/srsenb/hdr/stack/upper/sdap.h +++ b/srsgnb/hdr/stack/sdap/sdap.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsgnb/src/CMakeLists.txt b/srsgnb/src/CMakeLists.txt new file mode 100644 index 0000000000..13f947f9f1 --- /dev/null +++ b/srsgnb/src/CMakeLists.txt @@ -0,0 +1,21 @@ +# +# Copyright 2013-2023 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/. +# + +add_subdirectory(stack) \ No newline at end of file diff --git a/srsgnb/src/stack/CMakeLists.txt b/srsgnb/src/stack/CMakeLists.txt new file mode 100644 index 0000000000..7c3721ffe2 --- /dev/null +++ b/srsgnb/src/stack/CMakeLists.txt @@ -0,0 +1,31 @@ +# +# Copyright 2013-2023 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/. +# + +include_directories(${PROJECT_SOURCE_DIR}) + +add_subdirectory(mac) +add_subdirectory(ngap) +add_subdirectory(ric) +add_subdirectory(rrc) +add_subdirectory(sdap) + +set(SOURCES gnb_stack_nr.cc) + +add_library(srsgnb_stack STATIC ${SOURCES}) \ No newline at end of file diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsgnb/src/stack/gnb_stack_nr.cc similarity index 70% rename from srsenb/src/stack/gnb_stack_nr.cc rename to srsgnb/src/stack/gnb_stack_nr.cc index f0d8ce6908..5a484b26e5 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsgnb/src/stack/gnb_stack_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,8 +19,11 @@ * */ -#include "srsenb/hdr/stack/gnb_stack_nr.h" -#include "srsran/common/standard_streams.h" +#include "srsgnb/hdr/stack/gnb_stack_nr.h" +#include "srsenb/hdr/stack/upper/gtpu.h" +#include "srsenb/hdr/stack/upper/gtpu_pdcp_adapter.h" +#include "srsgnb/hdr/stack/ngap/ngap.h" +#include "srsran/common/network_utils.h" #include "srsran/srsran.h" #include @@ -34,9 +37,12 @@ gnb_stack_nr::gnb_stack_nr(srslog::sink& log_sink) : pdcp_logger(srslog::fetch_basic_logger("PDCP-NR", log_sink, false)), rrc_logger(srslog::fetch_basic_logger("RRC-NR", log_sink, false)), stack_logger(srslog::fetch_basic_logger("STCK-NR", log_sink, false)), + gtpu_logger(srslog::fetch_basic_logger("GTPU", log_sink, false)), + ngap_logger(srslog::fetch_basic_logger("NGAP", log_sink, false)), mac(&task_sched), rrc(&task_sched), pdcp(&task_sched, pdcp_logger), + bearer_manager(new srsenb::enb_bearer_manager()), rlc(rlc_logger) { sync_task_queue = task_sched.make_task_queue(); @@ -70,12 +76,25 @@ int gnb_stack_nr::init(const gnb_stack_args_t& args_, pdcp_logger.set_level(srslog::str_to_basic_level(args.log.pdcp_level)); rrc_logger.set_level(srslog::str_to_basic_level(args.log.rrc_level)); stack_logger.set_level(srslog::str_to_basic_level(args.log.stack_level)); + ngap_logger.set_level(srslog::str_to_basic_level(args.log.s1ap_level)); + gtpu_logger.set_level(srslog::str_to_basic_level(args.log.gtpu_level)); + srslog::fetch_basic_logger("COMN", false).set_level(srslog::str_to_basic_level(args.log.stack_level)); mac_logger.set_hex_dump_max_size(args.log.mac_hex_limit); rlc_logger.set_hex_dump_max_size(args.log.rlc_hex_limit); pdcp_logger.set_hex_dump_max_size(args.log.pdcp_hex_limit); rrc_logger.set_hex_dump_max_size(args.log.rrc_hex_limit); stack_logger.set_hex_dump_max_size(args.log.stack_hex_limit); + ngap_logger.set_hex_dump_max_size(args.log.s1ap_hex_limit); + gtpu_logger.set_hex_dump_max_size(args.log.gtpu_hex_limit); + srslog::fetch_basic_logger("COMN", false).set_hex_dump_max_size(args.log.stack_hex_limit); + + if (x2_ == nullptr) { + // SA mode + ngap.reset(new srsenb::ngap(&task_sched, ngap_logger, &srsran::get_rx_io_manager())); + gtpu.reset(new srsenb::gtpu(&task_sched, gtpu_logger, srsran::srsran_rat_t::nr, &srsran::get_rx_io_manager())); + gtpu_adapter.reset(new gtpu_pdcp_adapter(gtpu_logger, nullptr, &pdcp, gtpu.get(), *bearer_manager)); + } // Init all layers if (mac.init(args.mac, phy, nullptr, &rlc, &rrc) != SRSRAN_SUCCESS) { @@ -84,17 +103,31 @@ int gnb_stack_nr::init(const gnb_stack_args_t& args_, } rlc.init(&pdcp, &rrc, &mac, task_sched.get_timer_handler()); - pdcp.init(&rlc, &rrc, x2_); - if (rrc.init(rrc_cfg_, phy, &mac, &rlc, &pdcp, nullptr, nullptr, x2_) != SRSRAN_SUCCESS) { + if (rrc.init(rrc_cfg_, phy, &mac, &rlc, &pdcp, ngap.get(), gtpu.get(), *bearer_manager, x2_) != SRSRAN_SUCCESS) { stack_logger.error("Couldn't initialize RRC"); return SRSRAN_ERROR; } - // TODO: add SDAP, NGAP - // m_gtpu->init(args.s1ap.gtp_bind_addr, args.s1ap.mme_addr, - // args.expert.m1u_multiaddr, args.expert.m1u_if_addr, nullptr, >pu_log, - // args.expert.enable_mbsfn); + if (ngap != nullptr) { + pdcp.init(&rlc, &rrc, gtpu_adapter.get()); + + if (args.ngap_pcap.enable) { + ngap_pcap.open(args.ngap_pcap.filename.c_str()); + ngap->start_pcap(&ngap_pcap); + } + + ngap->init(args.ngap, &rrc, gtpu.get()); + gtpu_args_t gtpu_args; + gtpu_args.embms_enable = false; + gtpu_args.mme_addr = args.ngap.amf_addr; + gtpu_args.gtp_bind_addr = args.ngap.gtp_bind_addr; + gtpu->init(gtpu_args, gtpu_adapter.get()); + } else { + pdcp.init(&rlc, &rrc, x2_); + } + + // TODO: add SDAP running = true; @@ -113,6 +146,8 @@ void gnb_stack_nr::stop() void gnb_stack_nr::stop_impl() { + srsran::get_rx_io_manager().stop(); + rrc.stop(); pdcp.stop(); mac.stop(); @@ -195,13 +230,13 @@ int gnb_stack_nr::slot_indication(const srsran_slot_cfg_t& slot_cfg) { return mac.slot_indication(slot_cfg); } -int gnb_stack_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) +gnb_stack_nr::dl_sched_t* gnb_stack_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg) { - return mac.get_dl_sched(slot_cfg, dl_sched); + return mac.get_dl_sched(slot_cfg); } -int gnb_stack_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) +gnb_stack_nr::ul_sched_t* gnb_stack_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg) { - return mac.get_ul_sched(slot_cfg, ul_sched); + return mac.get_ul_sched(slot_cfg); } int gnb_stack_nr::pucch_info(const srsran_slot_cfg_t& slot_cfg, const mac_interface_phy_nr::pucch_info_t& pucch_info) { @@ -217,4 +252,4 @@ void gnb_stack_nr::rach_detected(const rach_info_t& rach_info) mac.rach_detected(rach_info); } -} // namespace srsenb \ No newline at end of file +} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/CMakeLists.txt b/srsgnb/src/stack/mac/CMakeLists.txt similarity index 75% rename from srsenb/src/stack/mac/nr/CMakeLists.txt rename to srsgnb/src/stack/mac/CMakeLists.txt index b25a9e1928..4505059eff 100644 --- a/srsenb/src/stack/mac/nr/CMakeLists.txt +++ b/srsgnb/src/stack/mac/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -22,17 +22,23 @@ set(SOURCES mac_nr.cc ue_nr.cc sched_nr.cc sched_nr_ue.cc + sched_ue/ue_cfg_manager.cc sched_nr_worker.cc sched_nr_grant_allocator.cc sched_nr_harq.cc sched_nr_pdcch.cc + sched_nr_sch.cc sched_nr_cfg.cc sched_nr_helpers.cc - sched_nr_cell.cc + sched_nr_bwp.cc sched_nr_rb.cc sched_nr_time_rr.cc harq_softbuffer.cc - sched_nr_signalling.cc) + sched_nr_signalling.cc + sched_nr_interface_utils.cc) add_library(srsgnb_mac STATIC ${SOURCES}) -target_link_libraries(srsgnb_mac srsenb_mac_common) +target_link_libraries(srsgnb_mac srsenb_mac_common srsran_mac rrc_nr_asn1) +include_directories(${PROJECT_SOURCE_DIR}) + +add_subdirectory(test) diff --git a/srsenb/src/stack/mac/nr/harq_softbuffer.cc b/srsgnb/src/stack/mac/harq_softbuffer.cc similarity index 95% rename from srsenb/src/stack/mac/nr/harq_softbuffer.cc rename to srsgnb/src/stack/mac/harq_softbuffer.cc index 36419dd08a..97e393e8f9 100644 --- a/srsenb/src/stack/mac/nr/harq_softbuffer.cc +++ b/srsgnb/src/stack/mac/harq_softbuffer.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,7 +19,7 @@ * */ -#include "srsenb/hdr/stack/mac/nr/harq_softbuffer.h" +#include "srsgnb/hdr/stack/mac/harq_softbuffer.h" #include "srsran/adt/pool/obj_pool.h" namespace srsenb { diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsgnb/src/stack/mac/mac_nr.cc similarity index 51% rename from srsenb/src/stack/mac/nr/mac_nr.cc rename to srsgnb/src/stack/mac/mac_nr.cc index 29be1e47b5..6c257437b8 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsgnb/src/stack/mac/mac_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,27 +19,205 @@ * */ -#include "srsenb/hdr/stack/mac/nr/mac_nr.h" +#include "srsgnb/hdr/stack/mac/mac_nr.h" +#include "srsgnb/hdr/stack/mac/sched_nr.h" #include "srsran/common/buffer_pool.h" -#include "srsran/common/log_helper.h" #include "srsran/common/phy_cfg_nr_default.h" #include "srsran/common/rwlock_guard.h" #include "srsran/common/standard_streams.h" #include "srsran/common/string_helpers.h" #include "srsran/common/time_prof.h" #include "srsran/mac/mac_rar_pdu_nr.h" -#include -#include -#include -#include + +//#define WRITE_SIB_PCAP namespace srsenb { +/** + * @brief Handles UL PDU processing + * + * This class implements the demuxing of UL PDUs received at the MAC layer. + * When the PHY decodes a valid PUSCH it passes the PDU to the MAC which + * in turn puts them in a thread-safe task queue to return to the calling + * thread as quick as possible. + * + * The demuxing of the PDUs for all users takes place on the Stack thread + * which calls RLC and RRC for SDUs, or the MAC/scheduler for control elements. + * + */ +class mac_nr_rx +{ +public: + explicit mac_nr_rx(rlc_interface_mac* rlc_, + rrc_interface_mac_nr* rrc_, + srsran::task_queue_handle& stack_task_queue_, + sched_nr_interface* sched_, + mac_interface_pdu_demux_nr& mac_, + srslog::basic_logger& logger_) : + task_queue(stack_task_queue_), rlc(rlc_), rrc(rrc_), sched(sched_), mac(mac_), logger(logger_) + {} + + void handle_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) + { + task_queue.push(std::bind( + [this, rnti](srsran::unique_byte_buffer_t& pdu) { handle_pdu_impl(rnti, std::move(pdu)); }, std::move(pdu))); + } + +private: + int handle_pdu_impl(uint16_t rnti, srsran::unique_byte_buffer_t pdu) + { + pdu_ul.init_rx(true); + if (pdu_ul.unpack(pdu->msg, pdu->N_bytes) != SRSRAN_SUCCESS) { + return SRSRAN_ERROR; + } + + if (logger.info.enabled()) { + fmt::memory_buffer str_buffer; + pdu_ul.to_string(str_buffer); + logger.info("Rx PDU: rnti=0x%x, %s", rnti, srsran::to_c_str(str_buffer)); + } + + // Process MAC CRNTI CE first, if it exists + uint32_t crnti_ce_pos = pdu_ul.get_num_subpdus(); + for (uint32_t n = pdu_ul.get_num_subpdus(); n > 0; --n) { + srsran::mac_sch_subpdu_nr& subpdu = pdu_ul.get_subpdu(n - 1); + if (subpdu.get_lcid() == srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CRNTI) { + if (process_ce_subpdu(rnti, subpdu) != SRSRAN_SUCCESS) { + return SRSRAN_ERROR; + } + crnti_ce_pos = n - 1; + } + } + + // Process SDUs and remaining MAC CEs + for (uint32_t n = 0; n < pdu_ul.get_num_subpdus(); ++n) { + srsran::mac_sch_subpdu_nr& subpdu = pdu_ul.get_subpdu(n); + if (subpdu.is_sdu()) { + rrc->set_activity_user(rnti); + rlc->write_pdu(rnti, subpdu.get_lcid(), subpdu.get_sdu(), subpdu.get_sdu_length()); + } else if (n != crnti_ce_pos) { + if (process_ce_subpdu(rnti, subpdu) != SRSRAN_SUCCESS) { + return SRSRAN_ERROR; + } + } + } + + return SRSRAN_SUCCESS; + } + + int process_ce_subpdu(uint16_t& rnti, const srsran::mac_sch_subpdu_nr& subpdu) + { + // Handle MAC CEs + switch (subpdu.get_lcid()) { + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CCCH_SIZE_48: + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CCCH_SIZE_64: { + srsran::mac_sch_subpdu_nr& ccch_subpdu = const_cast(subpdu); + rlc->write_pdu(rnti, 0, ccch_subpdu.get_sdu(), ccch_subpdu.get_sdu_length()); + // store content for ConRes CE and schedule CE accordingly + mac.store_msg3(rnti, + srsran::make_byte_buffer(ccch_subpdu.get_sdu(), ccch_subpdu.get_sdu_length(), __FUNCTION__)); + sched->dl_mac_ce(rnti, srsran::mac_sch_subpdu_nr::CON_RES_ID); + } break; + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CRNTI: { + uint16_t ce_crnti = subpdu.get_c_rnti(); + if (ce_crnti == SRSRAN_INVALID_RNTI) { + logger.error("Malformed C-RNTI CE detected. C-RNTI can't be 0x0.", subpdu.get_lcid()); + return SRSRAN_ERROR; + } + uint16_t prev_rnti = rnti; + rnti = ce_crnti; + rrc->update_user(prev_rnti, rnti); + sched->ul_sr_info(rnti); // provide UL grant regardless of other BSR content for UE to complete RA + } break; + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::SHORT_BSR: + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::SHORT_TRUNC_BSR: { + srsran::mac_sch_subpdu_nr::lcg_bsr_t sbsr = subpdu.get_sbsr(); + uint32_t buffer_size_bytes = buff_size_field_to_bytes(sbsr.buffer_size, srsran::SHORT_BSR); + // Assume all LCGs are 0 if reported SBSR is 0 + if (buffer_size_bytes == 0) { + for (uint32_t j = 0; j <= SCHED_NR_MAX_LC_GROUP; j++) { + sched->ul_bsr(rnti, j, 0); + } + } else { + sched->ul_bsr(rnti, sbsr.lcg_id, buffer_size_bytes); + } + } break; + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_BSR: + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_TRUNC_BSR: { + srsran::mac_sch_subpdu_nr::lbsr_t lbsr = subpdu.get_lbsr(); + for (auto& lb : lbsr.list) { + sched->ul_bsr(rnti, lb.lcg_id, buff_size_field_to_bytes(lb.buffer_size, srsran::LONG_BSR)); + } + } break; + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::SE_PHR: + // SE_PHR not implemented + break; + case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::PADDING: + break; + default: + logger.warning("Unhandled subPDU with LCID=%d", subpdu.get_lcid()); + } + + return SRSRAN_SUCCESS; + } + + /** Converts the buffer size field of a BSR (5 or 8-bit Buffer Size field) into Bytes + * @param buff_size_field The buffer size field contained in the MAC PDU + * @param format The BSR format that determines the buffer size field length + * @return uint32_t The actual buffer size level in Bytes + */ + static uint32_t buff_size_field_to_bytes(uint32_t buff_size_index, const srsran::bsr_format_nr_t& format) + { + using namespace srsran; + + // early exit + if (buff_size_index == 0) { + return 0; + } + + const uint32_t max_offset = 1; // make the reported value bigger than the 2nd biggest + + switch (format) { + case SHORT_BSR: + case SHORT_TRUNC_BSR: + if (buff_size_index >= buffer_size_levels_5bit_max_idx) { + return buffer_size_levels_5bit[buffer_size_levels_5bit_max_idx] + max_offset; + } else { + return buffer_size_levels_5bit[buff_size_index]; + } + break; + case LONG_BSR: + case LONG_TRUNC_BSR: + if (buff_size_index > buffer_size_levels_8bit_max_idx) { + return buffer_size_levels_8bit[buffer_size_levels_8bit_max_idx] + max_offset; + } else { + return buffer_size_levels_8bit[buff_size_index]; + } + break; + default: + break; + } + return 0; + } + + rlc_interface_mac* rlc; + rrc_interface_mac_nr* rrc; + sched_nr_interface* sched; + mac_interface_pdu_demux_nr& mac; + srslog::basic_logger& logger; + srsran::task_queue_handle& task_queue; + + srsran::mac_sch_pdu_nr pdu_ul; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + mac_nr::mac_nr(srsran::task_sched_handle task_sched_) : logger(srslog::fetch_basic_logger("MAC-NR")), task_sched(task_sched_), bcch_bch_payload(srsran::make_byte_buffer()), - rar_pdu_buffer(srsran::make_byte_buffer()) + rar_pdu_buffer(srsran::make_byte_buffer()), + sched(new sched_nr{}) { stack_task_queue = task_sched.make_task_queue(); } @@ -76,12 +254,12 @@ int mac_nr::init(const mac_nr_args_t& args_, void mac_nr::stop() { - if (started) { + bool started_prev = started.exchange(false); + if (started_prev) { + sched->stop(); if (pcap != nullptr) { pcap->close(); } - - started = false; } } @@ -93,7 +271,7 @@ void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) // TODO: We should comment on the logic we follow to get the metrics. Some of them are retrieved from MAC, some // others from the scheduler. get_metrics_nolock(metrics); - sched.get_metrics(metrics); + sched->get_metrics(metrics); } void mac_nr::get_metrics_nolock(srsenb::mac_metrics_t& metrics) @@ -107,43 +285,44 @@ void mac_nr::get_metrics_nolock(srsenb::mac_metrics_t& metrics) metrics.cc_info.resize(detected_rachs.size()); for (unsigned cc = 0, e = detected_rachs.size(); cc != e; ++cc) { metrics.cc_info[cc].cc_rach_counter = detected_rachs[cc]; - metrics.cc_info[cc].pci = (cc < cell_config.size()) ? cell_config[cc].carrier.pci : 0; + metrics.cc_info[cc].pci = (cc < cell_config.size()) ? cell_config[cc].pci : 0; } } -int mac_nr::cell_cfg(const std::vector& nr_cells) +int mac_nr::cell_cfg(const std::vector& nr_cells) { cell_config = nr_cells; - sched.config(args.sched_cfg, nr_cells); + sched->config(args.sched_cfg, nr_cells); detected_rachs.resize(nr_cells.size()); // read SIBs from RRC (SIB1 for now only) - for (int i = 0; i < 1 /* srsenb::sched_interface::MAX_SIBS */; i++) { - // TODO: add flag for SIBs into cell config - if (true) { - sib_info_t sib = {}; - sib.index = i; - sib.periodicity = 4; // TODO: read period_rf from config - sib.payload = srsran::make_byte_buffer(); - if (sib.payload == nullptr) { - logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); - return SRSRAN_ERROR; - } - if (rrc->read_pdu_bcch_dlsch(sib.index, sib.payload) != SRSRAN_SUCCESS) { - logger.error("Couldn't read SIB %d from RRC", sib.index); - } - - logger.info("Including SIB %d into SI scheduling", sib.index); - bcch_dlsch_payload.push_back(std::move(sib)); + for (uint32_t i = 0; i < nr_cells[0].sibs.size(); i++) { + sib_info_t sib = {}; + sib.index = i; + sib.periodicity = 160; // TODO: read period_rf from config + sib.payload = srsran::make_byte_buffer(); + if (sib.payload == nullptr) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + if (rrc->read_pdu_bcch_dlsch(sib.index, *sib.payload) != SRSRAN_SUCCESS) { + logger.error("Couldn't read SIB %d from RRC", sib.index); } + + logger.info("Including SIB %d into SI scheduling", sib.index + 1); + bcch_dlsch_payload.push_back(std::move(sib)); } + rx.reset(new mac_nr_rx{rlc, rrc, stack_task_queue, sched.get(), *this, logger}); + + default_ue_phy_cfg = get_common_ue_phy_cfg(cell_config[0]); + return SRSRAN_SUCCESS; } int mac_nr::ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) { - sched.ue_cfg(rnti, ue_cfg); + sched->ue_cfg(rnti, ue_cfg); return SRSRAN_SUCCESS; } @@ -154,7 +333,7 @@ uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx, const sched_nr_ue_cfg_t& uecf return rnti; } - sched.ue_cfg(rnti, uecfg); + sched->ue_cfg(rnti, uecfg); return rnti; } @@ -169,33 +348,23 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) stack_task_queue.push([this, rach_info, enb_cc_idx, rach_tprof_meas]() mutable { rach_tprof_meas.defer_stop(); - // Add new user to the scheduler so that it can RX/TX SRB0 - sched_nr_ue_cfg_t uecfg = {}; - uecfg.carriers.resize(1); - uecfg.carriers[0].active = true; - uecfg.carriers[0].cc = 0; - uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; - srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{}; - ref_args.duplex = cell_config[0].duplex.mode == SRSRAN_DUPLEX_MODE_TDD - ? srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4 - : srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; - uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{ref_args}; - uecfg.phy_cfg.csi = {}; // disable CSI until RA is complete - - uint16_t rnti = reserve_rnti(enb_cc_idx, uecfg); + uint16_t rnti = alloc_ue(enb_cc_idx); // Log this event. - ++detected_rachs[enb_cc_idx]; + { + srsran::rwlock_write_guard lock(rwmutex); + ++detected_rachs[enb_cc_idx]; + } // Trigger scheduler RACH srsenb::sched_nr_interface::rar_info_t rar_info = {}; + rar_info.cc = enb_cc_idx; rar_info.preamble_idx = rach_info.preamble; rar_info.temp_crnti = rnti; rar_info.ta_cmd = rach_info.time_adv; rar_info.prach_slot = slot_point{NUMEROLOGY_IDX, rach_info.slot_index}; - // TODO: fill remaining fields as required - sched.dl_rach_info(enb_cc_idx, rar_info); - rrc->add_user(rnti, uecfg); + sched->dl_rach_info(rar_info); + rrc->add_user(rnti, enb_cc_idx); logger.info("RACH: slot=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x", rach_info.slot_index, @@ -230,7 +399,7 @@ uint16_t mac_nr::alloc_ue(uint32_t enb_cc_idx) } // Allocate and initialize UE object - std::unique_ptr ue_ptr = std::unique_ptr(new ue_nr(rnti, enb_cc_idx, &sched, rrc, rlc, phy, logger)); + std::unique_ptr ue_ptr(new ue_nr(rnti, enb_cc_idx, sched.get(), rrc, rlc, phy, logger)); // Add UE to rnti map srsran::rwlock_write_guard rw_lock(rwmutex); @@ -253,7 +422,7 @@ int mac_nr::remove_ue(uint16_t rnti) { srsran::rwlock_write_guard lock(rwmutex); if (is_rnti_active_nolock(rnti)) { - sched.ue_rem(rnti); + sched->ue_rem(rnti); ue_db.erase(rnti); } else { logger.error("User rnti=0x%x not found", rnti); @@ -291,13 +460,13 @@ bool mac_nr::is_rnti_active_nolock(uint16_t rnti) int mac_nr::rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) { - sched.dl_buffer_state(rnti, lc_id, tx_queue, retx_queue); + sched->dl_buffer_state(rnti, lc_id, tx_queue, retx_queue); return SRSRAN_SUCCESS; } void mac_nr::ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr) { - sched.ul_bsr(rnti, lcid, bsr); + sched->ul_bsr(rnti, lcid, bsr); } int mac_nr::slot_indication(const srsran_slot_cfg_t& slot_cfg) @@ -305,25 +474,35 @@ int mac_nr::slot_indication(const srsran_slot_cfg_t& slot_cfg) return 0; } -int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) +void mac_nr::store_msg3(uint16_t rnti, srsran::unique_byte_buffer_t pdu) +{ + srsran::rwlock_read_guard rw_lock(rwmutex); + if (is_rnti_active_nolock(rnti)) { + ue_db[rnti]->store_msg3(std::move(pdu)); + } else { + logger.error("User rnti=0x%x not found. Can't store Msg3.", rnti); + } +} + +mac_nr::dl_sched_t* mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg) { slot_point pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; logger.set_context((pdsch_slot - TX_ENB_DELAY).to_uint()); - // Run Scheduler - sched_nr_interface::sched_rar_list_t rar_list; - sched_nr_interface::dl_res_t dl_res(rar_list, dl_sched); + // Initiate new slot and sync UE internal states + sched->slot_indication(pdsch_slot); - int ret = sched.run_slot(pdsch_slot, 0, dl_res); - if (ret != SRSRAN_SUCCESS) { - return ret; + // Run DL Scheduler for CC + sched_nr::dl_res_t* dl_res = sched->get_dl_sched(pdsch_slot, 0); + if (dl_res == nullptr) { + return nullptr; } // Generate MAC DL PDUs - uint32_t rar_count = 0; + uint32_t rar_count = 0, si_count = 0, data_count = 0; srsran::rwlock_read_guard rw_lock(rwmutex); - for (pdsch_t& pdsch : dl_sched.pdsch) { + for (pdsch_t& pdsch : dl_res->phy.pdsch) { if (pdsch.sch.grant.rnti_type == srsran_rnti_type_c) { uint16_t rnti = pdsch.sch.grant.rnti; if (not is_rnti_active_nolock(rnti)) { @@ -332,7 +511,8 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched for (auto& tb_data : pdsch.data) { if (tb_data != nullptr and tb_data->N_bytes == 0) { // TODO: exclude retx from packing - ue_db[rnti]->generate_pdu(tb_data, pdsch.sch.grant.tb->tbs / 8); + const sched_nr_interface::dl_pdu_t& pdu = dl_res->data[data_count++]; + ue_db[rnti]->generate_pdu(tb_data, pdsch.sch.grant.tb->tbs / 8, pdu.subpdus); if (pcap != nullptr) { uint32_t pid = 0; // TODO: get PID from PDCCH struct? @@ -342,31 +522,42 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched } } } else if (pdsch.sch.grant.rnti_type == srsran_rnti_type_ra) { - sched_nr_interface::rar_t& rar = dl_res.rar[rar_count++]; + sched_nr_interface::rar_t& rar = dl_res->rar[rar_count++]; // for RARs we could actually move the byte_buffer to the PHY, as there are no retx pdsch.data[0] = assemble_rar(rar.grants); + } else if (pdsch.sch.grant.rnti_type == srsran_rnti_type_si) { + uint32_t sib_idx = dl_res->sib_idxs[si_count++]; + pdsch.data[0] = bcch_dlsch_payload[sib_idx].payload.get(); +#ifdef WRITE_SIB_PCAP + if (pcap != nullptr) { + pcap->write_dl_si_rnti_nr(bcch_dlsch_payload[sib_idx].payload->msg, + bcch_dlsch_payload[sib_idx].payload->N_bytes, + SI_RNTI, + 0, + slot_cfg.idx); + } +#endif } } for (auto& u : ue_db) { u.second->metrics_cnt(); } - return SRSRAN_SUCCESS; + + return &dl_res->phy; } -int mac_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) +mac_nr::ul_sched_t* mac_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg) { - int ret = 0; - - slot_point pusch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; - ret = sched.get_ul_sched(pusch_slot, 0, ul_sched); + slot_point pusch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; + ul_sched_t* ul_sched = sched->get_ul_sched(pusch_slot, 0); srsran::rwlock_read_guard rw_lock(rwmutex); - for (auto& pusch : ul_sched.pusch) { + for (auto& pusch : ul_sched->pusch) { if (ue_db.contains(pusch.sch.grant.rnti)) { ue_db[pusch.sch.grant.rnti]->metrics_ul_mcs(pusch.sch.grant.tb->mcs); } } - return ret; + return ul_sched; } int mac_nr::pucch_info(const srsran_slot_cfg_t& slot_cfg, const mac_interface_phy_nr::pucch_info_t& pucch_info) @@ -386,13 +577,13 @@ int mac_nr::pucch_info(const srsran_slot_cfg_t& slot_cfg, const mac_interface_ph return SRSRAN_SUCCESS; } -bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg_, const srsran_uci_value_nr_t& value) +bool mac_nr::handle_uci_data(uint16_t rnti, const srsran_uci_cfg_nr_t& cfg_, const srsran_uci_value_nr_t& value) { // Process HARQ-ACK for (uint32_t i = 0; i < cfg_.ack.count; i++) { const srsran_harq_ack_bit_t* ack_bit = &cfg_.ack.bits[i]; bool is_ok = (value.ack[i] == 1) and value.valid; - sched.dl_ack_info(rnti, 0, ack_bit->pid, 0, is_ok); + sched->dl_ack_info(rnti, 0, ack_bit->pid, 0, is_ok); srsran::rwlock_read_guard rw_lock(rwmutex); if (ue_db.contains(rnti)) { ue_db[rnti]->metrics_tx(is_ok, 0 /*TODO get size of packet from scheduler somehow*/); @@ -401,11 +592,21 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg // Process SR if (value.valid and value.sr > 0) { - sched.ul_sr_info(cfg_.pucch.rnti); + sched->ul_sr_info(cfg_.pucch.rnti); } // Process CQI - { + for (uint32_t i = 0; i < cfg_.nof_csi; i++) { + // Skip if invalid or not supported CSI report + if (not value.valid or cfg_.csi[i].cfg.quantity != SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI or + cfg_.csi[i].cfg.freq_cfg != SRSRAN_CSI_REPORT_FREQ_WIDEBAND or value.csi[i].wideband_cri_ri_pmi_cqi.cqi == 0) { + continue; + } + + // 1. Pass CQI report to scheduler + sched->dl_cqi_info(rnti, 0, value.csi->wideband_cri_ri_pmi_cqi.cqi); + + // 2. Save CQI report for metrics stats srsran::rwlock_read_guard rw_lock(rwmutex); if (ue_db.contains(rnti) && value.valid) { ue_db[rnti]->metrics_dl_cqi(cfg_, value.csi->wideband_cri_ri_pmi_cqi.cqi); @@ -426,7 +627,7 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: return SRSRAN_ERROR; } - sched.ul_crc_info(rnti, 0, pusch_info.pid, pusch_info.pusch_data.tb[0].crc); + sched->ul_crc_info(rnti, 0, pusch_info.pid, pusch_info.pusch_data.tb[0].crc); // process only PDUs with CRC=OK if (pusch_info.pusch_data.tb[0].crc) { @@ -435,15 +636,8 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: pusch_info.pdu->msg, pusch_info.pdu->N_bytes, pusch_info.rnti, pusch_info.pid, slot_cfg.idx); } - auto process_pdu_task = [this, rnti](srsran::unique_byte_buffer_t& pdu) { - srsran::rwlock_read_guard lock(rwmutex); - if (is_rnti_active_nolock(rnti)) { - ue_db[rnti]->process_pdu(std::move(pdu)); - } else { - logger.debug("Discarding PDU rnti=0x%x", rnti); - } - }; - stack_task_queue.try_push(std::bind(process_pdu_task, std::move(pusch_info.pdu))); + // Decode and send PDU to upper layers + rx->handle_pdu(rnti, std::move(pusch_info.pdu)); } srsran::rwlock_read_guard rw_lock(rwmutex); if (ue_db.contains(rnti)) { @@ -457,7 +651,7 @@ srsran::byte_buffer_t* mac_nr::assemble_rar(srsran::const_span 0) { + if (cc < 0) { + sched_logger.debug("SCHED: slot events: [%s]", srsran::to_c_str(event_fmtbuf)); + } else { + sched_logger.debug("SCHED: slot events, cc=%d: [%s]", cc, srsran::to_c_str(event_fmtbuf)); + } + } + } + + template + void push(const char* fmt, Args&&... args) + { + if (log_enabled) { + if (event_fmtbuf.size() > 0) { + fmt::format_to(event_fmtbuf, ", "); + } + fmt::format_to(event_fmtbuf, fmt, std::forward(args)...); + } + } + + private: + bool log_enabled; + int cc; + srslog::basic_logger& sched_logger; + fmt::memory_buffer event_fmtbuf; + }; + + explicit event_manager(sched_params_t& params) : + sched_logger(srslog::fetch_basic_logger(params.sched_cfg.logger_name)), carriers(params.cells.size()) + { + } + + /// Enqueue an event that does not map into a ue method (e.g. rem_user, add_user) + void enqueue_event(const char* event_name, srsran::move_callback ev) + { + std::lock_guard lock(event_mutex); + next_slot_events.emplace_back(event_name, std::move(ev)); + } + + /// Enqueue an event that directly maps into a ue method (e.g. ul_sr_info, ul_bsr, etc.) + /// Note: these events can be processed sequentially or in parallel, depending on whether the UE supports CA + void enqueue_ue_event(const char* event_name, uint16_t rnti, srsran::move_callback callback) + { + srsran_assert(rnti != SRSRAN_INVALID_RNTI, "Invalid rnti=0x%x passed to common event manager", rnti); + std::lock_guard lock(event_mutex); + next_slot_ue_events.emplace_back(rnti, event_name, std::move(callback)); + } + + /// Enqueue feedback directed at a given UE in a given cell (e.g. ACKs, CQI) + void enqueue_ue_cc_feedback(const char* event_name, + uint16_t rnti, + uint32_t cc, + srsran::move_callback callback) + { + srsran_assert(rnti != SRSRAN_INVALID_RNTI, "Invalid rnti=0x%x passed to event manager", rnti); + srsran_assert(cc < carriers.size(), "Invalid cc=%d passed to event manager", cc); + std::lock_guard lock(carriers[cc].event_cc_mutex); + carriers[cc].next_slot_ue_events.emplace_back(rnti, cc, event_name, std::move(callback)); + } + + /// Process all events that are not specific to a carrier or that are directed at CA-enabled UEs + /// Note: non-CA UEs are updated later in get_dl_sched, to leverage parallelism + void process_common(ue_map_t& ues) + { + // Extract pending feedback events + current_slot_ue_events.clear(); + current_slot_events.clear(); + { + std::lock_guard ev_lock(event_mutex); + next_slot_ue_events.swap(current_slot_ue_events); + next_slot_events.swap(current_slot_events); + } + + logger evlogger(-1, sched_logger); + + // non-UE specific events + for (event_t& ev : current_slot_events) { + ev.callback(evlogger); + } + + for (ue_event_t& ev : current_slot_ue_events) { + auto ue_it = ues.find(ev.rnti); + if (ue_it == ues.end()) { + sched_logger.warning("SCHED: \"%s\" called for unknown rnti=0x%x.", ev.event_name, ev.rnti); + ev.rnti = SRSRAN_INVALID_RNTI; + } else if (ue_it->second->has_ca()) { + // events specific to existing UEs with CA + ev.callback(*ue_it->second, evlogger); + ev.rnti = SRSRAN_INVALID_RNTI; + } + } + } + + /// Process events synchronized during slot_indication() that are directed at non CA-enabled UEs + void process_cc_events(ue_map_t& ues, uint32_t cc) + { + logger evlogger(cc, sched_logger); + + { + carriers[cc].current_slot_ue_events.clear(); + std::lock_guard lock(carriers[cc].event_cc_mutex); + carriers[cc].current_slot_ue_events.swap(carriers[cc].next_slot_ue_events); + } + + for (ue_event_t& ev : current_slot_ue_events) { + if (ev.rnti == SRSRAN_INVALID_RNTI) { + // events already processed + continue; + } + auto ue_it = ues.find(ev.rnti); + if (ue_it == ues.end()) { + sched_logger.warning("SCHED: \"%s\" called for unknown rnti=0x%x.", ev.event_name, ev.rnti); + ev.rnti = SRSRAN_INVALID_RNTI; + } else if (not ue_it->second->has_ca() and ue_it->second->carriers[cc] != nullptr) { + ev.callback(*ue_it->second, evlogger); + ev.rnti = SRSRAN_INVALID_RNTI; + } + } + + for (ue_cc_event_t& ev : carriers[cc].current_slot_ue_events) { + auto ue_it = ues.find(ev.rnti); + if (ue_it != ues.end() and ue_it->second->carriers[cc] != nullptr) { + ev.callback(*ue_it->second->carriers[cc], evlogger); + } else { + sched_logger.warning("SCHED: \"%s\" called for unknown rnti=0x%x,cc=%d.", ev.event_name, ev.rnti, ev.cc); + } + } + } + +private: + struct event_t { + const char* event_name; + srsran::move_callback callback; + event_t(const char* event_name_, srsran::move_callback c) : + event_name(event_name_), callback(std::move(c)) + { + } + }; + struct ue_event_t { + uint16_t rnti; + const char* event_name; + srsran::move_callback callback; + ue_event_t(uint16_t rnti_, const char* event_name_, srsran::move_callback c) : + rnti(rnti_), event_name(event_name_), callback(std::move(c)) + { + } + }; + struct ue_cc_event_t { + uint16_t rnti; + uint32_t cc; + const char* event_name; + srsran::move_callback callback; + ue_cc_event_t(uint16_t rnti_, + uint32_t cc_, + const char* event_name_, + srsran::move_callback c) : + rnti(rnti_), cc(cc_), event_name(event_name_), callback(std::move(c)) + { + } + }; + + srslog::basic_logger& sched_logger; + + std::mutex event_mutex; + std::deque next_slot_events, current_slot_events; + std::deque next_slot_ue_events, current_slot_ue_events; + struct cc_events { + std::mutex event_cc_mutex; + srsran::deque next_slot_ue_events, current_slot_ue_events; + }; + std::vector carriers; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class sched_nr::ue_metrics_manager +{ +public: + explicit ue_metrics_manager(ue_map_t& ues_) : ues(ues_) {} + + void stop() + { + std::unique_lock lock(mutex); + if (not stopped) { + stopped = true; + // requests during sched::stop may not be fulfilled by sched main thread + save_metrics_nolock(); + } + } + + /// Blocking call that waits for the metrics to be filled + void get_metrics(mac_metrics_t& requested_metrics) + { + std::unique_lock lock(mutex); + pending_metrics = &requested_metrics; + if (not stopped) { + cvar.wait(lock, [this]() { return pending_metrics == nullptr; }); + } else { + save_metrics_nolock(); + } + } + + /// called from within the scheduler main thread to save metrics + void save_metrics() + { + { + std::unique_lock lock(mutex); + save_metrics_nolock(); + } + cvar.notify_one(); + } + +private: + void save_metrics_nolock() + { + if (pending_metrics == nullptr) { + return; + } + for (mac_ue_metrics_t& ue_metric : pending_metrics->ues) { + if (ues.contains(ue_metric.rnti) and ues[ue_metric.rnti]->carriers[0] != nullptr) { + auto& ue_cc = *ues[ue_metric.rnti]->carriers[0]; + ue_metric.tx_brate = ue_cc.metrics.tx_brate; + ue_metric.tx_errors = ue_cc.metrics.tx_errors; + ue_metric.tx_pkts = ue_cc.metrics.tx_pkts; + ue_cc.metrics = {}; + } + } + pending_metrics = nullptr; + } + + ue_map_t& ues; + + std::mutex mutex; + std::condition_variable cvar; + mac_metrics_t* pending_metrics = nullptr; + bool stopped = false; +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +sched_nr::sched_nr() : logger(&srslog::fetch_basic_logger("MAC-NR")), metrics_handler(new ue_metrics_manager{ue_db}) {} + +sched_nr::~sched_nr() +{ + stop(); +} + +void sched_nr::stop() +{ + metrics_handler->stop(); +} + +int sched_nr::config(const sched_args_t& sched_cfg, srsran::const_span cell_list) +{ + cfg = sched_params_t{sched_cfg}; + logger = &srslog::fetch_basic_logger(sched_cfg.logger_name); + + // Initiate UE memory pool + ue_pool.reset(new srsran::circular_stack_pool(8, sizeof(ue), 4)); + + // Initiate Common Sched Configuration + cfg.cells.reserve(cell_list.size()); + for (uint32_t cc = 0; cc < cell_list.size(); ++cc) { + cfg.cells.emplace_back(cc, cell_list[cc], cfg.sched_cfg); + } + + pending_events.reset(new event_manager{cfg}); + + // Initiate cell-specific schedulers + cc_workers.resize(cfg.cells.size()); + for (uint32_t cc = 0; cc < cfg.cells.size(); ++cc) { + cc_workers[cc].reset(new slot_cc_worker{cfg.cells[cc]}); + } + + return SRSRAN_SUCCESS; +} + +void sched_nr::ue_cfg(uint16_t rnti, const ue_cfg_t& uecfg) +{ + srsran_assert(assert_ue_cfg_valid(rnti, uecfg) == SRSRAN_SUCCESS, "Invalid UE configuration"); + pending_events->enqueue_event("ue_cfg", [this, rnti, uecfg](event_manager::logger& ev_logger) { + if (ue_cfg_impl(rnti, uecfg) == SRSRAN_SUCCESS) { + ev_logger.push("ue_cfg(0x{:x})", rnti); + } else { + logger->warning("Failed to create UE object for rnti=0x{:x}", rnti); + } + }); +} + +void sched_nr::ue_rem(uint16_t rnti) +{ + pending_events->enqueue_event("ue_rem", [this, rnti](event_manager::logger& ev_logger) { + ue_db.erase(rnti); + logger->info("SCHED: Removed user rnti=0x%x", rnti); + ev_logger.push("ue_rem(0x{:x})", rnti); + }); +} + +int sched_nr::add_ue_impl(uint16_t rnti, sched_nr_impl::unique_ue_ptr u) +{ + logger->info("SCHED: New user rnti=0x%x, cc=%d", rnti, cfg.cells[0].cc); + return ue_db.insert(rnti, std::move(u)).has_value() ? SRSRAN_SUCCESS : SRSRAN_ERROR; +} + +int sched_nr::ue_cfg_impl(uint16_t rnti, const ue_cfg_t& uecfg) +{ + if (not ue_db.contains(rnti)) { + // create user object + unique_ue_ptr u = srsran::make_pool_obj_with_fallback(*ue_pool, rnti, rnti, uecfg, cfg); + return add_ue_impl(rnti, std::make_unique(rnti, uecfg, cfg)); + } + ue_db[rnti]->set_cfg(uecfg); + return SRSRAN_SUCCESS; +} + +// NOTE: there is no parallelism in these operations +void sched_nr::slot_indication(slot_point slot_tx) +{ + srsran_assert(worker_count.load(std::memory_order_relaxed) == 0, + "Call of sched slot_indication when previous TTI has not been completed"); + // mark the start of slot. + current_slot_tx = slot_tx; + worker_count.store(static_cast(cfg.cells.size()), std::memory_order_relaxed); + + // process non-cc specific feedback if pending (e.g. SRs, buffer state updates, UE config) for CA-enabled UEs + // Note: non-CA UEs are updated later in get_dl_sched, to leverage parallelism + pending_events->process_common(ue_db); + + // prepare CA-enabled UEs internal state for new slot + // Note: non-CA UEs are updated later in get_dl_sched, to leverage parallelism + for (auto& u : ue_db) { + if (u.second->has_ca()) { + u.second->new_slot(slot_tx); + } + } + + // If UE metrics were externally requested, store the current UE state + metrics_handler->save_metrics(); +} + +/// Generate {pdcch_slot,cc} scheduling decision +sched_nr::dl_res_t* sched_nr::get_dl_sched(slot_point pdsch_tti, uint32_t cc) +{ + srsran_assert(pdsch_tti == current_slot_tx, "Unexpected pdsch_tti slot received"); + + // process non-cc specific feedback if pending (e.g. SRs, buffer state updates, UE config) for non-CA UEs + pending_events->process_cc_events(ue_db, cc); + + // prepare non-CA UEs internal state for new slot + for (auto& u : ue_db) { + if (not u.second->has_ca() and u.second->carriers[cc] != nullptr) { + u.second->new_slot(current_slot_tx); + } + } + + // Process pending CC-specific feedback, generate {slot_idx,cc} scheduling decision + sched_nr::dl_res_t* ret = cc_workers[cc]->run_slot(pdsch_tti, ue_db); + + // decrement the number of active workers + int rem_workers = worker_count.fetch_sub(1, std::memory_order_release) - 1; + srsran_assert(rem_workers >= 0, "invalid number of calls to get_dl_sched(slot, cc)"); + if (rem_workers == 0) { + // Last Worker to finish slot + // TODO: Sync sched results with ue_db state + } + + return ret; +} + +/// Fetch {ul_slot,cc} UL scheduling decision +sched_nr::ul_res_t* sched_nr::get_ul_sched(slot_point slot_ul, uint32_t cc) +{ + return cc_workers[cc]->get_ul_sched(slot_ul); +} + +void sched_nr::get_metrics(mac_metrics_t& metrics) +{ + metrics_handler->get_metrics(metrics); +} + +int sched_nr::dl_rach_info(const rar_info_t& rar_info) +{ + // create user object outside of sched main thread + unique_ue_ptr u = + srsran::make_pool_obj_with_fallback(*ue_pool, rar_info.temp_crnti, rar_info.temp_crnti, rar_info.cc, cfg); + + // enqueue UE creation event + RACH handling + auto add_ue = [this, rar_info, u = std::move(u)](event_manager::logger& ev_logger) mutable { + uint16_t rnti = rar_info.temp_crnti; + if (add_ue_impl(rnti, std::move(u)) == SRSRAN_SUCCESS) { + ev_logger.push("dl_rach_info(temp c-rnti=0x{:x})", rar_info.temp_crnti); + // RACH is handled only once the UE object is created and inserted in the ue_db + uint32_t cc = rar_info.cc; + cc_workers[cc]->dl_rach_info(rar_info); + } else { + logger->warning("Failed to create UE object with rnti=0x%x", rar_info.temp_crnti); + } + }; + pending_events->enqueue_event("dl_rach_info", std::move(add_ue)); + return SRSRAN_SUCCESS; +} + +void sched_nr::dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) +{ + auto callback = [pid, tb_idx, ack](ue_carrier& ue_cc, event_manager::logger& ev_logger) { + if (ue_cc.dl_ack_info(pid, tb_idx, ack) >= 0) { + ev_logger.push("0x{:x}: dl_ack_info(pid={}, ack={})", ue_cc.rnti, pid, ack ? "OK" : "KO"); + } + }; + pending_events->enqueue_ue_cc_feedback("dl_ack_info", rnti, cc, callback); +} + +void sched_nr::ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) +{ + auto callback = [pid, crc](ue_carrier& ue_cc, event_manager::logger& ev_logger) { + if (ue_cc.ul_crc_info(pid, crc) >= 0) { + ev_logger.push("0x{:x}: ul_crc_info(pid={}, crc={})", ue_cc.rnti, pid, crc ? "OK" : "KO"); + } + }; + pending_events->enqueue_ue_cc_feedback("ul_crc_info", rnti, cc, callback); +} + +void sched_nr::ul_sr_info(uint16_t rnti) +{ + pending_events->enqueue_ue_event("ul_sr_info", rnti, [](ue& u, event_manager::logger& evlogger) { + u.ul_sr_info(); + evlogger.push("0x{:x}: ul_sr_info()", u.rnti); + }); +} + +void sched_nr::ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) +{ + pending_events->enqueue_ue_event("ul_bsr", rnti, [lcg_id, bsr](ue& u, event_manager::logger& evlogger) { + u.ul_bsr(lcg_id, bsr); + evlogger.push("0x{:x}: ul_bsr(lcg={}, bsr={})", u.rnti, lcg_id, bsr); + }); +} + +void sched_nr::dl_mac_ce(uint16_t rnti, uint32_t ce_lcid) +{ + pending_events->enqueue_ue_event("dl_mac_ce", rnti, [ce_lcid](ue& u, event_manager::logger& event_logger) { + // CE is added to list of pending CE + u.add_dl_mac_ce(ce_lcid, 1); + event_logger.push("0x{:x}: dl_mac_ce(lcid={})", u.rnti, ce_lcid); + }); +} + +void sched_nr::dl_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t newtx, uint32_t retx) +{ + pending_events->enqueue_ue_event( + "dl_buffer_state", rnti, [lcid, newtx, retx](ue& u, event_manager::logger& event_logger) { + u.rlc_buffer_state(lcid, newtx, retx); + event_logger.push("0x{:x}: dl_buffer_state(lcid={}, bsr={},{})", u.rnti, lcid, newtx, retx); + }); +} + +void sched_nr::dl_cqi_info(uint16_t rnti, uint32_t cc, uint32_t cqi_value) +{ + auto callback = [cqi_value](ue_carrier& ue_cc, event_manager::logger& ev_logger) { + ue_cc.dl_cqi = cqi_value; + ev_logger.push("0x{:x}: dl_cqi_info(cqi={})", ue_cc.rnti, ue_cc.dl_cqi); + }; + pending_events->enqueue_ue_cc_feedback("dl_cqi_info", rnti, cc, callback); +} + +#define VERIFY_INPUT(cond, msg, ...) \ + do { \ + if (not(cond)) { \ + srslog::fetch_basic_logger("MAC").warning(msg, ##__VA_ARGS__); \ + return SRSRAN_ERROR; \ + } \ + } while (0) + +int assert_ue_cfg_valid(uint16_t rnti, const sched_nr_interface::ue_cfg_t& uecfg) +{ + VERIFY_INPUT(std::count(&uecfg.phy_cfg.pdcch.coreset_present[0], + &uecfg.phy_cfg.pdcch.coreset_present[SRSRAN_UE_DL_NR_MAX_NOF_CORESET], + true) > 0, + "Provided rnti=0x%x configuration does not contain any coreset", + rnti); + return SRSRAN_SUCCESS; +} + +} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_cell.cc b/srsgnb/src/stack/mac/sched_nr_bwp.cc similarity index 66% rename from srsenb/src/stack/mac/nr/sched_nr_cell.cc rename to srsgnb/src/stack/mac/sched_nr_bwp.cc index e1a849e05f..4fe95eb14c 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cell.cc +++ b/srsgnb/src/stack/mac/sched_nr_bwp.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,73 +19,13 @@ * */ -#include "srsenb/hdr/stack/mac/nr/sched_nr_cell.h" +#include "srsgnb/hdr/stack/mac/sched_nr_bwp.h" #include "srsran/common/standard_streams.h" #include "srsran/common/string_helpers.h" namespace srsenb { namespace sched_nr_impl { -si_sched::si_sched(const bwp_params_t& bwp_cfg_) : - bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger(bwp_cfg_.sched_cfg.logger_name)) -{} - -void si_sched::run_slot(bwp_slot_allocator& slot_alloc) -{ - const uint32_t si_aggr_level = 2; - slot_point pdcch_slot = slot_alloc.get_pdcch_tti(); - const prb_bitmap& prbs = slot_alloc.res_grid()[pdcch_slot].dl_prbs.prbs(); - - // Update SI windows - uint32_t N = bwp_cfg->slots.size(); - for (sched_si_t& si : pending_sis) { - uint32_t x = (si.n - 1) * si.win_len; - - if (not si.win_start.valid() and (pdcch_slot.sfn() % si.period == x / N) and - pdcch_slot.slot_idx() == x % bwp_cfg->slots.size()) { - // If start o SI message window - si.win_start = pdcch_slot; - } else if (si.win_start.valid() and si.win_start + si.win_len >= pdcch_slot) { - // If end of SI message window - logger.warning( - "SCHED: Could not allocate SI message idx=%d, len=%d. Cause: %s", si.n, si.len, to_string(si.result)); - si.win_start.clear(); - } - } - - // Schedule pending SIs - if (bwp_cfg->slots[pdcch_slot.slot_idx()].is_dl) { - for (sched_si_t& si : pending_sis) { - if (not si.win_start.valid()) { - continue; - } - - // TODO: NOTE 2: The UE is not required to monitor PDCCH monitoring occasion(s) corresponding to each transmitted - // SSB in SI-window. - - // Attempt grants with increasing number of PRBs (if the number of PRBs is too low, the coderate is invalid) - si.result = alloc_result::invalid_coderate; - uint32_t prb_start_idx = 0; - for (uint32_t nprbs = 4; nprbs < bwp_cfg->cfg.rb_width and si.result == alloc_result::invalid_coderate; ++nprbs) { - prb_interval grant = find_empty_interval_of_length(prbs, nprbs, prb_start_idx); - prb_start_idx = grant.start(); - if (grant.length() != nprbs) { - si.result = alloc_result::no_sch_space; - break; - } - si.result = slot_alloc.alloc_si(si_aggr_level, si.n, si.n_tx, grant); - if (si.result == alloc_result::success) { - // SIB scheduled successfully - si.win_start.clear(); - si.n_tx++; - } - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - ra_sched::ra_sched(const bwp_params_t& bwp_cfg_) : bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger(bwp_cfg_.sched_cfg.logger_name)) {} @@ -93,8 +33,9 @@ ra_sched::ra_sched(const bwp_params_t& bwp_cfg_) : alloc_result ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_t& rar, uint32_t& nof_grants_alloc) { - const uint32_t rar_aggr_level = 2; - const prb_bitmap& prbs = slot_grid.res_grid()[slot_grid.get_pdcch_tti()].dl_prbs.prbs(); + const uint32_t rar_aggr_level = 2; + prb_bitmap prbs = slot_grid.res_grid()[slot_grid.get_pdcch_tti()].pdschs.occupied_prbs( + bwp_cfg->cfg.pdcch.ra_search_space.id, srsran_dci_format_nr_1_0); alloc_result ret = alloc_result::other_cause; srsran::const_span msg3_grants{rar.msg3_grant}; @@ -229,22 +170,9 @@ int ra_sched::dl_rach_info(const dl_sched_rar_info_t& rar_info) return SRSRAN_SUCCESS; } -bwp_ctxt::bwp_ctxt(const bwp_params_t& bwp_cfg) : - cfg(&bwp_cfg), ra(bwp_cfg), grid(bwp_cfg), data_sched(new sched_nr_time_rr()) +bwp_manager::bwp_manager(const bwp_params_t& bwp_cfg) : + cfg(&bwp_cfg), ra(bwp_cfg), si(bwp_cfg), grid(bwp_cfg), data_sched(new sched_nr_time_rr()) {} -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -serv_cell_manager::serv_cell_manager(const cell_params_t& cell_cfg_) : - cfg(cell_cfg_), logger(srslog::fetch_basic_logger(cell_cfg_.sched_args.logger_name)) -{ - for (uint32_t bwp_id = 0; bwp_id < cfg.cfg.bwps.size(); ++bwp_id) { - bwps.emplace_back(cell_cfg_.bwps[bwp_id]); - } - - // Pre-allocate HARQs in common pool of softbuffers - harq_softbuffer_pool::get_instance().init_pool(cfg.nof_prb()); -} - } // namespace sched_nr_impl } // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc b/srsgnb/src/stack/mac/sched_nr_cfg.cc similarity index 51% rename from srsenb/src/stack/mac/nr/sched_nr_cfg.cc rename to srsgnb/src/stack/mac/sched_nr_cfg.cc index 848f77de1a..9e2a592711 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cfg.cc +++ b/srsgnb/src/stack/mac/sched_nr_cfg.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,9 +19,10 @@ * */ -#include "srsenb/hdr/stack/mac/nr/sched_nr_cfg.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_helpers.h" +#include "srsgnb/hdr/stack/mac/sched_nr_cfg.h" +#include "srsgnb/hdr/stack/mac/sched_nr_helpers.h" #include "srsran/adt/optional_array.h" +#include "srsran/asn1/rrc_nr_utils.h" extern "C" { #include "srsran/phy/phch/ra_ul_nr.h" } @@ -47,13 +48,15 @@ void get_dci_locs(const srsran_coreset_t& coreset, /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bwp_params_t::bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg_, uint32_t cc_, uint32_t bwp_id_) : +bwp_params_t::bwp_params_t(const cell_config_manager& cell, uint32_t bwp_id_, const sched_nr_bwp_cfg_t& bwp_cfg) : cell_cfg(cell), - sched_cfg(sched_cfg_), - cc(cc_), + sched_cfg(cell.sched_args), + cc(cell.cc), bwp_id(bwp_id_), - cfg(cell.bwps[bwp_id_]), - logger(srslog::fetch_basic_logger(sched_cfg_.logger_name)) + cfg(bwp_cfg), + nof_prb(cell_cfg.carrier.nof_prb), + logger(srslog::fetch_basic_logger(sched_cfg.logger_name)), + cached_empty_prb_mask(bwp_cfg.rb_width, bwp_cfg.start_rb, bwp_cfg.pdsch.rbg_size_cfg_1) { srsran_assert(cfg.pdcch.ra_search_space_present, "BWPs without RA search space not supported"); const uint32_t ra_coreset_id = cfg.pdcch.ra_search_space.coreset_id; @@ -61,6 +64,24 @@ bwp_params_t::bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg P = get_P(cfg.rb_width, cfg.pdsch.rbg_size_cfg_1); N_rbg = get_nof_rbgs(cfg.rb_width, cfg.start_rb, cfg.pdsch.rbg_size_cfg_1); + for (const srsran_coreset_t& cs : view_active_coresets(cfg.pdcch)) { + coresets.emplace(cs.id); + uint32_t rb_start = srsran_coreset_start_rb(&cs); + coresets[cs.id].prb_limits = prb_interval{rb_start, rb_start + srsran_coreset_get_bw(&cs)}; + coresets[cs.id].usable_common_ss_prb_mask = cached_empty_prb_mask; + + // TS 38.214, 5.1.2.2 - For DCI format 1_0 and common search space, lowest RB of the CORESET is the RB index = 0 + coresets[cs.id].usable_common_ss_prb_mask |= prb_interval(0, rb_start); + coresets[cs.id].dci_1_0_prb_limits = prb_interval{rb_start, cfg.rb_width}; + + // TS 38.214, 5.1.2.2.2 - when DCI format 1_0, common search space and CORESET#0 is configured for the cell, + // RA type 1 allocs shall be within the CORESET#0 region + if (cfg.pdcch.coreset_present[0]) { + coresets[cs.id].dci_1_0_prb_limits = coresets[cs.id].prb_limits; + coresets[cs.id].usable_common_ss_prb_mask |= prb_interval(coresets[cs.id].prb_limits.stop(), cfg.rb_width); + } + } + // Derive params of individual slots uint32_t nof_slots = SRSRAN_NSLOTS_PER_FRAME_NR(cfg.numerology_idx); for (size_t sl = 0; sl < nof_slots; ++sl) { @@ -88,8 +109,8 @@ bwp_params_t::bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg for (uint32_t sl = 0; sl < SRSRAN_NOF_SF_X_FRAME; ++sl) { for (uint32_t agg_idx = 0; agg_idx < MAX_NOF_AGGR_LEVELS; ++agg_idx) { rar_cce_list[sl][agg_idx].resize(SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR); - int n = srsran_pdcch_nr_locations_coreset(&cell_cfg.bwps[0].pdcch.coreset[ra_coreset_id], - &cell_cfg.bwps[0].pdcch.ra_search_space, + int n = srsran_pdcch_nr_locations_coreset(&cell_cfg.bwps[0].cfg.pdcch.coreset[ra_coreset_id], + &cell_cfg.bwps[0].cfg.pdcch.ra_search_space, 0, agg_idx, sl, @@ -98,69 +119,68 @@ bwp_params_t::bwp_params_t(const cell_cfg_t& cell, const sched_args_t& sched_cfg rar_cce_list[sl][agg_idx].resize(n); } } + + for (uint32_t ss_id = 0; ss_id < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE; ++ss_id) { + if (not cell_cfg.bwps[0].cfg.pdcch.search_space_present[ss_id]) { + continue; + } + auto& ss = cell_cfg.bwps[0].cfg.pdcch.search_space[ss_id]; + auto& coreset = cell_cfg.bwps[0].cfg.pdcch.coreset[ss.coreset_id]; + common_cce_list.emplace(ss_id); + bwp_cce_pos_list& ss_cce_list = common_cce_list[ss_id]; + for (uint32_t sl = 0; sl < SRSRAN_NOF_SF_X_FRAME; ++sl) { + for (uint32_t agg_idx = 0; agg_idx < MAX_NOF_AGGR_LEVELS; ++agg_idx) { + ss_cce_list[sl][agg_idx].resize(SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR); + int n = srsran_pdcch_nr_locations_coreset( + &coreset, &ss, SRSRAN_SIRNTI, agg_idx, sl, ss_cce_list[sl][agg_idx].data()); + srsran_assert(n >= 0, "Failed to configure DCI locations of search space id=%d", ss_id); + ss_cce_list[sl][agg_idx].resize(n); + } + } + } } -cell_params_t::cell_params_t(uint32_t cc_, const cell_cfg_t& cell, const sched_args_t& sched_cfg_) : - cc(cc_), cfg(cell), sched_args(sched_cfg_) +cell_config_manager::cell_config_manager(uint32_t cc_, + const sched_nr_cell_cfg_t& cell, + const sched_args_t& sched_args_) : + cc(cc_), sched_args(sched_args_), default_ue_phy_cfg(get_common_ue_phy_cfg(cell)), sibs(cell.sibs) { + carrier.pci = cell.pci; + carrier.dl_center_frequency_hz = cell.dl_center_frequency_hz; + carrier.ul_center_frequency_hz = cell.ul_center_frequency_hz; + carrier.ssb_center_freq_hz = cell.ssb_center_freq_hz; + carrier.nof_prb = cell.dl_cell_nof_prb; + carrier.start = 0; // TODO: Check + carrier.max_mimo_layers = cell.nof_layers; + carrier.offset_to_carrier = cell.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].offset_to_carrier; + carrier.scs = (srsran_subcarrier_spacing_t)cell.dl_cfg_common.init_dl_bwp.generic_params.subcarrier_spacing.value; + + // TDD-UL-DL-ConfigCommon + duplex.mode = SRSRAN_DUPLEX_MODE_FDD; + if (cell.tdd_ul_dl_cfg_common.has_value()) { + bool success = srsran::make_phy_tdd_cfg(*cell.tdd_ul_dl_cfg_common, &duplex); + srsran_assert(success, "Failed to generate Cell TDD config"); + } + + // Set SSB params + make_ssb_cfg(cell, &ssb); + + // MIB + make_mib_cfg(cell, &mib); + bwps.reserve(cell.bwps.size()); - for (uint32_t i = 0; i < cfg.bwps.size(); ++i) { - bwps.emplace_back(cfg, sched_cfg_, cc, i); + for (uint32_t i = 0; i < cell.bwps.size(); ++i) { + bwps.emplace_back(*this, i, cell.bwps[i]); } srsran_assert(not bwps.empty(), "No BWPs were configured"); } -sched_params::sched_params(const sched_args_t& sched_cfg_) : sched_cfg(sched_cfg_) +sched_params_t::sched_params_t(const sched_args_t& sched_cfg_) : sched_cfg(sched_cfg_) { - srsran_assert(sched_cfg.fixed_dl_mcs >= 0, "Dynamic DL MCS not supported"); srsran_assert(sched_cfg.fixed_ul_mcs >= 0, "Dynamic DL MCS not supported"); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bwp_ue_cfg::bwp_ue_cfg(uint16_t rnti_, const bwp_params_t& bwp_cfg_, const ue_cfg_t& uecfg_) : - rnti(rnti_), cfg_(&uecfg_), bwp_cfg(&bwp_cfg_) -{ - std::fill(ss_id_to_cce_idx.begin(), ss_id_to_cce_idx.end(), SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE); - const auto& pdcch = phy().pdcch; - auto ss_view = srsran::make_optional_span(pdcch.search_space, pdcch.search_space_present); - auto coreset_view = srsran::make_optional_span(pdcch.coreset, pdcch.coreset_present); - for (const auto& ss : ss_view) { - srsran_assert(coreset_view.contains(ss.coreset_id), - "Invalid mapping search space id=%d to coreset id=%d", - ss.id, - ss.coreset_id); - cce_positions_list.emplace_back(); - get_dci_locs(coreset_view[ss.coreset_id], ss, rnti, cce_positions_list.back()); - ss_id_to_cce_idx[ss.id] = cce_positions_list.size() - 1; - } -} - -ue_cfg_extended::ue_cfg_extended(uint16_t rnti_, const ue_cfg_t& uecfg) : ue_cfg_t(uecfg), rnti(rnti_) -{ - auto ss_view = srsran::make_optional_span(phy_cfg.pdcch.search_space, phy_cfg.pdcch.search_space_present); - auto coreset_view = srsran::make_optional_span(phy_cfg.pdcch.coreset, phy_cfg.pdcch.coreset_present); - cc_params.resize(carriers.size()); - for (uint32_t cc = 0; cc < cc_params.size(); ++cc) { - cc_params[cc].bwps.resize(1); - auto& bwp = cc_params[cc].bwps[0]; - for (auto& ss : ss_view) { - bwp.ss_list[ss.id].emplace(); - bwp.ss_list[ss.id]->cfg = &ss; - get_dci_locs(phy_cfg.pdcch.coreset[ss.coreset_id], ss, rnti, bwp.ss_list[ss.id]->cce_positions); - } - for (auto& coreset_cfg : coreset_view) { - bwp.coresets.emplace_back(); - auto& coreset = bwp.coresets.back(); - coreset.cfg = &coreset_cfg; - for (auto& ss : bwp.ss_list) { - if (ss.has_value() and ss->cfg->coreset_id == coreset.cfg->id) { - coreset.ss_list.push_back(ss->cfg->id); - } - } - } - } -} - } // namespace sched_nr_impl } // namespace srsenb \ No newline at end of file diff --git a/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc b/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc new file mode 100644 index 0000000000..6e83b2cbb8 --- /dev/null +++ b/srsgnb/src/stack/mac/sched_nr_grant_allocator.cc @@ -0,0 +1,509 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/mac/sched_nr_grant_allocator.h" +#include "srsgnb/hdr/stack/mac/sched_nr_bwp.h" +#include "srsgnb/hdr/stack/mac/sched_nr_helpers.h" +#include "srsran/mac/mac_sch_pdu_nr.h" + +namespace srsenb { +namespace sched_nr_impl { + +using candidate_ss_list_t = + srsran::bounded_vector; + +candidate_ss_list_t find_ss(const srsran_pdcch_cfg_nr_t& pdcch, + uint32_t aggr_idx, + srsran_rnti_type_t rnti_type, + srsran::const_span prio_dcis) +{ + candidate_ss_list_t ret; + auto active_ss_lst = view_active_search_spaces(pdcch); + + auto contains_dci_fmt = [prio_dcis, aggr_idx](const srsran_search_space_t& ss) { + if (ss.nof_candidates[aggr_idx] > 0 and ss.nof_formats > 0) { + for (uint32_t i = 0; i < prio_dcis.size(); ++i) { + for (uint32_t j = 0; j < ss.nof_formats; ++j) { + if (ss.formats[j] == prio_dcis[i]) { + return true; + } + } + } + } + return false; + }; + auto is_common_ss_allowed = [rnti_type](srsran_search_space_type_t ss_type) { + switch (rnti_type) { + case srsran_rnti_type_c: + return ss_type == srsran_search_space_type_common_1 or ss_type == srsran_search_space_type_common_3; + case srsran_rnti_type_tc: + case srsran_rnti_type_ra: + // TODO: Fix UE config to not use common3 + return ss_type == srsran_search_space_type_common_1 or ss_type == srsran_search_space_type_common_3; + case srsran_rnti_type_si: + return ss_type == srsran_search_space_type_common_0; + default: + // TODO: Remaining cases + break; + } + return false; + }; + + if (rnti_type == srsran_rnti_type_c) { + // First search UE-specific + for (const srsran_search_space_t& ss : active_ss_lst) { + if (ss.type == srsran_search_space_type_ue and contains_dci_fmt(ss)) { + ret.push_back(&ss); + } + } + } + for (const srsran_search_space_t& ss : active_ss_lst) { + if (is_common_ss_allowed(ss.type) and contains_dci_fmt(ss)) { + ret.push_back(&ss); + } + } + return ret; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bwp_slot_grid::bwp_slot_grid(const bwp_params_t& bwp_cfg_, uint32_t slot_idx_) : + slot_idx(slot_idx_), + cfg(&bwp_cfg_), + pdcchs(bwp_cfg_, slot_idx_, dl.phy.pdcch_dl, dl.phy.pdcch_ul), + pdschs(bwp_cfg_, slot_idx_, dl.phy.pdsch), + puschs(bwp_cfg_, slot_idx_, ul.pusch), + rar_softbuffer(harq_softbuffer_pool::get_instance().get_tx(bwp_cfg_.cfg.rb_width)) +{} + +void bwp_slot_grid::reset() +{ + pdcchs.reset(); + pdschs.reset(); + puschs.reset(); + dl.phy.ssb.clear(); + dl.phy.nzp_csi_rs.clear(); + dl.data.clear(); + dl.rar.clear(); + dl.sib_idxs.clear(); + ul.pucch.clear(); + pending_acks.clear(); +} + +bwp_res_grid::bwp_res_grid(const bwp_params_t& bwp_cfg_) : cfg(&bwp_cfg_) +{ + for (uint32_t sl = 0; sl < slots.capacity(); ++sl) { + slots.emplace_back(*cfg, sl % static_cast(SRSRAN_NSLOTS_PER_FRAME_NR(bwp_cfg_.cell_cfg.carrier.scs))); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bwp_slot_allocator::bwp_slot_allocator(bwp_res_grid& bwp_grid_, slot_point pdcch_slot_, slot_ue_map_t& ues_) : + logger(bwp_grid_.cfg->logger), cfg(*bwp_grid_.cfg), bwp_grid(bwp_grid_), pdcch_slot(pdcch_slot_), slot_ues(ues_) +{} + +alloc_result bwp_slot_allocator::alloc_si(uint32_t aggr_idx, + uint32_t si_idx, + uint32_t si_ntx, + const prb_interval& prbs, + tx_harq_softbuffer& softbuffer) +{ + static const uint32_t ss_id = 0; + static const srsran_dci_format_nr_t dci_fmt = srsran_dci_format_nr_1_0; + + bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot]; + + // Verify there is space in PDSCH + alloc_result ret = bwp_pdcch_slot.pdschs.is_si_grant_valid(ss_id, prbs); + if (ret != alloc_result::success) { + return ret; + } + + // Allocate PDCCH + auto pdcch_result = bwp_pdcch_slot.pdcchs.alloc_si_pdcch(ss_id, aggr_idx); + if (pdcch_result.is_error()) { + logger.warning("SCHED: Cannot allocate SIB due to lack of PDCCH space."); + return pdcch_result.error(); + } + pdcch_dl_t& pdcch = *pdcch_result.value(); + + // Allocate PDSCH (no need to verify again if there is space in PDSCH) + pdsch_t& pdsch = bwp_pdcch_slot.pdschs.alloc_si_pdsch_unchecked(ss_id, prbs, pdcch.dci); + + // Generate DCI for SIB + pdcch.dci_cfg.coreset0_bw = srsran_coreset_get_bw(&cfg.cfg.pdcch.coreset[0]); + pdcch.dci.mcs = 5; + pdcch.dci.rv = 0; + pdcch.dci.sii = si_idx == 0 ? 0 : 1; + + // Generate PDSCH + srsran_slot_cfg_t slot_cfg; + slot_cfg.idx = pdcch_slot.to_uint(); + int code = srsran_ra_dl_dci_to_grant_nr( + &cfg.cell_cfg.carrier, &slot_cfg, &cfg.cfg.pdsch, &pdcch.dci, &pdsch.sch, &pdsch.sch.grant); + if (code != SRSRAN_SUCCESS) { + logger.warning("Error generating SIB PDSCH grant."); + bwp_pdcch_slot.pdcchs.cancel_last_pdcch(); + bwp_pdcch_slot.dl.phy.pdsch.pop_back(); + return alloc_result::other_cause; + } + pdsch.sch.grant.tb[0].softbuffer.tx = softbuffer.get(); + + // Store SI msg index + bwp_pdcch_slot.dl.sib_idxs.push_back(si_idx); + + return alloc_result::success; +} + +alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t ra_rnti, + uint32_t aggr_idx, + prb_interval interv, + srsran::const_span pending_rachs) +{ + static const uint32_t msg3_nof_prbs = 3, m = 0; + static const srsran_dci_format_nr_t dci_fmt = srsran_dci_format_nr_1_0; + + bwp_slot_grid& bwp_pdcch_slot = bwp_grid[pdcch_slot]; + slot_point msg3_slot = pdcch_slot + cfg.pusch_ra_list[m].msg3_delay; + bwp_slot_grid& bwp_msg3_slot = bwp_grid[msg3_slot]; + + // Verify there is space in PDSCH for RAR + alloc_result ret = bwp_pdcch_slot.pdschs.is_rar_grant_valid(interv); + if (ret != alloc_result::success) { + return ret; + } + for (auto& rach : pending_rachs) { + auto ue_it = slot_ues.find(rach.temp_crnti); + if (ue_it == slot_ues.end()) { + logger.info("SCHED: Postponing rnti=0x%x RAR allocation. Cause: The ue object not yet fully created", + rach.temp_crnti); + return alloc_result::no_rnti_opportunity; + } + } + srsran_sanity_check(not bwp_pdcch_slot.dl.rar.full(), "The #RARs should be below #PDSCHs"); + if (not bwp_pdcch_slot.dl.phy.ssb.empty()) { + // TODO: support concurrent PDSCH and SSB + logger.debug("SCHED: skipping RAR allocation. Cause: concurrent PDSCH and SSB not yet supported"); + return alloc_result::no_sch_space; + } + + // Verify there is space in PUSCH for Msg3s + ret = bwp_msg3_slot.puschs.has_grant_space(pending_rachs.size()); + if (ret != alloc_result::success) { + return ret; + } + // Check Msg3 RB collision + uint32_t total_msg3_nof_prbs = msg3_nof_prbs * pending_rachs.size(); + prb_interval all_msg3_rbs = + find_empty_interval_of_length(bwp_msg3_slot.puschs.occupied_prbs(), total_msg3_nof_prbs, 0); + if (all_msg3_rbs.length() < total_msg3_nof_prbs) { + logger.debug("SCHED: No space in PUSCH for Msg3."); + return alloc_result::sch_collision; + } + + // Allocate PDCCH position for RAR + auto pdcch_result = bwp_pdcch_slot.pdcchs.alloc_rar_pdcch(ra_rnti, aggr_idx); + if (pdcch_result.is_error()) { + // Could not find space in PDCCH + return pdcch_result.error(); + } + pdcch_dl_t& pdcch = *pdcch_result.value(); + pdcch.dci_cfg = slot_ues[pending_rachs[0].temp_crnti]->get_dci_cfg(); + pdcch.dci.mcs = 5; + + // Allocate RAR PDSCH + pdsch_t& pdsch = bwp_pdcch_slot.pdschs.alloc_rar_pdsch_unchecked(interv, pdcch.dci); + + // Fill RAR PDSCH content + // TODO: Properly fill Msg3 grants + srsran_slot_cfg_t slot_cfg; + slot_cfg.idx = pdcch_slot.to_uint(); + int code = srsran_ra_dl_dci_to_grant_nr( + &cfg.cell_cfg.carrier, &slot_cfg, &cfg.cfg.pdsch, &pdcch.dci, &pdsch.sch, &pdsch.sch.grant); + srsran_assert(code == SRSRAN_SUCCESS, "Error converting DCI to grant"); + pdsch.sch.grant.tb[0].softbuffer.tx = bwp_pdcch_slot.rar_softbuffer->get(); + + // Generate Msg3 grants in PUSCH + uint32_t last_msg3 = all_msg3_rbs.start(); + const int mcs = 0, max_harq_msg3_retx = 4; + slot_cfg.idx = msg3_slot.to_uint(); + bwp_pdcch_slot.dl.rar.emplace_back(); + sched_nr_interface::rar_t& rar_out = bwp_pdcch_slot.dl.rar.back(); + for (const dl_sched_rar_info_t& grant : pending_rachs) { + slot_ue& ue = slot_ues[grant.temp_crnti]; + + // Generate RAR grant + rar_out.grants.emplace_back(); + auto& rar_grant = rar_out.grants.back(); + rar_grant.data = grant; + fill_dci_from_cfg(cfg, rar_grant.msg3_dci); + // Fill Msg3 DCI context + rar_grant.msg3_dci.ctx.coreset_id = pdcch.dci.ctx.coreset_id; + rar_grant.msg3_dci.ctx.rnti_type = srsran_rnti_type_tc; + rar_grant.msg3_dci.ctx.rnti = ue->rnti; + rar_grant.msg3_dci.ctx.ss_type = srsran_search_space_type_rar; + rar_grant.msg3_dci.ctx.format = srsran_dci_format_nr_rar; + + // Allocate Msg3 PUSCH allocation + prb_interval msg3_interv{last_msg3, last_msg3 + msg3_nof_prbs}; + last_msg3 += msg3_nof_prbs; + pusch_t& pusch = bwp_msg3_slot.puschs.alloc_pusch_unchecked(msg3_interv, rar_grant.msg3_dci); + + // Allocate UL HARQ + ue.h_ul = ue.find_empty_ul_harq(); + srsran_sanity_check(ue.h_ul != nullptr, "Failed to allocate Msg3"); + bool success = ue.h_ul->new_tx(msg3_slot, msg3_interv, mcs, max_harq_msg3_retx, rar_grant.msg3_dci); + srsran_sanity_check(success, "Failed to allocate Msg3"); + + // Generate PUSCH content + success = ue->phy().get_pusch_cfg(slot_cfg, rar_grant.msg3_dci, pusch.sch); + srsran_assert(success, "Error converting DCI to PUSCH grant"); + pusch.sch.grant.tb[0].softbuffer.rx = ue.h_ul->get_softbuffer().get(); + ue.h_ul->set_tbs(pusch.sch.grant.tb[0].tbs); + } + + return alloc_result::success; +} + +// ue is the UE (1 only) that will be allocated +// func computes the grant allocation for this UE +alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, uint32_t ss_id, const prb_grant& dl_grant) +{ + static const uint32_t aggr_idx = 2; + static const srsran_dci_format_nr_t dci_fmt = srsran_dci_format_nr_1_0; + static const srsran_rnti_type_t rnti_type = srsran_rnti_type_c; + + bwp_slot_grid& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot]; + bwp_slot_grid& bwp_pdsch_slot = bwp_grid[ue.pdsch_slot]; + bwp_slot_grid& bwp_uci_slot = bwp_grid[ue.uci_slot]; // UCI : UL control info + + // Verify there is space in PDSCH + alloc_result ret = bwp_pdcch_slot.pdschs.is_ue_grant_valid(ue.cfg(), ss_id, dci_fmt, dl_grant); + if (ret != alloc_result::success) { + return ret; + } + + alloc_result result = verify_uci_space(bwp_uci_slot); + if (result != alloc_result::success) { + return result; + } + if (ue.h_dl == nullptr) { + logger.warning("SCHED: Trying to allocate rnti=0x%x with no available DL HARQs", ue->rnti); + return result; + } + if (not bwp_pdsch_slot.dl.phy.ssb.empty()) { + // TODO: support concurrent PDSCH and SSB + logger.debug("SCHED: skipping PDSCH allocation. Cause: concurrent PDSCH and SSB not yet supported"); + return alloc_result::no_sch_space; + } + + // Check space in PUCCH/PUSCH for UCI + // TODO + + // Find space and allocate PDCCH + auto pdcch_result = bwp_pdcch_slot.pdcchs.alloc_dl_pdcch(rnti_type, ss_id, aggr_idx, ue.cfg()); + if (pdcch_result.is_error()) { + // Could not find space in PDCCH + return pdcch_result.error(); + } + pdcch_dl_t& pdcch = *pdcch_result.value(); + pdcch.dci_cfg = ue->get_dci_cfg(); + pdcch.dci.pucch_resource = 0; + pdcch.dci.dai = std::count_if(bwp_uci_slot.pending_acks.begin(), + bwp_uci_slot.pending_acks.end(), + [&ue](const harq_ack_t& p) { return p.res.rnti == ue->rnti; }); + pdcch.dci.dai %= 4; + + // Allocate PDSCH + pdsch_t& pdsch = bwp_pdcch_slot.pdschs.alloc_ue_pdsch_unchecked(ss_id, dci_fmt, dl_grant, ue.cfg(), pdcch.dci); + + // Select MCS and Allocate HARQ + int mcs = ue->fixed_pdsch_mcs(); + const static int min_MCS_ccch = 4; + if (ue.h_dl->empty()) { + if (mcs < 0) { + mcs = srsran_ra_nr_cqi_to_mcs(/* cqi */ ue.dl_cqi(), + /* cqi_table_idx */ ue.cfg().phy().csi.reports->cqi_table, + /* mcs_table */ pdsch.sch.sch_cfg.mcs_table, + /* dci_format */ pdcch.dci.ctx.format, + /* search_space_type*/ pdcch.dci.ctx.ss_type, + /* rnti_type */ rnti_type); + if (mcs < 0) { + logger.warning("SCHED: UE rnti=0x%x reported CQI=0 - Using lowest MCS=0", ue->rnti); + mcs = 0; + } + } + // Overwrite MCS if there are pending bytes for LCID. The optimal way would be to verify that there are pending + // bytes and that the MAC SDU for CCCH gets segmented. But since the event of segmentation happens at most a couple + // of times (e.g., to send msg4/RRCSetup), we opt for the less optimal but simpler approach. + if (ue.get_pending_bytes(srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CCCH) and mcs < min_MCS_ccch) { + mcs = min_MCS_ccch; + logger.info("SCHED: MCS increased to min value %d to allocate SRB0/CCCH for rnti=0x%x", min_MCS_ccch, ue->rnti); + } + bool success = ue.h_dl->new_tx(ue.pdsch_slot, ue.uci_slot, dl_grant, mcs, 4, pdcch.dci); + srsran_assert(success, "Failed to allocate DL HARQ"); + } else { + bool success = ue.h_dl->new_retx(ue.pdsch_slot, ue.uci_slot, dl_grant, pdcch.dci); + mcs = ue.h_dl->mcs(); + srsran_assert(success, "Failed to allocate DL HARQ retx"); + } + + srsran_slot_cfg_t slot_cfg; + slot_cfg.idx = ue.pdsch_slot.to_uint(); + // Value 0.95 is from TS 38.214 v15.14.00, Section 5.1.3, page 17 + const static float max_R = 0.95; + double R_prime; + // The purpose of the internal loop is to decrease the MCS if the effective coderate is too high. This loop + // only affects the high MCS values + while (true) { + // Generate PDSCH + bool success = ue->phy().get_pdsch_cfg(slot_cfg, pdcch.dci, pdsch.sch); + srsran_assert(success, "Error converting DCI to grant"); + if (ue.h_dl->nof_retx() != 0) { + srsran_assert(pdsch.sch.grant.tb[0].tbs == (int)ue.h_dl->tbs(), "The TBS did not remain constant in retx"); + } + R_prime = pdsch.sch.grant.tb[0].R_prime; + if (ue.h_dl->nof_retx() > 0 or R_prime < max_R or mcs <= 0 or + (ue.get_pending_bytes(srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CCCH) and mcs <= min_MCS_ccch)) { + break; + } + // Decrease MCS if first tx and rate is too high + mcs--; + pdcch.dci.mcs = mcs; + } + if (R_prime >= max_R and mcs == 0) { + logger.warning("Couldn't find mcs that leads to R<0.95"); + } + + ue.h_dl->set_mcs(mcs); + ue.h_dl->set_tbs(pdsch.sch.grant.tb[0].tbs); // set HARQ TBS + pdsch.sch.grant.tb[0].softbuffer.tx = ue.h_dl->get_softbuffer().get(); + pdsch.data[0] = ue.h_dl->get_tx_pdu()->get(); + + // Select scheduled LCIDs and update UE buffer state + bwp_pdsch_slot.dl.data.emplace_back(); + // NOTE: ue.h_dl->tbs() has to be converted from bits to bytes + bool segmented_ccch_pdu = not ue.build_pdu(ue.h_dl->tbs() / 8, bwp_pdsch_slot.dl.data.back()); + if (segmented_ccch_pdu) { + logger.error("SCHED: Insufficient resources to allocate SRB0/CCCH for rnti=0x%x", min_MCS_ccch, ue->rnti); + } + + // Generate PUCCH + bwp_uci_slot.pending_acks.emplace_back(); + bwp_uci_slot.pending_acks.back().phy_cfg = &ue->phy(); + bool success = ue->phy().get_pdsch_ack_resource(pdcch.dci, bwp_uci_slot.pending_acks.back().res); + srsran_assert(success, "Error getting ack resource"); + + return alloc_result::success; +} + +alloc_result bwp_slot_allocator::alloc_pusch(slot_ue& ue, const prb_grant& ul_grant) +{ + static const uint32_t aggr_idx = 2; + static const std::array dci_fmt_list{srsran_dci_format_nr_0_1, srsran_dci_format_nr_0_0}; + static const srsran_rnti_type_t rnti_type = srsran_rnti_type_c; + + auto& bwp_pdcch_slot = bwp_grid[ue.pdcch_slot]; + auto& bwp_pusch_slot = bwp_grid[ue.pusch_slot]; + + if (ue.h_ul == nullptr) { + logger.warning("SCHED: Trying to allocate rnti=0x%x with no available UL HARQs", ue->rnti); + return alloc_result::no_rnti_opportunity; + } + + // Choose SearchSpace + DCI format + candidate_ss_list_t ss_candidates = find_ss(ue->phy().pdcch, aggr_idx, rnti_type, dci_fmt_list); + if (ss_candidates.empty()) { + // Could not find space in PDCCH + logger.warning("SCHED: No PDCCH candidates for any of the rnti=0x%x search spaces", ue->rnti); + return alloc_result::no_cch_space; + } + const srsran_search_space_t& ss = *ss_candidates[0]; + + // Verify if PUSCH allocation is valid + alloc_result ret = bwp_pusch_slot.puschs.is_grant_valid(ss.type, ul_grant); + if (ret != alloc_result::success) { + return ret; + } + + auto pdcch_result = bwp_pdcch_slot.pdcchs.alloc_ul_pdcch(ss.id, aggr_idx, ue.cfg()); + if (pdcch_result.is_error()) { + // Could not find space in PDCCH + return pdcch_result.error(); + } + + // Allocation Successful + pdcch_ul_t& pdcch = *pdcch_result.value(); + pdcch.dci_cfg = ue->get_dci_cfg(); + + // Allocate PUSCH + pusch_t& pusch = bwp_pusch_slot.puschs.alloc_pusch_unchecked(ul_grant, pdcch.dci); + + if (ue.h_ul->empty()) { + int mcs = ue->fixed_pusch_mcs(); + bool success = ue.h_ul->new_tx(ue.pusch_slot, ul_grant, mcs, ue->ue_cfg().maxharq_tx, pdcch.dci); + srsran_assert(success, "Failed to allocate UL HARQ"); + } else { + bool success = ue.h_ul->new_retx(ue.pusch_slot, ul_grant, pdcch.dci); + srsran_assert(success, "Failed to allocate UL HARQ retx"); + } + + // Generate PUSCH content + srsran_slot_cfg_t slot_cfg; + slot_cfg.idx = ue.pusch_slot.to_uint(); + pusch.pid = ue.h_ul->pid; + bool success = ue->phy().get_pusch_cfg(slot_cfg, pdcch.dci, pusch.sch); + srsran_assert(success, "Error converting DCI to PUSCH grant"); + pusch.sch.grant.tb[0].softbuffer.rx = ue.h_ul->get_softbuffer().get(); + if (ue.h_ul->nof_retx() == 0) { + ue.h_ul->set_tbs(pusch.sch.grant.tb[0].tbs); // update HARQ with correct TBS + } else { + srsran_assert(pusch.sch.grant.tb[0].tbs == (int)ue.h_ul->tbs(), "The TBS did not remain constant in retx"); + } + + return alloc_result::success; +} + +alloc_result bwp_slot_allocator::verify_uci_space(const bwp_slot_grid& uci_grid) const +{ + if (uci_grid.pending_acks.full()) { + logger.warning("SCHED: No space for ACK."); + return alloc_result::no_grant_space; + } + return alloc_result::success; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +prb_grant find_optimal_dl_grant(bwp_slot_allocator& slot_alloc, const slot_ue& ue, uint32_t ss_id) +{ + static const srsran_dci_format_nr_t dci_fmt = srsran_dci_format_nr_1_0; // TODO: Support more DCI formats + + prb_bitmap used_prb_mask = slot_alloc.occupied_dl_prbs(ue.pdsch_slot, ss_id, dci_fmt); + + prb_interval prb_interv = find_empty_interval_of_length(used_prb_mask, used_prb_mask.size(), 0); + + return prb_interv; +} + +} // namespace sched_nr_impl +} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_harq.cc b/srsgnb/src/stack/mac/sched_nr_harq.cc similarity index 67% rename from srsenb/src/stack/mac/nr/sched_nr_harq.cc rename to srsgnb/src/stack/mac/sched_nr_harq.cc index bbf3fcc2b0..f77aa6f4cd 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_harq.cc +++ b/srsgnb/src/stack/mac/sched_nr_harq.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,7 +19,7 @@ * */ -#include "srsenb/hdr/stack/mac/nr/sched_nr_harq.h" +#include "srsgnb/hdr/stack/mac/sched_nr_harq.h" #include "srsran/common/buffer_pool.h" namespace srsenb { @@ -124,14 +124,76 @@ dl_harq_proc::dl_harq_proc(uint32_t id_, uint32_t nprb) : harq_proc(id_), softbuffer(harq_softbuffer_pool::get_instance().get_tx(nprb)), pdu(srsran::make_byte_buffer()) {} -bool dl_harq_proc::new_tx(slot_point slot_tx, - slot_point slot_ack, - const prb_grant& grant, - uint32_t mcs, - uint32_t max_retx) +void dl_harq_proc::fill_dci(srsran_dci_dl_nr_t& dci) { - if (harq_proc::new_tx(slot_tx, slot_ack, grant, mcs, max_retx)) { + const static uint32_t rv_idx[4] = {0, 2, 3, 1}; + + dci.pid = pid; + dci.ndi = ndi(); + dci.mcs = mcs(); + dci.rv = rv_idx[nof_retx() % 4]; + if (dci.ctx.format == srsran_dci_format_nr_1_0) { + dci.harq_feedback = (slot_ack - slot_tx) - 1; + } else { + dci.harq_feedback = slot_tx.to_uint(); + } +} + +bool dl_harq_proc::new_tx(slot_point slot_tx, + slot_point slot_ack, + const prb_grant& grant, + uint32_t mcs_, + uint32_t max_retx, + srsran_dci_dl_nr_t& dci) +{ + const static uint32_t rv_idx[4] = {0, 2, 3, 1}; + + if (harq_proc::new_tx(slot_tx, slot_ack, grant, mcs_, max_retx)) { pdu->clear(); + fill_dci(dci); + return true; + } + return false; +} + +bool dl_harq_proc::new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, srsran_dci_dl_nr_t& dci) +{ + if (harq_proc::new_retx(slot_tx, slot_ack, grant)) { + fill_dci(dci); + return true; + } + return false; +} + +void ul_harq_proc::fill_dci(srsran_dci_ul_nr_t& dci) +{ + const static uint32_t rv_idx[4] = {0, 2, 3, 1}; + + dci.pid = pid; + dci.ndi = ndi(); + dci.mcs = mcs(); + dci.rv = rv_idx[nof_retx() % 4]; +} + +bool ul_harq_proc::new_tx(slot_point slot_tx, + const prb_grant& grant, + uint32_t mcs_, + uint32_t max_retx, + srsran_dci_ul_nr_t& dci) +{ + const static uint32_t rv_idx[4] = {0, 2, 3, 1}; + + if (harq_proc::new_tx(slot_tx, slot_tx, grant, mcs_, max_retx)) { + fill_dci(dci); + return true; + } + return false; +} + +bool ul_harq_proc::new_retx(slot_point slot_tx, const prb_grant& grant, srsran_dci_ul_nr_t& dci) +{ + if (harq_proc::new_retx(slot_tx, slot_tx, grant)) { + fill_dci(dci); return true; } return false; diff --git a/srsgnb/src/stack/mac/sched_nr_helpers.cc b/srsgnb/src/stack/mac/sched_nr_helpers.cc new file mode 100644 index 0000000000..a0a2c440e6 --- /dev/null +++ b/srsgnb/src/stack/mac/sched_nr_helpers.cc @@ -0,0 +1,162 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/mac/sched_nr_helpers.h" +#include "srsgnb/hdr/stack/mac/sched_nr_grant_allocator.h" +#include "srsgnb/hdr/stack/mac/sched_nr_harq.h" +#include "srsgnb/hdr/stack/mac/sched_nr_ue.h" +#include "srsran/common/string_helpers.h" + +namespace srsenb { +namespace sched_nr_impl { + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void log_sched_slot_ues(srslog::basic_logger& logger, slot_point pdcch_slot, uint32_t cc, const slot_ue_map_t& slot_ues) +{ + if (not logger.debug.enabled() or slot_ues.empty()) { + return; + } + + fmt::memory_buffer fmtbuf; + fmt::format_to(fmtbuf, "SCHED: UE candidates, pdcch_tti={}, cc={}: [", pdcch_slot, cc); + + const char* use_comma = ""; + for (const auto& ue_pair : slot_ues) { + auto& ue = ue_pair->second; + + fmt::format_to(fmtbuf, "{}{{rnti=0x{:x}", use_comma, ue->rnti); + if (ue.dl_active) { + fmt::format_to(fmtbuf, ", dl_bs={}", ue.dl_bytes); + } + if (ue.ul_active) { + fmt::format_to(fmtbuf, ", ul_bs={}", ue.ul_bytes); + } + fmt::format_to(fmtbuf, "}}"); + use_comma = ", "; + } + + logger.debug("%s]", srsran::to_c_str(fmtbuf)); +} + +void log_sched_bwp_result(srslog::basic_logger& logger, + slot_point pdcch_slot, + const bwp_res_grid& res_grid, + const slot_ue_map_t& slot_ues) +{ + const bwp_slot_grid& bwp_slot = res_grid[pdcch_slot]; + size_t rar_count = 0, si_count = 0, data_count = 0; + for (const pdcch_dl_t& pdcch : bwp_slot.dl.phy.pdcch_dl) { + fmt::memory_buffer fmtbuf; + if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) { + const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; + fmt::format_to(fmtbuf, + "SCHED: DL {}, cc={}, rnti=0x{:x}, pid={}, cs={}, f={}, prbs={}, nrtx={}, dai={}, " + "lcids=[{}], tbs={}, bs={}, pdsch_slot={}, ack_slot={}", + ue.h_dl->nof_retx() == 0 ? "tx" : "retx", + res_grid.cfg->cc, + ue->rnti, + pdcch.dci.pid, + pdcch.dci.ctx.coreset_id, + srsran_dci_format_nr_string(pdcch.dci.ctx.format), + ue.h_dl->prbs(), + ue.h_dl->nof_retx(), + pdcch.dci.dai, + fmt::join(bwp_slot.dl.data[data_count].subpdus, ", "), + ue.h_dl->tbs() / 8u, + ue.dl_bytes, + ue.pdsch_slot, + ue.uci_slot); + data_count++; + } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_ra) { + const pdsch_t& pdsch = bwp_slot.dl.phy.pdsch[std::distance(bwp_slot.dl.phy.pdcch_dl.data(), &pdcch)]; + srsran::const_span prbs{pdsch.sch.grant.prb_idx, pdsch.sch.grant.prb_idx + SRSRAN_MAX_PRB_NR}; + uint32_t start_idx = std::distance(prbs.begin(), std::find(prbs.begin(), prbs.end(), true)); + uint32_t end_idx = start_idx + pdsch.sch.grant.nof_prb; + fmt::format_to(fmtbuf, + "SCHED: RAR, cc={}, ra-rnti=0x{:x}, prbs={}, pdsch_slot={}, msg3_slot={}, nof_grants={}", + res_grid.cfg->cc, + pdcch.dci.ctx.rnti, + srsran::interval{start_idx, end_idx}, + pdcch_slot, + pdcch_slot + res_grid.cfg->pusch_ra_list[0].msg3_delay, + bwp_slot.dl.rar[rar_count].grants.size()); + rar_count++; + } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_si) { + if (logger.debug.enabled()) { + const pdsch_t& pdsch = bwp_slot.dl.phy.pdsch[std::distance(bwp_slot.dl.phy.pdcch_dl.data(), &pdcch)]; + srsran::const_span prbs{pdsch.sch.grant.prb_idx, pdsch.sch.grant.prb_idx + SRSRAN_MAX_PRB_NR}; + uint32_t start_idx = std::distance(prbs.begin(), std::find(prbs.begin(), prbs.end(), true)); + uint32_t end_idx = start_idx + pdsch.sch.grant.nof_prb; + fmt::format_to(fmtbuf, + "SCHED: SI{}, cc={}, prbs={}, pdsch_slot={}", + pdcch.dci.sii == 0 ? "B" : " message", + res_grid.cfg->cc, + srsran::interval{start_idx, end_idx}, + pdcch_slot); + si_count++; + } + } + + if (fmtbuf.size() > 0) { + if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_si) { + logger.debug("%s", srsran::to_c_str(fmtbuf)); + } else { + logger.info("%s", srsran::to_c_str(fmtbuf)); + } + } + } + for (const pdcch_ul_t& pdcch : bwp_slot.dl.phy.pdcch_ul) { + fmt::memory_buffer fmtbuf; + if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) { + const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; + fmt::format_to(fmtbuf, + "SCHED: UL {}, cc={}, rnti=0x{:x}, pid={}, cs={}, f={}, nrtx={}, tbs={}, bs={}, pusch_slot={}", + ue.h_ul->nof_retx() == 0 ? "tx" : "retx", + res_grid.cfg->cc, + ue->rnti, + pdcch.dci.pid, + pdcch.dci.ctx.coreset_id, + srsran_dci_format_nr_string(pdcch.dci.ctx.format), + ue.h_ul->nof_retx(), + ue.h_ul->tbs() / 8u, + ue.ul_bytes, + ue.pusch_slot); + } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_tc) { + const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; + fmt::format_to(fmtbuf, + "SCHED: UL Msg3, cc={}, tc-rnti=0x{:x}, pid={}, nrtx={}, f={}, tti_pusch={}", + res_grid.cfg->cc, + ue->rnti, + pdcch.dci.pid, + ue.h_ul->nof_retx(), + srsran_dci_format_nr_string(pdcch.dci.ctx.format), + ue.pusch_slot); + } else { + fmt::format_to(fmtbuf, "SCHED: unknown rnti format"); + } + + logger.info("%s", srsran::to_c_str(fmtbuf)); + } +} + +} // namespace sched_nr_impl +} // namespace srsenb diff --git a/srsgnb/src/stack/mac/sched_nr_interface_utils.cc b/srsgnb/src/stack/mac/sched_nr_interface_utils.cc new file mode 100644 index 0000000000..e728803ff6 --- /dev/null +++ b/srsgnb/src/stack/mac/sched_nr_interface_utils.cc @@ -0,0 +1,115 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/mac/sched_nr_interface_utils.h" +#include "srsran/asn1/rrc_nr_utils.h" +#include "srsran/common/band_helper.h" + +namespace srsenb { + +uint32_t coreset_nof_cces(const srsran_coreset_t& coreset) +{ + const bool* res_active = &coreset.freq_resources[0]; + uint32_t nof_freq_res = std::count(res_active, res_active + SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE, true); + return nof_freq_res * coreset.duration; +} + +void make_mib_cfg(const sched_nr_cell_cfg_t& cfg, srsran_mib_nr_t* mib) +{ + *mib = {}; + mib->scs_common = (srsran_subcarrier_spacing_t)cfg.dl_cfg_common.init_dl_bwp.generic_params.subcarrier_spacing.value; + mib->ssb_offset = cfg.ssb_offset; + mib->dmrs_typeA_pos = (srsran_dmrs_sch_typeA_pos_t)cfg.dmrs_type_a_position.value; + mib->coreset0_idx = cfg.pdcch_cfg_sib1.ctrl_res_set_zero; + mib->ss0_idx = cfg.pdcch_cfg_sib1.search_space_zero; + mib->cell_barred = false; + mib->intra_freq_reselection = true; +} + +void make_ssb_cfg(const sched_nr_cell_cfg_t& cfg, srsran::phy_cfg_nr_t::ssb_cfg_t* ssb) +{ + ssb->periodicity_ms = cfg.ssb_periodicity_ms; + ssb->position_in_burst = {}; + uint32_t N = cfg.ssb_positions_in_burst.in_one_group.length(); + for (uint32_t i = 0; i < N; ++i) { + ssb->position_in_burst[i] = cfg.ssb_positions_in_burst.in_one_group.get(i); + } + if (cfg.ssb_positions_in_burst.group_presence_present) { + for (uint32_t i = 1; i < cfg.ssb_positions_in_burst.group_presence.length(); ++i) { + if (cfg.ssb_positions_in_burst.group_presence.get(i)) { + std::copy( + ssb->position_in_burst.begin(), ssb->position_in_burst.begin() + N, ssb->position_in_burst.begin() + i * N); + } + } + } + ssb->scs = (srsran_subcarrier_spacing_t)cfg.ssb_scs.value; + ssb->pattern = SRSRAN_SSB_PATTERN_A; + if (cfg.dl_cfg_common.freq_info_dl.freq_band_list.size() > 0 and + cfg.dl_cfg_common.freq_info_dl.freq_band_list[0].freq_band_ind_nr_present) { + uint32_t band = cfg.dl_cfg_common.freq_info_dl.freq_band_list[0].freq_band_ind_nr; + ssb->pattern = srsran::srsran_band_helper::get_ssb_pattern(band, ssb->scs); + } +} + +srsran::phy_cfg_nr_t get_common_ue_phy_cfg(const sched_nr_cell_cfg_t& cfg) +{ + srsran::phy_cfg_nr_t ue_phy_cfg; + + // TDD UL-DL config + ue_phy_cfg.duplex.mode = SRSRAN_DUPLEX_MODE_FDD; + if (cfg.tdd_ul_dl_cfg_common.has_value()) { + bool success = srsran::make_phy_tdd_cfg(*cfg.tdd_ul_dl_cfg_common, &ue_phy_cfg.duplex); + srsran_sanity_check(success, "Failed to convert Cell TDDConfig to UEPHYConfig"); + } + + ue_phy_cfg.pdcch = cfg.bwps[0].pdcch; + ue_phy_cfg.pdsch = cfg.bwps[0].pdsch; + ue_phy_cfg.pusch = cfg.bwps[0].pusch; + ue_phy_cfg.pucch = cfg.bwps[0].pucch; + srsran::make_phy_rach_cfg(cfg.ul_cfg_common.init_ul_bwp.rach_cfg_common.setup(), + cfg.tdd_ul_dl_cfg_common.has_value() ? SRSRAN_DUPLEX_MODE_TDD : SRSRAN_DUPLEX_MODE_FDD, + &ue_phy_cfg.prach); + ue_phy_cfg.harq_ack = cfg.bwps[0].harq_ack; + ue_phy_cfg.csi = {}; // disable CSI until RA is complete + ue_phy_cfg.carrier.pci = cfg.pci; + ue_phy_cfg.carrier.dl_center_frequency_hz = cfg.dl_center_frequency_hz; + ue_phy_cfg.carrier.ul_center_frequency_hz = cfg.ul_center_frequency_hz; + ue_phy_cfg.carrier.ssb_center_freq_hz = cfg.ssb_center_freq_hz; + ue_phy_cfg.carrier.offset_to_carrier = cfg.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].offset_to_carrier; + ue_phy_cfg.carrier.scs = + (srsran_subcarrier_spacing_t)cfg.dl_cfg_common.init_dl_bwp.generic_params.subcarrier_spacing.value; + ue_phy_cfg.carrier.nof_prb = cfg.dl_cell_nof_prb; + ue_phy_cfg.carrier.max_mimo_layers = cfg.nof_layers; + make_ssb_cfg(cfg, &ue_phy_cfg.ssb); + + // remove UE-specific SearchSpaces (they will be added later via RRC) + for (uint32_t i = 0; i < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE; ++i) { + if (ue_phy_cfg.pdcch.search_space_present[i] and + ue_phy_cfg.pdcch.search_space[i].type == srsran_search_space_type_ue) { + ue_phy_cfg.pdcch.search_space_present[i] = false; + ue_phy_cfg.pdcch.search_space[i] = {}; + } + } + + return ue_phy_cfg; +} + +} // namespace srsenb \ No newline at end of file diff --git a/srsgnb/src/stack/mac/sched_nr_pdcch.cc b/srsgnb/src/stack/mac/sched_nr_pdcch.cc new file mode 100644 index 0000000000..8cdf7a5ad2 --- /dev/null +++ b/srsgnb/src/stack/mac/sched_nr_pdcch.cc @@ -0,0 +1,521 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/mac/sched_nr_pdcch.h" +#include "srsgnb/hdr/stack/mac/sched_nr_helpers.h" +#include "srsran/common/string_helpers.h" + +namespace srsenb { +namespace sched_nr_impl { + +template +void log_pdcch_alloc_failure(srslog::log_channel& log_ch, + srsran_rnti_type_t rnti_type, + uint32_t ss_id, + uint16_t rnti, + const char* cause_fmt, + Args&&... args) +{ + if (not log_ch.enabled()) { + return; + } + + // Log PDCCH allocation failure + fmt::memory_buffer fmtbuf; + fmt::format_to(fmtbuf, + "SCHED: Failure to allocate PDCCH for {}-rnti=0x{:x}, SS#{}. Cause: ", + srsran_rnti_type_str_short(rnti_type), + rnti, + ss_id); + fmt::format_to(fmtbuf, cause_fmt, std::forward(args)...); + log_ch("%s", srsran::to_c_str(fmtbuf)); +} + +void fill_dci_from_cfg(const bwp_params_t& bwp_cfg, srsran_dci_dl_nr_t& dci) +{ + dci.bwp_id = bwp_cfg.bwp_id; + dci.cc_id = bwp_cfg.cc; + dci.tpc = 1; + dci.coreset0_bw = bwp_cfg.cfg.pdcch.coreset_present[0] ? bwp_cfg.coreset_prb_range(0).length() : 0; +} + +void fill_dci_from_cfg(const bwp_params_t& bwp_cfg, srsran_dci_ul_nr_t& dci) +{ + dci.bwp_id = bwp_cfg.bwp_id; + dci.cc_id = bwp_cfg.cc; + dci.tpc = 1; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +coreset_region::coreset_region(const bwp_params_t& bwp_cfg_, uint32_t coreset_id_, uint32_t slot_idx_) : + coreset_cfg(&bwp_cfg_.cfg.pdcch.coreset[coreset_id_]), + coreset_id(coreset_id_), + slot_idx(slot_idx_), + rar_cce_list(bwp_cfg_.rar_cce_list), + common_cce_list(bwp_cfg_.common_cce_list) +{ + const bool* res_active = &coreset_cfg->freq_resources[0]; + nof_freq_res = std::count(res_active, res_active + SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE, true); + srsran_assert(get_td_symbols() <= SRSRAN_CORESET_DURATION_MAX, + "Possible number of time-domain OFDM symbols in CORESET must be within {1,2,3}"); + srsran_assert(nof_freq_res <= bwp_cfg_.cell_cfg.nof_prb(), + "The number of frequency resources=%d of CORESET#%d exceeds BWP bandwidth=%d", + nof_freq_res, + coreset_id, + bwp_cfg_.cell_cfg.nof_prb()); +} + +void coreset_region::reset() +{ + dfs_tree.clear(); + saved_dfs_tree.clear(); + dci_list.clear(); +} + +bool coreset_region::alloc_pdcch(srsran_rnti_type_t rnti_type, + bool is_dl, + uint32_t aggr_idx, + uint32_t search_space_id, + const ue_carrier_params_t* user, + srsran_dci_ctx_t& dci) +{ + saved_dfs_tree.clear(); + + alloc_record record; + record.dci = &dci; + record.ue = user; + record.aggr_idx = aggr_idx; + record.ss_id = search_space_id; + record.is_dl = is_dl; + record.dci->rnti_type = rnti_type; + + // Try to allocate grant. If it fails, attempt the same grant, but using a different permutation of past grant DCI + // positions + do { + bool success = alloc_dfs_node(record, 0); + if (success) { + // DCI record allocation successful + dci_list.push_back(record); + return true; + } + if (saved_dfs_tree.empty()) { + saved_dfs_tree = dfs_tree; + } + } while (get_next_dfs()); + + // Revert steps to initial state, before dci record allocation was attempted + dfs_tree.swap(saved_dfs_tree); + return false; +} + +void coreset_region::rem_last_pdcch() +{ + srsran_assert(not dci_list.empty(), "%s called when no PDCCH have yet been allocated", __FUNCTION__); + + // Remove DCI record + dfs_tree.pop_back(); + dci_list.pop_back(); +} + +bool coreset_region::get_next_dfs() +{ + do { + if (dfs_tree.empty()) { + // If we reach root, the allocation failed + return false; + } + // Attempt to re-add last tree node, but with a higher node child index + uint32_t start_child_idx = dfs_tree.back().dci_pos_idx + 1; + dfs_tree.pop_back(); + while (dfs_tree.size() < dci_list.size() and alloc_dfs_node(dci_list[dfs_tree.size()], start_child_idx)) { + start_child_idx = 0; + } + } while (dfs_tree.size() < dci_list.size()); + + // Finished computation of next DFS node + return true; +} + +bool coreset_region::alloc_dfs_node(const alloc_record& record, uint32_t start_dci_idx) +{ + alloc_tree_dfs_t& alloc_dfs = dfs_tree; + // Get DCI Location Table + auto cce_locs = get_cce_loc_table(record); + if (start_dci_idx >= cce_locs.size()) { + return false; + } + + tree_node node; + node.dci_pos_idx = start_dci_idx; + node.dci_pos.L = record.aggr_idx; + node.rnti = record.ue != nullptr ? record.ue->rnti : SRSRAN_INVALID_RNTI; + node.current_mask.resize(nof_cces()); + // get cumulative pdcch bitmap + if (not alloc_dfs.empty()) { + node.total_mask = alloc_dfs.back().total_mask; + } else { + node.total_mask.resize(nof_cces()); + } + + for (; node.dci_pos_idx < cce_locs.size(); ++node.dci_pos_idx) { + node.dci_pos.ncce = cce_locs[node.dci_pos_idx]; + + node.current_mask.reset(); + node.current_mask.fill(node.dci_pos.ncce, node.dci_pos.ncce + (1U << record.aggr_idx)); + if ((node.total_mask & node.current_mask).any()) { + // there is a PDCCH collision. Try another CCE position + continue; + } + + // Allocation successful + node.total_mask |= node.current_mask; + alloc_dfs.push_back(node); + record.dci->location = node.dci_pos; + return true; + } + + return false; +} + +srsran::span coreset_region::get_cce_loc_table(const alloc_record& record) const +{ + switch (record.dci->rnti_type) { + case srsran_rnti_type_ra: + return rar_cce_list[slot_idx][record.aggr_idx]; + case srsran_rnti_type_si: + return common_cce_list[record.ss_id][slot_idx][record.aggr_idx]; + case srsran_rnti_type_c: + case srsran_rnti_type_tc: + case srsran_rnti_type_mcs_c: + case srsran_rnti_type_sp_csi: + return record.ue->cce_pos_list(record.ss_id, slot_idx, record.aggr_idx); + default: + srsran_terminate("Invalid RNTI type=%s", srsran_rnti_type_str(record.dci->rnti_type)); + break; + } + return {}; +} + +void coreset_region::print_allocations(fmt::memory_buffer& fmtbuf) const +{ + if (not dci_list.empty()) { + fmt::format_to(fmtbuf, "CORESET#{} (#CCEs={}):\n", coreset_id, nof_cces()); + } + for (const alloc_record& dci : dci_list) { + fmt::format_to(fmtbuf, + " {}-rnti=0x{:x}: ({}, {})\n", + srsran_rnti_type_str_short(dci.dci->rnti_type), + dci.dci->rnti, + dci.dci->location.ncce, + dci.dci->location.L); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bwp_pdcch_allocator::bwp_pdcch_allocator(const bwp_params_t& bwp_cfg_, + uint32_t slot_idx_, + pdcch_dl_list_t& dl_pdcchs, + pdcch_ul_list_t& ul_pdcchs) : + bwp_cfg(bwp_cfg_), pdcch_dl_list(dl_pdcchs), pdcch_ul_list(ul_pdcchs), slot_idx(slot_idx_), logger(bwp_cfg_.logger) +{ + for (uint32_t cs_idx = 0; cs_idx < SRSRAN_UE_DL_NR_MAX_NOF_CORESET; ++cs_idx) { + if (bwp_cfg.cfg.pdcch.coreset_present[cs_idx]) { + uint32_t cs_id = bwp_cfg.cfg.pdcch.coreset[cs_idx].id; + coresets.emplace(cs_id, bwp_cfg, cs_id, slot_idx); + } + } +} + +void bwp_pdcch_allocator::fill_dci_ctx_common(srsran_dci_ctx_t& dci, + srsran_rnti_type_t rnti_type, + uint16_t rnti, + const srsran_search_space_t& ss, + srsran_dci_format_nr_t dci_fmt, + const ue_carrier_params_t* ue) +{ + // Note: Location is filled by coreset_region class. + dci.ss_type = ss.type; + dci.coreset_id = ss.coreset_id; + const srsran_coreset_t* coreset = + ue == nullptr ? &bwp_cfg.cfg.pdcch.coreset[ss.coreset_id] : &ue->phy().pdcch.coreset[ss.coreset_id]; + dci.coreset_start_rb = srsran_coreset_start_rb(coreset); + dci.rnti_type = rnti_type; + dci.rnti = rnti; + dci.format = dci_fmt; +} + +pdcch_dl_alloc_result bwp_pdcch_allocator::alloc_rar_pdcch(uint16_t ra_rnti, uint32_t aggr_idx) +{ + srsran_assert(bwp_cfg.cfg.pdcch.ra_search_space_present, "Allocating RAR PDCCH in BWP without RA SearchSpace"); + return alloc_dl_pdcch_common( + srsran_rnti_type_ra, ra_rnti, bwp_cfg.cfg.pdcch.ra_search_space.id, aggr_idx, srsran_dci_format_nr_1_0, nullptr); +} + +pdcch_dl_alloc_result bwp_pdcch_allocator::alloc_si_pdcch(uint32_t ss_id, uint32_t aggr_idx) +{ + return alloc_dl_pdcch_common(srsran_rnti_type_si, SRSRAN_SIRNTI, ss_id, aggr_idx, srsran_dci_format_nr_1_0, nullptr); +} + +pdcch_dl_alloc_result bwp_pdcch_allocator::alloc_dl_pdcch(srsran_rnti_type_t rnti_type, + uint32_t ss_id, + uint32_t aggr_idx, + const ue_carrier_params_t& user) +{ + static const srsran_dci_format_nr_t dci_fmt = srsran_dci_format_nr_1_0; // TODO: make it configurable + srsran_assert(rnti_type == srsran_rnti_type_c or rnti_type == srsran_rnti_type_tc, + "Invalid RNTI type=%s for UE-specific PDCCH", + srsran_rnti_type_str_short(rnti_type)); + return alloc_dl_pdcch_common(rnti_type, user.rnti, ss_id, aggr_idx, dci_fmt, &user); +} + +pdcch_dl_alloc_result bwp_pdcch_allocator::alloc_dl_pdcch_common(srsran_rnti_type_t rnti_type, + uint16_t rnti, + uint32_t ss_id, + uint32_t aggr_idx, + srsran_dci_format_nr_t dci_fmt, + const ue_carrier_params_t* user) +{ + alloc_result r = check_args_valid(rnti_type, rnti, ss_id, aggr_idx, dci_fmt, user, true); + if (r != alloc_result::success) { + return {r}; + } + const srsran_search_space_t& ss = + (user == nullptr) + ? (rnti_type == srsran_rnti_type_ra ? bwp_cfg.cfg.pdcch.ra_search_space : *bwp_cfg.get_ss(ss_id)) + : *user->get_ss(ss_id); + + // Add new DL PDCCH to sched result + pdcch_dl_list.emplace_back(); + + bool success = + coresets[ss.coreset_id].alloc_pdcch(rnti_type, true, aggr_idx, ss_id, user, pdcch_dl_list.back().dci.ctx); + + if (not success) { + // Remove failed PDCCH allocation + pdcch_dl_list.pop_back(); + + // Log PDCCH allocation failure + srslog::log_channel& ch = user == nullptr ? logger.warning : logger.debug; + log_pdcch_alloc_failure(ch, rnti_type, ss_id, rnti, "No available PDCCH position"); + + return {alloc_result::no_cch_space}; + } + + // PDCCH allocation was successful + pdcch_dl_t& pdcch = pdcch_dl_list.back(); + + // Fill DCI with semi-static config + fill_dci_from_cfg(bwp_cfg, pdcch.dci); + + // Fill DCI context information + fill_dci_ctx_common(pdcch.dci.ctx, rnti_type, rnti, ss, dci_fmt, user); + + // register last PDCCH coreset, in case it needs to be aborted + pending_dci = &pdcch.dci.ctx; + + return {&pdcch}; +} + +pdcch_ul_alloc_result +bwp_pdcch_allocator::alloc_ul_pdcch(uint32_t ss_id, uint32_t aggr_idx, const ue_carrier_params_t& user) +{ + static const srsran_dci_format_nr_t dci_fmt = srsran_dci_format_nr_0_0; // TODO: make it configurable + alloc_result r = check_args_valid(srsran_rnti_type_c, user.rnti, ss_id, aggr_idx, dci_fmt, &user, false); + if (r != alloc_result::success) { + return {r}; + } + const srsran_search_space_t& ss = *user.get_ss(ss_id); + + // Add new UL PDCCH to sched result + pdcch_ul_list.emplace_back(); + + bool success = coresets[ss.coreset_id].alloc_pdcch( + srsran_rnti_type_c, false, aggr_idx, ss_id, &user, pdcch_ul_list.back().dci.ctx); + + if (not success) { + // Remove failed PDCCH allocation + pdcch_ul_list.pop_back(); + + // Log PDCCH allocation failure + log_pdcch_alloc_failure(logger.debug, srsran_rnti_type_c, ss_id, user.rnti, "No available PDCCH position"); + + return {alloc_result::no_cch_space}; + } + + // PDCCH allocation was successful + pdcch_ul_t& pdcch = pdcch_ul_list.back(); + + // Fill DCI with semi-static config + fill_dci_from_cfg(bwp_cfg, pdcch.dci); + + // Fill DCI context information + fill_dci_ctx_common(pdcch.dci.ctx, srsran_rnti_type_c, user.rnti, ss, dci_fmt, &user); + + // register last PDCCH coreset, in case it needs to be aborted + pending_dci = &pdcch.dci.ctx; + + return {&pdcch}; +} + +void bwp_pdcch_allocator::cancel_last_pdcch() +{ + srsran_assert(pending_dci != nullptr, "Trying to abort PDCCH allocation that does not exist"); + uint32_t cs_id = pending_dci->coreset_id; + + if (&pdcch_dl_list.back().dci.ctx == pending_dci) { + pdcch_dl_list.pop_back(); + } else if (&pdcch_ul_list.back().dci.ctx == pending_dci) { + pdcch_ul_list.pop_back(); + } else { + logger.error("Invalid DCI context provided to be removed"); + return; + } + coresets[cs_id].rem_last_pdcch(); + pending_dci = nullptr; +} + +void bwp_pdcch_allocator::reset() +{ + pending_dci = nullptr; + pdcch_dl_list.clear(); + pdcch_ul_list.clear(); + for (coreset_region& coreset : coresets) { + coreset.reset(); + } +} + +uint32_t bwp_pdcch_allocator::nof_allocations() const +{ + uint32_t count = 0; + for (const coreset_region& coreset : coresets) { + count += coreset.nof_allocs(); + } + return count; +} + +uint32_t bwp_pdcch_allocator::nof_cces(uint32_t coreset_id) const +{ + return coresets[coreset_id].nof_cces(); +} + +alloc_result bwp_pdcch_allocator::check_args_valid(srsran_rnti_type_t rnti_type, + uint16_t rnti, + uint32_t ss_id, + uint32_t aggr_idx, + srsran_dci_format_nr_t dci_fmt, + const ue_carrier_params_t* user, + bool is_dl) const +{ + srsran_assert(ss_id < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE, "Invalid SearchSpace#%d", ss_id); + srsran_assert( + aggr_idx < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR, "Invalid aggregation level index=%d", aggr_idx); + + // DL must be active in given slot + if (not bwp_cfg.slots[slot_idx].is_dl) { + log_pdcch_alloc_failure(logger.error, rnti_type, ss_id, rnti, "DL is disabled for slot={}", slot_idx); + return alloc_result::no_cch_space; + } + + // Verify SearchSpace validity + const srsran_search_space_t* ss = + (user == nullptr) + ? (rnti_type == srsran_rnti_type_ra ? &bwp_cfg.cfg.pdcch.ra_search_space : bwp_cfg.get_ss(ss_id)) + : user->get_ss(ss_id); + if (ss == nullptr) { + // Couldn't find SearchSpace + log_pdcch_alloc_failure(logger.error, rnti_type, ss_id, rnti, "SearchSpace has not been configured"); + return alloc_result::invalid_grant_params; + } + if (ss->nof_candidates[aggr_idx] == 0) { + // No valid DCI position candidates given aggregation level + log_pdcch_alloc_failure( + logger.warning, rnti_type, ss_id, rnti, "Chosen SearchSpace doesn't have CCE candidates for L={}", aggr_idx); + return alloc_result::invalid_grant_params; + } + if (not is_rnti_type_valid_in_search_space(rnti_type, ss->type)) { + // RNTI type doesnt match SearchSpace type + log_pdcch_alloc_failure(logger.warning, + rnti_type, + ss_id, + rnti, + "Chosen SearchSpace type \"{}\" does not match rnti_type.", + srsran_ss_type_str(ss->type)); + return alloc_result::invalid_grant_params; + } + auto dci_fmt_equal = [dci_fmt](srsran_dci_format_nr_t f) { return f == dci_fmt; }; + if (std::none_of(&ss->formats[0], &ss->formats[ss->nof_formats], dci_fmt_equal)) { + log_pdcch_alloc_failure(logger.warning, + rnti_type, + ss_id, + rnti, + "Chosen SearchSpace does not support chosen dci format={}", + srsran_dci_format_nr_string(dci_fmt)); + return alloc_result::invalid_grant_params; + } + + if (is_dl) { + if (pdcch_dl_list.full()) { + log_pdcch_alloc_failure( + logger.warning, rnti_type, ss_id, rnti, "Maximum number of allocations={} reached", pdcch_dl_list.size()); + return alloc_result::no_cch_space; + } + } else if (pdcch_ul_list.full()) { + log_pdcch_alloc_failure( + logger.warning, rnti_type, ss_id, rnti, "Maximum number of UL allocations={} reached", pdcch_ul_list.size()); + return alloc_result::no_cch_space; + } + + if (user != nullptr) { + if (user->active_bwp().bwp_id != bwp_cfg.bwp_id) { + log_pdcch_alloc_failure(logger.warning, + rnti_type, + ss_id, + rnti, + "Trying to allocate BWP#{} which is inactive for the UE.", + user->active_bwp().bwp_id); + return alloc_result::no_rnti_opportunity; + } + } + + srsran_sanity_check(pdcch_dl_list.size() + pdcch_ul_list.size() == nof_allocations(), "Invalid PDCCH state"); + return alloc_result::success; +} + +void bwp_pdcch_allocator::print_allocations(fmt::memory_buffer& fmtbuf) const +{ + fmt::format_to( + fmtbuf, "PDCCH allocations: ({} active coresets):{}\n", coresets.size(), nof_allocations() == 0 ? " None" : ""); + for (const coreset_region& cs : coresets) { + cs.print_allocations(fmtbuf); + } +} + +std::string bwp_pdcch_allocator::print_allocations() const +{ + fmt::memory_buffer fmtbuf; + print_allocations(fmtbuf); + return fmt::to_string(fmtbuf); +} + +} // namespace sched_nr_impl +} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_rb.cc b/srsgnb/src/stack/mac/sched_nr_rb.cc similarity index 97% rename from srsenb/src/stack/mac/nr/sched_nr_rb.cc rename to srsgnb/src/stack/mac/sched_nr_rb.cc index f826d5ccf9..e4dde70702 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_rb.cc +++ b/srsgnb/src/stack/mac/sched_nr_rb.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,7 +19,7 @@ * */ -#include "srsenb/hdr/stack/mac/nr/sched_nr_rb.h" +#include "srsgnb/hdr/stack/mac/sched_nr_rb.h" namespace srsenb { namespace sched_nr_impl { diff --git a/srsgnb/src/stack/mac/sched_nr_sch.cc b/srsgnb/src/stack/mac/sched_nr_sch.cc new file mode 100644 index 0000000000..cd7c161269 --- /dev/null +++ b/srsgnb/src/stack/mac/sched_nr_sch.cc @@ -0,0 +1,371 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/mac/sched_nr_sch.h" +#include "srsran/common/string_helpers.h" + +namespace srsenb { +namespace sched_nr_impl { + +template +void log_alloc_failure(srslog::log_channel& log_ch, const char* cause_fmt, Args&&... args) +{ + if (not log_ch.enabled()) { + return; + } + + // Log allocation failure + fmt::memory_buffer fmtbuf; + fmt::format_to(fmtbuf, "SCHED: Failure to allocate PDSCH. Cause: "); + fmt::format_to(fmtbuf, cause_fmt, std::forward(args)...); + log_ch("%s", srsran::to_c_str(fmtbuf)); +} + +pdsch_allocator::pdsch_allocator(const bwp_params_t& cfg_, uint32_t slot_index, pdsch_list_t& pdsch_lst) : + bwp_cfg(cfg_), + slot_idx(slot_index), + pdschs(pdsch_lst), + dl_prbs(bwp_cfg.cfg.rb_width, bwp_cfg.cfg.start_rb, bwp_cfg.cfg.pdsch.rbg_size_cfg_1) +{} + +void pdsch_allocator::reset() +{ + pdschs.clear(); + dl_prbs.reset(); +} + +alloc_result pdsch_allocator::is_grant_valid_common(srsran_search_space_type_t ss_type, + srsran_dci_format_nr_t dci_fmt, + uint32_t coreset_id, + const prb_grant& grant) const +{ + // DL must be active in given slot + if (not bwp_cfg.slots[slot_idx].is_dl) { + log_alloc_failure(bwp_cfg.logger.error, "DL is disabled for slot={}", slot_idx); + return alloc_result::no_sch_space; + } + + // No space in Scheduler PDSCH output list + if (pdschs.full()) { + log_alloc_failure(bwp_cfg.logger.warning, "Maximum number of PDSCHs={} reached.", pdschs.size()); + return alloc_result::no_sch_space; + } + + // TS 38.214, 5.1.2.2 - "The UE shall assume that when the scheduling grant is received with DCI format 1_0, then + // downlink resource allocation type 1 is used." + if (dci_fmt == srsran_dci_format_nr_1_0 and not grant.is_alloc_type1()) { + log_alloc_failure(bwp_cfg.logger.warning, "DL Resource Allocation type 1 must be used in case of DCI format 1_0."); + return alloc_result::invalid_grant_params; + } + + // TS 38.214 - 5.1.2.2 - For DCI format 1_0 and Common Search Space, the list of available PRBs is limited by the + // rb_start and bandwidth of the coreset + if (dci_fmt == srsran_dci_format_nr_1_0 and SRSRAN_SEARCH_SPACE_IS_COMMON(ss_type)) { + // Grant PRBs do not collide with CORESET PRB limits (in case of common SearchSpace) + if (bwp_cfg.dci_fmt_1_0_excluded_prbs(coreset_id).collides(grant)) { + log_alloc_failure( + bwp_cfg.logger.debug, "Provided PRB grant={:x} falls outside common CORESET PRB boundaries.", grant); + return alloc_result::sch_collision; + } + } + + // Grant PRBs do not collide with previous PDSCH allocations + if (dl_prbs.collides(grant)) { + log_alloc_failure( + bwp_cfg.logger.debug, "Provided PRB grant={:x} collides with allocations previously made.", grant); + return alloc_result::sch_collision; + } + + return alloc_result::success; +} + +alloc_result pdsch_allocator::is_si_grant_valid(uint32_t ss_id, const prb_grant& grant) const +{ + // Verify SearchSpace validity + const srsran_search_space_t* ss = bwp_cfg.get_ss(ss_id); + if (ss == nullptr) { + // Couldn't find SearchSpace + log_alloc_failure(bwp_cfg.logger.error, "SearchSpace has not been configured."); + return alloc_result::invalid_grant_params; + } + return is_grant_valid_common(ss->type, srsran_dci_format_nr_1_0, ss->coreset_id, grant); +} + +alloc_result pdsch_allocator::is_rar_grant_valid(const prb_grant& grant) const +{ + srsran_sanity_check(bwp_cfg.cfg.pdcch.ra_search_space_present, + "Attempting RAR allocation in BWP with no raSearchSpace"); + return is_grant_valid_common(bwp_cfg.cfg.pdcch.ra_search_space.type, + srsran_dci_format_nr_1_0, + bwp_cfg.cfg.pdcch.ra_search_space.coreset_id, + grant); +} + +alloc_result pdsch_allocator::is_ue_grant_valid(const ue_carrier_params_t& ue, + uint32_t ss_id, + srsran_dci_format_nr_t dci_fmt, + const prb_grant& grant) const +{ + const srsran_search_space_t* ss = ue.get_ss(ss_id); + if (ss == nullptr) { + // Couldn't find SearchSpace + log_alloc_failure(bwp_cfg.logger.error, "rnti=0x%x,SearchSpaceId={} has not been configured.", ue.rnti, ss_id); + return alloc_result::invalid_grant_params; + } + alloc_result ret = is_grant_valid_common(ss->type, dci_fmt, ss->coreset_id, grant); + if (ret != alloc_result::success) { + return ret; + } + + // TS 38.214, 5.1.2.2 - "the UE shall use the downlink frequency resource allocation type as defined by the higher + // layer parameter resourceAllocation" + if (ue.phy().pdsch.alloc != srsran_resource_alloc_dynamic) { + if ((ue.phy().pdsch.alloc == srsran_resource_alloc_type0) != grant.is_alloc_type0()) { + log_alloc_failure(bwp_cfg.logger.warning, + "UE rnti=0x{:x} PDSCH RA configuration type {} doesn't match grant type", + ue.rnti, + grant.is_alloc_type0() ? 0 : 1); + return alloc_result::invalid_grant_params; + } + } + + return alloc_result::success; +} + +pdsch_alloc_result pdsch_allocator::alloc_si_pdsch(uint32_t ss_id, const prb_grant& grant, srsran_dci_dl_nr_t& dci) +{ + alloc_result code = is_si_grant_valid(ss_id, grant); + if (code != alloc_result::success) { + return code; + } + return {&alloc_si_pdsch_unchecked(ss_id, grant, dci)}; +} + +pdsch_t& pdsch_allocator::alloc_si_pdsch_unchecked(uint32_t ss_id, const prb_grant& grant, srsran_dci_dl_nr_t& dci) +{ + // Verify SearchSpace validity + const srsran_search_space_t* ss = bwp_cfg.get_ss(ss_id); + srsran_sanity_check(ss != nullptr, "SearchSpace has not been configured"); + return alloc_pdsch_unchecked(ss->coreset_id, ss->type, srsran_dci_format_nr_1_0, grant, dci); +} + +pdsch_alloc_result pdsch_allocator::alloc_rar_pdsch(const prb_grant& grant, srsran_dci_dl_nr_t& dci) +{ + alloc_result code = is_rar_grant_valid(grant); + if (code != alloc_result::success) { + return code; + } + return {&alloc_rar_pdsch_unchecked(grant, dci)}; +} + +pdsch_t& pdsch_allocator::alloc_rar_pdsch_unchecked(const prb_grant& grant, srsran_dci_dl_nr_t& dci) +{ + // TS 38.213, 8.2 - "In response to a PRACH transmission, a UE attempts to detect a DCI format 1_0" + const static srsran_dci_format_nr_t dci_fmt = srsran_dci_format_nr_1_0; + + return alloc_pdsch_unchecked( + bwp_cfg.cfg.pdcch.ra_search_space.coreset_id, bwp_cfg.cfg.pdcch.ra_search_space.type, dci_fmt, grant, dci); +} + +pdsch_alloc_result pdsch_allocator::alloc_ue_pdsch(uint32_t ss_id, + srsran_dci_format_nr_t dci_fmt, + const prb_grant& grant, + const ue_carrier_params_t& ue, + srsran_dci_dl_nr_t& dci) +{ + alloc_result code = is_ue_grant_valid(ue, ss_id, dci_fmt, grant); + if (code != alloc_result::success) { + return code; + } + return {&alloc_ue_pdsch_unchecked(ss_id, dci_fmt, grant, ue, dci)}; +} + +pdsch_t& pdsch_allocator::alloc_ue_pdsch_unchecked(uint32_t ss_id, + srsran_dci_format_nr_t dci_fmt, + const prb_grant& grant, + const ue_carrier_params_t& ue, + srsran_dci_dl_nr_t& dci) +{ + const srsran_search_space_t* ss = ue.get_ss(ss_id); + srsran_sanity_check(ss != nullptr, "SearchSpace has not been configured"); + return alloc_pdsch_unchecked(ss->coreset_id, ss->type, dci_fmt, grant, dci); +} + +pdsch_t& pdsch_allocator::alloc_pdsch_unchecked(uint32_t coreset_id, + srsran_search_space_type_t ss_type, + srsran_dci_format_nr_t dci_fmt, + const prb_grant& grant, + srsran_dci_dl_nr_t& out_dci) +{ + // Create new PDSCH entry in output PDSCH list + pdschs.emplace_back(); + pdsch_t& pdsch = pdschs.back(); + + // Register allocated PRBs in accumulated bitmap + dl_prbs |= grant; + + // Fill DCI with PDSCH freq/time allocation information + out_dci.time_domain_assigment = 0; + if (grant.is_alloc_type0()) { + out_dci.freq_domain_assigment = grant.rbgs().to_uint64(); + } else { + uint32_t rb_start = grant.prbs().start(), nof_prb = bwp_cfg.nof_prb; + if (SRSRAN_SEARCH_SPACE_IS_COMMON(ss_type)) { + prb_interval lims = bwp_cfg.coreset_prb_range(coreset_id); + if (dci_fmt == srsran_dci_format_nr_1_0) { + srsran_sanity_check(rb_start >= lims.start(), "Invalid PRB grant"); + rb_start -= lims.start(); + } + if (coreset_id == 0) { + nof_prb = lims.length(); + } + } + srsran_sanity_check(rb_start + grant.prbs().length() <= nof_prb, "Invalid PRB grant"); + out_dci.freq_domain_assigment = srsran_ra_nr_type1_riv(nof_prb, rb_start, grant.prbs().length()); + } + + return pdsch; +} + +void pdsch_allocator::cancel_last_pdsch() +{ + srsran_assert(not pdschs.empty(), "Trying to abort PDSCH allocation that does not exist"); + pdschs.pop_back(); + // TODO: clear bitmap allocated RBs +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +template +void log_pusch_alloc_failure(srslog::log_channel& log_ch, const char* cause_fmt, Args&&... args) +{ + if (not log_ch.enabled()) { + return; + } + + // Log allocation failure + fmt::memory_buffer fmtbuf; + fmt::format_to(fmtbuf, "SCHED: Failure to allocate PUSCH. Cause: "); + fmt::format_to(fmtbuf, cause_fmt, std::forward(args)...); + log_ch("%s", srsran::to_c_str(fmtbuf)); +} + +pusch_allocator::pusch_allocator(const bwp_params_t& cfg_, uint32_t sl_index, pusch_list_t& pusch_lst) : + bwp_cfg(cfg_), + slot_idx(sl_index), + puschs(pusch_lst), + ul_prbs(bwp_cfg.cfg.rb_width, bwp_cfg.cfg.start_rb, bwp_cfg.cfg.pdsch.rbg_size_cfg_1) +{} + +void pusch_allocator::reset() +{ + puschs.clear(); + ul_prbs.reset(); +} + +alloc_result pusch_allocator::has_grant_space(uint32_t nof_grants, bool verbose) const +{ + // UL must be active in given slot + if (not bwp_cfg.slots[slot_idx].is_ul) { + if (verbose) { + log_pusch_alloc_failure(bwp_cfg.logger.error, "UL is disabled for slot={}", slot_idx); + } + return alloc_result::no_sch_space; + } + + // No space in Scheduler PDSCH output list + if (puschs.size() + nof_grants > puschs.capacity()) { + if (verbose) { + log_pusch_alloc_failure(bwp_cfg.logger.warning, "Maximum number of PUSCHs={} reached.", puschs.capacity()); + } + return alloc_result::no_sch_space; + } + + return alloc_result::success; +} + +alloc_result +pusch_allocator::is_grant_valid(srsran_search_space_type_t ss_type, const prb_grant& grant, bool verbose) const +{ + alloc_result ret = has_grant_space(1, verbose); + if (ret != alloc_result::success) { + return ret; + } + + if (SRSRAN_SEARCH_SPACE_IS_COMMON(ss_type)) { + // In case of common SearchSpaces, the PRBs must be contiguous + if (grant.is_alloc_type0()) { + log_pusch_alloc_failure(bwp_cfg.logger.warning, "AllocType0 not allowed in common SearchSpace."); + return alloc_result::invalid_grant_params; + } + } + + // Grant PRBs do not collide with previous PDSCH allocations + if (ul_prbs.collides(grant)) { + if (verbose) { + log_pusch_alloc_failure(bwp_cfg.logger.debug, "SCHED: Provided UL PRB mask collides with previous allocations."); + } + return alloc_result::sch_collision; + } + + return alloc_result::success; +} + +pusch_alloc_result +pusch_allocator::alloc_pusch(const srsran_search_space_type_t ss_type, const prb_grant& grant, srsran_dci_ul_nr_t& dci) +{ + alloc_result code = is_grant_valid(ss_type, grant); + if (code != alloc_result::success) { + return code; + } + + return {&alloc_pusch_unchecked(grant, dci)}; +} + +pusch_t& pusch_allocator::alloc_pusch_unchecked(const prb_grant& grant, srsran_dci_ul_nr_t& out_dci) +{ + // Create new PUSCH entry in output PUSCH list + puschs.emplace_back(); + pusch_t& pusch = puschs.back(); + + // Register allocated PRBs in accumulated bitmap + ul_prbs |= grant; + + // Fill DCI with PUSCH freq/time allocation information + out_dci.time_domain_assigment = 0; + if (grant.is_alloc_type0()) { + out_dci.freq_domain_assigment = grant.rbgs().to_uint64(); + } else { + uint32_t nof_prb = bwp_cfg.nof_prb; + out_dci.freq_domain_assigment = srsran_ra_nr_type1_riv(nof_prb, grant.prbs().start(), grant.prbs().length()); + } + + return pusch; +} + +void pusch_allocator::cancel_last_pusch() +{ + srsran_assert(not puschs.empty(), "Trying to abort PUSCH allocation that does not exist"); + puschs.pop_back(); +} + +} // namespace sched_nr_impl +} // namespace srsenb \ No newline at end of file diff --git a/srsgnb/src/stack/mac/sched_nr_signalling.cc b/srsgnb/src/stack/mac/sched_nr_signalling.cc new file mode 100644 index 0000000000..3c4f3cc423 --- /dev/null +++ b/srsgnb/src/stack/mac/sched_nr_signalling.cc @@ -0,0 +1,216 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/mac/sched_nr_signalling.h" +#include "srsgnb/hdr/stack/mac/sched_nr_grant_allocator.h" + +#define POS_IN_BURST_FIRST_BIT_IDX 0 +#define POS_IN_BURST_SECOND_BIT_IDX 1 +#define POS_IN_BURST_THIRD_BIT_IDX 2 +#define POS_IN_BURST_FOURTH_BIT_IDX 3 + +#define DEFAULT_SSB_PERIODICITY 5 +#define MAX_SIB_TX 8 + +namespace srsenb { +namespace sched_nr_impl { + +void sched_nzp_csi_rs(srsran::const_span nzp_csi_rs_sets_cfg, + const srsran_slot_cfg_t& slot_cfg, + nzp_csi_rs_list& csi_rs_list) +{ + for (const srsran_csi_rs_nzp_set_t& set : nzp_csi_rs_sets_cfg) { + // For each NZP-CSI-RS resource available in the set + for (uint32_t i = 0; i < set.count; ++i) { + // Select resource + const srsran_csi_rs_nzp_resource_t& nzp_csi_resource = set.data[i]; + + // Check if the resource is scheduled for this slot + if (srsran_csi_rs_send(&nzp_csi_resource.periodicity, &slot_cfg)) { + if (csi_rs_list.full()) { + srslog::fetch_basic_logger("MAC-NR").error("SCHED: Failed to allocate NZP-CSI RS"); + return; + } + csi_rs_list.push_back(nzp_csi_resource); + } + } + } +} + +void sched_ssb_basic(const slot_point& sl_point, + uint32_t ssb_periodicity, + const srsran_mib_nr_t& mib, + ssb_list& ssb_list) +{ + if (ssb_list.full()) { + srslog::fetch_basic_logger("MAC-NR").error("SCHED: Failed to allocate SSB"); + return; + } + // If the periodicity is 0, it means that the parameter was not passed by the upper layers. + // In that case, we use default value of 5ms (see Clause 4.1, TS 38.213) + if (ssb_periodicity == 0) { + ssb_periodicity = DEFAULT_SSB_PERIODICITY; + } + + uint32_t sl_cnt = sl_point.to_uint(); + // Perform mod operation of slot index by ssb_periodicity; + // "ssb_periodicity * nof_slots_per_subframe" gives the number of slots in 1 ssb_periodicity time interval + uint32_t sl_point_mod = sl_cnt % (ssb_periodicity * (uint32_t)sl_point.nof_slots_per_subframe()); + + // code below is simplified, it assumes 15kHz subcarrier spacing and sub 3GHz carrier + if (sl_point_mod == 0) { + ssb_t ssb_msg = {}; + srsran_mib_nr_t mib_msg = mib; + mib_msg.sfn = sl_point.sfn(); + mib_msg.hrf = (sl_point.slot_idx() % SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) >= + SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) / 2); + // This corresponds to "Position in Burst" = 1000 + mib_msg.ssb_idx = 0; + // Remaining MIB parameters remain constant + + // Pack mib message to be sent to PHY + int packing_ret_code = srsran_pbch_msg_nr_mib_pack(&mib_msg, &ssb_msg.pbch_msg); + srsran_assert(packing_ret_code == SRSRAN_SUCCESS, "SSB packing returned en error"); + ssb_list.push_back(ssb_msg); + } +} + +void sched_dl_signalling(bwp_slot_allocator& bwp_alloc) +{ + const bwp_params_t& bwp_params = bwp_alloc.cfg; + slot_point sl_pdcch = bwp_alloc.get_pdcch_tti(); + bwp_slot_grid& sl_grid = bwp_alloc.tx_slot_grid(); + + srsran_slot_cfg_t cfg; + cfg.idx = sl_pdcch.to_uint(); + + // Schedule SSB + sched_ssb_basic(sl_pdcch, bwp_params.cell_cfg.ssb.periodicity_ms, bwp_params.cell_cfg.mib, sl_grid.dl.phy.ssb); + + // Mark SSB region as occupied + if (!sl_grid.dl.phy.ssb.empty()) { + float ssb_offset_hz = + bwp_params.cell_cfg.carrier.ssb_center_freq_hz - bwp_params.cell_cfg.carrier.dl_center_frequency_hz; + int ssb_offset_rb = ceil(ssb_offset_hz / (15000.0f * 12)); + int ssb_start_rb = bwp_params.cell_cfg.carrier.nof_prb / 2 + ssb_offset_rb - 10; + uint32_t ssb_len_rb = 20; + assert(ssb_start_rb >= 0 && ssb_start_rb + ssb_len_rb < bwp_params.cell_cfg.carrier.nof_prb); + sl_grid.reserve_pdsch(prb_grant({(uint32_t)ssb_start_rb, ssb_start_rb + ssb_len_rb})); + } + + // Schedule NZP-CSI-RS + sched_nzp_csi_rs(bwp_params.cfg.pdsch.nzp_csi_rs_sets, cfg, sl_grid.dl.phy.nzp_csi_rs); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +si_sched::si_sched(const bwp_params_t& bwp_cfg_) : + bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger(bwp_cfg_.sched_cfg.logger_name)) +{ + for (uint32_t i = 0; i < bwp_cfg->cell_cfg.sibs.size(); ++i) { + pending_sis.emplace_back(); + si_msg_ctxt_t& si = pending_sis.back(); + si.n = i; + si.len_bytes = bwp_cfg->cell_cfg.sibs[i].len; + si.period_frames = bwp_cfg->cell_cfg.sibs[i].period_rf; + si.win_len_slots = bwp_cfg->cell_cfg.sibs[i].si_window_slots; + si.si_softbuffer = harq_softbuffer_pool::get_instance().get_tx(bwp_cfg->nof_prb); + } +} + +void si_sched::run_slot(bwp_slot_allocator& bwp_alloc) +{ + if (not bwp_alloc.cfg.cfg.pdcch.coreset_present[0]) { + // CORESET#0 must be present, otherwise SIs are not allocated + // TODO: provide proper config + return; + } + const uint32_t si_aggr_level = 2; + const uint32_t ss_id = 0; + slot_point sl_pdcch = bwp_alloc.get_pdcch_tti(); + prb_bitmap prbs = bwp_alloc.res_grid()[sl_pdcch].pdschs.occupied_prbs(ss_id, srsran_dci_format_nr_1_0); + + // Update SI windows + uint32_t N = bwp_cfg->slots.size(); + for (si_msg_ctxt_t& si : pending_sis) { + uint32_t x = (si.n - 1) * si.win_len_slots; + + if (not si.win_start.valid()) { + bool start_window; + if (si.n == 0) { + // SIB1 (slot index zero of even frames) + start_window = sl_pdcch.slot_idx() == 0 and sl_pdcch.sfn() % 2 == 0; + } else { + // 5.2.2.3.2 - Acquisition of SI message + start_window = + (sl_pdcch.sfn() % si.period_frames == x / N) and sl_pdcch.slot_idx() == x % bwp_cfg->slots.size(); + } + if (start_window) { + // If start of SI message window + si.win_start = sl_pdcch; + si.n_tx = 0; + } + } else if (si.win_start + si.win_len_slots >= sl_pdcch) { + // If end of SI message window + srsran_always_assert( + si.n == 0, "SCHED: Could not allocate SIB1, len=%d. Cause: %s", si.len_bytes, to_string(si.result)); + logger.warning( + "SCHED: Could not allocate SI message idx=%d, len=%d. Cause: %s", si.n, si.len_bytes, to_string(si.result)); + si.win_start.clear(); + } + } + + // Schedule pending SIBs + if (not bwp_cfg->slots[sl_pdcch.slot_idx()].is_dl) { + return; + } + for (si_msg_ctxt_t& si : pending_sis) { + if (not si.win_start.valid() or si.n_tx >= MAX_SIB_TX) { + continue; + } + + // Attempt grants with increasing number of PRBs (if the number of PRBs is too low, the coderate is invalid) + si.result = alloc_result::invalid_coderate; + uint32_t nprbs = 8; + prb_interval grant = find_empty_interval_of_length(prbs, nprbs, 0); + if (grant.length() >= nprbs) { + si.result = bwp_alloc.alloc_si(si_aggr_level, si.n, si.n_tx, grant, *si.si_softbuffer.get()); + if (si.result == alloc_result::success) { + // SIB scheduled successfully + si.win_start.clear(); + si.n_tx++; + if (si.n == 0) { + logger.debug("SCHED: Allocated SIB1, len=%d.", si.len_bytes); + } else { + logger.debug("SCHED: Allocated SI message idx=%d, len=%d.", si.n, si.len_bytes); + } + } + } + if (si.result != alloc_result::success) { + logger.warning("SCHED: Failed to allocate SI%s%d ntx=%d", si.n == 0 ? "B" : " message idx=", si.n + 1, si.n_tx); + } + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +} // namespace sched_nr_impl +} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_time_rr.cc b/srsgnb/src/stack/mac/sched_nr_time_rr.cc similarity index 66% rename from srsenb/src/stack/mac/nr/sched_nr_time_rr.cc rename to srsgnb/src/stack/mac/sched_nr_time_rr.cc index 24b8e2044b..437eb05106 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_time_rr.cc +++ b/srsgnb/src/stack/mac/sched_nr_time_rr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,11 +19,18 @@ * */ -#include "srsenb/hdr/stack/mac/nr/sched_nr_time_rr.h" +#include "srsgnb/hdr/stack/mac/sched_nr_time_rr.h" namespace srsenb { namespace sched_nr_impl { +/** + * @brief Algorithm to select next UE to allocate in a time-domain RR fashion + * @param ue_db map of "slot_ue" + * @param rr_count starting index to select next UE + * @param p callable with signature "bool(slot_ue&)" that returns true if UE allocation was successful + * @return true if a UE was allocated + */ template bool round_robin_apply(slot_ue_map_t& ue_db, uint32_t rr_count, Predicate p) { @@ -34,6 +41,7 @@ bool round_robin_apply(slot_ue_map_t& ue_db, uint32_t rr_count, Predicate p) std::advance(it, (rr_count % ue_db.size())); for (uint32_t count = 0; count < ue_db.size(); ++count, ++it) { if (it == ue_db.end()) { + // wrap-around it = ue_db.begin(); } if (p(it->second)) { @@ -46,28 +54,35 @@ bool round_robin_apply(slot_ue_map_t& ue_db, uint32_t rr_count, Predicate p) void sched_nr_time_rr::sched_dl_users(slot_ue_map_t& ue_db, bwp_slot_allocator& slot_alloc) { // Start with retxs - if (round_robin_apply(ue_db, slot_alloc.get_pdcch_tti().to_uint(), [&slot_alloc](slot_ue& ue) { - if (ue.h_dl != nullptr and ue.h_dl->has_pending_retx(slot_alloc.get_tti_rx())) { - alloc_result res = slot_alloc.alloc_pdsch(ue, ue.h_dl->prbs()); - if (res == alloc_result::success) { - return true; - } - } - return false; - })) { + auto retx_ue_function = [&slot_alloc](slot_ue& ue) { + if (ue.h_dl != nullptr and ue.h_dl->has_pending_retx(slot_alloc.get_tti_rx())) { + alloc_result res = slot_alloc.alloc_pdsch(ue, ue->find_ss_id(srsran_dci_format_nr_1_0), ue.h_dl->prbs()); + if (res == alloc_result::success) { + return true; + } + } + return false; + }; + if (round_robin_apply(ue_db, slot_alloc.get_pdcch_tti().to_uint(), retx_ue_function)) { return; } // Move on to new txs - round_robin_apply(ue_db, slot_alloc.get_pdcch_tti().to_uint(), [&slot_alloc](slot_ue& ue) { - if (ue.h_dl != nullptr and ue.h_dl->empty()) { - alloc_result res = slot_alloc.alloc_pdsch(ue, prb_interval{0, slot_alloc.cfg.cfg.rb_width}); + auto newtx_ue_function = [&slot_alloc](slot_ue& ue) { + if (ue.dl_bytes > 0 and ue.h_dl != nullptr and ue.h_dl->empty()) { + int ss_id = ue->find_ss_id(srsran_dci_format_nr_1_0); + if (ss_id < 0) { + return false; + } + prb_grant prbs = find_optimal_dl_grant(slot_alloc, ue, ss_id); + alloc_result res = slot_alloc.alloc_pdsch(ue, ss_id, prbs); if (res == alloc_result::success) { return true; } } return false; - }); + }; + round_robin_apply(ue_db, slot_alloc.get_pdcch_tti().to_uint(), newtx_ue_function); } void sched_nr_time_rr::sched_ul_users(slot_ue_map_t& ue_db, bwp_slot_allocator& slot_alloc) @@ -87,7 +102,7 @@ void sched_nr_time_rr::sched_ul_users(slot_ue_map_t& ue_db, bwp_slot_allocator& // Move on to new txs round_robin_apply(ue_db, slot_alloc.get_pdcch_tti().to_uint(), [&slot_alloc](slot_ue& ue) { - if (ue.h_ul != nullptr and ue.h_ul->empty()) { + if (ue.ul_bytes > 0 and ue.h_ul != nullptr and ue.h_ul->empty()) { alloc_result res = slot_alloc.alloc_pusch(ue, prb_interval{0, slot_alloc.cfg.cfg.rb_width}); if (res == alloc_result::success) { return true; diff --git a/srsgnb/src/stack/mac/sched_nr_ue.cc b/srsgnb/src/stack/mac/sched_nr_ue.cc new file mode 100644 index 0000000000..c3e5f53866 --- /dev/null +++ b/srsgnb/src/stack/mac/sched_nr_ue.cc @@ -0,0 +1,262 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/mac/sched_nr_ue.h" +#include "srsgnb/hdr/stack/mac/sched_nr_helpers.h" +#include "srsran/common/string_helpers.h" +#include "srsran/mac/mac_sch_pdu_nr.h" + +namespace srsenb { +namespace sched_nr_impl { + +int ue_buffer_manager::get_dl_tx_total() const +{ + int total_bytes = base_type::get_dl_tx_total(); + for (ue_buffer_manager::ce_t ce : pending_ces) { + total_bytes += srsran::mac_sch_subpdu_nr::sizeof_ce(ce.lcid, false); + } + return total_bytes; +} + +/** + * @brief Allocates LCIDs and update US buffer states depending on available resources and checks if there is SRB0/CCCH + MAC PDU segmentation + + * @param rem_bytes TBS to be filled with MAC CEs and MAC SDUs [in bytes] + * @param reset_buf_states If true, when there is SRB0/CCCH MAC PDU segmentation, restore the UE buffers and scheduled + LCIDs as before running this function + * @return true if there is no SRB0/CCCH MAC PDU segmentation, false otherwise + */ +bool ue_buffer_manager::pdu_builder::alloc_subpdus(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu) +{ + // First step: allocate MAC CEs until resources allow + srsran::deque restore_ces; + for (ce_t ce : parent->pending_ces) { + if (ce.cc == cc) { + // Note: This check also avoids thread collisions across UE carriers + uint32_t size_ce = srsran::mac_sch_subpdu_nr::sizeof_ce(ce.lcid, false); + if (size_ce > rem_bytes) { + break; + } + rem_bytes -= size_ce; + pdu.subpdus.push_back(ce.lcid); + parent->pending_ces.pop_front(); + } + } + + // Second step: allocate the remaining LCIDs (LCIDs for MAC CEs are addressed above) + for (uint32_t lcid = 0; rem_bytes > 0 and is_lcid_valid(lcid); ++lcid) { + uint32_t pending_lcid_bytes = parent->get_dl_tx_total(lcid); + // Return false if the TBS is too small to store the entire CCCH buffer without segmentation + if (lcid == srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CCCH and pending_lcid_bytes > rem_bytes) { + pdu.subpdus.push_back(lcid); + return false; + } + if (pending_lcid_bytes > 0) { + rem_bytes -= std::min(rem_bytes, pending_lcid_bytes); + pdu.subpdus.push_back(lcid); + } + } + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +slot_ue::slot_ue(ue_carrier& ue_, slot_point slot_tx_) : ue(&ue_), pdcch_slot(slot_tx_) +{ + const uint32_t k0 = 0; + pdsch_slot = pdcch_slot + k0; + uint32_t k1 = ue->bwp_cfg.get_k1(pdsch_slot); + uci_slot = pdsch_slot + k1; + uint32_t k2 = ue->bwp_cfg.active_bwp().pusch_ra_list[0].K; + pusch_slot = pdcch_slot + k2; + + dl_active = ue->cell_params.bwps[0].slots[pdsch_slot.slot_idx()].is_dl; + if (dl_active) { + dl_bytes = ue->common_ctxt.pending_dl_bytes; + h_dl = ue->harq_ent.find_pending_dl_retx(); + if (h_dl == nullptr) { + h_dl = ue->harq_ent.find_empty_dl_harq(); + } + } + ul_active = ue->cell_params.bwps[0].slots[pusch_slot.slot_idx()].is_ul; + if (ul_active) { + ul_bytes = ue->common_ctxt.pending_ul_bytes; + h_ul = ue->harq_ent.find_pending_ul_retx(); + if (h_ul == nullptr) { + h_ul = ue->harq_ent.find_empty_ul_harq(); + } + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +ue_carrier::ue_carrier(uint16_t rnti_, + const ue_cfg_manager& uecfg_, + const cell_config_manager& cell_params_, + const ue_context_common& ctxt, + const ue_buffer_manager::pdu_builder& pdu_builder_) : + rnti(rnti_), + cc(cell_params_.cc), + logger(srslog::fetch_basic_logger(cell_params_.sched_args.logger_name)), + bwp_cfg(rnti_, cell_params_.bwps[0], uecfg_), + cell_params(cell_params_), + pdu_builder(pdu_builder_), + common_ctxt(ctxt), + harq_ent(rnti_, cell_params_.nof_prb(), SCHED_NR_MAX_HARQ, cell_params_.bwps[0].logger) +{} + +void ue_carrier::set_cfg(const ue_cfg_manager& ue_cfg) +{ + bwp_cfg = ue_carrier_params_t(rnti, cell_params.bwps[0], ue_cfg); +} + +int ue_carrier::dl_ack_info(uint32_t pid, uint32_t tb_idx, bool ack) +{ + int tbs = harq_ent.dl_ack_info(pid, tb_idx, ack); + if (tbs < 0) { + logger.warning("SCHED: rnti=0x%x received DL HARQ-ACK for empty pid=%d", rnti, pid); + return tbs; + } + if (ack) { + metrics.tx_brate += tbs; + } else { + metrics.tx_errors++; + } + metrics.tx_pkts++; + return tbs; +} + +int ue_carrier::ul_crc_info(uint32_t pid, bool crc) +{ + int ret = harq_ent.ul_crc_info(pid, crc); + if (ret < 0) { + logger.warning("SCHED: rnti=0x%x,cc=%d received CRC for empty pid=%d", rnti, cc, pid); + } + return ret; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/// Generate basic UE config at the point of RACH +sched_nr_ue_cfg_t get_rach_ue_cfg_helper(uint32_t cc, const sched_params_t& sched_params) +{ + sched_nr_ue_cfg_t uecfg = {}; + uecfg.carriers.resize(1); + uecfg.carriers[0].active = true; + uecfg.carriers[0].cc = cc; + uecfg.phy_cfg = sched_params.cells[cc].default_ue_phy_cfg; + return uecfg; +} + +ue::ue(uint16_t rnti_, uint32_t cc, const sched_params_t& sched_cfg_) : + ue(rnti_, get_rach_ue_cfg_helper(cc, sched_cfg_), sched_cfg_) +{} + +ue::ue(uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg, const sched_params_t& sched_cfg_) : + rnti(rnti_), + sched_cfg(sched_cfg_), + buffers(rnti_, srslog::fetch_basic_logger(sched_cfg_.sched_cfg.logger_name)), + ue_cfg(uecfg.carriers[0].cc) +{ + set_cfg(uecfg); +} + +void ue::set_cfg(const sched_nr_ue_cfg_t& cfg) +{ + ue_cfg.apply_config_request(cfg); + for (auto& ue_cc_cfg : cfg.carriers) { + if (ue_cc_cfg.active) { + if (carriers[ue_cc_cfg.cc] == nullptr) { + carriers[ue_cc_cfg.cc] = std::make_unique(rnti, + ue_cfg, + sched_cfg.cells[ue_cc_cfg.cc], + common_ctxt, + ue_buffer_manager::pdu_builder{ue_cc_cfg.cc, buffers}); + } else { + carriers[ue_cc_cfg.cc]->set_cfg(ue_cfg); + } + } + } + + buffers.config_lcids(ue_cfg.ue_bearers); +} + +void ue::add_dl_mac_ce(uint32_t ce_lcid, uint32_t nof_cmds) +{ + for (uint32_t i = 0; i < nof_cmds; ++i) { + // If not specified otherwise, the CE is transmitted in PCell + buffers.pending_ces.push_back(ue_buffer_manager::ce_t{ce_lcid, cfg().carriers[0].cc}); + } +} + +void ue::rlc_buffer_state(uint32_t lcid, uint32_t newtx, uint32_t priotx) +{ + buffers.dl_buffer_state(lcid, newtx, priotx); +} + +void ue::new_slot(slot_point pdcch_slot) +{ + last_tx_slot = pdcch_slot; + + for (std::unique_ptr& cc : carriers) { + if (cc != nullptr) { + cc->harq_ent.new_slot(pdcch_slot - TX_ENB_DELAY); + } + } + + // Compute pending DL/UL bytes for {rnti, pdcch_slot} + if (sched_cfg.sched_cfg.auto_refill_buffer) { + common_ctxt.pending_dl_bytes = 1000000; + common_ctxt.pending_ul_bytes = 1000000; + } else { + common_ctxt.pending_dl_bytes = buffers.get_dl_tx_total(); + common_ctxt.pending_ul_bytes = buffers.get_bsr(); + for (auto& ue_cc_cfg : ue_cfg.carriers) { + auto& cc = carriers[ue_cc_cfg.cc]; + if (cc != nullptr) { + // Discount UL HARQ pending bytes to BSR + for (uint32_t pid = 0; pid < cc->harq_ent.nof_ul_harqs(); ++pid) { + if (not cc->harq_ent.ul_harq(pid).empty()) { + common_ctxt.pending_ul_bytes -= std::min(cc->harq_ent.ul_harq(pid).tbs() / 8, common_ctxt.pending_ul_bytes); + if (last_sr_slot.valid() and cc->harq_ent.ul_harq(pid).harq_slot_tx() > last_sr_slot) { + last_sr_slot.clear(); + } + } + } + } + } + if (common_ctxt.pending_ul_bytes == 0 and last_sr_slot.valid()) { + // If unanswered SR is pending + common_ctxt.pending_ul_bytes = 512; + } + } +} + +slot_ue ue::make_slot_ue(slot_point pdcch_slot, uint32_t cc) +{ + srsran_assert(carriers[cc] != nullptr, "make_slot_ue() called for unknown rnti=0x%x,cc=%d", rnti, cc); + return slot_ue(*carriers[cc], pdcch_slot); +} + +} // namespace sched_nr_impl +} // namespace srsenb diff --git a/srsgnb/src/stack/mac/sched_nr_worker.cc b/srsgnb/src/stack/mac/sched_nr_worker.cc new file mode 100644 index 0000000000..a687fcd636 --- /dev/null +++ b/srsgnb/src/stack/mac/sched_nr_worker.cc @@ -0,0 +1,224 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/mac/sched_nr_worker.h" +#include "srsenb/hdr/stack/mac/common/mac_metrics.h" +#include "srsgnb/hdr/stack/mac/sched_nr_signalling.h" +#include "srsran/common/string_helpers.h" + +namespace srsenb { +namespace sched_nr_impl { + +cc_worker::cc_worker(const cell_config_manager& params) : + cfg(params), logger(srslog::fetch_basic_logger(params.sched_args.logger_name)) +{ + for (uint32_t bwp_id = 0; bwp_id < cfg.bwps.size(); ++bwp_id) { + bwps.emplace_back(cfg.bwps[bwp_id]); + } + + // Pre-allocate HARQs in common pool of softbuffers + harq_softbuffer_pool::get_instance().init_pool(cfg.nof_prb()); +} + +void cc_worker::dl_rach_info(const sched_nr_interface::rar_info_t& rar_info) +{ + bwps[0].ra.dl_rach_info(rar_info); +} + +/// Called within a locked context, to generate {slot, cc} scheduling decision + +dl_sched_res_t* cc_worker::run_slot(slot_point tx_sl, ue_map_t& ue_db) +{ + // Reset old sched outputs + if (not last_tx_sl.valid()) { + last_tx_sl = tx_sl; + } + while (last_tx_sl != tx_sl) { + last_tx_sl++; + slot_point old_slot = last_tx_sl - TX_ENB_DELAY - 1; + for (bwp_manager& bwp : bwps) { + bwp.grid[old_slot].reset(); + } + } + + // Reserve UEs for this worker slot (select candidate UEs) + for (auto& ue_pair : ue_db) { + uint16_t rnti = ue_pair.first; + ue& u = *ue_pair.second; + if (u.carriers[cfg.cc] == nullptr) { + continue; + } + + // info for a given UE on a slot to be process + slot_ues.insert(rnti, u.make_slot_ue(tx_sl, cfg.cc)); + if (slot_ues[rnti].empty()) { + // Failed to generate slot UE because UE has no conditions for DL/UL tx + slot_ues.erase(rnti); + continue; + } + // UE acquired successfully for scheduling in this {slot, cc} + } + + // Create an BWP allocator object that will passed along to RA, SI, Data schedulers + bwp_slot_allocator bwp_alloc{bwps[0].grid, tx_sl, slot_ues}; + + // Log UEs state for slot + log_sched_slot_ues(logger, tx_sl, cfg.cc, slot_ues); + + const uint32_t ss_id = 0; + slot_point sl_pdcch = bwp_alloc.get_pdcch_tti(); + + prb_bitmap prbs_before = bwp_alloc.res_grid()[sl_pdcch].pdschs.occupied_prbs(ss_id, srsran_dci_format_nr_1_0); + // Allocate cell DL signalling + sched_dl_signalling(bwp_alloc); + + prb_bitmap prbs_after = bwp_alloc.res_grid()[sl_pdcch].pdschs.occupied_prbs(ss_id, srsran_dci_format_nr_1_0); + + // Allocate pending SIBs + bwps[0].si.run_slot(bwp_alloc); + + // Allocate pending RARs + bwps[0].ra.run_slot(bwp_alloc); + + // TODO: Prioritize PDCCH scheduling for DL and UL data in a Round-Robin fashion + alloc_dl_ues(bwp_alloc); + alloc_ul_ues(bwp_alloc); + + // Post-processing of scheduling decisions + postprocess_decisions(bwp_alloc); + + // Log CC scheduler result + log_sched_bwp_result(logger, bwp_alloc.get_pdcch_tti(), bwps[0].grid, slot_ues); + + // releases UE resources + slot_ues.clear(); + + return &bwp_alloc.tx_slot_grid().dl; +} + +ul_sched_t* cc_worker::get_ul_sched(slot_point sl) +{ + return &bwps[0].grid[sl].ul; +} + +void cc_worker::alloc_dl_ues(bwp_slot_allocator& bwp_alloc) +{ + if (not cfg.sched_args.pdsch_enabled) { + return; + } + bwps[0].data_sched->sched_dl_users(slot_ues, bwp_alloc); +} + +void cc_worker::alloc_ul_ues(bwp_slot_allocator& bwp_alloc) +{ + if (not cfg.sched_args.pusch_enabled) { + return; + } + bwps[0].data_sched->sched_ul_users(slot_ues, bwp_alloc); +} + +void cc_worker::postprocess_decisions(bwp_slot_allocator& bwp_alloc) +{ + auto& bwp_slot = bwps[0].grid[bwp_alloc.get_pdcch_tti()]; + srsran_slot_cfg_t slot_cfg{}; + slot_cfg.idx = bwp_alloc.get_pdcch_tti().to_uint(); + + for (auto& ue_pair : slot_ues) { + auto& ue = ue_pair.second; + // Group pending HARQ ACKs + srsran_pdsch_ack_nr_t ack = {}; + + for (auto& h_ack : bwp_slot.pending_acks) { + if (h_ack.res.rnti == ue->rnti) { + ack.nof_cc = 1; + + srsran_harq_ack_m_t ack_m = {}; + ack_m.resource = h_ack.res; + ack_m.present = true; + srsran_harq_ack_insert_m(&ack, &ack_m); + } + } + + srsran_uci_cfg_nr_t uci_cfg = {}; + if (not ue->phy().get_uci_cfg(slot_cfg, ack, uci_cfg)) { + logger.error("Error getting UCI configuration"); + continue; + } + + if (uci_cfg.ack.count == 0 and uci_cfg.nof_csi == 0 and uci_cfg.o_sr == 0) { + continue; + } + + bool has_pusch = false; + for (auto& pusch : bwp_slot.ul.pusch) { + if (pusch.sch.grant.rnti == ue->rnti) { + // Put UCI configuration in PUSCH config + has_pusch = true; + + // If has PUSCH, no SR shall be received + uci_cfg.o_sr = 0; + + if (not ue->phy().get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { + logger.error("Error setting UCI configuration in PUSCH"); + continue; + } + break; + } + } + if (not has_pusch) { + // If any UCI information is triggered, schedule PUCCH + if (bwp_slot.ul.pucch.full()) { + logger.warning("SCHED: Cannot fit pending UCI into PUCCH"); + continue; + } + bwp_slot.ul.pucch.emplace_back(); + mac_interface_phy_nr::pucch_t& pucch = bwp_slot.ul.pucch.back(); + + uci_cfg.pucch.rnti = ue->rnti; + pucch.candidates.emplace_back(); + pucch.candidates.back().uci_cfg = uci_cfg; + if (not ue->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { + logger.error("Error getting UCI CFG"); + continue; + } + + // If this slot has a SR opportunity and the selected PUCCH format is 1, consider positive SR. + if (uci_cfg.o_sr > 0 and uci_cfg.ack.count > 0 and + pucch.candidates.back().resource.format == SRSRAN_PUCCH_NR_FORMAT_1) { + // Set SR negative + if (uci_cfg.o_sr > 0) { + uci_cfg.sr_positive_present = false; + } + + // Append new resource + pucch.candidates.emplace_back(); + pucch.candidates.back().uci_cfg = uci_cfg; + if (not ue->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { + logger.error("Error getting UCI CFG"); + continue; + } + } + } + } +} + +} // namespace sched_nr_impl +} // namespace srsenb diff --git a/srsgnb/src/stack/mac/sched_ue/ue_cfg_manager.cc b/srsgnb/src/stack/mac/sched_ue/ue_cfg_manager.cc new file mode 100644 index 0000000000..bde876c605 --- /dev/null +++ b/srsgnb/src/stack/mac/sched_ue/ue_cfg_manager.cc @@ -0,0 +1,108 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/mac/sched_ue/ue_cfg_manager.h" +#include "srsgnb/hdr/stack/mac/sched_nr_helpers.h" +#include "srsran/asn1/rrc_nr_utils.h" + +namespace srsenb { +namespace sched_nr_impl { + +ue_cfg_manager::ue_cfg_manager(uint32_t enb_cc_idx) : carriers(1) +{ + carriers[enb_cc_idx].active = true; + carriers[enb_cc_idx].cc = enb_cc_idx; + ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; +} + +ue_cfg_manager::ue_cfg_manager(const sched_nr_ue_cfg_t& cfg_req) : ue_cfg_manager() +{ + apply_config_request(cfg_req); +} + +int ue_cfg_manager::apply_config_request(const sched_nr_ue_cfg_t& cfg_req) +{ + maxharq_tx = cfg_req.maxharq_tx; + carriers = cfg_req.carriers; + phy_cfg = cfg_req.phy_cfg; + + if (cfg_req.sp_cell_cfg.is_present()) { + srsran::make_pdsch_cfg_from_serv_cell(cfg_req.sp_cell_cfg->sp_cell_cfg_ded, &phy_cfg.pdsch); + srsran::make_csi_cfg_from_serv_cell(cfg_req.sp_cell_cfg->sp_cell_cfg_ded, &phy_cfg.csi); + } + for (uint32_t lcid : cfg_req.lc_ch_to_rem) { + assert(lcid > 0 && "LCID=0 cannot be removed"); + ue_bearers[lcid] = {}; + } + for (const sched_nr_ue_lc_ch_cfg_t& lc_ch : cfg_req.lc_ch_to_add) { + assert(lc_ch.lcid > 0 && "LCID=0 cannot be configured"); + ue_bearers[lc_ch.lcid] = lc_ch.cfg; + } + + return SRSRAN_SUCCESS; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +ue_carrier_params_t::ue_carrier_params_t(uint16_t rnti_, const bwp_params_t& bwp_cfg_, const ue_cfg_manager& uecfg_) : + rnti(rnti_), cc(bwp_cfg_.cc), cfg_(&uecfg_), bwp_cfg(&bwp_cfg_), cached_dci_cfg(uecfg_.phy_cfg.get_dci_cfg()) +{ + std::fill(ss_id_to_cce_idx.begin(), ss_id_to_cce_idx.end(), SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE); + const auto& pdcch = phy().pdcch; + auto ss_view = srsran::make_optional_span(pdcch.search_space, pdcch.search_space_present); + auto coreset_view = srsran::make_optional_span(pdcch.coreset, pdcch.coreset_present); + for (const auto& ss : ss_view) { + srsran_assert(coreset_view.contains(ss.coreset_id), + "Invalid mapping search space id=%d to coreset id=%d", + ss.id, + ss.coreset_id); + cce_positions_list.emplace_back(); + get_dci_locs(coreset_view[ss.coreset_id], ss, rnti, cce_positions_list.back()); + ss_id_to_cce_idx[ss.id] = cce_positions_list.size() - 1; + } +} + +int ue_carrier_params_t::find_ss_id(srsran_dci_format_nr_t dci_fmt) const +{ + static const uint32_t aggr_idx = 2; // TODO: Make it dynamic + static const srsran_rnti_type_t rnti_type = srsran_rnti_type_c; // TODO: Use TC-RNTI for Msg4 + + auto active_ss_lst = view_active_search_spaces(phy().pdcch); + + for (const srsran_search_space_t& ss : active_ss_lst) { + // Prioritize UE-dedicated SearchSpaces + if (ss.type == srsran_search_space_type_ue and ss.nof_candidates[aggr_idx] > 0 and + contains_dci_format(ss, dci_fmt) and is_rnti_type_valid_in_search_space(rnti_type, ss.type)) { + return ss.id; + } + } + // Search Common SearchSpaces + for (const srsran_search_space_t& ss : active_ss_lst) { + if (SRSRAN_SEARCH_SPACE_IS_COMMON(ss.type) and ss.nof_candidates[aggr_idx] > 0 and + contains_dci_format(ss, dci_fmt) and is_rnti_type_valid_in_search_space(rnti_type, ss.type)) { + return ss.id; + } + } + return -1; +} + +} // namespace sched_nr_impl +} // namespace srsenb diff --git a/srsgnb/src/stack/mac/test/CMakeLists.txt b/srsgnb/src/stack/mac/test/CMakeLists.txt new file mode 100644 index 0000000000..d7689ec396 --- /dev/null +++ b/srsgnb/src/stack/mac/test/CMakeLists.txt @@ -0,0 +1,68 @@ +# +# Copyright 2013-2023 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/. +# + +set_directory_properties(PROPERTIES LABELS "sched;nr") + +add_library(sched_nr_test_suite STATIC sched_nr_common_test.cc sched_nr_ue_ded_test_suite.cc sched_nr_sim_ue.cc) +target_link_libraries(sched_nr_test_suite srsgnb_mac srsran_common rrc_nr_asn1) + +add_executable(sched_nr_parallel_test sched_nr_parallel_test.cc) +target_link_libraries(sched_nr_parallel_test + srsgnb_mac + sched_nr_test_suite + srsran_common + rrc_nr_asn1 + ${CMAKE_THREAD_LIBS_INIT} + ${Boost_LIBRARIES}) +add_nr_test(sched_nr_parallel_test sched_nr_parallel_test) + +add_executable(sched_nr_prb_test sched_nr_prb_test.cc) +target_link_libraries(sched_nr_prb_test + srsgnb_mac + srsran_common + rrc_nr_asn1 + ${CMAKE_THREAD_LIBS_INIT} + ${Boost_LIBRARIES}) +add_nr_test(sched_nr_prb_test sched_nr_prb_test) + +add_executable(sched_nr_pdcch_test sched_nr_pdcch_test.cc) +target_link_libraries(sched_nr_pdcch_test srsgnb_mac sched_nr_test_suite srsran_common rrc_nr_asn1) +add_nr_test(sched_nr_pdcch_test sched_nr_pdcch_test) + +add_executable(sched_nr_sch_test sched_nr_sch_test.cc) +target_link_libraries(sched_nr_sch_test srsgnb_mac sched_nr_test_suite srsran_common rrc_nr_asn1) +add_nr_test(sched_nr_sch_test sched_nr_sch_test) + +add_executable(sched_nr_rar_test sched_nr_rar_test.cc) +target_link_libraries(sched_nr_rar_test srsgnb_mac sched_nr_test_suite srsran_common rrc_nr_asn1) +add_nr_test(sched_nr_rar_test sched_nr_rar_test) + +add_executable(sched_nr_dci_utilities_tests sched_nr_dci_utilities_tests.cc) +target_link_libraries(sched_nr_dci_utilities_tests srsgnb_mac srsran_common rrc_nr_asn1) +add_nr_test(sched_nr_dci_utilities_tests sched_nr_dci_utilities_tests) + +add_executable(sched_nr_test sched_nr_test.cc) +target_link_libraries(sched_nr_test + srsgnb_mac + sched_nr_test_suite + rrc_nr_asn1 + srsran_common ${CMAKE_THREAD_LIBS_INIT} + ${Boost_LIBRARIES}) +add_nr_test(sched_nr_test sched_nr_test) diff --git a/srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h b/srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h new file mode 100644 index 0000000000..27952c52f3 --- /dev/null +++ b/srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h @@ -0,0 +1,215 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_SCHED_NR_CFG_GENERATORS_H +#define SRSRAN_SCHED_NR_CFG_GENERATORS_H + +#include "srsgnb/hdr/stack/mac/sched_nr_interface_utils.h" +#include "srsran/asn1/rrc_nr_utils.h" +#include "srsran/common/phy_cfg_nr_default.h" + +namespace srsenb { + +inline srsran_coreset_t get_default_coreset0(uint32_t nof_prb) +{ + srsran_coreset_t coreset{}; + coreset.id = 0; + coreset.duration = 1; + coreset.precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle; + for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; ++i) { + coreset.freq_resources[i] = i < (nof_prb / 6); + } + return coreset; +} + +inline srsran_search_space_t get_default_search_space0() +{ + srsran_search_space_t ss{}; + ss.coreset_id = 0; + ss.nof_formats = 1; + ss.formats[0] = srsran_dci_format_nr_1_0; + ss.type = srsran_search_space_type_common_0; + ss.id = 0; + ss.nof_candidates[2] = 1; + ss.duration = 1; + return ss; +} + +inline sched_nr_cell_cfg_t get_default_cell_cfg(const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{ + srsran::phy_cfg_nr_default_t::reference_cfg_t{}}) +{ + sched_nr_cell_cfg_t cell_cfg{}; + + cell_cfg.pci = phy_cfg.carrier.pci; + cell_cfg.dl_center_frequency_hz = phy_cfg.carrier.dl_center_frequency_hz; + cell_cfg.ul_center_frequency_hz = phy_cfg.carrier.ul_center_frequency_hz; + cell_cfg.ssb_center_freq_hz = phy_cfg.carrier.ssb_center_freq_hz; + cell_cfg.dl_cfg_common.freq_info_dl.scs_specific_carrier_list.resize(1); + cell_cfg.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].subcarrier_spacing = + (asn1::rrc_nr::subcarrier_spacing_opts::options)phy_cfg.carrier.scs; + cell_cfg.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].offset_to_carrier = + phy_cfg.carrier.offset_to_carrier; + cell_cfg.dl_cfg_common.init_dl_bwp.generic_params.subcarrier_spacing = + (asn1::rrc_nr::subcarrier_spacing_opts::options)phy_cfg.carrier.scs; + cell_cfg.ul_cfg_common.init_ul_bwp.rach_cfg_common_present = true; + srsran::fill_rach_cfg_common(phy_cfg.prach, cell_cfg.ul_cfg_common.init_ul_bwp.rach_cfg_common.set_setup()); + cell_cfg.dl_cell_nof_prb = phy_cfg.carrier.nof_prb; + cell_cfg.nof_layers = phy_cfg.carrier.max_mimo_layers; + cell_cfg.ssb_periodicity_ms = phy_cfg.ssb.periodicity_ms; + for (uint32_t i = 0; i < cell_cfg.ssb_positions_in_burst.in_one_group.length(); ++i) { + cell_cfg.ssb_positions_in_burst.in_one_group.set(i, phy_cfg.ssb.position_in_burst[i]); + } + // TODO: phy_cfg.ssb_positions_in_burst.group_presence_present + cell_cfg.dmrs_type_a_position.value = asn1::rrc_nr::mib_s::dmrs_type_a_position_opts::pos2; + cell_cfg.ssb_scs.value = (asn1::rrc_nr::subcarrier_spacing_opts::options)phy_cfg.ssb.scs; + cell_cfg.pdcch_cfg_sib1.ctrl_res_set_zero = 0; + cell_cfg.pdcch_cfg_sib1.search_space_zero = 0; + + cell_cfg.bwps.resize(1); + cell_cfg.bwps[0].pdcch = phy_cfg.pdcch; + cell_cfg.bwps[0].pdsch = phy_cfg.pdsch; + cell_cfg.bwps[0].pusch = phy_cfg.pusch; + cell_cfg.bwps[0].pucch = phy_cfg.pucch; + cell_cfg.bwps[0].harq_ack = phy_cfg.harq_ack; + cell_cfg.bwps[0].rb_width = phy_cfg.carrier.nof_prb; + + if (phy_cfg.duplex.mode == SRSRAN_DUPLEX_MODE_TDD) { + cell_cfg.tdd_ul_dl_cfg_common.emplace(); + srsran_assert(srsran::make_phy_tdd_cfg( + phy_cfg.duplex, srsran_subcarrier_spacing_15kHz, &cell_cfg.tdd_ul_dl_cfg_common.value()), + "Failed to generate TDD config"); + } + + return cell_cfg; +} + +inline std::vector get_default_cells_cfg( + uint32_t nof_sectors, + const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}) +{ + std::vector cells; + cells.reserve(nof_sectors); + for (uint32_t i = 0; i < nof_sectors; ++i) { + cells.push_back(get_default_cell_cfg(phy_cfg)); + } + return cells; +} + +inline sched_nr_interface::ue_cfg_t get_rach_ue_cfg(uint32_t cc, + const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{ + srsran::phy_cfg_nr_default_t::reference_cfg_t{}}) +{ + sched_nr_interface::ue_cfg_t uecfg{}; + + // set PCell + uecfg.carriers.resize(1); + uecfg.carriers[0].active = true; + uecfg.carriers[0].cc = cc; + + // set basic PHY config + uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}; + uecfg.phy_cfg.csi = {}; + for (srsran_search_space_t& ss : view_active_search_spaces(uecfg.phy_cfg.pdcch)) { + // disable UE-specific search spaces + if (ss.type == srsran_search_space_type_ue) { + uecfg.phy_cfg.pdcch.search_space_present[ss.id] = false; + } + } + + return uecfg; +} + +inline sched_nr_interface::ue_cfg_t get_default_ue_cfg( + uint32_t nof_cc, + const srsran::phy_cfg_nr_t& phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}) +{ + sched_nr_interface::ue_cfg_t uecfg{}; + uecfg.carriers.resize(nof_cc); + for (uint32_t cc = 0; cc < nof_cc; ++cc) { + uecfg.carriers[cc].cc = cc; + uecfg.carriers[cc].active = true; + } + uecfg.phy_cfg = phy_cfg; + + return uecfg; +} + +inline sched_nr_cell_cfg_t get_default_sa_cell_cfg_common() +{ + srsran::phy_cfg_nr_default_t::reference_cfg_t ref; + ref.duplex = srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; + sched_nr_cell_cfg_t cell_cfg = get_default_cell_cfg(srsran::phy_cfg_nr_default_t{ref}); + cell_cfg.bwps[0].pdcch.coreset_present[0] = true; + cell_cfg.bwps[0].pdcch.coreset[0] = get_default_coreset0(52); + cell_cfg.bwps[0].pdcch.coreset[0].offset_rb = 1; + cell_cfg.bwps[0].pdcch.search_space_present[0] = true; + cell_cfg.bwps[0].pdcch.search_space[0] = get_default_search_space0(); + cell_cfg.bwps[0].pdcch.coreset_present[1] = false; + cell_cfg.bwps[0].pdcch.search_space[1].coreset_id = 0; + cell_cfg.bwps[0].pdcch.search_space[1].type = srsran_search_space_type_common_1; + cell_cfg.bwps[0].pdcch.search_space[1].nof_candidates[2] = 1; + cell_cfg.bwps[0].pdcch.search_space[1].nof_formats = 2; + cell_cfg.bwps[0].pdcch.search_space[1].formats[0] = srsran_dci_format_nr_1_0; + cell_cfg.bwps[0].pdcch.search_space[1].formats[1] = srsran_dci_format_nr_0_0; + cell_cfg.bwps[0].pdcch.ra_search_space = cell_cfg.bwps[0].pdcch.search_space[1]; + return cell_cfg; +} + +// Generate default UE-dedicated CORESET config +inline srsran_coreset_t get_default_ue_specific_coreset(uint32_t id, uint32_t pci) +{ + srsran_coreset_t coreset = {}; + coreset.id = id; + coreset.mapping_type = srsran_coreset_mapping_type_non_interleaved; + coreset.duration = 1; + for (uint32_t i = 0; i < 8; ++i) { + coreset.freq_resources[i] = true; + } + coreset.dmrs_scrambling_id_present = false; + coreset.precoder_granularity = srsran_coreset_precoder_granularity_reg_bundle; + coreset.interleaver_size = srsran_coreset_bundle_size_n2; + coreset.reg_bundle_size = srsran_coreset_bundle_size_n6; + coreset.shift_index = pci; + coreset.offset_rb = 0; + return coreset; +} + +inline srsran_search_space_t get_default_ue_specific_search_space(uint32_t id, uint32_t coreset_id) +{ + srsran_search_space_t ss = {}; + ss.id = id; + ss.coreset_id = coreset_id; + ss.duration = 1; + ss.type = srsran_search_space_type_ue; + ss.nof_formats = 2; + ss.formats[0] = srsran_dci_format_nr_1_0; + ss.formats[1] = srsran_dci_format_nr_0_0; + ss.nof_candidates[0] = 2; + ss.nof_candidates[1] = 2; + ss.nof_candidates[2] = 2; + ss.nof_candidates[3] = 1; + ss.nof_candidates[4] = 0; + return ss; +} + +} // namespace srsenb + +#endif // SRSRAN_SCHED_NR_CFG_GENERATORS_H diff --git a/srsgnb/src/stack/mac/test/sched_nr_common_test.cc b/srsgnb/src/stack/mac/test/sched_nr_common_test.cc new file mode 100644 index 0000000000..6c94e7334c --- /dev/null +++ b/srsgnb/src/stack/mac/test/sched_nr_common_test.cc @@ -0,0 +1,156 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "sched_nr_common_test.h" +#include "srsgnb/hdr/stack/mac/sched_nr_cfg.h" +#include "srsgnb/hdr/stack/mac/sched_nr_helpers.h" +#include "srsran/support/srsran_test.h" + +namespace srsenb { + +using namespace sched_nr_impl; + +void test_dci_ctx_consistency(const srsran_pdcch_cfg_nr_t& pdcch_cfg, const srsran_dci_ctx_t& dci_ctx) +{ + TESTASSERT(dci_ctx.coreset_id < SRSRAN_UE_DL_NR_MAX_NOF_CORESET); + TESTASSERT(pdcch_cfg.coreset_present[dci_ctx.coreset_id]); + const srsran_coreset_t& coreset = pdcch_cfg.coreset[dci_ctx.coreset_id]; + + // DCI location + TESTASSERT(dci_ctx.location.L < SRSRAN_SEARCH_SPACE_NOF_AGGREGATION_LEVELS_NR); + TESTASSERT(dci_ctx.location.ncce + (1U << dci_ctx.location.L) <= coreset_nof_cces(coreset)); + // RNTI type, SearchSpace type, DCI format + TESTASSERT(sched_nr_impl::is_rnti_type_valid_in_search_space(dci_ctx.rnti_type, dci_ctx.ss_type)); + switch (dci_ctx.rnti_type) { + case srsran_rnti_type_si: + TESTASSERT_EQ(srsran_dci_format_nr_1_0, dci_ctx.format); + TESTASSERT_EQ(srsran_search_space_type_common_0, dci_ctx.ss_type); + TESTASSERT_EQ(SRSRAN_SIRNTI, dci_ctx.rnti); + break; + case srsran_rnti_type_ra: + TESTASSERT_EQ(dci_ctx.format, srsran_dci_format_nr_1_0); + TESTASSERT_EQ(dci_ctx.ss_type, srsran_search_space_type_common_1); + TESTASSERT(pdcch_cfg.ra_search_space_present); + TESTASSERT_EQ(pdcch_cfg.ra_search_space.coreset_id, dci_ctx.coreset_id); + TESTASSERT(pdcch_cfg.ra_search_space.nof_candidates[dci_ctx.location.L] > 0); + break; + case srsran_rnti_type_tc: + TESTASSERT_EQ(srsran_dci_format_nr_1_0, dci_ctx.format); + TESTASSERT_EQ(srsran_search_space_type_common_1, dci_ctx.ss_type); + break; + case srsran_rnti_type_c: + TESTASSERT(dci_ctx.format == srsran_dci_format_nr_1_0 or dci_ctx.format == srsran_dci_format_nr_1_1 or + dci_ctx.format == srsran_dci_format_nr_0_0 or dci_ctx.format == srsran_dci_format_nr_0_1); + break; + default: + srsran_terminate("rnti type=%d not supported", dci_ctx.rnti_type); + } + // CORESET position + TESTASSERT_EQ(srsran_coreset_start_rb(&coreset), dci_ctx.coreset_start_rb); +} + +void test_pdcch_collisions(const srsran_pdcch_cfg_nr_t& pdcch_cfg, + srsran::const_span dl_pdcchs, + srsran::const_span ul_pdcchs) +{ + srsran::optional_vector coreset_bitmaps; + for (const srsran_coreset_t& coreset : view_active_coresets(pdcch_cfg)) { + coreset_bitmaps.emplace(coreset.id, coreset_bitmap(coreset_nof_cces(coreset))); + } + + for (const pdcch_dl_t& pdcch : dl_pdcchs) { + coreset_bitmap& total_bitmap = coreset_bitmaps[pdcch.dci.ctx.coreset_id]; + coreset_bitmap alloc(total_bitmap.size()); + alloc.fill(pdcch.dci.ctx.location.ncce, pdcch.dci.ctx.location.ncce + (1U << pdcch.dci.ctx.location.L)); + TESTASSERT((alloc & total_bitmap).none()); + total_bitmap |= alloc; + } + for (const pdcch_ul_t& pdcch : ul_pdcchs) { + coreset_bitmap& total_bitmap = coreset_bitmaps[pdcch.dci.ctx.coreset_id]; + coreset_bitmap alloc(total_bitmap.size()); + alloc.fill(pdcch.dci.ctx.location.ncce, pdcch.dci.ctx.location.ncce + (1U << pdcch.dci.ctx.location.L)); + TESTASSERT((alloc & total_bitmap).none()); + total_bitmap |= alloc; + } +} + +void test_dl_pdcch_consistency(const cell_config_manager& cell_cfg, + srsran::const_span dl_pdcchs) +{ + for (const auto& pdcch : dl_pdcchs) { + TESTASSERT(pdcch.dci.bwp_id < cell_cfg.bwps.size()); + const srsran_pdcch_cfg_nr_t& pdcch_cfg = cell_cfg.bwps[pdcch.dci.bwp_id].cfg.pdcch; + test_dci_ctx_consistency(pdcch_cfg, pdcch.dci.ctx); + + const srsran_coreset_t& coreset = pdcch_cfg.coreset[pdcch.dci.ctx.coreset_id]; + if (pdcch.dci.ctx.coreset_id == 0) { + TESTASSERT_EQ(srsran_coreset_get_bw(&pdcch_cfg.coreset[0]), pdcch.dci.coreset0_bw); + } + + switch (pdcch.dci.ctx.rnti_type) { + case srsran_rnti_type_si: + TESTASSERT(pdcch.dci.sii != 0 or pdcch.dci.ctx.coreset_id == 0); // sii=0 must go in CORESET#0 + break; + default: + break; + } + } +} + +void test_pdsch_consistency(srsran::const_span pdschs) +{ + for (const mac_interface_phy_nr::pdsch_t& pdsch : pdschs) { + TESTASSERT(pdsch.sch.grant.nof_layers > 0); + if (pdsch.sch.grant.rnti_type == srsran_rnti_type_c) { + TESTASSERT(pdsch.sch.grant.tb[0].softbuffer.tx != nullptr); + TESTASSERT(pdsch.sch.grant.tb[0].softbuffer.tx->buffer_b != nullptr); + TESTASSERT(pdsch.sch.grant.tb[0].softbuffer.tx->max_cb > 0); + } + } +} + +void test_ssb_scheduled_grant( + const srsran::slot_point& sl_point, + const sched_nr_impl::cell_config_manager& cell_cfg, + const srsran::bounded_vector& ssb_list) +{ + /* + * Verify that, with correct SSB periodicity, dl_res has: + * 1) SSB grant + * 2) 4 LSBs of SFN in packed MIB message are correct + * 3) SSB index is 0 + */ + if (sl_point.to_uint() % (cell_cfg.ssb.periodicity_ms * (uint32_t)sl_point.nof_slots_per_subframe()) == 0) { + TESTASSERT(ssb_list.size() == 1); + auto& ssb_item = ssb_list.back(); + TESTASSERT(ssb_item.pbch_msg.sfn_4lsb == ((uint8_t)sl_point.sfn() & 0b1111)); + bool expected_hrf = sl_point.slot_idx() % SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) >= + SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) / 2; + TESTASSERT(ssb_item.pbch_msg.hrf == expected_hrf); + TESTASSERT(ssb_item.pbch_msg.ssb_idx == 0); + } + // Verify that, outside SSB periodicity, there is NO SSB grant + else { + TESTASSERT(ssb_list.size() == 0); + } +} + +} // namespace srsenb diff --git a/srsenb/test/mac/nr/sched_nr_common_test.h b/srsgnb/src/stack/mac/test/sched_nr_common_test.h similarity index 65% rename from srsenb/test/mac/nr/sched_nr_common_test.h rename to srsgnb/src/stack/mac/test/sched_nr_common_test.h index 2754742bbb..02acbb2c9d 100644 --- a/srsenb/test/mac/nr/sched_nr_common_test.h +++ b/srsgnb/src/stack/mac/test/sched_nr_common_test.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,17 +22,26 @@ #ifndef SRSRAN_SCHED_NR_COMMON_TEST_H #define SRSRAN_SCHED_NR_COMMON_TEST_H -#include "srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h" +#include "srsgnb/hdr/stack/mac/sched_nr_pdcch.h" #include "srsran/adt/span.h" namespace srsenb { -void test_dl_pdcch_consistency(srsran::const_span dl_pdcch); +/// Test DCI context consistency +void test_dci_ctx_consistency(const srsran_pdcch_cfg_nr_t& pdcch_cfg, const srsran_dci_ctx_t& dci); + +/// Test PDCCH collisions +void test_pdcch_collisions(const srsran_pdcch_cfg_nr_t& pdcch_cfg, + srsran::const_span dl_pdcchs, + srsran::const_span ul_pddchs); + +void test_dl_pdcch_consistency(const sched_nr_impl::cell_config_manager& cell_cfg, + srsran::const_span dl_pdcch); void test_pdsch_consistency(srsran::const_span dl_pdcch); /// @brief Test whether the SSB grant gets scheduled with the correct periodicity. void test_ssb_scheduled_grant( const srsran::slot_point& sl_point, - const sched_nr_interface::cell_cfg_t& cell_cfg, + const sched_nr_impl::cell_config_manager& cell_cfg, const srsran::bounded_vector& ssb_list); } // namespace srsenb diff --git a/srsgnb/src/stack/mac/test/sched_nr_dci_utilities_tests.cc b/srsgnb/src/stack/mac/test/sched_nr_dci_utilities_tests.cc new file mode 100644 index 0000000000..1e35f9cbb7 --- /dev/null +++ b/srsgnb/src/stack/mac/test/sched_nr_dci_utilities_tests.cc @@ -0,0 +1,478 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/common/test_common.h" +extern "C" { +#include "srsran/phy/phch/ra_nr.h" +} + +void test_cqi_to_mcs() +{ + // Sample random CQI values and test the returned MCS, for different combinations of CQI and MCS tables + // Set the parameters so that to select a given MCS table (1, 2, or 3) + + // TEST CQI Table 1 - MCS table 1 + int mcs = srsran_ra_nr_cqi_to_mcs(/* cqi */ 3, + /* cqi_table_idx */ SRSRAN_CSI_CQI_TABLE_1, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(2, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(5, + SRSRAN_CSI_CQI_TABLE_1, + srsran_mcs_table_64qam, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(6, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(9, + SRSRAN_CSI_CQI_TABLE_1, + srsran_mcs_table_64qam, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(15, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(12, + SRSRAN_CSI_CQI_TABLE_1, + srsran_mcs_table_64qam, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(22, mcs); + + // TEST CQI Table 2 - MCS table 2 + mcs = srsran_ra_nr_cqi_to_mcs(1, + SRSRAN_CSI_CQI_TABLE_2, + srsran_mcs_table_256qam, + srsran_dci_format_nr_1_1, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(0, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(4, + SRSRAN_CSI_CQI_TABLE_2, + srsran_mcs_table_256qam, + srsran_dci_format_nr_1_1, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(5, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(7, + SRSRAN_CSI_CQI_TABLE_2, + srsran_mcs_table_256qam, + srsran_dci_format_nr_1_1, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(11, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(11, + SRSRAN_CSI_CQI_TABLE_2, + srsran_mcs_table_256qam, + srsran_dci_format_nr_1_1, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(19, mcs); + + // TEST CQI Table 3 - MCS table 3 + mcs = srsran_ra_nr_cqi_to_mcs(2, + SRSRAN_CSI_CQI_TABLE_3, + srsran_mcs_table_qam64LowSE, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(2, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(8, + SRSRAN_CSI_CQI_TABLE_3, + srsran_mcs_table_qam64LowSE, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(14, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(13, + SRSRAN_CSI_CQI_TABLE_3, + srsran_mcs_table_qam64LowSE, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(24, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(15, + SRSRAN_CSI_CQI_TABLE_3, + srsran_mcs_table_qam64LowSE, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(28, mcs); + + // TEST CQI Table 1 - MCS table 2 + mcs = srsran_ra_nr_cqi_to_mcs(6, + SRSRAN_CSI_CQI_TABLE_1, + srsran_mcs_table_256qam, + srsran_dci_format_nr_1_1, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(4, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(14, + SRSRAN_CSI_CQI_TABLE_1, + srsran_mcs_table_256qam, + srsran_dci_format_nr_1_1, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(19, mcs); + + // TEST CQI Table 1 - MCS table 3 + mcs = srsran_ra_nr_cqi_to_mcs(7, + SRSRAN_CSI_CQI_TABLE_1, + srsran_mcs_table_qam64LowSE, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(16, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(10, + SRSRAN_CSI_CQI_TABLE_1, + srsran_mcs_table_qam64LowSE, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(22, mcs); + + // TEST CQI Table 2 - MCS table 1 + mcs = srsran_ra_nr_cqi_to_mcs(3, + SRSRAN_CSI_CQI_TABLE_2, + srsran_mcs_table_64qam, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(6, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(11, + SRSRAN_CSI_CQI_TABLE_2, + srsran_mcs_table_64qam, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(26, mcs); + + // TEST CQI Table 2 - MCS table 3 + mcs = srsran_ra_nr_cqi_to_mcs(7, + SRSRAN_CSI_CQI_TABLE_2, + srsran_mcs_table_qam64LowSE, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(22, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(10, + SRSRAN_CSI_CQI_TABLE_2, + srsran_mcs_table_qam64LowSE, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(28, mcs); + + // TEST CQI Table 3 - MCS table 1 + mcs = srsran_ra_nr_cqi_to_mcs(2, + SRSRAN_CSI_CQI_TABLE_3, + srsran_mcs_table_64qam, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(0, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(13, + SRSRAN_CSI_CQI_TABLE_3, + srsran_mcs_table_64qam, + srsran_dci_format_nr_1_0, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(20, mcs); + + // TEST CQI Table 3 - MCS table 2 + mcs = srsran_ra_nr_cqi_to_mcs(5, + SRSRAN_CSI_CQI_TABLE_3, + srsran_mcs_table_256qam, + srsran_dci_format_nr_1_1, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(1, mcs); + + mcs = srsran_ra_nr_cqi_to_mcs(14, + SRSRAN_CSI_CQI_TABLE_3, + srsran_mcs_table_256qam, + srsran_dci_format_nr_1_1, + srsran_search_space_type_ue, + srsran_rnti_type_c); + TESTASSERT_EQ(15, mcs); +} + +void test_cqi_to_se() +{ + // TEST CQI Table 1 + double se = srsran_ra_nr_cqi_to_se(2, SRSRAN_CSI_CQI_TABLE_1); + TESTASSERT_EQ(0.2344, se); + + se = srsran_ra_nr_cqi_to_se(5, SRSRAN_CSI_CQI_TABLE_1); + TESTASSERT_EQ(0.8770, se); + + se = srsran_ra_nr_cqi_to_se(8, SRSRAN_CSI_CQI_TABLE_1); + TESTASSERT_EQ(1.9141, se); + + se = srsran_ra_nr_cqi_to_se(11, SRSRAN_CSI_CQI_TABLE_1); + TESTASSERT_EQ(3.3223, se); + + se = srsran_ra_nr_cqi_to_se(13, SRSRAN_CSI_CQI_TABLE_1); + TESTASSERT_EQ(4.5234, se); + + se = srsran_ra_nr_cqi_to_se(15, SRSRAN_CSI_CQI_TABLE_1); + TESTASSERT_EQ(5.5547, se); + + // TEST CQI Table 2 + se = srsran_ra_nr_cqi_to_se(1, SRSRAN_CSI_CQI_TABLE_2); + TESTASSERT_EQ(0.1523, se); + + se = srsran_ra_nr_cqi_to_se(4, SRSRAN_CSI_CQI_TABLE_2); + TESTASSERT_EQ(1.4766, se); + + se = srsran_ra_nr_cqi_to_se(7, SRSRAN_CSI_CQI_TABLE_2); + TESTASSERT_EQ(2.7305, se); + + se = srsran_ra_nr_cqi_to_se(10, SRSRAN_CSI_CQI_TABLE_2); + TESTASSERT_EQ(4.5234, se); + + se = srsran_ra_nr_cqi_to_se(12, SRSRAN_CSI_CQI_TABLE_2); + TESTASSERT_EQ(5.5547, se); + + se = srsran_ra_nr_cqi_to_se(14, SRSRAN_CSI_CQI_TABLE_2); + TESTASSERT_EQ(6.9141, se); + + // TEST CQI Table 3 + se = srsran_ra_nr_cqi_to_se(1, SRSRAN_CSI_CQI_TABLE_3); + TESTASSERT_EQ(0.0586, se); + + se = srsran_ra_nr_cqi_to_se(3, SRSRAN_CSI_CQI_TABLE_3); + TESTASSERT_EQ(0.1523, se); + + se = srsran_ra_nr_cqi_to_se(7, SRSRAN_CSI_CQI_TABLE_3); + TESTASSERT_EQ(0.8770, se); + + se = srsran_ra_nr_cqi_to_se(9, SRSRAN_CSI_CQI_TABLE_3); + TESTASSERT_EQ(1.4766, se); + + se = srsran_ra_nr_cqi_to_se(12, SRSRAN_CSI_CQI_TABLE_3); + TESTASSERT_EQ(2.7305, se); + + se = srsran_ra_nr_cqi_to_se(15, SRSRAN_CSI_CQI_TABLE_3); + TESTASSERT_EQ(4.5234, se); +} + +void test_se_to_mcs() +{ + // MCS table 1 + int mcs = srsran_ra_nr_se_to_mcs(/* se */ .1, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(0, mcs); + + mcs = srsran_ra_nr_se_to_mcs(/* se */ .2344, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(0, mcs); + + mcs = srsran_ra_nr_se_to_mcs(/* se */ 1, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(6, mcs); + + mcs = srsran_ra_nr_se_to_mcs(/* se */ 1.0273, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(7, mcs); + + mcs = srsran_ra_nr_se_to_mcs(/* se */ 2.5, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(15, mcs); + + mcs = srsran_ra_nr_se_to_mcs(/* se */ 2.5703, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(16, mcs); + + mcs = srsran_ra_nr_se_to_mcs(/* se */ 2.57, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(16, mcs); + + mcs = srsran_ra_nr_se_to_mcs(/* se */ 2.5664, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(17, mcs); + + mcs = srsran_ra_nr_se_to_mcs(/* se */ 5.5, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(27, mcs); + + mcs = srsran_ra_nr_se_to_mcs(/* se */ 5.5574, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(28, mcs); + + mcs = srsran_ra_nr_se_to_mcs(/* se */ 6, + /* mcs_table */ srsran_mcs_table_64qam, + /* dci_format */ srsran_dci_format_nr_1_0, + /* search_space_type*/ srsran_search_space_type_ue, + /* rnti_type */ srsran_rnti_type_c); + TESTASSERT_EQ(28, mcs); + + // MCS table 2 + mcs = srsran_ra_nr_se_to_mcs( + 0.1, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(0, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 0.2344, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(0, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 0.24, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(0, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 1.47, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(4, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 1.4766, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(5, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 3.5, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(13, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 3.6094, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(14, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 5.2, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(19, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 5.3320, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(20, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 5.4, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(20, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 7.4063, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(27, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 7.5, srsran_mcs_table_256qam, srsran_dci_format_nr_1_1, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(27, mcs); + + // MCS table 3 + mcs = srsran_ra_nr_se_to_mcs( + 0.05, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(0, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 0.0586, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(0, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 0.056, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(0, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 0.15, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(3, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 0.1523, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(4, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 0.49, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(8, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 0.4902, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(9, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 1.69, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(16, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 1.6953, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(17, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 4.52, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(27, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 4.5234, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(28, mcs); + + mcs = srsran_ra_nr_se_to_mcs( + 4.6, srsran_mcs_table_qam64LowSE, srsran_dci_format_nr_1_0, srsran_search_space_type_ue, srsran_rnti_type_c); + TESTASSERT_EQ(28, mcs); +}; + +int main() +{ + test_cqi_to_mcs(); + test_cqi_to_se(); + test_se_to_mcs(); +} \ No newline at end of file diff --git a/srsenb/test/mac/nr/sched_nr_test.cc b/srsgnb/src/stack/mac/test/sched_nr_parallel_test.cc similarity index 79% rename from srsenb/test/mac/nr/sched_nr_test.cc rename to srsgnb/src/stack/mac/test/sched_nr_parallel_test.cc index 5da49c8181..64c55f8e95 100644 --- a/srsenb/test/mac/nr/sched_nr_test.cc +++ b/srsgnb/src/stack/mac/test/sched_nr_parallel_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -32,10 +32,10 @@ using dl_sched_t = sched_nr_interface::dl_sched_t; static const srsran::phy_cfg_nr_t default_phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}; -class sched_nr_tester : public sched_nr_base_tester +class sched_nr_tester : public sched_nr_base_test_bench { public: - using sched_nr_base_tester::sched_nr_base_tester; + using sched_nr_base_test_bench::sched_nr_base_test_bench; void process_slot_result(const sim_nr_enb_ctxt_t& slot_ctxt, srsran::const_span cc_list) override { @@ -45,16 +45,16 @@ class sched_nr_tester : public sched_nr_base_tester })->cc_latency_ns.count(); for (auto& cc_out : cc_list) { - pdsch_count += cc_out.dl_res.pdcch_dl.size(); + pdsch_count += cc_out.res.dl->phy.pdcch_dl.size(); cc_res_count++; - bool is_dl_slot = srsran_duplex_nr_is_dl(&cell_params[cc_out.cc].cfg.duplex, 0, current_slot_tx.slot_idx()); + bool is_dl_slot = srsran_duplex_nr_is_dl(&cell_params[cc_out.res.cc].duplex, 0, current_slot_tx.slot_idx()); if (is_dl_slot) { - if (cc_out.dl_res.ssb.empty()) { - TESTASSERT(slot_ctxt.ue_db.empty() or cc_out.dl_res.pdcch_dl.size() == 1); + if (cc_out.res.dl->phy.ssb.empty() and not slot_ctxt.ue_db.empty()) { + TESTASSERT(slot_ctxt.ue_db.empty() or cc_out.res.dl->phy.pdcch_dl.size() >= 1); } else { - TESTASSERT(cc_out.dl_res.pdcch_dl.size() == 0); + TESTASSERT(cc_out.res.dl->phy.pdcch_dl.size() == 0); } } } @@ -82,7 +82,7 @@ void run_sched_nr_test(uint32_t nof_workers) sched_nr_interface::sched_args_t cfg; cfg.auto_refill_buffer = true; - std::vector cells_cfg = get_default_cells_cfg(nof_sectors); + std::vector cells_cfg = get_default_cells_cfg(nof_sectors); std::string test_name = "Serialized Test"; if (nof_workers > 1) { @@ -93,16 +93,20 @@ void run_sched_nr_test(uint32_t nof_workers) for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) { slot_point slot_rx(0, nof_slots % 10240); slot_point slot_tx = slot_rx + TX_ENB_DELAY; - if (slot_rx.to_uint() == 9) { + if (nof_slots == 9) { sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(nof_sectors); - tester.add_user(rnti, uecfg, slot_rx, 0); + uecfg.lc_ch_to_add.emplace_back(); + uecfg.lc_ch_to_add.back().lcid = 1; + uecfg.lc_ch_to_add.back().cfg.direction = mac_lc_ch_cfg_t::BOTH; + tester.user_cfg(rnti, uecfg); } tester.run_slot(slot_tx); } tester.stop(); tester.print_results(); - // TESTASSERT(tasks.pdsch_count == (int)(max_nof_ttis * nof_sectors * 0.6)); + TESTASSERT(tester.pdsch_count > 0); + // TESTASSERT(tester.pdsch_count == (int)(max_nof_ttis * nof_sectors * 0.6)); double final_avg_usec = tester.tot_latency_sched_ns; final_avg_usec = final_avg_usec / 1000.0 / max_nof_ttis; diff --git a/srsgnb/src/stack/mac/test/sched_nr_pdcch_test.cc b/srsgnb/src/stack/mac/test/sched_nr_pdcch_test.cc new file mode 100644 index 0000000000..d9dbb90a65 --- /dev/null +++ b/srsgnb/src/stack/mac/test/sched_nr_pdcch_test.cc @@ -0,0 +1,320 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "sched_nr_cfg_generators.h" +#include "sched_nr_common_test.h" +#include "srsgnb/hdr/stack/mac/sched_nr_interface_utils.h" +#include "srsgnb/hdr/stack/mac/sched_nr_pdcch.h" +#include "srsran/common/test_common.h" + +namespace srsenb { + +using namespace sched_nr_impl; + +/** + * Test for the case CORESET#0 is active. + * Given only one PDCCH candidate position is supported, only one PDCCH allocation should take place per slot + * The test additionally verifies that the DCI context content is correct for each PDCCH allocation + */ +void test_coreset0_cfg() +{ + const uint32_t aggr_idx = 2; + + srsran::test_delimit_logger delimiter{"Test PDCCH Allocation in CORESET#0"}; + + sched_nr_interface::sched_args_t sched_args; + sched_nr_impl::cell_config_manager cell_cfg{0, get_default_sa_cell_cfg_common(), sched_args}; + bwp_params_t& bwp_params = cell_cfg.bwps[0]; + + // UE config + ue_cfg_manager uecfg{get_rach_ue_cfg(0)}; + uecfg.phy_cfg.pdcch = cell_cfg.bwps[0].cfg.pdcch; // Starts without UE-specific PDCCH + ue_carrier_params_t ue_cc{0x46, bwp_params, uecfg}; + + pdcch_dl_list_t dl_pdcchs; + pdcch_ul_list_t ul_pdcchs; + pdcch_dl_alloc_result dl_pdcch_result; + pdcch_ul_alloc_result ul_pdcch_result; + pdcch_dl_t* dl_pdcch = nullptr; + pdcch_ul_t* ul_pdcch = nullptr; + + bwp_pdcch_allocator pdcch_sched(bwp_params, 0, dl_pdcchs, ul_pdcchs); + for (const srsran_coreset_t& cs : view_active_coresets(cell_cfg.bwps[0].cfg.pdcch)) { + // Verify nof CCEs is correctly computed + TESTASSERT_EQ(coreset_nof_cces(cs), pdcch_sched.nof_cces(cs.id)); + } + + // Slot with SIB1 + TESTASSERT_EQ(0, pdcch_sched.nof_allocations()); + + // SIB1 allocation should be successful + dl_pdcch_result = pdcch_sched.alloc_si_pdcch(0, aggr_idx); + TESTASSERT(dl_pdcch_result.has_value()); + dl_pdcch = dl_pdcch_result.value(); + TESTASSERT_EQ(1, pdcch_sched.nof_allocations()); + TESTASSERT_EQ(srsran_rnti_type_si, dl_pdcch->dci.ctx.rnti_type); + TESTASSERT_EQ(0, dl_pdcch->dci.ctx.coreset_id); + test_dci_ctx_consistency(bwp_params.cfg.pdcch, dl_pdcch->dci.ctx); + + // No space for RAR, UE PDSCH/PUSCH + TESTASSERT(pdcch_sched.alloc_rar_pdcch(0x2, aggr_idx).error() == alloc_result::no_cch_space); + TESTASSERT(pdcch_sched.alloc_dl_pdcch(srsran_rnti_type_c, 1, aggr_idx, ue_cc).error() == alloc_result::no_cch_space); + TESTASSERT(pdcch_sched.alloc_ul_pdcch(1, aggr_idx, ue_cc).error() == alloc_result::no_cch_space); + + srslog::fetch_basic_logger("TEST").info("%s", pdcch_sched.print_allocations()); + + // Slot with RAR + pdcch_sched.reset(); + + // RAR allocation should be successful + dl_pdcch_result = pdcch_sched.alloc_rar_pdcch(0x2, aggr_idx); + TESTASSERT(dl_pdcch_result.has_value()); + dl_pdcch = dl_pdcch_result.value(); + TESTASSERT_EQ(1, pdcch_sched.nof_allocations()); + TESTASSERT_EQ(srsran_rnti_type_ra, dl_pdcch->dci.ctx.rnti_type); + TESTASSERT_EQ(0, dl_pdcch->dci.ctx.coreset_id); + TESTASSERT_EQ(srsran_search_space_type_common_1, dl_pdcch->dci.ctx.ss_type); + test_dci_ctx_consistency(bwp_params.cfg.pdcch, dl_pdcch->dci.ctx); + + // No space for RAR, UE PDSCH/PUSCH + TESTASSERT(pdcch_sched.alloc_dl_pdcch(srsran_rnti_type_c, 1, aggr_idx, ue_cc).error() == alloc_result::no_cch_space); + TESTASSERT(pdcch_sched.alloc_ul_pdcch(1, aggr_idx, ue_cc).error() == alloc_result::no_cch_space); + + srslog::fetch_basic_logger("TEST").info("%s", pdcch_sched.print_allocations()); + + // Slot with DL PDSCH + pdcch_sched.reset(); + + // 1st PDCCH allocation for DL should be successful + dl_pdcch_result = pdcch_sched.alloc_dl_pdcch(srsran_rnti_type_c, 1, aggr_idx, ue_cc); + TESTASSERT(dl_pdcch_result.has_value()); + dl_pdcch = dl_pdcch_result.value(); + TESTASSERT_EQ(1, pdcch_sched.nof_allocations()); + TESTASSERT_EQ(srsran_rnti_type_c, dl_pdcch->dci.ctx.rnti_type); + TESTASSERT_EQ(0u, dl_pdcch->dci.ctx.coreset_id); + TESTASSERT_EQ(srsran_search_space_type_common_1, dl_pdcch->dci.ctx.ss_type); + test_dci_ctx_consistency(bwp_params.cfg.pdcch, dl_pdcch->dci.ctx); + + // No space for 2nd PDCCH allocation + TESTASSERT(pdcch_sched.alloc_ul_pdcch(1, aggr_idx, ue_cc).error() == alloc_result::no_cch_space); + + srslog::fetch_basic_logger("TEST").info("%s", pdcch_sched.print_allocations()); + + // Slot with UL PDSCH + pdcch_sched.reset(); + + // 1st PDCCH allocation for UL should be successful + ul_pdcch_result = pdcch_sched.alloc_ul_pdcch(1, aggr_idx, ue_cc); + TESTASSERT(ul_pdcch_result.has_value()); + ul_pdcch = ul_pdcch_result.value(); + TESTASSERT_EQ(1, pdcch_sched.nof_allocations()); + TESTASSERT_EQ(srsran_rnti_type_c, ul_pdcch->dci.ctx.rnti_type); + TESTASSERT_EQ(0u, ul_pdcch->dci.ctx.coreset_id); + TESTASSERT_EQ(srsran_search_space_type_common_1, ul_pdcch->dci.ctx.ss_type); + test_dci_ctx_consistency(bwp_params.cfg.pdcch, ul_pdcch->dci.ctx); + + // No space for 2nd PDCCH allocation + TESTASSERT(pdcch_sched.alloc_dl_pdcch(srsran_rnti_type_c, 1, aggr_idx, ue_cc).error() == alloc_result::no_cch_space); + + srslog::fetch_basic_logger("TEST").info("%s", pdcch_sched.print_allocations()); +} + +/** + * Test for the case CORESET#2 is active. + * The PDCCH allocator should find enough space to fit SIB1/RAR (in CORESET#0) and UE-dedicated PDCCHs in (CORESET#2) + * The test additionally verifies that the DCI context content is correct for each PDCCH allocation and there are no + * collisions between PDCCH CCE allocations + */ +void test_coreset2_cfg() +{ + const uint32_t aggr_idx = 2; + + srsran::test_delimit_logger delimiter{"Test PDCCH Allocation in CORESET#0 and CORESET#2"}; + + sched_nr_interface::sched_args_t sched_args; + sched_nr_cell_cfg_t cell_cfg = get_default_sa_cell_cfg_common(); + cell_cfg.bwps[0].pdcch.search_space_present[2] = true; + cell_cfg.bwps[0].pdcch.search_space[2] = get_default_ue_specific_search_space(2, 2); + cell_cfg.bwps[0].pdcch.coreset_present[2] = true; + cell_cfg.bwps[0].pdcch.coreset[2] = get_default_ue_specific_coreset(2, cell_cfg.pci); + sched_nr_impl::cell_config_manager cellparams{0, cell_cfg, sched_args}; + bwp_params_t& bwp_params = cellparams.bwps[0]; + + // UE config + ue_cfg_manager uecfg{get_rach_ue_cfg(0)}; + uecfg.phy_cfg = get_common_ue_phy_cfg(cell_cfg); + uecfg.phy_cfg.pdcch = cell_cfg.bwps[0].pdcch; // Starts with UE-specific PDCCH + ue_carrier_params_t ue_cc{0x46, bwp_params, uecfg}; + + pdcch_dl_list_t dl_pdcchs; + pdcch_ul_list_t ul_pdcchs; + pdcch_dl_t* dl_pdcch = nullptr; + pdcch_ul_t* ul_pdcch = nullptr; + + bwp_pdcch_allocator pdcch_sched(bwp_params, 0, dl_pdcchs, ul_pdcchs); + for (const srsran_coreset_t& cs : view_active_coresets(cell_cfg.bwps[0].pdcch)) { + // Verify nof CCEs is correctly computed + TESTASSERT_EQ(coreset_nof_cces(cs), pdcch_sched.nof_cces(cs.id)); + } + + // Slot with SIB1 + DL PDCCH and UL PDCCH + TESTASSERT_EQ(0, pdcch_sched.nof_allocations()); + + // SIB1 allocation should be successful + dl_pdcch = pdcch_sched.alloc_si_pdcch(0, aggr_idx).value(); + TESTASSERT(dl_pdcch != nullptr); + TESTASSERT_EQ(1, pdcch_sched.nof_allocations()); + TESTASSERT_EQ(srsran_rnti_type_si, dl_pdcch->dci.ctx.rnti_type); + TESTASSERT_EQ(0, dl_pdcch->dci.ctx.coreset_id); + srsran_dci_location_t expected_loc{aggr_idx, 0}; + TESTASSERT(dl_pdcch->dci.ctx.location == expected_loc); + test_dci_ctx_consistency(bwp_params.cfg.pdcch, dl_pdcch->dci.ctx); + + // No space for RAR or PDSCH in SS#1 + TESTASSERT(pdcch_sched.alloc_rar_pdcch(0x2, aggr_idx).error() == alloc_result::no_cch_space); + TESTASSERT(pdcch_sched.alloc_dl_pdcch(srsran_rnti_type_c, 1, aggr_idx, ue_cc).error() == alloc_result::no_cch_space); + TESTASSERT(pdcch_sched.alloc_ul_pdcch(1, aggr_idx, ue_cc).error() == alloc_result::no_cch_space); + + // there is space for UE DL PDCCH in SS#2 + dl_pdcch = pdcch_sched.alloc_dl_pdcch(srsran_rnti_type_c, 2, aggr_idx, ue_cc).value(); + TESTASSERT(dl_pdcch != nullptr); + TESTASSERT_EQ(2, pdcch_sched.nof_allocations()); + TESTASSERT_EQ(srsran_rnti_type_c, dl_pdcch->dci.ctx.rnti_type); + TESTASSERT_EQ(2u, dl_pdcch->dci.ctx.coreset_id); + TESTASSERT_EQ(srsran_search_space_type_ue, dl_pdcch->dci.ctx.ss_type); + expected_loc = srsran_dci_location_t{aggr_idx, 0}; + TESTASSERT(dl_pdcch->dci.ctx.location == expected_loc); + test_dci_ctx_consistency(bwp_params.cfg.pdcch, dl_pdcch->dci.ctx); + + // there is space for UE UL PDCCH in SS#2 + ul_pdcch = pdcch_sched.alloc_ul_pdcch(2, aggr_idx, ue_cc).value(); + TESTASSERT(ul_pdcch != nullptr); + TESTASSERT_EQ(3, pdcch_sched.nof_allocations()); + TESTASSERT_EQ(srsran_rnti_type_c, ul_pdcch->dci.ctx.rnti_type); + TESTASSERT_EQ(srsran_dci_format_nr_0_0, ul_pdcch->dci.ctx.format); + TESTASSERT_EQ(2u, ul_pdcch->dci.ctx.coreset_id); + TESTASSERT_EQ(srsran_search_space_type_ue, ul_pdcch->dci.ctx.ss_type); + expected_loc = srsran_dci_location_t{aggr_idx, 4}; + TESTASSERT(ul_pdcch->dci.ctx.location == expected_loc); + test_dci_ctx_consistency(bwp_params.cfg.pdcch, ul_pdcch->dci.ctx); + + // No space for 3rd PDCCH allocation in SS#2 + TESTASSERT(pdcch_sched.alloc_dl_pdcch(srsran_rnti_type_c, 2, aggr_idx, ue_cc).error() == alloc_result::no_cch_space); + + // Verify there are no PDCCH collisions + TESTASSERT_EQ(3, pdcch_sched.nof_allocations()); + TESTASSERT_EQ(2, dl_pdcchs.size()); + TESTASSERT_EQ(1, ul_pdcchs.size()); + test_pdcch_collisions(bwp_params.cfg.pdcch, dl_pdcchs, ul_pdcchs); + + srslog::fetch_basic_logger("TEST").info("%s", pdcch_sched.print_allocations()); + + // Verify all coresets are correctly cleaned up + pdcch_sched.reset(); + TESTASSERT_EQ(0, pdcch_sched.nof_allocations()); + TESTASSERT_EQ(0, dl_pdcchs.size()); + TESTASSERT_EQ(0, ul_pdcchs.size()); +} + +void test_invalid_params() +{ + const uint32_t aggr_idx = 2; + + srsran::test_delimit_logger delimiter{"Test PDCCH Allocation with Invalid Arguments"}; + + sched_nr_cell_cfg_t cell_cfg = get_default_sa_cell_cfg_common(); + cell_cfg.bwps[0].pdcch.search_space_present[2] = true; + cell_cfg.bwps[0].pdcch.search_space[2] = get_default_ue_specific_search_space(2, 2); + cell_cfg.bwps[0].pdcch.coreset_present[2] = true; + cell_cfg.bwps[0].pdcch.coreset[2] = get_default_ue_specific_coreset(2, cell_cfg.pci); + cell_cfg.bwps[0].pdcch.search_space_present[3] = true; + cell_cfg.bwps[0].pdcch.search_space[3] = get_default_ue_specific_search_space(3, 2); + cell_cfg.bwps[0].pdcch.search_space[3].nof_formats = 1; // only DL + cell_cfg.bwps[0].pdcch.search_space[3].formats[0] = srsran_dci_format_nr_1_0; + sched_nr_interface::sched_args_t sched_args; + sched_nr_impl::cell_config_manager cellparams{0, cell_cfg, sched_args}; + bwp_params_t& bwp_params = cellparams.bwps[0]; + + // UE config + ue_cfg_manager uecfg{get_rach_ue_cfg(0)}; + uecfg.phy_cfg = get_common_ue_phy_cfg(cell_cfg); + uecfg.phy_cfg.pdcch = cell_cfg.bwps[0].pdcch; // Starts with UE-specific PDCCH + ue_carrier_params_t ue_cc{0x46, bwp_params, uecfg}; + + pdcch_dl_list_t dl_pdcchs; + pdcch_ul_list_t ul_pdcchs; + pdcch_dl_alloc_result dl_res; + pdcch_ul_alloc_result ul_res; + + bwp_pdcch_allocator pdcch_sched(bwp_params, 0, dl_pdcchs, ul_pdcchs); + + // Slot with SIB1 + DL PDCCH and UL PDCCH + TESTASSERT_EQ(0, pdcch_sched.nof_allocations()); + + // Pass UE search space for SI alloc + dl_res = pdcch_sched.alloc_si_pdcch(2, aggr_idx); + TESTASSERT(dl_res.is_error() and dl_res.error() == alloc_result::invalid_grant_params); + + // Pass aggregation index for which there are no candidates + dl_res = pdcch_sched.alloc_si_pdcch(2, 4); + TESTASSERT(dl_res.is_error() and dl_res.error() == alloc_result::invalid_grant_params); + + // SearchSpace must exist + dl_res = pdcch_sched.alloc_dl_pdcch(srsran_rnti_type_c, 4, aggr_idx, ue_cc); + TESTASSERT(dl_res.is_error() and dl_res.error() == alloc_result::invalid_grant_params); + + // TC-RNTI cannot be allocated in Common SearchSpace Type1 + dl_res = pdcch_sched.alloc_dl_pdcch(srsran_rnti_type_tc, 2, aggr_idx, ue_cc); + TESTASSERT(dl_res.is_error() and dl_res.error() == alloc_result::invalid_grant_params); + + // C-RNTI cannot be allocated in Common SearchSpace Type0 + dl_res = pdcch_sched.alloc_dl_pdcch(srsran_rnti_type_c, 0, aggr_idx, ue_cc); + TESTASSERT(dl_res.is_error() and dl_res.error() == alloc_result::invalid_grant_params); + + // UL allocation cannot be made in SearchSpace without DCI format 0_0 + ul_res = pdcch_sched.alloc_ul_pdcch(3, aggr_idx, ue_cc); + TESTASSERT(ul_res.is_error() and ul_res.error() == alloc_result::invalid_grant_params); + + // Success case + TESTASSERT(pdcch_sched.nof_allocations() == 0); + ul_res = pdcch_sched.alloc_ul_pdcch(2, aggr_idx, ue_cc); + TESTASSERT(ul_res.has_value() and ul_res.value()->dci.ctx.format == srsran_dci_format_nr_0_0); + TESTASSERT(pdcch_sched.nof_allocations() == 1); +} + +} // namespace srsenb + +int main() +{ + auto& test_logger = srslog::fetch_basic_logger("TEST"); + test_logger.set_level(srslog::basic_levels::info); + auto& mac_nr_logger = srslog::fetch_basic_logger("MAC-NR"); + mac_nr_logger.set_level(srslog::basic_levels::debug); + auto& pool_logger = srslog::fetch_basic_logger("POOL"); + pool_logger.set_level(srslog::basic_levels::debug); + + // Start the log backend. + srslog::init(); + + srsenb::test_coreset0_cfg(); + srsenb::test_coreset2_cfg(); + srsenb::test_invalid_params(); +} \ No newline at end of file diff --git a/srsenb/test/mac/nr/sched_nr_prb_test.cc b/srsgnb/src/stack/mac/test/sched_nr_prb_test.cc similarity index 98% rename from srsenb/test/mac/nr/sched_nr_prb_test.cc rename to srsgnb/src/stack/mac/test/sched_nr_prb_test.cc index 338e01ec2d..4db3918fc2 100644 --- a/srsenb/test/mac/nr/sched_nr_prb_test.cc +++ b/srsgnb/src/stack/mac/test/sched_nr_prb_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,7 +19,7 @@ * */ -#include "srsenb/hdr/stack/mac/nr/sched_nr_rb.h" +#include "srsgnb/hdr/stack/mac/sched_nr_rb.h" #include "srsran/common/test_common.h" using namespace srsenb; diff --git a/srsenb/test/mac/nr/sched_nr_rar_test.cc b/srsgnb/src/stack/mac/test/sched_nr_rar_test.cc similarity index 81% rename from srsenb/test/mac/nr/sched_nr_rar_test.cc rename to srsgnb/src/stack/mac/test/sched_nr_rar_test.cc index 76a0c6fb36..5ae2edcd0c 100644 --- a/srsenb/test/mac/nr/sched_nr_rar_test.cc +++ b/srsgnb/src/stack/mac/test/sched_nr_rar_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ #include "sched_nr_cfg_generators.h" #include "sched_nr_common_test.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_cell.h" +#include "srsgnb/hdr/stack/mac/sched_nr_bwp.h" #include "srsran/common/test_common.h" #include "srsran/support/srsran_test.h" #include @@ -43,8 +43,8 @@ void test_single_prach() sched_cfg.auto_refill_buffer = std::uniform_int_distribution{0, 1}(rgen) > 0; // Set cells configuration - std::vector cells_cfg = get_default_cells_cfg(1); - sched_params schedparams{sched_cfg}; + std::vector cells_cfg = get_default_cells_cfg(1); + sched_params_t schedparams{sched_cfg}; schedparams.cells.emplace_back(0, cells_cfg[0], sched_cfg); const bwp_params_t& bwpparams = schedparams.cells[0].bwps[0]; slot_ue_map_t slot_ues; @@ -53,7 +53,6 @@ void test_single_prach() TESTASSERT(rasched.empty()); std::unique_ptr res_grid(new bwp_res_grid{bwpparams}); - bwp_slot_allocator alloc(*res_grid); // Create UE sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(1); @@ -63,22 +62,28 @@ void test_single_prach() slot_point prach_slot{0, std::uniform_int_distribution{TX_ENB_DELAY, 20}(rgen)}; const bwp_slot_grid* result = nullptr; - auto run_slot = [&alloc, &rasched, &pdcch_slot, &slot_ues, &u]() -> const bwp_slot_grid* { + auto run_slot = [&res_grid, &rasched, &pdcch_slot, &slot_ues, &u]() -> const bwp_slot_grid* { mac_logger.set_context(pdcch_slot.to_uint()); + + // delete old outputs + (*res_grid)[pdcch_slot - TX_ENB_DELAY - 1].reset(); + + // setup UE state for slot u.new_slot(pdcch_slot); - u.carriers[0]->new_slot(pdcch_slot); + + // pre-calculate UE slot vars slot_ues.clear(); - slot_ue sfu = u.try_reserve(pdcch_slot, 0); + slot_ue sfu = u.make_slot_ue(pdcch_slot, 0); if (not sfu.empty()) { slot_ues.insert(rnti, std::move(sfu)); } - alloc.new_slot(pdcch_slot, slot_ues); + bwp_slot_allocator alloc(*res_grid, pdcch_slot, slot_ues); rasched.run_slot(alloc); log_sched_bwp_result(mac_logger, alloc.get_pdcch_tti(), alloc.res_grid(), slot_ues); const bwp_slot_grid* result = &alloc.res_grid()[alloc.get_pdcch_tti()]; - test_dl_pdcch_consistency(result->dl_pdcchs); + test_dl_pdcch_consistency(res_grid->cfg->cell_cfg, result->dl.phy.pdcch_dl); ++pdcch_slot; return result; }; @@ -87,7 +92,7 @@ void test_single_prach() for (; pdcch_slot - TX_ENB_DELAY < prach_slot;) { result = run_slot(); - TESTASSERT(result->dl_pdcchs.empty()); + TESTASSERT(result->dl.phy.pdcch_dl.empty()); } // A PRACH arrives... @@ -108,15 +113,15 @@ void test_single_prach() result = run_slot(); if (bwpparams.slots[current_slot.slot_idx()].is_dl and bwpparams.slots[(current_slot + bwpparams.pusch_ra_list[0].msg3_delay).slot_idx()].is_ul) { - TESTASSERT_EQ(result->dl_pdcchs.size(), 1); - const auto& pdcch = result->dl_pdcchs[0]; + TESTASSERT_EQ(1, result->dl.phy.pdcch_dl.size()); + const auto& pdcch = result->dl.phy.pdcch_dl[0]; TESTASSERT_EQ(pdcch.dci.ctx.rnti, ra_rnti); TESTASSERT_EQ(pdcch.dci.ctx.rnti_type, srsran_rnti_type_ra); TESTASSERT(current_slot < prach_slot + prach_duration + bwpparams.cfg.rar_window_size); rar_slot = current_slot; break; } else { - TESTASSERT(result->dl_pdcchs.empty()); + TESTASSERT(result->dl.phy.pdcch_dl.empty()); } } @@ -124,7 +129,7 @@ void test_single_prach() while (pdcch_slot <= msg3_slot) { result = run_slot(); } - TESTASSERT(result->puschs.size() == 1); + TESTASSERT(result->ul.pusch.size() == 1); } } // namespace srsenb diff --git a/srsgnb/src/stack/mac/test/sched_nr_sch_test.cc b/srsgnb/src/stack/mac/test/sched_nr_sch_test.cc new file mode 100644 index 0000000000..b368dc939b --- /dev/null +++ b/srsgnb/src/stack/mac/test/sched_nr_sch_test.cc @@ -0,0 +1,496 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "sched_nr_cfg_generators.h" +#include "srsgnb/hdr/stack/mac/sched_nr_interface_utils.h" +#include "srsgnb/hdr/stack/mac/sched_nr_sch.h" +#include "srsran/common/test_common.h" +extern "C" { +#include "srsran/phy/common/sliv.h" +} + +namespace srsenb { + +using namespace sched_nr_impl; + +sched_nr_cell_cfg_t get_cell_cfg() +{ + sched_nr_cell_cfg_t cell_cfg = get_default_sa_cell_cfg_common(); + cell_cfg.bwps[0].pdcch.search_space_present[2] = true; + cell_cfg.bwps[0].pdcch.search_space[2] = get_default_ue_specific_search_space(2, 2); + cell_cfg.bwps[0].pdcch.coreset_present[2] = true; + cell_cfg.bwps[0].pdcch.coreset[2] = get_default_ue_specific_coreset(2, cell_cfg.pci); + return cell_cfg; +} + +sched_nr_interface::ue_cfg_t get_ue_cfg(const sched_nr_cell_cfg_t& cell_cfg) +{ + sched_nr_ue_cfg_t uecfg = get_rach_ue_cfg(0); + uecfg.phy_cfg = get_common_ue_phy_cfg(cell_cfg); + uecfg.phy_cfg.pdcch = cell_cfg.bwps[0].pdcch; // Starts with UE-specific PDCCH + return uecfg; +} + +srsran_dci_ctx_t generate_dci_ctx(const srsran_pdcch_cfg_nr_t& pdcch, + uint32_t ss_id, + srsran_rnti_type_t rnti_type, + uint16_t rnti, + srsran_dci_format_nr_t dci_fmt = srsran_dci_format_nr_1_0) +{ + const srsran_search_space_t& ss = pdcch.search_space[ss_id]; + const srsran_coreset_t& cs = pdcch.coreset[ss.coreset_id]; + + srsran_dci_ctx_t ctx; + ctx.location = {2, 4}; + ctx.ss_type = ss.type; + ctx.coreset_id = ss.coreset_id; + ctx.coreset_start_rb = srsran_coreset_start_rb(&cs); + ctx.rnti_type = rnti_type; + ctx.format = dci_fmt; + ctx.rnti = rnti; + return ctx; +} + +void test_dci_freq_assignment(const bwp_params_t& bwp_params, prb_interval grant, const pdcch_dl_t& pdcch) +{ + // Compute BWP PRB limits + prb_interval lims{0, bwp_params.nof_prb}; + if (SRSRAN_SEARCH_SPACE_IS_COMMON(pdcch.dci.ctx.ss_type) and pdcch.dci.ctx.format == srsran_dci_format_nr_1_0) { + lims = bwp_params.dci_fmt_1_0_prb_lims(pdcch.dci.ctx.coreset_id); + } + + // RB indexing should start from the first PRB of CORESET + uint32_t expected_freq_assignment = + srsran_ra_nr_type1_riv(lims.length(), grant.start() - lims.start(), grant.length()); + TESTASSERT_EQ(expected_freq_assignment, pdcch.dci.freq_domain_assigment); + + uint32_t st, len; + srsran_sliv_to_s_and_l(lims.length(), pdcch.dci.freq_domain_assigment, &st, &len); + prb_interval allocated_prbs{st + lims.start(), st + lims.start() + len}; + TESTASSERT(allocated_prbs == grant); +} + +void test_si() +{ + srsran::test_delimit_logger delimiter{"Test PDSCH SI Allocation"}; + + static const uint32_t ss_id = 0; + + // Create Cell and UE configs + sched_nr_interface::sched_args_t sched_args; + sched_nr_cell_cfg_t cellcfg = get_cell_cfg(); + sched_nr_impl::cell_config_manager cell_params{0, cellcfg, sched_args}; + const bwp_params_t& bwp_params = cell_params.bwps[0]; + + pdsch_list_t pdschs; + pdsch_alloc_result alloc_res; + + pdsch_allocator pdsch_sched(bwp_params, 0, pdschs); + + pdcch_dl_t pdcch; + pdcch.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, ss_id, srsran_rnti_type_si, SRSRAN_SIRNTI); + + uint32_t min_prb = bwp_params.dci_fmt_1_0_prb_lims(pdcch.dci.ctx.coreset_id).start(); + uint32_t max_prb = bwp_params.dci_fmt_1_0_prb_lims(pdcch.dci.ctx.coreset_id).stop(); + + std::array grant_list = { + prb_interval{2, 4}, prb_interval{min_prb, max_prb}, prb_interval{0, bwp_params.nof_prb}}; + + for (uint32_t i = 0; i < grant_list.size(); ++i) { + pdsch_sched.reset(); + TESTASSERT_EQ(0, pdschs.size()); + + prb_interval grant = grant_list[i]; + + bool success_expected = grant.start() >= min_prb and grant.stop() <= max_prb; + + alloc_result check_ret = pdsch_sched.is_si_grant_valid(ss_id, grant); + prb_bitmap avail_prbs = pdsch_sched.occupied_prbs(ss_id, srsran_dci_format_nr_1_0); + TESTASSERT_EQ((int)min_prb, avail_prbs.find_lowest(0, avail_prbs.size(), false)); + TESTASSERT_EQ((int)max_prb, avail_prbs.find_lowest(min_prb, avail_prbs.size(), true)); + + printf("Attempt %d should be %ssuccessful\n", i, success_expected ? "" : "un"); + alloc_res = pdsch_sched.alloc_si_pdsch(ss_id, grant, pdcch.dci); + if (success_expected) { + // SIB1 allocation doesnt go outside CORESET#0 BW + TESTASSERT(alloc_res.has_value()); + TESTASSERT_EQ(1, pdschs.size()); + TESTASSERT(&pdschs.back() == alloc_res.value()); + TESTASSERT_EQ(0, pdcch.dci.time_domain_assigment); + + TESTASSERT(not avail_prbs.any(grant.start(), grant.stop())); + + test_dci_freq_assignment(bwp_params, grant, pdcch); + } else { + TESTASSERT(alloc_res.is_error()); + TESTASSERT(check_ret == alloc_res.error()); + TESTASSERT_EQ(0, pdschs.size()); + TESTASSERT(avail_prbs.any(grant.start(), grant.stop())); + } + } +} + +void test_rar() +{ + srsran::test_delimit_logger delimiter{"Test PDSCH RAR Allocation"}; + static const uint32_t ss_id = 1; + + // Create Cell and UE configs + sched_nr_interface::sched_args_t sched_args; + sched_nr_impl::cell_config_manager cell_cfg{0, get_cell_cfg(), sched_args}; + const bwp_params_t& bwp_params = cell_cfg.bwps[0]; + + pdsch_list_t pdschs; + pdsch_alloc_result alloc_res; + + pdsch_allocator pdsch_sched(bwp_params, 0, pdschs); + + pdcch_dl_t pdcch; + pdcch.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, ss_id, srsran_rnti_type_ra, 0x2); + + uint32_t min_prb = bwp_params.dci_fmt_1_0_prb_lims(pdcch.dci.ctx.coreset_id).start(); + uint32_t max_prb = bwp_params.dci_fmt_1_0_prb_lims(pdcch.dci.ctx.coreset_id).stop(); + + std::array grant_list = { + prb_interval{2, 4}, prb_interval{min_prb, max_prb}, prb_interval{0, bwp_params.nof_prb}}; + + for (uint32_t i = 0; i < grant_list.size(); ++i) { + pdsch_sched.reset(); + TESTASSERT_EQ(0, pdschs.size()); + + prb_interval grant = grant_list[i]; + + bool success_expected = grant.start() >= min_prb and grant.stop() <= max_prb; + + alloc_result check_ret = pdsch_sched.is_rar_grant_valid(grant); + prb_bitmap avail_prbs = pdsch_sched.occupied_prbs(ss_id, srsran_dci_format_nr_1_0); + TESTASSERT_EQ((int)min_prb, avail_prbs.find_lowest(0, avail_prbs.size(), false)); + TESTASSERT_EQ((int)max_prb, avail_prbs.find_lowest(min_prb, avail_prbs.size(), true)); + + printf("Attempt %d should be %ssuccessful\n", i, success_expected ? "" : "un"); + alloc_res = pdsch_sched.alloc_rar_pdsch(grant, pdcch.dci); + if (success_expected) { + // SIB1 allocation doesnt go outside CORESET#0 BW + TESTASSERT(alloc_res.has_value()); + TESTASSERT_EQ(1, pdschs.size()); + TESTASSERT(&pdschs.back() == alloc_res.value()); + TESTASSERT_EQ(0, pdcch.dci.time_domain_assigment); + + TESTASSERT(not avail_prbs.any(grant.start(), grant.stop())); + + test_dci_freq_assignment(bwp_params, grant, pdcch); + } else { + TESTASSERT(alloc_res.is_error()); + TESTASSERT(check_ret == alloc_res.error()); + TESTASSERT_EQ(0, pdschs.size()); + TESTASSERT(avail_prbs.any(grant.start(), grant.stop())); + } + } +} + +void test_ue_pdsch() +{ + srsran::test_delimit_logger delimiter{"Test PDSCH UE Allocation"}; + + // Create Cell and UE configs + sched_nr_interface::sched_args_t sched_args; + sched_nr_cell_cfg_t cellcfg = get_cell_cfg(); + sched_nr_impl::cell_config_manager cell_params{0, get_cell_cfg(), sched_args}; + sched_nr_impl::ue_cfg_manager uecfg{get_ue_cfg(cellcfg)}; + const bwp_params_t& bwp_params = cell_params.bwps[0]; + ue_carrier_params_t ue_cc{0x4601, bwp_params, uecfg}; + + pdsch_list_t pdschs; + pdsch_alloc_result alloc_res; + + pdsch_allocator pdsch_sched(bwp_params, 0, pdschs); + + pdcch_dl_t pdcch_common, pdcch_ue; + pdcch_common.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, 1, srsran_rnti_type_c, 0x4601); + pdcch_ue.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, 2, srsran_rnti_type_c, 0x4601); + + prb_interval lims_common = bwp_params.dci_fmt_1_0_prb_lims(pdcch_common.dci.ctx.coreset_id); + prb_interval lims_ue{0, bwp_params.nof_prb}; + + std::array, 4> grant_list = {std::make_pair(1, prb_interval{2, 4}), + std::make_pair(1, lims_common), + std::make_pair(1, lims_ue), + std::make_pair(2, lims_common)}; + + for (uint32_t i = 0; i < grant_list.size(); ++i) { + pdsch_sched.reset(); + TESTASSERT_EQ(0, pdschs.size()); + + auto g = grant_list[i]; + uint32_t ss_id = g.first; + prb_interval grant = g.second; + prb_interval lims = ss_id == 1 ? lims_common : lims_ue; + pdcch_dl_t& pdcch = ss_id == 1 ? pdcch_common : pdcch_ue; + + bool success_expected = grant.start() >= lims.start() and grant.stop() <= lims.stop(); + + alloc_result check_ret = pdsch_sched.is_ue_grant_valid(ue_cc, ss_id, srsran_dci_format_nr_1_0, grant); + prb_bitmap avail_prbs = pdsch_sched.occupied_prbs(ss_id, srsran_dci_format_nr_1_0); + int pos = avail_prbs.find_lowest(0, avail_prbs.size(), false); + TESTASSERT_EQ((int)lims.start(), pos); + pos = avail_prbs.find_lowest(lims.start(), avail_prbs.size(), true); + TESTASSERT_EQ((int)lims.stop(), (pos < 0 ? (int)avail_prbs.size() : pos)); + + printf("Attempt %d should be %ssuccessful\n", i, success_expected ? "" : "un"); + alloc_res = pdsch_sched.alloc_ue_pdsch(ss_id, srsran_dci_format_nr_1_0, grant, ue_cc, pdcch.dci); + TESTASSERT(success_expected == alloc_res.has_value()); + if (success_expected) { + // SIB1 allocation doesnt go outside CORESET#0 BW + TESTASSERT_EQ(1, pdschs.size()); + TESTASSERT(&pdschs.back() == alloc_res.value()); + TESTASSERT_EQ(0, pdcch.dci.time_domain_assigment); + + TESTASSERT(not avail_prbs.any(grant.start(), grant.stop())); + + test_dci_freq_assignment(bwp_params, grant, pdcch); + } else { + TESTASSERT(check_ret == alloc_res.error()); + TESTASSERT_EQ(0, pdschs.size()); + TESTASSERT(avail_prbs.any(grant.start(), grant.stop())); + } + } +} + +void test_pdsch_fail() +{ + srsran::test_delimit_logger delimiter{"Test PDSCH Allocation Failure"}; + + // Create Cell and UE configs + sched_nr_interface::sched_args_t sched_args; + sched_nr_cell_cfg_t cellcfg = get_cell_cfg(); + sched_nr_impl::cell_config_manager cell_params{0, cellcfg, sched_args}; + sched_nr_impl::ue_cfg_manager uecfg{get_ue_cfg(cellcfg)}; + const bwp_params_t& bwp_params = cell_params.bwps[0]; + ue_carrier_params_t ue_cc{0x4601, bwp_params, uecfg}; + + pdsch_list_t pdschs; + pdsch_alloc_result alloc_res; + + pdsch_allocator pdsch_sched(bwp_params, 0, pdschs); + + pdcch_dl_t pdcch_common, pdcch_ue, pdcch_rar, pdcch_si, pdcch; + pdcch_si.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, 0, srsran_rnti_type_si, SRSRAN_SIRNTI); + pdcch_rar.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, 1, srsran_rnti_type_ra, 0x2); + pdcch_common.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, 1, srsran_rnti_type_c, 0x4601); + pdcch_ue.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, 2, srsran_rnti_type_c, 0x4601); + + // Allocations of type 0 are not compatible with DCI format 1_0 + rbg_bitmap rbgs(bwp_params.N_rbg); + rbgs.set(1); + rbgs.set(3); + prb_grant grant_type0 = rbgs; + TESTASSERT_EQ(alloc_result::invalid_grant_params, pdsch_sched.alloc_si_pdsch(0, grant_type0, pdcch_si.dci).error()); + TESTASSERT_EQ(alloc_result::invalid_grant_params, pdsch_sched.alloc_rar_pdsch(grant_type0, pdcch_rar.dci).error()); + TESTASSERT_EQ(alloc_result::invalid_grant_params, + pdsch_sched.alloc_ue_pdsch(1, srsran_dci_format_nr_1_0, grant_type0, ue_cc, pdcch.dci).error()); + TESTASSERT_EQ(alloc_result::invalid_grant_params, + pdsch_sched.alloc_ue_pdsch(2, srsran_dci_format_nr_1_0, grant_type0, ue_cc, pdcch.dci).error()); + + // Resource Allocation type must be compatible with UE PDSCH configuration + TESTASSERT_EQ(alloc_result::invalid_grant_params, + pdsch_sched.alloc_ue_pdsch(2, srsran_dci_format_nr_1_1, grant_type0, ue_cc, pdcch.dci).error()); + + // Allocations of DCI format 1_0 should start from CORESET first RB and their BW should be limited by CORESET#0 BW + prb_grant grant_type1 = prb_interval{0, bwp_params.coreset_prb_range(0).stop()}; + TESTASSERT(pdsch_sched.alloc_ue_pdsch(1, srsran_dci_format_nr_1_0, grant_type1, ue_cc, pdcch.dci).is_error()); + grant_type1 = prb_interval{bwp_params.coreset_prb_range(0).start(), bwp_params.nof_prb}; + TESTASSERT(pdsch_sched.alloc_ue_pdsch(1, srsran_dci_format_nr_1_0, grant_type1, ue_cc, pdcch.dci).is_error()); + TESTASSERT(pdsch_sched.alloc_ue_pdsch(2, srsran_dci_format_nr_1_0, grant_type1, ue_cc, pdcch.dci).has_value()); + + // PRB collisions are detected + TESTASSERT(pdsch_sched.alloc_ue_pdsch(2, srsran_dci_format_nr_1_0, prb_interval{5, 6}, ue_cc, pdcch.dci).is_error()); +} + +void test_multi_pdsch() +{ + srsran::test_delimit_logger delimiter{"Test Multiple PDSCH Allocations"}; + + // Create Cell and UE configs + sched_nr_interface::sched_args_t sched_args; + sched_nr_cell_cfg_t cellcfg = get_cell_cfg(); + sched_nr_impl::cell_config_manager cell_params{0, cellcfg, sched_args}; + sched_nr_impl::ue_cfg_manager uecfg{get_ue_cfg(cellcfg)}; + const bwp_params_t& bwp_params = cell_params.bwps[0]; + ue_carrier_params_t ue_cc{0x4601, bwp_params, uecfg}; + ue_carrier_params_t ue_cc2{0x4602, bwp_params, uecfg}; + + pdsch_list_t pdschs; + pdsch_alloc_result alloc_res; + + pdsch_allocator pdsch_sched(bwp_params, 0, pdschs); + + pdcch_dl_t pdcch_sib, pdcch_common, pdcch_ue; + pdcch_sib.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, 0, srsran_rnti_type_si, SRSRAN_SIRNTI); + pdcch_common.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, 1, srsran_rnti_type_c, 0x4601); + pdcch_ue.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, 2, srsran_rnti_type_c, 0x4602); + + // Allocate SIB1 + uint32_t ss_id = 0; + pdcch_dl_t* pdcch = &pdcch_sib; + prb_bitmap used_prbs = pdsch_sched.occupied_prbs(ss_id, srsran_dci_format_nr_1_0); + fmt::print("No allocations yet. Occupied PRBs for common SearchSpace: {:b}\n", used_prbs); + uint32_t sib1_grant_size = 4; + prb_bitmap sib_prbs = ~used_prbs; + int first_prb = sib_prbs.find_lowest(0, sib_prbs.size(), true); + prb_interval sib_grant{(uint32_t)first_prb, sib1_grant_size}; + TESTASSERT_EQ(alloc_result::success, pdsch_sched.is_si_grant_valid(ss_id, sib_grant)); + alloc_res = pdsch_sched.alloc_si_pdsch(ss_id, sib_grant, pdcch->dci); + TESTASSERT(alloc_res.has_value()); + test_dci_freq_assignment(bwp_params, sib_grant, *pdcch); + prb_bitmap used_prbs_sib1 = pdsch_sched.occupied_prbs(ss_id, srsran_dci_format_nr_1_0); + TESTASSERT_EQ(used_prbs_sib1.count(), used_prbs.count() + sib_grant.length()); + TESTASSERT_EQ(alloc_result::sch_collision, pdsch_sched.is_si_grant_valid(ss_id, sib_grant)); + + prb_bitmap last_prb_bitmap(used_prbs.size()); + last_prb_bitmap.fill(sib_grant.start(), sib_grant.stop()); + fmt::print("SIB1 allocated. Occupied PRBs:\n{:b} -> {:b}\n", last_prb_bitmap, used_prbs_sib1); + + // Allocate UE in common SearchSpace + ss_id = 1; + pdcch = &pdcch_common; + prb_bitmap ue_prbs = ~used_prbs_sib1; + first_prb = ue_prbs.find_lowest(0, ue_prbs.size(), true); + uint32_t ue_grant_size = 10; + prb_interval ue_grant{(uint32_t)first_prb, ue_grant_size}; + TESTASSERT_EQ(alloc_result::success, pdsch_sched.is_ue_grant_valid(ue_cc, ss_id, srsran_dci_format_nr_1_0, ue_grant)); + alloc_res = pdsch_sched.alloc_ue_pdsch(ss_id, srsran_dci_format_nr_1_0, ue_grant, ue_cc, pdcch->dci); + TESTASSERT(alloc_res.has_value()); + test_dci_freq_assignment(bwp_params, ue_grant, *pdcch); + prb_bitmap used_prbs_ue = pdsch_sched.occupied_prbs(ss_id, srsran_dci_format_nr_1_0); + TESTASSERT_EQ(used_prbs_ue.count(), used_prbs_sib1.count() + ue_grant.length()); + TESTASSERT_EQ(alloc_result::sch_collision, + pdsch_sched.is_ue_grant_valid(ue_cc, ss_id, srsran_dci_format_nr_1_0, ue_grant)); + + last_prb_bitmap.reset(); + last_prb_bitmap.fill(ue_grant.start(), ue_grant.stop()); + fmt::print("C-RNTI allocated in Common SearchSpace. Occupied PRBs:\n{:b} -> {:b}\n", last_prb_bitmap, used_prbs_ue); + + // Allocate UE in UE SearchSpace + ss_id = 2; + pdcch = &pdcch_ue; + used_prbs = pdsch_sched.occupied_prbs(ss_id, srsran_dci_format_nr_1_0); + prb_interval ue_grant2 = find_empty_interval_of_length(used_prbs, used_prbs_ue.size(), 0); + TESTASSERT_EQ(bwp_params.nof_prb, ue_grant2.stop()); + TESTASSERT_EQ(alloc_result::success, + pdsch_sched.is_ue_grant_valid(ue_cc, ss_id, srsran_dci_format_nr_1_0, ue_grant2)); + alloc_res = pdsch_sched.alloc_ue_pdsch(ss_id, srsran_dci_format_nr_1_0, ue_grant2, ue_cc, pdcch->dci); + TESTASSERT(alloc_res.has_value()); + test_dci_freq_assignment(bwp_params, ue_grant2, *pdcch); + prb_bitmap used_prbs_ue2 = pdsch_sched.occupied_prbs(ss_id, srsran_dci_format_nr_1_0); + TESTASSERT_EQ(used_prbs_ue2.count(), used_prbs.count() + ue_grant2.length()); + TESTASSERT_EQ(alloc_result::sch_collision, + pdsch_sched.is_ue_grant_valid(ue_cc, ss_id, srsran_dci_format_nr_1_0, ue_grant2)); + + last_prb_bitmap.reset(); + last_prb_bitmap.fill(ue_grant2.start(), ue_grant2.stop()); + fmt::print("C-RNTI allocated in UE-dedicated common SearchSpace. Occupied PRBs:\n{:b} -> {:b}\n", + last_prb_bitmap, + used_prbs_ue2); + + TESTASSERT_EQ(3, pdschs.size()); + pdsch_sched.reset(); + TESTASSERT_EQ(0, pdschs.size()); + TESTASSERT_EQ(0, pdsch_sched.occupied_prbs(2, srsran_dci_format_nr_1_0).count()); +} + +void test_multi_pusch() +{ + srsran::test_delimit_logger delimiter{"Test Multiple PUSCH Allocations"}; + + // Create Cell and UE configs + sched_nr_interface::sched_args_t sched_args; + sched_nr_cell_cfg_t cellcfg = get_cell_cfg(); + sched_nr_impl::cell_config_manager cell_params{0, cellcfg, sched_args}; + sched_nr_impl::ue_cfg_manager uecfg{get_ue_cfg(cellcfg)}; + const bwp_params_t& bwp_params = cell_params.bwps[0]; + ue_carrier_params_t ue_cc{0x4601, bwp_params, uecfg}; + ue_carrier_params_t ue_cc2{0x4602, bwp_params, uecfg}; + + pusch_list_t puschs; + pusch_alloc_result alloc_res; + + pusch_allocator pusch_sched(bwp_params, 0, puschs); + + pdcch_ul_t pdcch_ue1, pdcch_ue2; + pdcch_ue1.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, 1, srsran_rnti_type_c, 0x4601); + pdcch_ue2.dci.ctx = generate_dci_ctx(bwp_params.cfg.pdcch, 2, srsran_rnti_type_c, 0x4602); + + // Allocate UE in common SearchSpace + uint32_t ss_id = 1; + pdcch_ul_t* pdcch = &pdcch_ue1; + prb_bitmap used_prbs = pusch_sched.occupied_prbs(); + uint32_t ue_grant_size = 10; + prb_interval ue_grant = find_empty_interval_of_length(used_prbs, ue_grant_size); + TESTASSERT_EQ(alloc_result::success, pusch_sched.is_grant_valid(srsran_search_space_type_common_1, ue_grant)); + alloc_res = pusch_sched.alloc_pusch(pdcch->dci.ctx.ss_type, ue_grant, pdcch->dci); + TESTASSERT(alloc_res.has_value()); + prb_bitmap used_prbs_ue1 = pusch_sched.occupied_prbs(); + TESTASSERT_EQ(used_prbs_ue1.count(), used_prbs.count() + ue_grant.length()); + TESTASSERT_EQ(alloc_result::sch_collision, + pusch_sched.is_grant_valid(srsran_search_space_type_common_1, ue_grant, false)); + + prb_bitmap last_prb_bitmap(used_prbs.size()); + last_prb_bitmap.fill(ue_grant.start(), ue_grant.stop()); + fmt::print("C-RNTI allocated in Common SearchSpace. Occupied PRBs:\n{:b} -> {:b}\n", last_prb_bitmap, used_prbs_ue1); + + // Allocate UE in dedicated SearchSpace + ss_id = 2; + pdcch = &pdcch_ue2; + used_prbs = pusch_sched.occupied_prbs(); + prb_interval ue2_grant = find_empty_interval_of_length(used_prbs, used_prbs.size()); + TESTASSERT_EQ(alloc_result::success, pusch_sched.is_grant_valid(srsran_search_space_type_ue, ue2_grant)); + alloc_res = pusch_sched.alloc_pusch(pdcch->dci.ctx.ss_type, ue2_grant, pdcch->dci); + TESTASSERT(alloc_res.has_value()); + prb_bitmap used_prbs_ue2 = pusch_sched.occupied_prbs(); + TESTASSERT_EQ(used_prbs_ue2.count(), used_prbs.count() + ue2_grant.length()); + TESTASSERT_EQ(alloc_result::sch_collision, pusch_sched.is_grant_valid(srsran_search_space_type_ue, ue2_grant, false)); + + last_prb_bitmap.reset(); + last_prb_bitmap.fill(ue2_grant.start(), ue2_grant.stop()); + fmt::print("C-RNTI allocated in Common SearchSpace. Occupied PRBs:\n{:b} -> {:b}\n", last_prb_bitmap, used_prbs_ue2); +} + +} // namespace srsenb + +int main() +{ + auto& test_logger = srslog::fetch_basic_logger("TEST"); + test_logger.set_level(srslog::basic_levels::info); + auto& mac_nr_logger = srslog::fetch_basic_logger("MAC-NR"); + mac_nr_logger.set_level(srslog::basic_levels::debug); + auto& pool_logger = srslog::fetch_basic_logger("POOL"); + pool_logger.set_level(srslog::basic_levels::debug); + + // Start the log backend. + srslog::init(); + + srsenb::test_si(); + srsenb::test_rar(); + srsenb::test_ue_pdsch(); + srsenb::test_pdsch_fail(); + srsenb::test_multi_pdsch(); + srsenb::test_multi_pusch(); +} \ No newline at end of file diff --git a/srsgnb/src/stack/mac/test/sched_nr_sim_ue.cc b/srsgnb/src/stack/mac/test/sched_nr_sim_ue.cc new file mode 100644 index 0000000000..326cd845f7 --- /dev/null +++ b/srsgnb/src/stack/mac/test/sched_nr_sim_ue.cc @@ -0,0 +1,548 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "sched_nr_sim_ue.h" +#include "sched_nr_common_test.h" +#include "sched_nr_ue_ded_test_suite.h" +#include "srsran/common/test_common.h" +#include "srsran/common/thread_pool.h" + +namespace srsenb { + +sched_nr_ue_sim::sched_nr_ue_sim(uint16_t rnti_, const sched_nr_ue_cfg_t& ue_cfg_) : + logger(srslog::fetch_basic_logger("MAC")) +{ + ctxt.rnti = rnti_; + ctxt.ue_cfg.apply_config_request(ue_cfg_); + ctxt.preamble_idx = -1; + + ctxt.cc_list.resize(ue_cfg_.carriers.size()); + for (auto& cc : ctxt.cc_list) { + for (size_t pid = 0; pid < SCHED_NR_MAX_HARQ; ++pid) { + cc.ul_harqs[pid].pid = pid; + cc.dl_harqs[pid].pid = pid; + } + } +} + +sched_nr_ue_sim::sched_nr_ue_sim(uint16_t rnti_, + const sched_nr_ue_cfg_t& ue_cfg_, + slot_point prach_slot_rx, + uint32_t preamble_idx) : + sched_nr_ue_sim(rnti_, ue_cfg_) +{ + ctxt.prach_slot_rx = prach_slot_rx; + ctxt.preamble_idx = preamble_idx; +} + +int sched_nr_ue_sim::update(const sched_nr_cc_result_view& cc_out) +{ + update_dl_harqs(cc_out); + + for (uint32_t i = 0; i < cc_out.dl->phy.pdcch_dl.size(); ++i) { + const auto& data = cc_out.dl->phy.pdcch_dl[i]; + if (data.dci.ctx.rnti != ctxt.rnti) { + continue; + } + slot_point pdcch_slot = cc_out.slot; + uint32_t k1 = ctxt.ue_cfg.phy_cfg.harq_ack + .dl_data_to_ul_ack[pdcch_slot.slot_idx() % ctxt.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack]; + slot_point uci_slot = pdcch_slot + k1; + + ctxt.cc_list[cc_out.cc].pending_acks[uci_slot.to_uint()]++; + } + + // clear up old slots + ctxt.cc_list[cc_out.cc].pending_acks[(cc_out.slot - 1).to_uint()] = 0; + + return SRSRAN_SUCCESS; +} + +void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_result_view& cc_out) +{ + uint32_t cc = cc_out.cc; + + // Update DL Harqs + for (uint32_t i = 0; i < cc_out.dl->phy.pdcch_dl.size(); ++i) { + const auto& data = cc_out.dl->phy.pdcch_dl[i]; + if (data.dci.ctx.rnti != ctxt.rnti) { + continue; + } + auto& h = ctxt.cc_list[cc].dl_harqs[data.dci.pid]; + if (h.nof_txs == 0 or h.ndi != data.dci.ndi) { + // It is newtx + h.nof_retxs = 0; + h.ndi = data.dci.ndi; + h.first_slot_tx = cc_out.slot; + h.dci_loc = data.dci.ctx.location; + for (const sched_nr_impl::pdsch_t& pdsch : cc_out.dl->phy.pdsch) { + if (pdsch.sch.grant.rnti == data.dci.ctx.rnti) { + h.tbs = pdsch.sch.grant.tb[0].tbs / 8u; + } + } + } else { + // it is retx + h.nof_retxs++; + } + h.active = true; + h.last_slot_tx = cc_out.slot; + h.last_slot_ack = + h.last_slot_tx + + ctxt.ue_cfg.phy_cfg.harq_ack + .dl_data_to_ul_ack[h.last_slot_tx.slot_idx() % ctxt.ue_cfg.phy_cfg.harq_ack.nof_dl_data_to_ul_ack]; + h.nof_txs++; + } + + // Update UL harqs + for (uint32_t i = 0; i < cc_out.dl->phy.pdcch_ul.size(); ++i) { + const auto& data = cc_out.dl->phy.pdcch_ul[i]; + if (data.dci.ctx.rnti != ctxt.rnti) { + continue; + } + auto& h = ctxt.cc_list[cc].ul_harqs[data.dci.pid]; + if (h.nof_txs == 0 or h.ndi != data.dci.ndi) { + // It is newtx + h.is_msg3 = false; + h.nof_retxs = 0; + h.ndi = data.dci.ndi; + h.first_slot_tx = cc_out.slot + 4; // TODO + h.dci_loc = data.dci.ctx.location; + h.tbs = 100; // TODO + } else { + // it is retx + h.nof_retxs++; + } + h.active = true; + h.last_slot_tx = cc_out.slot + 4; // TODO + h.last_slot_ack = h.last_slot_tx; + h.nof_txs++; + } + + uint32_t rar_count = 0; + for (uint32_t i = 0; i < cc_out.dl->phy.pdcch_dl.size(); ++i) { + const auto& rar_pdcch = cc_out.dl->phy.pdcch_dl[i]; + if (rar_pdcch.dci.ctx.rnti_type != srsran_rnti_type_ra) { + continue; + } + const auto& rar_data = cc_out.dl->rar[rar_count++]; + for (uint32_t j = 0; j < rar_data.grants.size(); ++j) { + auto& msg3_grant = rar_data.grants[j]; + if (msg3_grant.msg3_dci.ctx.rnti != ctxt.rnti) { + continue; + } + auto& h = ctxt.cc_list[cc].ul_harqs[msg3_grant.msg3_dci.pid]; + if (h.nof_txs == 0) { + // It is newtx + h.is_msg3 = true; + h.nof_retxs = 0; + h.ndi = msg3_grant.msg3_dci.ndi; + h.first_slot_tx = cc_out.slot + 4 + MSG3_DELAY_MS; // TODO + h.dci_loc = msg3_grant.msg3_dci.ctx.location; + h.tbs = 100; // TODO + } else { + // it is retx + h.nof_retxs++; + } + h.active = true; + h.last_slot_tx = cc_out.slot + 4 + MSG3_DELAY_MS; // TODO + h.last_slot_ack = h.last_slot_tx; + h.nof_txs++; + } + } +} + +sched_nr_base_test_bench::sched_nr_base_test_bench(const sched_nr_interface::sched_args_t& sched_args, + const std::vector& cell_cfg_list, + std::string test_name_, + uint32_t nof_workers) : + logger(srslog::fetch_basic_logger("TEST")), + mac_logger(srslog::fetch_basic_logger("MAC-NR")), + sched_ptr(new sched_nr()), + test_delimiter(new srsran::test_delimit_logger{test_name_.c_str()}) +{ + sem_init(&slot_sem, 0, 1); + + cell_params.reserve(cell_cfg_list.size()); + for (uint32_t cc = 0; cc < cell_cfg_list.size(); ++cc) { + cell_params.emplace_back(cc, cell_cfg_list[cc], sched_args); + } + sched_ptr->config(sched_args, cell_cfg_list); // call parent cfg + + cc_workers.resize(nof_workers - 1); + for (uint32_t i = 0; i < cc_workers.size(); ++i) { + fmt::memory_buffer fmtbuf; + fmt::format_to(fmtbuf, "worker{}", i + 1); + cc_workers[i].reset(new srsran::task_worker{to_string(fmtbuf), 10}); + } + + cc_results.resize(cell_params.size()); + + TESTASSERT(cell_params.size() > 0); +} + +sched_nr_base_test_bench::~sched_nr_base_test_bench() +{ + stop(); +} + +void sched_nr_base_test_bench::stop() +{ + bool stopping = not stopped.exchange(true); + if (stopping) { + sem_wait(&slot_sem); + sem_post(&slot_sem); + for (auto& worker : cc_workers) { + worker->stop(); + } + sem_destroy(&slot_sem); + test_delimiter.reset(); + } +} + +std::vector sched_nr_base_test_bench::get_slot_results() const +{ + sem_wait(&slot_sem); + auto ret = cc_results; + sem_post(&slot_sem); + return ret; +} + +int sched_nr_base_test_bench::rach_ind(uint16_t rnti, uint32_t cc, slot_point tti_rx, uint32_t preamble_idx) +{ + sem_wait(&slot_sem); + + TESTASSERT(ue_db.count(rnti) == 0); + + sched_nr_interface::rar_info_t rach_info{}; + rach_info.cc = cc; + rach_info.temp_crnti = rnti; + rach_info.prach_slot = tti_rx; + rach_info.preamble_idx = preamble_idx; + rach_info.msg3_size = 7; + sched_ptr->dl_rach_info(rach_info); + + sched_nr_ue_cfg_t uecfg; + uecfg.carriers.resize(1); + uecfg.carriers[0].active = true; + uecfg.carriers[0].cc = cc; + uecfg.phy_cfg = cell_params[cc].default_ue_phy_cfg; + ue_db.insert(std::make_pair(rnti, sched_nr_ue_sim(rnti, uecfg, current_slot_tx, preamble_idx))); + + sem_post(&slot_sem); + return SRSRAN_SUCCESS; +} + +void sched_nr_base_test_bench::user_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_) +{ + sem_wait(&slot_sem); + + if (ue_db.count(rnti) == 0) { + ue_db.insert(std::make_pair(rnti, sched_nr_ue_sim(rnti, ue_cfg_))); + } else { + ue_db.at(rnti).get_ctxt().ue_cfg.apply_config_request(ue_cfg_); + } + sched_ptr->ue_cfg(rnti, ue_cfg_); + + sem_post(&slot_sem); +} + +void sched_nr_base_test_bench::add_rlc_dl_bytes(uint16_t rnti, uint32_t lcid, uint32_t pdu_size_bytes) +{ + TESTASSERT(ue_db.count(rnti) > 0); + dl_buffer_state_diff(rnti, lcid, pdu_size_bytes); +} + +void sched_nr_base_test_bench::run_slot(slot_point slot_tx) +{ + srsran_assert(not stopped.load(std::memory_order_relaxed), "Running scheduler when it has already been stopped"); + // Block concurrent or out-of-order calls to the scheduler + sem_wait(&slot_sem); + current_slot_tx = slot_tx; + nof_cc_remaining = cell_params.size(); + + logger.set_context(slot_tx.to_uint()); + mac_logger.set_context(slot_tx.to_uint()); + + // Clear previous slot results + for (uint32_t cc = 0; cc < cc_results.size(); ++cc) { + cc_results[cc] = {}; + } + logger.info("---------------- TTI=%d ---------------", slot_tx.to_uint()); + + // Process pending feedback + for (auto& ue : ue_db) { + ue_nr_slot_events events; + set_default_slot_events(ue.second.get_ctxt(), events); + set_external_slot_events(ue.second.get_ctxt(), events); + apply_slot_events(ue.second.get_ctxt(), events); + } + + slot_ctxt = get_enb_ctxt(); + slot_start_tp = std::chrono::steady_clock::now(); + + sched_ptr->slot_indication(current_slot_tx); + + // Generate CC result (parallel or serialized) + uint32_t worker_idx = 0; + for (uint32_t cc = 0; cc < cell_params.size(); ++cc) { + if (worker_idx == cc_workers.size()) { + generate_cc_result(cc); + } else { + cc_workers[worker_idx]->push_task([this, cc]() { generate_cc_result(cc); }); + } + worker_idx = (worker_idx + 1) % (cc_workers.size() + 1); + } +} + +void sched_nr_base_test_bench::generate_cc_result(uint32_t cc) +{ + // Run scheduler + cc_results[cc].res.slot = current_slot_tx; + cc_results[cc].res.cc = cc; + cc_results[cc].res.dl = sched_ptr->get_dl_sched(current_slot_tx, cc); + cc_results[cc].res.ul = sched_ptr->get_ul_sched(current_slot_tx, cc); + auto tp2 = std::chrono::steady_clock::now(); + cc_results[cc].cc_latency_ns = std::chrono::duration_cast(tp2 - slot_start_tp); + + if (--nof_cc_remaining > 0) { + // there are still missing CC results + return; + } + + // Run tests and update UE state + process_results(); + + // Notify awaiting new slot worker + sem_post(&slot_sem); +} + +void sched_nr_base_test_bench::process_results() +{ + // Derived class-defined tests + process_slot_result(slot_ctxt, cc_results); + + for (uint32_t cc = 0; cc < cell_params.size(); ++cc) { + sched_nr_cc_result_view cc_out = cc_results[cc].res; + + // Run common tests + test_dl_pdcch_consistency(cell_params[cc], cc_out.dl->phy.pdcch_dl); + test_pdsch_consistency(cc_out.dl->phy.pdsch); + test_ssb_scheduled_grant(cc_out.slot, cell_params[cc_out.cc], cc_out.dl->phy.ssb); + + // Run UE-dedicated tests + test_dl_sched_result(slot_ctxt, cc_out); + + // Update UE state + for (auto& u : ue_db) { + u.second.update(cc_out); + } + + // Update scheduler buffers + update_sched_buffer_state(cc_out); + } +} + +void sched_nr_base_test_bench::dl_buffer_state_diff(uint16_t rnti, uint32_t lcid, int newtx) +{ + auto& lch = gnb_ue_db[rnti].logical_channels[lcid]; + lch.rlc_unacked = std::max(0, (int)lch.rlc_unacked + newtx); + update_sched_buffer_state(rnti); + logger.debug("STATUS: rnti=0x%x, lcid=%d DL buffer state is (unacked=%d, newtx=%d)", + rnti, + lcid, + lch.rlc_unacked, + lch.rlc_newtx); +} + +void sched_nr_base_test_bench::dl_buffer_state_diff(uint16_t rnti, int diff_bs) +{ + if (diff_bs == 0) { + return; + } + if (diff_bs > 0) { + const auto& ue_bearers = ue_db.at(rnti).get_ctxt().ue_cfg.ue_bearers; + for (int i = ue_bearers.size() - 1; i >= 0; --i) { + if (ue_bearers[i].is_dl()) { + dl_buffer_state_diff(rnti, i, diff_bs); + return; + } + } + srsran_terminate("Updating UE RLC buffer state but no bearers are active"); + } + for (auto& lch : gnb_ue_db[rnti].logical_channels) { + if (not ue_db.at(rnti).get_ctxt().ue_cfg.ue_bearers[lch.first].is_dl()) { + continue; + } + int max_diff = -std::min((int)lch.second.rlc_unacked, -diff_bs); + if (max_diff != 0) { + dl_buffer_state_diff(rnti, lch.first, max_diff); + diff_bs -= max_diff; + } + } +} + +void sched_nr_base_test_bench::update_sched_buffer_state(uint16_t rnti) +{ + auto& u = ue_db.at(rnti); + for (auto& lch : gnb_ue_db[rnti].logical_channels) { + int newtx = lch.second.rlc_unacked; + for (auto& cc : u.get_ctxt().cc_list) { + if (newtx <= 0) { + break; + } + for (auto& dl_h : cc.dl_harqs) { + int tbs = dl_h.active ? dl_h.tbs : 0; + newtx = std::max(0, newtx - tbs); + } + } + if (newtx != (int)lch.second.rlc_newtx) { + sched_ptr->dl_buffer_state(rnti, lch.first, newtx, 0); + lch.second.rlc_newtx = newtx; + logger.debug("STATUS: rnti=0x%x, lcid=%d DL buffer state is (unacked=%d, newtx=%d)", + rnti, + lch.first, + lch.second.rlc_unacked, + lch.second.rlc_newtx); + } + } +} + +void sched_nr_base_test_bench::update_sched_buffer_state(const sched_nr_cc_result_view& cc_out) +{ + for (auto& dl : cc_out.dl->phy.pdcch_dl) { + if (dl.dci.ctx.rnti_type == srsran_rnti_type_c or dl.dci.ctx.rnti_type == srsran_rnti_type_tc) { + update_sched_buffer_state(dl.dci.ctx.rnti); + } + } +} + +int sched_nr_base_test_bench::set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, + ue_nr_slot_events& pending_events) +{ + pending_events.cc_list.clear(); + pending_events.cc_list.resize(cell_params.size()); + pending_events.slot_rx = current_slot_tx; + + for (uint32_t enb_cc_idx = 0; enb_cc_idx < pending_events.cc_list.size(); ++enb_cc_idx) { + auto& cc_feedback = pending_events.cc_list[enb_cc_idx]; + + cc_feedback.configured = true; + for (uint32_t pid = 0; pid < SCHED_NR_MAX_HARQ; ++pid) { + auto& dl_h = ue_ctxt.cc_list[enb_cc_idx].dl_harqs[pid]; + auto& ul_h = ue_ctxt.cc_list[enb_cc_idx].ul_harqs[pid]; + + // Set default DL ACK + if (dl_h.active and dl_h.last_slot_ack == current_slot_tx) { + cc_feedback.dl_acks.push_back(ue_nr_slot_events::ack_t{pid, true}); + } + + // Set default UL ACK + if (ul_h.active and ul_h.last_slot_ack == current_slot_tx) { + cc_feedback.ul_acks.emplace_back(ue_nr_slot_events::ack_t{pid, true}); + } + + // Set default CQI + if (ue_ctxt.ue_cfg.phy_cfg.csi.reports[0].type == SRSRAN_CSI_REPORT_TYPE_PERIODIC) { + auto& p = ue_ctxt.ue_cfg.phy_cfg.csi.reports[0].periodic; + if (p.offset == pending_events.slot_rx.to_uint() % p.period) { + cc_feedback.cqi = 15; + } + } + + // TODO: other CSI + } + } + + return SRSRAN_SUCCESS; +} + +int sched_nr_base_test_bench::apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_slot_events& events) +{ + for (uint32_t enb_cc_idx = 0; enb_cc_idx < events.cc_list.size(); ++enb_cc_idx) { + const auto& cc_feedback = events.cc_list[enb_cc_idx]; + if (not cc_feedback.configured) { + continue; + } + + for (auto& ack : cc_feedback.dl_acks) { + auto& h = ue_ctxt.cc_list[enb_cc_idx].dl_harqs[ack.pid]; + + if (ack.ack) { + logger.info("EVENT: DL ACK rnti=0x%x slot_dl_tx=%u cc=%d pid=%d, tbs=%d", + ue_ctxt.rnti, + h.last_slot_tx.to_uint(), + enb_cc_idx, + ack.pid, + h.tbs); + dl_buffer_state_diff(ue_ctxt.rnti, -(int)h.tbs); + } + + // update scheduler + sched_ptr->dl_ack_info(ue_ctxt.rnti, enb_cc_idx, h.pid, 0, ack.ack); + + // update UE sim context + if (ack.ack or ue_ctxt.is_last_dl_retx(enb_cc_idx, h.pid)) { + h.active = false; + } + } + + for (auto& ack : cc_feedback.ul_acks) { + auto& h = ue_ctxt.cc_list[enb_cc_idx].ul_harqs[ack.pid]; + + if (ack.ack) { + logger.info("EVENT: UL ACK rnti=0x%x, slot_ul_tx=%u, cc=%d pid=%d", + ue_ctxt.rnti, + h.last_slot_tx.to_uint(), + enb_cc_idx, + h.pid); + } + + // update scheduler + sched_ptr->ul_crc_info(ue_ctxt.rnti, enb_cc_idx, ack.pid, ack.ack); + + if (h.is_msg3) { + logger.info("STATUS: rnti=0x%x received Msg3", ue_ctxt.rnti); + dl_buffer_state_diff(ue_ctxt.rnti, 0, 150); // Schedule RRC setup + } + } + + if (cc_feedback.cqi >= 0) { + logger.info("EVENT: DL CQI rnti=0x%x, cqi=%d", ue_ctxt.rnti, cc_feedback.cqi); + sched_ptr->dl_cqi_info(ue_ctxt.rnti, enb_cc_idx, cc_feedback.cqi); + } + } + + return SRSRAN_SUCCESS; +} + +sim_nr_enb_ctxt_t sched_nr_base_test_bench::get_enb_ctxt() const +{ + sim_nr_enb_ctxt_t ctxt; + ctxt.cell_params = cell_params; + + for (auto& ue_pair : ue_db) { + ctxt.ue_db.insert(std::make_pair(ue_pair.first, &ue_pair.second.get_ctxt())); + } + + return ctxt; +} + +} // namespace srsenb \ No newline at end of file diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.h b/srsgnb/src/stack/mac/test/sched_nr_sim_ue.h similarity index 51% rename from srsenb/test/mac/nr/sched_nr_sim_ue.h rename to srsgnb/src/stack/mac/test/sched_nr_sim_ue.h index 5488c8eedf..119c5b6055 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.h +++ b/srsgnb/src/stack/mac/test/sched_nr_sim_ue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,9 +22,10 @@ #ifndef SRSRAN_SCHED_NR_SIM_UE_H #define SRSRAN_SCHED_NR_SIM_UE_H -#include "../sched_sim_ue.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr.h" +#include "srsenb/test/mac/sched_sim_ue.h" +#include "srsgnb/hdr/stack/mac/sched_nr.h" #include "srsran/adt/circular_array.h" +#include "srsran/common/test_common.h" #include #include @@ -39,6 +40,7 @@ const static uint32_t MAX_GRANTS = mac_interface_phy_nr::MAX_GRANTS; struct ue_nr_harq_ctxt_t { bool active = false; bool ndi = false; + bool is_msg3 = false; uint32_t pid = 0; uint32_t nof_txs = 0; uint32_t nof_retxs = std::numeric_limits::max(); @@ -49,17 +51,9 @@ struct ue_nr_harq_ctxt_t { }; struct sched_nr_cc_result_view { slot_point slot; - uint32_t cc; - const sched_nr_interface::dl_res_t dl_cc_result; - const sched_nr_interface::ul_res_t* ul_cc_result; - - sched_nr_cc_result_view(slot_point slot_, - uint32_t cc_, - sched_nr_interface::sched_rar_list_t& rar, - sched_nr_interface::dl_sched_t& dl_res, - sched_nr_interface::ul_res_t& ul_res) : - slot(slot_), cc(cc_), dl_cc_result(rar, dl_res), ul_cc_result(&ul_res) - {} + uint32_t cc = 0; + const sched_nr_interface::dl_res_t* dl = nullptr; + const sched_nr_interface::ul_res_t* ul = nullptr; }; struct ue_nr_cc_ctxt_t { @@ -77,17 +71,18 @@ struct ue_nr_slot_events { bool configured = false; srsran::bounded_vector dl_acks; srsran::bounded_vector ul_acks; + int cqi = -1; }; slot_point slot_rx; std::vector cc_list; }; struct sim_nr_ue_ctxt_t { - uint16_t rnti; - uint32_t preamble_idx; - slot_point prach_slot_rx; - sched_nr_interface::ue_cfg_t ue_cfg; - std::vector cc_list; + uint16_t rnti; + uint32_t preamble_idx; + slot_point prach_slot_rx; + sched_nr_impl::ue_cfg_manager ue_cfg; + std::vector cc_list; bool is_last_dl_retx(uint32_t ue_cc_idx, uint32_t pid) const { @@ -96,17 +91,15 @@ struct sim_nr_ue_ctxt_t { } }; struct sim_nr_enb_ctxt_t { - srsran::span cell_params; - std::map ue_db; + srsran::span cell_params; + std::map ue_db; }; class sched_nr_ue_sim { public: - sched_nr_ue_sim(uint16_t rnti_, - const sched_nr_interface::ue_cfg_t& ue_cfg_, - slot_point prach_slot_rx, - uint32_t preamble_idx); + sched_nr_ue_sim(uint16_t rnti_, const sched_nr_ue_cfg_t& ue_cfg_); + sched_nr_ue_sim(uint16_t rnti_, const sched_nr_ue_cfg_t& ue_cfg_, slot_point prach_slot_rx, uint32_t preamble_idx); int update(const sched_nr_cc_result_view& cc_out); @@ -120,58 +113,90 @@ class sched_nr_ue_sim sim_nr_ue_ctxt_t ctxt; }; -/// Implementation of features common to sched_nr_sim_parallel and sched_nr_sim -class sched_nr_base_tester +/// Implementation of features common to parallel and sequential sched nr testers +class sched_nr_base_test_bench { public: struct cc_result_t { - slot_point slot_tx; - uint32_t cc; - sched_nr_interface::dl_sched_t dl_res; - sched_nr_interface::sched_rar_list_t rar; - sched_nr_interface::ul_res_t ul_res; - std::chrono::nanoseconds cc_latency_ns; + sched_nr_cc_result_view res; + std::chrono::nanoseconds cc_latency_ns; }; - sched_nr_base_tester(const sched_nr_interface::sched_args_t& sched_args, - const std::vector& cell_params_, - std::string test_name, - uint32_t nof_workers = 1); - virtual ~sched_nr_base_tester(); + sched_nr_base_test_bench(const sched_nr_interface::sched_args_t& sched_args, + const std::vector& cell_params_, + std::string test_name, + uint32_t nof_workers = 1); + virtual ~sched_nr_base_test_bench(); void run_slot(slot_point slot_tx); void stop(); - int add_user(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_, slot_point tti_rx, uint32_t preamble_idx); + slot_point get_slot_tx() const { return current_slot_tx; } - srsran::const_span get_cell_params() { return cell_params; } + /// may block waiting for scheduler to finish generating slot result + std::vector get_slot_results() const; - // configurable by simulator concrete implementation + int rach_ind(uint16_t rnti, uint32_t cc, slot_point tti_rx, uint32_t preamble_idx); + + void user_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg_); + + void add_rlc_dl_bytes(uint16_t rnti, uint32_t lcid, uint32_t pdu_size_bytes); + + srsran::const_span get_cell_params() const { return cell_params; } + + /** + * @brief Specify external events that will be forwarded to the scheduler (CQI, ACKs, etc.) in the given slot + * This method can be overridden by the derived class to simulate the environment of interest. + * @param[in] ue_ctxt simulated UE context object + * @param[in/out] pending_events events to be sent to the scheduler. The passed arg is initialized with the + * "default events", sufficient to ensure a stable connection without retxs. + * The derived class can decide to erase/modify/add new events + */ virtual void set_external_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events) {} - // configurable by simulator concrete implementation + /** + * @brief Called every slot to process the scheduler output for a given CC. + * @param enb_ctxt simulated eNB context object + * @param cc_out scheduler result for a given CC + */ virtual void process_slot_result(const sim_nr_enb_ctxt_t& enb_ctxt, srsran::const_span cc_out) {} protected: void generate_cc_result(uint32_t cc); sim_nr_enb_ctxt_t get_enb_ctxt() const; + void dl_buffer_state_diff(uint16_t rnti, uint32_t lcid, int newtx); + void dl_buffer_state_diff(uint16_t rnti, int newtx); + void update_sched_buffer_state(uint16_t rnti); + void update_sched_buffer_state(const sched_nr_cc_result_view& cc_out); + int set_default_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events); int apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_nr_slot_events& events); /// Runs general tests to verify result consistency, and updates UE state void process_results(); - std::string test_name; - srslog::basic_logger& logger; - srslog::basic_logger& mac_logger; - std::unique_ptr sched_ptr; - std::vector cell_params; + std::unique_ptr test_delimiter; + srslog::basic_logger& logger; + srslog::basic_logger& mac_logger; + std::unique_ptr sched_ptr; + std::vector cell_params; std::vector > cc_workers; + // UE context from the UE's point-of-view std::map ue_db; + // gNB point-of-view of UE state + struct gnb_ue_ctxt { + struct channel_ctxt { + uint32_t rlc_unacked = 0; + uint32_t rlc_newtx = 0; + }; + std::map logical_channels; + }; + std::map gnb_ue_db; + // slot-specific slot_point current_slot_tx; std::chrono::steady_clock::time_point slot_start_tp; diff --git a/srsgnb/src/stack/mac/test/sched_nr_test.cc b/srsgnb/src/stack/mac/test/sched_nr_test.cc new file mode 100644 index 0000000000..d46bed1380 --- /dev/null +++ b/srsgnb/src/stack/mac/test/sched_nr_test.cc @@ -0,0 +1,334 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "sched_nr_cfg_generators.h" +#include "sched_nr_sim_ue.h" +#include "srsran/common/phy_cfg_nr_default.h" +#include "srsran/common/test_common.h" +#include "srsran/support/emergency_handlers.h" +#include +#include +#include + +// shorten boost program options namespace +namespace bpo = boost::program_options; + +namespace srsenb { + +std::default_random_engine rand_gen; + +struct sim_args_t { + uint32_t rand_seed; + uint32_t fixed_cqi; + std::string mac_log_level; + std::string test_log_level; +}; + +class sched_tester : public sched_nr_base_test_bench +{ + sim_args_t args; + +public: + explicit sched_tester(sim_args_t args_, + const sched_nr_interface::sched_args_t& sched_args, + const std::vector& cell_params_, + std::string test_name) : + sched_nr_base_test_bench(sched_args, cell_params_, test_name), args(args_) + {} + + void process_slot_result(const sim_nr_enb_ctxt_t& enb_ctxt, srsran::const_span cc_out) override + { + for (auto& cc : cc_out) { + for (auto& pdsch : cc.res.dl->phy.pdsch) { + if (pdsch.sch.grant.rnti_type == srsran_rnti_type_c or pdsch.sch.grant.rnti_type == srsran_rnti_type_tc) { + ue_metrics[pdsch.sch.grant.rnti].nof_dl_txs++; + ue_metrics[pdsch.sch.grant.rnti].nof_dl_bytes += pdsch.sch.grant.tb[0].tbs / 8u; + } + } + for (auto& pusch : cc.res.ul->pusch) { + if (pusch.sch.grant.rnti_type == srsran_rnti_type_c or pusch.sch.grant.rnti_type == srsran_rnti_type_tc) { + ue_metrics[pusch.sch.grant.rnti].nof_ul_txs++; + ue_metrics[pusch.sch.grant.rnti].nof_ul_bytes += pusch.sch.grant.tb[0].tbs / 8u; + } + } + } + } + + void set_external_slot_events(const sim_nr_ue_ctxt_t& ue_ctxt, ue_nr_slot_events& pending_events) override + { + for (uint32_t cc = 0; cc < pending_events.cc_list.size(); ++cc) { + auto& cc_events = pending_events.cc_list[cc]; + // if CQI is expected, set it to fixed value + if (cc_events.cqi >= 0) { + cc_events.cqi = args.fixed_cqi; + } + } + } + + void print_results() + { + srslog::flush(); + fmt::print("SCHED UE metrics:\n"); + for (auto& u : ue_metrics) { + fmt::print(" 0x{:x}: nof_txs=({}, {}), nof_bytes=({}, {})\n", + u.first, + u.second.nof_dl_txs, + u.second.nof_ul_txs, + u.second.nof_dl_bytes, + u.second.nof_ul_bytes); + } + } + + struct sched_ue_metrics { + uint32_t nof_dl_txs = 0, nof_ul_txs = 0; + uint64_t nof_dl_bytes = 0, nof_ul_bytes = 0; + }; + std::map ue_metrics; +}; + +struct sched_event_t { + uint32_t slot_count; + std::function run; +}; + +sched_event_t add_user(uint32_t slot_count, uint16_t rnti, uint32_t preamble_idx) +{ + auto task = [rnti, preamble_idx](sched_nr_base_test_bench& tester) { + tester.rach_ind(rnti, 0, tester.get_slot_tx() - TX_ENB_DELAY, preamble_idx); + }; + return sched_event_t{slot_count, task}; +} + +sched_event_t ue_cfg(uint32_t slot_count, uint16_t rnti, const sched_nr_ue_cfg_t& ue_cfg) +{ + auto task = [rnti, ue_cfg](sched_nr_base_test_bench& tester) { tester.user_cfg(rnti, ue_cfg); }; + return sched_event_t{slot_count, task}; +} + +sched_event_t add_rlc_dl_bytes(uint32_t slot_count, uint16_t rnti, uint32_t lcid, uint32_t pdu_size) +{ + auto task = [rnti, pdu_size, lcid](sched_nr_base_test_bench& tester) { + tester.add_rlc_dl_bytes(rnti, lcid, pdu_size); + }; + return sched_event_t{slot_count, task}; +} + +void test_sched_nr_no_data(sim_args_t args) +{ + uint32_t max_nof_ttis = 1000, nof_sectors = 1; + uint16_t rnti = 0x4601; + + sched_nr_interface::sched_args_t cfg; + cfg.auto_refill_buffer = false; + std::vector cells_cfg = get_default_cells_cfg(nof_sectors); + + std::string test_name = "Test with no data"; + sched_tester tester(args, cfg, cells_cfg, test_name); + + /* Set events */ + std::deque events; + events.push_back(add_user(9, rnti, 0)); + sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(1); + events.push_back(ue_cfg(20, rnti, uecfg)); + + /* Run Test */ + for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) { + slot_point slot_rx(0, nof_slots % 10240); + slot_point slot_tx = slot_rx + TX_ENB_DELAY; + + // run events + while (not events.empty() and events.front().slot_count <= nof_slots) { + events.front().run(tester); + events.pop_front(); + } + + // call sched + tester.run_slot(slot_tx); + } + + tester.print_results(); + + // Since DL buffers were not externally updated, we should only see Msg4 as DL tx + TESTASSERT_EQ(1, tester.ue_metrics[rnti].nof_dl_txs); + // Since UL buffers were not externally updated, we should only see Msg3 as UL tx + TESTASSERT_EQ(1, tester.ue_metrics[rnti].nof_ul_txs); +} + +void test_sched_nr_data(sim_args_t args) +{ + uint32_t nof_sectors = 1; + uint16_t rnti = 0x4601; + uint32_t nof_dl_bytes_to_tx = + std::uniform_int_distribution{1, 9}(rand_gen)*pow(10, std::uniform_int_distribution{1, 7}(rand_gen)); + + sched_nr_interface::sched_args_t cfg; + cfg.auto_refill_buffer = false; + std::vector cells_cfg = get_default_cells_cfg(nof_sectors); + + std::string test_name = "Test with data"; + sched_tester tester(args, cfg, cells_cfg, test_name); + + /* Set events */ + std::deque events; + events.push_back(add_user(9, rnti, 0)); + sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(1); + events.push_back(ue_cfg(20, rnti, uecfg)); + events.push_back(add_rlc_dl_bytes(50, rnti, 0, nof_dl_bytes_to_tx)); + + /* Run Test */ + uint32_t stop_tti = std::numeric_limits::max(); + auto finish_condition = [&stop_tti, rnti, nof_dl_bytes_to_tx, &tester](uint32_t nof_slots) mutable { + if (stop_tti == std::numeric_limits::max() and + tester.ue_metrics[rnti].nof_dl_bytes >= nof_dl_bytes_to_tx) { + stop_tti = nof_slots + 10; + } + return nof_slots >= std::min(stop_tti, 100000u); + }; + for (uint32_t nof_slots = 0; not finish_condition(nof_slots); ++nof_slots) { + slot_point slot_rx(0, nof_slots % 10240); + slot_point slot_tx = slot_rx + TX_ENB_DELAY; + + // run events + while (not events.empty() and events.front().slot_count <= nof_slots) { + events.front().run(tester); + events.pop_front(); + } + + // call sched + tester.run_slot(slot_tx); + } + // Run a few extra slots to ensure the scheduler does not allocate more DL bytes than necessary + for (uint32_t nof_slots_extra = 0; nof_slots_extra < 40; ++nof_slots_extra) { + tester.run_slot(tester.get_slot_tx() + 1); + auto results = tester.get_slot_results(); + TESTASSERT(results[0].res.dl->phy.pdcch_dl.empty()); + TESTASSERT(results[0].res.dl->phy.pdcch_ul.empty()); + } + + srslog::flush(); + fmt::print("== Results ==\n"); + fmt::print("Enqueued RLC DL bytes: {}\n", nof_dl_bytes_to_tx); + tester.print_results(); + + TESTASSERT(tester.ue_metrics[rnti].nof_dl_txs > 0); + TESTASSERT(tester.ue_metrics[rnti].nof_dl_bytes >= nof_dl_bytes_to_tx); + TESTASSERT(tester.ue_metrics[rnti].nof_dl_bytes < nof_dl_bytes_to_tx + 20000); + // Since UL buffers were not externally updated, we should only see Msg3 as UL tx + TESTASSERT_EQ(1, tester.ue_metrics[rnti].nof_ul_txs); +} + +sim_args_t handle_args(int argc, char** argv) +{ + sim_args_t args; + + std::string config_file; + bpo::options_description options; + bpo::options_description options_sim("Test Sim options"); + bpo::options_description options_conf_file("Configuration file"); + + // clang-format off + options_sim.add_options() + ("seed", bpo::value(&args.rand_seed)->default_value(std::chrono::system_clock::now().time_since_epoch().count()), "Simulation Random Seed") + ("cqi", bpo::value(&args.fixed_cqi)->default_value(15), "UE DL CQI") + ("log.mac_level", bpo::value(&args.mac_log_level)->default_value("info"), "MAC log level") + ("log.test_level", bpo::value(&args.test_log_level)->default_value("info"), "TEST log level") + ; + options_conf_file.add_options() + ("config_file", bpo::value(&config_file), "Configuration file") + ; + + bpo::positional_options_description p; + p.add("config_file", -1); + + options.add(options_sim).add(options_conf_file).add_options() + ("help", "Show this message") + ; + // clang-format on + + bpo::variables_map vm; + try { + bpo::store(bpo::command_line_parser(argc, argv).options(options).positional(p).run(), vm); + bpo::notify(vm); + } catch (bpo::error& e) { + srsran_terminate("%s", e.what()); + } + + // help option was given or error - print usage and exit + if (vm.count("help")) { + fmt::print("Usage: {} [OPTIONS] config_file\n\n", argv[0]); + fmt::print("{}\n", options); + exit(0); + } + + // if config file given + if (vm.count("config_file") != 0U) { + fmt::print("Reading configuration file {}...\n", config_file); + std::ifstream conf(config_file.c_str(), std::ios::in); + if (conf.fail()) { + fmt::print("Failed to read configuration file {} - exiting\n", config_file); + exit(1); + } + + // parse config file and handle errors gracefully + try { + bpo::store(bpo::parse_config_file(conf, options), vm); + bpo::notify(vm); + } catch (const boost::program_options::error& e) { + srsran_terminate("%s\n", e.what()); + } + } + + return args; +} + +} // namespace srsenb + +int main(int argc, char** argv) +{ + // Start the log backend. + srslog::init(); + + // Parse args + srsenb::sim_args_t args = srsenb::handle_args(argc, argv); + + // Initialize Loggers + auto& test_logger = srslog::fetch_basic_logger("TEST"); + test_logger.set_level(srslog::str_to_basic_level(args.test_log_level)); + auto& mac_nr_logger = srslog::fetch_basic_logger("MAC-NR"); + mac_nr_logger.set_level(srslog::str_to_basic_level(args.mac_log_level)); + auto& pool_logger = srslog::fetch_basic_logger("POOL"); + pool_logger.set_level(srslog::basic_levels::debug); + + // Setup Random Generator + srsenb::rand_gen = std::default_random_engine(args.rand_seed); + fmt::print("TEST: Random Seed is {}", args.rand_seed); + add_emergency_cleanup_handler( + [](void* args_void) { + auto* args = (srsenb::sim_args_t*)args_void; + fmt::print("TEST: Random Seed was {}", args->rand_seed); + }, + (void*)&args); + + srsenb::test_sched_nr_no_data(args); + srsenb::test_sched_nr_data(args); + + fmt::print("TEST: Random Seed was {}", args.rand_seed); +} diff --git a/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.cc b/srsgnb/src/stack/mac/test/sched_nr_ue_ded_test_suite.cc similarity index 89% rename from srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.cc rename to srsgnb/src/stack/mac/test/sched_nr_ue_ded_test_suite.cc index a1d6ec59af..ba9e2cf052 100644 --- a/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.cc +++ b/srsgnb/src/stack/mac/test/sched_nr_ue_ded_test_suite.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,7 +20,7 @@ */ #include "sched_nr_ue_ded_test_suite.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h" +#include "srsgnb/hdr/stack/mac/sched_nr_grant_allocator.h" #include "srsran/common/test_common.h" namespace srsenb { @@ -30,7 +30,7 @@ using namespace srsenb::sched_nr_impl; void test_dl_sched_result(const sim_nr_enb_ctxt_t& enb_ctxt, const sched_nr_cc_result_view& cc_out) { slot_point pdcch_slot = cc_out.slot; - const pdcch_dl_list_t& pdcchs = cc_out.dl_cc_result.dl_sched.pdcch_dl; + const pdcch_dl_list_t& pdcchs = cc_out.dl->phy.pdcch_dl; // Iterate over UE PDCCH allocations for (const pdcch_dl_t& pdcch : pdcchs) { @@ -51,7 +51,7 @@ void test_dl_sched_result(const sim_nr_enb_ctxt_t& enb_ctxt, const sched_nr_cc_r // CHECK: UCI if (pdcch.dci.ctx.format == srsran_dci_format_nr_1_0) { - TESTASSERT(pdcch.dci.harq_feedback == k1 - 1); + TESTASSERT_EQ(k1 - 1, pdcch.dci.harq_feedback); } else { TESTASSERT(pdcch.dci.harq_feedback == pdcch_slot.slot_idx()); } diff --git a/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.h b/srsgnb/src/stack/mac/test/sched_nr_ue_ded_test_suite.h similarity index 94% rename from srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.h rename to srsgnb/src/stack/mac/test/sched_nr_ue_ded_test_suite.h index 8547781126..3e7ca447a2 100644 --- a/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.h +++ b/srsgnb/src/stack/mac/test/sched_nr_ue_ded_test_suite.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsgnb/src/stack/mac/ue_nr.cc b/srsgnb/src/stack/mac/ue_nr.cc new file mode 100644 index 0000000000..8a3553be27 --- /dev/null +++ b/srsgnb/src/stack/mac/ue_nr.cc @@ -0,0 +1,273 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include +#include +#include +#include + +#include "srsgnb/hdr/stack/mac/ue_nr.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/common/string_helpers.h" +#include "srsran/interfaces/gnb_interfaces.h" + +namespace srsenb { + +ue_nr::ue_nr(uint16_t rnti_, + uint32_t enb_cc_idx, + sched_nr_interface* sched_, + rrc_interface_mac_nr* rrc_, + rlc_interface_mac* rlc_, + phy_interface_stack_nr* phy_, + srslog::basic_logger& logger_) : + rnti(rnti_), + sched(sched_), + rrc(rrc_), + rlc(rlc_), + phy(phy_), + logger(logger_), + ue_rlc_buffer(srsran::make_byte_buffer()) +{} + +ue_nr::~ue_nr() {} + +void ue_nr::reset() +{ + { + std::lock_guard lock(metrics_mutex); + ue_metrics = {}; + } + nof_failures = 0; +} + +void ue_nr::ue_cfg(const sched_nr_interface::ue_cfg_t& ue_cfg) +{ + // nop +} + +void ue_nr::set_tti(uint32_t tti) +{ + last_tti = tti; +} + +uint32_t ue_nr::read_pdu(uint32_t lcid, uint8_t* payload, uint32_t requested_bytes) +{ + return rlc->read_pdu(rnti, lcid, payload, requested_bytes); +} + +int ue_nr::generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size, srsran::const_span subpdu_lcids) +{ + std::lock_guard lock(mutex); + + if (mac_pdu_dl.init_tx(pdu, grant_size) != SRSRAN_SUCCESS) { + logger.error("Couldn't initialize MAC PDU buffer"); + return SRSRAN_ERROR; + } + + bool drb_activity = false; // inform RRC about user activity if true + + int32_t remaining_len = mac_pdu_dl.get_remaing_len(); + + logger.debug("0x%x Generating MAC PDU (%d B)", rnti, remaining_len); + + // First, add CEs as indicated by scheduler + for (const auto& lcid : subpdu_lcids) { + logger.debug("adding lcid=%d", lcid); + if (lcid == srsran::mac_sch_subpdu_nr::CON_RES_ID) { + if (last_msg3 != nullptr) { + srsran::mac_sch_subpdu_nr::ue_con_res_id_t id; + memcpy(id.data(), last_msg3->msg, id.size()); + if (mac_pdu_dl.add_ue_con_res_id_ce(id) != SRSRAN_SUCCESS) { + logger.error("0x%x Failed to add ConRes CE.", rnti); + } + last_msg3 = nullptr; // don't use this Msg3 again + } else { + logger.warning("0x%x Can't add ConRes CE. No Msg3 stored.", rnti); + } + } else { + // add SDUs for given LCID + while (remaining_len >= MIN_RLC_PDU_LEN) { + // clear read buffer + ue_rlc_buffer->clear(); + + // Determine space for RLC + remaining_len -= remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2; + + // read RLC PDU + int pdu_len = rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, remaining_len); + + if (pdu_len > remaining_len) { + logger.error("Can't add SDU of %d B. Available space %d B", pdu_len, remaining_len); + break; + } else { + // Add SDU if RLC has something to tx + if (pdu_len > 0) { + ue_rlc_buffer->N_bytes = pdu_len; + logger.debug(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC", ue_rlc_buffer->N_bytes); + + // add to MAC PDU and pack + if (mac_pdu_dl.add_sdu(lcid, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes) != SRSRAN_SUCCESS) { + logger.error("Error packing MAC PDU"); + break; + } + + // set DRB activity flag but only notify RRC once + if (lcid > 3) { + drb_activity = true; + } + } else { + break; + } + + remaining_len -= pdu_len; + logger.debug("%d B remaining PDU", remaining_len); + } + } + } + } + + mac_pdu_dl.pack(); + + if (drb_activity) { + // Indicate DRB activity in DL to RRC + rrc->set_activity_user(rnti); + logger.debug("DL activity rnti=0x%x", rnti); + } + + if (logger.info.enabled()) { + fmt::memory_buffer str_buffer; + mac_pdu_dl.to_string(str_buffer); + logger.info("0x%x %s", rnti, srsran::to_c_str(str_buffer)); + } + return SRSRAN_SUCCESS; +} + +/******* METRICS interface ***************/ +void ue_nr::metrics_read(mac_ue_metrics_t* metrics_) +{ + uint32_t ul_buffer = 0; // sched->get_ul_buffer(rnti); + uint32_t dl_buffer = 0; // sched->get_dl_buffer(rnti); + + std::lock_guard lock(metrics_mutex); + ue_metrics.rnti = rnti; + ue_metrics.ul_buffer = ul_buffer; + ue_metrics.dl_buffer = dl_buffer; + + // set PCell sector id + // TODO: use ue_cfg when multiple NR carriers are supported + ue_metrics.cc_idx = 0; + + *metrics_ = ue_metrics; + phr_counter = 0; + dl_cqi_valid_counter = 0; + pucch_sinr_counter = 0; + pusch_sinr_counter = 0; + ue_metrics = {}; +} + +void ue_nr::metrics_dl_cqi(const srsran_uci_cfg_nr_t& cfg_, uint32_t dl_cqi) +{ + std::lock_guard lock(metrics_mutex); + + // Process CQI + for (uint32_t i = 0; i < cfg_.nof_csi; i++) { + // Skip if invalid or not supported CSI report + if (cfg_.csi[i].cfg.quantity != SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI or + cfg_.csi[i].cfg.freq_cfg != SRSRAN_CSI_REPORT_FREQ_WIDEBAND) { + continue; + } + + // Add statistics + ue_metrics.dl_cqi = SRSRAN_VEC_SAFE_CMA(dl_cqi, ue_metrics.dl_cqi, dl_cqi_valid_counter); + dl_cqi_valid_counter++; + } +} + +void ue_nr::metrics_rx(bool crc, uint32_t tbs) +{ + std::lock_guard lock(metrics_mutex); + if (crc) { + ue_metrics.rx_brate += tbs * 8; + } else { + ue_metrics.rx_errors++; + } + ue_metrics.rx_pkts++; +} + +void ue_nr::metrics_tx(bool crc, uint32_t tbs) +{ + std::lock_guard lock(metrics_mutex); + if (crc) { + ue_metrics.tx_brate += tbs * 8; + } else { + ue_metrics.tx_errors++; + } + ue_metrics.tx_pkts++; +} + +void ue_nr::metrics_dl_mcs(uint32_t mcs) +{ + std::lock_guard lock(metrics_mutex); + ue_metrics.dl_mcs = SRSRAN_VEC_CMA((float)mcs, ue_metrics.dl_mcs, ue_metrics.dl_mcs_samples); + ue_metrics.dl_mcs_samples++; +} + +void ue_nr::metrics_ul_mcs(uint32_t mcs) +{ + std::lock_guard lock(metrics_mutex); + ue_metrics.ul_mcs = SRSRAN_VEC_CMA((float)mcs, ue_metrics.ul_mcs, ue_metrics.ul_mcs_samples); + ue_metrics.ul_mcs_samples++; +} + +void ue_nr::metrics_cnt() +{ + std::lock_guard lock(metrics_mutex); + ue_metrics.nof_tti++; +} + +void ue_nr::metrics_pucch_sinr(float sinr) +{ + std::lock_guard lock(metrics_mutex); + // discard nan or inf values for average SINR + if (!std::isinf(sinr) && !std::isnan(sinr)) { + ue_metrics.pucch_sinr = SRSRAN_VEC_SAFE_CMA((float)sinr, ue_metrics.pucch_sinr, pucch_sinr_counter); + pucch_sinr_counter++; + } +} + +void ue_nr::metrics_pusch_sinr(float sinr) +{ + std::lock_guard lock(metrics_mutex); + // discard nan or inf values for average SINR + if (!std::isinf(sinr) && !std::isnan(sinr)) { + ue_metrics.pusch_sinr = SRSRAN_VEC_SAFE_CMA((float)sinr, ue_metrics.pusch_sinr, pusch_sinr_counter); + pusch_sinr_counter++; + } +} + +// Called from Stack thread when demuxing UL PDUs +void ue_nr::store_msg3(srsran::unique_byte_buffer_t pdu) +{ + std::lock_guard lock(mutex); + last_msg3 = std::move(pdu); +} + +} // namespace srsenb diff --git a/srsenb/src/stack/ngap/CMakeLists.txt b/srsgnb/src/stack/ngap/CMakeLists.txt similarity index 91% rename from srsenb/src/stack/ngap/CMakeLists.txt rename to srsgnb/src/stack/ngap/CMakeLists.txt index e50cca2b15..d305ebcca9 100644 --- a/srsenb/src/stack/ngap/CMakeLists.txt +++ b/srsgnb/src/stack/ngap/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -20,3 +20,6 @@ set(SOURCES ngap.cc ngap_ue.cc ngap_ue_proc.cc ngap_ue_bearer_manager.cc) add_library(srsgnb_ngap STATIC ${SOURCES}) + +add_subdirectory(test) + diff --git a/srsenb/src/stack/ngap/ngap.cc b/srsgnb/src/stack/ngap/ngap.cc similarity index 70% rename from srsenb/src/stack/ngap/ngap.cc rename to srsgnb/src/stack/ngap/ngap.cc index a22d0ba63b..0a6f02f578 100644 --- a/srsenb/src/stack/ngap/ngap.cc +++ b/srsgnb/src/stack/ngap/ngap.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,8 +19,8 @@ * */ -#include "srsenb/hdr/stack/ngap/ngap.h" -#include "srsenb/hdr/stack/ngap/ngap_ue.h" +#include "srsgnb/hdr/stack/ngap/ngap.h" +#include "srsgnb/hdr/stack/ngap/ngap_ue.h" #include "srsran/common/int_helpers.h" using srsran::s1ap_mccmnc_to_plmn; @@ -37,7 +37,7 @@ using srsran::uint32_to_uint8; } \ } while (0) -using namespace asn1::ngap_nr; +using namespace asn1::ngap; namespace srsenb { /********************************************************* @@ -220,10 +220,10 @@ int ngap::build_tai_cgi() /******************************************************************************* /* RRC interface ********************************************************************************/ -void ngap::initial_ue(uint16_t rnti, - uint32_t gnb_cc_idx, - asn1::ngap_nr::rrcestablishment_cause_e cause, - srsran::unique_byte_buffer_t pdu) +void ngap::initial_ue(uint16_t rnti, + uint32_t gnb_cc_idx, + asn1::ngap::rrcestablishment_cause_e cause, + srsran::const_byte_span pdu) { std::unique_ptr ue_ptr{new ue{this, rrc, gtpu, logger}}; ue_ptr->ctxt.rnti = rnti; @@ -233,14 +233,14 @@ void ngap::initial_ue(uint16_t rnti, logger.error("Failed to add rnti=0x%x", rnti); return; } - u->send_initial_ue_message(cause, std::move(pdu), false); + u->send_initial_ue_message(cause, pdu, false); } -void ngap::initial_ue(uint16_t rnti, - uint32_t gnb_cc_idx, - asn1::ngap_nr::rrcestablishment_cause_e cause, - srsran::unique_byte_buffer_t pdu, - uint32_t s_tmsi) +void ngap::initial_ue(uint16_t rnti, + uint32_t gnb_cc_idx, + asn1::ngap::rrcestablishment_cause_e cause, + srsran::const_byte_span pdu, + uint32_t s_tmsi) { std::unique_ptr ue_ptr{new ue{this, rrc, gtpu, logger}}; ue_ptr->ctxt.rnti = rnti; @@ -250,7 +250,7 @@ void ngap::initial_ue(uint16_t rnti, logger.error("Failed to add rnti=0x%x", rnti); return; } - u->send_initial_ue_message(cause, std::move(pdu), true, s_tmsi); + u->send_initial_ue_message(cause, pdu, true, s_tmsi); } void ngap::ue_notify_rrc_reconf_complete(uint16_t rnti, bool outcome) @@ -262,16 +262,33 @@ void ngap::ue_notify_rrc_reconf_complete(uint16_t rnti, bool outcome) u->notify_rrc_reconf_complete(outcome); } -void ngap::write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) +void ngap::write_pdu(uint16_t rnti, srsran::const_byte_span pdu) { - logger.info(pdu->msg, pdu->N_bytes, "Received RRC SDU"); + logger.info(pdu.data(), pdu.size(), "Received RRC SDU"); ue* u = users.find_ue_rnti(rnti); if (u == nullptr) { logger.info("The rnti=0x%x does not exist", rnti); return; } - u->send_ul_nas_transport(std::move(pdu)); + u->send_ul_nas_transport(pdu); +} + +void ngap::user_release_request(uint16_t rnti, asn1::ngap::cause_radio_network_e cause_radio) +{ + ue* u = users.find_ue_rnti(rnti); + if (u == nullptr) { + logger.warning("Released UE rnti=0x%x not found.", rnti); + return; + } + + cause_c cause; + cause.set_radio_network().value = cause_radio; + if (not u->send_ue_context_release_request(cause)) { + logger.error("Failed to initiate RRC Release for rnti=0x%x. Removing user", rnti); + rrc->release_user(rnti); + users.erase(u); + } } /********************************************************* @@ -294,7 +311,7 @@ ngap::ue* ngap::user_list::find_ue_gnbid(uint32_t gnbid) return (it != users.end()) ? it->second.get() : nullptr; } -ngap::ue* ngap::user_list::find_ue_amfid(uint32_t amfid) +ngap::ue* ngap::user_list::find_ue_amfid(uint64_t amfid) { auto it = std::find_if(users.begin(), users.end(), [amfid](const user_list::pair_type& v) { return v.second->ctxt.amf_ue_ngap_id == amfid; @@ -380,12 +397,12 @@ bool ngap::handle_amf_rx_msg(srsran::unique_byte_buffer_t pdu, bool ngap::handle_ngap_rx_pdu(srsran::byte_buffer_t* pdu) { - // TODO: // Save message to PCAP - // if (pcap != nullptr) { - // pcap->write_ngap(pdu->msg, pdu->N_bytes); - // } + if (pcap != nullptr) { + pcap->write_ngap(pdu->msg, pdu->N_bytes); + } + // Unpack ngap_pdu_c rx_pdu; asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); @@ -397,6 +414,10 @@ bool ngap::handle_ngap_rx_pdu(srsran::byte_buffer_t* pdu) return false; } + // Logging + log_ngap_message(rx_pdu, Rx, srsran::make_span(*pdu)); + + // Handle the NGAP message switch (rx_pdu.type().value) { case ngap_pdu_c::types_opts::init_msg: return handle_initiating_message(rx_pdu.init_msg()); @@ -405,14 +426,14 @@ bool ngap::handle_ngap_rx_pdu(srsran::byte_buffer_t* pdu) case ngap_pdu_c::types_opts::unsuccessful_outcome: return handle_unsuccessful_outcome(rx_pdu.unsuccessful_outcome()); default: - logger.error("Unhandled PDU type %d", rx_pdu.type().value); + logger.warning("Unhandled PDU type %d", rx_pdu.type().value); return false; } return true; } -bool ngap::handle_initiating_message(const asn1::ngap_nr::init_msg_s& msg) +bool ngap::handle_initiating_message(const asn1::ngap::init_msg_s& msg) { switch (msg.value.type().value) { case ngap_elem_procs_o::init_msg_c::types_opts::dl_nas_transport: @@ -420,11 +441,13 @@ bool ngap::handle_initiating_message(const asn1::ngap_nr::init_msg_s& msg) case ngap_elem_procs_o::init_msg_c::types_opts::init_context_setup_request: return handle_initial_ctxt_setup_request(msg.value.init_context_setup_request()); case ngap_elem_procs_o::init_msg_c::types_opts::ue_context_release_cmd: - return handle_ue_ctxt_release_cmd(msg.value.ue_context_release_cmd()); + return handle_ue_context_release_cmd(msg.value.ue_context_release_cmd()); case ngap_elem_procs_o::init_msg_c::types_opts::pdu_session_res_setup_request: return handle_ue_pdu_session_res_setup_request(msg.value.pdu_session_res_setup_request()); + case ngap_elem_procs_o::init_msg_c::types_opts::paging: + return handle_paging(msg.value.paging()); default: - logger.error("Unhandled initiating message: %s", msg.value.type().to_string()); + logger.warning("Unhandled initiating message: %s", msg.value.type().to_string()); } return true; } @@ -440,7 +463,7 @@ bool ngap::handle_successful_outcome(const successful_outcome_s& msg) return true; } -bool ngap::handle_unsuccessful_outcome(const asn1::ngap_nr::unsuccessful_outcome_s& msg) +bool ngap::handle_unsuccessful_outcome(const asn1::ngap::unsuccessful_outcome_s& msg) { switch (msg.value.type().value) { case ngap_elem_procs_o::unsuccessful_outcome_c::types_opts::ng_setup_fail: @@ -451,62 +474,76 @@ bool ngap::handle_unsuccessful_outcome(const asn1::ngap_nr::unsuccessful_outcome return true; } -bool ngap::handle_ng_setup_response(const asn1::ngap_nr::ng_setup_resp_s& msg) +bool ngap::handle_ng_setup_response(const asn1::ngap::ng_setup_resp_s& msg) { ngsetupresponse = msg; amf_connected = true; ng_setup_proc_t::ngsetupresult res; res.success = true; - logger.info("AMF name: %s", ngsetupresponse.protocol_ies.amf_name.value.to_string()); + for (size_t i = 0; i < ngsetupresponse->plmn_support_list->size(); i++) { + plmn_support_item_s& plmn_support_item = ngsetupresponse->plmn_support_list.value[i]; + for (size_t j = 0; j < plmn_support_item.slice_support_list.size(); j++) { + slice_support_item_s slice_item = plmn_support_item.slice_support_list[j]; + for (int k = 0; k < SRSRAN_NUM_SLICE; k++) { + if (args.nssai[k].active) { + if (args.nssai[k].sst == slice_item.s_nssai.sst.to_number()) { + if (args.nssai[k].sd == slice_item.s_nssai.sd.to_number()) { + nssai_allowed_list.push_back(args.nssai[k]); + } + } + } + } + } + } + logger.info("AMF name: %s", ngsetupresponse->amf_name.value.to_string()); ngsetup_proc.trigger(res); return true; } -bool ngap::handle_ng_setup_failure(const asn1::ngap_nr::ng_setup_fail_s& msg) +bool ngap::handle_ng_setup_failure(const asn1::ngap::ng_setup_fail_s& msg) { - std::string cause = get_cause(msg.protocol_ies.cause.value); + std::string cause = get_cause(msg->cause.value); logger.error("NG Setup Failure. Cause: %s", cause.c_str()); srsran::console("NG Setup Failure. Cause: %s\n", cause.c_str()); return true; } -bool ngap::handle_dl_nas_transport(const asn1::ngap_nr::dl_nas_transport_s& msg) +bool ngap::handle_dl_nas_transport(const asn1::ngap::dl_nas_transport_s& msg) { if (msg.ext) { logger.warning("Not handling NGAP message extension"); } - ue* u = - handle_ngapmsg_ue_id(msg.protocol_ies.ran_ue_ngap_id.value.value, msg.protocol_ies.amf_ue_ngap_id.value.value); + ue* u = handle_ngapmsg_ue_id(msg->ran_ue_ngap_id.value.value, msg->amf_ue_ngap_id.value.value); if (u == nullptr) { logger.warning("Couldn't find user with ran_ue_ngap_id %d and %d", - msg.protocol_ies.ran_ue_ngap_id.value.value, - msg.protocol_ies.amf_ue_ngap_id.value.value); + msg->ran_ue_ngap_id.value.value, + msg->amf_ue_ngap_id.value.value); return false; } - if (msg.protocol_ies.old_amf_present) { + if (msg->old_amf_present) { logger.warning("Not handling OldAMF"); } - if (msg.protocol_ies.ran_paging_prio_present) { + if (msg->ran_paging_prio_present) { logger.warning("Not handling RANPagingPriority"); } - if (msg.protocol_ies.mob_restrict_list_present) { + if (msg->mob_restrict_list_present) { logger.warning("Not handling MobilityRestrictionList"); } - if (msg.protocol_ies.idx_to_rfsp_present) { + if (msg->idx_to_rfsp_present) { logger.warning("Not handling IndexToRFSP"); } - if (msg.protocol_ies.ue_aggregate_maximum_bit_rate_present) { + if (msg->ue_aggregate_maximum_bit_rate_present) { logger.warning("Not handling UEAggregateMaximumBitRate"); } - if (msg.protocol_ies.allowed_nssai_present) { + if (msg->allowed_nssai_present) { logger.warning("Not handling AllowedNSSAI"); } @@ -515,16 +552,15 @@ bool ngap::handle_dl_nas_transport(const asn1::ngap_nr::dl_nas_transport_s& msg) logger.error("Fatal Error: Couldn't allocate buffer in ngap::run_thread()."); return false; } - memcpy(pdu->msg, msg.protocol_ies.nas_pdu.value.data(), msg.protocol_ies.nas_pdu.value.size()); - pdu->N_bytes = msg.protocol_ies.nas_pdu.value.size(); + memcpy(pdu->msg, msg->nas_pdu.value.data(), msg->nas_pdu.value.size()); + pdu->N_bytes = msg->nas_pdu.value.size(); rrc->write_dl_info(u->ctxt.rnti, std::move(pdu)); return true; } -bool ngap::handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg) +bool ngap::handle_initial_ctxt_setup_request(const asn1::ngap::init_context_setup_request_s& msg) { - ue* u = - handle_ngapmsg_ue_id(msg.protocol_ies.ran_ue_ngap_id.value.value, msg.protocol_ies.amf_ue_ngap_id.value.value); + ue* u = handle_ngapmsg_ue_id(msg->ran_ue_ngap_id.value.value, msg->amf_ue_ngap_id.value.value); if (u == nullptr) { logger.warning("Can not find UE"); return false; @@ -535,9 +571,9 @@ bool ngap::handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_s return true; } -bool ngap::handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cmd_s& msg) +bool ngap::handle_ue_context_release_cmd(const asn1::ngap::ue_context_release_cmd_s& msg) { - const asn1::ngap_nr::ue_ngap_id_pair_s& ue_ngap_id_pair = msg.protocol_ies.ue_ngap_ids.value.ue_ngap_id_pair(); + const asn1::ngap::ue_ngap_id_pair_s& ue_ngap_id_pair = msg->ue_ngap_ids.value.ue_ngap_id_pair(); ue* u = handle_ngapmsg_ue_id(ue_ngap_id_pair.ran_ue_ngap_id, ue_ngap_id_pair.amf_ue_ngap_id); if (u == nullptr) { @@ -545,35 +581,46 @@ bool ngap::handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cm return false; } - u->handle_ue_ctxt_release_cmd(msg); - - return true; + return u->handle_ue_context_release_cmd(msg); } -bool ngap::handle_ue_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg) +bool ngap::handle_ue_pdu_session_res_setup_request(const asn1::ngap::pdu_session_res_setup_request_s& msg) { - ue* u = - handle_ngapmsg_ue_id(msg.protocol_ies.ran_ue_ngap_id.value.value, msg.protocol_ies.amf_ue_ngap_id.value.value); + ue* u = handle_ngapmsg_ue_id(msg->ran_ue_ngap_id.value.value, msg->amf_ue_ngap_id.value.value); if (u == nullptr) { logger.warning("Can not find UE"); return false; } - if (msg.protocol_ies.ue_aggregate_maximum_bit_rate_present) { - rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg.protocol_ies.ue_aggregate_maximum_bit_rate.value); + if (msg->ue_aggregate_maximum_bit_rate_present) { + rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg->ue_aggregate_maximum_bit_rate.value); } u->handle_pdu_session_res_setup_request(msg); return true; } +bool ngap::handle_paging(const asn1::ngap::paging_s& msg) +{ + logger.info("Paging is not supported yet."); + + // TODO: Handle Paging after RRC Paging is implemented + + // uint32_t ue_paging_id = msg->ue_paging_id.id; + // Note: IMSI Paging is not supported in NR + // uint64_t tmsi = msg->ue_paging_id.value.five_g_s_tmsi().five_g_tmsi.to_number(); + // rrc->add_paging(ue_paging_id, tmsi); + + return true; +} + /******************************************************************************* /* NGAP message senders ********************************************************************************/ -bool ngap::send_error_indication(const asn1::ngap_nr::cause_c& cause, - srsran::optional ran_ue_ngap_id, - srsran::optional amf_ue_ngap_id) +bool ngap::send_error_indication(const asn1::ngap::cause_c& cause, + srsran::optional ran_ue_ngap_id, + srsran::optional amf_ue_ngap_id) { if (amf_connected == false) { logger.warning("AMF not connected."); @@ -581,23 +628,23 @@ bool ngap::send_error_indication(const asn1::ngap_nr::cause_c& cause, } ngap_pdu_c tx_pdu; - tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_ERROR_IND); - auto& container = tx_pdu.init_msg().value.error_ind().protocol_ies; + tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_ID_ERROR_IND); + auto& container = tx_pdu.init_msg().value.error_ind(); - uint16_t rnti = SRSRAN_INVALID_RNTI; - container.ran_ue_ngap_id_present = ran_ue_ngap_id.has_value(); + uint16_t rnti = SRSRAN_INVALID_RNTI; + container->ran_ue_ngap_id_present = ran_ue_ngap_id.has_value(); if (ran_ue_ngap_id.has_value()) { - container.ran_ue_ngap_id.value = ran_ue_ngap_id.value(); - ue* user_ptr = users.find_ue_gnbid(ran_ue_ngap_id.value()); - rnti = user_ptr != nullptr ? user_ptr->ctxt.rnti : SRSRAN_INVALID_RNTI; + container->ran_ue_ngap_id.value = ran_ue_ngap_id.value(); + ue* user_ptr = users.find_ue_gnbid(ran_ue_ngap_id.value()); + rnti = user_ptr != nullptr ? user_ptr->ctxt.rnti : SRSRAN_INVALID_RNTI; } - container.amf_ue_ngap_id_present = amf_ue_ngap_id.has_value(); + container->amf_ue_ngap_id_present = amf_ue_ngap_id.has_value(); if (amf_ue_ngap_id.has_value()) { - container.amf_ue_ngap_id.value = amf_ue_ngap_id.value(); + container->amf_ue_ngap_id.value = amf_ue_ngap_id.value(); } - container.cause_present = true; - container.cause.value = cause; + container->cause_present = true; + container->cause.value = cause; return sctp_send_ngap_pdu(tx_pdu, rnti, "Error Indication"); } @@ -610,12 +657,34 @@ bool ngap::connect_amf() using namespace srsran::net_utils; logger.info("Connecting to AMF %s:%d", args.amf_addr.c_str(), int(AMF_PORT)); - // Init SCTP socket and bind it - if (not sctp_init_socket(&amf_socket, socket_type::seqpacket, args.ngc_bind_addr.c_str(), 0)) { + // Open SCTP socket + if (not amf_socket.open_socket( + srsran::net_utils::addr_family::ipv4, socket_type::seqpacket, srsran::net_utils::protocol_type::SCTP)) { return false; } logger.info("SCTP socket opened. fd=%d", amf_socket.fd()); + if (not amf_socket.sctp_subscribe_to_events()) { + amf_socket.close(); + return false; + } + + if (not amf_socket.sctp_set_rto_opts(5000)) { + amf_socket.close(); + return false; + } + + if (not amf_socket.sctp_set_init_msg_opts(3, 6000)) { + amf_socket.close(); + return false; + } + + // Bind socket + if (not amf_socket.bind_addr(args.ngc_bind_addr.c_str(), 0)) { + amf_socket.close(); + return false; + } + // Connect to the AMF address if (not amf_socket.connect_to(args.amf_addr.c_str(), AMF_PORT, &amf_addr)) { return false; @@ -645,39 +714,37 @@ bool ngap::setup_ng() plmn = htonl(plmn); ngap_pdu_c pdu; - pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_NG_SETUP); - ng_setup_request_ies_container& container = pdu.init_msg().value.ng_setup_request().protocol_ies; - global_gnb_id_s& global_gnb_id = container.global_ran_node_id.value.set_global_gnb_id(); - global_gnb_id.plmn_id = tai.plmn_id; - // TODO: when ASN1 is fixed - // global_gnb_id.gnb_id.set_gnb_id().from_number(args.gnb_id); - - // container.ran_node_name_present = true; - // container.ran_node_name.value.from_string(args.gnb_name); - - asn1::bounded_bitstring<22, 32, false, true>& gnb_str = global_gnb_id.gnb_id.set_gnb_id(); - gnb_str.resize(32); - uint8_t buffer[4]; - asn1::bit_ref bref(&buffer[0], sizeof(buffer)); - bref.pack(args.gnb_id, 8); - memcpy(gnb_str.data(), &buffer[0], bref.distance_bytes()); - - container.ran_node_name_present = true; + pdu.set_init_msg().load_info_obj(ASN1_NGAP_ID_NG_SETUP); + ng_setup_request_s& container = pdu.init_msg().value.ng_setup_request(); + global_gnb_id_s& global_gnb_id = container->global_ran_node_id.value.set_global_gnb_id(); + global_gnb_id.plmn_id = tai.plmn_id; + + global_gnb_id.gnb_id.set_gnb_id().from_number(args.gnb_id); + + container->ran_node_name_present = true; if (args.gnb_name.length() >= 150) { args.gnb_name.resize(150); } - container.ran_node_name.value.resize(args.gnb_name.size()); - memcpy(&container.ran_node_name.value[0], &args.gnb_name[0], args.gnb_name.size()); - - container.supported_ta_list.value.resize(1); - container.supported_ta_list.value[0].tac = tai.tac; - container.supported_ta_list.value[0].broadcast_plmn_list.resize(1); - container.supported_ta_list.value[0].broadcast_plmn_list[0].plmn_id = tai.plmn_id; - container.supported_ta_list.value[0].broadcast_plmn_list[0].tai_slice_support_list.resize(1); - container.supported_ta_list.value[0].broadcast_plmn_list[0].tai_slice_support_list[0].s_nssai.sst.from_number(1); - - container.default_paging_drx.value.value = asn1::ngap_nr::paging_drx_opts::v256; // Todo: add to args, config file + container->ran_node_name.value.resize(args.gnb_name.size()); + memcpy(&container->ran_node_name.value[0], &args.gnb_name[0], args.gnb_name.size()); + + container->supported_ta_list.value.resize(1); + container->supported_ta_list.value[0].tac = tai.tac; + container->supported_ta_list.value[0].broadcast_plmn_list.resize(1); + container->supported_ta_list.value[0].broadcast_plmn_list[0].plmn_id = tai.plmn_id; + for (const auto& slice : args.nssai) { + if (slice.active) { + slice_support_item_s slice_item; + slice_item.s_nssai.sst.from_number(slice.sst); + if (slice.sd != 0) { + slice_item.s_nssai.sd_present = true; + slice_item.s_nssai.sd.from_number(slice.sd); + } + container->supported_ta_list.value[0].broadcast_plmn_list[0].tai_slice_support_list.push_back(slice_item); + } + } + container->default_paging_drx.value.value = asn1::ngap::paging_drx_opts::v256; // Todo: add to args, config file return sctp_send_ngap_pdu(pdu, 0, "ngSetupRequest"); } @@ -686,7 +753,7 @@ bool ngap::setup_ng() /* General helpers ********************************************************************************/ -bool ngap::sctp_send_ngap_pdu(const asn1::ngap_nr::ngap_pdu_c& tx_pdu, uint32_t rnti, const char* procedure_name) +bool ngap::sctp_send_ngap_pdu(const asn1::ngap::ngap_pdu_c& tx_pdu, uint32_t rnti, const char* procedure_name) { if (not amf_connected and rnti != SRSRAN_INVALID_RNTI) { logger.error("Aborting %s for rnti=0x%x. Cause: AMF is not connected.", procedure_name, rnti); @@ -705,6 +772,11 @@ bool ngap::sctp_send_ngap_pdu(const asn1::ngap_nr::ngap_pdu_c& tx_pdu, uint32_t } buf->N_bytes = bref.distance_bytes(); + // Save message to PCAP + if (pcap != nullptr) { + pcap->write_ngap(buf->msg, buf->N_bytes); + } + if (rnti != SRSRAN_INVALID_RNTI) { logger.info(buf->msg, buf->N_bytes, "Tx NGAP SDU, %s, rnti=0x%x", procedure_name, rnti); } else { @@ -740,7 +812,7 @@ bool ngap::sctp_send_ngap_pdu(const asn1::ngap_nr::ngap_pdu_c& tx_pdu, uint32_t * @param amf_id amf_ue_ngap_id value stored in NGAP message * @return pointer to user if it has been found */ -ngap::ue* ngap::handle_ngapmsg_ue_id(uint32_t gnb_id, uint32_t amf_id) +ngap::ue* ngap::handle_ngapmsg_ue_id(uint32_t gnb_id, uint64_t amf_id) { ue* user_ptr = users.find_ue_gnbid(gnb_id); ue* user_amf_ptr = nullptr; @@ -803,4 +875,37 @@ std::string ngap::get_cause(const cause_c& c) return cause; } +/* + * PCAP + */ +void ngap::start_pcap(srsran::ngap_pcap* pcap_) +{ + pcap = pcap_; +} + +void ngap::log_ngap_message(const ngap_pdu_c& msg, const direction_t dir, srsran::const_byte_span pdu) +{ + std::string msg_type = {}; + switch (msg.type().value) { + case ngap_pdu_c::types_opts::init_msg: + msg_type = msg.init_msg().value.type().to_string(); + break; + case ngap_pdu_c::types_opts::successful_outcome: + msg_type = msg.successful_outcome().value.type().to_string(); + break; + case ngap_pdu_c::types_opts::unsuccessful_outcome: + msg_type = msg.unsuccessful_outcome().value.type().to_string(); + break; + default: + return; + } + if (logger.debug.enabled()) { + asn1::json_writer json_writer; + msg.to_json(json_writer); + logger.debug(pdu.data(), pdu.size(), "%s - %s (%d B)", (dir == Rx) ? "Rx" : "Tx", msg_type, pdu.size()); + logger.debug("Content:%s", json_writer.to_string().c_str()); + } else if (logger.info.enabled()) { + logger.info(pdu.data(), pdu.size(), "%s - %s (%d B)", (dir == Rx) ? "Rx" : "Tx", msg_type, pdu.size()); + } +} } // namespace srsenb diff --git a/srsenb/src/stack/ngap/ngap_ue.cc b/srsgnb/src/stack/ngap/ngap_ue.cc similarity index 52% rename from srsenb/src/stack/ngap/ngap_ue.cc rename to srsgnb/src/stack/ngap/ngap_ue.cc index 0a507ea3db..d956607e17 100644 --- a/srsenb/src/stack/ngap/ngap_ue.cc +++ b/srsgnb/src/stack/ngap/ngap_ue.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,12 +19,12 @@ * */ -#include "srsenb/hdr/stack/ngap/ngap_ue.h" -#include "srsenb/hdr/stack/ngap/ngap.h" -#include "srsenb/hdr/stack/ngap/ngap_ue_proc.h" +#include "srsgnb/hdr/stack/ngap/ngap_ue.h" +#include "srsgnb/hdr/stack/ngap/ngap.h" +#include "srsgnb/hdr/stack/ngap/ngap_ue_proc.h" #include "srsran/common/int_helpers.h" -using namespace asn1::ngap_nr; +using namespace asn1::ngap; namespace srsenb { @@ -54,10 +54,10 @@ ngap::ue::~ue() {} /* NGAP message senders ********************************************************************************/ -bool ngap::ue::send_initial_ue_message(asn1::ngap_nr::rrcestablishment_cause_e cause, - srsran::unique_byte_buffer_t pdu, - bool has_tmsi, - uint32_t s_tmsi) +bool ngap::ue::send_initial_ue_message(asn1::ngap::rrcestablishment_cause_e cause, + srsran::const_byte_span pdu, + bool has_tmsi, + uint32_t s_tmsi) { if (not ngap_ptr->amf_connected) { logger.warning("AMF not connected"); @@ -65,44 +65,44 @@ bool ngap::ue::send_initial_ue_message(asn1::ngap_nr::rrcestablishment_cause_e c } ngap_pdu_c tx_pdu; - tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_INIT_UE_MSG); - init_ue_msg_ies_container& container = tx_pdu.init_msg().value.init_ue_msg().protocol_ies; + tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_ID_INIT_UE_MSG); + init_ue_msg_s& container = tx_pdu.init_msg().value.init_ue_msg(); // 5G-S-TMSI if (has_tmsi) { - container.five_g_s_tmsi_present = true; - srsran::uint32_to_uint8(s_tmsi, container.five_g_s_tmsi.value.five_g_tmsi.data()); - container.five_g_s_tmsi.value.amf_set_id.from_number(ctxt.amf_set_id); - container.five_g_s_tmsi.value.amf_pointer.from_number(ctxt.amf_pointer); + container->five_g_s_tmsi_present = true; + srsran::uint32_to_uint8(s_tmsi, container->five_g_s_tmsi.value.five_g_tmsi.data()); + container->five_g_s_tmsi.value.amf_set_id.from_number(ctxt.amf_set_id); + container->five_g_s_tmsi.value.amf_pointer.from_number(ctxt.amf_pointer); } // RAN_UE_NGAP_ID - container.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + container->ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; // NAS_PDU - container.nas_pdu.value.resize(pdu->N_bytes); - memcpy(container.nas_pdu.value.data(), pdu->msg, pdu->N_bytes); + container->nas_pdu.value.resize(pdu.size()); + memcpy(container->nas_pdu.value.data(), pdu.data(), pdu.size()); // RRC Establishment Cause - container.rrcestablishment_cause.value = cause; + container->rrcestablishment_cause.value = cause; // User Location Info // userLocationInformationNR - container.user_location_info.value.set_user_location_info_nr(); - container.user_location_info.value.user_location_info_nr().nr_cgi.nrcell_id = ngap_ptr->nr_cgi.nrcell_id; - container.user_location_info.value.user_location_info_nr().nr_cgi.plmn_id = ngap_ptr->nr_cgi.plmn_id; - container.user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; - container.user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; + container->user_location_info.value.set_user_location_info_nr(); + container->user_location_info.value.user_location_info_nr().nr_cgi.nrcell_id = ngap_ptr->nr_cgi.nrcell_id; + container->user_location_info.value.user_location_info_nr().nr_cgi.plmn_id = ngap_ptr->nr_cgi.plmn_id; + container->user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; + container->user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; // UE context request for setup in the NAS registration request - container.ue_context_request_present = true; - container.ue_context_request.value = asn1::ngap_nr::ue_context_request_opts::options::requested; + container->ue_context_request_present = true; + container->ue_context_request.value = asn1::ngap::ue_context_request_opts::options::requested; return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "InitialUEMessage"); } -bool ngap::ue::send_ul_nas_transport(srsran::unique_byte_buffer_t pdu) +bool ngap::ue::send_ul_nas_transport(srsran::const_byte_span pdu) { if (not ngap_ptr->amf_connected) { logger.warning("AMF not connected"); @@ -110,31 +110,31 @@ bool ngap::ue::send_ul_nas_transport(srsran::unique_byte_buffer_t pdu) } ngap_pdu_c tx_pdu; - tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_UL_NAS_TRANSPORT); - asn1::ngap_nr::ul_nas_transport_ies_container& container = tx_pdu.init_msg().value.ul_nas_transport().protocol_ies; + tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_ID_UL_NAS_TRANSPORT); + ul_nas_transport_s& container = tx_pdu.init_msg().value.ul_nas_transport(); // AMF UE NGAP ID if (ctxt.amf_ue_ngap_id.has_value()) { - container.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); + container->amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); } else { logger.error("Attempting to send UL NAS Transport without AMF context"); return false; } // RAN UE NGAP ID - container.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + container->ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; // NAS PDU - container.nas_pdu.value.resize(pdu->N_bytes); - memcpy(container.nas_pdu.value.data(), pdu->msg, pdu->N_bytes); + container->nas_pdu.value.resize(pdu.size()); + memcpy(container->nas_pdu.value.data(), pdu.data(), pdu.size()); // User Location Info // userLocationInformationNR - container.user_location_info.value.set_user_location_info_nr(); - container.user_location_info.value.user_location_info_nr().nr_cgi.nrcell_id = ngap_ptr->nr_cgi.nrcell_id; - container.user_location_info.value.user_location_info_nr().nr_cgi.plmn_id = ngap_ptr->nr_cgi.plmn_id; - container.user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; - container.user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; + container->user_location_info.value.set_user_location_info_nr(); + container->user_location_info.value.user_location_info_nr().nr_cgi.nrcell_id = ngap_ptr->nr_cgi.nrcell_id; + container->user_location_info.value.user_location_info_nr().nr_cgi.plmn_id = ngap_ptr->nr_cgi.plmn_id; + container->user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; + container->user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "UplinkNASTransport"); } @@ -152,14 +152,14 @@ bool ngap::ue::send_initial_ctxt_setup_response() } ngap_pdu_c tx_pdu; - tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_NR_ID_INIT_CONTEXT_SETUP); + tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_ID_INIT_CONTEXT_SETUP); init_context_setup_resp_s& container = tx_pdu.successful_outcome().value.init_context_setup_resp(); // AMF UE NGAP ID - container.protocol_ies.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); + container->amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); // RAN UE NGAP ID - container.protocol_ies.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + container->ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "InitialContextSetupResponse"); } @@ -172,20 +172,20 @@ bool ngap::ue::send_initial_ctxt_setup_failure(cause_c cause) } ngap_pdu_c tx_pdu; - tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_INIT_CONTEXT_SETUP); + tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_ID_INIT_CONTEXT_SETUP); init_context_setup_fail_s& container = tx_pdu.unsuccessful_outcome().value.init_context_setup_fail(); // AMF UE NGAP ID - container.protocol_ies.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); + container->amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); // RAN UE NGAP ID - container.protocol_ies.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + container->ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; /* // TODO: PDU Session Resource Setup Response List - Integrate PDU Session and Bearer management into NGAP - container.protocol_ies.pdu_session_res_setup_list_cxt_res_present = true; + container->pdu_session_res_setup_list_cxt_res_present = true; // Case PDU Session Resource Failed to Setup List - container.protocol_ies.pdu_session_res_failed_to_setup_list_cxt_res_present = true; */ + container->pdu_session_res_failed_to_setup_list_cxt_res_present = true; */ return true; } @@ -200,11 +200,11 @@ bool ngap::ue::send_pdu_session_resource_setup_response(uint16_t } // TODO: QOS Params ngap_pdu_c tx_pdu; - tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_NR_ID_PDU_SESSION_RES_SETUP); - pdu_session_res_setup_resp_s& container = tx_pdu.successful_outcome().value.pdu_session_res_setup_resp(); - container.protocol_ies.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); - container.protocol_ies.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; - container.protocol_ies.pdu_session_res_setup_list_su_res_present = true; + tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_ID_PDU_SESSION_RES_SETUP); + pdu_session_res_setup_resp_s& container = tx_pdu.successful_outcome().value.pdu_session_res_setup_resp(); + container->amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); + container->ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + container->pdu_session_res_setup_list_su_res_present = true; pdu_session_res_setup_item_su_res_s su_res; su_res.pdu_session_res_setup_resp_transfer.resize(512); su_res.pdu_session_id = pdu_session_id; @@ -214,8 +214,8 @@ bool ngap::ue::send_pdu_session_resource_setup_response(uint16_t gtp_tunnel.gtp_teid.from_number(teid_in); gtp_tunnel.transport_layer_address = addr_in; - asn1::ngap_nr::associated_qos_flow_list_l qos_flow_list; - asn1::ngap_nr::associated_qos_flow_item_s qos_flow_item; + asn1::ngap::associated_qos_flow_list_l qos_flow_list; + asn1::ngap::associated_qos_flow_item_s qos_flow_item; qos_flow_item.qos_flow_id = 1; qos_flow_list.push_back(qos_flow_item); resp_transfer.dlqos_flow_per_tnl_info.associated_qos_flow_list = qos_flow_list; @@ -225,7 +225,7 @@ bool ngap::ue::send_pdu_session_resource_setup_response(uint16_t resp_transfer.pack(bref); su_res.pdu_session_res_setup_resp_transfer.resize(bref.distance_bytes()); - container.protocol_ies.pdu_session_res_setup_list_su_res.value.push_back(su_res); + container->pdu_session_res_setup_list_su_res.value.push_back(su_res); return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "PDUSessionResourceSetupResponse"); } @@ -237,27 +237,69 @@ bool ngap::ue::send_ue_ctxt_release_complete() } ngap_pdu_c tx_pdu; - tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_NR_ID_UE_CONTEXT_RELEASE); + tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_ID_UE_CONTEXT_RELEASE); ue_context_release_complete_s& container = tx_pdu.successful_outcome().value.ue_context_release_complete(); // userLocationInformationNR - container.protocol_ies.user_location_info.value.set_user_location_info_nr(); - container.protocol_ies.user_location_info.value.user_location_info_nr().nr_cgi.nrcell_id = ngap_ptr->nr_cgi.nrcell_id; - container.protocol_ies.user_location_info.value.user_location_info_nr().nr_cgi.plmn_id = ngap_ptr->nr_cgi.plmn_id; - container.protocol_ies.user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; - container.protocol_ies.user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; + container->user_location_info.value.set_user_location_info_nr(); + container->user_location_info.value.user_location_info_nr().nr_cgi.nrcell_id = ngap_ptr->nr_cgi.nrcell_id; + container->user_location_info.value.user_location_info_nr().nr_cgi.plmn_id = ngap_ptr->nr_cgi.plmn_id; + container->user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; + container->user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; - container.protocol_ies.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; - container.protocol_ies.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); + container->ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + container->amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "UEContextReleaseComplete"); } +bool ngap::ue::send_ue_context_release_request(asn1::ngap::cause_c cause) +{ + if (not ngap_ptr->amf_connected) { + logger.warning("AMF not connected"); + return false; + } + + if (not ctxt.amf_ue_ngap_id.has_value()) { + logger.warning("Can't send release request. User 0x%x has no AMF UE Id.", ctxt.rnti); + return false; + } + + if (was_ue_context_release_requested()) { + // let timeout auto-remove user. + return false; + } + release_requested = true; + + ngap_pdu_c tx_pdu; + tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_ID_UE_CONTEXT_RELEASE_REQUEST); + ue_context_release_request_s& container = tx_pdu.init_msg().value.ue_context_release_request(); + + container->cause.value = cause; + + // PDU Session Resource List + auto& session_lst = container->pdu_session_res_list_cxt_rel_req.value; + for (const auto& pdu_pair : bearer_manager.pdu_sessions()) { + const ngap_ue_bearer_manager::pdu_session_t& session = pdu_pair.second; + + pdu_session_res_item_cxt_rel_req_s obj; + obj.pdu_session_id = session.id; + session_lst.push_back(obj); + } + container->pdu_session_res_list_cxt_rel_req_present = session_lst.size() > 0; + + container->ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + container->amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); + + // TODO: Implement timeout + return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "UEContextReleaseRequest"); +} + /******************************************************************************* /* NGAP message handler ********************************************************************************/ -bool ngap::ue::handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg) +bool ngap::ue::handle_initial_ctxt_setup_request(const asn1::ngap::init_context_setup_request_s& msg) { if (not initial_context_setup_proc.launch(msg)) { logger.error("Failed to start Initial Context Setup Procedure"); @@ -266,7 +308,7 @@ bool ngap::ue::handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_conte return true; } -bool ngap::ue::handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cmd_s& msg) +bool ngap::ue::handle_ue_context_release_cmd(const asn1::ngap::ue_context_release_cmd_s& msg) { // TODO: Release UE context if (not ue_context_release_proc.launch(msg)) { @@ -276,7 +318,7 @@ bool ngap::ue::handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_releas return true; } -bool ngap::ue::handle_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg) +bool ngap::ue::handle_pdu_session_res_setup_request(const asn1::ngap::pdu_session_res_setup_request_s& msg) { if (not ue_pdu_session_res_setup_proc.launch(msg)) { logger.error("Failed to start UE PDU Session Resource Setup Procedure"); @@ -285,4 +327,4 @@ bool ngap::ue::handle_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_ses return true; } -} // namespace srsenb \ No newline at end of file +} // namespace srsenb diff --git a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc b/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc similarity index 78% rename from srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc rename to srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc index abed3400d1..962bb79c83 100644 --- a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc +++ b/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,30 +19,38 @@ * */ -#include "srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h" +#include "srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h" +#include "srsran/common/common_nr.h" namespace srsenb { ngap_ue_bearer_manager::ngap_ue_bearer_manager(gtpu_interface_rrc* gtpu_, srslog::basic_logger& logger_) : gtpu(gtpu_), logger(logger_) -{} +{ +} ngap_ue_bearer_manager::~ngap_ue_bearer_manager(){}; int ngap_ue_bearer_manager::add_pdu_session(uint16_t rnti, uint8_t pdu_session_id, - const asn1::ngap_nr::qos_flow_level_qos_params_s& qos, + const asn1::ngap::qos_flow_level_qos_params_s& qos, const asn1::bounded_bitstring<1, 160, true, true>& addr_out, uint32_t teid_out, uint16_t& lcid, asn1::bounded_bitstring<1, 160, true, true>& addr_in, uint32_t& teid_in, - asn1::ngap_nr::cause_c& cause) + asn1::ngap::cause_c& cause) { // Only add session if gtpu was successful pdu_session_t::gtpu_tunnel tunnel; if (addr_out.length() > 32) { logger.error("Only addresses with length <= 32 (IPv4) are supported"); - cause.set_radio_network().value = asn1::ngap_nr::cause_radio_network_opts::invalid_qos_combination; + cause.set_radio_network().value = asn1::ngap::cause_radio_network_opts::invalid_qos_combination; + return SRSRAN_ERROR; + } + + lcid = allocate_lcid(rnti); + if (lcid >= srsran::MAX_NR_NOF_BEARERS) { + logger.error("Adding PDU Session ID=%d to GTPU. No free LCID.", pdu_session_id); return SRSRAN_ERROR; } @@ -69,7 +77,7 @@ int ngap_ue_bearer_manager::reset_pdu_sessions(uint16_t rnti) { for (auto iter = pdu_session_list.begin(); iter != pdu_session_list.end(); iter++) { auto pdu_session_id = iter->first; - rem_gtpu_bearer(pdu_session_id, rnti); + rem_gtpu_bearer(rnti, pdu_session_id); } return true; } @@ -119,4 +127,22 @@ void ngap_ue_bearer_manager::rem_gtpu_bearer(uint16_t rnti, uint32_t pdu_session gtpu->rem_bearer(rnti, it->second.lcid); } -} // namespace srsenb \ No newline at end of file +uint8_t ngap_ue_bearer_manager::allocate_lcid(uint32_t rnti) +{ + if (pdu_session_list.empty()) { + return 4; + } + for (unsigned lcid = 4; lcid < srsran::MAX_NR_NOF_BEARERS; lcid++) { + const auto pdu_session_it = + std::find_if(pdu_session_list.cbegin(), + pdu_session_list.cend(), + [lcid](const std::pair& t) { return t.second.lcid != lcid; }); + if (pdu_session_it != pdu_session_list.cend()) { + return lcid; + } + } + // All LCIDs are used. + return srsran::MAX_NR_NOF_BEARERS; +} + +} // namespace srsenb diff --git a/srsenb/src/stack/ngap/ngap_ue_proc.cc b/srsgnb/src/stack/ngap/ngap_ue_proc.cc similarity index 62% rename from srsenb/src/stack/ngap/ngap_ue_proc.cc rename to srsgnb/src/stack/ngap/ngap_ue_proc.cc index ea61a29205..930aca6b63 100644 --- a/srsenb/src/stack/ngap/ngap_ue_proc.cc +++ b/srsgnb/src/stack/ngap/ngap_ue_proc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,87 +19,15 @@ * */ -#include "srsenb/hdr/stack/ngap/ngap_ue_proc.h" +#include "srsgnb/hdr/stack/ngap/ngap_ue_proc.h" using namespace srsran; namespace srsenb { -ngap_ue_initial_context_setup_proc::ngap_ue_initial_context_setup_proc(ngap_interface_ngap_proc* parent_, - rrc_interface_ngap_nr* rrc_, - ngap_ue_ctxt_t* ue_ctxt_, - srslog::basic_logger& logger_) : - logger(logger_), parent(parent_), rrc(rrc_), ue_ctxt(ue_ctxt_){}; - -proc_outcome_t ngap_ue_initial_context_setup_proc::init(const asn1::ngap_nr::init_context_setup_request_s& msg) -{ - ue_ctxt->amf_pointer = msg.protocol_ies.guami.value.amf_pointer.to_number(); - ue_ctxt->amf_set_id = msg.protocol_ies.guami.value.amf_set_id.to_number(); - ue_ctxt->amf_region_id = msg.protocol_ies.guami.value.amf_region_id.to_number(); - - if (msg.protocol_ies.ue_aggregate_maximum_bit_rate_present == true) { - rrc->ue_set_bitrates(ue_ctxt->rnti, msg.protocol_ies.ue_aggregate_maximum_bit_rate.value); - } - rrc->ue_set_security_cfg_capabilities(ue_ctxt->rnti, msg.protocol_ies.ue_security_cap.value); - rrc->ue_set_security_cfg_key(ue_ctxt->rnti, msg.protocol_ies.security_key.value); - rrc->start_security_mode_procedure(ue_ctxt->rnti); - - if (msg.protocol_ies.nas_pdu_present) { - srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); - if (pdu == nullptr) { - logger.error("Fatal Error: Couldn't allocate buffer in ngap_ue_initial_context_setup_proc::init()."); - return proc_outcome_t::error; - } - memcpy(pdu->msg, msg.protocol_ies.nas_pdu.value.data(), msg.protocol_ies.nas_pdu.value.size()); - pdu->N_bytes = msg.protocol_ies.nas_pdu.value.size(); - rrc->write_dl_info(ue_ctxt->rnti, std::move(pdu)); - } - return proc_outcome_t::yield; -}; - -proc_outcome_t ngap_ue_initial_context_setup_proc::react(bool rrc_reconf_outcome) -{ - if (rrc_reconf_outcome == true) { - parent->send_initial_ctxt_setup_response(); - return proc_outcome_t::success; - } - - return proc_outcome_t::error; -} - -proc_outcome_t ngap_ue_initial_context_setup_proc::step() -{ - return proc_outcome_t::yield; -} - -ngap_ue_ue_context_release_proc::ngap_ue_ue_context_release_proc(ngap_interface_ngap_proc* parent_, - rrc_interface_ngap_nr* rrc_, - ngap_ue_ctxt_t* ue_ctxt_, - ngap_ue_bearer_manager* bearer_manager_, - srslog::basic_logger& logger_) : - logger(logger_) -{ - parent = parent_; - rrc = rrc_; - ue_ctxt = ue_ctxt_; - bearer_manager = bearer_manager_; -}; - -proc_outcome_t ngap_ue_ue_context_release_proc::init(const asn1::ngap_nr::ue_context_release_cmd_s& msg) -{ - logger.info("Started %s", name()); - // TODO: How to approach erasing users ? - bearer_manager->reset_pdu_sessions(ue_ctxt->rnti); - rrc->release_bearers(ue_ctxt->rnti); - parent->send_ue_ctxt_release_complete(); - return proc_outcome_t::success; -} - -proc_outcome_t ngap_ue_ue_context_release_proc::step() -{ - return proc_outcome_t::success; -} - +/* + * TS 38.413 - Section 8.2.1 PDU Session Resource Setup + */ ngap_ue_pdu_session_res_setup_proc::ngap_ue_pdu_session_res_setup_proc(ngap_interface_ngap_proc* parent_, rrc_interface_ngap_nr* rrc_, ngap_ue_ctxt_t* ue_ctxt_, @@ -108,57 +36,56 @@ ngap_ue_pdu_session_res_setup_proc::ngap_ue_pdu_session_res_setup_proc(ngap_inte parent(parent_), rrc(rrc_), ue_ctxt(ue_ctxt_), bearer_manager(bearer_manager_), logger(logger_) {} -proc_outcome_t ngap_ue_pdu_session_res_setup_proc::init(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg) +proc_outcome_t ngap_ue_pdu_session_res_setup_proc::init(const asn1::ngap::pdu_session_res_setup_request_s& msg) { - if (msg.protocol_ies.pdu_session_res_setup_list_su_req.value.size() != 1) { + if (msg->pdu_session_res_setup_list_su_req.value.size() != 1) { logger.error("Not handling zero or multiple su requests"); return proc_outcome_t::error; } - asn1::ngap_nr::pdu_session_res_setup_item_su_req_s su_req = - msg.protocol_ies.pdu_session_res_setup_list_su_req.value[0]; + asn1::ngap::pdu_session_res_setup_item_su_req_s su_req = msg->pdu_session_res_setup_list_su_req.value[0]; asn1::cbit_ref pdu_session_bref(su_req.pdu_session_res_setup_request_transfer.data(), su_req.pdu_session_res_setup_request_transfer.size()); - asn1::ngap_nr::pdu_session_res_setup_request_transfer_s pdu_ses_res_setup_req_trans; + asn1::ngap::pdu_session_res_setup_request_transfer_s pdu_ses_res_setup_req_trans; if (pdu_ses_res_setup_req_trans.unpack(pdu_session_bref) != SRSRAN_SUCCESS) { logger.error("Unable to unpack PDU session response setup request"); return proc_outcome_t::error; } - if (pdu_ses_res_setup_req_trans.protocol_ies.qos_flow_setup_request_list.value.size() != 1) { + if (pdu_ses_res_setup_req_trans->qos_flow_setup_request_list.value.size() != 1) { logger.error("Expected one item in QoS flow setup request list"); return proc_outcome_t::error; } - if (pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.type() != - asn1::ngap_nr::up_transport_layer_info_c::types::gtp_tunnel) { + if (pdu_ses_res_setup_req_trans->ul_ngu_up_tnl_info.value.type() != + asn1::ngap::up_transport_layer_info_c::types::gtp_tunnel) { logger.error("Expected GTP Tunnel"); return proc_outcome_t::error; } - asn1::ngap_nr::qos_flow_setup_request_item_s qos_flow_setup = - pdu_ses_res_setup_req_trans.protocol_ies.qos_flow_setup_request_list.value[0]; + asn1::ngap::qos_flow_setup_request_item_s qos_flow_setup = + pdu_ses_res_setup_req_trans->qos_flow_setup_request_list.value[0]; srsran::const_span nas_pdu_dummy; uint32_t teid_out = 0; - teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[0] << 24u; - teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[1] << 16u; - teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[2] << 8u; - teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[3]; + teid_out |= pdu_ses_res_setup_req_trans->ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[0] << 24u; + teid_out |= pdu_ses_res_setup_req_trans->ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[1] << 16u; + teid_out |= pdu_ses_res_setup_req_trans->ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[2] << 8u; + teid_out |= pdu_ses_res_setup_req_trans->ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[3]; // TODO: Check cause - asn1::ngap_nr::cause_c cause; - uint32_t teid_in; - uint16_t lcid; + asn1::ngap::cause_c cause; + uint32_t teid_in = {}; + uint16_t lcid = {}; asn1::bounded_bitstring<1, 160, true, true> addr_in; if (bearer_manager->add_pdu_session( ue_ctxt->rnti, su_req.pdu_session_id, qos_flow_setup.qos_flow_level_qos_params, - pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().transport_layer_address, + pdu_ses_res_setup_req_trans->ul_ngu_up_tnl_info.value.gtp_tunnel().transport_layer_address, teid_out, lcid, addr_in, @@ -168,15 +95,19 @@ proc_outcome_t ngap_ue_pdu_session_res_setup_proc::init(const asn1::ngap_nr::pdu return proc_outcome_t::error; } - logger.info("Added PDU Session with LCID %d, teid_out %d, teid_in %d, addr_in %s", + uint16_t five_qi = pdu_ses_res_setup_req_trans->qos_flow_setup_request_list.value[0] + .qos_flow_level_qos_params.qos_characteristics.non_dynamic5_qi() + .five_qi; + + logger.info("Added PDU Session with LCID %d, 5QI %d, teid_out %d, teid_in %d, addr_in %s", lcid, + five_qi, teid_out, teid_in, addr_in.to_string()); - // QoS parameter mapping in config in LTE enb - if (su_req.pdu_session_nas_pdu_present) { - if (rrc->establish_rrc_bearer(ue_ctxt->rnti, su_req.pdu_session_id, su_req.pdu_session_nas_pdu, lcid) == + if (su_req.pdu_session_nas_pdu.size() > 0) { + if (rrc->establish_rrc_bearer(ue_ctxt->rnti, su_req.pdu_session_id, su_req.pdu_session_nas_pdu, lcid, five_qi) == SRSRAN_SUCCESS) { parent->send_pdu_session_resource_setup_response(su_req.pdu_session_id, teid_in, addr_in); return proc_outcome_t::success; @@ -191,4 +122,86 @@ proc_outcome_t ngap_ue_pdu_session_res_setup_proc::step() return proc_outcome_t::success; } -} // namespace srsenb \ No newline at end of file +/* + * TS 38.413 - Section 8.3.1 - Initial Context Setup + */ +ngap_ue_initial_context_setup_proc::ngap_ue_initial_context_setup_proc(ngap_interface_ngap_proc* parent_, + rrc_interface_ngap_nr* rrc_, + ngap_ue_ctxt_t* ue_ctxt_, + srslog::basic_logger& logger_) : + logger(logger_), parent(parent_), rrc(rrc_), ue_ctxt(ue_ctxt_){}; + +proc_outcome_t ngap_ue_initial_context_setup_proc::init(const asn1::ngap::init_context_setup_request_s& msg) +{ + ue_ctxt->amf_pointer = msg->guami.value.amf_pointer.to_number(); + ue_ctxt->amf_set_id = msg->guami.value.amf_set_id.to_number(); + ue_ctxt->amf_region_id = msg->guami.value.amf_region_id.to_number(); + + if (msg->ue_aggregate_maximum_bit_rate_present == true) { + rrc->ue_set_bitrates(ue_ctxt->rnti, msg->ue_aggregate_maximum_bit_rate.value); + } + rrc->ue_set_security_cfg_capabilities(ue_ctxt->rnti, msg->ue_security_cap.value); + rrc->ue_set_security_cfg_key(ue_ctxt->rnti, msg->security_key.value); + + if (msg->nas_pdu_present) { + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (pdu == nullptr) { + logger.error("Fatal Error: Couldn't allocate buffer in %s.", __FUNCTION__); + return proc_outcome_t::error; + } + memcpy(pdu->msg, msg->nas_pdu.value.data(), msg->nas_pdu.value.size()); + pdu->N_bytes = msg->nas_pdu.value.size(); + rrc->start_security_mode_procedure(ue_ctxt->rnti, std::move(pdu)); + } else { + rrc->start_security_mode_procedure(ue_ctxt->rnti, nullptr); + } + + return proc_outcome_t::yield; +}; + +proc_outcome_t ngap_ue_initial_context_setup_proc::react(bool rrc_reconf_outcome) +{ + if (rrc_reconf_outcome == true) { + parent->send_initial_ctxt_setup_response(); + return proc_outcome_t::success; + } + + return proc_outcome_t::error; +} + +proc_outcome_t ngap_ue_initial_context_setup_proc::step() +{ + return proc_outcome_t::yield; +} + +/* + * TS 38.413 - Section 8.3.2 - UE Context Release Request (NG-RAN node initiated) + */ +ngap_ue_ue_context_release_proc::ngap_ue_ue_context_release_proc(ngap_interface_ngap_proc* parent_, + rrc_interface_ngap_nr* rrc_, + ngap_ue_ctxt_t* ue_ctxt_, + ngap_ue_bearer_manager* bearer_manager_, + srslog::basic_logger& logger_) : + logger(logger_) +{ + parent = parent_; + rrc = rrc_; + ue_ctxt = ue_ctxt_; + bearer_manager = bearer_manager_; +}; + +proc_outcome_t ngap_ue_ue_context_release_proc::init(const asn1::ngap::ue_context_release_cmd_s& msg) +{ + logger.info("Started %s", name()); + bearer_manager->reset_pdu_sessions(ue_ctxt->rnti); + rrc->release_user(ue_ctxt->rnti); + parent->send_ue_ctxt_release_complete(); + return proc_outcome_t::success; +} + +proc_outcome_t ngap_ue_ue_context_release_proc::step() +{ + return proc_outcome_t::success; +} + +} // namespace srsenb diff --git a/srsenb/test/ngap/CMakeLists.txt b/srsgnb/src/stack/ngap/test/CMakeLists.txt similarity index 87% rename from srsenb/test/ngap/CMakeLists.txt rename to srsgnb/src/stack/ngap/test/CMakeLists.txt index 0924e3574d..007103e432 100644 --- a/srsenb/test/ngap/CMakeLists.txt +++ b/srsgnb/src/stack/ngap/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -19,7 +19,7 @@ # add_executable(ngap_test ngap_test.cc) -target_link_libraries(ngap_test srsran_common ngap_nr_asn1 srsenb_upper srsran_gtpu ngap_nr_asn1 srsgnb_upper srsgnb_ngap ${SCTP_LIBRARIES}) +target_link_libraries(ngap_test srsran_common ngap_nr_asn1 srsenb_upper srsran_gtpu ngap_nr_asn1 srsgnb_stack srsgnb_ngap ${SCTP_LIBRARIES}) add_test(ngap_test ngap_test) diff --git a/srsgnb/src/stack/ngap/test/ngap_test.cc b/srsgnb/src/stack/ngap/test/ngap_test.cc new file mode 100644 index 0000000000..3d83c25e20 --- /dev/null +++ b/srsgnb/src/stack/ngap/test/ngap_test.cc @@ -0,0 +1,322 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/ngap/ngap.h" +#include "srsran/common/network_utils.h" +#include "srsran/common/test_common.h" + +using namespace srsenb; + +struct amf_dummy { + amf_dummy(const char* addr_str_, int port_) : addr_str(addr_str_), port(port_) + { + srsran::net_utils::set_sockaddr(&amf_sockaddr, addr_str, port); + { + using namespace srsran::net_utils; + fd = open_socket(addr_family::ipv4, socket_type::seqpacket, protocol_type::SCTP); + TESTASSERT(fd > 0); + TESTASSERT(bind_addr(fd, amf_sockaddr)); + } + + int success = listen(fd, SOMAXCONN); + srsran_assert(success == 0, "Failed to listen to incoming SCTP connections"); + } + + ~amf_dummy() + { + if (fd > 0) { + close(fd); + } + } + + srsran::unique_byte_buffer_t read_msg(sockaddr_in* sockfrom = nullptr) + { + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + sockaddr_in from = {}; + socklen_t fromlen = sizeof(from); + sctp_sndrcvinfo sri = {}; + int flags = 0; + ssize_t n_recv = sctp_recvmsg(fd, pdu->msg, pdu->get_tailroom(), (struct sockaddr*)&from, &fromlen, &sri, &flags); + if (n_recv > 0) { + if (sockfrom != nullptr) { + *sockfrom = from; + } + pdu->N_bytes = n_recv; + } + return pdu; + } + + const char* addr_str; + int port; + struct sockaddr_in amf_sockaddr = {}; + int fd; + srsran::unique_byte_buffer_t last_sdu; +}; + +class rrc_nr_dummy : public rrc_interface_ngap_nr +{ +public: + rrc_nr_dummy() : rrc_logger(srslog::fetch_basic_logger("RRC_NR")) { rrc_logger.set_hex_dump_max_size(32); } + int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) + { + for (uint32_t i = 0; i < key.nof_octets(); ++i) { + sec_key[i] = key.data()[key.nof_octets() - 1 - i]; + } + rrc_logger.info(sec_key, 32, "Security key"); + return SRSRAN_SUCCESS; + } + int ue_set_bitrates(uint16_t rnti, const asn1::ngap::ue_aggregate_maximum_bit_rate_s& rates) + { + rrc_logger.info("Setting aggregate max bitrate. RNTI 0x%x", rnti); + return SRSRAN_SUCCESS; + } + int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap::ue_aggregate_maximum_bit_rate_s& rates) + { + rrc_logger.info("Setting aggregate max bitrate"); + return SRSRAN_SUCCESS; + } + int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap::ue_security_cap_s& caps) + { + rrc_logger.info("Setting security capabilities"); + for (uint8_t i = 0; i < 8; i++) { + rrc_logger.info("NIA%d = %s", i, caps.nrintegrity_protection_algorithms.get(i) ? "true" : "false"); + } + for (uint8_t i = 0; i < 8; i++) { + rrc_logger.info("NEA%d = %s", i, caps.nrencryption_algorithms.get(i) ? "true" : "false"); + } + for (uint8_t i = 0; i < 8; i++) { + rrc_logger.info("EEA%d = %s", i, caps.eutr_aencryption_algorithms.get(i) ? "true" : "false"); + } + for (uint8_t i = 0; i < 8; i++) { + rrc_logger.info("EIA%d = %s", i, caps.eutr_aintegrity_protection_algorithms.get(i) ? "true" : "false"); + } + sec_caps = caps; + return SRSRAN_SUCCESS; + } + int start_security_mode_procedure(uint16_t rnti, srsran::unique_byte_buffer_t nas_pdu) + { + rrc_logger.info("Starting securtity mode procedure"); + sec_mod_proc_started = true; + return SRSRAN_SUCCESS; + } + int establish_rrc_bearer(uint16_t rnti, + uint16_t pdu_session_id, + srsran::const_byte_span nas_pdu, + uint32_t lcid, + uint32_t five_qi) + { + rrc_logger.info("Establish RRC bearer"); + return SRSRAN_SUCCESS; + } + + int release_bearers(uint16_t rnti) { return SRSRAN_SUCCESS; } + void release_user(uint16_t rnti) {} + int allocate_lcid(uint16_t rnti) { return SRSRAN_SUCCESS; } + void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {} + + bool sec_mod_proc_started = false; + uint8_t sec_key[32] = {}; + asn1::ngap::ue_security_cap_s sec_caps = {}; + srslog::basic_logger& rrc_logger; +}; +struct dummy_socket_manager : public srsran::socket_manager_itf { + dummy_socket_manager() : srsran::socket_manager_itf(srslog::fetch_basic_logger("TEST")) {} + + /// Register (fd, callback). callback is called within socket thread when fd has data. + bool add_socket_handler(int fd, recv_callback_t handler) final + { + if (s1u_fd > 0) { + return false; + } + s1u_fd = fd; + callback = std::move(handler); + return true; + } + + /// remove registered socket fd + bool remove_socket(int fd) final + { + if (s1u_fd < 0) { + return false; + } + s1u_fd = -1; + return true; + } + + int s1u_fd = 0; + recv_callback_t callback; +}; + +void run_ng_setup(ngap& ngap_obj, amf_dummy& amf) +{ + asn1::ngap::ngap_pdu_c ngap_pdu; + + // gNB -> AMF: NG Setup Request + srsran::unique_byte_buffer_t sdu = amf.read_msg(); + TESTASSERT(sdu->N_bytes > 0); + asn1::cbit_ref cbref(sdu->msg, sdu->N_bytes); + TESTASSERT(ngap_pdu.unpack(cbref) == asn1::SRSASN_SUCCESS); + TESTASSERT(ngap_pdu.type().value == asn1::ngap::ngap_pdu_c::types_opts::init_msg); + TESTASSERT(ngap_pdu.init_msg().proc_code == ASN1_NGAP_ID_NG_SETUP); + + // AMF -> gNB: ng Setup Response + sockaddr_in amf_addr = {}; + sctp_sndrcvinfo rcvinfo = {}; + int flags = 0; + + uint8_t ng_setup_resp[] = {0x20, 0x15, 0x00, 0x55, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x31, 0x17, 0x00, 0x61, 0x6d, + 0x61, 0x72, 0x69, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x61, 0x6d, 0x66, 0x2e, 0x35, 0x67, 0x63, + 0x2e, 0x6d, 0x6e, 0x63, 0x30, 0x30, 0x31, 0x2e, 0x6d, 0x63, 0x63, 0x30, 0x30, 0x31, 0x2e, + 0x33, 0x67, 0x70, 0x70, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x6f, 0x72, 0x67, + 0x00, 0x60, 0x00, 0x08, 0x00, 0x00, 0x00, 0xf1, 0x10, 0x80, 0x01, 0x01, 0x00, 0x56, 0x40, + 0x01, 0x32, 0x00, 0x50, 0x00, 0x08, 0x00, 0x00, 0xf1, 0x10, 0x00, 0x00, 0x00, 0x08}; + memcpy(sdu->msg, ng_setup_resp, sizeof(ng_setup_resp)); + sdu->N_bytes = sizeof(ng_setup_resp); + TESTASSERT(ngap_obj.handle_amf_rx_msg(std::move(sdu), amf_addr, rcvinfo, flags)); +} + +void run_ng_initial_ue(ngap& ngap_obj, amf_dummy& amf, rrc_nr_dummy& rrc) +{ + // RRC will call the initial UE request with the NAS PDU + uint8_t nas_reg_req[] = {0x7e, 0x00, 0x41, 0x79, 0x00, 0x0d, 0x01, 0x00, 0xf1, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x32, 0x54, 0x76, 0x98, 0x2e, 0x02, 0xf0, 0xf0}; + + srsran::unique_byte_buffer_t nas_pdu = srsran::make_byte_buffer(); + memcpy(nas_pdu->msg, nas_reg_req, sizeof(nas_reg_req)); + nas_pdu->N_bytes = sizeof(nas_reg_req); + + uint32_t rnti = 0xf0f0; + ngap_obj.initial_ue(rnti, 0, asn1::ngap::rrcestablishment_cause_opts::mo_sig, srsran::make_span(nas_pdu)); + + // gNB -> AMF: Inital UE message + asn1::ngap::ngap_pdu_c ngap_initial_ue_pdu; + srsran::unique_byte_buffer_t sdu = amf.read_msg(); + TESTASSERT(sdu->N_bytes > 0); + asn1::cbit_ref cbref(sdu->msg, sdu->N_bytes); + TESTASSERT_EQ(ngap_initial_ue_pdu.unpack(cbref), asn1::SRSASN_SUCCESS); + TESTASSERT_EQ(ngap_initial_ue_pdu.type().value, asn1::ngap::ngap_pdu_c::types_opts::init_msg); + TESTASSERT_EQ(ngap_initial_ue_pdu.init_msg().proc_code, ASN1_NGAP_ID_INIT_UE_MSG); + + // AMF -> gNB: Initial Context Setup Request + sockaddr_in amf_addr = {}; + sctp_sndrcvinfo rcvinfo = {}; + int flags = 0; + + asn1::ngap::ngap_pdu_c ngap_initial_ctx_req_pdu; + ngap_initial_ctx_req_pdu.set_init_msg().load_info_obj(ASN1_NGAP_ID_INIT_CONTEXT_SETUP); + auto& container = ngap_initial_ctx_req_pdu.init_msg().value.init_context_setup_request(); + + container->amf_ue_ngap_id.value = 0x1; + container->ran_ue_ngap_id.value = 0x1; + container->nas_pdu_present = true; + + // Set allowed NSSAI + container->allowed_nssai.value.resize(1); + container->allowed_nssai.value[0].s_nssai.sst.from_number(1); + + // Set security key + uint8_t sec_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}; + for (uint8_t i = 0; i < 32; ++i) { + container->security_key.value.data()[31 - i] = sec_key[i]; + } + + // Set security capabilities + container->ue_security_cap.value.nrencryption_algorithms.set(0, true); + container->ue_security_cap.value.nrencryption_algorithms.set(1, true); + container->ue_security_cap.value.nrintegrity_protection_algorithms.set(0, true); + container->ue_security_cap.value.nrintegrity_protection_algorithms.set(1, true); + container->ue_security_cap.value.eutr_aencryption_algorithms.set(0, true); + container->ue_security_cap.value.eutr_aencryption_algorithms.set(1, true); + container->ue_security_cap.value.eutr_aintegrity_protection_algorithms.set(0, true); + container->ue_security_cap.value.eutr_aintegrity_protection_algorithms.set(1, true); + + // Set PDU Session Response Setup Item + // TODO + + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + TESTASSERT_NEQ(buf, nullptr); + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + TESTASSERT_EQ(ngap_initial_ctx_req_pdu.pack(bref), asn1::SRSASN_SUCCESS); + buf->N_bytes = bref.distance_bytes(); + + // Feed Initial Context Setup Request to NGAP + TESTASSERT(ngap_obj.handle_amf_rx_msg(std::move(buf), amf_addr, rcvinfo, flags)); + + // Check RRC security key + for (uint8_t i = 0; i < 32; ++i) { + TESTASSERT_EQ(sec_key[i], rrc.sec_key[i]); + } + + // Check RRC security capabilities + for (uint8_t i = 0; i < 8; ++i) { + TESTASSERT_EQ(container->ue_security_cap.value.nrencryption_algorithms.get(i), + rrc.sec_caps.nrencryption_algorithms.get(i)); + TESTASSERT_EQ(container->ue_security_cap.value.nrintegrity_protection_algorithms.get(i), + rrc.sec_caps.nrintegrity_protection_algorithms.get(i)); + TESTASSERT_EQ(container->ue_security_cap.value.eutr_aencryption_algorithms.get(i), + rrc.sec_caps.eutr_aencryption_algorithms.get(i)); + TESTASSERT_EQ(container->ue_security_cap.value.eutr_aintegrity_protection_algorithms.get(i), + rrc.sec_caps.eutr_aintegrity_protection_algorithms.get(i)); + } + + // Check PDU Session Response Setup Item + // TODO + + // Check RRC security mode command was started + TESTASSERT(rrc.sec_mod_proc_started); +} + +int main(int argc, char** argv) +{ + // Setup logging. + srslog::basic_logger& logger = srslog::fetch_basic_logger("NGAP"); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(-1); + + srsran::task_scheduler task_sched; + dummy_socket_manager rx_sockets; + ngap ngap_obj(&task_sched, logger, &rx_sockets); + + const char* amf_addr_str = "127.0.0.1"; + const uint32_t AMF_PORT = 38412; + amf_dummy amf(amf_addr_str, AMF_PORT); + + ngap_args_t args = {}; + args.cell_id = 0x01; + args.gnb_id = 0x19B; + args.mcc = 907; + args.mnc = 70; + args.ngc_bind_addr = "127.0.0.100"; + args.tac = 7; + args.gtp_bind_addr = "127.0.0.100"; + args.amf_addr = "127.0.0.1"; + args.gnb_name = "srsgnb01"; + + rrc_nr_dummy rrc; + gtpu_interface_rrc* gtpu = nullptr; + ngap_obj.init(args, &rrc, gtpu); + + // Start the log backend. + srsran::test_init(argc, argv); + run_ng_setup(ngap_obj, amf); + run_ng_initial_ue(ngap_obj, amf, rrc); +} diff --git a/srsgnb/src/stack/ric/CMakeLists.txt b/srsgnb/src/stack/ric/CMakeLists.txt new file mode 100644 index 0000000000..0372a6a4bc --- /dev/null +++ b/srsgnb/src/stack/ric/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# Copyright 2013-2023 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/. +# + +set(SOURCES e2_agent.cc e2ap_ric_subscription.cc e2ap.cc e2sm_kpm_common.cc e2sm_kpm.cc e2sm_kpm_report_service.cc) +add_library(srsgnb_ric STATIC ${SOURCES}) +target_link_libraries(srsgnb_ric srsran_asn1 ric_e2) + +add_subdirectory(test) diff --git a/srsgnb/src/stack/ric/e2_agent.cc b/srsgnb/src/stack/ric/e2_agent.cc new file mode 100644 index 0000000000..8ef2b8dd45 --- /dev/null +++ b/srsgnb/src/stack/ric/e2_agent.cc @@ -0,0 +1,608 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/ric/e2_agent.h" +#include "srsran/asn1/e2ap.h" +#include "srsran/common/standard_streams.h" + +using namespace srsenb; + +/********************************************************* + * RIC Connection + *********************************************************/ + +srsran::proc_outcome_t e2_agent::e2_setup_proc_t::init() +{ + e2_agent_ptr->logger.info("Starting new RIC connection."); + connect_count++; + return start_ric_connection(); +} + +srsran::proc_outcome_t e2_agent::e2_setup_proc_t::start_ric_connection() +{ + if (not e2_agent_ptr->running) { + e2_agent_ptr->logger.info("E2 Agent is not running anymore."); + return srsran::proc_outcome_t::error; + } + if (e2_agent_ptr->ric_connected) { + e2_agent_ptr->logger.info("E2 Agent is already connected to RIC"); + return srsran::proc_outcome_t::success; + } + + auto connect_callback = [this]() { + bool connected = e2_agent_ptr->connect_ric(); + + auto notify_result = [this, connected]() { + e2_setup_proc_t::e2connectresult res; + res.success = connected; + e2_agent_ptr->e2_setup_proc.trigger(res); + }; + e2_agent_ptr->task_sched.notify_background_task_result(notify_result); + }; + srsran::get_background_workers().push_task(connect_callback); + e2_agent_ptr->logger.debug("Connection to RIC requested."); + + return srsran::proc_outcome_t::yield; +} + +srsran::proc_outcome_t e2_agent::e2_setup_proc_t::react(const srsenb::e2_agent::e2_setup_proc_t::e2connectresult& event) +{ + if (event.success) { + e2_agent_ptr->logger.info("Connected to RIC. Sending setup request."); + e2_agent_ptr->e2_setup_timeout.run(); + if (not e2_agent_ptr->setup_e2()) { + e2_agent_ptr->logger.error("E2 setup failed. Exiting..."); + srsran::console("E2 setup failed\n"); + e2_agent_ptr->running = false; + return srsran::proc_outcome_t::error; + } + e2_agent_ptr->logger.info("E2 setup request sent. Waiting for response."); + return srsran::proc_outcome_t::yield; + } + + e2_agent_ptr->logger.info("Could not connected to RIC. Aborting"); + return srsran::proc_outcome_t::error; +} + +srsran::proc_outcome_t e2_agent::e2_setup_proc_t::react(const srsenb::e2_agent::e2_setup_proc_t::e2setupresult& event) +{ + if (e2_agent_ptr->e2_setup_timeout.is_running()) { + e2_agent_ptr->e2_setup_timeout.stop(); + } + if (event.success) { + e2_agent_ptr->logger.info("E2 Setup procedure completed successfully"); + return srsran::proc_outcome_t::success; + } + e2_agent_ptr->logger.error("E2 Setup failed."); + srsran::console("E2 setup failed\n"); + return srsran::proc_outcome_t::error; +} + +void e2_agent::e2_setup_proc_t::then(const srsran::proc_state_t& result) +{ + if (result.is_error()) { + e2_agent_ptr->logger.info("Failed to initiate RIC connection. Attempting reconnection in %d seconds", + e2_agent_ptr->ric_connect_timer.duration() / 1000); + srsran::console("Failed to initiate RIC connection. Attempting reconnection in %d seconds\n", + e2_agent_ptr->ric_connect_timer.duration() / 1000); + e2_agent_ptr->rx_sockets.remove_socket(e2_agent_ptr->ric_socket.get_socket()); + e2_agent_ptr->ric_socket.close(); + e2_agent_ptr->logger.info("R2 Agent socket closed."); + e2_agent_ptr->ric_connect_timer.run(); + if (e2_agent_ptr->_args.max_ric_setup_retries > 0 && connect_count > e2_agent_ptr->_args.max_ric_setup_retries) { + srsran_terminate("Error connecting to RIC"); + } + // Try again with in 10 seconds + } else { + connect_count = 0; + } +} + +/********************************************************* + * E2 Agent class + *********************************************************/ + +e2_agent::e2_agent(srslog::basic_logger& logger, e2_interface_metrics* _gnb_metrics) : + task_sched(), + logger(logger), + rx_sockets(), + thread("E2_AGENT_THREAD"), + e2ap_(logger, this, _gnb_metrics, &task_sched), + e2_setup_proc(this) +{ + gnb_metrics = _gnb_metrics; + ric_rece_task_queue = task_sched.make_task_queue(); +} + +bool e2_agent::init(e2_agent_args_t args) +{ + _args = args; + + // Setup RIC reconnection timer + ric_connect_timer = task_sched.get_unique_timer(); + auto ric_connect_run = [this](uint32_t tid) { + if (e2_setup_proc.is_busy()) { + logger.error("Failed to initiate RIC Setup procedure: procedure is busy."); + } + e2_setup_proc.launch(); + }; + ric_connect_timer.set(_args.ric_connect_timer * 1000, ric_connect_run); + // Setup timeout + e2_setup_timeout = task_sched.get_unique_timer(); + uint32_t ric_setup_timeout_val = 5000; + e2_setup_timeout.set(ric_setup_timeout_val, [this](uint32_t tid) { + e2_setup_proc_t::e2setupresult res; + res.success = false; + res.cause = e2_setup_proc_t::e2setupresult::cause_t::timeout; + e2_setup_proc.trigger(res); + }); + + start(0); + running = true; + // starting RIC connection + if (not e2_setup_proc.launch()) { + logger.error("Failed to initiate RIC Setup procedure: error launching procedure."); + } + + return SRSRAN_SUCCESS; +} + +void e2_agent::stop() +{ + running = false; + wait_thread_finish(); +} + +void e2_agent::tic() +{ + // get tick every 1ms to advance timers + task_sched.tic(); +} + +bool e2_agent::is_ric_connected() +{ + return ric_connected; +} + +bool e2_agent::connect_ric() +{ + using namespace srsran::net_utils; + logger.info("Connecting to RIC %s:%d", _args.ric_ip.c_str(), _args.ric_port); + // Open SCTP socket + if (not ric_socket.open_socket(addr_family::ipv4, socket_type::seqpacket, protocol_type::SCTP)) { + return false; + } + + // Subscribe to shutdown events + if (not ric_socket.sctp_subscribe_to_events()) { + ric_socket.close(); + return false; + } + + // Set SRTO_MAX + if (not ric_socket.sctp_set_rto_opts(6000)) { + return false; + } + + // Set SCTP init options + if (not ric_socket.sctp_set_init_msg_opts(3, 5000)) { + return false; + } + + // Bind socket + if (not ric_socket.bind_addr(_args.ric_bind_ip.c_str(), _args.ric_bind_port)) { + ric_socket.close(); + return false; + } + logger.info("SCTP socket opened. fd=%d", ric_socket.fd()); + + // Connect to the AMF address + if (not ric_socket.connect_to(_args.ric_ip.c_str(), _args.ric_port, &ric_addr)) { + ric_socket.close(); + return false; + } + logger.info("SCTP socket connected with RIC. fd=%d", ric_socket.fd()); + + // Assign a handler to rx RIC packets + auto rx_callback = + [this](srsran::unique_byte_buffer_t pdu, const sockaddr_in& from, const sctp_sndrcvinfo& sri, int flags) { + handle_ric_rx_msg(std::move(pdu), from, sri, flags); + }; + rx_sockets.add_socket_handler(ric_socket.fd(), + srsran::make_sctp_sdu_handler(logger, ric_rece_task_queue, rx_callback)); + + logger.info("SCTP socket connected established with RIC"); + return true; +} + +bool e2_agent::setup_e2() +{ + return send_e2_msg(E2_SETUP_REQUEST); +} + +void e2_agent::run_thread() +{ + while (running) { + task_sched.run_next_task(); + } +} + +bool e2_agent::send_sctp(srsran::unique_byte_buffer_t& buf) +{ + ssize_t ret; + ret = sctp_sendmsg(ric_socket.fd(), + buf->msg, + buf->N_bytes, + (struct sockaddr*)&ric_addr, + sizeof(ric_addr), + htonl(e2ap_ppid), + 0, + 0, + 0, + 0); + if (ret == -1) { + printf("failed to send %d bytes\n", buf->N_bytes); + return false; + } + return true; +} + +bool e2_agent::send_e2_msg(e2_msg_type_t msg_type) +{ + std::string message_name; + e2_ap_pdu_c send_pdu; + + switch (msg_type) { + case e2_msg_type_t::E2_SETUP_REQUEST: + send_pdu = e2ap_.generate_setup_request(); + message_name = "E2 SETUP REQUEST"; + break; + case e2_msg_type_t::E2_RESET: + send_pdu = e2ap_.generate_reset_request(); + message_name = "E2 RESET REQUEST"; + break; + case e2_msg_type_t::E2_RESET_RESPONSE: + send_pdu = e2ap_.generate_reset_response(); + message_name = "E2 RESET RESPONSE"; + break; + default: + printf("Unknown E2AP message type\n"); + return false; + } + + return send_e2ap_pdu(send_pdu); +} + +bool e2_agent::queue_send_e2ap_pdu(e2_ap_pdu_c e2ap_pdu) +{ + if (not ric_connected) { + logger.error("Aborting sending msg. Cause: RIC is not connected."); + return false; + } + + auto send_e2ap_pdu_task = [this, e2ap_pdu]() { send_e2ap_pdu(e2ap_pdu); }; + ric_rece_task_queue.push(send_e2ap_pdu_task); + return true; +} + +bool e2_agent::send_e2ap_pdu(e2_ap_pdu_c send_pdu) +{ + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + if (buf == nullptr) { + // logger.error("Fatal Error: Couldn't allocate buffer for %s.", procedure_name); + return false; + } + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (send_pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + logger.error("Failed to pack TX E2 PDU"); + return false; + } + buf->N_bytes = bref.distance_bytes(); + printf("try to send %d bytes to addr %s \n", buf->N_bytes, inet_ntoa(ric_addr.sin_addr)); + if (!send_sctp(buf)) { + logger.error("failed to send"); + return false; + } + return true; +} + +bool e2_agent::handle_ric_rx_msg(srsran::unique_byte_buffer_t pdu, + const sockaddr_in& from, + const sctp_sndrcvinfo& sri, + int flags) +{ + // Handle Notification Case + if (flags & MSG_NOTIFICATION) { + // Received notification + union sctp_notification* notification = (union sctp_notification*)pdu->msg; + logger.info("SCTP Notification %04x", notification->sn_header.sn_type); + bool restart_e2 = false; + if (notification->sn_header.sn_type == SCTP_SHUTDOWN_EVENT) { + logger.info("SCTP Association Shutdown. Association: %d", sri.sinfo_assoc_id); + srsran::console("SCTP Association Shutdown. Association: %d\n", sri.sinfo_assoc_id); + restart_e2 = true; + } else if (notification->sn_header.sn_type == SCTP_PEER_ADDR_CHANGE && + notification->sn_paddr_change.spc_state == SCTP_ADDR_UNREACHABLE) { + logger.info("SCTP peer addres unreachable. Association: %d", sri.sinfo_assoc_id); + srsran::console("SCTP peer address unreachable. Association: %d\n", sri.sinfo_assoc_id); + restart_e2 = true; + } else if (notification->sn_header.sn_type == SCTP_REMOTE_ERROR) { + logger.info("SCTP remote error. Association: %d", sri.sinfo_assoc_id); + srsran::console("SCTP remote error. Association: %d\n", sri.sinfo_assoc_id); + restart_e2 = true; + } else if (notification->sn_header.sn_type == SCTP_ASSOC_CHANGE) { + logger.info("SCTP association changed. Association: %d", sri.sinfo_assoc_id); + srsran::console("SCTP association changed. Association: %d\n", sri.sinfo_assoc_id); + } + if (restart_e2) { + logger.info("Restarting E2 connection"); + srsran::console("Restarting E2 connection\n"); + rx_sockets.remove_socket(ric_socket.get_socket()); + ric_socket.close(); + } + } else if (pdu->N_bytes == 0) { + logger.error("SCTP return 0 bytes. Closing socket"); + ric_socket.close(); + } + + // Restart RIC connection procedure if we lost connection + if (not ric_socket.is_open()) { + ric_connected = false; + if (e2_setup_proc.is_busy()) { + logger.error("Failed to initiate RIC connection procedure, as it is already running."); + return false; + } + e2_setup_proc.launch(); + return false; + } + + if ((flags & MSG_NOTIFICATION) == 0 && pdu->N_bytes != 0) { + handle_e2_rx_pdu(pdu.get()); + } + + return true; +} + +bool e2_agent::handle_e2_rx_pdu(srsran::byte_buffer_t* pdu) +{ + printf("E2_AGENT: Received %d bytes from RIC\n", pdu->N_bytes); + e2_ap_pdu_c pdu_c; + asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); + if (pdu_c.unpack(bref) != asn1::SRSASN_SUCCESS) { + logger.error("Failed to unpack RX E2 PDU"); + return false; + } + if (pdu_c.type().value == e2_ap_pdu_c::types_opts::init_msg) { + logger.info("Received E2AP Init Message"); + handle_e2_init_msg(pdu_c.init_msg()); + } else if (pdu_c.type().value == e2_ap_pdu_c::types_opts::successful_outcome) { + logger.info("Received E2AP Successful Outcome"); + handle_e2_successful_outcome(pdu_c.successful_outcome()); + } else if (pdu_c.type().value == e2_ap_pdu_c::types_opts::unsuccessful_outcome) { + logger.info("Received E2AP Unsuccessful Outcome "); + handle_e2_unsuccessful_outcome(pdu_c.unsuccessful_outcome()); + } else { + logger.warning("Received E2AP Unknown Message "); + } + return true; +} + +bool e2_agent::handle_e2_init_msg(asn1::e2ap::init_msg_s& init_msg) +{ + using namespace asn1::e2ap; + if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::ricsubscription_request) { + logger.info("Received E2AP RIC Subscription Request"); + handle_ric_subscription_request(init_msg.value.ricsubscription_request()); + } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::ricsubscription_delete_request) { + logger.info("Received E2AP RIC Subscription Delete Request"); + handle_ric_subscription_delete_request(init_msg.value.ricsubscription_delete_request()); + } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::ri_cctrl_request) { + logger.info("Received E2AP RIC Control Request"); + // handle_ri_cctrl_request(init_msg.value.ri_cctrl_request()); + } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::e2conn_upd) { + logger.info("Received E2AP E2 Connection Update"); + //handle_e2conn_upd(init_msg.value.e2conn_upd()); + } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::reset_request) { + logger.info("Received E2AP E2 Reset Request"); + handle_reset_request(init_msg.value.reset_request()); + } else if (init_msg.value.type() == e2_ap_elem_procs_o::init_msg_c::types_opts::e2_removal_request) { + logger.info("Received E2AP E2 Removal Request"); + //handle_e2_removal_request(init_msg.value.e2_removal_request()); + } else { + logger.warning("Received E2AP Unknown Init Message "); + } + // TODO check for different type of RIC generated init messages + // eg. RIC subscription request, RIC Reset request, RIC control request, RIC subscription delete request + return true; +} + +bool e2_agent::handle_e2_successful_outcome(asn1::e2ap::successful_outcome_s& successful_outcome) +{ + using namespace asn1::e2ap; + if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::e2setup_resp) { + logger.info("Received E2AP E2 Setup Response"); + handle_e2_setup_response(successful_outcome.value.e2setup_resp()); + } else if (successful_outcome.value.type() == + e2_ap_elem_procs_o::successful_outcome_c::types_opts::ricsubscription_resp) { + logger.info("Received E2AP RIC Subscription Response"); + // handle_ric_subscription_response(successful_outcome.value.ric_subscription()); + } else if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::ri_cctrl_ack) { + logger.info("Received E2AP RIC Control acknowlegement \n"); + // handle_ric_control_response(successful_outcome.value.ric_control()); + } else if (successful_outcome.value.type() == + e2_ap_elem_procs_o::successful_outcome_c::types_opts::ricservice_upd_ack) { + logger.info("Received E2AP RIC Service Update acknowlegement \n"); + // handle_ric_service_update_ack(successful_outcome.value.ric_service_update()); + } else if (successful_outcome.value.type() == + e2_ap_elem_procs_o::successful_outcome_c::types_opts::ricsubscription_delete_resp) { + logger.info("Received E2AP RIC Subscription Delete Response \n"); + // handle_ric_subscription_delete_response(successful_outcome.value.ric_subscription_delete()); + } else if (successful_outcome.value.type() == e2_ap_elem_procs_o::successful_outcome_c::types_opts::reset_resp) { + logger.info("Received E2AP RIC Reset Response \n"); + handle_reset_response(successful_outcome.value.reset_resp()); + } else { + logger.info("Received E2AP Unknown Successful Outcome \n"); + } + return true; +} + +bool e2_agent::handle_e2_setup_response(e2setup_resp_s setup_response) +{ + if (e2ap_.process_setup_response(setup_response)) { + logger.error("Failed to process E2 Setup Response \n"); + ric_connected = false; + e2_setup_proc_t::e2setupresult res; + res.success = false; + e2_setup_proc.trigger(res); + return false; + } + + ric_connected = true; + e2_setup_proc_t::e2setupresult res; + res.success = true; + e2_setup_proc.trigger(res); + return true; +} + +bool e2_agent::handle_e2_unsuccessful_outcome(asn1::e2ap::unsuccessful_outcome_s& unsuccessful_outcome) +{ + using namespace asn1::e2ap; + if (unsuccessful_outcome.value.type() == e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::e2setup_fail) { + logger.info("Received E2AP E2 Setup Failure"); + if (e2ap_.process_e2_setup_failure(unsuccessful_outcome.value.e2setup_fail())) { + logger.error("Failed to process E2 Setup Failure \n"); + return false; + } + } else if (unsuccessful_outcome.value.type() == + e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::e2node_cfg_upd_fail) { + logger.info("Received E2node configuration update Failure"); + if (e2ap_.process_e2_node_config_update_failure(unsuccessful_outcome.value.e2node_cfg_upd_fail())) { + logger.error("Failed to process E2node configuration update Failure \n"); + return false; + } + } else if (unsuccessful_outcome.value.type() == + e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::ricservice_upd_fail) { + logger.info("Received E2AP RIC Service Update Failure \n"); + if (e2ap_.process_ric_service_update_failure(unsuccessful_outcome.value.ricservice_upd_fail())) { + logger.error("Failed to process RIC service update failure \n"); + return false; + } + } else if (unsuccessful_outcome.value.type() == + e2_ap_elem_procs_o::unsuccessful_outcome_c::types_opts::e2_removal_fail) { + logger.info("Received E2AP removal Unsuccessful Outcome \n"); + if (e2ap_.process_e2_removal_failure(unsuccessful_outcome.value.e2_removal_fail())) { + logger.error("Failed to process RIC service status failure \n"); + return false; + } + } else { + logger.info("Received E2AP Unknown Unsuccessful Outcome \n"); + } + + return true; +} + +bool e2_agent::handle_ric_subscription_request(ricsubscription_request_s ric_subscription_request) +{ + logger.info("Received RIC Subscription Request from RIC ID: %i (instance id %i) to RAN Function ID: %i", + ric_subscription_request->ri_crequest_id->ric_requestor_id, + ric_subscription_request->ri_crequest_id->ric_instance_id, + ric_subscription_request->ra_nfunction_id->value); + + if (e2ap_.process_subscription_request(ric_subscription_request)) { + logger.error("Failed to process RIC subscription request \n"); + return false; + } + + return true; +} + +bool e2_agent::handle_ric_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request) +{ + logger.info("Received RIC Subscription Delete request from RIC ID: %i (instance id %i) to RAN Function ID: %i", + ricsubscription_delete_request->ri_crequest_id->ric_requestor_id, + ricsubscription_delete_request->ri_crequest_id->ric_instance_id, + ricsubscription_delete_request->ra_nfunction_id->value); + + if (e2ap_.process_subscription_delete_request(ricsubscription_delete_request)) { + logger.error("Failed to process RIC subscription delete request \n"); + return false; + } + + return true; +} + +bool e2_agent::handle_subscription_modification_request(uint32_t ric_subscription_modification_request) +{ + if (e2ap_.process_subscription_modification_request(ric_subscription_modification_request)) { + logger.error("Failed to process RIC subscription delete request \n"); + return false; + } + return true; +} +bool e2_agent::handle_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm) +{ + if (e2ap_.process_subscription_modification_confirm(ric_subscription_modification_confirm)) { + logger.error("Failed to process RIC subscription delete request \n"); + return false; + } + return true; +} +bool e2_agent::handle_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse) +{ + if (e2ap_.process_subscription_modification_refuse(ric_subscription_modification_refuse)) { + logger.error("Failed to process RIC subscription delete request \n"); + return false; + } + return true; +} + +bool e2_agent::handle_reset_request(reset_request_s& reset_request) +{ + printf("Received E2AP E2 Reset Request \n"); + // call process to handle reset request, if it fails log error and return false, else return true - success + if (e2ap_.process_reset_request(reset_request)) { + logger.error("Failed to process E2 Reset Request \n"); + return false; + } + + logger.info("Reset transaction with ID = {}", e2ap_.get_reset_id()); + + // send reset reset response + auto send_reset_resp = [this]() { send_e2_msg(E2_RESET_RESPONSE); }; + ric_rece_task_queue.push(send_reset_resp); + + return true; +} + +bool e2_agent::handle_reset_response(reset_resp_s& reset_response) +{ + printf("Received E2AP E2 Reset Response \n"); + // call process to handle reset reponse, if it fails log error, else return true - success + // all processing of message will be done in process_reset_response (e2ap.cc) + if (e2ap_.process_reset_response(reset_response)) { + logger.error("Failed to process E2 Reset Response \n"); + return false; + } + + logger.info("Reset Response successfully processed \n"); + + return true; +} diff --git a/srsgnb/src/stack/ric/e2ap.cc b/srsgnb/src/stack/ric/e2ap.cc new file mode 100644 index 0000000000..ebd6394841 --- /dev/null +++ b/srsgnb/src/stack/ric/e2ap.cc @@ -0,0 +1,465 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/ric/e2ap.h" +#include "srsgnb/hdr/stack/ric/e2_agent.h" +#include "srsgnb/hdr/stack/ric/e2ap_ric_subscription.h" + +e2ap::e2ap(srslog::basic_logger& logger, + e2_agent* _e2_agent, + srsenb::e2_interface_metrics* _gnb_metrics, + srsran::task_scheduler* _task_sched_ptr) : + logger(logger), _e2_agent(_e2_agent), e2sm_(logger, _task_sched_ptr), task_sched_ptr(_task_sched_ptr) +{ + gnb_metrics = _gnb_metrics; + if (task_sched_ptr) { + e2_procedure_timeout = task_sched_ptr->get_unique_timer(); + } + + // register SM to receive enb metrics + gnb_metrics->register_e2sm(&e2sm_); + + // add SMs to map + uint32_t local_ran_function_id = 147; + RANfunction_description add_func; + add_func.function_instance = 0; + add_func.sm_ptr = &e2sm_; + ran_functions[local_ran_function_id] = add_func; +} + +e2ap::~e2ap(){}; + +bool e2ap::get_func_desc(uint32_t ran_func_id, RANfunction_description& fdesc) +{ + if (ran_functions.count(ran_func_id)) { + fdesc = ran_functions.at(ran_func_id); + return true; + } + return false; +} + +bool e2ap::queue_send_e2ap_pdu(e2_ap_pdu_c e2ap_pdu) +{ + if (_e2_agent) { + _e2_agent->queue_send_e2ap_pdu(e2ap_pdu); + } + return true; +} + +e2_ap_pdu_c e2ap::generate_setup_request() +{ + e2_ap_pdu_c pdu; + init_msg_s& initmsg = pdu.set_init_msg(); + initmsg.load_info_obj(ASN1_E2AP_ID_E2SETUP); + + e2setup_request_s& setup = initmsg.value.e2setup_request(); + setup->transaction_id.crit = asn1::crit_opts::reject; + setup->transaction_id.value.value = setup_procedure_transaction_id; + setup->global_e2node_id.crit = asn1::crit_opts::reject; + + auto& gnb_ = setup->global_e2node_id.value.set_gnb(); + gnb_.global_g_nb_id.plmn_id.from_number(plmn_id); + gnb_.global_g_nb_id.gnb_id.gnb_id().from_number(gnb_id, 28); // eutra_cell_id has 28 bits + + // add all supported e2SM functions + setup->ra_nfunctions_added.crit = asn1::crit_opts::reject; + auto& ra_nfunc_list = setup->ra_nfunctions_added.value; + ra_nfunc_list.resize(ran_functions.size()); + + uint32_t idx = 0; + for (auto& x : ran_functions) { + uint32_t local_ran_function_id = x.first; + e2sm* sm_ptr = x.second.sm_ptr; + + ra_nfunction_item_s& ran_func = ra_nfunc_list[idx].value().ra_nfunction_item(); + ran_func.ran_function_id = local_ran_function_id; + ran_func.ran_function_revision = sm_ptr->get_revision(); + ran_func.ran_function_oid.from_string(sm_ptr->get_oid().c_str()); + sm_ptr->generate_ran_function_description(x.second, ran_func); + idx++; + } + + setup->e2node_component_cfg_addition.crit = asn1::crit_opts::reject; + auto& list1 = setup->e2node_component_cfg_addition.value; + list1.resize(1); + e2node_component_cfg_addition_item_s& item1 = list1[0].value().e2node_component_cfg_addition_item(); + item1.e2node_component_interface_type = e2node_component_interface_type_opts::ng; + item1.e2node_component_id.set_e2node_component_interface_type_ng().amf_name.from_string("nginterf"); + item1.e2node_component_cfg.e2node_component_request_part.from_string("72657170617274"); + item1.e2node_component_cfg.e2node_component_resp_part.from_string("72657370617274"); + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_response(ric_subscription_reponse_t ric_subscription_reponse) +{ + e2_ap_pdu_c pdu; + successful_outcome_s& success = pdu.set_successful_outcome(); + success.load_info_obj(ASN1_E2AP_ID_RICSUBSCRIPTION); + success.crit = asn1::crit_opts::reject; + ricsubscription_resp_s& sub_resp = success.value.ricsubscription_resp(); + + sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; + sub_resp->ri_crequest_id.id = ASN1_E2AP_ID_RI_CREQUEST_ID; + sub_resp->ri_crequest_id.value.ric_requestor_id = ric_subscription_reponse.ric_requestor_id; + sub_resp->ri_crequest_id.value.ric_instance_id = ric_subscription_reponse.ric_instance_id; + + sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; + sub_resp->ra_nfunction_id.id = ASN1_E2AP_ID_RA_NFUNCTION_ID; + sub_resp->ra_nfunction_id->value = ric_subscription_reponse.ra_nfunction_id; + + sub_resp->ri_cactions_admitted.crit = asn1::crit_opts::reject; + auto& action_admit_list = sub_resp->ri_cactions_admitted.value; + action_admit_list.resize(ric_subscription_reponse.admitted_actions.size()); + for (uint32_t i = 0; i < ric_subscription_reponse.admitted_actions.size(); i++) { + action_admit_list[i].load_info_obj(ASN1_E2AP_ID_RI_CACTION_ADMITTED_ITEM); + ri_caction_admitted_item_s& a_item = action_admit_list[i]->ri_caction_admitted_item(); + a_item.ric_action_id = ric_subscription_reponse.admitted_actions[i]; + } + + if (ric_subscription_reponse.not_admitted_actions.size()) { + sub_resp->ri_cactions_not_admitted.crit = asn1::crit_opts::reject; + auto& action_not_admit_list = sub_resp->ri_cactions_not_admitted.value; + action_not_admit_list.resize(ric_subscription_reponse.not_admitted_actions.size()); + for (uint32_t i = 0; i < ric_subscription_reponse.not_admitted_actions.size(); i++) { + action_not_admit_list[i].load_info_obj(ASN1_E2AP_ID_RI_CACTION_NOT_ADMITTED_ITEM); + ri_caction_not_admitted_item_s& not_a_item = action_not_admit_list[i]->ri_caction_not_admitted_item(); + not_a_item.ric_action_id = ric_subscription_reponse.not_admitted_actions[i]; + not_a_item.cause.set_misc(); // TODO: support cause properly + } + } + + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_failure(ric_subscription_reponse_t ric_subscription_reponse) +{ + e2_ap_pdu_c pdu; + unsuccessful_outcome_s& failure = pdu.set_unsuccessful_outcome(); + failure.load_info_obj(ASN1_E2AP_ID_RICSUBSCRIPTION); + failure.crit = asn1::crit_opts::reject; + ricsubscription_fail_s& sub_resp = failure.value.ricsubscription_fail(); + + sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; + sub_resp->ri_crequest_id.id = ASN1_E2AP_ID_RI_CREQUEST_ID; + sub_resp->ri_crequest_id.value.ric_requestor_id = ric_subscription_reponse.ric_requestor_id; + sub_resp->ri_crequest_id.value.ric_instance_id = ric_subscription_reponse.ric_instance_id; + + sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; + sub_resp->ra_nfunction_id.id = ASN1_E2AP_ID_RA_NFUNCTION_ID; + sub_resp->ra_nfunction_id->value = ric_subscription_reponse.ra_nfunction_id; + + sub_resp->cause->set_misc(); // TODO: set the cause and crit_diagnostics properly + sub_resp->crit_diagnostics_present = false; + + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_delete_response(ric_subscription_reponse_t ric_subscription_reponse) +{ + e2_ap_pdu_c pdu; + successful_outcome_s& success = pdu.set_successful_outcome(); + success.load_info_obj(ASN1_E2AP_ID_RICSUBSCRIPTION_DELETE); + success.crit = asn1::crit_opts::reject; + ricsubscription_delete_resp_s& sub_resp = success.value.ricsubscription_delete_resp(); + + sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; + sub_resp->ri_crequest_id->ric_requestor_id = ric_subscription_reponse.ric_requestor_id; + sub_resp->ri_crequest_id->ric_instance_id = ric_subscription_reponse.ric_instance_id; + + sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; + sub_resp->ra_nfunction_id->value = ric_subscription_reponse.ra_nfunction_id; + + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_delete_failure(ric_subscription_reponse_t ric_subscription_reponse) +{ + e2_ap_pdu_c pdu; + unsuccessful_outcome_s& failure = pdu.set_unsuccessful_outcome(); + failure.load_info_obj(ASN1_E2AP_ID_RICSUBSCRIPTION); + failure.crit = asn1::crit_opts::reject; + ricsubscription_delete_fail_s& sub_resp = failure.value.ricsubscription_delete_fail(); + + sub_resp->ri_crequest_id.crit = asn1::crit_opts::reject; + sub_resp->ri_crequest_id.id = ASN1_E2AP_ID_RI_CREQUEST_ID; + sub_resp->ri_crequest_id.value.ric_requestor_id = ric_subscription_reponse.ric_requestor_id; + sub_resp->ri_crequest_id.value.ric_instance_id = ric_subscription_reponse.ric_instance_id; + + sub_resp->ra_nfunction_id.crit = asn1::crit_opts::reject; + sub_resp->ra_nfunction_id.id = ASN1_E2AP_ID_RA_NFUNCTION_ID; + sub_resp->ra_nfunction_id->value = ric_subscription_reponse.ra_nfunction_id; + + sub_resp->cause->set_misc(); // TODO: set the cause and crit_diagnostics properly + sub_resp->crit_diagnostics_present = false; + + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_delete_required(ric_subscription_reponse_t ric_subscription_reponse) +{ + // TODO: available in e2ap-v3 + e2_ap_pdu_c pdu; + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_modification_response() +{ + // TODO: available in e2ap-v3 + e2_ap_pdu_c pdu; + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_modification_failure() +{ + // TODO: available in e2ap-v3 + e2_ap_pdu_c pdu; + return pdu; +} + +e2_ap_pdu_c e2ap::generate_subscription_modification_required() +{ + // TODO: available in e2ap-v3 + e2_ap_pdu_c pdu; + return pdu; +} + +int e2ap::process_setup_response(e2setup_resp_s setup_response) +{ + if (setup_response->transaction_id.value.value == 0) { + // TODO: transaction_id reset? check specs + setup_procedure_transaction_id = 0; + } + + if (setup_procedure_transaction_id == setup_response->transaction_id.value.value) { + setup_procedure_transaction_id++; + e2_established = true; + } else { + logger.error("Received setup response with wrong transaction id"); + return SRSRAN_ERROR; + } + global_ric_id.plmn_id = setup_response->global_ric_id.value.plmn_id.to_number(); + global_ric_id.ric_id = setup_response->global_ric_id.value.ric_id.to_number(); + + if (setup_response->ra_nfunctions_accepted_present) { + for (int i = 0; i < (int)setup_response->ra_nfunctions_accepted.value.size(); i++) { + uint32_t ran_func_id = setup_response->ra_nfunctions_accepted.value[i]->ra_nfunction_id_item().ran_function_id; + if (ran_functions.find(ran_func_id) == ran_functions.end()) { + logger.error("Received setup response with unknown ran function id %d", ran_func_id); + } else { + logger.info("Received setup response with ran function id %d", ran_func_id); + ran_functions[ran_func_id].accepted = true; + } + } + } + return SRSRAN_SUCCESS; +} + +int e2ap::process_subscription_request(ricsubscription_request_s ric_subscription_request) +{ + std::unique_ptr new_ric_subs = + std::make_unique(this, ric_subscription_request); + + if (new_ric_subs->is_initialized()) { + new_ric_subs->start_subscription(); + active_subscriptions.push_back(std::move(new_ric_subs)); + } else { + return false; + } + + return SRSRAN_SUCCESS; +} + +int e2ap::process_subscription_delete_request(ricsubscription_delete_request_s ricsubscription_delete_request) +{ + bool ric_subs_found = false; + for (auto it = active_subscriptions.begin(); it != active_subscriptions.end(); it++) { + if ((**it).get_ric_requestor_id() == ricsubscription_delete_request->ri_crequest_id->ric_requestor_id and + (**it).get_ric_instance_id() == ricsubscription_delete_request->ri_crequest_id->ric_instance_id) { + ric_subs_found = true; + (**it).delete_subscription(); + active_subscriptions.erase(it); + break; + } + } + + if (not ric_subs_found) { + // TODO: send failure + } + + return SRSRAN_SUCCESS; +} + +int e2ap::process_subscription_modification_request(uint32_t ric_subscription_modification_request) +{ + // TODO: implement, here only placeholder + return SRSRAN_SUCCESS; +} + +int e2ap::process_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm) +{ + // TODO: implement, here only placeholder + return SRSRAN_SUCCESS; +} + +int e2ap::process_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse) +{ + // TODO: implement, here only placeholder + return SRSRAN_SUCCESS; +} + +e2_ap_pdu_c e2ap::generate_indication(ric_indication_t& ric_indication) +{ + using namespace asn1::e2ap; + e2_ap_pdu_c pdu; + + init_msg_s& initmsg = pdu.set_init_msg(); + initmsg.load_info_obj(ASN1_E2AP_ID_RI_CIND); + initmsg.crit = asn1::crit_opts::reject; + + ri_cind_s& indication = initmsg.value.ri_cind(); + indication->ri_crequest_id.crit = asn1::crit_opts::reject; + indication->ri_crequest_id.value.ric_requestor_id = ric_indication.ric_requestor_id; + indication->ri_crequest_id.value.ric_instance_id = ric_indication.ric_instance_id; + + indication->ra_nfunction_id.crit = asn1::crit_opts::reject; + indication->ra_nfunction_id.value = ric_indication.ra_nfunction_id; + + indication->ri_caction_id.crit = asn1::crit_opts::reject; + indication->ri_caction_id.value = ric_indication.ri_caction_id; + + if (ric_indication.ri_indication_sn_present) { + indication->ri_cind_sn_present = true; + indication->ri_cind_sn.crit = asn1::crit_opts::reject; + indication->ri_cind_sn->value = ric_indication.ri_indication_sn; + } + + indication->ri_cind_type.crit = asn1::crit_opts::reject; + indication->ri_cind_type.value = ric_indication.indication_type; + + indication->ri_cind_hdr.crit = asn1::crit_opts::reject; + indication->ri_cind_hdr->resize(ric_indication.ri_cind_hdr->N_bytes); + std::copy(ric_indication.ri_cind_hdr->msg, + ric_indication.ri_cind_hdr->msg + ric_indication.ri_cind_hdr->N_bytes, + indication->ri_cind_hdr->data()); + + indication->ri_cind_msg.crit = asn1::crit_opts::reject; + indication->ri_cind_msg->resize(ric_indication.ri_cind_msg->N_bytes); + std::copy(ric_indication.ri_cind_msg->msg, + ric_indication.ri_cind_msg->msg + ric_indication.ri_cind_msg->N_bytes, + indication->ri_cind_msg->data()); + + return pdu; +} + +e2_ap_pdu_c e2ap::generate_reset_request() +{ + using namespace asn1::e2ap; + e2_ap_pdu_c pdu; + init_msg_s& request = pdu.set_init_msg(); + request.load_info_obj(ASN1_E2AP_ID_RESET); + reset_request_s& reset_request = request.value.reset_request(); + reset_request->transaction_id.crit = asn1::crit_opts::reject; + reset_request->transaction_id.value.value = reset_transaction_id; + reset_request->cause.crit = asn1::crit_opts::ignore; + reset_request->cause.value.set_misc(); + return pdu; +} + +e2_ap_pdu_c e2ap::generate_reset_response() +{ + e2_ap_pdu_c pdu; + successful_outcome_s& response = pdu.set_successful_outcome(); + response.load_info_obj(ASN1_E2AP_ID_RESET); + reset_resp_s& reset_response = response.value.reset_resp(); + reset_response->transaction_id.crit = asn1::crit_opts::reject; + reset_response->transaction_id.value.value = reset_transaction_id; + return pdu; +} + +int e2ap::process_reset_request(reset_request_s reset_request) +{ + reset_id = reset_request->transaction_id.value; + + // TODO: Parse and store the cause for future extension of the e2_agent + + return SRSRAN_SUCCESS; +} + +int e2ap::process_reset_response(reset_resp_s reset_response) +{ + // TO DO process reset response from RIC + reset_response_received = true; + + return SRSRAN_SUCCESS; +} + +int e2ap::get_reset_id() +{ + return reset_id; +} + +// implementation of e2ap failure functions +int e2ap::process_e2_setup_failure(e2setup_fail_s e2setup_failure) +{ + if (e2setup_failure->transaction_id.value.value == 0) { + // TODO: transaction_id reset? check specs + setup_procedure_transaction_id = 0; + } + + if (setup_procedure_transaction_id == e2setup_failure->transaction_id.value.value) { + setup_procedure_transaction_id++; + } else { + logger.error("Received setup failure with wrong transaction id"); + } + if (e2setup_failure->tn_linfo_present) { + logger.error("Received setup failure with transport layer info"); + } + if (e2setup_failure->time_to_wait_present) { + logger.error("Received setup failure with time to wait"); + e2_procedure_timeout.set(e2setup_failure->time_to_wait.value.to_number(), [this](int trans_id) { + logger.info("E2AP procedure timeout expired transaction id %d", trans_id); + pending_e2_setup = false; + }); + e2_procedure_timeout.run(); + } + return SRSRAN_SUCCESS; +} + +int e2ap::process_e2_node_config_update_failure(e2node_cfg_upd_fail_s e2node_config_update_failure) +{ + pending_e2_node_config_update = false; + + return SRSRAN_SUCCESS; +} + +int e2ap::process_ric_service_update_failure(ricservice_upd_fail_s service_update_failure) +{ + pending_ric_service_update = false; + + return SRSRAN_SUCCESS; +} + +int e2ap::process_e2_removal_failure(e2_removal_fail_s e2removal_failure) +{ + pending_e2_removal = false; + + return SRSRAN_SUCCESS; +} diff --git a/srsgnb/src/stack/ric/e2ap_ric_subscription.cc b/srsgnb/src/stack/ric/e2ap_ric_subscription.cc new file mode 100644 index 0000000000..43698b1649 --- /dev/null +++ b/srsgnb/src/stack/ric/e2ap_ric_subscription.cc @@ -0,0 +1,226 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/ric/e2ap_ric_subscription.h" + +e2ap::ric_subscription::ric_subscription(e2ap* e2ap, ricsubscription_request_s ric_subscription_request) : + parent(e2ap), + initialized(false), + ric_requestor_id(ric_subscription_request->ri_crequest_id->ric_requestor_id), + ric_instance_id(ric_subscription_request->ri_crequest_id->ric_instance_id), + ra_nfunction_id(ric_subscription_request->ra_nfunction_id->value), + reporting_timer(parent->task_sched_ptr->get_unique_timer()) +{ + RANfunction_description ran_func_desc; + if (!parent->get_func_desc(ra_nfunction_id, ran_func_desc)) { + parent->logger.debug("Cannot find RAN function with ID: %i\n", ra_nfunction_id); + this->_send_subscription_failure(); + return; + } + + sm_ptr = ran_func_desc.sm_ptr; + if (sm_ptr == nullptr) { + parent->logger.debug("No valid pointer to SM with RAN function id: %i\n", ra_nfunction_id); + this->_send_subscription_failure(); + return; + } + + RIC_event_trigger_definition_t event_trigger; + if (sm_ptr->process_ric_event_trigger_definition(ric_subscription_request, event_trigger)) { + if (event_trigger.type == RIC_event_trigger_definition_t::e2sm_event_trigger_type_t::E2SM_REPORT) { + reporting_period = event_trigger.report_period; + reporting_period = 3000; // TODO: to remove, keep it 3s for testing + } + } + + ri_cactions_to_be_setup_list_l& action_list = + ric_subscription_request->ricsubscription_details->ric_action_to_be_setup_list; + + for (uint32_t i = 0; i < action_list.size(); i++) { + ri_caction_to_be_setup_item_s action_item = action_list[i]->ri_caction_to_be_setup_item(); + + E2AP_RIC_action_t candidate_action; + candidate_action.ric_action_id = action_item.ric_action_id; + candidate_action.ric_action_type = action_item.ric_action_type; + + if (sm_ptr->process_ric_action_definition(action_item, candidate_action)) { + parent->logger.debug("Admitted action %i (type: %i), mapped to SM local action ID: %i", + candidate_action.ric_action_id, + candidate_action.ric_action_type, + candidate_action.sm_local_ric_action_id); + + printf("Admitted action %i, mapped to SM local action ID: %i\n", + candidate_action.ric_action_id, + candidate_action.sm_local_ric_action_id); + + admitted_actions.push_back(candidate_action); + + if (action_item.ric_subsequent_action_present) { + parent->logger.debug("--Action %i (type: %i) contains subsequent action of type %i with wait time: %i", + action_item.ric_action_id, + action_item.ric_action_type, + action_item.ric_subsequent_action.ric_subsequent_action_type, + action_item.ric_subsequent_action.ric_time_to_wait); + } + } else { + parent->logger.debug("Not admitted action %i (type: %i)", action_item.ric_action_id, action_item.ric_action_type); + not_admitted_actions.push_back(action_item.ric_action_id); + } + } + + if (admitted_actions.size() == 0) { + parent->logger.debug("No Action admitted -> remove subscription for RAN function id: %i", ra_nfunction_id); + printf("No Action admitted -> remove subscription for RAN function id: %i\n", ra_nfunction_id); + this->_send_subscription_failure(); + return; + } + + initialized = true; +} + +void e2ap::ric_subscription::start_subscription() +{ + this->_send_subscription_response(); + + if (reporting_period) { + printf("Start sending RIC indication msgs every %i ms\n", reporting_period); + parent->logger.debug("Start sending RIC indication msgs every %i ms", reporting_period); + reporting_timer.set(reporting_period, [this](uint32_t tid) { _send_ric_indication(); }); + reporting_timer.run(); + } +} + +void e2ap::ric_subscription::_send_subscription_response() +{ + parent->logger.debug("Send RIC Subscription Response to RIC Requestor ID: %i\n", ric_requestor_id); + ric_subscription_reponse_t ric_subscription_reponse; + ric_subscription_reponse.ric_requestor_id = ric_requestor_id; + ric_subscription_reponse.ric_instance_id = ric_instance_id; + ric_subscription_reponse.ra_nfunction_id = ra_nfunction_id; + + for (auto& action : admitted_actions) { + ric_subscription_reponse.admitted_actions.push_back(action.ric_action_id); + } + + for (auto& action : not_admitted_actions) { + ric_subscription_reponse.not_admitted_actions.push_back(action); + } + + e2_ap_pdu_c send_pdu = parent->generate_subscription_response(ric_subscription_reponse); + parent->queue_send_e2ap_pdu(send_pdu); +} + +void e2ap::ric_subscription::_send_subscription_failure() +{ + parent->logger.debug("Send RIC Subscription Failure Response to RIC Requestor ID: %i\n", ric_requestor_id); + ric_subscription_reponse_t ric_subscription_reponse; + ric_subscription_reponse.ric_requestor_id = ric_requestor_id; + ric_subscription_reponse.ric_instance_id = ric_instance_id; + ric_subscription_reponse.ra_nfunction_id = ra_nfunction_id; + + e2_ap_pdu_c send_pdu = parent->generate_subscription_failure(ric_subscription_reponse); + parent->queue_send_e2ap_pdu(send_pdu); +} + +void e2ap::ric_subscription::delete_subscription() +{ + if (reporting_timer.is_running()) { + parent->logger.debug("Stop sending RIC indication msgs"); + reporting_timer.stop(); + } + + ric_subscription_reponse_t ric_subscription_reponse; + ric_subscription_reponse.ric_requestor_id = ric_requestor_id; + ric_subscription_reponse.ric_instance_id = ric_instance_id; + ric_subscription_reponse.ra_nfunction_id = ra_nfunction_id; + + // remove registered actions from SM + if (sm_ptr) { + for (auto& action : admitted_actions) { + sm_ptr->remove_ric_action_definition(action); + } + } else { + e2_ap_pdu_c send_pdu = parent->generate_subscription_delete_failure(ric_subscription_reponse); + parent->queue_send_e2ap_pdu(send_pdu); + return; + } + + parent->logger.debug("Send RIC Subscription Delete Response to RIC Requestor ID: %i\n", ric_requestor_id); + + e2_ap_pdu_c send_pdu = parent->generate_subscription_delete_response(ric_subscription_reponse); + parent->queue_send_e2ap_pdu(send_pdu); +} + +bool e2ap::ric_subscription::process_subscription_modification_request(uint32_t ric_subscription_modification_request) +{ + // TODO: implement, currently not supported in ans1 + return false; +} + +bool e2ap::ric_subscription::process_subscription_modification_confirm(uint32_t ric_subscription_modification_confirm) +{ + // TODO: implement, currently not supported in ans1 + return false; +} + +bool e2ap::ric_subscription::process_subscription_modification_refuse(uint32_t ric_subscription_modification_refuse) +{ + // TODO: implement, currently not supported in ans1 + return false; +} + +uint32_t e2ap::ric_subscription::_generate_ric_indication_sn() +{ + uint32_t sn = _ric_indication_sn_gen; + _ric_indication_sn_gen++; + if (_ric_indication_sn_gen > 65535) { + _ric_indication_sn_gen = 0; + } + return sn; +}; + +void e2ap::ric_subscription::_send_ric_indication() +{ + if (sm_ptr == nullptr) { + parent->logger.error("SM pointer not set in subscription: %i\n", ric_requestor_id); + return; + } + + for (auto& action : admitted_actions) { + printf("Sending RIC indication msg to RIC Requestor ID: %i\n", ric_requestor_id); + ric_indication_t ric_indication; + ric_indication.ric_requestor_id = ric_requestor_id; + ric_indication.ric_instance_id = ric_instance_id; + ric_indication.ra_nfunction_id = ra_nfunction_id; + ric_indication.ri_caction_id = action.ric_action_id; + ric_indication.ri_indication_sn_present = true; + ric_indication.ri_indication_sn = _generate_ric_indication_sn(); + if (sm_ptr->generate_ric_indication_content(action, ric_indication)) { + e2_ap_pdu_c send_pdu = parent->generate_indication(ric_indication); + parent->queue_send_e2ap_pdu(send_pdu); + } + } + + // reschedule sending RIC indication + if (reporting_period) { + reporting_timer.run(); + } +} \ No newline at end of file diff --git a/srsgnb/src/stack/ric/e2sm_kpm.cc b/srsgnb/src/stack/ric/e2sm_kpm.cc new file mode 100644 index 0000000000..e8ff386ecf --- /dev/null +++ b/srsgnb/src/stack/ric/e2sm_kpm.cc @@ -0,0 +1,460 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/ric/e2sm_kpm.h" +#include "srsgnb/hdr/stack/ric/e2sm_kpm_metrics.h" +#include "srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h" +#include + +const std::string e2sm_kpm::short_name = "ORAN-E2SM-KPM"; +const std::string e2sm_kpm::oid = "1.3.6.1.4.1.53148.1.2.2.2"; +const std::string e2sm_kpm::func_description = "KPM Monitor"; +const uint32_t e2sm_kpm::revision = 0; + +e2sm_kpm::e2sm_kpm(srslog::basic_logger& logger_, srsran::task_scheduler* _task_sched_ptr) : + e2sm(short_name, oid, func_description, revision, _task_sched_ptr), logger(logger_) +{ + random_gen = srsran_random_init(1234); + + // add supported metrics + for (auto& metric : get_e2sm_kpm_28_552_metrics()) { + if (metric.supported) { + supported_meas_types.push_back(metric); + } + } + for (auto& metric : get_e2sm_kpm_34_425_metrics()) { + if (metric.supported) { + supported_meas_types.push_back(metric); + } + } + for (auto& metric : e2sm_kpm_oran_metrics()) { + if (metric.supported) { + supported_meas_types.push_back(metric); + } + } + for (auto& metric : e2sm_kpm_custom_metrics()) { + if (metric.supported) { + supported_meas_types.push_back(metric); + } + } +} + +e2sm_kpm::~e2sm_kpm() +{ + srsran_random_free(random_gen); +} +bool e2sm_kpm::generate_ran_function_description(RANfunction_description& desc, ra_nfunction_item_s& ran_func) +{ + desc.function_shortname = short_name; + desc.function_e2_sm_oid = oid; + desc.function_desc = func_description; + + e2_sm_kpm_ra_nfunction_description_s e2sm_kpm_ra_nfunction_description; + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_short_name.from_string(short_name.c_str()); + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_e2_sm_oid.from_string(oid.c_str()); + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_description.from_string(func_description.c_str()); + if (desc.function_instance) { + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_instance_present = true; + e2sm_kpm_ra_nfunction_description.ran_function_name.ran_function_instance = desc.function_instance; + } + + // O-RAN.WG3.E2SM-KPM-R003-v03.00, 7.3.1 Event Trigger Style Types + auto& event_trigger_style_list = e2sm_kpm_ra_nfunction_description.ric_event_trigger_style_list; + event_trigger_style_list.resize(1); + event_trigger_style_list[0].ric_event_trigger_style_type = 1; + event_trigger_style_list[0].ric_event_trigger_style_name.from_string("Periodic report"); + event_trigger_style_list[0].ric_event_trigger_format_type = 1; // uses RIC Event Trigger Definition Format 1 + + // O-RAN.WG3.E2SM-KPM-R003-v03.00, 7.4.1 REPORT Service Style Type + auto& report_style_list = e2sm_kpm_ra_nfunction_description.ric_report_style_list; + report_style_list.resize(1); + + report_style_list[0].ric_report_style_type = 1; + report_style_list[0].ric_report_style_name.from_string("E2 Node Measurement"); + report_style_list[0].ric_action_format_type = 1; + report_style_list[0].ric_ind_hdr_format_type = 1; + report_style_list[0].ric_ind_msg_format_type = 1; + + std::vector supported_enb_meas = _get_supported_meas(ENB_LEVEL | CELL_LEVEL); + for (const auto& metric : supported_enb_meas) { + meas_info_action_item_s meas_info_item; + meas_info_item.meas_name.from_string(metric.c_str()); + report_style_list[0].meas_info_action_list.push_back(meas_info_item); + break; // TODO: add only one as flexric does not like long setup_request msg and crashes + } + + /* TODO: seems that flexric does not like long setup_request msg and crashes, note: wireshark decodes it correctly + // see: nearRT-RIC: flexric/src/ric/msg_handler_ric.c:88: + // generate_setup_response: Assertion `req->ran_func_item[i].def.len < 127' failed + report_style_list[1].ric_report_style_type = 2; + report_style_list[1].ric_report_style_name.from_string("E2 Node Measurement for a single UE"); + report_style_list[1].ric_action_format_type = 2; + report_style_list[1].ric_ind_hdr_format_type = 1; + report_style_list[1].ric_ind_msg_format_type = 1; + // TODO: add all supported UE LEVEL metrics + report_style_list[1].meas_info_action_list.resize(1); + report_style_list[1].meas_info_action_list[0].meas_name.from_string("RRU.PrbTotDl"); + // A measurement ID can be used for subscription instead of a measurement type if an identifier of a certain + // measurement type was exposed by an E2 Node via the RAN Function Definition IE. + // measurement name to ID mapping (local to the E2 node), here only an example: + // report_style_list[1].meas_info_action_list[0].meas_id = 123; + + report_style_list[2].ric_report_style_type = 3; + report_style_list[2].ric_report_style_name.from_string("Condition-based, UE-level E2 Node Measurement"); + report_style_list[2].ric_action_format_type = 3; + report_style_list[2].ric_ind_hdr_format_type = 1; + report_style_list[2].ric_ind_msg_format_type = 2; + // TODO: add all supported UE LEVEL metrics + report_style_list[2].meas_info_action_list.resize(1); + report_style_list[2].meas_info_action_list[0].meas_name.from_string("RRU.PrbTotDl"); + + report_style_list[3].ric_report_style_type = 4; + report_style_list[3].ric_report_style_name.from_string("Common Condition-based, UE-level Measurement"); + report_style_list[3].ric_action_format_type = 4; + report_style_list[3].ric_ind_hdr_format_type = 1; + report_style_list[3].ric_ind_msg_format_type = 3; + // TODO: add all supported UE LEVEL metrics + report_style_list[3].meas_info_action_list.resize(1); + report_style_list[3].meas_info_action_list[0].meas_name.from_string("RRU.PrbTotDl"); + + report_style_list[4].ric_report_style_type = 5; + report_style_list[4].ric_report_style_name.from_string("E2 Node Measurement for multiple UEs"); + report_style_list[4].ric_action_format_type = 5; + report_style_list[4].ric_ind_hdr_format_type = 1; + report_style_list[4].ric_ind_msg_format_type = 3; + // TODO: add all supported UE LEVEL metrics + report_style_list[4].meas_info_action_list.resize(1); + report_style_list[4].meas_info_action_list[0].meas_name.from_string("RRU.PrbTotDl"); + */ + logger.info("Generating RAN function description"); + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (e2sm_kpm_ra_nfunction_description.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("Failed to pack TX E2 PDU\n"); + return false; + } + buf->N_bytes = bref.distance_bytes(); + + ran_func.ran_function_definition.resize(buf->N_bytes); + std::copy(buf->msg, buf->msg + buf->N_bytes, ran_func.ran_function_definition.data()); + + return true; +} + +bool e2sm_kpm::process_ric_event_trigger_definition(ricsubscription_request_s subscription_request, + RIC_event_trigger_definition_t& event_def) +{ + e2_sm_kpm_event_trigger_definition_s trigger_def; + asn1::cbit_ref bref(subscription_request->ricsubscription_details->ric_event_trigger_definition.data(), + subscription_request->ricsubscription_details->ric_event_trigger_definition.size()); + + if (trigger_def.unpack(bref) != asn1::SRSASN_SUCCESS) { + return false; + } + + event_def.type = RIC_event_trigger_definition_t::e2sm_event_trigger_type_t::E2SM_REPORT; + event_def.report_period = trigger_def.event_definition_formats.event_definition_format1().report_period; + return true; +} + +bool e2sm_kpm::process_ric_action_definition(ri_caction_to_be_setup_item_s ric_action, E2AP_RIC_action_t& action_entry) +{ + bool admit_action = false; + e2_sm_kpm_action_definition_s e2sm_kpm_action_def; + asn1::cbit_ref bref(ric_action.ric_action_definition.data(), ric_action.ric_action_definition.size()); + + if (e2sm_kpm_action_def.unpack(bref) != asn1::SRSASN_SUCCESS) { + return false; + } + + action_entry.sm_local_ric_action_id = _get_local_action_id(); + e2sm_kpm_report_service* report_service; + + switch (e2sm_kpm_action_def.ric_style_type) { + case 1: + admit_action = e2sm_kpm_report_service_style1::process_ric_action_definition(this, e2sm_kpm_action_def); + if (admit_action) { + report_service = + new e2sm_kpm_report_service_style1(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); + } + break; + case 2: + admit_action = e2sm_kpm_report_service_style2::process_ric_action_definition(this, e2sm_kpm_action_def); + if (admit_action) { + report_service = + new e2sm_kpm_report_service_style2(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); + } + break; + case 3: + admit_action = e2sm_kpm_report_service_style3::process_ric_action_definition(this, e2sm_kpm_action_def); + if (admit_action) { + report_service = + new e2sm_kpm_report_service_style3(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); + } + break; + case 4: + admit_action = e2sm_kpm_report_service_style4::process_ric_action_definition(this, e2sm_kpm_action_def); + if (admit_action) { + report_service = + new e2sm_kpm_report_service_style4(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); + } + break; + case 5: + admit_action = e2sm_kpm_report_service_style5::process_ric_action_definition(this, e2sm_kpm_action_def); + if (admit_action) { + report_service = + new e2sm_kpm_report_service_style5(this, action_entry.sm_local_ric_action_id, e2sm_kpm_action_def); + } + break; + default: + logger.info("Unknown RIC style type %i -> do not admit action %i (type %i)", + e2sm_kpm_action_def.ric_style_type, + ric_action.ric_action_id, + ric_action.ric_action_type); + return false; + } + + if (not admit_action) { + return false; + } + + _generate_new_local_action_id(); + + registered_actions_data.insert( + std::pair(action_entry.sm_local_ric_action_id, report_service)); + + return admit_action; +} + +bool e2sm_kpm::remove_ric_action_definition(E2AP_RIC_action_t& action_entry) +{ + if (registered_actions_data.count(action_entry.sm_local_ric_action_id)) { + registered_actions_data.at(action_entry.sm_local_ric_action_id)->stop(); + delete registered_actions_data.at(action_entry.sm_local_ric_action_id); + registered_actions_data.erase(action_entry.sm_local_ric_action_id); + return true; + } + return false; +} + +bool e2sm_kpm::generate_ric_indication_content(E2AP_RIC_action_t& action_entry, ric_indication_t& ric_indication) +{ + uint32_t action_id = action_entry.sm_local_ric_action_id; + if (!registered_actions_data.count(action_id)) { + logger.info("Unknown RIC action ID: %i (type %i) (SM local RIC action ID: %i)", + action_entry.ric_action_id, + action_entry.ric_action_type, + action_entry.sm_local_ric_action_id); + return false; + } + e2sm_kpm_report_service* report_service = registered_actions_data.at(action_id); + + if (not report_service->is_ric_ind_ready()) { + return false; + } + + ric_indication.indication_type = ri_cind_type_opts::report; + + // header is the same for all RIC service styles, i.e., type 1 + ric_indication.ri_cind_hdr = srsran::make_byte_buffer(); + this->_generate_indication_header(report_service->get_ind_hdr(), ric_indication.ri_cind_hdr); + + logger.info("Generating E2-SM-KPM Indication Message"); + ric_indication.ri_cind_msg = srsran::make_byte_buffer(); + this->_generate_indication_message(report_service->get_ind_msg(), ric_indication.ri_cind_msg); + + // clear data collected for this action + report_service->clear_collected_data(); + return true; +} + +bool e2sm_kpm::_generate_indication_header(e2_sm_kpm_ind_hdr_s& hdr, srsran::unique_byte_buffer_t& buf) +{ + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (hdr.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("IND HEADER: Failed to pack TX E2 PDU\n"); + return false; + } + buf->N_bytes = bref.distance_bytes(); + + return true; +} + +bool e2sm_kpm::_generate_indication_message(e2_sm_kpm_ind_msg_s& msg, srsran::unique_byte_buffer_t& buf) +{ + logger.info("Generating E2-SM-KPM Indication Message"); + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (msg.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("IND MSG: Failed to pack TX E2 PDU\n"); + return false; + } + buf->N_bytes = bref.distance_bytes(); + + return true; +} + +bool e2sm_kpm::_get_meas_definition(std::string meas_name, e2sm_kpm_metric_t& def) +{ + auto name_matches = [&meas_name](const e2sm_kpm_metric_t& x) { + return (x.name == meas_name.c_str() or x.name == meas_name); + }; + auto it = std::find_if(supported_meas_types.begin(), supported_meas_types.end(), name_matches); + if (it == supported_meas_types.end()) { + return false; + } + def = *it; + return true; +} + +std::vector e2sm_kpm::_get_supported_meas(uint32_t level_mask) +{ + std::vector supported_meas; + for (auto& metric : supported_meas_types) { + if ((level_mask & ENB_LEVEL) and (metric.supported_scopes & ENB_LEVEL)) { + supported_meas.push_back(metric.name); + } else if ((level_mask & CELL_LEVEL) and (metric.supported_scopes & CELL_LEVEL)) { + supported_meas.push_back(metric.name); + } else if ((level_mask & UE_LEVEL) and (metric.supported_scopes & UE_LEVEL)) { + supported_meas.push_back(metric.name); + } else if ((level_mask & BEARER_LEVEL) and (metric.supported_scopes & BEARER_LEVEL)) { + supported_meas.push_back(metric.name); + } + } + + return supported_meas; +} + +void e2sm_kpm::receive_e2_metrics_callback(const enb_metrics_t& m) +{ + last_enb_metrics = m; + logger.debug("e2sm_kpm received new enb metrics, CPU0 Load: %.1f", last_enb_metrics.sys.cpu_load[0]); +} + +bool e2sm_kpm::_collect_meas_value(e2sm_kpm_meas_def_t& meas_value, meas_record_item_c& item) +{ + // here we implement logic of measurement data collection, currently we only read from enb_metrics + if (meas_value.data_type == meas_record_item_c::types::options::integer) { + uint32_t value; + if (_extract_integer_type_meas_value(meas_value, last_enb_metrics, value)) { + item.set_integer() = value; + return true; + } + } else { + // data_type == meas_record_item_c::types::options::real; + float value; + if (_extract_real_type_meas_value(meas_value, last_enb_metrics, value)) { + real_s real_value; + // TODO: real value seems to be not supported in asn1??? + // real_value.value = value; + item.set_real() = real_value; + return true; + } + } + + return false; +} + +bool e2sm_kpm::_extract_integer_type_meas_value(e2sm_kpm_meas_def_t& meas_value, + const enb_metrics_t& enb_metrics, + uint32_t& value) +{ + // TODO: maybe add ID to metric types in e2sm_kpm_metrics definitions, so we do not have to compare strings? + // TODO: make string comparison case insensitive + // all integer type measurements + // test: no_label + if (meas_value.name.c_str() == std::string("test")) { + switch (meas_value.label) { + case NO_LABEL: + if (meas_value.scope & ENB_LEVEL) { + value = (int32_t)enb_metrics.sys.cpu_load[0]; + printf("extract last \"test\" value as int, (filled with ENB_LEVEL metric: CPU0_load) value %i \n", value); + return true; + } + if (meas_value.scope & CELL_LEVEL) { + uint32_t cell_id = meas_value.cell_id; + value = (int32_t)enb_metrics.stack.mac.cc_info[cell_id].cc_rach_counter; + printf("extract last \"test\" value as int, (filled with CELL_LEVEL metric: cc_rach_counter) value %i \n", + value); + return true; + } + if (meas_value.scope & UE_LEVEL) { + uint32_t ue_id = meas_value.ue_id; + value = (int32_t)enb_metrics.stack.mac.ues[ue_id].ul_rssi; + printf("extract last \"test\" value as int, (filled with UE_LEVEL metric: ul_rssi) value %i \n", value); + return true; + } + default: + return false; + } + } + + // random_int: no_label + if (meas_value.name.c_str() == std::string("random_int")) { + switch (meas_value.label) { + case NO_LABEL: + value = srsran_random_uniform_int_dist(random_gen, 0, 100); + printf("extract last \"random_int\" value as int, random value %i \n", value); + return true; + default: + return false; + } + } + + return false; +} + +bool e2sm_kpm::_extract_real_type_meas_value(e2sm_kpm_meas_def_t& meas_value, + const enb_metrics_t& enb_metrics, + float& value) +{ + // all real type measurements + // cpu0_load: no_label + if (meas_value.name.c_str() == std::string("cpu0_load")) { + switch (meas_value.label) { + case NO_LABEL: + value = enb_metrics.sys.cpu_load[0]; + return true; + default: + return false; + } + } + + // cpu_load: min,max,avg + if (meas_value.name.c_str() == std::string("cpu_load")) { + uint32_t size; + switch (meas_value.label) { + case MIN_LABEL: + value = *std::min_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); + return true; + case MAX_LABEL: + value = *std::max_element(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end()); + return true; + case AVG_LABEL: + size = enb_metrics.sys.cpu_load.size(); + value = std::accumulate(enb_metrics.sys.cpu_load.begin(), enb_metrics.sys.cpu_load.end(), 0.0 / size); + return true; + default: + return false; + } + } + + return false; +} \ No newline at end of file diff --git a/srsgnb/src/stack/ric/e2sm_kpm_common.cc b/srsgnb/src/stack/ric/e2sm_kpm_common.cc new file mode 100644 index 0000000000..3ee888ea32 --- /dev/null +++ b/srsgnb/src/stack/ric/e2sm_kpm_common.cc @@ -0,0 +1,40 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/ric/e2sm_kpm_common.h" + +std::string e2sm_kpm_label_2_str(e2sm_kpm_label_enum label) +{ + switch (label) { + case NO_LABEL: + return "NO_LABEL"; + case MIN_LABEL: + return "MIN_LABEL"; + case MAX_LABEL: + return "MAX_LABEL"; + case AVG_LABEL: + return "AVG_LABEL"; + case SUM_LABEL: + return "SUM_LABEL"; + default: + return "UNKNOWN_LABEL"; + } +} \ No newline at end of file diff --git a/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc new file mode 100644 index 0000000000..f6ce7f1462 --- /dev/null +++ b/srsgnb/src/stack/ric/e2sm_kpm_report_service.cc @@ -0,0 +1,593 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/ric/e2sm_kpm_report_service.h" + +e2sm_kpm_report_service::e2sm_kpm_report_service(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + parent(e2sm_kpm), + action_id(action_id), + action_def_generic(action_definition), + ric_ind_header_generic(), + ric_ind_header(ric_ind_header_generic.ind_hdr_formats.ind_hdr_format1()), + meas_collection_timer(parent->task_sched_ptr->get_unique_timer()) +{ +} + +std::vector +e2sm_kpm_report_service::_get_present_labels(const meas_info_item_s& action_meas_info_item) +{ + std::vector labels; + // TODO: add all labels defined in e2sm_kpm doc + for (uint32_t l = 0; l < action_meas_info_item.label_info_list.size(); l++) { + if (action_meas_info_item.label_info_list[l].meas_label.no_label_present) { + labels.push_back(NO_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.min_present) { + labels.push_back(MIN_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.max_present) { + labels.push_back(MAX_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.avg_present) { + labels.push_back(AVG_LABEL); + } + if (action_meas_info_item.label_info_list[l].meas_label.sum_present) { + labels.push_back(SUM_LABEL); + } + } + return labels; +} + +bool e2sm_kpm_report_service::_initialize_ric_ind_hdr() +{ + // TODO: set the remaining fields properly (they are optional) + ric_ind_header.collet_start_time.from_number(std::time(0)); + // ric_ind_header.file_formatversion.from_string(hdr.file_formatversion); + // ric_ind_header.sender_name.from_string(hdr.sender_name); + // ric_ind_header.sender_type.from_string(hdr.sender_type); + // ric_ind_header.vendor_name.from_string(hdr.vendor_name); + return true; +} + +meas_record_item_c::types e2sm_kpm_report_service::_get_meas_data_type(std::string meas_name, + e2sm_kpm_label_enum label, + meas_record_l& meas_record_list) +{ + meas_record_item_c::types data_type = meas_record_item_c::types::options::nulltype; + // if no data collected check the type using metric definition + if (meas_record_list.size() == 0) { + e2sm_kpm_metric_t metric_definition; + if (not parent->_get_meas_definition(meas_name, metric_definition)) { + parent->logger.debug("No definition for measurement type \"%s\"", metric_definition.name); + return data_type; + } + if (metric_definition.data_type == INTEGER) { + data_type = meas_record_item_c::types::options::integer; + } else { + data_type = meas_record_item_c::types::options::real; + } + } else { + // check the data type of the first element in the list + data_type = meas_record_list[0].type(); + } + return data_type; +} + +bool e2sm_kpm_report_service::_start_meas_collection() +{ + if (granul_period) { + printf("Start collecting measurements every %i ms\n", granul_period); + parent->logger.debug("Start collecting measurements every every %i ms", granul_period); + meas_collection_timer.set(granul_period, [this](uint32_t tid) { this->_collect_meas_data(); }); + meas_collection_timer.run(); + return true; + } + return false; +} + +bool e2sm_kpm_report_service::stop() +{ + return _stop_meas_collection(); +} + +bool e2sm_kpm_report_service::_stop_meas_collection() +{ + if (meas_collection_timer.is_running()) { + printf("Stop collecting measurements every %i ms\n", granul_period); + parent->logger.debug("Stop collecting measurements every %i ms\n", granul_period); + meas_collection_timer.stop(); + return true; + } + return false; +} + +bool e2sm_kpm_report_service::_reschedule_meas_collection() +{ + if (granul_period) { + meas_collection_timer.run(); + return true; + } + return false; +} + +e2sm_kpm_report_service_style1::e2sm_kpm_report_service_style1(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + e2sm_kpm_report_service(e2sm_kpm, action_id, action_definition), + action_def(action_def_generic.action_definition_formats.action_definition_format1()), + ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format1()) +{ + ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + granul_period = action_def.granul_period; + cell_global_id_present = action_def.cell_global_id_present; + if (cell_global_id_present) { + cell_global_id = action_def.cell_global_id; + } + + this->_initialize_ric_ind_hdr(); + this->_initialize_ric_ind_msg(); + + granul_period = 1000; // TODO: overwrite for testing + _start_meas_collection(); +} + +bool e2sm_kpm_report_service_style1::_initialize_ric_ind_msg() +{ + meas_info_list_l action_meas_info_list = action_def.meas_info_list; + + // ric_ind_message.granul_period_present = true; + // ric_ind_message.granul_period = granul_period; // TODO: our asn1 has some issues with this field + ric_ind_message.granul_period = 0; + ric_ind_message.meas_info_list.resize(action_meas_info_list.size()); + ric_ind_message.meas_data.resize(action_meas_info_list.size()); + + // add measurement info + for (uint32_t i = 0; i < ric_ind_message.meas_info_list.size(); i++) { + // structs to fill + meas_info_item_s& meas_info_item = ric_ind_message.meas_info_list[i]; + + // measurements definition + meas_info_item_s& meas_def_item = action_meas_info_list[i]; + std::string meas_name = meas_def_item.meas_type.meas_name().to_string(); + + meas_info_item.meas_type.set_meas_name().from_string(meas_name.c_str()); + meas_info_item.label_info_list.resize(meas_def_item.label_info_list.size()); + + // TODO: add all labels defined in e2sm_kpm doc, make this part generic and put to the base class + for (uint32_t l = 0; l < meas_def_item.label_info_list.size(); l++) { + if (meas_def_item.label_info_list[l].meas_label.no_label_present) { + meas_info_item.label_info_list[l].meas_label.no_label_present = true; + meas_info_item.label_info_list[l].meas_label.no_label = meas_label_s::no_label_opts::true_value; + } + if (meas_def_item.label_info_list[l].meas_label.min_present) { + meas_info_item.label_info_list[l].meas_label.min_present = true; + meas_info_item.label_info_list[l].meas_label.min = meas_label_s::min_opts::true_value; + } + if (meas_def_item.label_info_list[l].meas_label.max_present) { + meas_info_item.label_info_list[l].meas_label.max_present = true; + meas_info_item.label_info_list[l].meas_label.max = meas_label_s::max_opts::true_value; + } + if (meas_def_item.label_info_list[l].meas_label.avg_present) { + meas_info_item.label_info_list[l].meas_label.avg_present = true; + meas_info_item.label_info_list[l].meas_label.avg = meas_label_s::avg_opts::true_value; + } + if (meas_def_item.label_info_list[l].meas_label.sum_present) { + meas_info_item.label_info_list[l].meas_label.sum_present = true; + meas_info_item.label_info_list[l].meas_label.sum = meas_label_s::sum_opts::true_value; + } + } + } + + return true; +} + +bool e2sm_kpm_report_service_style1::process_ric_action_definition(e2sm_kpm* e2sm_kpm, + e2_sm_kpm_action_definition_s& action_def_generic) +{ + e2_sm_kpm_action_definition_format1_s& action_definition = + action_def_generic.action_definition_formats.action_definition_format1(); + + bool cell_global_id_present = false; + uint64_t granul_period; + uint64_t eutra_cell_id; + uint64_t plmn_id; + ueid_c ue_id; + meas_info_list_l meas_info_list; + + granul_period = action_definition.granul_period; + + if (granul_period == 0) { + e2sm_kpm->logger.debug("Action granularity period of %i is not supported -> do not admitted action\n", + granul_period); + return false; + } + + if (action_definition.cell_global_id_present) { + cell_global_id_present = true; + if (action_definition.cell_global_id.type() == cgi_c::types_opts::eutra_cgi) { + eutra_cell_id = action_definition.cell_global_id.eutra_cgi().eutra_cell_id.to_number(); + plmn_id = action_definition.cell_global_id.eutra_cgi().plmn_id.to_number(); + e2sm_kpm->logger.debug("plmn_id 0x%x, eutra_cell_id %i", plmn_id, eutra_cell_id); + // TODO: check if E2 node has cell_id and plmn_id + } + } + + std::map admitted_metrics; + meas_info_list = action_definition.meas_info_list; + for (uint32_t i = 0; i < meas_info_list.size(); i++) { + std::string meas_name = meas_info_list[i].meas_type.meas_name().to_string(); + e2sm_kpm_metric_t metric_definition; + if (not e2sm_kpm->_get_meas_definition(meas_name, metric_definition)) { + printf("Unsupported measurement name: \"%s\" --> do not admit action\n", meas_name.c_str()); + return false; + } + + uint32_t nof_labels = 0; + // TODO: add all labels defined in e2sm_kpm doc, make this part generic and put to base class + // TODO: check if metric is supported at the requested level, i.e., CELL_LEVEL if cell_global_id_present == true, + // and ENB_LEVEL otherwise + for (uint32_t l = 0; l < meas_info_list[i].label_info_list.size(); l++) { + if (meas_info_list[i].label_info_list[l].meas_label.no_label_present) { + if (metric_definition.supported_labels & NO_LABEL) { + nof_labels++; + admitted_metrics[meas_name] = NO_LABEL; + } else { + printf("Unsupported label: NO_LABEL for metric \"%s\" --> do not admit action\n", meas_name.c_str()); + return false; + } + } + if (meas_info_list[i].label_info_list[l].meas_label.min_present) { + if (metric_definition.supported_labels & MIN_LABEL) { + nof_labels++; + admitted_metrics[meas_name] = MIN_LABEL; + } else { + printf("Unsupported label: MIN_LABEL for metric \"%s\" --> do not admit action\n", meas_name.c_str()); + return false; + } + } + if (meas_info_list[i].label_info_list[l].meas_label.max_present) { + if (metric_definition.supported_labels & MAX_LABEL) { + nof_labels++; + admitted_metrics[meas_name] = MAX_LABEL; + } else { + printf("Unsupported label: MAX_LABEL for metric \"%s\" --> do not admit action\n", meas_name.c_str()); + return false; + } + } + if (meas_info_list[i].label_info_list[l].meas_label.avg_present) { + if (metric_definition.supported_labels & AVG_LABEL) { + nof_labels++; + admitted_metrics[meas_name] = AVG_LABEL; + } else { + printf("Unsupported label: AVG_LABEL for metric \"%s\" --> do not admit action\n", meas_name.c_str()); + return false; + } + } + } + + // Note: currently we use labels as choice (i.e., only one can be present) as documentation is not clear about it + if (nof_labels > 1) { + printf("Only one label per metric can be present, meas: \"%s\" has %i labels --> do not admit action\n", + meas_name.c_str(), + nof_labels); + return false; + } + } + + printf("Admitted action with the following metrics and labels: \n"); + for (const auto& it : admitted_metrics) { + std::string meas_name = it.first; + std::string label_str = e2sm_kpm_label_2_str(it.second); + printf("--- Metric: \"%s\" with label: %s\n", meas_name.c_str(), label_str.c_str()); + } + + return true; +} + +meas_data_item_s& e2sm_kpm_report_service_style1::_get_meas_data_item(std::string meas_name, + e2sm_kpm_label_enum label, + uint32_t ue_id, + bool& ref_found) +{ + meas_info_list_l& meas_info_list = ric_ind_message.meas_info_list; + ref_found = false; + // find proper index of the metric + for (uint32_t i = 0; i < meas_info_list.size(); i++) { + // measurements definition + meas_info_item_s meas_def_item = meas_info_list[i]; + std::string meas_def_name = meas_def_item.meas_type.meas_name().to_string(); + + // check if the metric name matches + if (meas_def_name != meas_name.c_str()) { + continue; + } + + // check if the metric label matches + // TODO: add all labels defined in e2sm_kpm doc + for (uint32_t l = 0; l < meas_def_item.label_info_list.size(); l++) { + if (meas_def_item.label_info_list[l].meas_label.no_label_present and label == NO_LABEL) { + ref_found = true; + return ric_ind_message.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.min_present and label == MIN_LABEL) { + ref_found = true; + return ric_ind_message.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.max_present and label == MAX_LABEL) { + ref_found = true; + return ric_ind_message.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.avg_present and label == AVG_LABEL) { + ref_found = true; + return ric_ind_message.meas_data[i]; + } + if (meas_def_item.label_info_list[l].meas_label.sum_present and label == SUM_LABEL) { + ref_found = true; + return ric_ind_message.meas_data[i]; + } + } + } + // TODO assert if match == false, has to be present as was created during initialization + ref_found = false; + return ric_ind_message.meas_data[0]; +} + +bool e2sm_kpm_report_service_style1::_collect_meas_data() +{ + meas_info_list_l& meas_info_list = ric_ind_message.meas_info_list; + for (uint32_t i = 0; i < meas_info_list.size(); i++) { + meas_info_item_s& meas_def_item = meas_info_list[i]; + std::string meas_name = meas_def_item.meas_type.meas_name().to_string(); + std::vector labels = _get_present_labels(meas_def_item); + + for (const auto& label : labels) { + // TODO: probably some labels need a special processing (e.g., use bin width that needs to be stored) + // get a proper record list + bool ref_found = false; + meas_data_item_s& meas_data_item = _get_meas_data_item(meas_name, label, 0, ref_found); + if (not ref_found) { + parent->logger.info("Cannot find a meas record list, action_id %i, metric \"%s\" label: %i", + action_id, + meas_name.c_str(), + label); + return false; + } + + // get data type + meas_record_item_c::types data_type = _get_meas_data_type(meas_name, label, meas_data_item.meas_record); + + // extract a needed value from enb metrics and add to the proper meas record list + e2sm_kpm_meas_def_t meas_value; + meas_value.name = meas_name; + meas_value.label = label; + meas_value.scope = ENB_LEVEL; + if (cell_global_id_present) { + meas_value.scope = CELL_LEVEL; + meas_value.cell_id = 0; + } + meas_value.data_type = data_type; + + meas_record_item_c item; + if (not parent->_collect_meas_value(meas_value, item)) { + parent->logger.info("Cannot extract value \"%s\" label: %i", meas_name.c_str(), label); + return false; + } + + // save meas value in the proper record list + meas_data_item.meas_record.push_back(item); + } + } + + // reschedule measurement collection + _reschedule_meas_collection(); + return true; +} + +bool e2sm_kpm_report_service_style1::is_ric_ind_ready() +{ + // TODO: check if only NO_VALUES, if so then skip + return true; +} + +bool e2sm_kpm_report_service_style1::clear_collected_data() +{ + ric_ind_header.collet_start_time.from_number(std::time(0)); + for (uint32_t i = 0; i < ric_ind_message.meas_data.size(); ++i) { + ric_ind_message.meas_data[i].meas_record.clear(); + } + return true; +} + +e2sm_kpm_report_service_style2::e2sm_kpm_report_service_style2(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + e2sm_kpm_report_service(e2sm_kpm, action_id, action_definition), + action_def(action_def_generic.action_definition_formats.action_definition_format2()), + ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format1()) +{ + ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + this->_initialize_ric_ind_hdr(); + this->_initialize_ric_ind_msg(); +} + +bool e2sm_kpm_report_service_style2::_initialize_ric_ind_msg() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style2::process_ric_action_definition(e2sm_kpm* e2sm_kpm, + e2_sm_kpm_action_definition_s& action_def_generic) +{ + // TODO: implement + // note: similar to e2sm_kpm_report_service_style1::process_ric_action_definition but in addition + // we need to check whether measurement is supported at UE_LEVEL + return false; +} + +bool e2sm_kpm_report_service_style2::_collect_meas_data() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style2::is_ric_ind_ready() +{ + // TODO: check if only NO_VALUES, if so then skip + return false; +} + +bool e2sm_kpm_report_service_style2::clear_collected_data() +{ + // TODO: implement + return false; +} + +e2sm_kpm_report_service_style3::e2sm_kpm_report_service_style3(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + e2sm_kpm_report_service(e2sm_kpm, action_id, action_definition), + action_def(action_def_generic.action_definition_formats.action_definition_format3()), + ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format2()) +{ + ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + this->_initialize_ric_ind_hdr(); + this->_initialize_ric_ind_msg(); +} + +bool e2sm_kpm_report_service_style3::_initialize_ric_ind_msg() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style3::process_ric_action_definition(e2sm_kpm* e2sm_kpm, + e2_sm_kpm_action_definition_s& action_def_generic) +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style3::_collect_meas_data() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style3::is_ric_ind_ready() +{ + // TODO: check if only NO_VALUES, if so then skip + return false; +} + +bool e2sm_kpm_report_service_style3::clear_collected_data() +{ + // TODO: implement + return false; +} + +e2sm_kpm_report_service_style4::e2sm_kpm_report_service_style4(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + e2sm_kpm_report_service(e2sm_kpm, action_id, action_definition), + action_def(action_def_generic.action_definition_formats.action_definition_format4()), + ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format3()) +{ + ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + this->_initialize_ric_ind_hdr(); + this->_initialize_ric_ind_msg(); +} + +bool e2sm_kpm_report_service_style4::_initialize_ric_ind_msg() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style4::process_ric_action_definition(e2sm_kpm* e2sm_kpm, + e2_sm_kpm_action_definition_s& action_def_generic) +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style4::_collect_meas_data() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style4::is_ric_ind_ready() +{ + // TODO: check if only NO_VALUES, if so then skip + return false; +} + +bool e2sm_kpm_report_service_style4::clear_collected_data() +{ + // TODO: implement + return false; +} + +e2sm_kpm_report_service_style5::e2sm_kpm_report_service_style5(e2sm_kpm* e2sm_kpm, + uint16_t action_id, + e2_sm_kpm_action_definition_s action_definition) : + e2sm_kpm_report_service(e2sm_kpm, action_id, action_definition), + action_def(action_def_generic.action_definition_formats.action_definition_format5()), + ric_ind_message(ric_ind_message_generic.ind_msg_formats.set_ind_msg_format3()) +{ + ind_msg_format = e2_sm_kpm_ind_msg_s::ind_msg_formats_c_::types_opts::ind_msg_format1; + this->_initialize_ric_ind_hdr(); + this->_initialize_ric_ind_msg(); +} + +bool e2sm_kpm_report_service_style5::_initialize_ric_ind_msg() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style5::process_ric_action_definition(e2sm_kpm* e2sm_kpm, + e2_sm_kpm_action_definition_s& action_def_generic) +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style5::_collect_meas_data() +{ + // TODO: implement + return false; +} + +bool e2sm_kpm_report_service_style5::is_ric_ind_ready() +{ + // TODO: check if only NO_VALUES, if so then skip + return false; +} + +bool e2sm_kpm_report_service_style5::clear_collected_data() +{ + // TODO: implement + return false; +} \ No newline at end of file diff --git a/srsgnb/src/stack/ric/test/CMakeLists.txt b/srsgnb/src/stack/ric/test/CMakeLists.txt new file mode 100644 index 0000000000..4a4808b5fd --- /dev/null +++ b/srsgnb/src/stack/ric/test/CMakeLists.txt @@ -0,0 +1,24 @@ +# +# Copyright 2013-2023 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/. +# + +add_executable(e2ap_test e2ap_test.cc) +target_link_libraries(e2ap_test srsran_common ric_e2 srsgnb_ric srsenb_upper srsgnb_stack ${SCTP_LIBRARIES}) + +add_test(e2ap_test e2ap_test) \ No newline at end of file diff --git a/srsgnb/src/stack/ric/test/e2ap_test.cc b/srsgnb/src/stack/ric/test/e2ap_test.cc new file mode 100644 index 0000000000..c8c0c0e008 --- /dev/null +++ b/srsgnb/src/stack/ric/test/e2ap_test.cc @@ -0,0 +1,186 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/ric/e2ap.h" +#include "srsran/asn1/e2ap.h" +#include "srsran/common/test_common.h" +#include "srsran/interfaces/e2_metrics_interface.h" +#include "srsran/interfaces/enb_metrics_interface.h" +#include "srsran/srsran.h" + +class dummy_metrics_interface : public srsenb::e2_interface_metrics +{ + bool pull_metrics(srsenb::enb_metrics_t* m) { return true; } + bool register_e2sm(e2sm* sm) { return true; } + bool unregister_e2sm(e2sm* sm) { return true; } +}; +// function to test the encoding of the E2AP message +void test_reference_e2ap_setup_request() +{ + uint8_t e2ap_msg_foreign[] = { + 0x00, 0x01, 0x00, 0x80, 0xa3, 0x00, 0x00, 0x04, 0x00, 0x31, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x09, 0x00, + 0x05, 0xf5, 0x10, 0x30, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x53, 0x00, 0x00, 0x08, 0x00, 0x4e, 0x00, 0x00, + 0x93, 0x38, 0x00, 0x30, 0x4f, 0x52, 0x41, 0x4e, 0x2d, 0x45, 0x32, 0x53, 0x4d, 0x2d, 0x4b, 0x50, 0x4d, 0x00, 0x00, + 0x18, 0x31, 0x2e, 0x33, 0x2e, 0x36, 0x2e, 0x31, 0x2e, 0x34, 0x2e, 0x31, 0x2e, 0x35, 0x33, 0x31, 0x34, 0x38, 0x2e, + 0x31, 0x2e, 0x32, 0x2e, 0x32, 0x2e, 0x32, 0x05, 0x00, 0x4b, 0x50, 0x4d, 0x20, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x4f, 0x52, 0x41, 0x4e, 0x2d, 0x45, 0x32, 0x53, 0x4d, 0x2d, 0x4b, 0x50, 0x4d, + 0x00, 0x32, 0x00, 0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x2c, 0x00, 0x01, 0x80, 0x44, 0x55, 0x4d, 0x4d, 0x59, 0x20, + 0x4f, 0x41, 0x49, 0x2d, 0x41, 0x4d, 0x46, 0x00, 0x0c, 0x46, 0x41, 0x4b, 0x45, 0x20, 0x52, 0x45, 0x51, 0x55, 0x45, + 0x53, 0x54, 0x0d, 0x46, 0x41, 0x4b, 0x45, 0x20, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45}; + + asn1::cbit_ref bref(&e2ap_msg_foreign[0], sizeof(e2ap_msg_foreign)); + e2_ap_pdu_c pdu; + asn1::SRSASN_CODE unpack_ret = pdu.unpack(bref); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked E2AP PDU %d\n", (int)unpack_ret); + auto& ran_func_data = pdu.init_msg() + .value.e2setup_request() + ->ra_nfunctions_added.value[0] + .value() + .ra_nfunction_item() + .ran_function_definition; + srsran::byte_buffer_t ran_function_def; + asn1::cbit_ref ran_func_bref(ran_function_def.msg, ran_function_def.get_tailroom()); + std::copy(ran_func_data.data(), ran_func_data.data() + ran_func_data.size(), ran_function_def.begin()); + e2_sm_kpm_ra_nfunction_description_s e2sm_kpm_ra_nfunction_description; + asn1::SRSASN_CODE nfunc_unpack = e2sm_kpm_ra_nfunction_description.unpack(ran_func_bref); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, nfunc_unpack); + printf("Unpacked E2SM PDU (KPM RAN function description) %d\n", (int)nfunc_unpack); +} + +void test_native_e2ap_setup_request() +{ + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + e2_ap_pdu_c pdu, pdu2; + srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); + dummy_metrics_interface dummy_metrics; + e2ap e2ap_(logger, nullptr, &dummy_metrics, NULL); + pdu = e2ap_.generate_setup_request(); + + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("Failed to pack TX E2 PDU\n"); + return; + } + + asn1::cbit_ref bref2(buf->msg, buf->get_tailroom()); + + asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked native E2AP PDU %d\n", (int)unpack_ret); +} + +void test_reference_e2ap_subscription_request() +{ + uint8_t e2ap_msg_foreign[] = {0x00, 0x08, 0x40, 0x2b, 0x00, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x05, 0x00, + 0x00, 0x7b, 0x00, 0x15, 0x00, 0x05, 0x00, 0x02, 0x00, 0x01, 0x00, 0x1e, + 0x00, 0x15, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00, 0x00, 0x13, 0x40, + 0x0a, 0x60, 0x01, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, 0x02, 0x00}; + + asn1::cbit_ref bref(&e2ap_msg_foreign[0], sizeof(e2ap_msg_foreign)); + e2_ap_pdu_c pdu; + asn1::SRSASN_CODE unpack_ret = pdu.unpack(bref); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked E2AP PDU (subscription request) %d\n", (int)unpack_ret); +} + +void test_native_e2ap_subscription_response() +{ + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + e2_ap_pdu_c pdu, pdu2; + srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); + dummy_metrics_interface dummy_metrics; + e2ap e2ap_(logger, nullptr, &dummy_metrics, NULL); + + ric_subscription_reponse_t ric_subscription_reponse; + ric_subscription_reponse.ric_requestor_id = 1021; + ric_subscription_reponse.ric_instance_id = 0; + ric_subscription_reponse.ra_nfunction_id = 147; + ric_subscription_reponse.admitted_actions.push_back(0); + + pdu = e2ap_.generate_subscription_response(ric_subscription_reponse); + + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("Failed to pack TX E2 PDU\n"); + return; + } + + asn1::cbit_ref bref2(buf->msg, buf->get_tailroom()); + asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked native E2AP PDU (subscription response) %d\n", (int)unpack_ret); +} + +void test_native_e2ap_reset_request() +{ + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + e2_ap_pdu_c pdu, pdu2; + srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); + dummy_metrics_interface dummy_metrics; + e2ap e2ap_(logger, nullptr, &dummy_metrics, NULL); + + pdu = e2ap_.generate_reset_request(); + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("Failed to pack TX E2 PDU\n"); + return; + } + + asn1::cbit_ref bref2(buf->msg, buf->get_tailroom()); + asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked native E2AP PDU RESET %d\n", (int)unpack_ret); +} + +void test_native_e2ap_reset_response() +{ + srsran::unique_byte_buffer_t buf = srsran::make_byte_buffer(); + e2_ap_pdu_c pdu, pdu2; + srslog::basic_logger& logger = srslog::fetch_basic_logger("E2AP"); + dummy_metrics_interface dummy_metrics; + e2ap e2ap_(logger, nullptr, &dummy_metrics, NULL); + + pdu = e2ap_.generate_reset_response(); + asn1::bit_ref bref(buf->msg, buf->get_tailroom()); + if (pdu.pack(bref) != asn1::SRSASN_SUCCESS) { + printf("Failed to pack TX E2 PDU\n"); + return; + } + + asn1::cbit_ref bref2(buf->msg, buf->get_tailroom()); + asn1::SRSASN_CODE unpack_ret = pdu2.unpack(bref2); + TESTASSERT_EQ(asn1::SRSASN_SUCCESS, unpack_ret); + printf("Unpacked native E2AP PDU RESET RESPONSE %d\n", (int)unpack_ret); +} +// add tets for set-up request and response + +int main() +{ + test_reference_e2ap_setup_request(); + test_native_e2ap_setup_request(); + test_reference_e2ap_subscription_request(); + test_native_e2ap_subscription_response(); + test_native_e2ap_reset_request(); + test_native_e2ap_reset_response(); + // call reset test functions here + return 0; +} diff --git a/srsgnb/src/stack/rrc/CMakeLists.txt b/srsgnb/src/stack/rrc/CMakeLists.txt new file mode 100644 index 0000000000..e0688615b0 --- /dev/null +++ b/srsgnb/src/stack/rrc/CMakeLists.txt @@ -0,0 +1,31 @@ +# +# Copyright 2013-2023 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/. +# + +set(SOURCES rrc_nr_config_utils.cc) +add_library(srsgnb_rrc_config_utils STATIC ${SOURCES}) +target_link_libraries(srsgnb_rrc_config_utils srsran_phy) + +set(SOURCES rrc_nr.cc rrc_nr_ue.cc rrc_nr_security_context.cc cell_asn1_config.cc rrc_nr_du_manager.cc) +add_library(srsgnb_rrc STATIC ${SOURCES}) +target_link_libraries(srsgnb_rrc srsgnb_rrc_config_utils) + +include_directories(${PROJECT_SOURCE_DIR}) + +add_subdirectory(test) diff --git a/srsgnb/src/stack/rrc/cell_asn1_config.cc b/srsgnb/src/stack/rrc/cell_asn1_config.cc new file mode 100644 index 0000000000..c39556b98d --- /dev/null +++ b/srsgnb/src/stack/rrc/cell_asn1_config.cc @@ -0,0 +1,1370 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/rrc/cell_asn1_config.h" +#include "srsenb/hdr/common/common_enb.h" +#include "srsran/asn1/obj_id_cmp_utils.h" +#include "srsran/asn1/rrc_nr_utils.h" +#include "srsran/common/band_helper.h" +#include + +using namespace asn1::rrc_nr; + +#define HANDLE_ERROR(ret) \ + if ((ret) != SRSRAN_SUCCESS) { \ + return SRSRAN_ERROR; \ + } + +namespace srsenb { + +srslog::basic_logger& get_logger(const rrc_nr_cfg_t& cfg) +{ + static srslog::basic_logger& log_obj = srslog::fetch_basic_logger(cfg.log_name); + return log_obj; +} + +void set_search_space_from_phy_cfg(const srsran_search_space_t& cfg, asn1::rrc_nr::search_space_s& out) +{ + out.search_space_id = cfg.id; + out.ctrl_res_set_id_present = true; + out.ctrl_res_set_id = cfg.coreset_id; + out.monitoring_slot_periodicity_and_offset_present = true; + out.monitoring_slot_periodicity_and_offset.set_sl1(); + out.dur_present = false; // false for duration=1 + out.monitoring_symbols_within_slot_present = true; + out.monitoring_symbols_within_slot.from_number(0b10000000000000); + + out.nrof_candidates_present = true; + bool ret = asn1::number_to_enum(out.nrof_candidates.aggregation_level1, cfg.nof_candidates[0]); + srsran_assert(ret, "Failed to convert nof candidates=%d", cfg.nof_candidates[0]); + ret = asn1::number_to_enum(out.nrof_candidates.aggregation_level2, cfg.nof_candidates[1]); + srsran_assert(ret, "Failed to convert nof candidates=%d", cfg.nof_candidates[1]); + ret = asn1::number_to_enum(out.nrof_candidates.aggregation_level4, cfg.nof_candidates[2]); + srsran_assert(ret, "Failed to convert nof candidates=%d", cfg.nof_candidates[2]); + ret = asn1::number_to_enum(out.nrof_candidates.aggregation_level8, cfg.nof_candidates[3]); + srsran_assert(ret, "Failed to convert nof candidates=%d", cfg.nof_candidates[3]); + ret = asn1::number_to_enum(out.nrof_candidates.aggregation_level16, cfg.nof_candidates[4]); + srsran_assert(ret, "Failed to convert nof candidates=%d", cfg.nof_candidates[4]); + + out.search_space_type_present = true; + if ((cfg.type == srsran_search_space_type_common_0) or (cfg.type == srsran_search_space_type_common_0A) or + (cfg.type == srsran_search_space_type_common_1) or (cfg.type == srsran_search_space_type_common_2) or + (cfg.type == srsran_search_space_type_common_3)) { + out.search_space_type.set_common(); + + out.search_space_type.common().dci_format0_minus0_and_format1_minus0_present = true; + } else if (cfg.type == srsran_search_space_type_ue) { + out.search_space_type.set_ue_specific().dci_formats.value = + search_space_s::search_space_type_c_::ue_specific_s_::dci_formats_opts::formats0_minus0_and_minus1_minus0; + } else { + srsran_terminate("Config Error: Unsupported search space type."); + } +} + +void set_coreset_from_phy_cfg(const srsran_coreset_t& coreset_cfg, asn1::rrc_nr::ctrl_res_set_s& out) +{ + out.ctrl_res_set_id = coreset_cfg.id; + + std::bitset freq_domain_res; + for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { + freq_domain_res[SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE - 1 - i] = coreset_cfg.freq_resources[i]; + } + out.freq_domain_res.from_number(freq_domain_res.to_ulong()); + + out.dur = coreset_cfg.duration; + + if (coreset_cfg.mapping_type == srsran_coreset_mapping_type_non_interleaved) { + out.cce_reg_map_type.set_non_interleaved(); + } else { + auto& interleaved = out.cce_reg_map_type.set_interleaved(); + interleaved.reg_bundle_size.value = (decltype(interleaved.reg_bundle_size.value))coreset_cfg.reg_bundle_size; + interleaved.interleaver_size.value = (decltype(interleaved.interleaver_size.value))coreset_cfg.interleaver_size; + interleaved.shift_idx_present = true; + interleaved.shift_idx = coreset_cfg.shift_index; + } + + if (coreset_cfg.precoder_granularity == srsran_coreset_precoder_granularity_reg_bundle) { + out.precoder_granularity = asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; + } else { + out.precoder_granularity = asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::all_contiguous_rbs; + } + + // TODO: Remaining fields +} + +void set_rach_cfg_common(const srsran_prach_cfg_t& prach_cfg, asn1::rrc_nr::rach_cfg_common_s& out) +{ + // rach-ConfigGeneric + out.rach_cfg_generic.prach_cfg_idx = prach_cfg.config_idx; + out.rach_cfg_generic.msg1_fdm.value = rach_cfg_generic_s::msg1_fdm_opts::one; + out.rach_cfg_generic.msg1_freq_start = prach_cfg.freq_offset; + out.rach_cfg_generic.zero_correlation_zone_cfg = prach_cfg.zero_corr_zone; + out.rach_cfg_generic.preamb_rx_target_pwr = -110; + out.rach_cfg_generic.preamb_trans_max.value = rach_cfg_generic_s::preamb_trans_max_opts::n7; + out.rach_cfg_generic.pwr_ramp_step.value = rach_cfg_generic_s::pwr_ramp_step_opts::db4; + out.rach_cfg_generic.ra_resp_win.value = rach_cfg_generic_s::ra_resp_win_opts::sl10; + + out.ssb_per_rach_occasion_and_cb_preambs_per_ssb_present = true; + asn1::number_to_enum(out.ssb_per_rach_occasion_and_cb_preambs_per_ssb.set_one(), prach_cfg.num_ra_preambles); + out.ra_contention_resolution_timer.value = rach_cfg_common_s::ra_contention_resolution_timer_opts::sf64; + out.prach_root_seq_idx.set_l839() = prach_cfg.root_seq_idx; + out.restricted_set_cfg.value = rach_cfg_common_s::restricted_set_cfg_opts::unrestricted_set; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void fill_tdd_ul_dl_config_common(const rrc_cell_cfg_nr_t& cfg, asn1::rrc_nr::tdd_ul_dl_cfg_common_s& tdd) +{ + srsran_assert(cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD, "This function should only be called for TDD configs"); + // TDD UL-DL config + tdd.ref_subcarrier_spacing.value = (asn1::rrc_nr::subcarrier_spacing_opts::options)cfg.phy_cell.carrier.scs; + tdd.pattern1.dl_ul_tx_periodicity = asn1::rrc_nr::tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms10; + tdd.pattern1.nrof_dl_slots = 6; + tdd.pattern1.nrof_dl_symbols = 0; + tdd.pattern1.nrof_ul_slots = 4; + tdd.pattern1.nrof_ul_symbols = 0; +} + +/// Fill list of CSI-ReportConfig with gNB config +int fill_csi_report_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) +{ + if (cfg.is_standalone) { + csi_meas_cfg.csi_report_cfg_to_add_mod_list.resize(1); + + auto& csi_report = csi_meas_cfg.csi_report_cfg_to_add_mod_list[0]; + csi_report.report_cfg_id = 0; + csi_report.res_for_ch_meas = 0; + csi_report.csi_im_res_for_interference_present = true; + csi_report.csi_im_res_for_interference = 1; + csi_report.report_cfg_type.set_periodic(); + csi_report.report_cfg_type.periodic().report_slot_cfg.set_slots80(); + csi_report.report_cfg_type.periodic().pucch_csi_res_list.resize(1); + csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].ul_bw_part_id = 0; + csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].pucch_res = + 17; // was 17 in orig PCAP, but code for NSA it was set to 1 + csi_report.report_quant.set_cri_ri_pmi_cqi(); + // Report freq config (optional) + csi_report.report_freq_cfg_present = true; + csi_report.report_freq_cfg.cqi_format_ind_present = true; + csi_report.report_freq_cfg.cqi_format_ind.value = + csi_report_cfg_s::report_freq_cfg_s_::cqi_format_ind_opts::wideband_cqi; + csi_report.report_freq_cfg.pmi_format_ind_present = true; + csi_report.report_freq_cfg.pmi_format_ind.value = + csi_report_cfg_s::report_freq_cfg_s_::pmi_format_ind_opts::wideband_pmi; + csi_report.time_restrict_for_ch_meass.value = csi_report_cfg_s::time_restrict_for_ch_meass_opts::not_cfgured; + csi_report.time_restrict_for_interference_meass.value = + asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_interference_meass_opts::not_cfgured; + csi_report.codebook_cfg_present = true; + auto& type1 = csi_report.codebook_cfg.codebook_type.set_type1(); + type1.sub_type.set_type_i_single_panel(); + type1.sub_type.type_i_single_panel().nr_of_ant_ports.set_two(); + type1.sub_type.type_i_single_panel().nr_of_ant_ports.two().two_tx_codebook_subset_restrict.from_number(0b111111); + type1.sub_type.type_i_single_panel().type_i_single_panel_ri_restrict.from_number(0x03); + type1.codebook_mode = 1; + csi_report.group_based_beam_report.set_disabled(); + // Skip CQI table (optional) + csi_report.cqi_table_present = true; + csi_report.cqi_table = asn1::rrc_nr::csi_report_cfg_s::cqi_table_opts::table1; + csi_report.subband_size = asn1::rrc_nr::csi_report_cfg_s::subband_size_opts::value1; + + if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 1; + } else { + csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 7; + } + } else { + csi_meas_cfg.csi_report_cfg_to_add_mod_list.resize(1); + + auto& csi_report = csi_meas_cfg.csi_report_cfg_to_add_mod_list[0]; + csi_report.report_cfg_id = 0; + csi_report.res_for_ch_meas = 0; + csi_report.csi_im_res_for_interference_present = true; + csi_report.csi_im_res_for_interference = 1; + csi_report.report_cfg_type.set_periodic(); + csi_report.report_cfg_type.periodic().report_slot_cfg.set_slots80(); + csi_report.report_cfg_type.periodic().pucch_csi_res_list.resize(1); + csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].ul_bw_part_id = 0; + csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].pucch_res = 1; // was 17 in orig PCAP + csi_report.report_quant.set_cri_ri_pmi_cqi(); + // Report freq config (optional) + csi_report.report_freq_cfg_present = true; + csi_report.report_freq_cfg.cqi_format_ind_present = true; + csi_report.report_freq_cfg.cqi_format_ind = csi_report_cfg_s::report_freq_cfg_s_::cqi_format_ind_opts::wideband_cqi; + csi_report.time_restrict_for_ch_meass = csi_report_cfg_s::time_restrict_for_ch_meass_opts::not_cfgured; + csi_report.time_restrict_for_interference_meass = + asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_interference_meass_opts::not_cfgured; + csi_report.group_based_beam_report.set_disabled(); + // Skip CQI table (optional) + csi_report.cqi_table_present = true; + csi_report.cqi_table = asn1::rrc_nr::csi_report_cfg_s::cqi_table_opts::table2; + csi_report.subband_size = asn1::rrc_nr::csi_report_cfg_s::subband_size_opts::value1; + + if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 5; + } else { + csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 7; + } + } + + return SRSRAN_SUCCESS; +} + +/// Fill lists of NZP-CSI-RS-Resource and NZP-CSI-RS-ResourceSet with gNB config +void fill_nzp_csi_rs_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) +{ + if (cfg.is_standalone) { + if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(5); + auto& nzp_csi_res = csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list; + // item 0 + nzp_csi_res[0].nzp_csi_rs_res_id = 0; + nzp_csi_res[0].res_map.freq_domain_alloc.set_row2(); + nzp_csi_res[0].res_map.freq_domain_alloc.row2().from_number(0x800); + nzp_csi_res[0].res_map.nrof_ports.value = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res[0].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res[0].res_map.cdm_type.value = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res[0].res_map.density.set_one(); + nzp_csi_res[0].res_map.freq_band.start_rb = 0; + nzp_csi_res[0].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res[0].pwr_ctrl_offset = 0; + nzp_csi_res[0].pwr_ctrl_offset_ss_present = true; + nzp_csi_res[0].pwr_ctrl_offset_ss.value = asn1::rrc_nr::nzp_csi_rs_res_s::pwr_ctrl_offset_ss_opts::db0; + nzp_csi_res[0].scrambling_id = cfg.cell_list[0].phy_cell.cell_id; + nzp_csi_res[0].periodicity_and_offset_present = true; + nzp_csi_res[0].periodicity_and_offset.set_slots80(); + nzp_csi_res[0].periodicity_and_offset.slots80() = 1; + // optional + nzp_csi_res[0].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res[0].qcl_info_periodic_csi_rs = 0; + // item 1 + nzp_csi_res[1] = nzp_csi_res[0]; + nzp_csi_res[1].nzp_csi_rs_res_id = 1; + nzp_csi_res[1].res_map.freq_domain_alloc.set_row1(); + nzp_csi_res[1].res_map.freq_domain_alloc.row1().from_number(0x1); + nzp_csi_res[1].res_map.nrof_ports.value = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res[1].res_map.cdm_type.value = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res[1].res_map.density.set_three(); + nzp_csi_res[1].periodicity_and_offset.set_slots40(); + nzp_csi_res[1].periodicity_and_offset.slots40() = 11; + // item 2 + nzp_csi_res[2] = nzp_csi_res[1]; + nzp_csi_res[2].nzp_csi_rs_res_id = 2; + nzp_csi_res[2].res_map.first_ofdm_symbol_in_time_domain = 8; + // item 3 + nzp_csi_res[3] = nzp_csi_res[1]; + nzp_csi_res[3].nzp_csi_rs_res_id = 3; + nzp_csi_res[3].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res[3].periodicity_and_offset.set_slots40(); + nzp_csi_res[3].periodicity_and_offset.slots40() = 12; + // item 4 + nzp_csi_res[4] = nzp_csi_res[1]; + nzp_csi_res[4].nzp_csi_rs_res_id = 4; + nzp_csi_res[4].res_map.first_ofdm_symbol_in_time_domain = 8; + nzp_csi_res[4].periodicity_and_offset.set_slots40(); + nzp_csi_res[4].periodicity_and_offset.slots40() = 12; + } else { + csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(1); + auto& nzp_csi_res = csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list; + nzp_csi_res[0].nzp_csi_rs_res_id = 0; + nzp_csi_res[0].res_map.freq_domain_alloc.set_row2(); + nzp_csi_res[0].res_map.freq_domain_alloc.row2().from_number(0b100000000000); + nzp_csi_res[0].res_map.nrof_ports.value = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res[0].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res[0].res_map.cdm_type.value = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res[0].res_map.density.set_one(); + nzp_csi_res[0].res_map.freq_band.start_rb = 0; + nzp_csi_res[0].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res[0].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res[0].periodicity_and_offset_present = true; + nzp_csi_res[0].periodicity_and_offset.set_slots80() = 0; + // optional + nzp_csi_res[0].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res[0].qcl_info_periodic_csi_rs = 0; + } + + // Fill NZP-CSI Resource Sets + if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(2); + auto& nzp_csi_res_set = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list; + // item 0 + nzp_csi_res_set[0].nzp_csi_res_set_id = 0; + nzp_csi_res_set[0].nzp_csi_rs_res.resize(1); + nzp_csi_res_set[0].nzp_csi_rs_res[0] = 0; + // item 1 + nzp_csi_res_set[1].nzp_csi_res_set_id = 1; + nzp_csi_res_set[1].nzp_csi_rs_res.resize(4); + nzp_csi_res_set[1].nzp_csi_rs_res[0] = 1; + nzp_csi_res_set[1].nzp_csi_rs_res[1] = 2; + nzp_csi_res_set[1].nzp_csi_rs_res[2] = 3; + nzp_csi_res_set[1].nzp_csi_rs_res[3] = 4; + nzp_csi_res_set[1].trs_info_present = true; + // // Skip TRS info + } else { + csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(1); + auto& nzp_csi_res_set = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list; + nzp_csi_res_set[0].nzp_csi_res_set_id = 0; + nzp_csi_res_set[0].nzp_csi_rs_res.resize(1); + nzp_csi_res_set[0].nzp_csi_rs_res[0] = 0; + // Skip TRS info + } + } else { + if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(5); + auto& nzp_csi_res = csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list; + // item 0 + nzp_csi_res[0].nzp_csi_rs_res_id = 0; + nzp_csi_res[0].res_map.freq_domain_alloc.set_row2(); + nzp_csi_res[0].res_map.freq_domain_alloc.row2().from_number(0b100000000000); + nzp_csi_res[0].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res[0].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res[0].res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res[0].res_map.density.set_one(); + nzp_csi_res[0].res_map.freq_band.start_rb = 0; + nzp_csi_res[0].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res[0].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res[0].scrambling_id = cfg.cell_list[0].phy_cell.cell_id; + nzp_csi_res[0].periodicity_and_offset_present = true; + nzp_csi_res[0].periodicity_and_offset.set_slots80(); + nzp_csi_res[0].periodicity_and_offset.slots80() = 1; + // optional + nzp_csi_res[0].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res[0].qcl_info_periodic_csi_rs = 0; + // item 1 + nzp_csi_res[1] = nzp_csi_res[0]; + nzp_csi_res[1].nzp_csi_rs_res_id = 1; + nzp_csi_res[1].res_map.freq_domain_alloc.set_row1(); + nzp_csi_res[1].res_map.freq_domain_alloc.row1().from_number(0b0001); + nzp_csi_res[1].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res[1].res_map.density.set_three(); + nzp_csi_res[1].periodicity_and_offset.set_slots40(); + nzp_csi_res[1].periodicity_and_offset.slots40() = 11; + // item 2 + nzp_csi_res[2] = nzp_csi_res[1]; + nzp_csi_res[2].nzp_csi_rs_res_id = 2; + nzp_csi_res[2].res_map.first_ofdm_symbol_in_time_domain = 8; + nzp_csi_res[2].periodicity_and_offset.set_slots40(); + nzp_csi_res[2].periodicity_and_offset.slots40() = 11; + // item 3 + nzp_csi_res[3] = nzp_csi_res[1]; + nzp_csi_res[3].nzp_csi_rs_res_id = 3; + nzp_csi_res[3].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res[3].periodicity_and_offset.set_slots40(); + nzp_csi_res[3].periodicity_and_offset.slots40() = 12; + // item 4 + nzp_csi_res[4] = nzp_csi_res[1]; + nzp_csi_res[4].nzp_csi_rs_res_id = 4; + nzp_csi_res[4].res_map.first_ofdm_symbol_in_time_domain = 8; + nzp_csi_res[4].periodicity_and_offset.set_slots40(); + nzp_csi_res[4].periodicity_and_offset.slots40() = 12; + } else { + csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.resize(1); + auto& nzp_csi_res = csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list; + nzp_csi_res[0].nzp_csi_rs_res_id = 0; + nzp_csi_res[0].res_map.freq_domain_alloc.set_row2(); + nzp_csi_res[0].res_map.freq_domain_alloc.row2().from_number(0b100000000000); + nzp_csi_res[0].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res[0].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res[0].res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res[0].res_map.density.set_one(); + nzp_csi_res[0].res_map.freq_band.start_rb = 0; + nzp_csi_res[0].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res[0].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res[0].periodicity_and_offset_present = true; + nzp_csi_res[0].periodicity_and_offset.set_slots80() = 0; + // optional + nzp_csi_res[0].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res[0].qcl_info_periodic_csi_rs = 0; + } + + // Fill NZP-CSI Resource Sets + if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(2); + auto& nzp_csi_res_set = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list; + // item 0 + nzp_csi_res_set[0].nzp_csi_res_set_id = 0; + nzp_csi_res_set[0].nzp_csi_rs_res.resize(1); + nzp_csi_res_set[0].nzp_csi_rs_res[0] = 0; + // item 1 + nzp_csi_res_set[1].nzp_csi_res_set_id = 1; + nzp_csi_res_set[1].nzp_csi_rs_res.resize(4); + nzp_csi_res_set[1].nzp_csi_rs_res[0] = 1; + nzp_csi_res_set[1].nzp_csi_rs_res[1] = 2; + nzp_csi_res_set[1].nzp_csi_rs_res[2] = 3; + nzp_csi_res_set[1].nzp_csi_rs_res[3] = 4; + // // Skip TRS info + } else { + csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.resize(1); + auto& nzp_csi_res_set = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list; + nzp_csi_res_set[0].nzp_csi_res_set_id = 0; + nzp_csi_res_set[0].nzp_csi_rs_res.resize(1); + nzp_csi_res_set[0].nzp_csi_rs_res[0] = 0; + // Skip TRS info + } + } +} + +/// Fill csi-ResoureConfigToAddModList +void fill_csi_resource_cfg_to_add(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) +{ + if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + csi_meas_cfg.csi_res_cfg_to_add_mod_list.resize(2); + + auto& res0 = csi_meas_cfg.csi_res_cfg_to_add_mod_list[0]; + res0.csi_res_cfg_id = 0; + res0.bwp_id = 0; + res0.res_type.value = csi_res_cfg_s::res_type_opts::periodic; + auto& nzp = res0.csi_rs_res_set_list.set_nzp_csi_rs_ssb(); + nzp.nzp_csi_rs_res_set_list.push_back(0); + + auto& res2 = csi_meas_cfg.csi_res_cfg_to_add_mod_list[1]; + res2.csi_res_cfg_id = 1; + res2.bwp_id = 0; + res2.res_type.value = csi_res_cfg_s::res_type_opts::periodic; + auto& nzp2 = res2.csi_rs_res_set_list.set_nzp_csi_rs_ssb(); + nzp2.nzp_csi_rs_res_set_list.push_back(1); + } +} + +void fill_csi_im_resource_cfg_to_add(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) +{ + if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + // csi-IM-ResourceToAddModList + csi_meas_cfg.csi_im_res_to_add_mod_list.resize(1); + + auto& csi_im_res = csi_meas_cfg.csi_im_res_to_add_mod_list[0]; + csi_im_res.csi_im_res_id = 0; + csi_im_res.csi_im_res_elem_pattern_present = true; + // csi-im-resource pattern1 + auto& csi_res_pattern1 = csi_im_res.csi_im_res_elem_pattern.set_pattern1(); + csi_res_pattern1.subcarrier_location_p1.value = + csi_im_res_s::csi_im_res_elem_pattern_c_::pattern1_s_::subcarrier_location_p1_opts::s8; + csi_res_pattern1.symbol_location_p1 = 8; + // csi-im-resource freqBand + csi_im_res.freq_band_present = true; + csi_im_res.freq_band.start_rb = 0; + csi_im_res.freq_band.nrof_rbs = 52; + // csi-im-resource periodicity_and_offset + csi_im_res.periodicity_and_offset_present = true; + csi_im_res.periodicity_and_offset.set_slots80(); + csi_im_res.periodicity_and_offset.slots80() = 1; + + // csi-IM-ResourceSetToAddModList + csi_meas_cfg.csi_im_res_set_to_add_mod_list.resize(1); + + auto& csi_im_res_set = csi_meas_cfg.csi_im_res_set_to_add_mod_list[0]; + csi_im_res_set.csi_im_res_set_id = 0; + csi_im_res_set.csi_im_res.push_back(0); + } +} + +/// Fill CSI-MeasConfig with gNB config +int fill_csi_meas_from_enb_cfg(const rrc_nr_cfg_t& cfg, csi_meas_cfg_s& csi_meas_cfg) +{ + // // Fill CSI Report + // if (fill_csi_report_from_enb_cfg(cfg, csi_meas_cfg) != SRSRAN_SUCCESS) { + // get_logger(cfg).error("Failed to configure eNB CSI Report"); + // return SRSRAN_ERROR; + // } + + // Fill CSI resource config + fill_csi_resource_cfg_to_add(cfg, csi_meas_cfg); + + // Fill NZP-CSI Resources + fill_nzp_csi_rs_from_enb_cfg(cfg, csi_meas_cfg); + + if (cfg.is_standalone) { + // CSI report config + fill_csi_report_from_enb_cfg(cfg, csi_meas_cfg); + } + + return SRSRAN_SUCCESS; +} + +void fill_pdsch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pdsch_cfg_s& out) +{ + out.dmrs_dl_for_pdsch_map_type_a_present = true; + out.dmrs_dl_for_pdsch_map_type_a.set_setup(); + out.dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position_present = true; + out.dmrs_dl_for_pdsch_map_type_a.setup().dmrs_add_position = dmrs_dl_cfg_s::dmrs_add_position_opts::pos1; + + out.tci_states_to_add_mod_list.resize(1); + out.tci_states_to_add_mod_list[0].tci_state_id = 0; + out.tci_states_to_add_mod_list[0].qcl_type1.ref_sig.set_ssb(); + out.tci_states_to_add_mod_list[0].qcl_type1.ref_sig.ssb() = 0; + out.tci_states_to_add_mod_list[0].qcl_type1.qcl_type = asn1::rrc_nr::qcl_info_s::qcl_type_opts::type_d; + + out.res_alloc = pdsch_cfg_s::res_alloc_opts::res_alloc_type1; + out.rbg_size = pdsch_cfg_s::rbg_size_opts::cfg1; + out.prb_bundling_type.set_static_bundling(); + out.prb_bundling_type.static_bundling().bundle_size_present = true; + out.prb_bundling_type.static_bundling().bundle_size = + pdsch_cfg_s::prb_bundling_type_c_::static_bundling_s_::bundle_size_opts::wideband; + + // MCS Table + // NOTE: For Table 1 or QAM64, set false and comment value + // out.mcs_table_present = true; + // out.mcs_table.value = pdsch_cfg_s::mcs_table_opts::qam256; + + // ZP-CSI + out.zp_csi_rs_res_to_add_mod_list.resize(1); + out.zp_csi_rs_res_to_add_mod_list[0].zp_csi_rs_res_id = 0; + out.zp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.set_row4(); + out.zp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.row4().from_number(0b100); + out.zp_csi_rs_res_to_add_mod_list[0].res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p4; + + out.zp_csi_rs_res_to_add_mod_list[0].res_map.first_ofdm_symbol_in_time_domain = 8; + out.zp_csi_rs_res_to_add_mod_list[0].res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::fd_cdm2; + out.zp_csi_rs_res_to_add_mod_list[0].res_map.density.set_one(); + + out.zp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.start_rb = 0; + out.zp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.nrof_rbs = cfg.cell_list[cc].phy_cell.carrier.nof_prb; + out.zp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset_present = true; + out.zp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset.set_slots80() = 1; + + out.p_zp_csi_rs_res_set_present = false; // TEMP + out.p_zp_csi_rs_res_set.set_setup(); + out.p_zp_csi_rs_res_set.setup().zp_csi_rs_res_set_id = 0; + out.p_zp_csi_rs_res_set.setup().zp_csi_rs_res_id_list.resize(1); + out.p_zp_csi_rs_res_set.setup().zp_csi_rs_res_id_list[0] = 0; +} + +/// Fill InitDlBwp with gNB config +int fill_init_dl_bwp_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, bwp_dl_ded_s& init_dl_bwp) +{ + init_dl_bwp.pdcch_cfg_present = true; + init_dl_bwp.pdcch_cfg.set_setup() = cfg.cell_list[cc].pdcch_cfg_ded; + + init_dl_bwp.pdsch_cfg_present = true; + fill_pdsch_cfg_from_enb_cfg(cfg, cc, init_dl_bwp.pdsch_cfg.set_setup()); + + // TODO: ADD missing fields + + return SRSRAN_SUCCESS; +} + +void fill_pucch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pucch_cfg_s& out) +{ + // Make 2 PUCCH resource sets + out.res_set_to_add_mod_list.resize(2); + + // Make PUCCH resource set for 1-2 bit + for (uint32_t set_id = 0; set_id < out.res_set_to_add_mod_list.size(); ++set_id) { + auto& res_set = out.res_set_to_add_mod_list[set_id]; + res_set.pucch_res_set_id = set_id; + res_set.res_list.resize(8); + for (uint32_t i = 0; i < res_set.res_list.size(); ++i) { + if (cfg.is_standalone) { + res_set.res_list[i] = i + set_id * 8; + } else { + res_set.res_list[i] = set_id; + } + } + } + + // Make 3 possible resources + out.res_to_add_mod_list.resize(18); + uint32_t j = 0, j2 = 0; + for (uint32_t i = 0; i < out.res_to_add_mod_list.size(); ++i) { + out.res_to_add_mod_list[i].pucch_res_id = i; + out.res_to_add_mod_list[i].intra_slot_freq_hop_present = false; + if (i < 8 or i == 16) { + out.res_to_add_mod_list[i].start_prb = 51; + out.res_to_add_mod_list[i].second_hop_prb_present = true; + out.res_to_add_mod_list[i].second_hop_prb = 0; + out.res_to_add_mod_list[i].format.set_format1().init_cyclic_shift = (4 * (j % 3)); + out.res_to_add_mod_list[i].format.format1().nrof_symbols = 14; + out.res_to_add_mod_list[i].format.format1().start_symbol_idx = 0; + out.res_to_add_mod_list[i].format.format1().time_domain_occ = j / 3; + j++; + } else if (i < 15) { + out.res_to_add_mod_list[i].start_prb = 1; + out.res_to_add_mod_list[i].second_hop_prb_present = true; + out.res_to_add_mod_list[i].second_hop_prb = 50; + out.res_to_add_mod_list[i].format.set_format2().nrof_prbs = 1; + out.res_to_add_mod_list[i].format.format2().nrof_symbols = 2; + out.res_to_add_mod_list[i].format.format2().start_symbol_idx = 2 * (j2 % 7); + j2++; + } else { + out.res_to_add_mod_list[i].start_prb = 50; + out.res_to_add_mod_list[i].second_hop_prb_present = true; + out.res_to_add_mod_list[i].second_hop_prb = 1; + out.res_to_add_mod_list[i].format.set_format2().nrof_prbs = 1; + out.res_to_add_mod_list[i].format.format2().nrof_symbols = 2; + out.res_to_add_mod_list[i].format.format2().start_symbol_idx = 2 * (j2 % 7); + j2++; + } + } + + out.format1_present = true; + out.format1.set_setup(); + + out.format2_present = true; + out.format2.set_setup(); + out.format2.setup().max_code_rate_present = true; + out.format2.setup().max_code_rate = pucch_max_code_rate_opts::zero_dot25; + // NOTE: IMPORTANT!! The gNB expects the CSI to be reported along with HARQ-ACK + // If simul_harq_ack_csi_present = false, PUCCH might not be decoded properly when CSI is reported + out.format2.setup().simul_harq_ack_csi_present = true; + + // SR resources + out.sched_request_res_to_add_mod_list.resize(1); + auto& sr_res1 = out.sched_request_res_to_add_mod_list[0]; + sr_res1.sched_request_res_id = 1; + sr_res1.sched_request_id = 0; + sr_res1.periodicity_and_offset_present = true; + sr_res1.periodicity_and_offset.set_sl40() = 8; + sr_res1.res_present = true; + sr_res1.res = 2; + + // DL data + if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + out.dl_data_to_ul_ack.resize(1); + out.dl_data_to_ul_ack[0] = 4; + } else { + out.dl_data_to_ul_ack.resize(6); + out.dl_data_to_ul_ack[0] = 6; + out.dl_data_to_ul_ack[1] = 5; + out.dl_data_to_ul_ack[2] = 4; + out.dl_data_to_ul_ack[3] = 4; + out.dl_data_to_ul_ack[4] = 4; + out.dl_data_to_ul_ack[5] = 4; + } +} + +void fill_pusch_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, pusch_cfg_s& out) +{ + out.dmrs_ul_for_pusch_map_type_a_present = true; + out.dmrs_ul_for_pusch_map_type_a.set_setup(); + out.dmrs_ul_for_pusch_map_type_a.setup().dmrs_add_position_present = true; + out.dmrs_ul_for_pusch_map_type_a.setup().dmrs_add_position = dmrs_ul_cfg_s::dmrs_add_position_opts::pos1; + // PUSH power control skipped + out.res_alloc = pusch_cfg_s::res_alloc_opts::res_alloc_type1; + + // UCI + out.uci_on_pusch_present = true; + out.uci_on_pusch.set_setup(); + out.uci_on_pusch.setup().beta_offsets_present = true; + out.uci_on_pusch.setup().beta_offsets.set_semi_static(); + auto& beta_offset_semi_static = out.uci_on_pusch.setup().beta_offsets.semi_static(); + beta_offset_semi_static.beta_offset_ack_idx1_present = true; + beta_offset_semi_static.beta_offset_ack_idx1 = 9; + beta_offset_semi_static.beta_offset_ack_idx2_present = true; + beta_offset_semi_static.beta_offset_ack_idx2 = 9; + beta_offset_semi_static.beta_offset_ack_idx3_present = true; + beta_offset_semi_static.beta_offset_ack_idx3 = 9; + beta_offset_semi_static.beta_offset_csi_part1_idx1_present = true; + beta_offset_semi_static.beta_offset_csi_part1_idx1 = 6; + beta_offset_semi_static.beta_offset_csi_part1_idx2_present = true; + beta_offset_semi_static.beta_offset_csi_part1_idx2 = 6; + beta_offset_semi_static.beta_offset_csi_part2_idx1_present = true; + beta_offset_semi_static.beta_offset_csi_part2_idx1 = 6; + beta_offset_semi_static.beta_offset_csi_part2_idx2_present = true; + beta_offset_semi_static.beta_offset_csi_part2_idx2 = 6; + + out.uci_on_pusch.setup().scaling = uci_on_pusch_s::scaling_opts::f1; +} + +void fill_init_ul_bwp_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, bwp_ul_ded_s& out) +{ + if (cfg.is_standalone) { + out.pucch_cfg_present = true; + fill_pucch_cfg_from_enb_cfg(cfg, cc, out.pucch_cfg.set_setup()); + + out.pusch_cfg_present = true; + fill_pusch_cfg_from_enb_cfg(cfg, cc, out.pusch_cfg.set_setup()); + } +} + +/// Fill InitUlBwp with gNB config +void fill_ul_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, ul_cfg_s& out) +{ + out.init_ul_bwp_present = true; + fill_init_ul_bwp_from_enb_cfg(cfg, cc, out.init_ul_bwp); +} + +/// Fill ServingCellConfig with gNB config +int fill_serv_cell_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, serving_cell_cfg_s& serv_cell) +{ + serv_cell.csi_meas_cfg_present = true; + HANDLE_ERROR(fill_csi_meas_from_enb_cfg(cfg, serv_cell.csi_meas_cfg.set_setup())); + + serv_cell.init_dl_bwp_present = true; + fill_init_dl_bwp_from_enb_cfg(cfg, cc, serv_cell.init_dl_bwp); + + serv_cell.first_active_dl_bwp_id_present = true; + if (cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + serv_cell.first_active_dl_bwp_id = 0; + } else { + serv_cell.first_active_dl_bwp_id = 1; + } + + serv_cell.ul_cfg_present = true; + fill_ul_cfg_from_enb_cfg(cfg, cc, serv_cell.ul_cfg); + + // TODO: remaining fields + + return SRSRAN_SUCCESS; +} + +void fill_pdcch_cfg_common(const rrc_nr_cfg_t& cfg, uint32_t cc, pdcch_cfg_common_s& out); + +/// Fill FrequencyInfoDL with gNB config +int fill_freq_info_dl_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, freq_info_dl_s& freq_info_dl) +{ + auto& cell_cfg = cfg.cell_list.at(cc); + + freq_info_dl.freq_band_list.push_back(cell_cfg.band); + freq_info_dl.absolute_freq_point_a = cell_cfg.dl_absolute_freq_point_a; + freq_info_dl.absolute_freq_ssb_present = true; + freq_info_dl.absolute_freq_ssb = cell_cfg.ssb_absolute_freq_point; + + freq_info_dl.scs_specific_carrier_list.resize(1); + auto& dl_carrier = freq_info_dl.scs_specific_carrier_list[0]; + dl_carrier.offset_to_carrier = cell_cfg.phy_cell.carrier.offset_to_carrier; + + if (!asn1::number_to_enum(dl_carrier.subcarrier_spacing, + SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs) / 1000)) { + get_logger(cfg).error("Config Error: Invalid subcarrier spacing (%d).\n", + SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs)); + return SRSRAN_ERROR; + } + + dl_carrier.carrier_bw = cell_cfg.phy_cell.carrier.nof_prb; + + return SRSRAN_SUCCESS; +} + +/// Fill InitDlBwp with gNB config +int fill_init_dl_bwp_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, bwp_dl_common_s& init_dl_bwp) +{ + init_dl_bwp.pdcch_cfg_common_present = true; + fill_pdcch_cfg_common(cfg, cc, init_dl_bwp.pdcch_cfg_common.set_setup()); + // TODO: ADD missing fields + return SRSRAN_SUCCESS; +} + +/// Fill DLCellConfigCommon with gNB config +int fill_dl_cfg_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, dl_cfg_common_s& dl_cfg_common) +{ + dl_cfg_common.freq_info_dl_present = true; + HANDLE_ERROR(fill_freq_info_dl_from_enb_cfg(cfg, cc, dl_cfg_common.freq_info_dl)); + + dl_cfg_common.init_dl_bwp_present = true; + HANDLE_ERROR(fill_init_dl_bwp_common_from_enb_cfg(cfg, cc, dl_cfg_common.init_dl_bwp)); + + // TODO: ADD missing fields + + return SRSRAN_SUCCESS; +} + +/// Fill FrequencyInfoUL with gNB config +int fill_freq_info_ul_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, freq_info_ul_s& freq_info_ul) +{ + auto& cell_cfg = cfg.cell_list.at(cc); + + freq_info_ul.freq_band_list.push_back(cell_cfg.band); + freq_info_ul.absolute_freq_point_a_present = true; + freq_info_ul.absolute_freq_point_a = cell_cfg.ul_absolute_freq_point_a; + freq_info_ul.scs_specific_carrier_list.resize(1); + + auto& ul_carrier = freq_info_ul.scs_specific_carrier_list[0]; + ul_carrier.offset_to_carrier = cell_cfg.phy_cell.carrier.offset_to_carrier; + + if (!asn1::number_to_enum(ul_carrier.subcarrier_spacing, + SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs) / 1000)) { + get_logger(cfg).error("Config Error: Invalid subcarrier spacing (%d).\n", + SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs)); + return SRSRAN_ERROR; + } + + ul_carrier.carrier_bw = cell_cfg.phy_cell.carrier.nof_prb; + + return SRSRAN_SUCCESS; +} + +int fill_rach_cfg_common(const rrc_nr_cfg_t& cfg, uint32_t cc, rach_cfg_common_s& rach) +{ + // rach-ConfigGeneric + rach.rach_cfg_generic.prach_cfg_idx = 0; + if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { + // Note: Give more time margin to fit RAR + rach.rach_cfg_generic.prach_cfg_idx = 8; + } + rach.rach_cfg_generic.msg1_fdm.value = rach_cfg_generic_s::msg1_fdm_opts::one; + rach.rach_cfg_generic.msg1_freq_start = 1; // zero not supported with current PRACH implementation + rach.rach_cfg_generic.zero_correlation_zone_cfg = 0; + rach.rach_cfg_generic.preamb_rx_target_pwr = -110; + rach.rach_cfg_generic.preamb_trans_max.value = rach_cfg_generic_s::preamb_trans_max_opts::n7; + rach.rach_cfg_generic.pwr_ramp_step.value = rach_cfg_generic_s::pwr_ramp_step_opts::db4; + rach.rach_cfg_generic.ra_resp_win.value = rach_cfg_generic_s::ra_resp_win_opts::sl10; + + // totalNumberOfRA-Preambles + if (cfg.cell_list[cc].num_ra_preambles != 64) { + rach.total_nof_ra_preambs_present = true; + rach.total_nof_ra_preambs = cfg.cell_list[cc].num_ra_preambles; + } + + // ssb-perRACH-OccasionAndCB-PreamblesPerSSB + rach.ssb_per_rach_occasion_and_cb_preambs_per_ssb_present = true; + if (not asn1::number_to_enum(rach.ssb_per_rach_occasion_and_cb_preambs_per_ssb.set_one(), + cfg.cell_list[cc].num_ra_preambles)) { + get_logger(cfg).error("Invalid number of RA preambles=%d", cfg.cell_list[cc].num_ra_preambles); + return -1; + } + + rach.ra_contention_resolution_timer.value = rach_cfg_common_s::ra_contention_resolution_timer_opts::sf64; + rach.prach_root_seq_idx.set_l839() = cfg.cell_list[cc].prach_root_seq_idx; + rach.restricted_set_cfg.value = rach_cfg_common_s::restricted_set_cfg_opts::unrestricted_set; + + return SRSRAN_SUCCESS; +} + +/// Fill InitUlBwp with gNB config +int fill_init_ul_bwp_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, bwp_ul_common_s& init_ul_bwp) +{ + init_ul_bwp.rach_cfg_common_present = true; + HANDLE_ERROR(fill_rach_cfg_common(cfg, cc, init_ul_bwp.rach_cfg_common.set_setup())); + + // TODO: Add missing fields + + return SRSRAN_SUCCESS; +} + +/// Fill ULCellConfigCommon with gNB config +int fill_ul_cfg_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, ul_cfg_common_s& ul_cfg_common) +{ + ul_cfg_common.dummy = time_align_timer_opts::ms500; + + ul_cfg_common.freq_info_ul_present = true; + HANDLE_ERROR(fill_freq_info_ul_from_enb_cfg(cfg, cc, ul_cfg_common.freq_info_ul)); + + ul_cfg_common.init_ul_bwp_present = true; + fill_init_ul_bwp_from_enb_cfg(cfg, cc, ul_cfg_common.init_ul_bwp); + + // TODO: Add missing fields + + return SRSRAN_SUCCESS; +} + +/// Fill ServingCellConfigCommon with gNB config +int fill_serv_cell_common_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, serving_cell_cfg_common_s& serv_common) +{ + auto& cell_cfg = cfg.cell_list.at(cc); + + serv_common.ss_pbch_block_pwr = cell_cfg.pdsch_rs_power; + serv_common.n_timing_advance_offset_present = true; + serv_common.n_timing_advance_offset = serving_cell_cfg_common_s::n_timing_advance_offset_opts::n0; + serv_common.n_timing_advance_offset_present = true; + serv_common.dmrs_type_a_position = serving_cell_cfg_common_s::dmrs_type_a_position_opts::pos2; + + serv_common.pci_present = true; + serv_common.pci = cell_cfg.phy_cell.carrier.pci; + + serv_common.ssb_periodicity_serving_cell_present = true; + serv_common.ssb_periodicity_serving_cell.value = serving_cell_cfg_common_s::ssb_periodicity_serving_cell_opts::ms10; + + // Fill SSB config + serv_common.ssb_positions_in_burst_present = true; + if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + serv_common.ssb_positions_in_burst.set_short_bitmap().from_number(0b1000); + } else { + serv_common.ssb_positions_in_burst.set_medium_bitmap().from_number(0b10000000); + } + + // Set SSB SCS + serv_common.ssb_subcarrier_spacing_present = true; + if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + serv_common.ssb_subcarrier_spacing = subcarrier_spacing_opts::khz15; + } else { + serv_common.ssb_subcarrier_spacing = subcarrier_spacing_opts::khz30; + } + + if (cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { + // TDD UL-DL config + serv_common.tdd_ul_dl_cfg_common_present = true; + fill_tdd_ul_dl_config_common(cfg.cell_list[cc], serv_common.tdd_ul_dl_cfg_common); + } + + serv_common.ul_cfg_common_present = true; + fill_ul_cfg_common_from_enb_cfg(cfg, cc, serv_common.ul_cfg_common); + + serv_common.dl_cfg_common_present = true; + fill_dl_cfg_common_from_enb_cfg(cfg, cc, serv_common.dl_cfg_common); + + return SRSRAN_SUCCESS; +} + +/// Fill reconfigurationWithSync with gNB config +int fill_recfg_with_sync_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, recfg_with_sync_s& sync) +{ + sync.sp_cell_cfg_common_present = true; + HANDLE_ERROR(fill_serv_cell_common_from_enb_cfg(cfg, cc, sync.sp_cell_cfg_common)); + + return SRSRAN_SUCCESS; +} + +/// Fill spCellConfig with gNB config +int fill_sp_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, sp_cell_cfg_s& sp_cell) +{ + if (not cfg.is_standalone) { + sp_cell.recfg_with_sync_present = true; + } + HANDLE_ERROR(fill_recfg_with_sync_from_enb_cfg(cfg, cc, sp_cell.recfg_with_sync)); + + sp_cell.sp_cell_cfg_ded_present = true; + HANDLE_ERROR(fill_serv_cell_from_enb_cfg(cfg, cc, sp_cell.sp_cell_cfg_ded)); + + return SRSRAN_SUCCESS; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/// Fill SRB with parameters derived from cfg +void fill_srb(const rrc_nr_cfg_t& cfg, srsran::nr_srb srb_id, asn1::rrc_nr::rlc_bearer_cfg_s& out) +{ + srsran_assert(srb_id > srsran::nr_srb::srb0 and srb_id < srsran::nr_srb::count, "Invalid srb_id argument"); + + out.lc_ch_id = srsran::srb_to_lcid(srb_id); + out.served_radio_bearer_present = true; + out.served_radio_bearer.set_srb_id() = (uint8_t)srb_id; + + if (srb_id == srsran::nr_srb::srb1) { + if (cfg.srb1_cfg.present) { + out.rlc_cfg_present = true; + out.rlc_cfg = cfg.srb1_cfg.rlc_cfg; + } else { + out.rlc_cfg_present = false; + } + } else if (srb_id == srsran::nr_srb::srb2) { + if (cfg.srb2_cfg.present) { + out.rlc_cfg_present = true; + out.rlc_cfg = cfg.srb2_cfg.rlc_cfg; + } else { + out.rlc_cfg_present = false; + } + } else { + out.rlc_cfg_present = true; + auto& ul_am = out.rlc_cfg.set_am().ul_am_rlc; + ul_am.sn_field_len_present = true; + ul_am.sn_field_len.value = asn1::rrc_nr::sn_field_len_am_opts::size12; + ul_am.t_poll_retx.value = asn1::rrc_nr::t_poll_retx_opts::ms45; + ul_am.poll_pdu.value = asn1::rrc_nr::poll_pdu_opts::infinity; + ul_am.poll_byte.value = asn1::rrc_nr::poll_byte_opts::infinity; + ul_am.max_retx_thres.value = asn1::rrc_nr::ul_am_rlc_s::max_retx_thres_opts::t8; + auto& dl_am = out.rlc_cfg.am().dl_am_rlc; + dl_am.sn_field_len_present = true; + dl_am.sn_field_len.value = asn1::rrc_nr::sn_field_len_am_opts::size12; + dl_am.t_reassembly.value = t_reassembly_opts::ms35; + dl_am.t_status_prohibit.value = asn1::rrc_nr::t_status_prohibit_opts::ms0; + } + + // mac-LogicalChannelConfig -- Cond LCH-Setup + out.mac_lc_ch_cfg_present = true; + out.mac_lc_ch_cfg.ul_specific_params_present = true; + out.mac_lc_ch_cfg.ul_specific_params.prio = srb_id == srsran::nr_srb::srb1 ? 1 : 3; + out.mac_lc_ch_cfg.ul_specific_params.prioritised_bit_rate.value = + lc_ch_cfg_s::ul_specific_params_s_::prioritised_bit_rate_opts::infinity; + out.mac_lc_ch_cfg.ul_specific_params.bucket_size_dur.value = + lc_ch_cfg_s::ul_specific_params_s_::bucket_size_dur_opts::ms5; + out.mac_lc_ch_cfg.ul_specific_params.lc_ch_group_present = true; + out.mac_lc_ch_cfg.ul_specific_params.lc_ch_group = 0; + out.mac_lc_ch_cfg.ul_specific_params.sched_request_id_present = true; + out.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0; + out.mac_lc_ch_cfg.ul_specific_params.lc_ch_sr_mask = false; + out.mac_lc_ch_cfg.ul_specific_params.lc_ch_sr_delay_timer_applied = false; +} + +/// Fill DRB with parameters derived from cfg +void fill_drb(const rrc_nr_cfg_t& cfg, + const enb_bearer_manager::radio_bearer_t& rb, + srsran::nr_drb drb_id, + asn1::rrc_nr::rlc_bearer_cfg_s& out) +{ + out.lc_ch_id = rb.lcid; + out.served_radio_bearer_present = true; + out.served_radio_bearer.set_drb_id() = (uint8_t)drb_id; + + out.rlc_cfg_present = true; + out.rlc_cfg = cfg.five_qi_cfg.at(rb.five_qi).rlc_cfg; + + // MAC logical channel config + out.mac_lc_ch_cfg_present = true; + out.mac_lc_ch_cfg.ul_specific_params_present = true; + out.mac_lc_ch_cfg.ul_specific_params.prio = 11; // TODO + out.mac_lc_ch_cfg.ul_specific_params.prioritised_bit_rate = + lc_ch_cfg_s::ul_specific_params_s_::prioritised_bit_rate_opts::kbps0; + out.mac_lc_ch_cfg.ul_specific_params.bucket_size_dur = + asn1::rrc_nr::lc_ch_cfg_s::ul_specific_params_s_::bucket_size_dur_opts::ms100; + out.mac_lc_ch_cfg.ul_specific_params.lc_ch_group_present = true; + out.mac_lc_ch_cfg.ul_specific_params.lc_ch_group = 3; // TODO + out.mac_lc_ch_cfg.ul_specific_params.sched_request_id_present = true; + out.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0; // TODO + out.mac_lc_ch_cfg.ul_specific_params.lc_ch_sr_mask = false; + out.mac_lc_ch_cfg.ul_specific_params.lc_ch_sr_delay_timer_applied = false; + // TODO: add LC config to MAC +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/// Fill MasterCellConfig with gNB config +int fill_master_cell_cfg_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::cell_group_cfg_s& out) +{ + out.cell_group_id = 0; + out.rlc_bearer_to_add_mod_list.resize(1); + fill_srb(cfg, srsran::nr_srb::srb1, out.rlc_bearer_to_add_mod_list[0]); + + // mac-CellGroupConfig -- Need M + out.mac_cell_group_cfg_present = true; + out.mac_cell_group_cfg.sched_request_cfg_present = true; + out.mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list.resize(1); + out.mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list[0].sched_request_id = 0; + out.mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list[0].sr_trans_max.value = + sched_request_to_add_mod_s::sr_trans_max_opts::n64; + out.mac_cell_group_cfg.bsr_cfg_present = true; + out.mac_cell_group_cfg.bsr_cfg.periodic_bsr_timer.value = bsr_cfg_s::periodic_bsr_timer_opts::sf20; + out.mac_cell_group_cfg.bsr_cfg.retx_bsr_timer.value = bsr_cfg_s::retx_bsr_timer_opts::sf320; + out.mac_cell_group_cfg.tag_cfg_present = true; + out.mac_cell_group_cfg.tag_cfg.tag_to_add_mod_list.resize(1); + out.mac_cell_group_cfg.tag_cfg.tag_to_add_mod_list[0].tag_id = 0; + out.mac_cell_group_cfg.tag_cfg.tag_to_add_mod_list[0].time_align_timer.value = time_align_timer_opts::infinity; + out.mac_cell_group_cfg.phr_cfg_present = true; + phr_cfg_s& phr = out.mac_cell_group_cfg.phr_cfg.set_setup(); + phr.phr_periodic_timer.value = asn1::rrc_nr::phr_cfg_s::phr_periodic_timer_opts::sf500; + phr.phr_prohibit_timer.value = asn1::rrc_nr::phr_cfg_s::phr_prohibit_timer_opts::sf200; + phr.phr_tx_pwr_factor_change.value = asn1::rrc_nr::phr_cfg_s::phr_tx_pwr_factor_change_opts::db3; + phr.multiple_phr = false; + phr.dummy = false; + phr.phr_type2_other_cell = false; + phr.phr_mode_other_cg.value = asn1::rrc_nr::phr_cfg_s::phr_mode_other_cg_opts::real; + out.mac_cell_group_cfg.skip_ul_tx_dynamic = false; + out.mac_cell_group_cfg.phr_cfg_present = false; // Note: not supported + + // physicalCellGroupConfig -- Need M + out.phys_cell_group_cfg_present = true; + out.phys_cell_group_cfg.p_nr_fr1_present = true; + out.phys_cell_group_cfg.p_nr_fr1 = 10; + out.phys_cell_group_cfg.pdsch_harq_ack_codebook.value = + phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts::dynamic_value; + + // spCellConfig -- Need M + out.sp_cell_cfg_present = true; + fill_sp_cell_cfg_from_enb_cfg(cfg, cc, out.sp_cell_cfg); + + return SRSRAN_SUCCESS; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +int fill_mib_from_enb_cfg(const rrc_cell_cfg_nr_t& cell_cfg, asn1::rrc_nr::mib_s& mib) +{ + mib.sys_frame_num.from_number(0); + switch (cell_cfg.phy_cell.carrier.scs) { + case srsran_subcarrier_spacing_15kHz: + case srsran_subcarrier_spacing_60kHz: + mib.sub_carrier_spacing_common.value = mib_s::sub_carrier_spacing_common_opts::scs15or60; + break; + case srsran_subcarrier_spacing_30kHz: + case srsran_subcarrier_spacing_120kHz: + mib.sub_carrier_spacing_common.value = mib_s::sub_carrier_spacing_common_opts::scs30or120; + break; + default: + srsran_terminate("Invalid carrier SCS=%d Hz", SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs)); + } + mib.ssb_subcarrier_offset = cell_cfg.ssb_offset; + mib.dmrs_type_a_position.value = mib_s::dmrs_type_a_position_opts::pos2; + mib.pdcch_cfg_sib1.search_space_zero = 0; + mib.pdcch_cfg_sib1.ctrl_res_set_zero = cell_cfg.coreset0_idx; + mib.cell_barred.value = mib_s::cell_barred_opts::not_barred; + mib.intra_freq_resel.value = mib_s::intra_freq_resel_opts::allowed; + mib.spare.from_number(0); + return SRSRAN_SUCCESS; +} + +// Called for SA and NSA +void fill_pdcch_cfg_common(const rrc_nr_cfg_t& cfg, uint32_t cc, pdcch_cfg_common_s& out) +{ + auto& cell_cfg = cfg.cell_list[cc]; + + out.ctrl_res_set_zero_present = false; + out.search_space_zero_present = false; + + out.common_ctrl_res_set_present = cell_cfg.pdcch_cfg_common.common_ctrl_res_set_present; + out.common_ctrl_res_set = cell_cfg.pdcch_cfg_common.common_ctrl_res_set; + out.common_search_space_list = cell_cfg.pdcch_cfg_common.common_search_space_list; + + out.search_space_sib1_present = true; + out.search_space_sib1 = 0; + out.search_space_other_sys_info_present = true; + out.search_space_other_sys_info = 1; + out.paging_search_space_present = true; + out.paging_search_space = 1; + out.ra_search_space_present = true; + out.ra_search_space = 1; +} + +void fill_pdsch_cfg_common(const rrc_cell_cfg_nr_t& cell_cfg, pdsch_cfg_common_s& cfg) +{ + cfg.pdsch_time_domain_alloc_list.resize(1); + cfg.pdsch_time_domain_alloc_list[0].map_type.value = pdsch_time_domain_res_alloc_s::map_type_opts::type_a; + cfg.pdsch_time_domain_alloc_list[0].start_symbol_and_len = 40; +} + +// Called for SA +void fill_init_dl_bwp(const rrc_nr_cfg_t& cfg, uint32_t cc, bwp_dl_common_s& out) +{ + auto& cell_cfg = cfg.cell_list[cc]; + + out.generic_params.location_and_bw = 14025; + out.generic_params.subcarrier_spacing = (subcarrier_spacing_opts::options)cell_cfg.phy_cell.carrier.scs; + + out.pdcch_cfg_common_present = true; + fill_pdcch_cfg_common(cfg, cc, out.pdcch_cfg_common.set_setup()); + out.pdsch_cfg_common_present = true; + fill_pdsch_cfg_common(cell_cfg, out.pdsch_cfg_common.set_setup()); +} + +void fill_dl_cfg_common_sib(const rrc_nr_cfg_t& cfg, uint32_t cc, dl_cfg_common_sib_s& out) +{ + auto& cell_cfg = cfg.cell_list[cc]; + + uint32_t scs_hz = SRSRAN_SUBC_SPACING_NR(cell_cfg.phy_cell.carrier.scs); + uint32_t prb_bw = scs_hz * SRSRAN_NRE; + + srsran::srsran_band_helper band_helper; + out.freq_info_dl.freq_band_list.resize(1); + out.freq_info_dl.freq_band_list[0].freq_band_ind_nr_present = true; + out.freq_info_dl.freq_band_list[0].freq_band_ind_nr = cell_cfg.band; + double ssb_freq_start = cell_cfg.ssb_freq_hz - SRSRAN_SSB_BW_SUBC * scs_hz / 2; + double offset_point_a_hz = ssb_freq_start - band_helper.nr_arfcn_to_freq(cell_cfg.dl_absolute_freq_point_a); + uint32_t offset_point_a_prbs = offset_point_a_hz / prb_bw; + out.freq_info_dl.offset_to_point_a = offset_point_a_prbs; + out.freq_info_dl.scs_specific_carrier_list.resize(1); + out.freq_info_dl.scs_specific_carrier_list[0].offset_to_carrier = cell_cfg.phy_cell.carrier.offset_to_carrier; + out.freq_info_dl.scs_specific_carrier_list[0].subcarrier_spacing = + (subcarrier_spacing_opts::options)cell_cfg.phy_cell.carrier.scs; + out.freq_info_dl.scs_specific_carrier_list[0].carrier_bw = cell_cfg.phy_cell.carrier.nof_prb; + + fill_init_dl_bwp(cfg, cc, out.init_dl_bwp); + // disable InitialBWP-Only fields + out.init_dl_bwp.pdcch_cfg_common.setup().ctrl_res_set_zero_present = false; + out.init_dl_bwp.pdcch_cfg_common.setup().search_space_zero_present = false; + + out.bcch_cfg.mod_period_coeff.value = bcch_cfg_s::mod_period_coeff_opts::n4; + + out.pcch_cfg.default_paging_cycle.value = paging_cycle_opts::rf128; + out.pcch_cfg.nand_paging_frame_offset.set_one_t(); + out.pcch_cfg.ns.value = pcch_cfg_s::ns_opts::one; +} + +void fill_ul_cfg_common_sib(const rrc_nr_cfg_t& cfg, uint32_t cc, ul_cfg_common_sib_s& out) +{ + auto& cell_cfg = cfg.cell_list[cc]; + srsran::srsran_band_helper band_helper; + + out.freq_info_ul.freq_band_list.resize(1); + out.freq_info_ul.freq_band_list[0].freq_band_ind_nr_present = true; + out.freq_info_ul.freq_band_list[0].freq_band_ind_nr = cell_cfg.band; + + out.freq_info_ul.absolute_freq_point_a_present = true; + out.freq_info_ul.absolute_freq_point_a = + band_helper.get_abs_freq_point_a_arfcn(cell_cfg.phy_cell.carrier.nof_prb, cell_cfg.ul_arfcn); + + out.freq_info_ul.scs_specific_carrier_list.resize(1); + out.freq_info_ul.scs_specific_carrier_list[0].offset_to_carrier = cell_cfg.phy_cell.carrier.offset_to_carrier; + out.freq_info_ul.scs_specific_carrier_list[0].subcarrier_spacing = + (subcarrier_spacing_opts::options)cell_cfg.phy_cell.carrier.scs; + out.freq_info_ul.scs_specific_carrier_list[0].carrier_bw = cell_cfg.phy_cell.carrier.nof_prb; + + out.freq_info_ul.p_max_present = true; + out.freq_info_ul.p_max = 10; + + out.init_ul_bwp.generic_params.location_and_bw = 14025; + out.init_ul_bwp.generic_params.subcarrier_spacing.value = + (subcarrier_spacing_opts::options)cell_cfg.phy_cell.carrier.scs; + + out.init_ul_bwp.rach_cfg_common_present = true; + fill_rach_cfg_common(cfg, cc, out.init_ul_bwp.rach_cfg_common.set_setup()); + + out.init_ul_bwp.pusch_cfg_common_present = true; + pusch_cfg_common_s& pusch = out.init_ul_bwp.pusch_cfg_common.set_setup(); + pusch.pusch_time_domain_alloc_list.resize(1); + pusch.pusch_time_domain_alloc_list[0].k2_present = true; + pusch.pusch_time_domain_alloc_list[0].k2 = 4; + pusch.pusch_time_domain_alloc_list[0].map_type.value = pusch_time_domain_res_alloc_s::map_type_opts::type_a; + pusch.pusch_time_domain_alloc_list[0].start_symbol_and_len = 27; + pusch.p0_nominal_with_grant_present = true; + pusch.p0_nominal_with_grant = -76; + + out.init_ul_bwp.pucch_cfg_common_present = true; + pucch_cfg_common_s& pucch = out.init_ul_bwp.pucch_cfg_common.set_setup(); + pucch.pucch_res_common_present = true; + pucch.pucch_res_common = 11; + pucch.pucch_group_hop.value = pucch_cfg_common_s::pucch_group_hop_opts::neither; + pucch.p0_nominal_present = true; + pucch.p0_nominal = -90; + + out.time_align_timer_common.value = time_align_timer_opts::infinity; +} + +int fill_serv_cell_cfg_common_sib(const rrc_nr_cfg_t& cfg, uint32_t cc, serving_cell_cfg_common_sib_s& out) +{ + auto& cell_cfg = cfg.cell_list[cc]; + + fill_dl_cfg_common_sib(cfg, cc, out.dl_cfg_common); + + out.ul_cfg_common_present = true; + fill_ul_cfg_common_sib(cfg, cc, out.ul_cfg_common); + + out.ssb_positions_in_burst.in_one_group.from_number(0x80); + + out.ssb_periodicity_serving_cell.value = serving_cell_cfg_common_sib_s::ssb_periodicity_serving_cell_opts::ms10; + + // The time advance offset is not supported by the current PHY + out.n_timing_advance_offset_present = true; + out.n_timing_advance_offset = serving_cell_cfg_common_sib_s::n_timing_advance_offset_opts::n0; + + // TDD UL-DL config + if (cell_cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { + out.tdd_ul_dl_cfg_common_present = true; + fill_tdd_ul_dl_config_common(cell_cfg, out.tdd_ul_dl_cfg_common); + } + + out.ss_pbch_block_pwr = cell_cfg.pdsch_rs_power; + + return SRSRAN_SUCCESS; +} + +int fill_sib1_from_enb_cfg(const rrc_nr_cfg_t& cfg, uint32_t cc, asn1::rrc_nr::sib1_s& sib1) +{ + const rrc_cell_cfg_nr_t& cell_cfg = cfg.cell_list[cc]; + + sib1.cell_sel_info_present = true; + sib1.cell_sel_info.q_rx_lev_min = -70; + sib1.cell_sel_info.q_qual_min_present = true; + sib1.cell_sel_info.q_qual_min = -20; + + sib1.cell_access_related_info.plmn_id_list.resize(1); + sib1.cell_access_related_info.plmn_id_list[0].plmn_id_list.resize(1); + srsran::plmn_id_t plmn; + plmn.from_number(cfg.mcc, cfg.mnc); + srsran::to_asn1(&sib1.cell_access_related_info.plmn_id_list[0].plmn_id_list[0], plmn); + sib1.cell_access_related_info.plmn_id_list[0].tac_present = true; + sib1.cell_access_related_info.plmn_id_list[0].tac.from_number(cell_cfg.tac); + sib1.cell_access_related_info.plmn_id_list[0].cell_id.from_number((cfg.enb_id << 8U) + cell_cfg.phy_cell.cell_id); + sib1.cell_access_related_info.plmn_id_list[0].cell_reserved_for_oper.value = + plmn_id_info_s::cell_reserved_for_oper_opts::not_reserved; + + sib1.conn_est_fail_ctrl_present = true; + sib1.conn_est_fail_ctrl.conn_est_fail_count.value = conn_est_fail_ctrl_s::conn_est_fail_count_opts::n1; + sib1.conn_est_fail_ctrl.conn_est_fail_offset_validity.value = + conn_est_fail_ctrl_s::conn_est_fail_offset_validity_opts::s30; + sib1.conn_est_fail_ctrl.conn_est_fail_offset_present = true; + sib1.conn_est_fail_ctrl.conn_est_fail_offset = 1; + + // sib1.si_sched_info_present = true; + // sib1.si_sched_info.si_request_cfg.rach_occasions_si_present = true; + // sib1.si_sched_info.si_request_cfg.rach_occasions_si.rach_cfg_si.ra_resp_win.value = + // rach_cfg_generic_s::ra_resp_win_opts::sl8; + // sib1.si_sched_info.si_win_len.value = si_sched_info_s::si_win_len_opts::s20; + // sib1.si_sched_info.sched_info_list.resize(1); + // sib1.si_sched_info.sched_info_list[0].si_broadcast_status.value = + // sched_info_s::si_broadcast_status_opts::broadcasting; sib1.si_sched_info.sched_info_list[0].si_periodicity.value = + // sched_info_s::si_periodicity_opts::rf16; sib1.si_sched_info.sched_info_list[0].sib_map_info.resize(1); + // // scheduling of SI messages + // sib1.si_sched_info.sched_info_list[0].sib_map_info[0].type.value = sib_type_info_s::type_opts::sib_type2; + // sib1.si_sched_info.sched_info_list[0].sib_map_info[0].value_tag_present = true; + // sib1.si_sched_info.sched_info_list[0].sib_map_info[0].value_tag = 0; + + sib1.serving_cell_cfg_common_present = true; + HANDLE_ERROR(fill_serv_cell_cfg_common_sib(cfg, cc, sib1.serving_cell_cfg_common)); + + sib1.ue_timers_and_consts_present = true; + sib1.ue_timers_and_consts.t300.value = ue_timers_and_consts_s::t300_opts::ms1000; + sib1.ue_timers_and_consts.t301.value = ue_timers_and_consts_s::t301_opts::ms1000; + sib1.ue_timers_and_consts.t310.value = ue_timers_and_consts_s::t310_opts::ms1000; + sib1.ue_timers_and_consts.n310.value = ue_timers_and_consts_s::n310_opts::n1; + sib1.ue_timers_and_consts.t311.value = ue_timers_and_consts_s::t311_opts::ms30000; + sib1.ue_timers_and_consts.n311.value = ue_timers_and_consts_s::n311_opts::n1; + sib1.ue_timers_and_consts.t319.value = ue_timers_and_consts_s::t319_opts::ms1000; + + return SRSRAN_SUCCESS; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +bool compute_diff_radio_bearer_cfg(const rrc_nr_cfg_t& cfg, + const radio_bearer_cfg_s& prev_bearers, + const radio_bearer_cfg_s& next_bearers, + radio_bearer_cfg_s& diff) +{ + // Compute SRB differences + std::vector srbs_to_rem; + srsran::compute_cfg_diff( + prev_bearers.srb_to_add_mod_list, next_bearers.srb_to_add_mod_list, diff.srb_to_add_mod_list, srbs_to_rem); + + // Compute DRB differences + srsran::compute_cfg_diff(prev_bearers.drb_to_add_mod_list, + next_bearers.drb_to_add_mod_list, + diff.drb_to_add_mod_list, + diff.drb_to_release_list); + + return diff.srb_to_add_mod_list.size() > 0 or diff.drb_to_release_list.size() > 0 or + diff.drb_to_add_mod_list.size() > 0; +} + +int fill_cellgroup_with_radio_bearer_cfg(const rrc_nr_cfg_t& cfg, + const uint32_t rnti, + const enb_bearer_manager& bearer_mapper, + const asn1::rrc_nr::radio_bearer_cfg_s& bearers, + asn1::rrc_nr::cell_group_cfg_s& out) +{ + out.rlc_bearer_to_add_mod_list.clear(); + out.rlc_bearer_to_release_list.clear(); + + // Add SRBs + for (const srb_to_add_mod_s& srb : bearers.srb_to_add_mod_list) { + out.rlc_bearer_to_add_mod_list.push_back({}); + fill_srb(cfg, (srsran::nr_srb)srb.srb_id, out.rlc_bearer_to_add_mod_list.back()); + } + // Add DRBs + for (const drb_to_add_mod_s& drb : bearers.drb_to_add_mod_list) { + out.rlc_bearer_to_add_mod_list.push_back({}); + uint32_t lcid = drb.drb_id + srsran::MAX_NR_SRB_ID; + enb_bearer_manager::radio_bearer_t rb = bearer_mapper.get_lcid_bearer(rnti, lcid); + if (rb.is_valid() and cfg.five_qi_cfg.find(rb.five_qi) != cfg.five_qi_cfg.end()) { + fill_drb(cfg, rb, (srsran::nr_drb)drb.drb_id, out.rlc_bearer_to_add_mod_list.back()); + } else { + return SRSRAN_ERROR; + } + } + + // Release DRBs + for (uint8_t drb_id : bearers.drb_to_release_list) { + out.rlc_bearer_to_release_list.push_back(drb_id); + } + + return SRSRAN_SUCCESS; +} + +} // namespace srsenb diff --git a/srsgnb/src/stack/rrc/rrc_nr.cc b/srsgnb/src/stack/rrc/rrc_nr.cc new file mode 100644 index 0000000000..99ec025bd8 --- /dev/null +++ b/srsgnb/src/stack/rrc/rrc_nr.cc @@ -0,0 +1,767 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/rrc/rrc_nr.h" +#include "srsenb/hdr/common/common_enb.h" +#include "srsgnb/hdr/stack/rrc/cell_asn1_config.h" +#include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h" +#include "srsgnb/hdr/stack/rrc/rrc_nr_du_manager.h" +#include "srsgnb/hdr/stack/rrc/rrc_nr_ue.h" +#include "srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h" +#include "srsran/asn1/rrc_nr_utils.h" +#include "srsran/common/bearer_manager.h" +#include "srsran/common/common_nr.h" +#include "srsran/common/phy_cfg_nr_default.h" +#include "srsran/common/standard_streams.h" +#include "srsran/common/string_helpers.h" + +using namespace asn1::rrc_nr; + +namespace srsenb { + +rrc_nr::rrc_nr(srsran::task_sched_handle task_sched_) : + logger(srslog::fetch_basic_logger("RRC-NR")), task_sched(task_sched_) +{} + +rrc_nr::~rrc_nr() {} + +int rrc_nr::init(const rrc_nr_cfg_t& cfg_, + phy_interface_stack_nr* phy_, + mac_interface_rrc_nr* mac_, + rlc_interface_rrc* rlc_, + pdcp_interface_rrc* pdcp_, + ngap_interface_rrc_nr* ngap_, + gtpu_interface_rrc* gtpu_, + enb_bearer_manager& bearer_mapper_, + rrc_eutra_interface_rrc_nr* rrc_eutra_) +{ + phy = phy_; + mac = mac_; + rlc = rlc_; + pdcp = pdcp_; + ngap = ngap_; + gtpu = gtpu_; + bearer_mapper = &bearer_mapper_; + rrc_eutra = rrc_eutra_; + + cfg = cfg_; + + // log cell configs + for (uint32_t i = 0; i < cfg.cell_list.size(); ++i) { + const auto& cell = cfg.cell_list.at(i); + logger.info("Cell idx=%d, pci=%d, nr_dl_arfcn=%d, nr_ul_arfcn=%d, band=%d, duplex=%s, n_rb_dl=%d, ssb_arfcn=%d", + i, + cell.phy_cell.carrier.pci, + cell.dl_arfcn, + cell.ul_arfcn, + cell.band, + cell.duplex_mode == SRSRAN_DUPLEX_MODE_FDD ? "FDD" : "TDD", + cell.phy_cell.carrier.nof_prb, + cell.ssb_absolute_freq_point); + } + + du_cfg = std::make_unique(cfg); + for (uint32_t i = 0; i < cfg.cell_list.size(); ++i) { + int ret = du_cfg->add_cell(); + srsran_assert(ret == SRSRAN_SUCCESS, "Failed to configure NR cell %d", i); + } + + // Generate cell config structs + cell_ctxt = std::make_unique(); + std::unique_ptr master_cell_group = std::make_unique(); + int ret = fill_master_cell_cfg_from_enb_cfg(cfg, 0, *master_cell_group); + srsran_assert(ret == SRSRAN_SUCCESS, "Failed to configure MasterCellGroup"); + cell_ctxt->master_cell_group = std::move(master_cell_group); + + // derived + slot_dur_ms = 1; + + if (generate_sibs() != SRSRAN_SUCCESS) { + logger.error("Couldn't generate SIB messages."); + return SRSRAN_ERROR; + } + + config_phy(); // if PHY is not yet initialized, config will be stored and applied on initialization + config_mac(); + + logger.info("Number of 5QI %d", cfg.five_qi_cfg.size()); + for (const std::pair& five_qi_cfg : cfg.five_qi_cfg) { + logger.info("5QI configuration. 5QI=%d", five_qi_cfg.first); + if (logger.info.enabled()) { + asn1::json_writer js{}; + five_qi_cfg.second.pdcp_cfg.to_json(js); + logger.info("PDCP NR configuration: %s", js.to_string().c_str()); + js = {}; + five_qi_cfg.second.rlc_cfg.to_json(js); + logger.info("RLC NR configuration: %s", js.to_string().c_str()); + } + } + logger.info("NIA preference list: NIA%d, NIA%d, NIA%d", + cfg.nia_preference_list[0], + cfg.nia_preference_list[1], + cfg.nia_preference_list[2]); + logger.info("NEA preference list: NEA%d, NEA%d, NEA%d", + cfg.nea_preference_list[0], + cfg.nea_preference_list[1], + cfg.nea_preference_list[2]); + running = true; + + return SRSRAN_SUCCESS; +} + +void rrc_nr::stop() +{ + if (running) { + running = false; + } + users.clear(); +} + +template +void rrc_nr::log_rrc_message(const char* source, + const direction_t dir, + srsran::const_byte_span pdu, + const T& msg, + const char* msg_type) +{ + if (logger.debug.enabled()) { + asn1::json_writer json_writer; + msg.to_json(json_writer); + logger.debug(pdu.data(), pdu.size(), "%s - %s %s (%d B)", source, (dir == Rx) ? "Rx" : "Tx", msg_type, pdu.size()); + logger.debug("Content:%s", json_writer.to_string().c_str()); + } else if (logger.info.enabled()) { + logger.info(pdu.data(), pdu.size(), "%s - %s %s (%d B)", source, (dir == Rx) ? "Rx" : "Tx", msg_type, pdu.size()); + } +} +template void rrc_nr::log_rrc_message(const char* source, + const direction_t dir, + srsran::const_byte_span pdu, + const dl_ccch_msg_s& msg, + const char* msg_type); +template void rrc_nr::log_rrc_message(const char* source, + const direction_t dir, + srsran::const_byte_span pdu, + const dl_dcch_msg_s& msg, + const char* msg_type); +template void rrc_nr::log_rrc_message(const char* source, + const direction_t dir, + srsran::const_byte_span pdu, + const cell_group_cfg_s& msg, + const char* msg_type); +template void rrc_nr::log_rrc_message(const char* source, + const direction_t dir, + srsran::const_byte_span pdu, + const radio_bearer_cfg_s& msg, + const char* msg_type); + +void rrc_nr::log_rx_pdu_fail(uint16_t rnti, + uint32_t lcid, + srsran::const_byte_span pdu, + const char* cause_str, + bool log_hex) +{ + if (log_hex) { + logger.error( + pdu.data(), pdu.size(), "Rx %s PDU, rnti=0x%x - Discarding. Cause: %s", get_rb_name(lcid), rnti, cause_str); + } else { + logger.error("Rx %s PDU, rnti=0x%x - Discarding. Cause: %s", get_rb_name(lcid), rnti, cause_str); + } +} + +/* @brief PRIVATE function, gets called by sgnb_addition_request + * + * This function WILL NOT TRIGGER the RX MSG3 activity timer + */ +int rrc_nr::add_user(uint16_t rnti, uint32_t pcell_cc_idx, bool start_msg3_timer) +{ + if (users.contains(rnti) == 0) { + // If in the ue ctor, "start_msg3_timer" is set to true, this will start the MSG3 RX TIMEOUT at ue creation + users.insert(rnti, std::make_unique(this, rnti, pcell_cc_idx, start_msg3_timer)); + rlc->add_user(rnti); + pdcp->add_user(rnti); + logger.info("Added new user rnti=0x%x", rnti); + return SRSRAN_SUCCESS; + } + logger.error("Adding user rnti=0x%x (already exists)", rnti); + return SRSRAN_ERROR; +} + +/* @brief PUBLIC function, gets called by mac_nr::rach_detected + * + * This function is called from PRACH worker (can wait) and WILL TRIGGER the RX MSG3 activity timer + */ +int rrc_nr::add_user(uint16_t rnti, uint32_t pcell_cc_idx) +{ + // Set "triggered_by_rach" to true to start the MSG3 RX TIMEOUT + return add_user(rnti, pcell_cc_idx, true); +} + +void rrc_nr::rem_user(uint16_t rnti) +{ + auto user_it = users.find(rnti); + if (user_it != users.end()) { + // First remove MAC and GTPU to stop processing DL/UL traffic for this user + mac->remove_ue(rnti); // MAC handles PHY + rlc->rem_user(rnti); + pdcp->rem_user(rnti); + users.erase(rnti); + + srsran::console("Disconnecting rnti=0x%x.\n", rnti); + logger.info("Removed user rnti=0x%x", rnti); + } else { + logger.error("Removing user rnti=0x%x (does not exist)", rnti); + } +} + +/// This function is called when the INACTIVITY TIMER FOR +int rrc_nr::rrc_release(uint16_t rnti) +{ + // TODO: we do not have yet a defined procedure to handle this + return SRSRAN_SUCCESS; +} + +/* Function called by MAC after the reception of a C-RNTI CE indicating that the UE still has a + * valid RNTI. + */ +int rrc_nr::update_user(uint16_t new_rnti, uint16_t old_rnti) +{ + if (new_rnti == old_rnti) { + logger.warning("rnti=0x%x received MAC CRNTI CE with same rnti", new_rnti); + return SRSRAN_ERROR; + } + + // Remove new_rnti + auto new_ue_it = users.find(new_rnti); + if (new_ue_it != users.end()) { + new_ue_it->second->deactivate_bearers(); + task_sched.defer_task([this, new_rnti]() { rem_user(new_rnti); }); + } + + // Send Reconfiguration to old_rnti if is RRC_CONNECT or RRC Release if already released here + auto old_it = users.find(old_rnti); + if (old_it == users.end()) { + logger.info("rnti=0x%x received MAC CRNTI CE: 0x%x, but old context is unavailable", new_rnti, old_rnti); + return SRSRAN_ERROR; + } + ue* ue_ptr = old_it->second.get(); + + logger.info("Resuming rnti=0x%x RRC connection due to received C-RNTI CE from rnti=0x%x.", old_rnti, new_rnti); + ue_ptr->crnti_ce_received(); + + return SRSRAN_SUCCESS; +} + +void rrc_nr::set_activity_user(uint16_t rnti) +{ + auto it = users.find(rnti); + if (it == users.end()) { + logger.info("rnti=0x%x not found. Can't set activity", rnti); + return; + } + ue* ue_ptr = it->second.get(); + + // Restart inactivity timer for RRC-NR + ue_ptr->set_activity(); + + // inform EUTRA RRC about user activity + if (ue_ptr->is_endc()) { + // inform EUTRA RRC about user activity + rrc_eutra->set_activity_user(ue_ptr->get_eutra_rnti()); + } +} + +void rrc_nr::config_phy() +{ + srsenb::phy_interface_rrc_nr::common_cfg_t common_cfg = {}; + common_cfg.carrier = cfg.cell_list[0].phy_cell.carrier; + fill_phy_pdcch_cfg_common(du_cfg->cell(0), &common_cfg.pdcch); + bool ret = srsran::fill_phy_pdcch_cfg( + cell_ctxt->master_cell_group->sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(), &common_cfg.pdcch); + srsran_assert(ret, "Failed to generate Dedicated PDCCH config"); + srsran::make_phy_rach_cfg(du_cfg->cell(0).serv_cell_cfg_common().ul_cfg_common.init_ul_bwp.rach_cfg_common.setup(), + cfg.cell_list[0].duplex_mode, + &common_cfg.prach); + common_cfg.duplex_mode = cfg.cell_list[0].duplex_mode; + ret = srsran::fill_phy_ssb_cfg( + cfg.cell_list[0].phy_cell.carrier, du_cfg->cell(0).serv_cell_cfg_common(), &common_cfg.ssb); + srsran_assert(ret, "Failed to generate PHY config"); + if (phy->set_common_cfg(common_cfg) < SRSRAN_SUCCESS) { + logger.error("Couldn't set common PHY config"); + return; + } +} + +void rrc_nr::config_mac() +{ + uint32_t cc = 0; + // Fill MAC scheduler configuration for SIBs + // TODO: use parsed cell NR cfg configuration + srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{}; + ref_args.duplex = cfg.cell_list[cc].duplex_mode == SRSRAN_DUPLEX_MODE_TDD + ? srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4 + : srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; + std::vector sched_cells_cfg(1, get_default_cell_cfg(srsran::phy_cfg_nr_default_t{ref_args})); + sched_nr_cell_cfg_t& cell = sched_cells_cfg[cc]; + + // Derive cell config from rrc_nr_cfg_t + fill_phy_pdcch_cfg_common(du_cfg->cell(cc), &cell.bwps[0].pdcch); + bool ret = srsran::fill_phy_pdcch_cfg( + cell_ctxt->master_cell_group->sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(), &cell.bwps[0].pdcch); + srsran_assert(ret, "Failed to generate Dedicated PDCCH config"); + cell.pci = cfg.cell_list[cc].phy_cell.carrier.pci; + cell.nof_layers = cfg.cell_list[cc].phy_cell.carrier.max_mimo_layers; + cell.dl_cell_nof_prb = cfg.cell_list[cc].phy_cell.carrier.nof_prb; + cell.ul_cell_nof_prb = cfg.cell_list[cc].phy_cell.carrier.nof_prb; + cell.dl_center_frequency_hz = cfg.cell_list[cc].phy_cell.carrier.dl_center_frequency_hz; + cell.ul_center_frequency_hz = cfg.cell_list[cc].phy_cell.carrier.ul_center_frequency_hz; + cell.ssb_center_freq_hz = cfg.cell_list[cc].phy_cell.carrier.ssb_center_freq_hz; + cell.dmrs_type_a_position = du_cfg->cell(cc).mib.dmrs_type_a_position; + cell.pdcch_cfg_sib1 = du_cfg->cell(cc).mib.pdcch_cfg_sib1; + if (du_cfg->cell(cc).serv_cell_cfg_common().tdd_ul_dl_cfg_common_present) { + cell.tdd_ul_dl_cfg_common.emplace(du_cfg->cell(cc).serv_cell_cfg_common().tdd_ul_dl_cfg_common); + } + cell.dl_cfg_common = du_cfg->cell(cc).serv_cell_cfg_common().dl_cfg_common; + cell.ul_cfg_common = du_cfg->cell(cc).serv_cell_cfg_common().ul_cfg_common; + cell.ss_pbch_block_power = du_cfg->cell(cc).serv_cell_cfg_common().ss_pbch_block_pwr; + bool valid_cfg = srsran::make_pdsch_cfg_from_serv_cell(cell_ctxt->master_cell_group->sp_cell_cfg.sp_cell_cfg_ded, + &cell.bwps[0].pdsch); + srsran_assert(valid_cfg, "Invalid NR cell configuration."); + cell.ssb_positions_in_burst = du_cfg->cell(cc).serv_cell_cfg_common().ssb_positions_in_burst; + cell.ssb_periodicity_ms = du_cfg->cell(cc).serv_cell_cfg_common().ssb_periodicity_serving_cell.to_number(); + cell.ssb_scs.value = (subcarrier_spacing_e::options)cfg.cell_list[0].phy_cell.carrier.scs; + cell.ssb_offset = du_cfg->cell(cc).mib.ssb_subcarrier_offset; + if (not cfg.is_standalone) { + const serving_cell_cfg_common_s& serv_cell = + cell_ctxt->master_cell_group->sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common; + // Derive cell config from ASN1 + cell.ssb_scs = serv_cell.ssb_subcarrier_spacing; + } + + // Set SIB1 and SI messages + cell.sibs.resize(cell_ctxt->sib_buffer.size()); + for (uint32_t i = 0; i < cell_ctxt->sib_buffer.size(); i++) { + cell.sibs[i].len = cell_ctxt->sib_buffer[i]->N_bytes; + if (i == 0) { + cell.sibs[i].period_rf = 16; // SIB1 is always 16 rf + cell.sibs[i].si_window_slots = 160; + } else { + cell.sibs[i].period_rf = du_cfg->cell(0).sib1.si_sched_info.sched_info_list[i - 1].si_periodicity.to_number(); + cell.sibs[i].si_window_slots = du_cfg->cell(0).sib1.si_sched_info.si_win_len.to_number(); + } + } + + // Configure MAC/scheduler + mac->cell_cfg(sched_cells_cfg); + + // Make default UE PHY config object + cell_ctxt->default_phy_ue_cfg_nr = get_common_ue_phy_cfg(cell); +} + +int32_t rrc_nr::generate_sibs() +{ + if (not cfg.is_standalone) { + return SRSRAN_SUCCESS; + } + + // SIB1 packing + const si_sched_info_s::sched_info_list_l_& sched_info = du_cfg->cell(0).sib1.si_sched_info.sched_info_list; + + // SI messages packing + cell_ctxt->sibs.resize(1); + sib2_s& sib2 = cell_ctxt->sibs[0].set_sib2(); + sib2.cell_resel_info_common.q_hyst.value = sib2_s::cell_resel_info_common_s_::q_hyst_opts::db5; + + // msg is array of SI messages, each SI message msg[i] may contain multiple SIBs + // all SIBs in a SI message msg[i] share the same periodicity + const uint32_t nof_messages = + du_cfg->cell(0).sib1.si_sched_info_present ? du_cfg->cell(0).sib1.si_sched_info.sched_info_list.size() : 0; + cell_ctxt->sib_buffer.reserve(nof_messages + 1); + asn1::dyn_array msg(nof_messages + 1); + + // Copy SIB1 to first SI message + msg[0].msg.set_c1().set_sib_type1() = du_cfg->cell(0).sib1; + + // Copy rest of SIBs + for (uint32_t sched_info_elem = 0; sched_info_elem < nof_messages; sched_info_elem++) { + uint32_t msg_index = sched_info_elem + 1; // first msg is SIB1, therefore start with second + + msg[msg_index].msg.set_c1().set_sys_info().crit_exts.set_sys_info(); + auto& sib_list = msg[msg_index].msg.c1().sys_info().crit_exts.sys_info().sib_type_and_info; + + for (uint32_t mapping = 0; mapping < sched_info[sched_info_elem].sib_map_info.size(); ++mapping) { + uint32_t sibidx = sched_info[sched_info_elem].sib_map_info[mapping].type; // SIB2 == 0 + sib_list.push_back(cell_ctxt->sibs[sibidx]); + } + } + + // Pack payload for all messages + for (uint32_t msg_index = 0; msg_index < nof_messages + 1; msg_index++) { + srsran::unique_byte_buffer_t sib_pdu = pack_into_pdu(msg[msg_index]); + if (sib_pdu == nullptr) { + logger.error("Failed to pack SIB"); + return SRSRAN_ERROR; + } + cell_ctxt->sib_buffer.push_back(std::move(sib_pdu)); + + // Log SIBs in JSON format + fmt::memory_buffer strbuf; + if (msg_index == 0) { + fmt::format_to(strbuf, "SIB1 payload"); + } else { + fmt::format_to(strbuf, "SI message={} payload", msg_index + 1); + } + log_rrc_message("BCCH", Tx, *cell_ctxt->sib_buffer.back(), msg[msg_index], srsran::to_c_str(strbuf)); + } + + return SRSRAN_SUCCESS; +} + +/******************************************************************************* + MAC interface +*******************************************************************************/ + +int rrc_nr::read_pdu_bcch_bch(const uint32_t tti, srsran::byte_buffer_t& buffer) +{ + if (du_cfg->cell(0).packed_mib == nullptr || buffer.get_tailroom() < du_cfg->cell(0).packed_mib->N_bytes) { + return SRSRAN_ERROR; + } + buffer = *du_cfg->cell(0).packed_mib; + return SRSRAN_SUCCESS; +} + +int rrc_nr::read_pdu_bcch_dlsch(uint32_t sib_index, srsran::byte_buffer_t& buffer) +{ + if (sib_index >= cell_ctxt->sib_buffer.size()) { + logger.error("SI%s%d is not a configured SIB.", sib_index == 0 ? "B" : "", sib_index + 1); + return SRSRAN_ERROR; + } + + buffer = *cell_ctxt->sib_buffer[sib_index]; + + return SRSRAN_SUCCESS; +} + +void rrc_nr::get_metrics(srsenb::rrc_metrics_t& m) +{ + if (running) { + for (auto& ue : users) { + rrc_ue_metrics_t ue_metrics; + ue.second->get_metrics(ue_metrics); + m.ues.push_back(ue_metrics); + } + } +} + +void rrc_nr::handle_pdu(uint16_t rnti, uint32_t lcid, srsran::const_byte_span pdu) +{ + switch (static_cast(lcid)) { + case srsran::nr_srb::srb0: + handle_ul_ccch(rnti, pdu); + break; + case srsran::nr_srb::srb1: + case srsran::nr_srb::srb2: + case srsran::nr_srb::srb3: + handle_ul_dcch(rnti, lcid, std::move(pdu)); + break; + default: + std::string errcause = fmt::format("Invalid LCID=%d", lcid); + log_rx_pdu_fail(rnti, lcid, pdu, errcause.c_str()); + break; + } +} + +void rrc_nr::handle_ul_ccch(uint16_t rnti, srsran::const_byte_span pdu) +{ + // Parse UL-CCCH + ul_ccch_msg_s ul_ccch_msg; + { + asn1::cbit_ref bref(pdu.data(), pdu.size()); + if (ul_ccch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or + ul_ccch_msg.msg.type().value != ul_ccch_msg_type_c::types_opts::c1) { + log_rx_pdu_fail(rnti, srb_to_lcid(lte_srb::srb0), pdu, "Failed to unpack UL-CCCH message", true); + return; + } + } + + // Log Rx message + fmt::memory_buffer fmtbuf, fmtbuf2; + fmt::format_to(fmtbuf, "rnti=0x{:x}, SRB0", rnti); + fmt::format_to(fmtbuf2, "UL-CCCH.{}", ul_ccch_msg.msg.c1().type().to_string()); + log_rrc_message(srsran::to_c_str(fmtbuf), Rx, pdu, ul_ccch_msg, srsran::to_c_str(fmtbuf2)); + + // Handle message + switch (ul_ccch_msg.msg.c1().type().value) { + case ul_ccch_msg_type_c::c1_c_::types_opts::rrc_setup_request: + handle_rrc_setup_request(rnti, ul_ccch_msg.msg.c1().rrc_setup_request()); + break; + case ul_ccch_msg_type_c::c1_c_::types_opts::rrc_reest_request: + handle_rrc_reest_request(rnti, ul_ccch_msg.msg.c1().rrc_reest_request()); + break; + default: + log_rx_pdu_fail(rnti, srb_to_lcid(lte_srb::srb0), pdu, "Unsupported UL-CCCH message type"); + // TODO Remove user + } +} + +void rrc_nr::handle_ul_dcch(uint16_t rnti, uint32_t lcid, srsran::const_byte_span pdu) +{ + // Parse UL-DCCH + ul_dcch_msg_s ul_dcch_msg; + { + asn1::cbit_ref bref(pdu.data(), pdu.size()); + if (ul_dcch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or + ul_dcch_msg.msg.type().value != ul_dcch_msg_type_c::types_opts::c1) { + log_rx_pdu_fail(rnti, lcid, pdu, "Failed to unpack UL-DCCH message"); + return; + } + } + + // Verify UE exists + auto ue_it = users.find(rnti); + if (ue_it == users.end()) { + log_rx_pdu_fail(rnti, lcid, pdu, "Inexistent rnti"); + } + ue& u = *ue_it->second; + + // Log Rx message + fmt::memory_buffer fmtbuf, fmtbuf2; + fmt::format_to(fmtbuf, "rnti=0x{:x}, {}", rnti, srsran::get_srb_name(srsran::nr_lcid_to_srb(lcid))); + fmt::format_to(fmtbuf2, "UL-DCCH.{}", ul_dcch_msg.msg.c1().type().to_string()); + log_rrc_message(srsran::to_c_str(fmtbuf), Rx, pdu, ul_dcch_msg, srsran::to_c_str(fmtbuf2)); + + // Handle message + switch (ul_dcch_msg.msg.c1().type().value) { + case ul_dcch_msg_type_c::c1_c_::types_opts::rrc_setup_complete: + u.handle_rrc_setup_complete(ul_dcch_msg.msg.c1().rrc_setup_complete()); + break; + case ul_dcch_msg_type_c::c1_c_::types_opts::security_mode_complete: + u.handle_security_mode_complete(ul_dcch_msg.msg.c1().security_mode_complete()); + break; + case ul_dcch_msg_type_c::c1_c_::types_opts::rrc_recfg_complete: + u.handle_rrc_reconfiguration_complete(ul_dcch_msg.msg.c1().rrc_recfg_complete()); + break; + case ul_dcch_msg_type_c::c1_c_::types_opts::ul_info_transfer: + u.handle_ul_information_transfer(ul_dcch_msg.msg.c1().ul_info_transfer()); + break; + case ul_dcch_msg_type_c::c1_c_::types_opts::rrc_reest_complete: + u.handle_rrc_reestablishment_complete(ul_dcch_msg.msg.c1().rrc_reest_complete()); + break; + case ul_dcch_msg_type_c::c1_c_::types_opts::ue_cap_info: + u.handle_ue_capability_information(ul_dcch_msg.msg.c1().ue_cap_info()); + break; + default: + log_rx_pdu_fail(rnti, srb_to_lcid(lte_srb::srb0), pdu, "Unsupported UL-CCCH message type", false); + // TODO Remove user + } +} + +void rrc_nr::handle_rrc_setup_request(uint16_t rnti, const asn1::rrc_nr::rrc_setup_request_s& msg) +{ + auto ue_it = users.find(rnti); + + // TODO: Defer creation of ue to this point + if (ue_it == users.end()) { + logger.error("%s received for inexistent rnti=0x%x", "UL-CCCH", rnti); + return; + } + ue& u = *ue_it->second; + u.handle_rrc_setup_request(msg); +} + +void rrc_nr::handle_rrc_reest_request(uint16_t rnti, const asn1::rrc_nr::rrc_reest_request_s& msg) +{ + auto ue_it = users.find(rnti); + + // TODO: Defer creation of ue to this point + if (ue_it == users.end()) { + logger.error("%s received for inexistent rnti=0x%x", "UL-CCCH", rnti); + return; + } + ue& u = *ue_it->second; + u.handle_rrc_reestablishment_request(msg); +} + +/******************************************************************************* + PDCP interface +*******************************************************************************/ +void rrc_nr::write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) +{ + if (pdu == nullptr or pdu->N_bytes == 0) { + logger.error("Rx %s PDU, rnti=0x%x - Discarding. Cause: PDU is empty", srsenb::get_rb_name(lcid), rnti); + return; + } + handle_pdu(rnti, lcid, *pdu); +} + +void rrc_nr::notify_pdcp_integrity_error(uint16_t rnti, uint32_t lcid) {} + +/******************************************************************************* + NGAP interface +*******************************************************************************/ + +int rrc_nr::ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) +{ + logger.debug("Setting securtiy key for rnti=0x%x", rnti); + auto ue_it = users.find(rnti); + + if (ue_it == users.end()) { + logger.error("Trying to set key for non-existing rnti=0x%x", rnti); + return SRSRAN_ERROR; + } + ue& u = *ue_it->second; + u.set_security_key(key); + return SRSRAN_SUCCESS; +} +int rrc_nr::ue_set_bitrates(uint16_t rnti, const asn1::ngap::ue_aggregate_maximum_bit_rate_s& rates) +{ + return SRSRAN_SUCCESS; +} +int rrc_nr::set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap::ue_aggregate_maximum_bit_rate_s& rates) +{ + return SRSRAN_SUCCESS; +} +int rrc_nr::ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap::ue_security_cap_s& caps) +{ + logger.debug("Setting securtiy capabilites for rnti=0x%x", rnti); + auto ue_it = users.find(rnti); + + if (ue_it == users.end()) { + logger.error("Trying to set security capabilities for non-existing rnti=0x%x", rnti); + return SRSRAN_ERROR; + } + ue& u = *ue_it->second; + u.set_security_capabilities(caps); + return SRSRAN_SUCCESS; +} +int rrc_nr::start_security_mode_procedure(uint16_t rnti, srsran::unique_byte_buffer_t nas_pdu) +{ + auto user_it = users.find(rnti); + if (user_it == users.end()) { + logger.error("Starting SecurityModeCommand procedure failed - rnti=0x%x not found", rnti); + return SRSRAN_ERROR; + } + user_it->second->send_security_mode_command(std::move(nas_pdu)); + return SRSRAN_SUCCESS; +} +int rrc_nr::establish_rrc_bearer(uint16_t rnti, + uint16_t pdu_session_id, + srsran::const_byte_span nas_pdu, + uint32_t lcid, + uint32_t five_qi) +{ + if (not users.contains(rnti)) { + logger.error("Establishing RRC bearers for inexistent rnti=0x%x", rnti); + return SRSRAN_ERROR; + } + + users[rnti]->establish_eps_bearer(pdu_session_id, nas_pdu, lcid, five_qi); + + // TODO: verify whether this is the best place where to call the RRCReconfig + users[rnti]->send_rrc_reconfiguration(); + return SRSRAN_SUCCESS; +} + +int rrc_nr::release_bearers(uint16_t rnti) +{ + return SRSRAN_SUCCESS; +} + +void rrc_nr::release_user(uint16_t rnti) +{ + if (not users.contains(rnti)) { + logger.warning("User rnti=0x%x has already been released", rnti); + return; + } + + users[rnti]->send_rrc_release(); +} + +int rrc_nr::allocate_lcid(uint16_t rnti) +{ + return SRSRAN_SUCCESS; +} + +void rrc_nr::write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) +{ + if (not users.contains(rnti)) { + logger.error("Received DL information transfer for inexistent rnti=0x%x", rnti); + return; + } + if (sdu == nullptr or sdu->size() == 0) { + logger.error("Received empty DL information transfer for rnti=0x%x", rnti); + return; + } + users[rnti]->send_dl_information_transfer(std::move(sdu)); +} + +/******************************************************************************* + Interface for EUTRA RRC +*******************************************************************************/ + +void rrc_nr::sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_params_t& params) +{ + // try to allocate new user + sched_nr_ue_cfg_t uecfg{}; + uecfg.carriers.resize(1); + uecfg.carriers[0].active = true; + uecfg.carriers[0].cc = 0; + uecfg.phy_cfg = cell_ctxt->default_phy_ue_cfg_nr; + + uint16_t nr_rnti = mac->reserve_rnti(0, uecfg); + if (nr_rnti == SRSRAN_INVALID_RNTI) { + logger.error("Failed to allocate RNTI at MAC"); + rrc_eutra->sgnb_addition_reject(eutra_rnti); + return; + } + + if (add_user(nr_rnti, 0, false) != SRSRAN_SUCCESS) { + logger.error("Failed to allocate RNTI at RRC"); + rrc_eutra->sgnb_addition_reject(eutra_rnti); + return; + } + + // new RNTI is now registered at MAC and RRC + auto user_it = users.find(nr_rnti); + if (user_it == users.end()) { + logger.warning("Unrecognised rnti: 0x%x", nr_rnti); + return; + } + user_it->second->handle_sgnb_addition_request(eutra_rnti, params); +} + +void rrc_nr::sgnb_reconfiguration_complete(uint16_t eutra_rnti, const asn1::dyn_octstring& reconfig_response) +{ + // user has completeted the reconfiguration and has acked on 4G side, wait until RA on NR + logger.info("Received Reconfiguration complete for RNTI=0x%x", eutra_rnti); +} + +void rrc_nr::sgnb_release_request(uint16_t nr_rnti) +{ + // remove user + auto it = users.find(nr_rnti); + uint16_t eutra_rnti = it != users.end() ? it->second->get_eutra_rnti() : SRSRAN_INVALID_RNTI; + rem_user(nr_rnti); + if (eutra_rnti != SRSRAN_INVALID_RNTI) { + rrc_eutra->sgnb_release_ack(eutra_rnti); + } +} + +} // namespace srsenb diff --git a/srsgnb/src/stack/rrc/rrc_nr_config_utils.cc b/srsgnb/src/stack/rrc/rrc_nr_config_utils.cc new file mode 100644 index 0000000000..c77a54e997 --- /dev/null +++ b/srsgnb/src/stack/rrc/rrc_nr_config_utils.cc @@ -0,0 +1,363 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h" +#include "srsran/common/band_helper.h" + +#define HANDLE_ERROR(x) \ + do { \ + if (x != SRSRAN_SUCCESS) { \ + return SRSRAN_ERROR; \ + } \ + } while (0) + +#define ERROR_IF_NOT(x, fmt, ...) \ + do { \ + if (not(x)) { \ + fprintf(stderr, "ERROR: " fmt "\n", ##__VA_ARGS__); \ + return SRSRAN_ERROR; \ + } \ + } while (0) + +using namespace asn1::rrc_nr; + +namespace srsenb { + +uint32_t coreset_get_bw(const asn1::rrc_nr::ctrl_res_set_s& coreset) +{ + uint32_t prb_count = 0; + + // Iterate all the frequency domain resources bit-map... + for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { + // ... and count 6 PRB for every frequency domain resource that it is enabled + if (coreset.freq_domain_res.get(i)) { + prb_count += 6; + } + } + + // Return the total count of physical resource blocks + return prb_count; +} + +int coreset_get_pdcch_nr_max_candidates(const asn1::rrc_nr::ctrl_res_set_s& coreset, uint32_t aggregation_level) +{ + uint32_t coreset_bw = coreset_get_bw(coreset); + uint32_t nof_cce = (coreset_bw * coreset.dur) / 6; + + uint32_t L = 1U << aggregation_level; + uint32_t nof_candidates = nof_cce / L; + + return SRSRAN_MIN(nof_candidates, SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR); +} + +ctrl_res_set_s make_default_coreset(uint8_t coreset_id, uint32_t nof_prb) +{ + ctrl_res_set_s coreset; + coreset.ctrl_res_set_id = coreset_id; + // Generate frequency resources for the full BW + for (uint32_t i = 0; i < SRSRAN_CORESET_FREQ_DOMAIN_RES_SIZE; i++) { + coreset.freq_domain_res.set(coreset.freq_domain_res.length() - i - 1, i < SRSRAN_FLOOR(nof_prb, 6)); + } + coreset.dur = 1; + coreset.cce_reg_map_type.set_non_interleaved(); + coreset.precoder_granularity.value = ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; + return coreset; +} + +search_space_s make_default_common_search_space(uint8_t ss_id, const ctrl_res_set_s& cs) +{ + search_space_s ss; + ss.search_space_id = ss_id; + ss.ctrl_res_set_id_present = true; + ss.ctrl_res_set_id = cs.ctrl_res_set_id; + ss.dur_present = false; // false for duration=1 + ss.monitoring_slot_periodicity_and_offset_present = true; + ss.monitoring_slot_periodicity_and_offset.set_sl1(); + ss.monitoring_symbols_within_slot_present = true; + ss.monitoring_symbols_within_slot.from_number(0b10000000000000); + ss.search_space_type_present = true; + ss.search_space_type.set_common().dci_format0_minus0_and_format1_minus0_present = true; + ss.nrof_candidates_present = true; + uint32_t nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(cs, 0), 2); + asn1::number_to_enum(ss.nrof_candidates.aggregation_level1, nof_cand); + nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(cs, 1), 2); + asn1::number_to_enum(ss.nrof_candidates.aggregation_level2, nof_cand); + nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(cs, 2), 2); + asn1::number_to_enum(ss.nrof_candidates.aggregation_level4, nof_cand); + nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(cs, 3), 2); + asn1::number_to_enum(ss.nrof_candidates.aggregation_level8, nof_cand); + nof_cand = SRSRAN_MIN(coreset_get_pdcch_nr_max_candidates(cs, 4), 2); + asn1::number_to_enum(ss.nrof_candidates.aggregation_level16, nof_cand); + + return ss; +} + +/// Generate default phy cell configuration +void generate_default_nr_phy_cell(phy_cell_cfg_nr_t& phy_cell) +{ + phy_cell = {}; + + phy_cell.carrier.scs = srsran_subcarrier_spacing_15kHz; + phy_cell.carrier.nof_prb = 52; + phy_cell.carrier.max_mimo_layers = 1; +} + +/// Generate default rrc nr cell configuration +void generate_default_nr_cell(rrc_cell_cfg_nr_t& cell) +{ + cell = {}; + cell.coreset0_idx = 7; + cell.ssb_absolute_freq_point = 0; // auto derived + cell.num_ra_preambles = 8; + generate_default_nr_phy_cell(cell.phy_cell); + + // PDCCH + // - Add CORESET#2 as UE-specific + cell.pdcch_cfg_ded.ctrl_res_set_to_add_mod_list.resize(1); + auto& coreset2 = cell.pdcch_cfg_ded.ctrl_res_set_to_add_mod_list[0]; + coreset2 = make_default_coreset(2, cell.phy_cell.carrier.nof_prb); + + // - Add SearchSpace#2 as UE-specific -> CORESET#2 + cell.pdcch_cfg_ded.search_spaces_to_add_mod_list.resize(1); + auto& ss2 = cell.pdcch_cfg_ded.search_spaces_to_add_mod_list[0]; + ss2 = make_default_common_search_space(2, coreset2); + ss2.search_space_type.set_ue_specific().dci_formats.value = asn1::rrc_nr::search_space_s::search_space_type_c_:: + ue_specific_s_::dci_formats_opts::formats0_minus0_and_minus1_minus0; +} + +int derive_ssb_params(bool is_sa, + uint32_t dl_arfcn, + uint32_t band, + srsran_subcarrier_spacing_t pdcch_scs, + uint32_t coreset0_idx, + uint32_t nof_prb, + rrc_cell_cfg_nr_t& cell) +{ + // Verify essential parameters are specified and valid + ERROR_IF_NOT(dl_arfcn > 0, "Invalid DL ARFCN=%d", dl_arfcn); + ERROR_IF_NOT(band > 0, "Band is a mandatory parameter"); + ERROR_IF_NOT(pdcch_scs < srsran_subcarrier_spacing_invalid, "Invalid carrier SCS"); + ERROR_IF_NOT(coreset0_idx < 15, "Invalid controlResourceSetZero"); + ERROR_IF_NOT(nof_prb > 0, "Invalid DL number of PRBS=%d", nof_prb); + + srsran::srsran_band_helper band_helper; + + double dl_freq_hz = band_helper.nr_arfcn_to_freq(dl_arfcn); + uint32_t dl_absolute_freq_point_a = band_helper.get_abs_freq_point_a_arfcn(nof_prb, dl_arfcn); + + // derive SSB pattern and scs + cell.ssb_pattern = band_helper.get_ssb_pattern(band, srsran_subcarrier_spacing_15kHz); + if (cell.ssb_pattern == SRSRAN_SSB_PATTERN_A) { + // 15kHz SSB SCS + cell.ssb_scs = srsran_subcarrier_spacing_15kHz; + } else { + // try to optain SSB pattern for same band with 30kHz SCS + cell.ssb_pattern = band_helper.get_ssb_pattern(band, srsran_subcarrier_spacing_30kHz); + if (cell.ssb_pattern == SRSRAN_SSB_PATTERN_B || cell.ssb_pattern == SRSRAN_SSB_PATTERN_C) { + // SSB SCS is 30 kHz + cell.ssb_scs = srsran_subcarrier_spacing_30kHz; + } else { + srsran_terminate("Can't derive SSB pattern from band %d", band); + } + } + + // derive SSB position + int coreset0_rb_offset = 0; + if (is_sa) { + // Get offset in RBs between CORESET#0 and SSB + coreset0_rb_offset = srsran_coreset0_ssb_offset(coreset0_idx, cell.ssb_scs, pdcch_scs); + ERROR_IF_NOT(coreset0_rb_offset >= 0, "Failed to compute RB offset between CORESET#0 and SSB"); + } else { + // TODO: Verify if specified SSB frequency is valid + } + uint32_t ssb_abs_freq_point = + band_helper.get_abs_freq_ssb_arfcn(band, cell.ssb_scs, dl_absolute_freq_point_a, coreset0_rb_offset); + ERROR_IF_NOT(ssb_abs_freq_point > 0, + "Can't derive SSB freq point for dl_arfcn=%d and band %d", + band_helper.freq_to_nr_arfcn(dl_freq_hz), + band); + + // Convert to frequency for PHY + cell.ssb_absolute_freq_point = ssb_abs_freq_point; + cell.ssb_freq_hz = band_helper.nr_arfcn_to_freq(ssb_abs_freq_point); + + double pointA_abs_freq_Hz = dl_freq_hz - nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(pdcch_scs) / 2; + uint32_t ssb_pointA_freq_offset_Hz = + (cell.ssb_freq_hz > pointA_abs_freq_Hz) ? (uint32_t)(cell.ssb_freq_hz - pointA_abs_freq_Hz) : 0; + + cell.ssb_offset = (uint32_t)(ssb_pointA_freq_offset_Hz / SRSRAN_SUBC_SPACING_NR(pdcch_scs)) % SRSRAN_NRE; + + // Validate Coreset0 has space + srsran_coreset_t coreset0 = {}; + ERROR_IF_NOT( + srsran_coreset_zero( + cell.phy_cell.cell_id, ssb_pointA_freq_offset_Hz, cell.ssb_scs, pdcch_scs, coreset0_idx, &coreset0) == 0, + "Deriving parameters for coreset0: index=%d, ssb_pointA_offset=%d kHz\n", + coreset0_idx, + ssb_pointA_freq_offset_Hz / 1000); + + ERROR_IF_NOT(srsran_coreset_start_rb(&coreset0) + srsran_coreset_get_bw(&coreset0) <= cell.phy_cell.carrier.nof_prb, + "Coreset0 index=%d is not compatible with DL ARFCN %d in band %d\n", + coreset0_idx, + cell.dl_arfcn, + cell.band); + + // Validate Coreset0 has less than 3 symbols + ERROR_IF_NOT(coreset0.duration < 3, + "Coreset0 index=%d is not supported due to overlap with SSB. Select a coreset0 index from 38.213 Table " + "13-1 such that N_symb_coreset < 3\n", + coreset0_idx); + + // Validate Coreset0 has more than 24 RB + ERROR_IF_NOT(srsran_coreset_get_bw(&coreset0) > 24, + "Coreset0 configuration index=%d has only %d RB. A coreset0 index >= 6 is required such as N_rb >= 48\n", + srsran_coreset_get_bw(&coreset0), + coreset0_idx); + + return SRSRAN_SUCCESS; +} + +int derive_phy_cell_freq_params(uint32_t dl_arfcn, uint32_t ul_arfcn, phy_cell_cfg_nr_t& phy_cell) +{ + // Verify essential parameters are specified and valid + ERROR_IF_NOT(dl_arfcn > 0, "DL ARFCN is a mandatory parameter"); + + // Use helper class to derive NR carrier parameters + srsran::srsran_band_helper band_helper; + + // derive DL freq from ARFCN + if (phy_cell.carrier.dl_center_frequency_hz == 0) { + phy_cell.carrier.dl_center_frequency_hz = band_helper.nr_arfcn_to_freq(dl_arfcn); + } + + // derive UL freq from ARFCN + if (phy_cell.carrier.ul_center_frequency_hz == 0) { + // auto-detect UL frequency + if (ul_arfcn == 0) { + // derive UL ARFCN from given DL ARFCN + ul_arfcn = band_helper.get_ul_arfcn_from_dl_arfcn(dl_arfcn); + ERROR_IF_NOT(ul_arfcn > 0, "Can't derive UL ARFCN from DL ARFCN %d", dl_arfcn); + } + phy_cell.carrier.ul_center_frequency_hz = band_helper.nr_arfcn_to_freq(ul_arfcn); + } + + return SRSRAN_SUCCESS; +} + +int set_derived_nr_cell_params(bool is_sa, rrc_cell_cfg_nr_t& cell) +{ + // Verify essential parameters are specified and valid + ERROR_IF_NOT(cell.dl_arfcn > 0, "DL ARFCN is a mandatory parameter"); + ERROR_IF_NOT(cell.band > 0, "Band is a mandatory parameter"); + ERROR_IF_NOT(cell.phy_cell.carrier.nof_prb > 0, "Number of PRBs is a mandatory parameter"); + + // Use helper class to derive NR carrier parameters + srsran::srsran_band_helper band_helper; + + if (cell.ul_arfcn == 0) { + // derive UL ARFCN from given DL ARFCN + cell.ul_arfcn = band_helper.get_ul_arfcn_from_dl_arfcn(cell.dl_arfcn); + ERROR_IF_NOT(cell.ul_arfcn > 0, "Can't derive UL ARFCN from DL ARFCN %d", cell.dl_arfcn); + } + + // duplex mode + cell.duplex_mode = band_helper.get_duplex_mode(cell.band); + + // PointA + cell.dl_absolute_freq_point_a = band_helper.get_abs_freq_point_a_arfcn(cell.phy_cell.carrier.nof_prb, cell.dl_arfcn); + cell.ul_absolute_freq_point_a = band_helper.get_abs_freq_point_a_arfcn(cell.phy_cell.carrier.nof_prb, cell.ul_arfcn); + + // Derive phy_cell parameters that depend on ARFCNs + derive_phy_cell_freq_params(cell.dl_arfcn, cell.ul_arfcn, cell.phy_cell); + + // Derive SSB params + ERROR_IF_NOT(derive_ssb_params(is_sa, + cell.dl_arfcn, + cell.band, + cell.phy_cell.carrier.scs, + cell.coreset0_idx, + cell.phy_cell.carrier.nof_prb, + cell) == 0, + "Deriving SSB parameters\n"); + + cell.phy_cell.carrier.ssb_center_freq_hz = cell.ssb_freq_hz; + + // Derive remaining config params + if (not is_sa) { + // Configure CORESET#1 + cell.pdcch_cfg_common.common_ctrl_res_set_present = true; + cell.pdcch_cfg_common.common_ctrl_res_set = make_default_coreset(1, cell.phy_cell.carrier.nof_prb); + } + + // Configure SearchSpace#1 + cell.pdcch_cfg_common.common_search_space_list.resize(1); + auto& ss1 = cell.pdcch_cfg_common.common_search_space_list[0]; + if (is_sa) { + // Configure SearchSpace#1 -> CORESET#0 + ctrl_res_set_s dummy_coreset = make_default_coreset(0, cell.phy_cell.carrier.nof_prb); + ss1 = make_default_common_search_space(1, dummy_coreset); + ss1.nrof_candidates.aggregation_level1.value = search_space_s::nrof_candidates_s_::aggregation_level1_opts::n0; + ss1.nrof_candidates.aggregation_level2.value = search_space_s::nrof_candidates_s_::aggregation_level2_opts::n0; + ss1.nrof_candidates.aggregation_level4.value = search_space_s::nrof_candidates_s_::aggregation_level4_opts::n1; + ss1.nrof_candidates.aggregation_level8.value = search_space_s::nrof_candidates_s_::aggregation_level8_opts::n0; + ss1.nrof_candidates.aggregation_level16.value = search_space_s::nrof_candidates_s_::aggregation_level16_opts::n0; + } else { + // Configure SearchSpace#1 -> CORESET#1 + ss1 = make_default_common_search_space(1, cell.pdcch_cfg_common.common_ctrl_res_set); + // cell.phy_cell.pdcch.search_space[1].type = srsran_search_space_type_common_3; + } + cell.pdcch_cfg_common.ra_search_space_present = true; + cell.pdcch_cfg_common.ra_search_space = ss1.search_space_id; + + return SRSRAN_SUCCESS; +} + +int set_derived_nr_rrc_params(rrc_nr_cfg_t& rrc_cfg) +{ + for (rrc_cell_cfg_nr_t& cell : rrc_cfg.cell_list) { + HANDLE_ERROR(set_derived_nr_cell_params(rrc_cfg.is_standalone, cell)); + } + return SRSRAN_SUCCESS; +} + +int check_nr_pdcch_cfg_valid(const srsran_pdcch_cfg_nr_t& pdcch) +{ + // Verify Search Spaces + std::array used_coresets{}; + for (uint32_t ss_id = 0; ss_id < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE; ++ss_id) { + if (pdcch.search_space_present[ss_id]) { + const srsran_search_space_t& ss = pdcch.search_space[ss_id]; + ERROR_IF_NOT(ss.id == ss_id, "SearchSpace#%d should match list index", ss_id); + uint32_t cs_id = ss.coreset_id; + ERROR_IF_NOT(pdcch.coreset_present[cs_id], "SearchSpace#%d points to absent CORESET#%d", ss_id, cs_id); + used_coresets[cs_id] = true; + } + } + + // Verify CORESET id + for (uint32_t cs_id = 0; cs_id < SRSRAN_UE_DL_NR_MAX_NOF_CORESET; ++cs_id) { + ERROR_IF_NOT(pdcch.coreset_present[cs_id] == used_coresets[cs_id], "CORESET#%d is configured but not used", cs_id); + } + + return SRSRAN_SUCCESS; +} + +} // namespace srsenb diff --git a/srsgnb/src/stack/rrc/rrc_nr_du_manager.cc b/srsgnb/src/stack/rrc/rrc_nr_du_manager.cc new file mode 100644 index 0000000000..464c96d62f --- /dev/null +++ b/srsgnb/src/stack/rrc/rrc_nr_du_manager.cc @@ -0,0 +1,161 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/rrc/rrc_nr_du_manager.h" +#include "srsgnb/hdr/stack/rrc/cell_asn1_config.h" +#include "srsran/asn1/rrc_nr_utils.h" +#include "srsran/common/string_helpers.h" + +using namespace asn1::rrc_nr; + +namespace srsenb { + +du_config_manager::du_config_manager(const rrc_nr_cfg_t& cfg_) : cfg(cfg_), logger(srslog::fetch_basic_logger("RRC-NR")) +{} + +du_config_manager::~du_config_manager() {} + +int du_config_manager::add_cell() +{ + // add cell + std::unique_ptr obj = std::make_unique(); + du_cell_config& cell = *obj; + cell.cc = cells.size(); + + // Fill general cell params + cell.pci = cfg.cell_list[cell.cc].phy_cell.carrier.pci; + + // fill MIB ASN.1 + if (fill_mib_from_enb_cfg(cfg.cell_list[cell.cc], cell.mib) != SRSRAN_SUCCESS) { + return SRSRAN_ERROR; + } + + // Pack MIB + cell.packed_mib = srsran::make_byte_buffer(); + if (cell.packed_mib == nullptr) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + { + asn1::bit_ref bref(cell.packed_mib->msg, cell.packed_mib->get_tailroom()); + bcch_bch_msg_s bch_msg; + bch_msg.msg.set_mib() = cell.mib; + if (bch_msg.pack(bref) != asn1::SRSASN_SUCCESS) { + logger.error("Couldn't pack mib msg"); + return SRSRAN_ERROR; + } + cell.packed_mib->N_bytes = bref.distance_bytes(); + } + logger.info( + cell.packed_mib->data(), cell.packed_mib->size(), "BCCH-BCH Message (with MIB) (%d B)", cell.packed_mib->size()); + asn1::json_writer js; + cell.mib.to_json(js); + logger.info("MIB content: %s", js.to_string().c_str()); + + // fill SIB1 ASN.1 + if (fill_sib1_from_enb_cfg(cfg, cell.cc, cell.sib1) != SRSRAN_SUCCESS) { + logger.error("Couldn't generate SIB1"); + return SRSRAN_ERROR; + } + + // Pack SIB1 + cell.packed_sib1 = srsran::make_byte_buffer(); + if (cell.packed_sib1 == nullptr) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + { + asn1::bit_ref bref(cell.packed_sib1->msg, cell.packed_sib1->get_tailroom()); + bcch_dl_sch_msg_s bcch_msg; + bcch_msg.msg.set_c1().set_sib_type1() = cell.sib1; + if (bcch_msg.pack(bref) != asn1::SRSASN_SUCCESS) { + logger.error("Couldn't pack SIB1 msg"); + return SRSRAN_ERROR; + } + cell.packed_sib1->N_bytes = bref.distance_bytes(); + } + if (cfg.is_standalone) { + logger.info(cell.packed_sib1->data(), + cell.packed_sib1->size(), + "BCCH-DL-SCH-Message (with SIB1) (%d B)", + cell.packed_sib1->size()); + cell.sib1.to_json(js); + logger.info("SIB1 content: %s", js.to_string().c_str()); + } + + // Generate SSB SCS + srsran_subcarrier_spacing_t ssb_scs; + if (not srsran::fill_ssb_pattern_scs(cfg.cell_list[cell.cc].phy_cell.carrier, &cell.ssb_pattern, &ssb_scs)) { + return SRSRAN_ERROR; + } + cell.ssb_scs.value = (subcarrier_spacing_e::options)ssb_scs; + cell.ssb_center_freq_hz = cfg.cell_list[cell.cc].ssb_freq_hz; + cell.dl_freq_hz = cfg.cell_list[cell.cc].phy_cell.carrier.dl_center_frequency_hz; + cell.is_standalone = cfg.is_standalone; + + cells.push_back(std::move(obj)); + return SRSRAN_SUCCESS; +} + +void fill_phy_pdcch_cfg_common(const du_cell_config& cell, srsran_pdcch_cfg_nr_t* pdcch) +{ + const serving_cell_cfg_common_sib_s& serv_cell = cell.serv_cell_cfg_common(); + const pdcch_cfg_common_s& pdcch_common = serv_cell.dl_cfg_common.init_dl_bwp.pdcch_cfg_common.setup(); + + bool is_sa = cell.is_standalone; + uint8_t coreset0_idx = cell.mib.pdcch_cfg_sib1.ctrl_res_set_zero; + auto scs = (srsran_subcarrier_spacing_t)serv_cell.dl_cfg_common.init_dl_bwp.generic_params.subcarrier_spacing.value; + auto ssb_scs = (srsran_subcarrier_spacing_t)cell.ssb_scs.value; + uint32_t nof_prb = serv_cell.dl_cfg_common.freq_info_dl.scs_specific_carrier_list[0].carrier_bw; + + if (is_sa) { + // Generate CORESET#0 + pdcch->coreset_present[0] = true; + // Get pointA and SSB absolute frequencies + double pointA_abs_freq_Hz = cell.dl_freq_hz - nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(scs) / 2; + double ssb_abs_freq_Hz = cell.ssb_center_freq_hz; + // Calculate integer SSB to pointA frequency offset in Hz + uint32_t ssb_pointA_freq_offset_Hz = + (ssb_abs_freq_Hz > pointA_abs_freq_Hz) ? (uint32_t)(ssb_abs_freq_Hz - pointA_abs_freq_Hz) : 0; + int ret = srsran_coreset_zero(cell.pci, ssb_pointA_freq_offset_Hz, ssb_scs, scs, coreset0_idx, &pdcch->coreset[0]); + srsran_assert(ret == SRSRAN_SUCCESS, "Failed to generate CORESET#0"); + + // Generate SearchSpace#0 + pdcch->search_space_present[0] = true; + pdcch->search_space[0].id = 0; + pdcch->search_space[0].coreset_id = 0; + pdcch->search_space[0].type = srsran_search_space_type_common_0; + pdcch->search_space[0].nof_candidates[0] = 1; + pdcch->search_space[0].nof_candidates[1] = 1; + pdcch->search_space[0].nof_candidates[2] = 1; + pdcch->search_space[0].nof_candidates[3] = 0; + pdcch->search_space[0].nof_candidates[4] = 0; + pdcch->search_space[0].nof_formats = 1; + pdcch->search_space[0].formats[0] = srsran_dci_format_nr_1_0; + pdcch->search_space[0].duration = 1; + } + + // Generate Common CORESETs and Search Spaces + bool ret = srsran::fill_phy_pdcch_cfg_common(pdcch_common, pdcch); + srsran_assert(ret, "PDCCH Config Common"); +} + +} // namespace srsenb diff --git a/srsgnb/src/stack/rrc/rrc_nr_security_context.cc b/srsgnb/src/stack/rrc/rrc_nr_security_context.cc new file mode 100644 index 0000000000..c0f136e995 --- /dev/null +++ b/srsgnb/src/stack/rrc/rrc_nr_security_context.cc @@ -0,0 +1,212 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/rrc/rrc_nr_security_context.h" +#include "srsran/asn1/obj_id_cmp_utils.h" +#include "srsran/asn1/rrc_utils.h" + +namespace srsgnb { + +asn1::rrc_nr::security_algorithm_cfg_s nr_security_context::get_security_algorithm_cfg() const +{ + asn1::rrc_nr::security_algorithm_cfg_s ret; + // TODO: select these based on UE capabilities and preference order + ret.integrity_prot_algorithm_present = true; + ret.integrity_prot_algorithm = (asn1::rrc_nr::integrity_prot_algorithm_e::options)sec_cfg.integ_algo; + ret.ciphering_algorithm = (asn1::rrc_nr::ciphering_algorithm_e::options)sec_cfg.cipher_algo; + return ret; +} + +bool nr_security_context::set_security_capabilities(const asn1::ngap::ue_security_cap_s& caps) +{ + security_capabilities = caps; + + // Selects security algorithms (cipher_algo and integ_algo) based on capabilities and config preferences + // Each position in the bitmap represents an encryption algorithm: + // “all bits equal to 0” – UE supports no other algorithm than NEA0, + // “first bit” – 128-NEA1, + // “second bit” – 128-NEA2, + // “third bit” – 128-NEA3, + // other bits reserved for future use. Value ‘1’ indicates support and value + // ‘0’ indicates no support of the algorithm. + // Algorithms are defined in TS 33.401 [15]. + // Note: information missing + + bool enc_algo_found = false; + bool integ_algo_found = false; + + for (const auto& cipher_item : cfg.nea_preference_list) { + auto& v = security_capabilities.nrencryption_algorithms; + switch (cipher_item) { + case srsran::CIPHERING_ALGORITHM_ID_NR_NEA0: + // “all bits equal to 0” – UE supports no other algorithm than EEA0, + // specification does not cover the case in which EEA0 is supported with other algorithms + // just assume that EEA0 is always supported even this can not be explicity signaled by S1AP + sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_NR_NEA0; + enc_algo_found = true; + logger.info("Selected NEA0 as RRC encryption algorithm"); + break; + case srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA1: + // “first bit” – 128-EEA1, + if (v.get(v.length() - srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA1)) { + sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA1; + enc_algo_found = true; + logger.info("Selected NEA1 as RRC encryption algorithm"); + break; + } else { + logger.info("Failed to selected NEA1 as RRC encryption algorithm, due to unsupported algorithm"); + } + break; + case srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA2: + // “second bit” – 128-EEA2, + if (v.get(v.length() - srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA2)) { + sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA2; + enc_algo_found = true; + logger.info("Selected NEA2 as RRC encryption algorithm"); + break; + } else { + logger.info("Failed to selected NEA2 as RRC encryption algorithm, due to unsupported algorithm"); + } + break; + case srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA3: + // “third bit” – 128-EEA3, + if (v.get(v.length() - srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA3)) { + sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA3; + enc_algo_found = true; + logger.info("Selected NEA3 as RRC encryption algorithm"); + break; + } else { + logger.info("Failed to selected NEA2 as RRC encryption algorithm, due to unsupported algorithm"); + } + break; + default: + enc_algo_found = false; + break; + } + if (enc_algo_found) { + break; + } + } + + for (const auto& eia_enum : cfg.nia_preference_list) { + auto& v = security_capabilities.nrintegrity_protection_algorithms; + switch (eia_enum) { + case srsran::INTEGRITY_ALGORITHM_ID_NR_NIA0: + // Null integrity is not supported + logger.info("Skipping NIA0 as RRC integrity algorithm. Null integrity is not supported."); + sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_NR_NIA0; + integ_algo_found = true; + break; + case srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA1: + // “first bit” – 128-EIA1, + if (v.get(v.length() - srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA1)) { + sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA1; + integ_algo_found = true; + logger.info("Selected NIA1 as RRC integrity algorithm."); + } else { + logger.info("Failed to selected NIA1 as RRC encryption algorithm, due to unsupported algorithm"); + } + break; + case srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA2: + // “second bit” – 128-EIA2, + if (v.get(v.length() - srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA2)) { + sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA2; + integ_algo_found = true; + logger.info("Selected NIA2 as RRC integrity algorithm."); + } else { + logger.info("Failed to selected NIA2 as RRC encryption algorithm, due to unsupported algorithm"); + } + break; + case srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA3: + // “third bit” – 128-EIA3, + if (v.get(v.length() - srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA3)) { + sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA3; + integ_algo_found = true; + logger.info("Selected NIA3 as RRC integrity algorithm."); + } else { + logger.info("Failed to selected NIA3 as RRC encryption algorithm, due to unsupported algorithm"); + } + break; + default: + integ_algo_found = false; + break; + } + + if (integ_algo_found) { + break; + } + } + + if (not integ_algo_found || not enc_algo_found) { + logger.error("Did not find a matching integrity or encryption algorithm with the UE"); + return false; + } + return true; +} + +void nr_security_context::set_security_key(const asn1::fixed_bitstring<256, false, true>& key) +{ + k_gnb_present = true; + for (uint32_t i = 0; i < key.nof_octets(); ++i) { + k_gnb[i] = key.data()[key.nof_octets() - 1 - i]; + } + + generate_as_keys(); +} + +void nr_security_context::generate_as_keys() +{ + // Generate K_rrc_enc and K_rrc_int + srsran::security_generate_k_nr_rrc(k_gnb, + (srsran::CIPHERING_ALGORITHM_ID_ENUM)sec_cfg.cipher_algo, + (srsran::INTEGRITY_ALGORITHM_ID_ENUM)sec_cfg.integ_algo, + sec_cfg.k_nr_rrc_enc.data(), + sec_cfg.k_nr_rrc_int.data()); + + // Generate K_up_enc and K_up_int + security_generate_k_nr_up(k_gnb, + (srsran::CIPHERING_ALGORITHM_ID_ENUM)sec_cfg.cipher_algo, + (srsran::INTEGRITY_ALGORITHM_ID_ENUM)sec_cfg.integ_algo, + sec_cfg.k_nr_up_enc.data(), + sec_cfg.k_nr_up_int.data()); + + logger.info(k_gnb, 32, "K_gNB (k_gnb)"); + logger.info(sec_cfg.k_nr_rrc_enc.data(), 32, "NR RRC Encryption Key (k_nr_rrc_enc)"); + logger.info(sec_cfg.k_nr_rrc_int.data(), 32, "NR RRC Integrity Key (k_nr_rrc_int)"); + logger.info(sec_cfg.k_nr_up_enc.data(), 32, "NR UP Encryption Key (k_nr_up_enc)"); + logger.info(sec_cfg.k_nr_up_int.data(), 32, "NR UP Integrity Key (k_nr_up_int)"); +} + +void nr_security_context::regenerate_keys_handover(uint32_t new_pci, uint32_t new_dl_arfcn) +{ + logger.info("Regenerating KgNB with PCI=0x%02x, SSB-ARFCN=%d", new_pci, new_dl_arfcn); + logger.info(k_gnb, 32, "Old K_gNB (k_gnb)"); + // Generate K_enb* + uint8_t k_gnb_star[32]; + srsran::security_generate_k_gnb_star(k_gnb, new_pci, new_dl_arfcn, k_gnb_star); + + // K_enb becomes K_enb* + memcpy(k_gnb, k_gnb_star, 32); + + generate_as_keys(); +} + +} // namespace srsgnb diff --git a/srsgnb/src/stack/rrc/rrc_nr_ue.cc b/srsgnb/src/stack/rrc/rrc_nr_ue.cc new file mode 100644 index 0000000000..0c468a41e4 --- /dev/null +++ b/srsgnb/src/stack/rrc/rrc_nr_ue.cc @@ -0,0 +1,1582 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsgnb/hdr/stack/rrc/rrc_nr_ue.h" +#include "srsgnb/hdr/stack/rrc/cell_asn1_config.h" +#include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h" +#include "srsran/asn1/rrc_nr_utils.h" +#include "srsran/common/bearer_manager.h" +#include "srsran/common/standard_streams.h" +#include "srsran/common/string_helpers.h" + +using namespace asn1::rrc_nr; + +namespace srsenb { + +/******************************************************************************* + UE class + +Every function in UE class is called from a mutex environment thus does not + need extra protection. + *******************************************************************************/ +rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_, uint32_t pcell_cc_idx, bool start_msg3_timer) : + parent(parent_), logger(parent_->logger), rnti(rnti_), uecfg(), sec_ctx(parent->cfg) +{ + // Set default MAC UE config + uecfg.carriers.resize(1); + uecfg.carriers[0].active = true; + uecfg.carriers[0].cc = pcell_cc_idx; + uecfg.phy_cfg = parent->cell_ctxt->default_phy_ue_cfg_nr; + + if (not parent->cfg.is_standalone) { + // Add the final PDCCH config in case of NSA + srsran::fill_phy_pdcch_cfg( + parent->cell_ctxt->master_cell_group->sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(), + &uecfg.phy_cfg.pdcch); + } else { + cell_group_cfg = *parent->cell_ctxt->master_cell_group; + next_cell_group_cfg = cell_group_cfg; + } + + // Set timer for MSG3_RX_TIMEOUT or UE_INACTIVITY_TIMEOUT + activity_timer = parent->task_sched.get_unique_timer(); + start_msg3_timer ? set_activity_timeout(MSG3_RX_TIMEOUT) : set_activity_timeout(MSG5_RX_TIMEOUT); +} + +rrc_nr::ue::~ue() {} + +void rrc_nr::ue::set_activity_timeout(activity_timeout_type_t type) +{ + uint32_t deadline_ms = 0; + + switch (type) { + case MSG3_RX_TIMEOUT: + // TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 100ms + deadline_ms = 100; + break; + case MSG5_RX_TIMEOUT: + // TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 1s + deadline_ms = 5000; + break; + case UE_INACTIVITY_TIMEOUT: + deadline_ms = parent->cfg.inactivity_timeout_ms; + break; + default: + logger.error("Unknown timeout type %d", type); + return; + } + + activity_timer.set(deadline_ms, [this, type](uint32_t tid) { activity_timer_expired(type); }); + logger.debug("Setting timer for %s for rnti=0x%x to %dms", to_string(type).c_str(), rnti, deadline_ms); + + set_activity(); +} + +void rrc_nr::ue::set_activity(bool enabled) +{ + if (not enabled) { + if (activity_timer.is_running()) { + logger.debug("Inactivity timer interrupted for rnti=0x%x", rnti); + } + activity_timer.stop(); + return; + } + + // re-start activity timer with current timeout value + activity_timer.run(); + logger.debug("Activity registered for rnti=0x%x (timeout_value=%dms)", rnti, activity_timer.duration()); +} + +void rrc_nr::ue::activity_timer_expired(const activity_timeout_type_t type) +{ + logger.info("Activity timer for rnti=0x%x expired after %d ms", rnti, activity_timer.time_elapsed()); + + switch (type) { + case MSG5_RX_TIMEOUT: + case UE_INACTIVITY_TIMEOUT: { + state = rrc_nr_state_t::RRC_INACTIVE; + if (parent->cfg.is_standalone) { + // Start NGAP Release UE context + parent->ngap->user_release_request(rnti, asn1::ngap::cause_radio_network_opts::user_inactivity); + } else { + parent->rrc_eutra->sgnb_inactivity_timeout(eutra_rnti); + } + break; + } + case MSG3_RX_TIMEOUT: { + // MSG3 timeout, no need to notify NGAP or LTE stack. Just remove UE + state = rrc_nr_state_t::RRC_IDLE; + uint32_t rnti_to_rem = rnti; + parent->task_sched.defer_task([this, rnti_to_rem]() { parent->rem_user(rnti_to_rem); }); + break; + } + default: + // Unhandled activity timeout, just remove UE and log an error + parent->rem_user(rnti); + logger.error( + "Unhandled reason for activity timer expiration. rnti=0x%x, cause %d", rnti, static_cast(type)); + } +} + +std::string rrc_nr::ue::to_string(const activity_timeout_type_t& type) +{ + constexpr static const char* options[] = {"Msg3 reception", "UE inactivity", "Msg5 reception"}; + return srsran::enum_to_text(options, (uint32_t)activity_timeout_type_t::nulltype, (uint32_t)type); +} + +int rrc_nr::ue::send_dl_ccch(const dl_ccch_msg_s& dl_ccch_msg) +{ + // Allocate a new PDU buffer, pack the message and send to PDCP + srsran::unique_byte_buffer_t pdu = parent->pack_into_pdu(dl_ccch_msg, __FUNCTION__); + if (pdu == nullptr) { + logger.error("Failed to send DL-CCCH"); + return SRSRAN_ERROR; + } + fmt::memory_buffer fmtbuf; + fmt::format_to(fmtbuf, "DL-CCCH.{}", dl_ccch_msg.msg.c1().type().to_string()); + log_rrc_message(srsran::nr_srb::srb0, Tx, *pdu.get(), dl_ccch_msg, srsran::to_c_str(fmtbuf)); + parent->rlc->write_sdu(rnti, srsran::srb_to_lcid(srsran::nr_srb::srb0), std::move(pdu)); + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::send_dl_dcch(srsran::nr_srb srb, const asn1::rrc_nr::dl_dcch_msg_s& dl_dcch_msg) +{ + // Allocate a new PDU buffer, pack the message and send to PDCP + srsran::unique_byte_buffer_t pdu = parent->pack_into_pdu(dl_dcch_msg, __FUNCTION__); + if (pdu == nullptr) { + return SRSRAN_ERROR; + } + fmt::memory_buffer fmtbuf; + fmt::format_to(fmtbuf, "DL-DCCH.{}", dl_dcch_msg.msg.c1().type().to_string()); + log_rrc_message(srb, Tx, *pdu.get(), dl_dcch_msg, srsran::to_c_str(fmtbuf)); + parent->pdcp->write_sdu(rnti, srsran::srb_to_lcid(srb), std::move(pdu)); + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_secondary_cell_group_mac_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + // mac-CellGroup-Config for BSR and SR + cell_group_cfg_pack.mac_cell_group_cfg_present = true; + auto& mac_cell_group = cell_group_cfg_pack.mac_cell_group_cfg; + mac_cell_group.sched_request_cfg_present = true; + mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list.resize(1); + mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list[0].sched_request_id = 0; + mac_cell_group.sched_request_cfg.sched_request_to_add_mod_list[0].sr_trans_max = + asn1::rrc_nr::sched_request_to_add_mod_s::sr_trans_max_opts::n64; + mac_cell_group.bsr_cfg_present = true; + mac_cell_group.bsr_cfg.periodic_bsr_timer = asn1::rrc_nr::bsr_cfg_s::periodic_bsr_timer_opts::sf20; + mac_cell_group.bsr_cfg.retx_bsr_timer = asn1::rrc_nr::bsr_cfg_s::retx_bsr_timer_opts::sf320; + + // Skip TAG and PHR config + mac_cell_group.tag_cfg_present = false; + mac_cell_group.tag_cfg.tag_to_add_mod_list.resize(1); + mac_cell_group.tag_cfg.tag_to_add_mod_list[0].tag_id = 0; + mac_cell_group.tag_cfg.tag_to_add_mod_list[0].time_align_timer = time_align_timer_opts::infinity; + + mac_cell_group.phr_cfg_present = false; + mac_cell_group.phr_cfg.set_setup(); + mac_cell_group.phr_cfg.setup().phr_periodic_timer = asn1::rrc_nr::phr_cfg_s::phr_periodic_timer_opts::sf500; + mac_cell_group.phr_cfg.setup().phr_prohibit_timer = asn1::rrc_nr::phr_cfg_s::phr_prohibit_timer_opts::sf200; + mac_cell_group.phr_cfg.setup().phr_tx_pwr_factor_change = asn1::rrc_nr::phr_cfg_s::phr_tx_pwr_factor_change_opts::db3; + mac_cell_group.phr_cfg.setup().multiple_phr = true; + mac_cell_group.phr_cfg.setup().dummy = false; + mac_cell_group.phr_cfg.setup().phr_type2_other_cell = false; + mac_cell_group.phr_cfg.setup().phr_mode_other_cg = asn1::rrc_nr::phr_cfg_s::phr_mode_other_cg_opts::real; + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp_present = true; + + pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring(cell_group_cfg_pack); + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_sp_cell_cfg_ded_init_dl_bwp_radio_link_monitoring( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.radio_link_monitoring_cfg_present = true; + auto& radio_link_monitoring = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.radio_link_monitoring_cfg; + + // add resource to detect RLF + radio_link_monitoring.set_setup().fail_detection_res_to_add_mod_list.resize(1); + auto& fail_detec_res_elem = radio_link_monitoring.set_setup().fail_detection_res_to_add_mod_list[0]; + fail_detec_res_elem.radio_link_monitoring_rs_id = 0; + fail_detec_res_elem.purpose = asn1::rrc_nr::radio_link_monitoring_rs_s::purpose_opts::rlf; + fail_detec_res_elem.detection_res.set_ssb_idx() = 0; + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pucch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + // PUCCH + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pucch_cfg_present = true; + auto& pucch_cfg = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pucch_cfg; + + pucch_cfg.set_setup(); + pucch_cfg.setup().format2_present = true; + pucch_cfg.setup().format2.set_setup(); + pucch_cfg.setup().format2.setup().max_code_rate_present = true; + pucch_cfg.setup().format2.setup().max_code_rate = pucch_max_code_rate_opts::zero_dot25; + + // SR resources + pucch_cfg.setup().sched_request_res_to_add_mod_list.resize(1); + auto& sr_res1 = pucch_cfg.setup().sched_request_res_to_add_mod_list[0]; + sr_res1.sched_request_res_id = 1; + sr_res1.sched_request_id = 0; + sr_res1.periodicity_and_offset_present = true; + sr_res1.periodicity_and_offset.set_sl40() = 8; + sr_res1.res_present = true; + sr_res1.res = 2; // PUCCH resource for SR + + // DL data + if (parent->cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + pucch_cfg.setup().dl_data_to_ul_ack.resize(1); + pucch_cfg.setup().dl_data_to_ul_ack[0] = 4; + } else { + pucch_cfg.setup().dl_data_to_ul_ack.resize(6); + pucch_cfg.setup().dl_data_to_ul_ack[0] = 6; + pucch_cfg.setup().dl_data_to_ul_ack[1] = 5; + pucch_cfg.setup().dl_data_to_ul_ack[2] = 4; + pucch_cfg.setup().dl_data_to_ul_ack[3] = 4; + pucch_cfg.setup().dl_data_to_ul_ack[4] = 4; + pucch_cfg.setup().dl_data_to_ul_ack[5] = 4; + } + + // PUCCH Resource for format 1 + srsran_pucch_nr_resource_t resource_small = {}; + resource_small.starting_prb = 0; + resource_small.format = SRSRAN_PUCCH_NR_FORMAT_1; + resource_small.initial_cyclic_shift = 0; + resource_small.nof_symbols = 14; + resource_small.start_symbol_idx = 0; + resource_small.time_domain_occ = 0; + + // PUCCH Resource for format 2 + srsran_pucch_nr_resource_t resource_big = {}; + resource_big.starting_prb = 51; + resource_big.format = SRSRAN_PUCCH_NR_FORMAT_2; + resource_big.nof_prb = 1; + resource_big.nof_symbols = 2; + resource_big.start_symbol_idx = 12; + + // Resource for SR + srsran_pucch_nr_resource_t resource_sr = {}; + resource_sr.starting_prb = 51; + resource_sr.format = SRSRAN_PUCCH_NR_FORMAT_1; + resource_sr.initial_cyclic_shift = 0; + resource_sr.nof_symbols = 14; + resource_sr.start_symbol_idx = 0; + resource_sr.time_domain_occ = 0; + + // Make 3 possible resources + pucch_cfg.setup().res_to_add_mod_list.resize(3); + if (not srsran::make_phy_res_config(resource_small, pucch_cfg.setup().res_to_add_mod_list[0], 0)) { + logger.warning("Failed to create 1-2 bit NR PUCCH resource"); + } + if (not srsran::make_phy_res_config(resource_big, pucch_cfg.setup().res_to_add_mod_list[1], 1)) { + logger.warning("Failed to create >2 bit NR PUCCH resource"); + } + if (not srsran::make_phy_res_config(resource_sr, pucch_cfg.setup().res_to_add_mod_list[2], 2)) { + logger.warning("Failed to create SR NR PUCCH resource"); + } + + // Make 2 PUCCH resource sets + pucch_cfg.setup().res_set_to_add_mod_list.resize(2); + + // Make PUCCH resource set for 1-2 bit + pucch_cfg.setup().res_set_to_add_mod_list[0].pucch_res_set_id = 0; + pucch_cfg.setup().res_set_to_add_mod_list[0].res_list.resize(8); + for (auto& e : pucch_cfg.setup().res_set_to_add_mod_list[0].res_list) { + e = 0; + } + + // Make PUCCH resource set for >2 bit + pucch_cfg.setup().res_set_to_add_mod_list[1].pucch_res_set_id = 1; + pucch_cfg.setup().res_set_to_add_mod_list[1].res_list.resize(8); + for (auto& e : pucch_cfg.setup().res_set_to_add_mod_list[1].res_list) { + e = 1; + } + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pusch_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + // PUSCH config + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pusch_cfg_present = true; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pusch_cfg.set_setup(); + auto& pusch_cfg_ded = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pusch_cfg.setup(); + + pusch_cfg_ded.dmrs_ul_for_pusch_map_type_a_present = true; + pusch_cfg_ded.dmrs_ul_for_pusch_map_type_a.set_setup(); + pusch_cfg_ded.dmrs_ul_for_pusch_map_type_a.setup().dmrs_add_position_present = true; + pusch_cfg_ded.dmrs_ul_for_pusch_map_type_a.setup().dmrs_add_position = dmrs_ul_cfg_s::dmrs_add_position_opts::pos1; + // PUSH power control skipped + pusch_cfg_ded.res_alloc = pusch_cfg_s::res_alloc_opts::res_alloc_type1; + + // UCI + pusch_cfg_ded.uci_on_pusch_present = true; + pusch_cfg_ded.uci_on_pusch.set_setup(); + pusch_cfg_ded.uci_on_pusch.setup().beta_offsets_present = true; + pusch_cfg_ded.uci_on_pusch.setup().beta_offsets.set_semi_static(); + auto& beta_offset_semi_static = pusch_cfg_ded.uci_on_pusch.setup().beta_offsets.semi_static(); + beta_offset_semi_static.beta_offset_ack_idx1_present = true; + beta_offset_semi_static.beta_offset_ack_idx1 = 9; + beta_offset_semi_static.beta_offset_ack_idx2_present = true; + beta_offset_semi_static.beta_offset_ack_idx2 = 9; + beta_offset_semi_static.beta_offset_ack_idx3_present = true; + beta_offset_semi_static.beta_offset_ack_idx3 = 9; + beta_offset_semi_static.beta_offset_csi_part1_idx1_present = true; + beta_offset_semi_static.beta_offset_csi_part1_idx1 = 6; + beta_offset_semi_static.beta_offset_csi_part1_idx2_present = true; + beta_offset_semi_static.beta_offset_csi_part1_idx2 = 6; + beta_offset_semi_static.beta_offset_csi_part2_idx1_present = true; + beta_offset_semi_static.beta_offset_csi_part2_idx1 = 6; + beta_offset_semi_static.beta_offset_csi_part2_idx2_present = true; + beta_offset_semi_static.beta_offset_csi_part2_idx2 = 6; + pusch_cfg_ded.uci_on_pusch.setup().scaling = uci_on_pusch_s::scaling_opts::f1; + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp_present = true; + + pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pucch_cfg(cell_group_cfg_pack); + pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp_pusch_cfg(cell_group_cfg_pack); + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_sp_cell_cfg_ded_ul_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + // UL config dedicated + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg_present = true; + + pack_sp_cell_cfg_ded_ul_cfg_init_ul_bwp(cell_group_cfg_pack); + + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.first_active_ul_bwp_id_present = true; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.first_active_ul_bwp_id = 0; + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_sp_cell_cfg_ded_pdcch_serving_cell_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdcch_serving_cell_cfg_present = true; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdcch_serving_cell_cfg.set_setup(); + + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg_present = true; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg.set_setup(); + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg.setup().nrof_harq_processes_for_pdsch_present = + true; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.pdsch_serving_cell_cfg.setup().nrof_harq_processes_for_pdsch = + pdsch_serving_cell_cfg_s::nrof_harq_processes_for_pdsch_opts::n16; + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_sp_cell_cfg_ded(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + // SP Cell Dedicated config + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded_present = true; + + pack_sp_cell_cfg_ded_ul_cfg(cell_group_cfg_pack); + pack_sp_cell_cfg_ded_init_dl_bwp(cell_group_cfg_pack); + + // Serving cell config (only to setup) + pack_sp_cell_cfg_ded_pdcch_serving_cell_cfg(cell_group_cfg_pack); + + // spCellConfig + if (fill_sp_cell_cfg_from_enb_cfg(parent->cfg, UE_PSCELL_CC_IDX, cell_group_cfg_pack.sp_cell_cfg) != SRSRAN_SUCCESS) { + logger.error("Failed to pack spCellConfig for rnti=0x%x", rnti); + } + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common_phy_cell_group_cfg( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + cell_group_cfg_pack.phys_cell_group_cfg_present = true; + cell_group_cfg_pack.phys_cell_group_cfg.pdsch_harq_ack_codebook = + phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts::dynamic_value; + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdsch_cfg_common( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + // PDSCH config common + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp + .pdsch_cfg_common_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common + .set_setup(); + + auto& pdsch_cfg_common = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp + .pdsch_cfg_common.setup(); + pdsch_cfg_common.pdsch_time_domain_alloc_list.resize(1); + pdsch_cfg_common.pdsch_time_domain_alloc_list[0].map_type = pdsch_time_domain_res_alloc_s::map_type_opts::type_a; + pdsch_cfg_common.pdsch_time_domain_alloc_list[0].start_symbol_and_len = 40; + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp_present = true; + auto& init_dl_bwp = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp; + + init_dl_bwp.generic_params.location_and_bw = 14025; + init_dl_bwp.generic_params.subcarrier_spacing = subcarrier_spacing_opts::khz15; + + pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp_pdsch_cfg_common(cell_group_cfg_pack); + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + // DL config + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present = true; + + pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common_phy_cell_group_cfg(cell_group_cfg_pack); + pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_init_dl_bwp(cell_group_cfg_pack); + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp_pusch_cfg_common( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + // PUSCH config common + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp + .pusch_cfg_common_present = true; + auto& pusch_cfg_common_pack = + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common; + pusch_cfg_common_pack.set_setup(); + pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list.resize(2); + pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].k2_present = true; + pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].k2 = 4; + pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].map_type = + asn1::rrc_nr::pusch_time_domain_res_alloc_s::map_type_opts::type_a; + pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[0].start_symbol_and_len = 27; + pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[1].k2_present = true; + pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[1].k2 = 3; + pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[1].map_type = + asn1::rrc_nr::pusch_time_domain_res_alloc_s::map_type_opts::type_a; + pusch_cfg_common_pack.setup().pusch_time_domain_alloc_list[1].start_symbol_and_len = 27; + pusch_cfg_common_pack.setup().p0_nominal_with_grant_present = true; + pusch_cfg_common_pack.setup().p0_nominal_with_grant = -60; + + // PUCCH config common + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp + .pucch_cfg_common_present = true; + auto& pucch_cfg_common_pack = + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.pucch_cfg_common; + pucch_cfg_common_pack.set_setup(); + pucch_cfg_common_pack.setup().pucch_group_hop = asn1::rrc_nr::pucch_cfg_common_s::pucch_group_hop_opts::neither; + pucch_cfg_common_pack.setup().p0_nominal_present = true; + pucch_cfg_common_pack.setup().p0_nominal = -60; + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.generic_params + .location_and_bw = 14025; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.generic_params + .subcarrier_spacing = subcarrier_spacing_opts::khz15; + + pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp_pusch_cfg_common(cell_group_cfg_pack); + + return SRSRAN_ERROR; +} + +int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common( + asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + // UL config + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.dummy = time_align_timer_opts::ms500; + + pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common_init_ul_bwp(cell_group_cfg_pack); + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_recfg_with_sync_sp_cell_cfg_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + auto& pscell_cfg = parent->cfg.cell_list.at(UE_PSCELL_CC_IDX); + + if (pscell_cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.smtc.release(); + } + + // DL config + pack_recfg_with_sync_sp_cell_cfg_common_dl_cfg_common(cell_group_cfg_pack); + + // UL config + pack_recfg_with_sync_sp_cell_cfg_common_ul_cfg_common(cell_group_cfg_pack); + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_recfg_with_sync(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + // Reconfig with Sync + cell_group_cfg_pack.cell_group_id = 1; // 0 identifies the MCG. Other values identify SCGs. + + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.new_ue_id = rnti; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.t304 = recfg_with_sync_s::t304_opts::ms1000; + + pack_recfg_with_sync_sp_cell_cfg_common(cell_group_cfg_pack); + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::pack_secondary_cell_group_sp_cell_cfg(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) +{ + cell_group_cfg_pack.sp_cell_cfg_present = true; + cell_group_cfg_pack.sp_cell_cfg.serv_cell_idx_present = true; + cell_group_cfg_pack.sp_cell_cfg.serv_cell_idx = 1; // Serving cell ID of a PSCell. The PCell of the MCG uses ID 0. + + pack_sp_cell_cfg_ded(cell_group_cfg_pack); + pack_recfg_with_sync(cell_group_cfg_pack); + + return SRSRAN_SUCCESS; +} + +// Helper for the RRC Reconfiguration sender to pack hard-coded config +int rrc_nr::ue::pack_secondary_cell_group_cfg(asn1::dyn_octstring& packed_secondary_cell_config) +{ + auto& cell_group_cfg_pack = cell_group_cfg; + + pack_secondary_cell_group_mac_cfg(cell_group_cfg_pack); + pack_secondary_cell_group_sp_cell_cfg(cell_group_cfg_pack); + + // make sufficiant space + packed_secondary_cell_config.resize(256); + asn1::bit_ref bref_pack(packed_secondary_cell_config.data(), packed_secondary_cell_config.size()); + if (cell_group_cfg_pack.pack(bref_pack) != asn1::SRSASN_SUCCESS) { + logger.error("Failed to pack NR secondary cell config"); + return SRSRAN_ERROR; + } + packed_secondary_cell_config.resize(bref_pack.distance_bytes()); + + log_rrc_container(Tx, packed_secondary_cell_config, cell_group_cfg_pack, "nr-SecondaryCellGroupConfig-r15"); + + return SRSRAN_SUCCESS; +} + +// Packs a hard-coded RRC Reconfiguration with fixed params for all layers (for now) +int rrc_nr::ue::pack_rrc_reconfiguration(asn1::dyn_octstring& packed_rrc_reconfig) +{ + rrc_recfg_s reconfig; + reconfig.rrc_transaction_id = ((transaction_id++) % 4u); + rrc_recfg_ies_s& recfg_ies = reconfig.crit_exts.set_rrc_recfg(); + + // add secondary cell group config + if (pack_secondary_cell_group_cfg(recfg_ies.secondary_cell_group) == SRSRAN_ERROR) { + logger.error("Failed to pack secondary cell group"); + return SRSRAN_ERROR; + } + + // now pack .. + packed_rrc_reconfig.resize(512); + asn1::bit_ref bref_pack(packed_rrc_reconfig.data(), packed_rrc_reconfig.size()); + if (reconfig.pack(bref_pack) != asn1::SRSASN_SUCCESS) { + logger.error("Failed to pack RRC Reconfiguration"); + return SRSRAN_ERROR; + } + packed_rrc_reconfig.resize(bref_pack.distance_bytes()); + + return SRSRAN_SUCCESS; +} + +// Packs a hard-coded NR radio bearer config with fixed params for RLC/PDCP (for now) +int rrc_nr::ue::pack_nr_radio_bearer_config(asn1::dyn_octstring& packed_nr_bearer_config) +{ + // set security config + auto& radio_bearer_cfg_pack = radio_bearer_cfg; + radio_bearer_cfg_pack.security_cfg_present = true; + auto& sec_cfg = radio_bearer_cfg_pack.security_cfg; + sec_cfg.key_to_use_present = true; + sec_cfg.key_to_use = asn1::rrc_nr::security_cfg_s::key_to_use_opts::secondary; + sec_cfg.security_algorithm_cfg_present = true; + sec_cfg.security_algorithm_cfg.ciphering_algorithm = ciphering_algorithm_opts::nea0; + sec_cfg.security_algorithm_cfg.integrity_prot_algorithm_present = true; + sec_cfg.security_algorithm_cfg.integrity_prot_algorithm = integrity_prot_algorithm_opts::nia0; + + // pack it + packed_nr_bearer_config.resize(128); + asn1::bit_ref bref_pack(packed_nr_bearer_config.data(), packed_nr_bearer_config.size()); + if (radio_bearer_cfg_pack.pack(bref_pack) != asn1::SRSASN_SUCCESS) { + logger.error("Failed to pack NR radio bearer config"); + return SRSRAN_ERROR; + } + + // resize to packed length + packed_nr_bearer_config.resize(bref_pack.distance_bytes()); + + log_rrc_container(Tx, packed_nr_bearer_config, radio_bearer_cfg_pack, "nr-RadioBearerConfig1-r15"); + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::handle_sgnb_addition_request(uint16_t eutra_rnti_, const sgnb_addition_req_params_t& req_params) +{ + // Add DRB1 to RLC and PDCP + if (add_drb(req_params.five_qi) != SRSRAN_SUCCESS) { + parent->logger.error("Failed to configure DRB"); + parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); + return SRSRAN_ERROR; + } + + // provide hard-coded NR configs + rrc_eutra_interface_rrc_nr::sgnb_addition_ack_params_t ack_params = {}; + if (pack_rrc_reconfiguration(ack_params.nr_secondary_cell_group_cfg_r15) == SRSRAN_ERROR) { + parent->logger.error("Failed to pack RRC Reconfiguration. Sending SgNB addition reject."); + parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); + return SRSRAN_ERROR; + } + + if (pack_nr_radio_bearer_config(ack_params.nr_radio_bearer_cfg1_r15) == SRSRAN_ERROR) { + parent->logger.error("Failed to pack NR radio bearer config. Sending SgNB addition reject."); + parent->rrc_eutra->sgnb_addition_reject(eutra_rnti_); + return SRSRAN_ERROR; + } + + // send response to EUTRA + ack_params.nr_rnti = rnti; + ack_params.eps_bearer_id = req_params.eps_bearer_id; + parent->rrc_eutra->sgnb_addition_ack(eutra_rnti_, ack_params); + + // recognize RNTI as ENDC user + endc = true; + eutra_rnti = eutra_rnti_; + + return SRSRAN_SUCCESS; +} + +void rrc_nr::ue::crnti_ce_received() +{ + // Assume NSA mode active + if (endc) { + // send SgNB addition complete for ENDC users + parent->rrc_eutra->sgnb_addition_complete(eutra_rnti, rnti); + + // stop RX MSG3/MSG5 activity timer on MAC CE RNTI reception + set_activity_timeout(UE_INACTIVITY_TIMEOUT); + parent->logger.debug("Received MAC CE-RNTI for 0x%x - stopping MSG3/MSG5 timer, starting inactivity timer", rnti); + + // Add DRB1 to MAC + for (auto& drb : cell_group_cfg.rlc_bearer_to_add_mod_list) { + uecfg.lc_ch_to_add.emplace_back(); + uecfg.lc_ch_to_add.back().lcid = drb.lc_ch_id; + uecfg.lc_ch_to_add.back().cfg.direction = mac_lc_ch_cfg_t::BOTH; + uecfg.lc_ch_to_add.back().cfg.group = drb.mac_lc_ch_cfg.ul_specific_params.lc_ch_group; + } + + // Update UE phy params + srsran::make_phy_ssb_cfg(parent->cfg.cell_list[0].phy_cell.carrier, + cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, + &uecfg.phy_cfg.ssb); + srsran::make_duplex_cfg_from_serv_cell(cell_group_cfg.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common, + &uecfg.phy_cfg.duplex); + + srsran_assert(check_nr_pdcch_cfg_valid(uecfg.phy_cfg.pdcch) == SRSRAN_SUCCESS, "Invalid PhyCell Config"); + + uecfg.sp_cell_cfg.reset(new sp_cell_cfg_s{cell_group_cfg.sp_cell_cfg}); + uecfg.mac_cell_group_cfg.reset(new mac_cell_group_cfg_s{cell_group_cfg.mac_cell_group_cfg}); + uecfg.phy_cell_group_cfg.reset(new phys_cell_group_cfg_s{cell_group_cfg.phys_cell_group_cfg}); + parent->mac->ue_cfg(rnti, uecfg); + } +} + +/** + * @brief Set DRB configuration + * + * The function sets and configures all relavant fields for the DRB configuration (MAC, RLC, PDCP) in the + * cellGroupConfig and also adds the bearer to the local RLC and PDCP entities. + * + * @param int 5QI of the DRB to be added + * @return int SRSRAN_SUCCESS on success + */ +int rrc_nr::ue::add_drb(uint32_t five_qi) +{ + if (parent->cfg.five_qi_cfg.find(five_qi) == parent->cfg.five_qi_cfg.end()) { + parent->logger.error("No bearer config for 5QI %d present. Aborting DRB addition.", five_qi); + return SRSRAN_ERROR; + } + + // RLC for DRB1 (with fixed LCID) inside cell_group_cfg + auto& cell_group_cfg_pack = cell_group_cfg; + + cell_group_cfg_pack.rlc_bearer_to_add_mod_list.resize(1); + auto& rlc_bearer = cell_group_cfg_pack.rlc_bearer_to_add_mod_list[0]; + rlc_bearer.lc_ch_id = drb1_lcid; + rlc_bearer.served_radio_bearer_present = true; + rlc_bearer.served_radio_bearer.set_drb_id(); + rlc_bearer.served_radio_bearer.drb_id() = 1; + rlc_bearer.rlc_cfg_present = true; + rlc_bearer.rlc_cfg = parent->cfg.five_qi_cfg[five_qi].rlc_cfg; + + // add RLC bearer + srsran::rlc_config_t rlc_cfg; + /// NOTE, we need to pass the radio-bearer to the rlc_config + if (srsran::make_rlc_config_t(cell_group_cfg.rlc_bearer_to_add_mod_list[0].rlc_cfg, + rlc_bearer.served_radio_bearer.drb_id(), + &rlc_cfg) != SRSRAN_SUCCESS) { + parent->logger.error("Failed to build RLC config"); + return SRSRAN_ERROR; + } + parent->rlc->add_bearer(rnti, drb1_lcid, rlc_cfg); + + // MAC logical channel config + rlc_bearer.mac_lc_ch_cfg_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.prio = 11; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.prioritised_bit_rate = + asn1::rrc_nr::lc_ch_cfg_s::ul_specific_params_s_::prioritised_bit_rate_opts::kbps0; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.bucket_size_dur = + asn1::rrc_nr::lc_ch_cfg_s::ul_specific_params_s_::bucket_size_dur_opts::ms100; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.lc_ch_group_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.lc_ch_group = 3; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.sched_request_id_present = true; + rlc_bearer.mac_lc_ch_cfg.ul_specific_params.sched_request_id = 0; + // TODO: add LC config to MAC + + // PDCP config goes into radio_bearer_cfg + auto& radio_bearer_cfg_pack = radio_bearer_cfg; + radio_bearer_cfg_pack.drb_to_add_mod_list.resize(1); + + // configure fixed DRB1 + auto& drb_item = radio_bearer_cfg_pack.drb_to_add_mod_list[0]; + drb_item.drb_id = 1; + drb_item.cn_assoc_present = true; + drb_item.cn_assoc.set_eps_bearer_id() = 5; + drb_item.pdcp_cfg_present = true; + drb_item.pdcp_cfg = parent->cfg.five_qi_cfg[five_qi].pdcp_cfg; + + // Add DRB1 to PDCP + srsran::pdcp_config_t pdcp_cnfg = srsran::make_drb_pdcp_config_t(drb_item.drb_id, false, drb_item.pdcp_cfg); + parent->pdcp->add_bearer(rnti, rlc_bearer.lc_ch_id, pdcp_cnfg); + + // Note: DRB1 is only activated in the MAC when the C-RNTI CE is received + + return SRSRAN_SUCCESS; +} + +void rrc_nr::ue::handle_rrc_setup_request(const asn1::rrc_nr::rrc_setup_request_s& msg) +{ + const uint8_t max_wait_time_secs = 16; + if (not parent->ngap->is_amf_connected()) { + logger.error("MME isn't connected. Sending Connection Reject"); + send_rrc_reject(max_wait_time_secs); + return; + } + + // Allocate PUCCH resources and reject if not available + if (not init_pucch()) { + logger.warning("Could not allocate PUCCH resources for rnti=0x%x. Sending Connection Reject", rnti); + send_rrc_reject(max_wait_time_secs); + return; + } + + const rrc_setup_request_ies_s& ies = msg.rrc_setup_request; + + switch (ies.ue_id.type().value) { + case init_ue_id_c::types_opts::ng_minus5_g_s_tmsi_part1: + ctxt.setup_ue_id = ies.ue_id.ng_minus5_g_s_tmsi_part1().to_number(); + break; + case asn1::rrc_nr::init_ue_id_c::types_opts::random_value: + ctxt.setup_ue_id = ies.ue_id.random_value().to_number(); + // TODO: communicate with NGAP + break; + default: + logger.error("Unsupported RRCSetupRequest"); + send_rrc_reject(max_wait_time_secs); + return; + } + ctxt.connection_cause.value = ies.establishment_cause.value; + + send_rrc_setup(); + set_activity_timeout(UE_INACTIVITY_TIMEOUT); +} + +void rrc_nr::ue::handle_rrc_reestablishment_request(const asn1::rrc_nr::rrc_reest_request_s& msg) +{ + uint32_t old_rnti = msg.rrc_reest_request.ue_id.c_rnti; + uint16_t pci = msg.rrc_reest_request.ue_id.pci; + + // Log event + parent->logger.debug("rnti=0x%x, phyid=0x%x, smac=0x%x, cause=%s", + old_rnti, + pci, + (uint32_t)msg.rrc_reest_request.ue_id.short_mac_i.to_number(), + msg.rrc_reest_request.reest_cause.to_string()); + + // Check AMF connection + const uint8_t max_wait_time_secs = 16; + if (not parent->ngap->is_amf_connected()) { + logger.error("AMF not connected. Sending Connection Reject."); + send_rrc_reject(max_wait_time_secs); + return; + } + + // Allocate PUCCH resources and reject if not available + if (not init_pucch()) { + logger.warning("Could not allocate PUCCH resources for rnti=0x%x. Sending RRC Reject.", rnti); + send_rrc_reject(max_wait_time_secs); + return; + } + + if (not is_idle()) { + // The created RNTI has to receive ReestablishmentRequest as first message + parent->logger.error( + "Could not reestablish connection for rnti=0x%x. Cause: old rnti=0x%x is not in RRC_IDLE.", rnti, old_rnti); + send_rrc_reject(max_wait_time_secs); + return; + } + + auto old_ue_it = parent->users.find(old_rnti); + + // Fallback to connection establishment for unrecognized rntis, and PCIs that do not belong to eNB + if (old_ue_it == parent->users.end()) { + parent->logger.info( + "Fallback to connection establishment for rnti=0x%x. Cause: no rnti=0x%x context available", rnti, old_rnti); + srsran::console("Fallback to connection establishment for rnti=0x%x. Cause: no context available\n", rnti); + + // send RRC Setup + send_rrc_setup(); + set_activity_timeout(UE_INACTIVITY_TIMEOUT); + + return; + } + + // Reestablishment procedure going forward + parent->logger.info("ConnectionReestablishmentRequest for rnti=0x%x. Sending Connection Reestablishment.", old_rnti); + srsran::console("User 0x%x requesting RRC Reestablishment as 0x%x. Cause: %s\n", + rnti, + old_rnti, + msg.rrc_reest_request.reest_cause.to_string()); + + ue* old_ue = old_ue_it->second.get(); + + // Recover security setup + sec_ctx = old_ue->sec_ctx; + auto& pscell_cfg = parent->cfg.cell_list.at(UE_PSCELL_CC_IDX); + sec_ctx.regenerate_keys_handover(pscell_cfg.phy_cell.carrier.pci, pscell_cfg.ssb_absolute_freq_point); + + // For the reestablishment, only add SRB1 to new UE context + next_radio_bearer_cfg.srb_to_add_mod_list.resize(1); + srb_to_add_mod_s& srb1 = next_radio_bearer_cfg.srb_to_add_mod_list[0]; + srb1.srb_id = 1; + + // compute config and create SRB1 for new user + asn1::rrc_nr::radio_bearer_cfg_s dummy_radio_bearer_cfg; // just to compute difference, it's never sent to UE + compute_diff_radio_bearer_cfg(parent->cfg, radio_bearer_cfg, next_radio_bearer_cfg, dummy_radio_bearer_cfg); + if (fill_cellgroup_with_radio_bearer_cfg( + parent->cfg, old_rnti, *parent->bearer_mapper, dummy_radio_bearer_cfg, next_cell_group_cfg) != + SRSRAN_SUCCESS) { + logger.error("Couldn't fill cellGroupCfg during RRC Reestablishment"); + send_rrc_reject(max_wait_time_secs); + return; + } + + // send RRC Reestablishment message and restore bearer configuration + send_connection_reest(old_ue->sec_ctx.get_ncc()); + + // store current bearer/cell config with configured SRB1 + radio_bearer_cfg = next_radio_bearer_cfg; + cell_group_cfg = next_cell_group_cfg; + + // recover all previously created bearers from old UE object for (later) reconfiguration + next_radio_bearer_cfg = old_ue->radio_bearer_cfg; + next_cell_group_cfg = old_ue->cell_group_cfg; + + // Recover GTP-U tunnels and NGAP context + parent->gtpu->mod_bearer_rnti(old_rnti, rnti); + parent->ngap->user_mod(old_rnti, rnti); + + // Reestablish E-RABs of old rnti later, during ConnectionReconfiguration + // bearer_list.reestablish_bearers(std::move(old_ue->bearer_list)); + drb1_five_qi = old_ue->drb1_five_qi; + + // remove old RNTI + old_ue->deactivate_bearers(); + parent->bearer_mapper->rem_user(old_rnti); + parent->task_sched.defer_task([this, old_rnti]() { parent->rem_user(old_rnti); }); + + set_activity_timeout(MSG5_RX_TIMEOUT); +} + +void rrc_nr::ue::send_connection_reest(uint8_t ncc) +{ + dl_dcch_msg_s msg; + rrc_reest_ies_s& reest = msg.msg.set_c1().set_rrc_reest().crit_exts.set_rrc_reest(); + + msg.msg.c1().rrc_reest().rrc_transaction_id = (uint8_t)((transaction_id++) % 4); + + // set NCC + reest.next_hop_chaining_count = ncc; + + // add RLC bearers + update_rlc_bearers(next_cell_group_cfg); + + // add PDCP bearers + // this is done after updating the RLC bearers, + // so the PDCP can query the RLC mode + update_pdcp_bearers(next_radio_bearer_cfg, next_cell_group_cfg); + + // add MAC bearers + update_mac(next_cell_group_cfg, false); + + if (send_dl_dcch(srsran::nr_srb::srb1, msg) != SRSRAN_SUCCESS) { + // TODO: Handle + } +} + +/// TS 38.331, RRCReject message +void rrc_nr::ue::send_rrc_reject(uint8_t reject_wait_time_secs) +{ + dl_ccch_msg_s msg; + rrc_reject_ies_s& reject = msg.msg.set_c1().set_rrc_reject().crit_exts.set_rrc_reject(); + + // See TS 38.331, RejectWaitTime + if (reject_wait_time_secs > 0) { + reject.wait_time_present = true; + reject.wait_time = reject_wait_time_secs; + } + if (send_dl_ccch(msg) != SRSRAN_SUCCESS) { + // TODO: Handle + } + + // TODO: remove user +} + +/// TS 38.331, RRCSetup +void rrc_nr::ue::send_rrc_setup() +{ + const uint8_t max_wait_time_secs = 16; + + // Add SRB1 to UE context + // Note: See 5.3.5.6.3 - SRB addition/modification + next_radio_bearer_cfg.srb_to_add_mod_list.resize(1); + srb_to_add_mod_s& srb1 = next_radio_bearer_cfg.srb_to_add_mod_list[0]; + srb1.srb_id = 1; + + // Generate RRC setup message + dl_ccch_msg_s msg; + rrc_setup_s& setup = msg.msg.set_c1().set_rrc_setup(); + setup.rrc_transaction_id = (uint8_t)((transaction_id++) % 4); + rrc_setup_ies_s& setup_ies = setup.crit_exts.set_rrc_setup(); + + // Fill RRC Setup + // - Setup SRB1 + compute_diff_radio_bearer_cfg(parent->cfg, radio_bearer_cfg, next_radio_bearer_cfg, setup_ies.radio_bearer_cfg); + + // - Setup masterCellGroup + // - Derive master cell group config bearers + if (fill_cellgroup_with_radio_bearer_cfg( + parent->cfg, rnti, *parent->bearer_mapper, setup_ies.radio_bearer_cfg, next_cell_group_cfg) != + SRSRAN_SUCCESS) { + logger.error("Couldn't fill cellGroupCfg during RRC Setup"); + send_rrc_reject(max_wait_time_secs); + return; + } + + // - Pack masterCellGroup into container + srsran::unique_byte_buffer_t pdu = parent->pack_into_pdu(next_cell_group_cfg, __FUNCTION__); + if (pdu == nullptr) { + send_rrc_reject(max_wait_time_secs); + return; + } + setup_ies.master_cell_group.resize(pdu->N_bytes); + memcpy(setup_ies.master_cell_group.data(), pdu->data(), pdu->N_bytes); + if (logger.debug.enabled()) { + asn1::json_writer js; + next_cell_group_cfg.to_json(js); + logger.debug("Containerized MasterCellGroup: %s", js.to_string().c_str()); + } + + // add RLC bearers + update_rlc_bearers(next_cell_group_cfg); + + // add PDCP bearers + // this is done after updating the RLC bearers, + // so the PDCP can query the RLC mode + update_pdcp_bearers(next_radio_bearer_cfg, next_cell_group_cfg); + + // add MAC bearers + update_mac(next_cell_group_cfg, false); + + // Send RRC Setup message to UE + if (send_dl_ccch(msg) != SRSRAN_SUCCESS) { + send_rrc_reject(max_wait_time_secs); + } +} + +/// TS 38.331, RRCSetupComplete +void rrc_nr::ue::handle_rrc_setup_complete(const asn1::rrc_nr::rrc_setup_complete_s& msg) +{ + update_mac(next_cell_group_cfg, true); + + // Update current radio bearer cfg + radio_bearer_cfg = next_radio_bearer_cfg; + cell_group_cfg = next_cell_group_cfg; + + // Create UE context in NGAP + using ngap_cause_t = asn1::ngap::rrcestablishment_cause_opts::options; + auto ngap_cause = (ngap_cause_t)ctxt.connection_cause.value; // NGAP and RRC causes seem to have a 1-1 mapping + parent->ngap->initial_ue( + rnti, uecfg.carriers[0].cc, ngap_cause, msg.crit_exts.rrc_setup_complete().ded_nas_msg, ctxt.setup_ue_id); +} + +/// TS 38.331, SecurityModeCommand +void rrc_nr::ue::send_security_mode_command(srsran::unique_byte_buffer_t nas_pdu) +{ + // apply selected security config and enable integrity on SRB1 before generating security mode command + update_as_security(srb_to_lcid(srsran::nr_srb::srb1), true, false); + + if (nas_pdu != nullptr) { + nas_pdu_queue.push_back(std::move(nas_pdu)); + } + + asn1::rrc_nr::dl_dcch_msg_s dl_dcch_msg; + dl_dcch_msg.msg.set_c1().set_security_mode_cmd().rrc_transaction_id = (uint8_t)((transaction_id++) % 4); + security_mode_cmd_ies_s& ies = dl_dcch_msg.msg.c1().security_mode_cmd().crit_exts.set_security_mode_cmd(); + + ies.security_cfg_smc.security_algorithm_cfg.integrity_prot_algorithm_present = true; + ies.security_cfg_smc.security_algorithm_cfg = sec_ctx.get_security_algorithm_cfg(); + + if (send_dl_dcch(srsran::nr_srb::srb1, dl_dcch_msg) != SRSRAN_SUCCESS) { + parent->ngap->user_release_request(rnti, asn1::ngap::cause_radio_network_opts::radio_res_not_available); + } +} + +/** + * @brief Internal helper to update the security configuration of a PDCP bearer + * + * If no valid AS security config is present (yet) the method doesn't modify the + * PDCP config and returns SRSRAN_ERROR. In some cases, however, + * for example during RRC Setup, this is in fact the expected behaviour as + * AS security isn't established yet. + * + * @param lcid Logical channel ID of the bearer + * @param enable_integrity Whether to enable integrity protection for the bearer + * @param enable_ciphering Whether to enable ciphering for the bearer + * @return int SRSRAN_SUCCESS if a valid AS security config was found and the security was configured + */ +int rrc_nr::ue::update_as_security(uint32_t lcid, bool enable_integrity = true, bool enable_ciphering = true) +{ + if (not sec_ctx.is_as_sec_cfg_valid()) { + parent->logger.error("Invalid AS security configuration. Skipping configuration for lcid=%d", lcid); + return SRSRAN_ERROR; + } + + // TODO: Currently we are using the PDCP-LTE, so we need to convert from nr_as_security_cfg to as_security_config. + // When we start using PDCP-NR we can avoid this step. + srsran::nr_as_security_config_t tmp_cnfg = sec_ctx.get_as_sec_cfg(); + srsran::as_security_config_t pdcp_cnfg = {}; + pdcp_cnfg.k_rrc_int = tmp_cnfg.k_nr_rrc_int; + pdcp_cnfg.k_rrc_enc = tmp_cnfg.k_nr_rrc_enc; + pdcp_cnfg.k_up_int = tmp_cnfg.k_nr_up_int; + pdcp_cnfg.k_up_enc = tmp_cnfg.k_nr_up_enc; + pdcp_cnfg.integ_algo = (srsran::INTEGRITY_ALGORITHM_ID_ENUM)tmp_cnfg.integ_algo; + pdcp_cnfg.cipher_algo = (srsran::CIPHERING_ALGORITHM_ID_ENUM)tmp_cnfg.cipher_algo; + + // configure algorithm and keys + parent->pdcp->config_security(rnti, lcid, pdcp_cnfg); + + if (enable_integrity) { + parent->pdcp->enable_integrity(rnti, lcid); + } + + if (enable_ciphering) { + parent->pdcp->enable_encryption(rnti, lcid); + } + + return SRSRAN_SUCCESS; +} + +/// TS 38.331, SecurityModeComplete +void rrc_nr::ue::handle_security_mode_complete(const asn1::rrc_nr::security_mode_complete_s& msg) +{ + parent->logger.info("SecurityModeComplete transaction ID: %d", msg.rrc_transaction_id); + + // finally, also enable ciphering on SRB1 + update_as_security(srb_to_lcid(srsran::nr_srb::srb1), false, true); + + send_ue_capability_enquiry(); +} + +/// TS 38.331, RRCReconfiguration +void rrc_nr::ue::send_rrc_reconfiguration() +{ + dl_dcch_msg_s dl_dcch_msg; + dl_dcch_msg.msg.set_c1().set_rrc_recfg().rrc_transaction_id = (uint8_t)((transaction_id++) % 4); + rrc_recfg_ies_s& ies = dl_dcch_msg.msg.c1().rrc_recfg().crit_exts.set_rrc_recfg(); + + // Add new SRBs/DRBs + ies.radio_bearer_cfg_present = + compute_diff_radio_bearer_cfg(parent->cfg, radio_bearer_cfg, next_radio_bearer_cfg, ies.radio_bearer_cfg); + + // If no bearer to add/mod/remove, do not include master_cell_group + // Set ies.non_crit_ext_present (a few lines below) only if + // master_cell_group_present == true or ies.non_crit_ext.ded_nas_msg_list_present == true + if (ies.radio_bearer_cfg_present) { + // Fill masterCellGroup + cell_group_cfg_s master_cell_group; + master_cell_group.cell_group_id = 0; + if (fill_cellgroup_with_radio_bearer_cfg( + parent->cfg, rnti, *parent->bearer_mapper, ies.radio_bearer_cfg, master_cell_group) != SRSRAN_SUCCESS) { + logger.error("Couldn't fill cellGroupCfg during RRC Reconfiguration"); + parent->ngap->user_release_request(rnti, asn1::ngap::cause_radio_network_opts::radio_res_not_available); + return; + } + + // Pack masterCellGroup into container + srsran::unique_byte_buffer_t pdu = parent->pack_into_pdu(master_cell_group, __FUNCTION__); + if (pdu == nullptr) { + parent->ngap->user_release_request(rnti, asn1::ngap::cause_radio_network_opts::radio_res_not_available); + return; + } + ies.non_crit_ext.master_cell_group.resize(pdu->N_bytes); + memcpy(ies.non_crit_ext.master_cell_group.data(), pdu->data(), pdu->N_bytes); + if (logger.debug.enabled()) { + asn1::json_writer js; + master_cell_group.to_json(js); + logger.debug("Containerized MasterCellGroup: %s", js.to_string().c_str()); + } + + // Update lower layers + // add MAC bearers + update_mac(master_cell_group, false); + + // add RLC bearers + update_rlc_bearers(master_cell_group); + + // add PDCP bearers + // this is done after updating the RLC bearers, + // so the PDCP can query the RLC mode + update_pdcp_bearers(ies.radio_bearer_cfg, master_cell_group); + } + + if (nas_pdu_queue.size() > 0) { + // Pass stored NAS PDUs + ies.non_crit_ext.ded_nas_msg_list.resize(nas_pdu_queue.size()); + for (uint32_t i = 0; i < nas_pdu_queue.size(); ++i) { + ies.non_crit_ext.ded_nas_msg_list[i].resize(nas_pdu_queue[i]->size()); + memcpy(ies.non_crit_ext.ded_nas_msg_list[i].data(), nas_pdu_queue[i]->data(), nas_pdu_queue[i]->size()); + } + nas_pdu_queue.clear(); + } + + ies.non_crit_ext_present = + ies.non_crit_ext.master_cell_group.size() > 0 or ies.non_crit_ext.ded_nas_msg_list.size() > 0; + + if (send_dl_dcch(srsran::nr_srb::srb1, dl_dcch_msg) != SRSRAN_SUCCESS) { + parent->ngap->user_release_request(rnti, asn1::ngap::cause_radio_network_opts::radio_res_not_available); + } +} + +int rrc_nr::ue::send_ue_capability_enquiry() +{ + dl_dcch_msg_s dl_dcch_msg; + dl_dcch_msg.msg.set_c1().set_ue_cap_enquiry().rrc_transaction_id = (uint8_t)((transaction_id++) % 4); + ue_cap_enquiry_ies_s& ies = dl_dcch_msg.msg.c1().ue_cap_enquiry().crit_exts.set_ue_cap_enquiry(); + + // ue-CapabilityRAT-RequestList + ue_cap_rat_request_s cap_rat_request; + cap_rat_request.rat_type.value = rat_type_opts::nr; + + // capabilityRequestFilter + ue_cap_request_filt_nr_s request_filter; + + // frequencyBandListFilter + freq_band_info_c freq_band_info; + freq_band_info_nr_s& freq_band_info_nr = freq_band_info.set_band_info_nr(); + + // Iterate through cell list and assign bandInformationNR items + for (auto& iter : parent->cfg.cell_list) { + freq_band_info_nr.band_nr = iter.band; + request_filter.freq_band_list_filt.push_back(freq_band_info); + } + + // Pack capabilityRequestFilter + cap_rat_request.cap_request_filt.resize(128); + asn1::bit_ref bref_pack(cap_rat_request.cap_request_filt.data(), cap_rat_request.cap_request_filt.size()); + if (request_filter.pack(bref_pack) != asn1::SRSASN_SUCCESS) { + logger.error("Failed to pack capabilityRequestFilter in UE Capability Enquiry"); + return SRSRAN_ERROR; + } + cap_rat_request.cap_request_filt.resize(bref_pack.distance_bytes()); + + ies.ue_cap_rat_request_list.push_back(cap_rat_request); + + send_dl_dcch(srsran::nr_srb::srb1, dl_dcch_msg); + + return SRSRAN_SUCCESS; +} + +void rrc_nr::ue::handle_ue_capability_information(const asn1::rrc_nr::ue_cap_info_s& msg) +{ + logger.info("UECapabilityInformation transaction ID: %d", msg.rrc_transaction_id); + + send_rrc_reconfiguration(); + + // Send RRCReconfiguration if necessary + if (not nas_pdu_queue.empty()) { + send_rrc_reconfiguration(); + } +} + +void rrc_nr::ue::handle_rrc_reconfiguration_complete(const asn1::rrc_nr::rrc_recfg_complete_s& msg) +{ + update_mac(next_cell_group_cfg, true); + + radio_bearer_cfg = next_radio_bearer_cfg; + cell_group_cfg = next_cell_group_cfg; + parent->ngap->ue_notify_rrc_reconf_complete(rnti, true); +} + +void rrc_nr::ue::handle_rrc_reestablishment_complete(const asn1::rrc_nr::rrc_reest_complete_s& msg) +{ + // Register DRB again, TODO: combine/move to establish_eps_bearer() + for (const auto& drb : next_radio_bearer_cfg.drb_to_add_mod_list) { + uint16_t lcid = drb1_lcid; + parent->bearer_mapper->add_eps_bearer(rnti, lcid - 3, srsran::srsran_rat_t::nr, lcid); + parent->bearer_mapper->set_five_qi(rnti, lcid - 3, drb1_five_qi); + + logger.info("Established EPS bearer for LCID %u and RNTI 0x%x", lcid, rnti); + } + + // send reconfiguration to reestablish SRB2 and all previously established DRBs + send_rrc_reconfiguration(); +} + +void rrc_nr::ue::send_rrc_release() +{ + static const uint32_t release_delay = 60; // Taken from TS 38.331, 5.3.8.3 + + dl_dcch_msg_s dl_dcch_msg; + rrc_release_s& release = dl_dcch_msg.msg.set_c1().set_rrc_release(); + + release.rrc_transaction_id = (uint8_t)((transaction_id++) % 4); + rrc_release_ies_s& ies = release.crit_exts.set_rrc_release(); + + ies.suspend_cfg_present = false; // goes to RRC_IDLE + + send_dl_dcch(srsran::nr_srb::srb1, dl_dcch_msg); + state = rrc_nr_state_t::RRC_IDLE; + + // TODO: Obtain acknowledgment from lower layers that RRC Release was received + parent->task_sched.defer_callback(release_delay, [this]() { parent->rem_user(rnti); }); +} + +void rrc_nr::ue::send_dl_information_transfer(srsran::unique_byte_buffer_t sdu) +{ + dl_dcch_msg_s dl_dcch_msg; + dl_dcch_msg.msg.set_c1().set_dl_info_transfer().rrc_transaction_id = (uint8_t)((transaction_id++) % 4); + dl_info_transfer_ies_s& ies = dl_dcch_msg.msg.c1().dl_info_transfer().crit_exts.set_dl_info_transfer(); + + ies.ded_nas_msg.resize(sdu->N_bytes); + memcpy(ies.ded_nas_msg.data(), sdu->data(), ies.ded_nas_msg.size()); + + if (send_dl_dcch(srsran::nr_srb::srb1, dl_dcch_msg) != SRSRAN_SUCCESS) { + parent->ngap->user_release_request(rnti, asn1::ngap::cause_radio_network_opts::radio_res_not_available); + } +} + +void rrc_nr::ue::handle_ul_information_transfer(const asn1::rrc_nr::ul_info_transfer_s& msg) +{ + // Forward dedicatedNAS-Message to NGAP + parent->ngap->write_pdu(rnti, msg.crit_exts.ul_info_transfer().ded_nas_msg); +} + +void rrc_nr::ue::establish_eps_bearer(uint32_t pdu_session_id, + srsran::const_byte_span nas_pdu, + uint32_t lcid, + uint32_t five_qi) +{ + if (parent->cfg.five_qi_cfg.find(five_qi) == parent->cfg.five_qi_cfg.end()) { + parent->logger.error("No bearer config for 5QI %d present. Aborting DRB addition.", five_qi); + return; + } + + // Enqueue NAS PDU + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (pdu == nullptr) { + logger.error("Couldn't allocate NAS PDU in %s().", __FUNCTION__); + return; + } + pdu->resize(nas_pdu.size()); + memcpy(pdu->data(), nas_pdu.data(), nas_pdu.size()); + nas_pdu_queue.push_back(std::move(pdu)); + + // Add SRB2, if not yet added + asn1::rrc_nr::srb_to_add_mod_s* srb_it = + std::find_if(radio_bearer_cfg.srb_to_add_mod_list.begin(), + radio_bearer_cfg.srb_to_add_mod_list.end(), + [](const asn1::rrc_nr::srb_to_add_mod_s& srb) { return srb.srb_id == 2; }); + + if (srb_it == radio_bearer_cfg.srb_to_add_mod_list.end()) { + next_radio_bearer_cfg.srb_to_add_mod_list.push_back(srb_to_add_mod_s{}); + next_radio_bearer_cfg.srb_to_add_mod_list.back().srb_id = 2; + } + + drb_to_add_mod_s drb; + drb.cn_assoc_present = true; + drb.cn_assoc.set_sdap_cfg().pdu_session = pdu_session_id; + drb.cn_assoc.sdap_cfg().sdap_hdr_dl.value = asn1::rrc_nr::sdap_cfg_s::sdap_hdr_dl_opts::absent; + drb.cn_assoc.sdap_cfg().sdap_hdr_ul.value = asn1::rrc_nr::sdap_cfg_s::sdap_hdr_ul_opts::absent; + drb.cn_assoc.sdap_cfg().default_drb = true; + drb.cn_assoc.sdap_cfg().mapped_qos_flows_to_add.resize(1); + drb.cn_assoc.sdap_cfg().mapped_qos_flows_to_add[0] = 1; + + drb.drb_id = lcid - srsran::MAX_NR_SRB_ID; + drb.pdcp_cfg_present = true; + drb.pdcp_cfg = parent->cfg.five_qi_cfg[five_qi].pdcp_cfg; + + next_radio_bearer_cfg.drb_to_add_mod_list.push_back(drb); + + parent->bearer_mapper->add_eps_bearer(rnti, + pdu_session_id, + srsran::srsran_rat_t::nr, + lcid); // TODO: configurable bearer id <-> lcid mapping + parent->bearer_mapper->set_five_qi(rnti, pdu_session_id, five_qi); + + // store 5QI for possible reestablishment of DRB + drb1_five_qi = five_qi; + + logger.info("Established EPS bearer for LCID %u and RNTI 0x%x", lcid, rnti); +} + +bool rrc_nr::ue::init_pucch() +{ + // TODO: Allocate PUCCH resources + + return true; +} + +int rrc_nr::ue::update_pdcp_bearers(const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_diff, + const asn1::rrc_nr::cell_group_cfg_s& cell_group_diff) +{ + // release DRBs + // TODO + + // add SRBs + for (const srb_to_add_mod_s& srb : radio_bearer_diff.srb_to_add_mod_list) { + srsran::pdcp_config_t pdcp_cnfg = srsran::make_nr_srb_pdcp_config_t(srb.srb_id, false); + const rlc_bearer_cfg_s* rlc_bearer = nullptr; + for (const rlc_bearer_cfg_s& item : cell_group_diff.rlc_bearer_to_add_mod_list) { + if (item.served_radio_bearer.type().value == rlc_bearer_cfg_s::served_radio_bearer_c_::types_opts::srb_id and + item.served_radio_bearer.srb_id() == srb.srb_id) { + rlc_bearer = &item; + break; + } + } + if (rlc_bearer == nullptr) { + logger.error("Inconsistency between cellGroupConfig and radioBearerConfig in ASN1 message"); + return SRSRAN_ERROR; + } + parent->pdcp->add_bearer(rnti, rlc_bearer->lc_ch_id, pdcp_cnfg); + + if (sec_ctx.is_as_sec_cfg_valid()) { + update_as_security(rlc_bearer->lc_ch_id); + } + } + + // Add DRBs + for (const drb_to_add_mod_s& drb : radio_bearer_diff.drb_to_add_mod_list) { + srsran::pdcp_config_t pdcp_cnfg = srsran::make_drb_pdcp_config_t(drb.drb_id, false, drb.pdcp_cfg); + const rlc_bearer_cfg_s* rlc_bearer = nullptr; + for (const rlc_bearer_cfg_s& item : cell_group_diff.rlc_bearer_to_add_mod_list) { + if (item.served_radio_bearer.type().value == rlc_bearer_cfg_s::served_radio_bearer_c_::types_opts::drb_id and + item.served_radio_bearer.drb_id() == drb.drb_id) { + rlc_bearer = &item; + break; + } + } + if (rlc_bearer == nullptr) { + logger.error("Inconsistency between cellGroupConfig and radioBearerConfig in ASN1 message"); + return SRSRAN_ERROR; + } + parent->pdcp->add_bearer(rnti, rlc_bearer->lc_ch_id, pdcp_cnfg); + + if (sec_ctx.is_as_sec_cfg_valid()) { + update_as_security(rlc_bearer->lc_ch_id, drb.pdcp_cfg.drb.integrity_protection_present, true); + } + } + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::update_rlc_bearers(const asn1::rrc_nr::cell_group_cfg_s& cell_group_diff) +{ + // Release RLC radio bearers + for (uint8_t lcid : cell_group_diff.rlc_bearer_to_release_list) { + parent->rlc->del_bearer(rnti, lcid); + } + + // Add/Mod RLC radio bearers + for (const rlc_bearer_cfg_s& rb : cell_group_diff.rlc_bearer_to_add_mod_list) { + srsran::rlc_config_t rlc_cfg; + uint8_t rb_id = 0; + if (rb.served_radio_bearer.type().value == rlc_bearer_cfg_s::served_radio_bearer_c_::types_opts::srb_id) { + rb_id = rb.served_radio_bearer.srb_id(); + if (not rb.rlc_cfg_present) { + rlc_cfg = srsran::rlc_config_t::default_rlc_am_nr_config(); + } else { + if (srsran::make_rlc_config_t(rb.rlc_cfg, rb_id, &rlc_cfg) != SRSRAN_SUCCESS) { + logger.error("Failed to build RLC config"); + // TODO: HANDLE + return SRSRAN_ERROR; + } + } + } else { + rb_id = rb.served_radio_bearer.drb_id(); + if (not rb.rlc_cfg_present) { + logger.error("No RLC config for DRB"); + // TODO: HANDLE + return SRSRAN_ERROR; + } + if (srsran::make_rlc_config_t(rb.rlc_cfg, rb_id, &rlc_cfg) != SRSRAN_SUCCESS) { + logger.error("Failed to build RLC config"); + // TODO: HANDLE + return SRSRAN_ERROR; + } + } + parent->rlc->add_bearer(rnti, rb.lc_ch_id, rlc_cfg); + } + + return SRSRAN_SUCCESS; +} + +int rrc_nr::ue::update_mac(const cell_group_cfg_s& cell_group_config, bool is_config_complete) +{ + if (not is_config_complete) { + // Release bearers + for (uint8_t lcid : cell_group_config.rlc_bearer_to_release_list) { + uecfg.lc_ch_to_rem.push_back(lcid); + } + + for (const rlc_bearer_cfg_s& bearer : cell_group_config.rlc_bearer_to_add_mod_list) { + uecfg.lc_ch_to_add.emplace_back(); + uecfg.lc_ch_to_add.back().lcid = bearer.lc_ch_id; + auto& lch = uecfg.lc_ch_to_add.back().cfg; + lch.direction = mac_lc_ch_cfg_t::BOTH; + if (bearer.mac_lc_ch_cfg.ul_specific_params_present) { + lch.priority = bearer.mac_lc_ch_cfg.ul_specific_params.prio; + lch.pbr = bearer.mac_lc_ch_cfg.ul_specific_params.prioritised_bit_rate.to_number(); + lch.bsd = bearer.mac_lc_ch_cfg.ul_specific_params.bucket_size_dur.to_number(); + lch.group = bearer.mac_lc_ch_cfg.ul_specific_params.lc_ch_group; + // TODO: remaining fields + } + } + + if (cell_group_config.sp_cell_cfg_present and cell_group_config.sp_cell_cfg.sp_cell_cfg_ded_present and + cell_group_config.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg_present and + cell_group_config.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp_present and + cell_group_config.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pucch_cfg_present) { + auto& pucch_cfg = cell_group_config.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg.init_ul_bwp.pucch_cfg.setup(); + srsran::fill_phy_pucch_cfg(pucch_cfg, &uecfg.phy_cfg.pucch); + } + } else { + auto& pdcch = cell_group_config.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg.setup(); + for (auto& ss : pdcch.search_spaces_to_add_mod_list) { + uecfg.phy_cfg.pdcch.search_space_present[ss.search_space_id] = true; + srsran::make_phy_search_space_cfg(ss, &uecfg.phy_cfg.pdcch.search_space[ss.search_space_id]); + } + for (auto& cs : pdcch.ctrl_res_set_to_add_mod_list) { + uecfg.phy_cfg.pdcch.coreset_present[cs.ctrl_res_set_id] = true; + srsran::make_phy_coreset_cfg(cs, &uecfg.phy_cfg.pdcch.coreset[cs.ctrl_res_set_id]); + } + } + + uecfg.sp_cell_cfg.reset(new sp_cell_cfg_s{cell_group_cfg.sp_cell_cfg}); + uecfg.mac_cell_group_cfg.reset(new mac_cell_group_cfg_s{cell_group_cfg.mac_cell_group_cfg}); + uecfg.phy_cell_group_cfg.reset(new phys_cell_group_cfg_s{cell_group_cfg.phys_cell_group_cfg}); + srsran::make_csi_cfg_from_serv_cell(cell_group_config.sp_cell_cfg.sp_cell_cfg_ded, &uecfg.phy_cfg.csi); + parent->mac->ue_cfg(rnti, uecfg); + + return SRSRAN_SUCCESS; +} + +/** + * @brief Deactivate all Bearers (MAC logical channel) for this specific RNTI + * + * The function iterates over the bearers or MAC logical channels and deactivates them by setting each one to IDLE + */ +void rrc_nr::ue::deactivate_bearers() +{ + // Iterate over the bearers (MAC LC CH) and set each of them to IDLE + for (uint32_t lcid = 1; lcid < SCHED_NR_MAX_LCID; ++lcid) { + uecfg.lc_ch_to_rem.push_back(lcid); + } + + // No need to check the returned value, as the function ue_cfg will return SRSRAN_SUCCESS (it asserts if it fails) + uecfg.phy_cell_group_cfg = {}; + uecfg.mac_cell_group_cfg = {}; + uecfg.sp_cell_cfg = {}; + parent->mac->ue_cfg(rnti, uecfg); +} + +template +void rrc_nr::ue::log_rrc_message(srsran::nr_srb srb, + const direction_t dir, + srsran::const_byte_span pdu, + const M& msg, + const char* msg_type) +{ + fmt::memory_buffer strbuf; + fmt::format_to(strbuf, "rnti=0x{:x}, {}", rnti, srsran::get_srb_name(srb)); + parent->log_rrc_message(srsran::to_c_str(strbuf), Tx, pdu, msg, msg_type); +} + +template +void rrc_nr::ue::log_rrc_container(const direction_t dir, + srsran::const_byte_span pdu, + const M& msg, + const char* msg_type) +{ + fmt::memory_buffer strbuf; + fmt::format_to(strbuf, "rnti=0x{:x}, container", rnti); + parent->log_rrc_message(srsran::to_c_str(strbuf), Tx, pdu, msg, msg_type); +} + +} // namespace srsenb diff --git a/srsgnb/src/stack/rrc/test/CMakeLists.txt b/srsgnb/src/stack/rrc/test/CMakeLists.txt new file mode 100644 index 0000000000..40e2b9ed41 --- /dev/null +++ b/srsgnb/src/stack/rrc/test/CMakeLists.txt @@ -0,0 +1,31 @@ +# +# Copyright 2013-2023 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/. +# + +add_library(rrc_nr_test_helpers STATIC rrc_nr_test_helpers.cc) + +add_executable(rrc_nr_test rrc_nr_test.cc) +target_link_libraries(rrc_nr_test srsgnb_rrc srsgnb_rrc_config_utils srsran_common rrc_nr_asn1 rrc_nr_test_helpers srsgnb_mac ${ATOMIC_LIBS}) +add_test(rrc_nr_test rrc_nr_test) + +add_executable(rrc_nr_core_test rrc_nr_core_test.cc) +target_link_libraries(rrc_nr_core_test srsgnb_rrc srsgnb_rrc_config_utils srsran_common rrc_nr_asn1 test_helpers + rrc_nr_test_helpers srsgnb_mac srsgnb_ngap ngap_nr_asn1 srsran_gtpu + srsenb_upper ${SCTP_LIBRARIES} ${ATOMIC_LIBS} ${Boost_LIBRARIES}) + diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc b/srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc new file mode 100644 index 0000000000..6085cc6f3b --- /dev/null +++ b/srsgnb/src/stack/rrc/test/rrc_nr_core_test.cc @@ -0,0 +1,228 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "rrc_nr_test_helpers.h" +#include "srsenb/hdr/enb.h" +#include "srsenb/hdr/stack/upper/gtpu.h" +#include "srsenb/test/rrc/test_helpers.h" +#include "srsgnb/hdr/stack/ngap/ngap.h" +#include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h" +#include "srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h" +#include "srsran/common/network_utils.h" +#include "srsran/common/test_common.h" +#include "srsran/interfaces/gnb_rrc_nr_interfaces.h" +#include "srsran/upper/gtpu.h" +#include +#include + +#include + +using namespace asn1::rrc_nr; +namespace bpo = boost::program_options; + +namespace srsenb { // namespace srsenb + +void parse_args(ngap_args_t* ngap_args, int argc, char* argv[]) +{ + // temporary helpers for conversion + std::string config_file; + std::string gnb_id{}; + std::string gnb_cell_id{}; + std::string gnb_tac{}; + std::string gnb_mcc{}; + std::string gnb_mnc{}; + + // Command line only options + bpo::options_description general("General options"); + + general.add_options()("help,h", "Produce help message"); + + // Command line or config file options + bpo::options_description common("Configuration options"); + + // clang-format off + common.add_options() + + ("gnb_id", bpo::value(&gnb_id)->default_value("0x0"), "gnb ID") + ("name", bpo::value(&ngap_args->gnb_name)->default_value("srsgnb01"), "gnb Name") + ("cell_id", bpo::value(&gnb_cell_id)->default_value("0x0"), "Cell ID") + ("tac", bpo::value(&gnb_tac)->default_value("0x0"), "Tracking Area Code") + ("mcc", bpo::value(&gnb_mcc)->default_value("001"), "Mobile Country Code") + ("mnc", bpo::value(&gnb_mnc)->default_value("01"), "Mobile Network Code") + ("amf_addr", bpo::value(&ngap_args->amf_addr)->default_value("127.0.0.1"), "IP address of AMF for NG connection") + ("n1c_bind_addr", bpo::value(&ngap_args->ngc_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for NGAP connection") + ("gtp_bind_addr", bpo::value(&ngap_args->gtp_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for GTP connection"); + + bpo::options_description position("Positional options"); + + // clang-format on + bpo::positional_options_description p{}; + p.add("config_file", -1); + + bpo::options_description cmdline_options; + cmdline_options.add(common).add(position).add(general); + + bpo::variables_map vm{}; + + try { + bpo::store(bpo::command_line_parser(argc, argv).options(cmdline_options).positional(p).run(), vm); + bpo::notify(vm); + } catch (bpo::error& e) { + std::cerr << e.what() << std::endl; + exit(1); + } + + if (vm.count("help")) { + std::cout << common << std::endl << general << std::endl; + exit(0); + } + + // Convert hex strings + { + std::stringstream sstr{}; + sstr << std::hex << vm["gnb_id"].as(); + sstr >> ngap_args->gnb_id; + } + { + std::stringstream sstr{}; + sstr << std::hex << vm["cell_id"].as(); + uint16_t tmp; // Need intermediate uint16_t as uint8_t is treated as char + sstr >> tmp; + ngap_args->cell_id = tmp; + } + { + std::stringstream sstr{}; + sstr << std::hex << vm["tac"].as(); + sstr >> ngap_args->tac; + } + + // Convert MCC/MNC strings + if (!srsran::string_to_mcc(gnb_mcc, &ngap_args->mcc)) { + std::cout << "Error parsing mcc:" << gnb_mcc << " - must be a 3-digit string." << std::endl; + } + if (!srsran::string_to_mnc(gnb_mnc, &ngap_args->mnc)) { + std::cout << "Error parsing mnc:" << gnb_mnc << " - must be a 2 or 3-digit string." << std::endl; + } +} + +void test_rrc_sa_ngap_integration(ngap_args_t ngap_args) +{ + // This takes the existing RRC-NR tests and exercises the NGAP integration with a real core network. + // The test currently runs down untill the RRCReconfiguration. + srsran::task_scheduler task_sched; + + phy_nr_dummy phy_obj; + mac_nr_dummy mac_obj; + rlc_nr_rrc_tester rlc_obj; + pdcp_nr_rrc_tester pdcp_obj; + rrc_nr rrc_obj(&task_sched); + enb_bearer_manager bearer_mapper; + + // NGAP Setup + auto& ngap_logger = srslog::fetch_basic_logger("NGAP"); + ngap_logger.set_level(srslog::basic_levels::debug); + ngap_logger.set_hex_dump_max_size(-1); + auto& gtpu_logger = srslog::fetch_basic_logger("GTPU"); + gtpu_logger.set_level(srslog::basic_levels::debug); + gtpu_logger.set_hex_dump_max_size(-1); + + srsran::socket_manager rx_sockets; + srsenb::ngap ngap_obj(&task_sched, ngap_logger, &rx_sockets); + srsenb::gtpu gtpu_obj(&task_sched, gtpu_logger, srsran::srsran_rat_t::nr, &rx_sockets); + + gtpu_args_t gtpu_args; + gtpu_args.embms_enable = false; + gtpu_args.mme_addr = ngap_args.amf_addr; + gtpu_args.gtp_bind_addr = ngap_args.gtp_bind_addr; + TESTASSERT(gtpu_obj.init(gtpu_args, &pdcp_obj) == SRSRAN_SUCCESS); + TESTASSERT(ngap_obj.init(ngap_args, &rrc_obj, >pu_obj) == SRSRAN_SUCCESS); + task_sched.run_next_task(); + + // set cfg + rrc_nr_cfg_t rrc_cfg_nr = rrc_nr_cfg_t{}; + rrc_cfg_nr.cell_list.emplace_back(); + generate_default_nr_cell(rrc_cfg_nr.cell_list[0]); + rrc_cfg_nr.cell_list[0].phy_cell.carrier.pci = 500; + rrc_cfg_nr.cell_list[0].dl_arfcn = 368500; + rrc_cfg_nr.cell_list[0].band = 3; + rrc_cfg_nr.cell_list[0].phy_cell.carrier.nof_prb = 52; + rrc_cfg_nr.cell_list[0].duplex_mode = SRSRAN_DUPLEX_MODE_FDD; + rrc_cfg_nr.is_standalone = true; + set_derived_nr_cell_params(rrc_cfg_nr.is_standalone, rrc_cfg_nr.cell_list[0]); + + TESTASSERT( + rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, &ngap_obj, >pu_obj, bearer_mapper, nullptr) == + SRSRAN_SUCCESS); + + TESTASSERT_SUCCESS(rrc_obj.add_user(0x4601, 0)); + + // RRCSetupComplete triggers NGAP Initial UE Message with NAS-PDU: Registration Request + ngap_rrc_tester ngap_dummy; + test_rrc_nr_connection_establishment(task_sched, rrc_obj, rlc_obj, mac_obj, ngap_dummy, 0x4601); + task_sched.run_next_task(); + + // ULInformationTransfer -> UplinkNASTransport(NAS Authentication Response) + srsran::unique_byte_buffer_t auth_resp_pdu; + auth_resp_pdu = srsran::make_byte_buffer(); + asn1::bit_ref bref_ar{auth_resp_pdu->data(), auth_resp_pdu->get_tailroom()}; + ul_dcch_msg_s ul_dcch_msg_auth_resp; + + ul_dcch_msg_auth_resp.msg.set_c1().set_ul_info_transfer().crit_exts.set_ul_info_transfer(); + ul_dcch_msg_auth_resp.msg.c1().ul_info_transfer().crit_exts.ul_info_transfer().ded_nas_msg.from_string( + "7e00572d10db165fffdb7b74c326e3fc3f154117fe"); + + TESTASSERT_SUCCESS(ul_dcch_msg_auth_resp.pack(bref_ar)); + auth_resp_pdu->N_bytes = bref_ar.distance_bytes(); + rrc_obj.write_pdu(0x4601, 1, std::move(auth_resp_pdu)); + task_sched.run_next_task(); + + // ULInformationTransfer -> UplinkNASTransport(NAS Security Mode Complete) + srsran::unique_byte_buffer_t sec_complete_pdu; + sec_complete_pdu = srsran::make_byte_buffer(); + asn1::bit_ref bref_smc{sec_complete_pdu->data(), sec_complete_pdu->get_tailroom()}; + ul_dcch_msg_s ul_dcch_msg_smc; + ul_dcch_msg_smc.msg.set_c1().set_ul_info_transfer().crit_exts.set_ul_info_transfer(); + ul_dcch_msg_smc.msg.c1().ul_info_transfer().crit_exts.ul_info_transfer().ded_nas_msg.from_string( + "7e046b3737af017e005e7700093535940096783351f37100237e004179000d0100f11000000000103254760810030000002e02e0602f0201" + "01530100"); + TESTASSERT_SUCCESS(ul_dcch_msg_smc.pack(bref_smc)); + sec_complete_pdu->N_bytes = bref_smc.distance_bytes(); + rrc_obj.write_pdu(0x4601, 1, std::move(sec_complete_pdu)); + task_sched.run_next_task(); + + test_rrc_nr_security_mode_cmd(task_sched, rrc_obj, pdcp_obj, 0x4601); +} +} // namespace srsenb + +int main(int argc, char** argv) +{ + auto& logger = srslog::fetch_basic_logger("ASN1"); + logger.set_level(srslog::basic_levels::info); + auto& rrc_logger = srslog::fetch_basic_logger("RRC-NR"); + rrc_logger.set_level(srslog::basic_levels::debug); + + srslog::init(); + ngap_args_t ngap_args = {}; + srsenb::parse_args(&ngap_args, argc, argv); + srsenb::test_rrc_sa_ngap_integration(ngap_args); + + return SRSRAN_SUCCESS; +} \ No newline at end of file diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_test.cc b/srsgnb/src/stack/rrc/test/rrc_nr_test.cc new file mode 100644 index 0000000000..0442ffcbe6 --- /dev/null +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test.cc @@ -0,0 +1,228 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "rrc_nr_test_helpers.h" +#include "srsgnb/hdr/stack/rrc/rrc_nr_config_utils.h" +#include "srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h" +#include "srsran/common/bearer_manager.h" +#include "srsran/common/test_common.h" +#include "srsran/interfaces/gnb_rrc_nr_interfaces.h" +#include + +using namespace asn1::rrc_nr; + +namespace srsenb { + +int test_cell_cfg(const srsenb::sched_interface::cell_cfg_t& cellcfg) +{ + // SIB1 must exist and have period 16rf + TESTASSERT(cellcfg.sibs[0].len > 0); + TESTASSERT(cellcfg.sibs[0].period_rf == 16); + + TESTASSERT(cellcfg.si_window_ms > 0); + return SRSRAN_SUCCESS; +} + +/* + * Test 1 - Test default SIB generation + * Description: Check whether the SIBs were set correctly + */ +void test_sib_generation() +{ + srsran::test_delimit_logger test_logger{"SIB generation"}; + + srsran::task_scheduler task_sched; + phy_nr_dummy phy_obj; + mac_nr_dummy mac_obj; + rlc_dummy rlc_obj; + pdcp_dummy pdcp_obj; + rrc_nr rrc_obj(&task_sched); + enb_bearer_manager bearer_mapper; + + // set cfg + rrc_nr_cfg_t rrc_cfg_nr = {}; + rrc_cfg_nr.cell_list.emplace_back(); + generate_default_nr_cell(rrc_cfg_nr.cell_list[0]); + rrc_cfg_nr.cell_list[0].phy_cell.carrier.pci = 500; + rrc_cfg_nr.cell_list[0].dl_arfcn = 368500; + rrc_cfg_nr.cell_list[0].band = 3; + rrc_cfg_nr.cell_list[0].phy_cell.carrier.nof_prb = 52; + rrc_cfg_nr.cell_list[0].duplex_mode = SRSRAN_DUPLEX_MODE_FDD; + rrc_cfg_nr.is_standalone = true; + rrc_cfg_nr.enb_id = 0x19B; + srsran::string_to_mcc("001", &rrc_cfg_nr.mcc); + srsran::string_to_mnc("01", &rrc_cfg_nr.mnc); + set_derived_nr_cell_params(rrc_cfg_nr.is_standalone, rrc_cfg_nr.cell_list[0]); + + TESTASSERT( + rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, nullptr, nullptr, bearer_mapper, nullptr) == + SRSRAN_SUCCESS); + + const sched_nr_cell_cfg_t& nrcell = mac_obj.nr_cells.at(0); + + TESTASSERT(nrcell.sibs.size() > 0); + + // TEST SIB1 + TESTASSERT(nrcell.sibs[0].len > 0); + TESTASSERT_EQ(16, nrcell.sibs[0].period_rf); + + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + TESTASSERT_EQ(SRSRAN_SUCCESS, rrc_obj.read_pdu_bcch_dlsch(0, *pdu)); + TESTASSERT(pdu->size() > 0); + asn1::rrc_nr::bcch_dl_sch_msg_s msg; + { + asn1::cbit_ref bref{pdu->data(), pdu->size()}; + TESTASSERT_EQ(SRSRAN_SUCCESS, msg.unpack(bref)); + } + TESTASSERT_EQ(bcch_dl_sch_msg_type_c::types_opts::c1, msg.msg.type().value); + TESTASSERT_EQ(bcch_dl_sch_msg_type_c::c1_c_::types_opts::sib_type1, msg.msg.c1().type().value); + asn1::rrc_nr::sib1_s& sib1 = msg.msg.c1().sib_type1(); + TESTASSERT(sib1.serving_cell_cfg_common_present); + + pdcch_cfg_common_s& pdcch = sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdcch_cfg_common.setup(); + TESTASSERT(not pdcch.ctrl_res_set_zero_present); // CORESET#0 id is passed in MIB + TESTASSERT(not pdcch.search_space_zero_present); // SS#0 id is passed in MIB +} + +int test_rrc_setup() +{ + srsran::test_delimit_logger test_logger{"NSA RRC"}; + + srsran::task_scheduler task_sched; + phy_nr_dummy phy_obj; + mac_nr_dummy mac_obj; + rlc_dummy rlc_obj; + pdcp_dummy pdcp_obj; + enb_bearer_manager bearer_mapper; + rrc_nr rrc_obj(&task_sched); + + // set cfg + rrc_nr_cfg_t rrc_cfg_nr = {}; + rrc_cfg_nr.cell_list.emplace_back(); + generate_default_nr_cell(rrc_cfg_nr.cell_list[0]); + rrc_cfg_nr.cell_list[0].phy_cell.carrier.pci = 500; + rrc_cfg_nr.cell_list[0].dl_arfcn = 634240; + rrc_cfg_nr.cell_list[0].coreset0_idx = 3; + rrc_cfg_nr.cell_list[0].band = 78; + rrc_cfg_nr.cell_list[0].phy_cell.carrier.nof_prb = 52; + rrc_cfg_nr.is_standalone = false; + rrc_cfg_nr.enb_id = 0x19B; + srsran::string_to_mcc("001", &rrc_cfg_nr.mcc); + srsran::string_to_mnc("01", &rrc_cfg_nr.mnc); + set_derived_nr_cell_params(rrc_cfg_nr.is_standalone, rrc_cfg_nr.cell_list[0]); + TESTASSERT( + rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, nullptr, nullptr, bearer_mapper, nullptr) == + SRSRAN_SUCCESS); + + for (uint32_t n = 0; n < 2; ++n) { + uint32_t timeout = 5500; + for (uint32_t i = 0; i < timeout and rlc_obj.last_sdu == nullptr; ++i) { + task_sched.tic(); + } + // TODO: trigger proper RRC Setup procedure (not timer based) + // TESTASSERT(rlc_obj.last_sdu != nullptr); + } + return SRSRAN_SUCCESS; +} + +void test_rrc_sa_connection() +{ + srsran::test_delimit_logger test_logger{"SA RRCConnectionEstablishment"}; + + srsran::task_scheduler task_sched; + phy_nr_dummy phy_obj; + mac_nr_dummy mac_obj; + rlc_nr_rrc_tester rlc_obj; + pdcp_nr_rrc_tester pdcp_obj; + ngap_rrc_tester ngap_obj; + enb_bearer_manager bearer_mapper; + + rrc_nr rrc_obj(&task_sched); + + // Dummy RLC/PDCP configs + asn1::rrc_nr::rlc_cfg_c rlc_cfg; + rlc_cfg.set_um_bi_dir(); + rlc_cfg.um_bi_dir().dl_um_rlc.t_reassembly = t_reassembly_e::ms50; + + // set cfg + rrc_nr_cfg_t rrc_cfg_nr = {}; + rrc_cfg_nr.cell_list.emplace_back(); + generate_default_nr_cell(rrc_cfg_nr.cell_list[0]); + rrc_cfg_nr.cell_list[0].phy_cell.carrier.pci = 500; + rrc_cfg_nr.cell_list[0].dl_arfcn = 368500; + rrc_cfg_nr.cell_list[0].band = 3; + rrc_cfg_nr.cell_list[0].phy_cell.carrier.nof_prb = 52; + rrc_cfg_nr.cell_list[0].duplex_mode = SRSRAN_DUPLEX_MODE_FDD; + rrc_cfg_nr.is_standalone = true; + rrc_cfg_nr.enb_id = 0x19B; + rrc_cfg_nr.five_qi_cfg[9].configured = true; + rrc_cfg_nr.five_qi_cfg[9].rlc_cfg = rlc_cfg; + rrc_cfg_nr.five_qi_cfg[9].pdcp_cfg = {}; + srsran::string_to_mcc("001", &rrc_cfg_nr.mcc); + srsran::string_to_mnc("01", &rrc_cfg_nr.mnc); + set_derived_nr_cell_params(rrc_cfg_nr.is_standalone, rrc_cfg_nr.cell_list[0]); + + TESTASSERT( + rrc_obj.init(rrc_cfg_nr, &phy_obj, &mac_obj, &rlc_obj, &pdcp_obj, &ngap_obj, nullptr, bearer_mapper, nullptr) == + SRSRAN_SUCCESS); + + TESTASSERT_SUCCESS(rrc_obj.add_user(0x4601, 0)); + TESTASSERT_SUCCESS(rrc_obj.ue_set_security_cfg_key(0x4601, {})); + + test_rrc_nr_connection_establishment(task_sched, rrc_obj, rlc_obj, mac_obj, ngap_obj, 0x4601); + test_rrc_nr_info_transfer(task_sched, rrc_obj, pdcp_obj, ngap_obj, 0x4601); + test_rrc_nr_security_mode_cmd(task_sched, rrc_obj, pdcp_obj, 0x4601); + test_rrc_nr_ue_capability_enquiry(task_sched, rrc_obj, pdcp_obj, 0x4601); + test_rrc_nr_reconfiguration(task_sched, rrc_obj, pdcp_obj, ngap_obj, 0x4601); + test_rrc_nr_2nd_reconfiguration(task_sched, rrc_obj, pdcp_obj, ngap_obj, 0x4601); +} + +} // namespace srsenb + +int main(int argc, char** argv) +{ + // Setup the log spy to intercept error and warning log entries. + if (!srslog::install_custom_sink( + srsran::log_sink_spy::name(), + std::unique_ptr(new srsran::log_sink_spy(srslog::get_default_log_formatter())))) { + return SRSRAN_ERROR; + } + + auto* spy = static_cast(srslog::find_sink(srsran::log_sink_spy::name())); + if (!spy) { + return SRSRAN_ERROR; + } + + auto& logger = srslog::fetch_basic_logger("ASN1", *spy, true); + logger.set_level(srslog::basic_levels::info); + auto& test_log = srslog::fetch_basic_logger("RRC-NR", *spy, true); + test_log.set_level(srslog::basic_levels::debug); + + srslog::init(); + + srsenb::test_sib_generation(); + TESTASSERT(srsenb::test_rrc_setup() == SRSRAN_SUCCESS); + srsenb::test_rrc_sa_connection(); + TESTASSERT_EQ(0, spy->get_warning_counter()); + TESTASSERT_EQ(0, spy->get_error_counter()); + + return SRSRAN_SUCCESS; +} diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc new file mode 100644 index 0000000000..95b5c6d7de --- /dev/null +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc @@ -0,0 +1,432 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "rrc_nr_test_helpers.h" +#include "srsran/common/test_common.h" +#include + +#define NAS_SEC_CMD_STR "d9119b97d7bb59fc842d5b9cc12f00c27e9d5e4c80ee4cceb99a0dbbc6e0b54daa21a5d9e36d2e3b" + +using namespace asn1::rrc_nr; + +namespace srsenb { + +void test_rrc_nr_connection_establishment(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + rlc_nr_rrc_tester& rlc, + mac_nr_dummy& mac, + ngap_rrc_tester& ngap, + uint16_t rnti) +{ + srsran::unique_byte_buffer_t pdu; + + // Step 1 - Send RRCSetupRequest (UE -> gNB) + ul_ccch_msg_s setup_msg; + rrc_setup_request_ies_s& setup = setup_msg.msg.set_c1().set_rrc_setup_request().rrc_setup_request; + setup.establishment_cause.value = establishment_cause_opts::mo_data; + setup.ue_id.set_random_value().from_number(0); + { + pdu = srsran::make_byte_buffer(); + asn1::bit_ref bref{pdu->data(), pdu->get_tailroom()}; + TESTASSERT_SUCCESS(setup_msg.pack(bref)); + pdu->N_bytes = bref.distance_bytes(); + } + + // Pass message to RRC + rrc_obj.write_pdu(rnti, 0, std::move(pdu)); + task_sched.tic(); + + // Step 2 - RRCSetup (gNB -> UE) + // The response to RRCSetupRequest has been sent by RRC - check if this message (RRCSetup) is correct + TESTASSERT_EQ(rnti, rlc.last_sdu_rnti); + TESTASSERT_EQ(srsran::srb_to_lcid(srsran::nr_srb::srb0), rlc.last_sdu_lcid); + TESTASSERT(rlc.last_sdu->size() > 0); + + // dl_ccch_msg will store the unpacked RRCSetup msg sent by the RRC + dl_ccch_msg_s dl_ccch_msg; + { + asn1::cbit_ref bref{rlc.last_sdu->data(), rlc.last_sdu->size()}; + TESTASSERT_SUCCESS(dl_ccch_msg.unpack(bref)); + } + // Test if the RRC sent the correct RRCSetup msg + TESTASSERT_EQ(dl_ccch_msg_type_c::types_opts::c1, dl_ccch_msg.msg.type().value); + TESTASSERT_EQ(dl_ccch_msg_type_c::c1_c_::types_opts::rrc_setup, dl_ccch_msg.msg.c1().type().value); + TESTASSERT_EQ(rrc_setup_s::crit_exts_c_::types_opts::rrc_setup, + dl_ccch_msg.msg.c1().rrc_setup().crit_exts.type().value); + + const rrc_setup_ies_s& setup_ies = dl_ccch_msg.msg.c1().rrc_setup().crit_exts.rrc_setup(); + TESTASSERT(setup_ies.radio_bearer_cfg.srb_to_add_mod_list.size() > 0); + TESTASSERT_EQ(1, setup_ies.radio_bearer_cfg.srb_to_add_mod_list.size()); + + const srb_to_add_mod_s& srb1 = setup_ies.radio_bearer_cfg.srb_to_add_mod_list[0]; + TESTASSERT_EQ(srsran::srb_to_lcid(srsran::nr_srb::srb1), srb1.srb_id); + // Test UE context in MAC + TESTASSERT_EQ(rnti, mac.last_ue_cfg_rnti); + // Only LCID=1 is added + TESTASSERT_EQ(1, mac.last_ue_cfg.lc_ch_to_add.size()); + TESTASSERT_EQ(1, mac.last_ue_cfg.lc_ch_to_add.front().lcid); + TESTASSERT_EQ(mac_lc_ch_cfg_t::BOTH, mac.last_ue_cfg.lc_ch_to_add.front().cfg.direction); + bool found_common_ul_dci_format = false; + for (uint32_t ss_id = 0; ss_id < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE; ++ss_id) { + if (mac.last_ue_cfg.phy_cfg.pdcch.search_space_present[ss_id]) { + const srsran_search_space_t& ss = mac.last_ue_cfg.phy_cfg.pdcch.search_space[ss_id]; + // Ensure MAC ue_cfg does not have yet any UE-specific SS + TESTASSERT_NEQ(srsran_search_space_type_ue, ss.type); + for (uint32_t f = 0; f < ss.nof_formats; ++f) { + found_common_ul_dci_format |= ss.formats[f] == srsran_dci_format_nr_0_0; + } + } + } + TESTASSERT(found_common_ul_dci_format); + + // Step 3 - RRCSetupComplete (UE -> gNB) - Configure the msg and send it to RRC + ul_dcch_msg_s ul_dcch_msg; + rrc_setup_complete_s& complete = ul_dcch_msg.msg.set_c1().set_rrc_setup_complete(); + complete.rrc_transaction_id = dl_ccch_msg.msg.c1().rrc_setup().rrc_transaction_id; + rrc_setup_complete_ies_s& complete_ies = complete.crit_exts.set_rrc_setup_complete(); + complete_ies.sel_plmn_id = 1; // First PLMN in list + complete_ies.registered_amf_present = true; + complete_ies.registered_amf.amf_id.from_number(0x800101); + complete_ies.guami_type_present = true; + complete_ies.guami_type.value = rrc_setup_complete_ies_s::guami_type_opts::native; + std::string NAS_msg_str = "7E01280E534C337E004109000BF200F110800101347B80802E02F07071002D7E004109000BF200F11080010134" + "7B80801001002E02F0702F0201015200F11000006418010174000090530101"; + auto& ded_nas_msg = complete_ies.ded_nas_msg.from_string(NAS_msg_str); + + { + pdu = srsran::make_byte_buffer(); + asn1::bit_ref bref{pdu->data(), pdu->get_tailroom()}; + TESTASSERT_SUCCESS(ul_dcch_msg.pack(bref)); + pdu->N_bytes = bref.distance_bytes(); + } + rrc_obj.write_pdu(rnti, 1, std::move(pdu)); + + // Test new UE context in MAC + bool ss_ue_found = false; + for (uint32_t ss_id = 0; ss_id < SRSRAN_UE_DL_NR_MAX_NOF_SEARCH_SPACE; ++ss_id) { + if (mac.last_ue_cfg.phy_cfg.pdcch.search_space_present[ss_id]) { + const srsran_search_space_t& ss = mac.last_ue_cfg.phy_cfg.pdcch.search_space[ss_id]; + if (ss.type == srsran_search_space_type_ue) { + ss_ue_found = true; + } + } + } + TESTASSERT(ss_ue_found); /// Ensure UE-specific SearchSpace was added + + // Check here if the MSG sent to NGAP is correct + // Create a unbounded_octstring for the expected MSG + asn1::unbounded_octstring expected; + expected.from_string(NAS_msg_str); + TESTASSERT(expected == ngap.last_pdu); +} + +void test_rrc_nr_info_transfer(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + ngap_rrc_tester& ngap, + uint16_t rnti) +{ + // STEP 1 : Send DLInformationTransfer (gNB -> UE) + // generate sdu to pass as NAS message in DLInformationTransfer + srsran::unique_byte_buffer_t nsa_sdu; + nsa_sdu = srsran::make_byte_buffer(); + + // create an unbounded_octstring object that contains a random NAS message (we simulate a NAS message) + asn1::unbounded_octstring NAS_DL_msg; + NAS_DL_msg.from_string("21d9dfe07800371095c79a751be8352fb44aba7d69b836f5aad594ede9e72b8e34105ca8d7669d5c"); + nsa_sdu->append_bytes(NAS_DL_msg.data(), NAS_DL_msg.size()); + + // trigger the RRC to send the DLInformationTransfer + rrc_obj.write_dl_info(rnti, std::move(nsa_sdu)); + + // Test whether there exists the SRB1 initiated in the Connection Establishment + // We test this as the SRB1 was setup in a different function + TESTASSERT_EQ(rnti, pdcp.last_sdu_rnti); + TESTASSERT_EQ(srsran::srb_to_lcid(srsran::nr_srb::srb1), pdcp.last_sdu_lcid); + + // Send SecurityModeCommand (gNB -> UE) + dl_dcch_msg_s dl_dcch_msg; + { + asn1::cbit_ref bref{pdcp.last_sdu->data(), pdcp.last_sdu->size()}; + TESTASSERT_SUCCESS(dl_dcch_msg.unpack(bref)); + } + + // Test if the unpacked message retrived from PCDP is correct + TESTASSERT_EQ(dl_dcch_msg_type_c::types_opts::c1, dl_dcch_msg.msg.type().value); + TESTASSERT_EQ(dl_dcch_msg_type_c::c1_c_::types_opts::dl_info_transfer, dl_dcch_msg.msg.c1().type().value); + TESTASSERT_EQ(dl_info_transfer_s::crit_exts_c_::types_opts::dl_info_transfer, + dl_dcch_msg.msg.c1().dl_info_transfer().crit_exts.type().value); + + dl_info_transfer_ies_s& ies_DL = dl_dcch_msg.msg.c1().dl_info_transfer().crit_exts.dl_info_transfer(); + TESTASSERT(ies_DL.ded_nas_msg.size() > 0); + TESTASSERT(NAS_DL_msg == ies_DL.ded_nas_msg); + + // STEP 2: Send ULInformationTransfer (UE -> gNB) + ul_dcch_msg_s ul_dcch_msg; + auto& ies_UL = ul_dcch_msg.msg.set_c1().set_ul_info_transfer().crit_exts.set_ul_info_transfer(); + + // Create an unbounded_octstring object that contains a random NAS message (we simulate a NAS message) + // We reuse ies_UL below to compare the string with the message sent to and unpacked by the gNB + ies_UL.ded_nas_msg.from_string("6671f8bc80b1860f29b3a8b3b8563ce6c36a591bb1a3dc6612674448fb958d274426d326356aa9aa"); + + srsran::unique_byte_buffer_t pdu; + { + pdu = srsran::make_byte_buffer(); + asn1::bit_ref bref{pdu->data(), pdu->get_tailroom()}; + TESTASSERT_SUCCESS(ul_dcch_msg.pack(bref)); + pdu->N_bytes = bref.distance_bytes(); + } + + // send message to RRC + rrc_obj.write_pdu(rnti, 1, std::move(pdu)); + + // compare if the actual transmitted matches with the MSG created from the original string + TESTASSERT(ies_UL.ded_nas_msg == ngap.last_pdu); +} + +void test_rrc_nr_security_mode_cmd(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + uint16_t rnti) +{ + // create an unbounded_octstring object that contains a random NAS message (we simulate a NAS message) + asn1::unbounded_octstring NAS_msg; + NAS_msg.from_string(NAS_SEC_CMD_STR); + srsran::unique_byte_buffer_t nas_pdu; + nas_pdu = srsran::make_byte_buffer(); + nas_pdu->append_bytes(NAS_msg.data(), NAS_msg.size()); + + // Trigger Send SecurityCommand (simulate request from NGAP) + rrc_obj.start_security_mode_procedure(rnti, std::move(nas_pdu)); + + // Test whether there exists the SRB1 initiated in the Connection Establishment + // We test this as the SRB1 was setup in a different function + TESTASSERT_EQ(rnti, pdcp.last_sdu_rnti); + TESTASSERT_EQ(srsran::srb_to_lcid(srsran::nr_srb::srb1), pdcp.last_sdu_lcid); + + // STEP 1 - Send SecurityModeCommand (gNB -> UE) + dl_dcch_msg_s dl_dcch_msg; + { + asn1::cbit_ref bref{pdcp.last_sdu->data(), pdcp.last_sdu->size()}; + TESTASSERT_SUCCESS(dl_dcch_msg.unpack(bref)); + } + TESTASSERT_EQ(dl_dcch_msg_type_c::types_opts::c1, dl_dcch_msg.msg.type().value); + TESTASSERT_EQ(dl_dcch_msg_type_c::c1_c_::types_opts::security_mode_cmd, dl_dcch_msg.msg.c1().type().value); + TESTASSERT_EQ(security_mode_cmd_s::crit_exts_c_::types_opts::security_mode_cmd, + dl_dcch_msg.msg.c1().security_mode_cmd().crit_exts.type().value); + + security_mode_cmd_ies_s& ies = dl_dcch_msg.msg.c1().security_mode_cmd().crit_exts.security_mode_cmd(); + TESTASSERT_EQ(true, ies.security_cfg_smc.security_algorithm_cfg.integrity_prot_algorithm_present); + TESTASSERT_EQ(integrity_prot_algorithm_opts::nia0, + ies.security_cfg_smc.security_algorithm_cfg.integrity_prot_algorithm.value); + TESTASSERT_EQ(ciphering_algorithm_opts::nea0, ies.security_cfg_smc.security_algorithm_cfg.ciphering_algorithm.value); + + // STEP 2 - Send SecurityModeComplete (UE -> gNB) + ul_dcch_msg_s ul_dcch_msg; + auto& sec_cmd_complete_msg = ul_dcch_msg.msg.set_c1().set_security_mode_complete(); + sec_cmd_complete_msg.rrc_transaction_id = dl_dcch_msg.msg.c1().security_mode_cmd().rrc_transaction_id; + auto& ies_complete = sec_cmd_complete_msg.crit_exts.set_security_mode_complete(); + + srsran::unique_byte_buffer_t pdu; + { + pdu = srsran::make_byte_buffer(); + asn1::bit_ref bref{pdu->data(), pdu->get_tailroom()}; + TESTASSERT_SUCCESS(ul_dcch_msg.pack(bref)); + pdu->N_bytes = bref.distance_bytes(); + } + + // send message to RRC + rrc_obj.write_pdu(rnti, 1, std::move(pdu)); +} + +void test_rrc_nr_ue_capability_enquiry(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + uint16_t rnti) +{ + dl_dcch_msg_s dl_dcch_msg; + { + asn1::cbit_ref bref{pdcp.last_sdu->data(), pdcp.last_sdu->size()}; + TESTASSERT_SUCCESS(dl_dcch_msg.unpack(bref)); + } + + // Check if unpacked message is correct (ueCapabilityEnquiry | gNB -> UE) + TESTASSERT_EQ(dl_dcch_msg_type_c::types_opts::c1, dl_dcch_msg.msg.type().value); + TESTASSERT_EQ(dl_dcch_msg_type_c::c1_c_::types_opts::ue_cap_enquiry, dl_dcch_msg.msg.c1().type().value); + TESTASSERT_EQ(ue_cap_enquiry_s::crit_exts_c_::types_opts::ue_cap_enquiry, + dl_dcch_msg.msg.c1().ue_cap_enquiry().crit_exts.type().value); + + // Send response (ueCapabilityInformation | UE -> gNB) + ul_dcch_msg_s ul_dcch_msg; + auto& ue_capability_information = ul_dcch_msg.msg.set_c1().set_ue_cap_info(); + ue_capability_information.rrc_transaction_id = dl_dcch_msg.msg.c1().ue_cap_enquiry().rrc_transaction_id; + ue_capability_information.crit_exts.set_ue_cap_info(); + + srsran::unique_byte_buffer_t pdu; + { + pdu = srsran::make_byte_buffer(); + asn1::bit_ref bref{pdu->data(), pdu->get_tailroom()}; + TESTASSERT_SUCCESS(ul_dcch_msg.pack(bref)); + pdu->N_bytes = bref.distance_bytes(); + } + + // send message to RRC + rrc_obj.write_pdu(rnti, 1, std::move(pdu)); +} + +void test_rrc_nr_reconfiguration(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + ngap_rrc_tester& ngap, + uint16_t rnti) +{ + // Test whether there exists the SRB1 initiated in the Connection Establishment + // We test this as the SRB1 was set up in a different function + TESTASSERT_EQ(rnti, pdcp.last_sdu_rnti); + TESTASSERT_EQ(srsran::srb_to_lcid(srsran::nr_srb::srb1), pdcp.last_sdu_lcid); + + dl_dcch_msg_s dl_dcch_msg; + { + asn1::cbit_ref bref{pdcp.last_sdu->data(), pdcp.last_sdu->size()}; + TESTASSERT_SUCCESS(dl_dcch_msg.unpack(bref)); + } + + // Test whether the unpacked message is correct + TESTASSERT_EQ(dl_dcch_msg_type_c::types_opts::c1, dl_dcch_msg.msg.type().value); + TESTASSERT_EQ(dl_dcch_msg_type_c::c1_c_::types_opts::rrc_recfg, dl_dcch_msg.msg.c1().type().value); + TESTASSERT_EQ(rrc_recfg_s::crit_exts_c_::types_opts::rrc_recfg, + dl_dcch_msg.msg.c1().rrc_recfg().crit_exts.type().value); + const rrc_recfg_ies_s& reconf_ies = dl_dcch_msg.msg.c1().rrc_recfg().crit_exts.rrc_recfg(); + + // create an unbounded_octstring object that contains the same NAS message as in SecurityModeCommand + // The RRCreconfiguration reads the SecurityModeCommand NAS msg previously saved in the queue + asn1::unbounded_octstring NAS_msg; + NAS_msg.from_string(NAS_SEC_CMD_STR); + TESTASSERT(reconf_ies.non_crit_ext.ded_nas_msg_list.size() > 0); + // Test if NAS_msg is the same as the one sent in SecurityModeCommand + TESTASSERT(NAS_msg == reconf_ies.non_crit_ext.ded_nas_msg_list[0]); + + // STEP 2 - Send RRCReconfiguration (UE -> gNB) + ul_dcch_msg_s ul_dcch_msg; + auto& RRC_recfg_complete = ul_dcch_msg.msg.set_c1().set_rrc_recfg_complete(); + RRC_recfg_complete.rrc_transaction_id = dl_dcch_msg.msg.c1().rrc_recfg().rrc_transaction_id; + RRC_recfg_complete.crit_exts.set_rrc_recfg_complete(); + + srsran::unique_byte_buffer_t pdu; + { + pdu = srsran::make_byte_buffer(); + asn1::bit_ref bref{pdu->data(), pdu->get_tailroom()}; + TESTASSERT_SUCCESS(ul_dcch_msg.pack(bref)); + pdu->N_bytes = bref.distance_bytes(); + } + + // send message to RRC + rrc_obj.write_pdu(rnti, 1, std::move(pdu)); + + // Verify the NGAP gets notified for the RRCReconfigurationComplete + TESTASSERT_EQ(true, ngap.last_rrc_recnf_complete); +} + +void test_rrc_nr_2nd_reconfiguration(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + ngap_rrc_tester& ngap, + uint16_t rnti) +{ + // Make sure the NGAP RRCReconfigurationComplete bool is reset to false + ngap.last_rrc_recnf_complete = false; + + // create an unbounded_octstring object that contains a NAS message (we simulate a random NAS nas) + asn1::unbounded_octstring NAS_msg; + NAS_msg.from_string("c574defc80ba722bffb8eacb6f8a163e3222cf1542ac529f6980bb15e0bf12d9f2b29f11fb458ec9"); + + // Test whether there exists the SRB1 initiated in the Connection Establishment + // We test this as the SRB1 was set up in a different function + TESTASSERT_EQ(rnti, pdcp.last_sdu_rnti); + TESTASSERT_EQ(srsran::srb_to_lcid(srsran::nr_srb::srb1), pdcp.last_sdu_lcid); + + // STEP 2 - Trigger and send RRCReconfiguration command (gNB -> UE) + rrc_obj.establish_rrc_bearer(rnti, 1, NAS_msg, 4, 9); + + dl_dcch_msg_s dl_dcch_msg; + { + asn1::cbit_ref bref{pdcp.last_sdu->data(), pdcp.last_sdu->size()}; + TESTASSERT_SUCCESS(dl_dcch_msg.unpack(bref)); + } + + // Test whether the unpacked message is correct + TESTASSERT_EQ(dl_dcch_msg_type_c::types_opts::c1, dl_dcch_msg.msg.type().value); + TESTASSERT_EQ(dl_dcch_msg_type_c::c1_c_::types_opts::rrc_recfg, dl_dcch_msg.msg.c1().type().value); + TESTASSERT_EQ(rrc_recfg_s::crit_exts_c_::types_opts::rrc_recfg, + dl_dcch_msg.msg.c1().rrc_recfg().crit_exts.type().value); + const rrc_recfg_ies_s& reconf_ies = dl_dcch_msg.msg.c1().rrc_recfg().crit_exts.rrc_recfg(); + TESTASSERT_EQ(true, reconf_ies.radio_bearer_cfg_present); + TESTASSERT(reconf_ies.radio_bearer_cfg.srb_to_add_mod_list.size() > 0); + TESTASSERT_EQ(1, reconf_ies.radio_bearer_cfg.srb_to_add_mod_list.size()); + TESTASSERT_EQ(2, reconf_ies.radio_bearer_cfg.srb_to_add_mod_list[0].srb_id); + TESTASSERT_EQ(1, reconf_ies.radio_bearer_cfg.drb_to_add_mod_list.size()); + auto& drb = reconf_ies.radio_bearer_cfg.drb_to_add_mod_list[0]; + TESTASSERT_EQ(1, drb.drb_id); + + TESTASSERT_EQ(true, reconf_ies.non_crit_ext_present); + TESTASSERT(reconf_ies.non_crit_ext.master_cell_group.size() > 0); + auto& master_group_msg = reconf_ies.non_crit_ext.master_cell_group; + + cell_group_cfg_s master_cell_group; + { + asn1::cbit_ref bref{master_group_msg.data(), master_group_msg.size()}; + TESTASSERT_SUCCESS(master_cell_group.unpack(bref)); + } + + // Test if the master_cell_group SRB and DRB IDs match those in the RadioBearerConfig + TESTASSERT_EQ(0, master_cell_group.cell_group_id); + TESTASSERT(master_cell_group.rlc_bearer_to_add_mod_list.size() > 0); + auto& rlc_srb = master_cell_group.rlc_bearer_to_add_mod_list[0]; + TESTASSERT_EQ(reconf_ies.radio_bearer_cfg.srb_to_add_mod_list[0].srb_id, rlc_srb.served_radio_bearer.srb_id()); + auto& rlc_drb = master_cell_group.rlc_bearer_to_add_mod_list[1]; + TESTASSERT_EQ(reconf_ies.radio_bearer_cfg.drb_to_add_mod_list[0].drb_id, rlc_drb.served_radio_bearer.drb_id()); + + // Test if NAS_msg is the same as the one sent in DLInformationTransfer + TESTASSERT(reconf_ies.non_crit_ext.ded_nas_msg_list.size() > 0); + TESTASSERT(NAS_msg == reconf_ies.non_crit_ext.ded_nas_msg_list[0]); + + // STEP 2 - Send RRCReconfiguration (UE -> gNB) + ul_dcch_msg_s ul_dcch_msg; + auto& RRC_recfg_complete = ul_dcch_msg.msg.set_c1().set_rrc_recfg_complete(); + RRC_recfg_complete.rrc_transaction_id = dl_dcch_msg.msg.c1().rrc_recfg().rrc_transaction_id; + RRC_recfg_complete.crit_exts.set_rrc_recfg_complete(); + + srsran::unique_byte_buffer_t pdu; + { + pdu = srsran::make_byte_buffer(); + asn1::bit_ref bref{pdu->data(), pdu->get_tailroom()}; + TESTASSERT_SUCCESS(ul_dcch_msg.pack(bref)); + pdu->N_bytes = bref.distance_bytes(); + } + + // send message to RRC + rrc_obj.write_pdu(rnti, 1, std::move(pdu)); + + // Verify the NGAP gets notified for the RRCReconfigurationComplete + TESTASSERT_EQ(true, ngap.last_rrc_recnf_complete); +} + +} // namespace srsenb diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.h b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.h new file mode 100644 index 0000000000..30174cf732 --- /dev/null +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.h @@ -0,0 +1,137 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_RRC_NR_TEST_HELPERS_H +#define SRSRAN_RRC_NR_TEST_HELPERS_H + +#include "srsenb/test/common/dummy_classes_common.h" +#include "srsgnb/hdr/stack/common/test/dummy_nr_classes.h" +#include "srsgnb/hdr/stack/rrc/rrc_nr.h" + +namespace srsenb { + +class pdcp_nr_rrc_tester : public pdcp_dummy +{ +public: + void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu, int pdcp_sn = -1) override + { + last_sdu_rnti = rnti; + last_sdu_lcid = lcid; + last_sdu = std::move(sdu); + } + + uint16_t last_sdu_rnti = SRSRAN_INVALID_RNTI; + uint32_t last_sdu_lcid = srsran::MAX_NR_NOF_BEARERS; + srsran::unique_byte_buffer_t last_sdu; +}; + +class rlc_nr_rrc_tester : public rlc_dummy +{ +public: + void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) + { + last_sdu_rnti = rnti; + last_sdu_lcid = lcid; + last_sdu = std::move(sdu); + } + + uint16_t last_sdu_rnti; + uint32_t last_sdu_lcid; + srsran::unique_byte_buffer_t last_sdu; +}; + +class ngap_rrc_tester : public ngap_dummy +{ +public: + void initial_ue(uint16_t rnti, + uint32_t gnb_cc_idx, + asn1::ngap::rrcestablishment_cause_e cause, + srsran::const_byte_span pdu, + uint32_t s_tmsi) + { + last_sdu_rnti = rnti; + last_pdu.resize(pdu.size()); + memcpy(last_pdu.data(), pdu.data(), pdu.size()); + } + + void write_pdu(uint16_t rnti, srsran::const_byte_span pdu) + { + last_sdu_rnti = rnti; + last_pdu.resize(pdu.size()); + memcpy(last_pdu.data(), pdu.data(), pdu.size()); + } + + void ue_notify_rrc_reconf_complete(uint16_t rnti, bool outcome) { last_rrc_recnf_complete = outcome; } + + uint16_t last_sdu_rnti; + asn1::dyn_octstring last_pdu; + bool last_rrc_recnf_complete = false; +}; + +/** + * Run TS 38.331, 5.3.3 "RRC connection establishment" to completion + * RRC actions: + * - Rx RRCSetupRequest + * - Tx RRCSetup to lower layers + * - Tx RRCSetupComplete + * Checks: + * - the RRC sends RRCSetup as reply to RRCSetupRequest + * - verify that RRCSetup rnti, lcid are correct + * - verify that RRCSetup adds an SRB1 + */ +void test_rrc_nr_connection_establishment(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + rlc_nr_rrc_tester& rlc, + mac_nr_dummy& mac, + ngap_rrc_tester& ngap, + uint16_t rnti); + +void test_rrc_nr_info_transfer(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + ngap_rrc_tester& ngap, + uint16_t rnti); + +void test_rrc_nr_security_mode_cmd(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + uint16_t rnti); + +void test_rrc_nr_ue_capability_enquiry(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + uint16_t rnti); + +void test_rrc_nr_reconfiguration(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + ngap_rrc_tester& ngap, + uint16_t rnti); + +void test_rrc_nr_2nd_reconfiguration(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + ngap_rrc_tester& ngap, + uint16_t rnti); + +} // namespace srsenb + +#endif // SRSRAN_RRC_NR_TEST_HELPERS_H diff --git a/srsgnb/src/stack/sdap/CMakeLists.txt b/srsgnb/src/stack/sdap/CMakeLists.txt new file mode 100644 index 0000000000..3f233cd417 --- /dev/null +++ b/srsgnb/src/stack/sdap/CMakeLists.txt @@ -0,0 +1,22 @@ +# +# Copyright 2013-2023 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/. +# + +set(SOURCES sdap.cc) +add_library(srsgnb_sdap STATIC ${SOURCES}) \ No newline at end of file diff --git a/srsenb/src/stack/upper/sdap.cc b/srsgnb/src/stack/sdap/sdap.cc similarity index 93% rename from srsenb/src/stack/upper/sdap.cc rename to srsgnb/src/stack/sdap/sdap.cc index d00e001c83..0ab6761d89 100644 --- a/srsenb/src/stack/upper/sdap.cc +++ b/srsgnb/src/stack/sdap/sdap.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,7 +19,7 @@ * */ -#include "srsenb/hdr/stack/upper/sdap.h" +#include "srsgnb/hdr/stack/sdap/sdap.h" namespace srsenb { diff --git a/srsue/CMakeLists.txt b/srsue/CMakeLists.txt index 9bdb3d5c32..5582264ea8 100644 --- a/srsue/CMakeLists.txt +++ b/srsue/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/hdr/metrics_csv.h b/srsue/hdr/metrics_csv.h index 80a45c317a..122552fb92 100644 --- a/srsue/hdr/metrics_csv.h +++ b/srsue/hdr/metrics_csv.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/metrics_json.h b/srsue/hdr/metrics_json.h index e3e6272d13..b30443abbd 100644 --- a/srsue/hdr/metrics_json.h +++ b/srsue/hdr/metrics_json.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/metrics_stdout.h b/srsue/hdr/metrics_stdout.h index c9a424ad33..8f4cb57c8c 100644 --- a/srsue/hdr/metrics_stdout.h +++ b/srsue/hdr/metrics_stdout.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/phy/dummy_phy.h b/srsue/hdr/phy/dummy_phy.h new file mode 100644 index 0000000000..4161bed74a --- /dev/null +++ b/srsue/hdr/phy/dummy_phy.h @@ -0,0 +1,85 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_DUMMY_PHY_H +#define SRSRAN_DUMMY_PHY_H + +#include "srsran/interfaces/phy_interface_types.h" +#include "srsue/hdr/phy/ue_phy_base.h" + +namespace srsue { + +class dummy_phy final : public ue_phy_base, public phy_interface_stack_lte +{ +public: + // ue_phy_base + std::string get_type() final { return "dummy_phy"; } + void stop() final {} + void wait_initialize() final {} + bool is_initialized() final { return false; } + void start_plot() final {} + void get_metrics(const srsran::srsran_rat_t& rat, phy_metrics_t* m) final {} + + // phy_interface_stack_lte + void prach_send(uint32_t preamble_idx, int allowed_subframe, float target_power_dbm, float ta_base_sec = 0.0f) final + {} + prach_info_t prach_get_info() final { return {}; } + + /* Indicates the transmission of a SR signal in the next opportunity */ + void sr_send() final {} + int sr_last_tx_tti() final { return 0; } + + void set_mch_period_stop(uint32_t stop) final {} + bool set_config(const srsran::phy_cfg_t& config, uint32_t cc_idx = 0) final { return false; } + bool set_scell(srsran_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn) final { return false; } + void set_config_tdd(srsran_tdd_config_t& tdd_config) final {} + void set_config_mbsfn_sib2(srsran::mbsfn_sf_cfg_t* cfg_list, uint32_t nof_cfgs) final {} + void set_config_mbsfn_sib13(const srsran::sib13_t& sib13) final {} + void set_config_mbsfn_mcch(const srsran::mcch_msg_t& mcch) final {} + + void deactivate_scells() final {} + + /* Measurements interface */ + void set_cells_to_meas(uint32_t earfcn, const std::set& pci) final {} + void meas_stop() final {} + + /* Cell search and selection procedures */ + bool cell_search(int earfcn) final { return false; } + bool cell_select(phy_cell_t cell) final { return false; } + bool cell_is_camping() final { return false; } + + /* Time advance commands */ + void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) final {} + void set_timeadv(uint32_t tti, uint32_t ta_cmd) final {} + + /* Activate / Disactivate SCell*/ + void set_activation_deactivation_scell(uint32_t cmd, uint32_t tti) final {} + + /* Sets RAR dci payload */ + void set_rar_grant(uint8_t grant_payload[SRSRAN_RAR_GRANT_LEN], uint16_t rnti) final {} + + uint32_t get_current_tti() final { return 0; } + + float get_phr() final { return 0.0; } + float get_pathloss_db() final { return 0.0; } +}; +} // namespace srsue +#endif // SRSRAN_DUMMY_PHY_H diff --git a/srsue/hdr/phy/lte/cc_worker.h b/srsue/hdr/phy/lte/cc_worker.h index b9d4a6a207..a019d9286c 100644 --- a/srsue/hdr/phy/lte/cc_worker.h +++ b/srsue/hdr/phy/lte/cc_worker.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -84,7 +84,7 @@ class cc_worker mac_interface_phy_lte::tb_action_dl_t* action, bool acks[SRSRAN_MAX_CODEWORDS]); int decode_pmch(mac_interface_phy_lte::tb_action_dl_t* action, srsran_mbsfn_cfg_t* mbsfn_cfg); - + void new_mch_dl(mac_interface_phy_lte::tb_action_dl_t*); /* Methods for UL */ bool encode_uplink(mac_interface_phy_lte::tb_action_ul_t* action, srsran_uci_data_t* uci_data); void set_uci_sr(srsran_uci_data_t* uci_data); @@ -100,11 +100,14 @@ class cc_worker srsran_dl_sf_cfg_t sf_cfg_dl = {}; srsran_ul_sf_cfg_t sf_cfg_ul = {}; - uint32_t cc_idx = 0; - bool cell_initiated = false; - cf_t* signal_buffer_rx[SRSRAN_MAX_PORTS] = {}; - cf_t* signal_buffer_tx[SRSRAN_MAX_PORTS] = {}; - uint32_t signal_buffer_max_samples = 0; + uint32_t cc_idx = 0; + bool cell_initiated = false; + cf_t* signal_buffer_rx[SRSRAN_MAX_PORTS] = {}; + cf_t* signal_buffer_tx[SRSRAN_MAX_PORTS] = {}; + uint32_t signal_buffer_max_samples = 0; + const static uint32_t mch_payload_buffer_sz = SRSRAN_MAX_BUFFER_SIZE_BYTES; + uint8_t mch_payload_buffer[mch_payload_buffer_sz]; + srsran_softbuffer_rx_t mch_softbuffer = {}; /* Objects for DL */ srsran_ue_dl_t ue_dl = {}; diff --git a/srsue/hdr/phy/lte/sf_worker.h b/srsue/hdr/phy/lte/sf_worker.h index ccccbdc957..4ddb2bac65 100644 --- a/srsue/hdr/phy/lte/sf_worker.h +++ b/srsue/hdr/phy/lte/sf_worker.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/phy/lte/worker_pool.h b/srsue/hdr/phy/lte/worker_pool.h index bee88afbe4..ac72c975d6 100644 --- a/srsue/hdr/phy/lte/worker_pool.h +++ b/srsue/hdr/phy/lte/worker_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/phy/nr/cc_worker.h b/srsue/hdr/phy/nr/cc_worker.h index c65f6a9f15..268f98b97f 100644 --- a/srsue/hdr/phy/nr/cc_worker.h +++ b/srsue/hdr/phy/nr/cc_worker.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/phy/nr/cell_search.h b/srsue/hdr/phy/nr/cell_search.h new file mode 100644 index 0000000000..d7a25db015 --- /dev/null +++ b/srsue/hdr/phy/nr/cell_search.h @@ -0,0 +1,68 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSUE_CELL_SEARCH_H +#define SRSUE_CELL_SEARCH_H + +#include "srsran/interfaces/radio_interfaces.h" +#include "srsran/interfaces/ue_nr_interfaces.h" +#include "srsran/srsran.h" + +namespace srsue { +namespace nr { +class cell_search +{ +public: + struct args_t { + double max_srate_hz; + srsran_subcarrier_spacing_t ssb_min_scs = srsran_subcarrier_spacing_15kHz; + }; + + struct cfg_t { + double srate_hz; + double center_freq_hz; + double ssb_freq_hz; + srsran_subcarrier_spacing_t ssb_scs; + srsran_ssb_pattern_t ssb_pattern; + srsran_duplex_mode_t duplex_mode; + }; + + struct ret_t { + enum { CELL_FOUND = 1, CELL_NOT_FOUND = 0, ERROR = -1 } result; + srsran_ssb_search_res_t ssb_res; + }; + + cell_search(srslog::basic_logger& logger); + ~cell_search(); + + bool init(const args_t& args); + + bool start(const cfg_t& cfg); + ret_t run_slot(const cf_t* buffer, uint32_t slot_sz); + +private: + srslog::basic_logger& logger; + srsran_ssb_t ssb = {}; +}; +} // namespace nr +} // namespace srsue + +#endif // SRSUE_CELL_SEARCH_H diff --git a/srsue/hdr/phy/nr/sf_worker.h b/srsue/hdr/phy/nr/sf_worker.h index 20fc5eb33b..bd4e079638 100644 --- a/srsue/hdr/phy/nr/sf_worker.h +++ b/srsue/hdr/phy/nr/sf_worker.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -75,7 +75,6 @@ class sf_worker final : public srsran::thread_pool::worker state& phy_state; srslog::basic_logger& logger; srsran::rf_timestamp_t tx_time = {}; - uint32_t tti_rx = 0; cf_t* prach_ptr = nullptr; float prach_power = 0; srsran::phy_common_interface::worker_context_t context = {}; diff --git a/srsue/hdr/phy/nr/slot_sync.h b/srsue/hdr/phy/nr/slot_sync.h new file mode 100644 index 0000000000..bba00689e5 --- /dev/null +++ b/srsue/hdr/phy/nr/slot_sync.h @@ -0,0 +1,77 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSUE_SLOT_SYNC_H +#define SRSUE_SLOT_SYNC_H + +#include "srsran/interfaces/radio_interfaces.h" +#include "srsran/interfaces/ue_nr_interfaces.h" +#include "srsran/radio/rf_buffer.h" +#include "srsran/radio/rf_timestamp.h" +#include "srsran/srsran.h" + +namespace srsue { +namespace nr { +class slot_sync +{ +public: + struct args_t { + double max_srate_hz = 1.92e6; + uint32_t nof_rx_channels = 1; + srsran_subcarrier_spacing_t ssb_min_scs = srsran_subcarrier_spacing_15kHz; + bool disable_cfo = false; + float pbch_dmrs_thr = 0.0f; ///< PBCH DMRS correlation detection threshold (0 means auto) + float cfo_alpha = 0.0f; ///< CFO averaging alpha (0 means auto) + int thread_priority = -1; + }; + + slot_sync(srslog::basic_logger& logger); + ~slot_sync(); + + bool init(const args_t& args, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_); + + int set_sync_cfg(const srsran_ue_sync_nr_cfg_t& cfg); + + int recv_callback(srsran::rf_buffer_t& rf_buffer, srsran_timestamp_t* timestamp); + bool run_sfn_sync(); + bool run_camping(srsran::rf_buffer_t& buffer, srsran::rf_timestamp_t& timestamp); + void run_stack_tti(); + + srsran_slot_cfg_t get_slot_cfg(); + +private: + const static int MIN_TTI_JUMP = 1; ///< Time gap reported to stack after receiving subframe + const static int MAX_TTI_JUMP = 1000; ///< Maximum time gap tolerance in RF stream metadata + srslog::basic_logger& logger; + stack_interface_phy_nr* stack = nullptr; + srsran::radio_interface_phy* radio = nullptr; + srsran::rf_timestamp_t last_rx_time; + srsran_ue_sync_nr_t ue_sync_nr = {}; + srsran_timestamp_t stack_tti_ts_new = {}; + srsran_timestamp_t stack_tti_ts = {}; + bool forced_rx_time_init = true; // Rx time sync after first receive from radio + srsran::rf_buffer_t sfn_sync_buff = {}; + srsran_slot_cfg_t slot_cfg = {}; +}; +} // namespace nr +} // namespace srsue + +#endif // SRSUE_SLOT_SYNC_H diff --git a/srsue/hdr/phy/nr/state.h b/srsue/hdr/phy/nr/state.h index e9f38fe04d..4aceac6ed5 100644 --- a/srsue/hdr/phy/nr/state.h +++ b/srsue/hdr/phy/nr/state.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -312,13 +312,20 @@ class state void clear_pending_grants() { - // Scope mutex to protect read/write the list - std::lock_guard lock(pending_ul_grant_mutex); - // Clear all PDSCH assignments and PUSCH grants - pending_dl_grant = {}; - pending_ul_grant = {}; - pending_ack = {}; + // Scope mutex to protect read/write each list + { + std::lock_guard lock(pending_ul_grant_mutex); + pending_ul_grant = {}; + } + { + std::lock_guard lock(pending_dl_grant_mutex); + pending_dl_grant = {}; + } + { + std::lock_guard lock(pending_ack_mutex); + pending_ack = {}; + } } void get_pending_sr(const srsran::phy_cfg_nr_t& cfg, const uint32_t& tti, srsran_uci_data_nr_t& uci_data) @@ -370,6 +377,16 @@ class state uci_data.cfg.nof_csi = n; } + // Set fix wideband CQI if it is not zero nor greater than 15 + if (args.fix_wideband_cqi != 0 && args.fix_wideband_cqi < 15) { + for (uint32_t i = 0; i < uci_data.cfg.nof_csi; i++) { + if (uci_data.cfg.csi[i].cfg.quantity == SRSRAN_CSI_REPORT_QUANTITY_CRI_RI_PMI_CQI && + uci_data.cfg.csi[i].cfg.freq_cfg == SRSRAN_CSI_REPORT_FREQ_WIDEBAND) { + uci_data.value.csi[i].wideband_cri_ri_pmi_cqi.cqi = args.fix_wideband_cqi; + } + } + } + uci_data.cfg.pucch.rnti = stack->get_ul_sched_rnti_nr(slot_cfg.idx).id; } diff --git a/srsue/hdr/phy/nr/sync_sa.h b/srsue/hdr/phy/nr/sync_sa.h new file mode 100644 index 0000000000..07dd9a5b86 --- /dev/null +++ b/srsue/hdr/phy/nr/sync_sa.h @@ -0,0 +1,141 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSUE_SYNC_NR_SA_H +#define SRSUE_SYNC_NR_SA_H + +#include "cell_search.h" +#include "slot_sync.h" +#include "srsran/common/threads.h" +#include "srsran/interfaces/radio_interfaces.h" +#include "srsran/interfaces/ue_nr_interfaces.h" +#include "srsran/radio/rf_buffer.h" +#include "srsran/radio/rf_timestamp.h" +#include "srsran/srslog/logger.h" +#include "srsran/srsran.h" +#include "srsue/hdr/phy/sync_state.h" +#include "worker_pool.h" +#include +#include +#include + +namespace srsue { +namespace nr { + +/** + * @brief NR Standalone synchronization class + */ +class sync_sa : public srsran::thread, public srsran::phy_common_interface +{ +public: + struct args_t { + double srate_hz = 61.44e6; + srsran_subcarrier_spacing_t ssb_min_scs = srsran_subcarrier_spacing_15kHz; + uint32_t nof_rx_channels = 1; + bool disable_cfo = false; + float pbch_dmrs_thr = 0.0f; ///< PBCH DMRS correlation detection threshold (0 means auto) + float cfo_alpha = 0.0f; ///< CFO averaging alpha (0 means auto) + int thread_priority = 1; + + cell_search::args_t get_cell_search() const + { + cell_search::args_t ret = {}; + ret.max_srate_hz = srate_hz; + return ret; + } + + slot_sync::args_t get_slot_sync() const + { + slot_sync::args_t ret = {}; + ret.max_srate_hz = srate_hz; + ret.nof_rx_channels = nof_rx_channels; + ret.ssb_min_scs = ssb_min_scs; + + return ret; + } + }; + + sync_sa(srslog::basic_logger& logger, worker_pool& workers_); + ~sync_sa(); + + bool init(const args_t& args_, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_); + bool reset(); + void stop(); + sync_state::state_t get_state(); + + // The following methods control the SYNC state machine + void cell_go_idle(); + cell_search::ret_t cell_search_run(const cell_search::cfg_t& cfg); + rrc_interface_phy_nr::cell_select_result_t cell_select_run(const phy_interface_rrc_nr::cell_select_args_t& req); + + void worker_end(const worker_context_t& w_ctx, const bool& tx_enable, srsran::rf_buffer_t& buffer) override; + + void add_ta_cmd_rar(uint32_t tti, uint32_t ta_cmd); + void add_ta_cmd_new(uint32_t tti, uint32_t ta_cmd); + void add_ta_offset(uint32_t ta_offset); + +private: + stack_interface_phy_nr* stack = nullptr; ///< Stand-Alone RRC interface + srsran::radio_interface_phy* radio = nullptr; ///< Radio object + srslog::basic_logger& logger; ///< General PHY logger + worker_pool& workers; + + // FSM that manages RRC commands for cell search/select/sync procedures + std::mutex rrc_mutex; + enum { PROC_IDLE = 0, PROC_SELECT_RUNNING, PROC_SEARCH_RUNNING } rrc_proc_state = PROC_IDLE; + sync_state phy_state; + + std::atomic running = {false}; + cf_t* rx_buffer = nullptr; + double srate_hz = 0; ///< Sampling rate in Hz + uint32_t slot_sz = 0; ///< Subframe size (1-ms) + uint32_t tti = 0; + srsran::tti_semaphore tti_semaphore; + srsran::rf_timestamp_t last_rx_time; + std::atomic is_pending_tx_end = {false}; + uint32_t cell_search_nof_trials = 0; + const static uint32_t cell_search_max_trials = 100; + uint32_t sfn_sync_nof_trials = 0; + const static uint32_t sfn_sync_max_trials = 100; + + cell_search::ret_t cs_ret; + cell_search searcher; + slot_sync slot_synchronizer; + + // Time Aligment Controller, internal thread safe + ta_control ta; + + // FSM States + bool wait_idle(); + void run_state_idle(); + void run_state_cell_search(); + void run_state_sfn_sync(); + void run_state_cell_camping(); + + int radio_recv_fnc(srsran::rf_buffer_t& data, srsran_timestamp_t* rx_time); + void run_stack_tti(); + void run_thread() override; +}; + +} // namespace nr +} // namespace srsue + +#endif // SRSUE_SYNC_NR_SA_H diff --git a/srsue/hdr/phy/nr/worker_pool.h b/srsue/hdr/phy/nr/worker_pool.h index 5c806f75b5..357eb8745d 100644 --- a/srsue/hdr/phy/nr/worker_pool.h +++ b/srsue/hdr/phy/nr/worker_pool.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,7 +29,7 @@ namespace srsue { namespace nr { -class worker_pool : public srsue::phy_interface_stack_nr +class worker_pool { private: srslog::basic_logger& logger; @@ -49,24 +49,23 @@ class worker_pool : public srsue::phy_interface_stack_nr public: sf_worker* operator[](std::size_t pos) { return workers.at(pos).get(); } - worker_pool(uint32_t max_workers); - bool init(const phy_args_nr_t& args_, srsran::phy_common_interface& common, stack_interface_phy_nr* stack_, int prio); + worker_pool(srslog::basic_logger& logger_, uint32_t max_workers); + bool init(const phy_args_nr_t& args_, srsran::phy_common_interface& common, stack_interface_phy_nr* stack_); sf_worker* wait_worker(uint32_t tti); void start_worker(sf_worker* w); void stop(); void send_prach(const uint32_t prach_occasion, const int preamble_index, const float preamble_received_target_power, - const float ta_base_sec = 0.0f) override; - int set_ul_grant(uint32_t rx_tti, - std::array array, - uint16_t rnti, - srsran_rnti_type_t rnti_type) override; - bool set_config(const srsran::phy_cfg_nr_t& cfg) override; - bool has_valid_sr_resource(uint32_t sr_id) override; - void clear_pending_grants() override; + const float ta_base_sec = 0.0f); + int set_rar_grant(uint32_t rx_tti, + std::array array, + uint16_t rnti, + srsran_rnti_type_t rnti_type); + bool set_config(const srsran::phy_cfg_nr_t& cfg); + bool has_valid_sr_resource(uint32_t sr_id); + void clear_pending_grants(); void get_metrics(phy_metrics_t& m); - int tx_request(const tx_request_t& request) override; /** * @brief Sets external CFO to compensate UL signal frequency offset diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 61fc89ee30..caf1b87cb1 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -34,53 +34,25 @@ #include "srsran/srsran.h" #include "srsue/hdr/phy/lte/worker_pool.h" #include "srsue/hdr/phy/nr/worker_pool.h" -#include "srsue/hdr/phy/ue_lte_phy_base.h" -#include "srsue/hdr/phy/ue_nr_phy_base.h" +#include "srsue/hdr/phy/ue_phy_base.h" #include "sync.h" namespace srsue { typedef _Complex float cf_t; -class phy_cmd_proc : public srsran::thread -{ -public: - phy_cmd_proc() : thread("PHY_CMD") { start(); } - - ~phy_cmd_proc() { stop(); } - - void add_cmd(std::function cmd) { cmd_queue.push(cmd); } - - void stop() - { - if (running) { - add_cmd([this]() { running = false; }); - wait_thread_finish(); - } - } - -private: - void run_thread() - { - std::function cmd; - while (running) { - cmd = cmd_queue.wait_pop(); - cmd(); - } - } - bool running = true; - // Queue for commands - srsran::block_queue > cmd_queue; -}; - -class phy final : public ue_lte_phy_base, public ue_nr_phy_base, public srsran::thread +class phy final : public ue_phy_base, + public phy_interface_stack_lte, + public phy_interface_stack_nr, + public srsran::phy_interface_radio, + public srsran::thread { public: explicit phy() : logger_phy(srslog::fetch_basic_logger("PHY")), logger_phy_lib(srslog::fetch_basic_logger("PHY_LIB")), lte_workers(MAX_WORKERS), - nr_workers(MAX_WORKERS), + nr_workers(logger_phy, MAX_WORKERS), common(logger_phy), sfsync(logger_phy, logger_phy_lib), prach_buffer(logger_phy), @@ -89,16 +61,13 @@ class phy final : public ue_lte_phy_base, public ue_nr_phy_base, public srsran:: ~phy() final { stop(); } - // Init defined in base class - int init(const phy_args_t& args_) final; - // Init for LTE PHYs - int init(const phy_args_t& args_, stack_interface_phy_lte* stack_, srsran::radio_interface_phy* radio_) final; + int init(const phy_args_t& args_, stack_interface_phy_lte* stack_, srsran::radio_interface_phy* radio_); void stop() final; void wait_initialize() final; - bool is_initiated(); + bool is_initialized() final; void get_metrics(const srsran::srsran_rat_t& rat, phy_metrics_t* m) final; void srsran_phy_logger(phy_logger_level_t log_level, char* str); @@ -108,7 +77,7 @@ class phy final : public ue_lte_phy_base, public ue_nr_phy_base, public srsran:: /********** RRC INTERFACE ********************/ - bool cell_search() final; + bool cell_search(int earfcn) final; bool cell_select(phy_cell_t cell) final; // Sets the new PHY configuration for the given CC. The configuration is applied in the background. The notify() @@ -172,25 +141,31 @@ class phy final : public ue_lte_phy_base, public ue_nr_phy_base, public srsran:: std::string get_type() final { return "lte_soft"; } - int init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_) final; - bool set_config(const srsran::phy_cfg_nr_t& cfg) final; - int set_ul_grant(uint32_t rx_tti, - std::array packed_ul_grant, - uint16_t rnti, - srsran_rnti_type_t rnti_type) final; - void send_prach(const uint32_t prach_occasion, - const int preamble_index, - const float preamble_received_target_power, - const float ta_base_sec = 0.0f) final; - int tx_request(const tx_request_t& request) final; - void set_earfcn(std::vector earfcns) final; - bool has_valid_sr_resource(uint32_t sr_id) final; - void clear_pending_grants() final; + /********** NR INTERFACE ********************/ + int init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_); + bool set_config(const srsran::phy_cfg_nr_t& cfg) final; + void send_prach(const uint32_t prach_occasion, + const int preamble_index, + const float preamble_received_target_power, + const float ta_base_sec = 0.0f) final; + void set_earfcn(std::vector earfcns); + bool has_valid_sr_resource(uint32_t sr_id) final; + void clear_pending_grants() final; + int set_rar_grant(uint32_t rar_slot_idx, + std::array packed_ul_grant, + uint16_t rnti, + srsran_rnti_type_t rnti_type) final; + phy_nr_state_t get_state() override { return PHY_NR_STATE_IDLE; }; + void reset_nr() override{}; + bool start_cell_search(const cell_search_args_t& req) override { return false; }; + bool start_cell_select(const cell_select_args_t& req) override { return false; }; private: void run_thread() final; void configure_prach_params(); void reset(); + bool set_scell(srsran_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn, bool run_in_background); + void set_scell_cmd(srsran_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn, bool earfcn_is_different); std::mutex config_mutex; std::condition_variable config_cond; @@ -226,6 +201,9 @@ class phy final : public ue_lte_phy_base, public ue_nr_phy_base, public srsran:: // Tracks the current selected cell (last call to cell_select) srsran_cell_t selected_cell = {}; + // Tracks the current selected EARFCN (last call to cell_select) + uint32_t selected_earfcn = 0; + static void set_default_args(phy_args_t& args); bool check_args(const phy_args_t& args); }; diff --git a/srsue/hdr/phy/phy_common.h b/srsue/hdr/phy/phy_common.h index b64f296666..bcfd81c59d 100644 --- a/srsue/hdr/phy/phy_common.h +++ b/srsue/hdr/phy/phy_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,7 +24,9 @@ #include "phy_metrics.h" #include "srsran/adt/circular_array.h" +#include "srsran/common/block_queue.h" #include "srsran/common/gen_mch_tables.h" +#include "srsran/common/threads.h" #include "srsran/common/tti_sempahore.h" #include "srsran/interfaces/phy_common_interface.h" #include "srsran/interfaces/phy_interface_types.h" @@ -55,6 +57,37 @@ class rsrp_insync_itf virtual void set_cfo(float cfo) = 0; }; +class phy_cmd_proc : public srsran::thread +{ +public: + phy_cmd_proc() : thread("PHY_CMD") { start(); } + + ~phy_cmd_proc() { stop(); } + + void add_cmd(std::function cmd) { cmd_queue.push(cmd); } + + void stop() + { + if (running) { + add_cmd([this]() { running = false; }); + wait_thread_finish(); + } + } + +private: + void run_thread() + { + std::function cmd; + while (running) { + cmd = cmd_queue.wait_pop(); + cmd(); + } + } + bool running = true; + // Queue for commands + srsran::block_queue > cmd_queue; +}; + /* Subclass that manages variables common to all workers */ class phy_common : public srsran::phy_common_interface { @@ -282,6 +315,8 @@ class phy_common : public srsran::phy_common_interface } } + srsran_cfr_cfg_t get_cfr_config() { return cfr_config; } + private: std::mutex meas_mutex; @@ -299,13 +334,18 @@ class phy_common : public srsran::phy_common_interface std::array avg_noise = {}; std::array avg_rsrp_neigh = {}; + srsran_cfr_cfg_t cfr_config = {}; + static constexpr uint32_t pcell_report_period = 20; - uint32_t rssi_read_cnt = 0; + + static constexpr uint32_t update_rxgain_period = 10; + uint32_t update_rxgain_cnt = 0; rsrp_insync_itf* insync_itf = nullptr; bool have_mtch_stop = false; std::mutex mtch_mutex; + std::mutex mch_mutex; std::condition_variable mtch_cvar; std::atomic is_pending_tx_end{false}; diff --git a/srsue/hdr/phy/phy_metrics.h b/srsue/hdr/phy/phy_metrics.h index b14b47b7d5..09b0c3c0f3 100644 --- a/srsue/hdr/phy/phy_metrics.h +++ b/srsue/hdr/phy/phy_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -42,11 +42,11 @@ struct info_metrics_t { struct sync_metrics_t { typedef std::array array_t; - float ta_us; - float distance_km; - float speed_kmph; - float cfo; - float sfo; + float ta_us = 0.0; + float distance_km = 0.0; + float speed_kmph = 0.0; + float cfo = 0.0; + float sfo = 0.0; void set(const sync_metrics_t& other) { @@ -75,14 +75,14 @@ struct sync_metrics_t { struct ch_metrics_t { typedef std::array array_t; - float n; - float sinr; - float rsrp; - float rsrq; - float rssi; - float ri; - float pathloss; - float sync_err; + float n = 0.0; + float sinr = 0.0; + float rsrp = 0.0; + float rsrq = 0.0; + float rssi = 0.0; + float ri = 0.0; + float pathloss = 0.0; + float sync_err = 0.0; void set(const ch_metrics_t& other) { @@ -120,9 +120,9 @@ struct ch_metrics_t { struct dl_metrics_t { typedef std::array array_t; - float fec_iters; - float mcs; - float evm; + float fec_iters = 0.0; + float mcs = 0.0; + float evm = 0.0; void set(const dl_metrics_t& other) { diff --git a/srsue/hdr/phy/phy_nr_sa.h b/srsue/hdr/phy/phy_nr_sa.h new file mode 100644 index 0000000000..76ad05568f --- /dev/null +++ b/srsue/hdr/phy/phy_nr_sa.h @@ -0,0 +1,114 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSUE_PHY_NR_SA_H +#define SRSUE_PHY_NR_SA_H + +#include "phy_common.h" +#include "srsran/interfaces/ue_nr_interfaces.h" +#include "srsue/hdr/phy/nr/sync_sa.h" +#include "srsue/hdr/phy/ue_phy_base.h" + +namespace srsue { + +/** + * @brief NR Standalone PHY + */ +class phy_nr_sa final : public ue_phy_base, public phy_interface_stack_nr, public srsran::phy_interface_radio +{ +public: + phy_nr_sa(const char* logname); + ~phy_nr_sa() final { stop(); } + + int init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_); + void wait_initialize() final; + bool is_initialized() final; + void stop() final; + void reset_nr() final; + + void start_plot() final {} + + void radio_overflow() final {} + void radio_failure() final {} + + std::string get_type() final { return "nr_soft"; } + + int set_rar_grant(uint32_t rar_slot_idx, + std::array packed_ul_grant, + uint16_t rnti, + srsran_rnti_type_t rnti_type) final; + void send_prach(const uint32_t prach_occasion, + const int preamble_index, + const float preamble_received_target_power, + const float ta_base_sec) final; + void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) final; + void set_timeadv(uint32_t tti, uint32_t ta_cmd) final; + + void set_earfcn(std::vector earfcns); + bool has_valid_sr_resource(uint32_t sr_id) final; + void clear_pending_grants() final; + bool set_config(const srsran::phy_cfg_nr_t& cfg) final; + + phy_nr_state_t get_state() final; + bool start_cell_search(const cell_search_args_t& req) final; + bool start_cell_select(const cell_select_args_t& req) final; + + void get_metrics(const srsran::srsran_rat_t& rat, phy_metrics_t* m) final + { + if (rat == srsran::srsran_rat_t::nr) { + return workers.get_metrics(*m); + } + }; + void srsran_phy_logger(phy_logger_level_t log_level, char* str); + +private: + srslog::basic_logger& logger; + srslog::basic_logger& logger_phy_lib; + + nr::worker_pool workers; + nr::sync_sa sync; + + srsran::phy_cfg_nr_t config_nr = {}; + phy_args_nr_t args = {}; + srsran_carrier_nr_t selected_cell = {}; + + srsran::radio_interface_phy* radio = nullptr; + stack_interface_phy_nr* stack = nullptr; + + std::atomic is_configured = {false}; + + // Since cell_search/cell_select operations take a lot of time, we use another queue to process the other commands + // in parallel and avoid accumulating in the queue + phy_cmd_proc cmd_worker_cell, cmd_worker; + + // Run initialization functions in the background + void init_background(); + std::thread init_thread; + + const static int MAX_WORKERS = 4; + const static int DEFAULT_WORKERS = 4; + + static void set_default_args(phy_args_nr_t& args); + bool check_args(const phy_args_nr_t& args); +}; + +} // namespace srsue +#endif // SRSUE_PHY_NR_SA_H diff --git a/srsue/hdr/phy/prach.h b/srsue/hdr/phy/prach.h index 8ba709774d..84fd37bb8d 100644 --- a/srsue/hdr/phy/prach.h +++ b/srsue/hdr/phy/prach.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/phy/scell/intra_measure_base.h b/srsue/hdr/phy/scell/intra_measure_base.h index 999d31298a..c341208ecd 100644 --- a/srsue/hdr/phy/scell/intra_measure_base.h +++ b/srsue/hdr/phy/scell/intra_measure_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -280,7 +280,7 @@ class intra_measure_base : public srsran::thread * @param rx_gain_offset Provides last received rx_gain_offset * @return True if the measurement functions are executed without errors, otherwise false */ - virtual bool measure_rat(measure_context_t context, std::vector& 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 f59e505ee2..5dc8a8fa86 100644 --- a/srsue/hdr/phy/scell/intra_measure_lte.h +++ b/srsue/hdr/phy/scell/intra_measure_lte.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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 515b6f2d8d..032a4c2f34 100644 --- a/srsue/hdr/phy/scell/intra_measure_nr.h +++ b/srsue/hdr/phy/scell/intra_measure_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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/phy/scell/scell_recv.h b/srsue/hdr/phy/scell/scell_recv.h index e935df1955..b41a46d223 100644 --- a/srsue/hdr/phy/scell/scell_recv.h +++ b/srsue/hdr/phy/scell/scell_recv.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/phy/scell/scell_state.h b/srsue/hdr/phy/scell/scell_state.h index b9df6b61ca..8b52c01c00 100644 --- a/srsue/hdr/phy/scell/scell_state.h +++ b/srsue/hdr/phy/scell/scell_state.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/phy/scell/scell_sync.h b/srsue/hdr/phy/scell/scell_sync.h index b7229502a8..7ee656fdb9 100644 --- a/srsue/hdr/phy/scell/scell_sync.h +++ b/srsue/hdr/phy/scell/scell_sync.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/phy/search.h b/srsue/hdr/phy/search.h index b065e36cc1..29ba1e34a5 100644 --- a/srsue/hdr/phy/search.h +++ b/srsue/hdr/phy/search.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -45,7 +45,7 @@ class search explicit search(srslog::basic_logger& logger) : logger(logger) {} ~search(); - void init(srsran::rf_buffer_t& buffer_, uint32_t nof_rx_channels, search_callback* parent, int force_N_id_2_); + void init(srsran::rf_buffer_t& buffer_, uint32_t nof_rx_channels, search_callback* parent, int force_N_id_2_, int force_N_id_1_); void reset(); float get_last_cfo(); void set_agc_enable(bool enable); @@ -59,6 +59,7 @@ class search srsran_ue_cellsearch_t cs = {}; srsran_ue_mib_sync_t ue_mib_sync = {}; int force_N_id_2 = 0; + int force_N_id_1 = 0; }; }; // namespace srsue diff --git a/srsue/hdr/phy/sfn_sync.h b/srsue/hdr/phy/sfn_sync.h index ff312b611c..f9ec816293 100644 --- a/srsue/hdr/phy/sfn_sync.h +++ b/srsue/hdr/phy/sfn_sync.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/phy/sync.h b/srsue/hdr/phy/sync.h index 5a48be22de..152f255a33 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -77,7 +77,7 @@ class sync : public srsran::thread, // RRC interface for controling the SYNC state bool cell_search_init(); - rrc_interface_phy_lte::cell_search_ret_t cell_search_start(phy_cell_t* cell); + rrc_interface_phy_lte::cell_search_ret_t cell_search_start(phy_cell_t* cell, int earfcn); bool cell_select_init(phy_cell_t cell); bool cell_select_start(phy_cell_t cell); bool cell_is_camping(); diff --git a/srsue/hdr/phy/sync_state.h b/srsue/hdr/phy/sync_state.h index 9f3dd042a2..cbae0a37f5 100644 --- a/srsue/hdr/phy/sync_state.h +++ b/srsue/hdr/phy/sync_state.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,6 +22,9 @@ #ifndef SRSUE_SYNC_STATE_H #define SRSUE_SYNC_STATE_H +#include +#include + namespace srsue { class sync_state @@ -67,6 +70,12 @@ class sync_state next_state = SFN_SYNC; } + state_t get_state() + { + std::lock_guard lock(mutex); + return cur_state; + } + /* Functions to be called from outside the STM thread to instruct the STM to switch state. * The functions change the state and wait until it has changed it. * diff --git a/srsue/hdr/phy/ta_control.h b/srsue/hdr/phy/ta_control.h index 9d97f736b9..25a003cad1 100644 --- a/srsue/hdr/phy/ta_control.h +++ b/srsue/hdr/phy/ta_control.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -104,6 +104,19 @@ class ta_control next_base_sec * 1e6f); } + void add_ta_offset(uint32_t ta_offset) + { + std::lock_guard lock(mutex); + + // Assuming numerology 0 + next_base_nta = ta_offset / 64; + + // Update base in seconds + next_base_sec = static_cast(next_base_nta) * SRSRAN_LTE_TS; + + logger.info("PHY: Set TA offset: n_ta_offset: %d, ta_usec: %.1f", next_base_nta, next_base_sec * 1e6f); + } + /** * Increments (delta) the next base time according to time alignment command from a Random Access Response (RAR). * diff --git a/srsue/hdr/phy/ue_lte_phy_base.h b/srsue/hdr/phy/ue_lte_phy_base.h deleted file mode 100644 index 2a31346767..0000000000 --- a/srsue/hdr/phy/ue_lte_phy_base.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -/****************************************************************************** - * File: ue_lte_phy_base.h - * Description: Base class for UE LTE PHYs. - *****************************************************************************/ - -#ifndef SRSUE_UE_LTE_PHY_BASE_H -#define SRSUE_UE_LTE_PHY_BASE_H - -#include "srsran/interfaces/radio_interfaces.h" -#include "srsue/hdr/phy/ue_phy_base.h" - -namespace srsue { - -class stack_interface_phy_lte; - -class ue_lte_phy_base : public ue_phy_base, public phy_interface_stack_lte, public srsran::phy_interface_radio -{ -public: - ue_lte_phy_base(){}; - virtual ~ue_lte_phy_base(){}; - - virtual std::string get_type() = 0; - - virtual int init(const phy_args_t& args_) = 0; - virtual int init(const phy_args_t& args_, stack_interface_phy_lte* stack_, srsran::radio_interface_phy* radio_) = 0; - virtual void stop() = 0; - - virtual void wait_initialize() = 0; - virtual void start_plot() = 0; - - virtual void get_metrics(const srsran::srsran_rat_t& rat, phy_metrics_t* m) = 0; -}; - -} // namespace srsue - -#endif // SRSUE_UE_LTE_PHY_BASE_H diff --git a/srsue/hdr/phy/ue_nr_phy_base.h b/srsue/hdr/phy/ue_nr_phy_base.h deleted file mode 100644 index 04bde236fc..0000000000 --- a/srsue/hdr/phy/ue_nr_phy_base.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -/****************************************************************************** - * File: ue_nr_phy_base.h - * Description: Base class for UE NR PHYs. - *****************************************************************************/ - -#ifndef SRSUE_UE_NR_PHY_BASE_H -#define SRSUE_UE_NR_PHY_BASE_H - -#include "srsran/interfaces/radio_interfaces.h" -#include "srsran/interfaces/ue_nr_interfaces.h" -#include "srsue/hdr/phy/ue_phy_base.h" - -namespace srsue { - -class ue_nr_phy_base : public phy_interface_stack_nr -{ -public: - ue_nr_phy_base(){}; - virtual ~ue_nr_phy_base() {} - - virtual std::string get_type() = 0; - - virtual int init(const phy_args_t& args_) = 0; - virtual int init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_) = 0; - virtual void stop() = 0; - - virtual void set_earfcn(std::vector earfcns) = 0; - - virtual void get_metrics(const srsran::srsran_rat_t& rat, phy_metrics_t* m) = 0; -}; - -} // namespace srsue - -#endif // SRSUE_UE_NR_PHY_BASE_H \ No newline at end of file diff --git a/srsue/hdr/phy/ue_phy_base.h b/srsue/hdr/phy/ue_phy_base.h index 23f6fb605c..555cafa7b3 100644 --- a/srsue/hdr/phy/ue_phy_base.h +++ b/srsue/hdr/phy/ue_phy_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -40,11 +40,10 @@ class ue_phy_base virtual std::string get_type() = 0; - virtual int init(const phy_args_t& args_) = 0; - virtual void stop() = 0; virtual void wait_initialize() = 0; + virtual bool is_initialized() = 0; virtual void start_plot() = 0; virtual void get_metrics(const srsran::srsran_rat_t& rat, phy_metrics_t* m) = 0; diff --git a/srsue/hdr/stack/mac/demux.h b/srsue/hdr/stack/mac/demux.h index c5c213b935..fe98c6d062 100644 --- a/srsue/hdr/stack/mac/demux.h +++ b/srsue/hdr/stack/mac/demux.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac/dl_harq.h b/srsue/hdr/stack/mac/dl_harq.h index 9302051e61..0a1ddd8ffe 100644 --- a/srsue/hdr/stack/mac/dl_harq.h +++ b/srsue/hdr/stack/mac/dl_harq.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac/dl_sps.h b/srsue/hdr/stack/mac/dl_sps.h index f5361c1fa5..db351233a9 100644 --- a/srsue/hdr/stack/mac/dl_sps.h +++ b/srsue/hdr/stack/mac/dl_sps.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac/mac.h b/srsue/hdr/stack/mac/mac.h index bd7cf0f0a7..30873b86f3 100644 --- a/srsue/hdr/stack/mac/mac.h +++ b/srsue/hdr/stack/mac/mac.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -59,13 +59,12 @@ class mac : public mac_interface_phy_lte, /* see mac_interface.h for comments */ void new_grant_ul(uint32_t cc_idx, mac_grant_ul_t grant, tb_action_ul_t* action); void new_grant_dl(uint32_t cc_idx, mac_grant_dl_t grant, tb_action_dl_t* action); - void new_mch_dl(const srsran_pdsch_grant_t& phy_grant, tb_action_dl_t* action); void tb_decoded(uint32_t cc_idx, mac_grant_dl_t grant, bool ack[SRSRAN_MAX_CODEWORDS]); void bch_decoded_ok(uint32_t cc_idx, uint8_t* payload, uint32_t len); uint16_t get_dl_sched_rnti(uint32_t tti); uint16_t get_ul_sched_rnti(uint32_t tti); - void mch_decoded(uint32_t len, bool crc); + void mch_decoded(uint32_t len, bool crc, uint8_t* payload); void process_mch_pdu(uint32_t len); void set_mbsfn_config(uint32_t nof_mbsfn_services); @@ -140,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/mac/mac_metrics.h b/srsue/hdr/stack/mac/mac_metrics.h index c82b6f018c..81e4ec7da3 100644 --- a/srsue/hdr/stack/mac/mac_metrics.h +++ b/srsue/hdr/stack/mac/mac_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac/mux.h b/srsue/hdr/stack/mac/mux.h index 611f3bbc25..7608ed2190 100644 --- a/srsue/hdr/stack/mac/mux.h +++ b/srsue/hdr/stack/mac/mux.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac/proc.h b/srsue/hdr/stack/mac/proc.h index d46665ec7f..d79b83ffe5 100644 --- a/srsue/hdr/stack/mac/proc.h +++ b/srsue/hdr/stack/mac/proc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac/proc_bsr.h b/srsue/hdr/stack/mac/proc_bsr.h index 94c6960b63..fda1f9bf50 100644 --- a/srsue/hdr/stack/mac/proc_bsr.h +++ b/srsue/hdr/stack/mac/proc_bsr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac/proc_phr.h b/srsue/hdr/stack/mac/proc_phr.h index ffdf953b5e..d9e9adfea1 100644 --- a/srsue/hdr/stack/mac/proc_phr.h +++ b/srsue/hdr/stack/mac/proc_phr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac/proc_ra.h b/srsue/hdr/stack/mac/proc_ra.h index 220c62660b..3a8f5a4623 100644 --- a/srsue/hdr/stack/mac/proc_ra.h +++ b/srsue/hdr/stack/mac/proc_ra.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac/proc_sr.h b/srsue/hdr/stack/mac/proc_sr.h index c70be90803..25ee46e364 100644 --- a/srsue/hdr/stack/mac/proc_sr.h +++ b/srsue/hdr/stack/mac/proc_sr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac/ul_harq.h b/srsue/hdr/stack/mac/ul_harq.h index ef4e0c95a5..0a0f304add 100644 --- a/srsue/hdr/stack/mac/ul_harq.h +++ b/srsue/hdr/stack/mac/ul_harq.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac/ul_sps.h b/srsue/hdr/stack/mac/ul_sps.h index 643a369f38..88a5315fee 100644 --- a/srsue/hdr/stack/mac/ul_sps.h +++ b/srsue/hdr/stack/mac/ul_sps.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac_common/mac_common.h b/srsue/hdr/stack/mac_common/mac_common.h index 27c1cbebf3..7bfc7c25e3 100644 --- a/srsue/hdr/stack/mac_common/mac_common.h +++ b/srsue/hdr/stack/mac_common/mac_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac_common/mux_base.h b/srsue/hdr/stack/mac_common/mux_base.h index f740c808d6..6d6a1b8f2f 100644 --- a/srsue/hdr/stack/mac_common/mux_base.h +++ b/srsue/hdr/stack/mac_common/mux_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac_nr/demux_nr.h b/srsue/hdr/stack/mac_nr/demux_nr.h index f77ca1d8a2..5a579902d1 100644 --- a/srsue/hdr/stack/mac_nr/demux_nr.h +++ b/srsue/hdr/stack/mac_nr/demux_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,6 +24,7 @@ #include "mac_nr_interfaces.h" #include "srsran/common/block_queue.h" +#include "srsran/interfaces/ue_nr_interfaces.h" #include "srsran/interfaces/ue_rlc_interfaces.h" namespace srsue { @@ -44,24 +45,32 @@ class demux_nr : public demux_interface_harq_nr demux_nr(srslog::basic_logger& logger_); ~demux_nr(); - int32_t init(rlc_interface_mac* rlc_); + int32_t init(rlc_interface_mac* rlc_, phy_interface_mac_nr* phy_); void process_pdus(); /// Called by MAC to process received PDUs // HARQ interface - void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti); + void push_bcch(srsran::unique_byte_buffer_t pdu); + void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti); + void push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tti); + uint64_t get_received_crueid(); private: // internal helpers - void handle_pdu(srsran::unique_byte_buffer_t pdu); + void handle_pdu(srsran::mac_sch_pdu_nr& pdu_buffer, srsran::unique_byte_buffer_t pdu); srslog::basic_logger& logger; rlc_interface_mac* rlc = nullptr; + phy_interface_mac_nr* phy = nullptr; - ///< currently only DCH PDUs supported (add BCH, PCH, etc) + uint64_t received_crueid = 0; + + ///< currently only DCH & BCH PDUs supported (add PCH, etc) srsran::block_queue pdu_queue; + srsran::block_queue bcch_queue; srsran::mac_sch_pdu_nr rx_pdu; + srsran::mac_sch_pdu_nr rx_pdu_tcrnti; }; } // namespace srsue diff --git a/srsue/hdr/stack/mac_nr/dl_harq_nr.h b/srsue/hdr/stack/mac_nr/dl_harq_nr.h index fc9c112dd5..dd0fffe5aa 100644 --- a/srsue/hdr/stack/mac_nr/dl_harq_nr.h +++ b/srsue/hdr/stack/mac_nr/dl_harq_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h index f4ebee4e68..27577eaa1c 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -87,7 +87,7 @@ class mac_nr final : public mac_interface_phy_nr, int setup_lcid(const srsran::logical_channel_config_t& config); int set_config(const srsran::bsr_cfg_nr_t& bsr_cfg); int set_config(const srsran::sr_cfg_nr_t& sr_cfg); - void set_config(const srsran::rach_nr_cfg_t& rach_cfg); + void set_config(const srsran::rach_cfg_nr_t& rach_cfg_nr); int set_config(const srsran::dl_harq_cfg_nr_t& dl_hrq_cfg); void set_contention_id(const uint64_t ue_identity); bool set_crnti(const uint16_t crnti); @@ -97,10 +97,12 @@ class mac_nr final : public mac_interface_phy_nr, void start_ra_procedure(); /// Interface for internal procedures (RA, MUX, HARQ) - uint64_t get_contention_id(); + bool received_contention_id(uint64_t rx_contention_id); uint16_t get_crnti(); uint16_t get_temp_crnti(); uint16_t get_csrnti() { return SRSRAN_INVALID_RNTI; }; // SPS not supported + void set_temp_crnti(uint16_t temp_crnti); + void set_crnti_to_temp(); /// procedure sr nr interface void start_ra() { proc_ra.start_by_mac(); } @@ -118,6 +120,7 @@ class mac_nr final : public mac_interface_phy_nr, /// RRC void rrc_ra_problem(); void rrc_ra_completed(); + void bcch_search(bool enabled); /// stack interface void process_pdus(); @@ -138,6 +141,7 @@ class mac_nr final : public mac_interface_phy_nr, bool is_paging_opportunity(); bool has_crnti(); + bool has_temp_crnti(); bool is_valid_crnti(const uint16_t crnti); std::vector logical_channels; // stores the raw configs provide by upper layers @@ -158,7 +162,11 @@ class mac_nr final : public mac_interface_phy_nr, std::atomic started = {false}; + // Boolean to determine if need to decode SI-RNTI + std::atomic search_bcch = {false}; + ue_rnti rntis; // thread-safe helper to store RNTIs, contention ID, etc + bool contention_res_successful; std::array metrics = {}; diff --git a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h index 105dc06f68..d9f20d9afa 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h +++ b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -33,9 +33,10 @@ class mac_interface_proc_ra_nr { public: // Functions for identity handling, e.g., contention id and c-rnti - virtual uint64_t get_contention_id() = 0; virtual uint16_t get_crnti() = 0; virtual bool set_crnti(uint16_t c_rnti) = 0; + virtual void set_temp_crnti(uint16_t c_rnti) = 0; + virtual void set_crnti_to_temp() = 0; // Functions for msg3 manipulation which shall be transparent to the procedure virtual bool msg3_is_transmitted() = 0; @@ -89,6 +90,9 @@ class mac_interface_harq_nr // MAC also provides Temp C-RNTI (through RA proc) virtual uint16_t get_temp_crnti() = 0; + // HARQ can query MAC for current C-RNTI + virtual bool received_contention_id(uint64_t rx_contention_id) = 0; + // MAC provides the Currently Scheduled RNTI (for SPS) virtual uint16_t get_csrnti() = 0; }; @@ -100,7 +104,10 @@ class demux_interface_harq_nr { public: /// Inform demux unit about a newly decoded TB. - virtual void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti) = 0; + virtual void push_bcch(srsran::unique_byte_buffer_t pdu) = 0; + virtual void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti) = 0; + virtual void push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tti) = 0; + virtual uint64_t get_received_crueid() = 0; }; } // namespace srsue diff --git a/srsue/hdr/stack/mac_nr/mux_nr.h b/srsue/hdr/stack/mac_nr/mux_nr.h index f4ec975978..0e99bc4bfd 100644 --- a/srsue/hdr/stack/mac_nr/mux_nr.h +++ b/srsue/hdr/stack/mac_nr/mux_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac_nr/proc_bsr_nr.h b/srsue/hdr/stack/mac_nr/proc_bsr_nr.h index ea567540b0..94fb8e5503 100644 --- a/srsue/hdr/stack/mac_nr/proc_bsr_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_bsr_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac_nr/proc_ra_nr.h b/srsue/hdr/stack/mac_nr/proc_ra_nr.h index fbc4f9f50e..252fba994b 100644 --- a/srsue/hdr/stack/mac_nr/proc_ra_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_ra_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -41,7 +41,7 @@ class proc_ra_nr ~proc_ra_nr(){}; void init(phy_interface_mac_nr* phy_h_, srsran::ext_task_sched_handle* task_sched_); - void set_config(const srsran::rach_nr_cfg_t& rach_cfg); + void set_config(const srsran::rach_cfg_nr_t& rach_cfg_nr); bool is_contention_resolution(); bool is_rar_opportunity(uint32_t tti); @@ -49,6 +49,8 @@ class proc_ra_nr uint16_t get_rar_rnti(); bool has_temp_crnti(); uint16_t get_temp_crnti(); + void set_crnti_to_temp(); + void received_contention_resolution(bool is_successful); // PHY interfaces void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id); @@ -72,10 +74,9 @@ class proc_ra_nr int ra_window_length = -1, ra_window_start = -1; uint16_t rar_rnti = SRSRAN_INVALID_RNTI; - uint16_t temp_crnti = SRSRAN_INVALID_RNTI; std::mutex mutex; - srsran::rach_nr_cfg_t rach_cfg = {}; + srsran::rach_cfg_nr_t rach_cfg = {}; bool configured = false; enum ra_state_t { @@ -119,8 +120,7 @@ class proc_ra_nr void ra_resource_selection(); void ra_preamble_transmission(); void ra_response_reception(const mac_interface_phy_nr::tb_action_dl_result_t& tb); - void ra_contention_resolution(); - void ra_contention_resolution(uint64_t rx_contention_id); + void ra_contention_resolution(bool received_con_res_matches_ue_id); void ra_completion(); void ra_error(); }; diff --git a/srsue/hdr/stack/mac_nr/proc_sr_nr.h b/srsue/hdr/stack/mac_nr/proc_sr_nr.h index 5d52d5bf04..caa2a635cc 100644 --- a/srsue/hdr/stack/mac_nr/proc_sr_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_sr_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/mac_nr/ul_harq_nr.h b/srsue/hdr/stack/mac_nr/ul_harq_nr.h index e4ad730b18..8978ab35fa 100644 --- a/srsue/hdr/stack/mac_nr/ul_harq_nr.h +++ b/srsue/hdr/stack/mac_nr/ul_harq_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/rrc/phy_controller.h b/srsue/hdr/stack/rrc/phy_controller.h index 456df9cdf1..3e6fa35f2b 100644 --- a/srsue/hdr/stack/rrc/phy_controller.h +++ b/srsue/hdr/stack/rrc/phy_controller.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -49,7 +49,9 @@ class phy_controller : public srsran::fsm_t struct cell_sel_cmd { phy_cell_t phy_cell; }; - struct cell_search_cmd {}; + struct cell_search_cmd { + int earfcn; + }; struct in_sync_ev { static const bool log_verbose = false; }; @@ -61,7 +63,7 @@ class phy_controller : public srsran::fsm_t // PHY procedures interfaces bool start_cell_select(const phy_cell_t& phy_cell, srsran::event_observer observer = {}); - bool start_cell_search(srsran::event_observer observer); + bool start_cell_search(srsran::event_observer observer, int earfcn); void cell_search_completed(cell_search_ret_t cs_ret, phy_cell_t found_cell); void cell_selection_completed(bool outcome); void in_sync(); @@ -126,7 +128,7 @@ class phy_controller : public srsran::fsm_t // clang-format on }; struct searching_cell { - void enter(phy_controller* f); + void enter(phy_controller* f, const cell_search_cmd& ev); }; private: diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index efe2c70571..a12ca08069 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -220,6 +220,9 @@ class rrc : public rrc_interface_nas, meas_cell_list meas_cells_nr; + // if this is set to a valid earfcn, this earfcn will be used for cell search + int cell_search_earfcn = -1; + bool initiated = false; asn1::rrc::reest_cause_e m_reest_cause = asn1::rrc::reest_cause_e::nulltype; uint16_t m_reest_rnti = 0; @@ -337,7 +340,8 @@ class rrc : public rrc_interface_nas, bool con_reconfig_ho(const asn1::rrc::rrc_conn_recfg_s& reconfig); void ho_failed(); void start_go_idle(); - void rrc_connection_release(const std::string& cause); + void handle_rrc_connection_release(const asn1::rrc::rrc_conn_release_s& release); + void start_rrc_redirect(uint32_t new_dl_earfcn); void radio_link_failure_push_cmd(); void radio_link_failure_process(); void leave_connected(); diff --git a/srsue/hdr/stack/rrc/rrc_cell.h b/srsue/hdr/stack/rrc/rrc_cell.h index 33389cfee4..1aceac5592 100644 --- a/srsue/hdr/stack/rrc/rrc_cell.h +++ b/srsue/hdr/stack/rrc/rrc_cell.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -40,6 +40,9 @@ inline std::string to_string(const phy_cell_t& c) return {buffer}; } +/// \brief Helper function to get the SIB number from the SIB type. +unsigned get_sib_number(const asn1::rrc::sib_type_e& sib); + class meas_cell { public: @@ -130,8 +133,6 @@ class meas_cell_nr : public meas_cell void set_sib3(const asn1::rrc_nr::sib3_s& sib3_); const asn1::rrc_nr::sib1_s* sib1ptr() const { return has_sib1() ? &sib1 : nullptr; } - const asn1::rrc_nr::sib2_s* sib2ptr() const { return has_sib2() ? &sib2 : nullptr; } - const asn1::rrc_nr::sib3_s* sib3ptr() const { return has_sib3() ? &sib3 : nullptr; } uint32_t get_cell_id() const { return (uint32_t)0xFFFF; } // TODO find the correct sib @@ -140,11 +141,7 @@ class meas_cell_nr : public meas_cell std::string to_string() const; - bool has_mcch = false; - asn1::rrc_nr::sib1_s sib1 = {}; - asn1::rrc_nr::sib2_s sib2 = {}; - asn1::rrc_nr::sib3_s sib3 = {}; - asn1::rrc::mcch_msg_s mcch = {}; + asn1::rrc_nr::sib1_s sib1 = {}; }; class meas_cell_eutra : public meas_cell @@ -153,9 +150,9 @@ class meas_cell_eutra : public meas_cell explicit meas_cell_eutra(srsran::unique_timer timer) : meas_cell(std::move(timer)){}; meas_cell_eutra(const phy_cell_t& phy_cell_, srsran::unique_timer timer) : meas_cell(phy_cell_, std::move(timer)){}; - bool has_plmn_id(asn1::rrc::plmn_id_s plmn_id) const; - uint32_t nof_plmns() const { return has_sib1() ? sib1.cell_access_related_info.plmn_id_list.size() : 0; } - srsran::plmn_id_t get_plmn(uint32_t idx) const; + bool has_plmn_id(asn1::rrc::plmn_id_s plmn_id) const; + uint32_t nof_plmns() const { return has_sib1() ? sib1.cell_access_related_info.plmn_id_list.size() : 0; } + srsran::plmn_id_t get_plmn(uint32_t idx) const; asn1::rrc::plmn_id_s get_plmn_asn1(uint32_t idx) const; uint16_t get_tac() const { return has_sib1() ? (uint16_t)sib1.cell_access_related_info.tac.to_number() : 0; } @@ -170,11 +167,9 @@ class meas_cell_eutra : public meas_cell const asn1::rrc::sib_type3_s* sib3ptr() const { return has_sib3() ? &sib3 : nullptr; } const asn1::rrc::sib_type13_r9_s* sib13ptr() const { return has_sib13() ? &sib13 : nullptr; } - uint32_t get_cell_id() const { return (uint32_t)sib1.cell_access_related_info.cell_id.to_number(); } + uint32_t get_cell_id() const { return (uint32_t)sib1.cell_access_related_info.cell_id.to_number(); } asn1::fixed_bitstring<28> get_cell_id_bit() const { return sib1.cell_access_related_info.cell_id; } - bool has_sib13() const { return has_valid_sib13; } - uint16_t get_mcc() const; uint16_t get_mnc() const; @@ -188,7 +183,6 @@ class meas_cell_eutra : public meas_cell asn1::rrc::mcch_msg_s mcch = {}; private: - bool has_valid_sib13 = false; }; //! Universal methods to extract pci/earfcn and compare the two values @@ -262,6 +256,10 @@ class meas_cell_list // serving cell handling int set_serving_cell(phy_cell_t phy_cell, bool discard_serving); + // Set serving cell and earfcn for each cc_idx + void set_scell_cc_idx(uint32_t cc_idx, uint32_t earfcn, uint32_t pci); + bool get_scell_cc_idx(uint32_t earfcn, uint32_t& pci); + T& serving_cell() { return *serv_cell; } const T& serving_cell() const { return *serv_cell; } @@ -278,6 +276,9 @@ class meas_cell_list unique_meas_cell serv_cell; std::vector neighbour_cells; + + // store serving pci and earfcn for each carrier + std::array, SRSRAN_MAX_CARRIERS> current_cell_pci_earfcn = {}; }; } // namespace srsue diff --git a/srsue/hdr/stack/rrc/rrc_config.h b/srsue/hdr/stack/rrc/rrc_config.h index ba30b22f26..bc63deb5b1 100644 --- a/srsue/hdr/stack/rrc/rrc_config.h +++ b/srsue/hdr/stack/rrc/rrc_config.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -36,6 +36,8 @@ struct rrc_args_t { std::array supported_bands; std::vector supported_bands_nr; uint32_t nof_supported_bands; + uint32_t nof_lte_carriers; + uint32_t nof_nr_carriers; bool support_ca; int mbms_service_id; uint32_t mbms_service_port; diff --git a/srsue/hdr/stack/rrc/rrc_meas.h b/srsue/hdr/stack/rrc/rrc_meas.h index b5bde4cdf8..792bec73f6 100644 --- a/srsue/hdr/stack/rrc/rrc_meas.h +++ b/srsue/hdr/stack/rrc/rrc_meas.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/rrc/rrc_metrics.h b/srsue/hdr/stack/rrc/rrc_metrics.h index 6c5901786b..783242e739 100644 --- a/srsue/hdr/stack/rrc/rrc_metrics.h +++ b/srsue/hdr/stack/rrc/rrc_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index efbc925a4c..031fd5f2c6 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/rrc/rrc_rlf_report.h b/srsue/hdr/stack/rrc/rrc_rlf_report.h index 666724d0ad..bed8eab7cc 100644 --- a/srsue/hdr/stack/rrc/rrc_rlf_report.h +++ b/srsue/hdr/stack/rrc/rrc_rlf_report.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/rrc/rrc_nr.h b/srsue/hdr/stack/rrc_nr/rrc_nr.h similarity index 65% rename from srsue/hdr/stack/rrc/rrc_nr.h rename to srsue/hdr/stack/rrc_nr/rrc_nr.h index 0bf8158c29..80e8936193 100644 --- a/srsue/hdr/stack/rrc/rrc_nr.h +++ b/srsue/hdr/stack/rrc_nr/rrc_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,7 +22,9 @@ #ifndef SRSUE_RRC_NR_H #define SRSUE_RRC_NR_H -#include "nr/rrc_nr_config.h" +#include "../rrc/rrc_cell.h" +#include "rrc_nr_config.h" +#include "rrc_nr_metrics.h" #include "srsran/adt/circular_map.h" #include "srsran/asn1/rrc_nr.h" #include "srsran/asn1/rrc_nr_utils.h" @@ -32,8 +34,10 @@ #include "srsran/common/stack_procedure.h" #include "srsran/common/task_scheduler.h" #include "srsran/interfaces/ue_interfaces.h" +#include "srsran/interfaces/ue_nas_interfaces.h" #include "srsran/interfaces/ue_nr_interfaces.h" #include "srsran/interfaces/ue_rrc_interfaces.h" +#include "srsran/interfaces/ue_sdap_interfaces.h" #include "srsue/hdr/stack/upper/gw.h" namespace srsue { @@ -42,13 +46,12 @@ class usim_interface_rrc_nr; class pdcp_interface_rrc; class rlc_interface_rrc; -struct rrc_nr_metrics_t {}; - class rrc_nr final : public rrc_interface_phy_nr, public rrc_interface_pdcp, public rrc_interface_rlc, public rrc_interface_mac, public rrc_nr_interface_rrc, + public rrc_nr_interface_nas_5g, public srsran::timer_callback { public: @@ -59,7 +62,9 @@ class rrc_nr final : public rrc_interface_phy_nr, mac_interface_rrc_nr* mac_, rlc_interface_rrc* rlc_, pdcp_interface_rrc* pdcp_, + sdap_interface_rrc* sdap_, gw_interface_rrc* gw_, + nas_5g_interface_rrc_nr* nas_, rrc_eutra_interface_rrc_nr* rrc_eutra_, usim_interface_rrc_nr* usim_, srsran::timer_handler* timers_, @@ -67,7 +72,6 @@ class rrc_nr final : public rrc_interface_phy_nr, const rrc_nr_args_t& args_); void stop(); - void init_core_less(); void get_metrics(rrc_nr_metrics_t& m); @@ -88,6 +92,9 @@ class rrc_nr final : public rrc_interface_phy_nr, asn1::dyn_octstring oct, const T& msg, const std::string& msg_type); + + void run_tti(uint32_t tti); + // PHY interface void in_sync() final; void out_of_sync() final; @@ -97,7 +104,6 @@ class rrc_nr final : public rrc_interface_phy_nr, void protocol_failure() final; // MAC interface - void run_tti(uint32_t tti) final; void ra_completed() final; void ra_problem() final; void release_pucch_srs() final; @@ -110,27 +116,54 @@ class rrc_nr final : public rrc_interface_phy_nr, void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) final; void notify_pdcp_integrity_error(uint32_t lcid) final; + // NAS interface + int write_sdu(srsran::unique_byte_buffer_t sdu); + bool is_connected(); + int connection_request(srsran::nr_establishment_cause_t cause, srsran::unique_byte_buffer_t sdu); + uint16_t get_mcc(); + uint16_t get_mnc(); + // RRC (LTE) interface int get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps); int get_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps); void phy_meas_stop(); void phy_set_cells_to_meas(uint32_t carrier_freq_r15); - bool rrc_reconfiguration(bool endc_release_and_add_r15, - bool nr_secondary_cell_group_cfg_r15_present, - asn1::dyn_octstring nr_secondary_cell_group_cfg_r15, - bool sk_counter_r15_present, - uint32_t sk_counter_r15, - bool nr_radio_bearer_cfg1_r15_present, - asn1::dyn_octstring nr_radio_bearer_cfg1_r15); + bool rrc_reconfiguration(bool endc_release_and_add_r15, const asn1::rrc_nr::rrc_recfg_s& rrc_nr_reconf); void rrc_release(); bool configure_sk_counter(uint16_t sk_counter); bool is_config_pending(); - // STACK interface - void cell_search_completed(const rrc_interface_phy_lte::cell_search_ret_t& cs_ret, const phy_cell_t& found_cell); + // STACK interface + void cell_search_found_cell(const rrc_interface_phy_nr::cell_search_result_t& result) final; + void cell_select_completed(const cell_select_result_t& result) final; void set_phy_config_complete(bool status) final; private: + // parsers + void decode_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu); + void decode_dl_ccch(srsran::unique_byte_buffer_t pdu); + void decode_dl_dcch(uint32_t lcid, srsran::unique_byte_buffer_t pdu); + // senders + void send_setup_request(srsran::nr_establishment_cause_t cause); + void send_con_setup_complete(srsran::unique_byte_buffer_t nas_msg); + void send_rrc_reconfig_complete(); + int send_ue_capability_info(const asn1::rrc_nr::ue_cap_enquiry_s& msg); + void send_ul_info_transfer(srsran::unique_byte_buffer_t nas_msg); + void send_ul_ccch_msg(const asn1::rrc_nr::ul_ccch_msg_s& msg); + void send_ul_dcch_msg(uint32_t lcid, const asn1::rrc_nr::ul_dcch_msg_s& msg); + void send_security_mode_complete(); + + // helpers + void set_phy_default_config(); + void handle_sib1(const asn1::rrc_nr::sib1_s& sib1); + bool handle_rrc_setup(const asn1::rrc_nr::rrc_setup_s& setup); + void handle_rrc_reconfig(const asn1::rrc_nr::rrc_recfg_s& reconfig); + void handle_ue_capability_enquiry(const asn1::rrc_nr::ue_cap_enquiry_s& ue_cap_enquiry); + void handle_dl_info_transfer(const asn1::rrc_nr::dl_info_transfer_s& dl_info_transfer); + void handle_security_mode_command(const asn1::rrc_nr::security_mode_cmd_s& smc); + void handle_rrc_release(const asn1::rrc_nr::rrc_release_s& rrc_release); + void generate_as_keys(); + srsran::task_sched_handle task_sched; struct cmd_msg_t { enum { PDU, PCCH, PDU_MCH, RLF, PDU_BCCH_DLSCH, STOP } command; @@ -149,31 +182,40 @@ class rrc_nr final : public rrc_interface_phy_nr, mac_interface_rrc_nr* mac = nullptr; rlc_interface_rrc* rlc = nullptr; pdcp_interface_rrc* pdcp = nullptr; + sdap_interface_rrc* sdap = nullptr; gw_interface_rrc* gw = nullptr; + nas_5g_interface_rrc_nr* nas = nullptr; rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr; usim_interface_rrc_nr* usim = nullptr; stack_interface_rrc* stack = nullptr; + meas_cell_list meas_cells; + + // PLMN + bool plmn_is_selected = false; + srsran::unique_byte_buffer_t dedicated_info_nas; + const uint32_t sim_measurement_timer_duration_ms = 250; uint32_t sim_measurement_carrier_freq_r15; srsran::timer_handler::unique_timer sim_measurement_timer; - /// RRC states (3GPP 38.331 v15.5.1 Sec 4.2.1) - enum rrc_nr_state_t { - RRC_NR_STATE_IDLE = 0, - RRC_NR_STATE_CONNECTED, - RRC_NR_STATE_CONNECTED_INACTIVE, - RRC_NR_STATE_N_ITEMS, - }; - const static char* rrc_nr_state_text[RRC_NR_STATE_N_ITEMS]; + rrc_nr_state_t state = RRC_NR_STATE_IDLE; - // rrc_nr_state_t state = RRC_NR_STATE_IDLE; + uint8_t transaction_id = 0; - // Stores the state of the PHy configuration setting + // RRC constants and timers + uint32_t n310_cnt = 0, N310 = 0; + uint32_t n311_cnt = 0, N311 = 0; + srsran::timer_handler::unique_timer t300, t301, t302, t310, t311, t304; + + // Stores the state of the PHY configuration setting enum { PHY_CFG_STATE_NONE = 0, - PHY_CFG_STATE_APPLY_SP_CELL, - PHY_CFG_STATE_RA_COMPLETED, + PHY_CFG_STATE_SA_MIB_CFG, + PHY_CFG_STATE_SA_SIB_CFG, + PHY_CFG_STATE_SA_FULL_CFG, + PHY_CFG_STATE_NSA_APPLY_SP_CELL, + PHY_CFG_STATE_NSA_RA_COMPLETED, } phy_cfg_state; rrc_nr_args_t args = {}; @@ -193,10 +235,12 @@ class rrc_nr final : public rrc_interface_phy_nr, std::map csi_rs_nzp_res; bool apply_cell_group_cfg(const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg); + bool update_cell_group_cfg(const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg); bool apply_radio_bearer_cfg(const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg); bool apply_rlc_add_mod(const asn1::rrc_nr::rlc_bearer_cfg_s& rlc_bearer_cfg); bool apply_mac_cell_group(const asn1::rrc_nr::mac_cell_group_cfg_s& mac_cell_group_cfg); bool apply_sp_cell_cfg(const asn1::rrc_nr::sp_cell_cfg_s& sp_cell_cfg); + bool update_sp_cell_cfg(const asn1::rrc_nr::sp_cell_cfg_s& sp_cell_cfg); bool apply_phy_cell_group_cfg(const asn1::rrc_nr::phys_cell_group_cfg_s& phys_cell_group_cfg); bool apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_common); bool apply_ul_common_cfg(const asn1::rrc_nr::ul_cfg_common_s& ul_cfg_common); @@ -206,40 +250,28 @@ class rrc_nr final : public rrc_interface_phy_nr, bool apply_sp_cell_ded_ul_pusch(const asn1::rrc_nr::pusch_cfg_s& pusch_cfg); bool apply_csi_meas_cfg(const asn1::rrc_nr::csi_meas_cfg_s& csi_meas_cfg); bool apply_res_csi_report_cfg(const asn1::rrc_nr::csi_report_cfg_s& csi_report_cfg); + bool apply_srb_add_mod(const asn1::rrc_nr::srb_to_add_mod_s& srb_cfg); bool apply_drb_add_mod(const asn1::rrc_nr::drb_to_add_mod_s& drb_cfg); bool apply_drb_release(const uint8_t drb); bool apply_security_cfg(const asn1::rrc_nr::security_cfg_s& security_cfg); + // Security configuration + bool security_is_activated = false; srsran::as_security_config_t sec_cfg; typedef enum { mcg_srb1, en_dc_srb3, nr } reconf_initiator_t; - class connection_reconf_no_ho_proc - { - public: - explicit connection_reconf_no_ho_proc(rrc_nr* parent_); - srsran::proc_outcome_t init(const reconf_initiator_t initiator_, - const bool endc_release_and_add_r15, - const bool nr_secondary_cell_group_cfg_r15_present, - const asn1::dyn_octstring nr_secondary_cell_group_cfg_r15, - const bool sk_counter_r15_present, - const uint32_t sk_counter_r15, - const bool nr_radio_bearer_cfg1_r15_present, - const asn1::dyn_octstring nr_radio_bearer_cfg1_r15); - srsran::proc_outcome_t step() { return srsran::proc_outcome_t::yield; } - static const char* name() { return "NR Connection Reconfiguration"; } - srsran::proc_outcome_t react(const bool& config_complete); - void then(const srsran::proc_state_t& result); - - private: - // const - rrc_nr* rrc_ptr; - reconf_initiator_t initiator; - asn1::rrc_nr::rrc_recfg_s rrc_recfg; - asn1::rrc_nr::cell_group_cfg_s cell_group_cfg; - }; - - srsran::proc_t conn_recfg_proc; + // RRC procedures + enum class rrc_cell_search_result_t { changed_cell, same_cell, no_cell }; + class cell_selection_proc; + class connection_setup_proc; + class connection_reconf_no_ho_proc; + class setup_request_proc; + + srsran::proc_t cell_selector; + srsran::proc_t conn_setup_proc; + srsran::proc_t conn_recfg_proc; + srsran::proc_t setup_req_proc; srsran::proc_manager_list_t callback_list; }; diff --git a/srsue/hdr/stack/rrc/nr/rrc_nr_config.h b/srsue/hdr/stack/rrc_nr/rrc_nr_config.h similarity index 60% rename from srsue/hdr/stack/rrc/nr/rrc_nr_config.h rename to srsue/hdr/stack/rrc_nr/rrc_nr_config.h index ac1f2aef03..ec23a1a264 100644 --- a/srsue/hdr/stack/rrc/nr/rrc_nr_config.h +++ b/srsue/hdr/stack/rrc_nr/rrc_nr_config.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -27,21 +27,19 @@ namespace srsue { -// Expert arguments to create GW without proper RRC -struct core_less_args_t { - std::string ip_addr; - uint8_t drb_lcid; -}; - struct rrc_nr_args_t { - core_less_args_t coreless; - uint32_t sim_nr_meas_pci; - bool pdcp_short_sn_support; - std::string supported_bands_nr_str; - std::vector supported_bands_nr; - std::vector supported_bands_eutra; - std::string log_level; - uint32_t log_hex_limit; + uint32_t sim_nr_meas_pci; + bool pdcp_short_sn_support; + std::string supported_bands_nr_str; + std::vector supported_bands_nr; + std::vector supported_bands_eutra; + uint32_t dl_nr_arfcn; + uint32_t ssb_nr_arfcn; + uint32_t nof_prb; + srsran_subcarrier_spacing_t scs; + srsran_subcarrier_spacing_t ssb_scs; + std::string log_level; + uint32_t log_hex_limit; }; } // namespace srsue diff --git a/srsue/hdr/stack/rrc_nr/rrc_nr_metrics.h b/srsue/hdr/stack/rrc_nr/rrc_nr_metrics.h new file mode 100644 index 0000000000..ebd7ff89e7 --- /dev/null +++ b/srsue/hdr/stack/rrc_nr/rrc_nr_metrics.h @@ -0,0 +1,41 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSUE_RRC_NR_METRICS_H +#define SRSUE_RRC_NR_METRICS_H + +namespace srsue { + +/// RRC states (3GPP 38.331 v15.5.1 Sec 4.2.1) +enum rrc_nr_state_t { + RRC_NR_STATE_IDLE = 0, + RRC_NR_STATE_CONNECTED, + RRC_NR_STATE_CONNECTED_INACTIVE, + RRC_NR_STATE_N_ITEMS, +}; + +struct rrc_nr_metrics_t { + rrc_nr_state_t state; +}; + +} // namespace srsue + +#endif // SRSUE_RRC_NR_METRICS_H diff --git a/srsue/hdr/stack/rrc_nr/rrc_nr_procedures.h b/srsue/hdr/stack/rrc_nr/rrc_nr_procedures.h new file mode 100644 index 0000000000..d7cc00345f --- /dev/null +++ b/srsue/hdr/stack/rrc_nr/rrc_nr_procedures.h @@ -0,0 +1,131 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/srslog/srslog.h" +#include "srsue/hdr/stack/rrc_nr/rrc_nr.h" + +#ifndef SRSRAN_RRC_NR_PROCEDURES_H +#define SRSRAN_RRC_NR_PROCEDURES_H + +namespace srsue { + +/******************************** + * Procedures + *******************************/ + +class rrc_nr::cell_selection_proc +{ +public: + enum class state_t { phy_cell_search, phy_cell_select, sib_acquire }; + + using cell_selection_complete_ev = srsran::proc_result_t; + explicit cell_selection_proc(rrc_nr& parent_); + srsran::proc_outcome_t init(); + srsran::proc_outcome_t step(); + srsran::proc_outcome_t react(const rrc_interface_phy_nr::cell_search_result_t& event); + srsran::proc_outcome_t react(const rrc_interface_phy_nr::cell_select_result_t& event); + srsran::proc_outcome_t react(const bool sib1_found); + + void then(const cell_selection_complete_ev& proc_result) const; + + rrc_cell_search_result_t get_result() const { return rrc_search_result; } + static const char* name() { return "Cell Selection"; } + +private: + srsran::proc_outcome_t handle_cell_search_result(const rrc_interface_phy_nr::cell_search_result_t& result); + + // conts + rrc_nr& rrc_handle; + + // state vars + rrc_interface_phy_nr::cell_search_result_t phy_search_result = {}; + rrc_cell_search_result_t rrc_search_result = {}; + state_t state; +}; + +class rrc_nr::setup_request_proc +{ +public: + explicit setup_request_proc(rrc_nr& parent_); + srsran::proc_outcome_t init(srsran::nr_establishment_cause_t cause_, + srsran::unique_byte_buffer_t dedicated_info_nas_); + srsran::proc_outcome_t step(); + void then(const srsran::proc_state_t& result); + srsran::proc_outcome_t react(const cell_selection_proc::cell_selection_complete_ev& e); + static const char* name() { return "Setup Request"; } + +private: + // const + rrc_nr& rrc_handle; + srslog::basic_logger& logger; + // args + srsran::nr_establishment_cause_t cause; + srsran::unique_byte_buffer_t dedicated_info_nas; + + // state variables + enum class state_t { cell_selection, config_serving_cell, wait_t300 } state; + rrc_cell_search_result_t cell_search_ret; + srsran::proc_future_t serv_cfg_fut; +}; + +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 step() { return srsran::proc_outcome_t::yield; } + static const char* name() { return "Connection Setup"; } + srsran::proc_outcome_t react(const bool& config_complete); + void then(const srsran::proc_state_t& result); + +private: + // const + rrc_nr& rrc_handle; + srslog::basic_logger& logger; + // args + srsran::unique_byte_buffer_t dedicated_info_nas; +}; + +class rrc_nr::connection_reconf_no_ho_proc +{ +public: + explicit connection_reconf_no_ho_proc(rrc_nr& parent_); + srsran::proc_outcome_t init(const reconf_initiator_t initiator_, + const bool endc_release_and_add_r15, + const asn1::rrc_nr::rrc_recfg_s& rrc_nr_reconf); + srsran::proc_outcome_t step() { return srsran::proc_outcome_t::yield; } + static const char* name() { return "NR Connection Reconfiguration"; } + srsran::proc_outcome_t react(const bool& config_complete); + void then(const srsran::proc_state_t& result); + +private: + // const + rrc_nr& rrc_handle; + reconf_initiator_t initiator; + asn1::rrc_nr::rrc_recfg_s rrc_recfg; + asn1::rrc_nr::cell_group_cfg_s cell_group_cfg; +}; + +} // namespace srsue + +#endif // SRSRAN_RRC_NR_PROCEDURES_H diff --git a/srsue/hdr/stack/ue_stack_base.h b/srsue/hdr/stack/ue_stack_base.h index 8bac5695d6..dede23c0f9 100644 --- a/srsue/hdr/stack/ue_stack_base.h +++ b/srsue/hdr/stack/ue_stack_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,8 +22,8 @@ #ifndef SRSUE_UE_STACK_BASE_H #define SRSUE_UE_STACK_BASE_H -#include "rrc/nr/rrc_nr_config.h" #include "rrc/rrc_config.h" +#include "rrc_nr/rrc_nr_config.h" #include "srsue/hdr/stack/upper/nas_config.h" #include "srsue/hdr/ue_metrics_interface.h" #include "upper/gw.h" @@ -71,9 +71,11 @@ typedef struct { rrc_nr_args_t rrc_nr; std::string ue_category_str; nas_args_t nas; + nas_5g_args_t nas_5g; gw_args_t gw; uint32_t sync_queue_size; // Max allowed difference between PHY and Stack clocks (in TTI) bool have_tti_time_stats; + bool sa_mode; } stack_args_t; class ue_stack_base diff --git a/srsue/hdr/stack/ue_stack_lte.h b/srsue/hdr/stack/ue_stack_lte.h index 144652656d..87eb8b1cb7 100644 --- a/srsue/hdr/stack/ue_stack_lte.h +++ b/srsue/hdr/stack/ue_stack_lte.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -29,7 +29,7 @@ #include "mac/mac.h" #include "mac_nr/mac_nr.h" #include "rrc/rrc.h" -#include "rrc/rrc_nr.h" +#include "rrc_nr/rrc_nr.h" #include "srsran/common/bearer_manager.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/multiqueue.h" @@ -44,6 +44,8 @@ #include "srsue/hdr/ue_metrics_interface.h" #include "ue_stack_base.h" #include "upper/nas.h" +#include "upper/nas_5g.h" +#include "upper/sdap.h" #include "upper/usim.h" #include #include @@ -54,6 +56,28 @@ namespace srsue { class phy_interface_stack_lte; +class sdap_pdcp_adapter : public pdcp_interface_sdap_nr, public gw_interface_pdcp +{ +public: + sdap_pdcp_adapter(pdcp* parent_pdcp_, sdap* parent_sdap_) : parent_pdcp(parent_pdcp_), parent_sdap(parent_sdap_) {} + void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) final + { + parent_pdcp->write_sdu(lcid, std::move(pdu)); + } + void write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) final + { + parent_sdap->write_pdu(lcid, std::move(pdu)); + } + void write_pdu_mch(uint32_t mch_idx, uint32_t lcid, srsran::unique_byte_buffer_t pdu) final + { + // not implemented + } + +private: + pdcp* parent_pdcp = nullptr; + sdap* parent_sdap = nullptr; +}; + class ue_stack_lte final : public ue_stack_base, public stack_interface_phy_lte, public stack_interface_phy_nr, @@ -121,19 +145,17 @@ class ue_stack_lte final : public ue_stack_base, mac.bch_decoded_ok(cc_idx, payload, len); } - void mch_decoded(uint32_t len, bool crc) final { mac.mch_decoded(len, crc); } - - void new_mch_dl(const srsran_pdsch_grant_t& phy_grant, mac_interface_phy_lte::tb_action_dl_t* action) final - { - mac.new_mch_dl(phy_grant, action); - } + void mch_decoded(uint32_t len, bool crc, uint8_t* payload) final { mac.mch_decoded(len, crc, payload); } void set_mbsfn_config(uint32_t nof_mbsfn_services) final { mac.set_mbsfn_config(nof_mbsfn_services); } void run_tti(uint32_t tti, uint32_t tti_jump) final; + // RRC interface for NR PHY + void cell_search_found_cell(const cell_search_result_t& result) final; + void cell_select_completed(const cell_select_result_t& result) final; + // MAC Interface for NR PHY - int sf_indication(const uint32_t tti) final { return SRSRAN_SUCCESS; } void tb_decoded(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, mac_interface_phy_nr::tb_action_dl_result_t result) final @@ -153,11 +175,6 @@ class ue_stack_lte final : public ue_stack_base, mac_nr.new_grant_ul(cc_idx, grant, action); } - void run_tti(const uint32_t tti) final - { - // ignored, timing will be handled by EUTRA - } - void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id) final { mac_nr.prach_sent(tti, s_id, t_id, f_id, ul_carrier_id); @@ -202,6 +219,7 @@ class ue_stack_lte final : public ue_stack_base, srslog::basic_logger& rrc_logger; srslog::basic_logger& usim_logger; srslog::basic_logger& nas_logger; + srslog::basic_logger& nas5g_logger; // UE NR stack logging srslog::basic_logger& mac_nr_logger; @@ -238,8 +256,13 @@ class ue_stack_lte final : public ue_stack_base, srsran::pdcp pdcp_nr; srsue::rrc_nr rrc_nr; srsue::nas nas; + srsue::nas_5g nas_5g; std::unique_ptr usim; + // SDAP only applies to NR + srsue::sdap sdap; + sdap_pdcp_adapter sdap_pdcp; + ue_bearer_manager bearers; // helper to manage mapping between EPS and radio bearers // Metrics helper diff --git a/srsue/hdr/stack/ue_stack_nr.h b/srsue/hdr/stack/ue_stack_nr.h index 10190d0d7c..3349a324fe 100644 --- a/srsue/hdr/stack/ue_stack_nr.h +++ b/srsue/hdr/stack/ue_stack_nr.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -32,6 +32,7 @@ #include "srsran/rlc/rlc.h" #include "srsran/upper/pdcp.h" #include "upper/nas.h" +#include "upper/sdap.h" #include "upper/usim.h" #include "srsran/common/buffer_pool.h" @@ -81,17 +82,15 @@ class ue_stack_nr final : public ue_stack_base, // RRC interface for PHY void in_sync() final; void out_of_sync() final; - void run_tti(const uint32_t tti) final; - void set_phy_config_complete(bool status) override; + void set_phy_config_complete(bool status) final; + void cell_search_found_cell(const cell_search_result_t& result) final; + + void run_tti(uint32_t tti, uint32_t tti_jump) final; // MAC interface for PHY sched_rnti_t get_dl_sched_rnti_nr(const uint32_t tti) final { return mac->get_dl_sched_rnti_nr(tti); } sched_rnti_t get_ul_sched_rnti_nr(const uint32_t tti) final { return mac->get_ul_sched_rnti_nr(tti); } - int sf_indication(const uint32_t tti) final - { - run_tti(tti); - return SRSRAN_SUCCESS; - } + void tb_decoded(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, tb_action_dl_result_t result) final { mac->tb_decoded(cc_idx, grant, std::move(result)); @@ -122,6 +121,7 @@ class ue_stack_nr final : public ue_stack_base, void add_eps_bearer(uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid) final {} void remove_eps_bearer(uint8_t eps_bearer_id) final {} void reset_eps_bearers() final {} + void cell_select_completed(const cell_select_result_t& result) override; private: void run_thread() final; @@ -145,6 +145,7 @@ class ue_stack_nr final : public ue_stack_base, std::unique_ptr rrc; std::unique_ptr rlc; std::unique_ptr pdcp; + std::unique_ptr sdap; // RAT-specific interfaces phy_interface_stack_nr* phy = nullptr; diff --git a/srsue/hdr/stack/upper/gw.h b/srsue/hdr/stack/upper/gw.h index 0ae9377d8c..6c66ebd934 100644 --- a/srsue/hdr/stack/upper/gw.h +++ b/srsue/hdr/stack/upper/gw.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -61,7 +61,7 @@ class gw : public gw_interface_stack, public srsran::thread // PDCP interface void write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu); - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu); + void write_pdu_mch(uint32_t mch_idx, uint32_t lcid, srsran::unique_byte_buffer_t pdu); // NAS interface int setup_if_addr(uint32_t eps_bearer_id, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char* err_str); diff --git a/srsue/hdr/stack/upper/gw_metrics.h b/srsue/hdr/stack/upper/gw_metrics.h index 8befc535bb..1c60b74eb5 100644 --- a/srsue/hdr/stack/upper/gw_metrics.h +++ b/srsue/hdr/stack/upper/gw_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index fb51f7504e..bf3fdaa69a 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -89,9 +89,9 @@ class nas : public nas_interface_rrc, public srsran::timer_callback, public nas_ void timer_expired(uint32_t timeout_id) override; private: - rrc_interface_nas* rrc = nullptr; - usim_interface_nas* usim = nullptr; - gw_interface_nas* gw = nullptr; + rrc_interface_nas* rrc = nullptr; + usim_interface_nas* usim = nullptr; + gw_interface_nas* gw = nullptr; bool running = false; @@ -117,10 +117,10 @@ class nas : public nas_interface_rrc, public srsran::timer_callback, public nas_ typedef std::pair eps_bearer_map_pair_t; eps_bearer_map_t eps_bearer; - bool have_guti = false; - bool have_ctxt = false; - bool auth_request = false; - uint8_t current_sec_hdr = LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS; + bool have_guti = false; + bool have_ctxt = false; + bool auth_request = false; + uint8_t current_sec_hdr = LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS; const uint32_t max_attach_attempts = 5; // Sec. 5.5.1.2.6 uint32_t attach_attempt_counter = 0; @@ -153,8 +153,8 @@ class nas : public nas_interface_rrc, public srsran::timer_callback, public nas_ const uint8_t ue_svn_oct2 = 0x3; // Security - bool eia_caps[8] = {}; - bool eea_caps[8] = {}; + bool eia_caps[8] = {}; + bool eea_caps[8] = {}; // Airplane mode simulation typedef enum { DISABLED = 0, ENABLED } airplane_mode_state_t; @@ -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.h b/srsue/hdr/stack/upper/nas_5g.h index a721da520f..5ada19eb54 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -66,7 +66,9 @@ class nas_5g : public nas_base, public nas_5g_interface_rrc_nr, public nas_5g_in void run_tti(); // Stack+RRC interface - bool is_registered(); + bool is_registered(); + int get_k_amf(srsran::as_key_t& k_amf); + uint32_t get_ul_nas_count(); int write_pdu(srsran::unique_byte_buffer_t pdu); @@ -88,8 +90,8 @@ class nas_5g : public nas_base, public nas_5g_interface_rrc_nr, public nas_5g_in usim_interface_nas* usim = nullptr; gw_interface_nas* gw = nullptr; - bool running = false; - + bool running = false; + bool has_sec_ctxt = false; bool initial_sec_command = false; srsran::nas_5g::mobile_identity_5gs_t::guti_5g_s guti_5g; @@ -102,6 +104,8 @@ class nas_5g : public nas_base, public nas_5g_interface_rrc_nr, public nas_5g_in bool ia5g_caps[8] = {}; bool ea5g_caps[8] = {}; + void set_k_gnb_count(uint32_t count); + // TS 23.003 Sec. 6.2.2 IMEISV's last two octets are Software Version Number (SVN) // which identifies the software version number of the mobile equipment const uint8_t ue_svn_oct1 = 0x5; @@ -155,6 +159,7 @@ class nas_5g : public nas_base, public nas_5g_interface_rrc_nr, public nas_5g_in void fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps); int apply_security_config(srsran::unique_byte_buffer_t& pdu, uint8_t sec_hdr_type); bool check_replayed_ue_security_capabilities(srsran::nas_5g::ue_security_capability_t& caps); + void set_nssai(srsran::nas_5g::s_nssai_t& s_nssai); // message handler int handle_registration_accept(srsran::nas_5g::registration_accept_t& registration_accept); diff --git a/srsue/hdr/stack/upper/nas_5g_metrics.h b/srsue/hdr/stack/upper/nas_5g_metrics.h index 73f29cc9f0..de6df2736a 100644 --- a/srsue/hdr/stack/upper/nas_5g_metrics.h +++ b/srsue/hdr/stack/upper/nas_5g_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/upper/nas_5g_procedures.h b/srsue/hdr/stack/upper/nas_5g_procedures.h index 5cea4304f1..f138abdf21 100644 --- a/srsue/hdr/stack/upper/nas_5g_procedures.h +++ b/srsue/hdr/stack/upper/nas_5g_procedures.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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/hdr/stack/upper/nas_5gmm_state.h b/srsue/hdr/stack/upper/nas_5gmm_state.h index be0b39233f..3a1a37f042 100644 --- a/srsue/hdr/stack/upper/nas_5gmm_state.h +++ b/srsue/hdr/stack/upper/nas_5gmm_state.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/upper/nas_base.h b/srsue/hdr/stack/upper/nas_base.h index a591925457..c5c8de4365 100644 --- a/srsue/hdr/stack/upper/nas_base.h +++ b/srsue/hdr/stack/upper/nas_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -69,6 +69,7 @@ class nas_base struct nas_5g_sec_ctxt { uint8_t ksi; uint8_t k_amf[32]; + uint32_t k_gnb_count; }; nas_sec_base_ctxt ctxt_base = {}; @@ -79,7 +80,7 @@ class nas_base // Security void - integrity_generate(uint8_t* key_128, uint32_t count, uint8_t direction, uint8_t* msg, uint32_t msg_len, uint8_t* mac); + integrity_generate(uint8_t* key_128, uint32_t count, uint8_t direction, uint8_t* msg, uint32_t msg_len, uint8_t* mac); bool integrity_check(srsran::byte_buffer_t* pdu); void cipher_encrypt(srsran::byte_buffer_t* pdu); void cipher_decrypt(srsran::byte_buffer_t* pdu); diff --git a/srsue/hdr/stack/upper/nas_config.h b/srsue/hdr/stack/upper/nas_config.h index 8400e21504..91014d0427 100644 --- a/srsue/hdr/stack/upper/nas_config.h +++ b/srsue/hdr/stack/upper/nas_config.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -67,6 +67,10 @@ class nas_5g_args_t std::string ia5g; std::string ea5g; std::vector pdu_session_cfgs; + // slicing configuration + bool enable_slicing; + int nssai_sst; + int nssai_sd; }; } // namespace srsue diff --git a/srsue/hdr/stack/upper/nas_emm_state.h b/srsue/hdr/stack/upper/nas_emm_state.h index 5d3aca1b4f..77f7e9f557 100644 --- a/srsue/hdr/stack/upper/nas_emm_state.h +++ b/srsue/hdr/stack/upper/nas_emm_state.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/upper/nas_idle_procedures.h b/srsue/hdr/stack/upper/nas_idle_procedures.h index 5c556ce92a..cd1b7fa6ae 100644 --- a/srsue/hdr/stack/upper/nas_idle_procedures.h +++ b/srsue/hdr/stack/upper/nas_idle_procedures.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/upper/nas_metrics.h b/srsue/hdr/stack/upper/nas_metrics.h index 3508a5edac..893acec45f 100644 --- a/srsue/hdr/stack/upper/nas_metrics.h +++ b/srsue/hdr/stack/upper/nas_metrics.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/upper/pcsc_usim.h b/srsue/hdr/stack/upper/pcsc_usim.h index cb077a5fd8..886dfab50e 100644 --- a/srsue/hdr/stack/upper/pcsc_usim.h +++ b/srsue/hdr/stack/upper/pcsc_usim.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/upper/sdap.h b/srsue/hdr/stack/upper/sdap.h new file mode 100644 index 0000000000..81e38dd37e --- /dev/null +++ b/srsue/hdr/stack/upper/sdap.h @@ -0,0 +1,65 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSUE_SDAP_H +#define SRSUE_SDAP_H + +#include "srsran/common/buffer_pool.h" +#include "srsran/common/common.h" +#include "srsran/common/common_nr.h" +#include "srsran/interfaces/ue_gw_interfaces.h" +#include "srsran/interfaces/ue_pdcp_interfaces.h" +#include "srsran/interfaces/ue_sdap_interfaces.h" + +namespace srsue { + +class sdap final : public sdap_interface_pdcp_nr, public sdap_interface_gw_nr, public sdap_interface_rrc +{ +public: + explicit sdap(const char* logname); + bool init(pdcp_interface_sdap_nr* pdcp_, srsue::gw_interface_pdcp* gw_); + void stop(); + + // Interface for GW + void write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) final; + + // Interface for PDCP + void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) final; + + // Interface for RRC + bool set_bearer_cfg(uint32_t lcid, const sdap_interface_rrc::bearer_cfg_t& cfg) final; + +private: + pdcp_interface_sdap_nr* m_pdcp = nullptr; + gw_interface_pdcp* m_gw = nullptr; + + // state + bool running = false; + + // configuration + std::array bearers = {}; + + srslog::basic_logger& logger; +}; + +} // namespace srsue + +#endif // SRSUE_SDAP_H diff --git a/srsue/hdr/stack/upper/test/nas_test_common.h b/srsue/hdr/stack/upper/test/nas_test_common.h index 98cb28adf2..b9beecb812 100644 --- a/srsue/hdr/stack/upper/test/nas_test_common.h +++ b/srsue/hdr/stack/upper/test/nas_test_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -216,10 +216,10 @@ class gw_dummy : public gw_interface_nas, public gw_interface_pdcp return SRSRAN_SUCCESS; } void write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) {} - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} + void write_pdu_mch(uint32_t mch_idx, uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} void set_test_loop_mode(const test_loop_mode_state_t mode, const uint32_t ip_pdu_delay_ms = 0) {} }; } // namespace srsran -#endif // SRSUE_NAS_TEST_COMMON \ No newline at end of file +#endif // SRSUE_NAS_TEST_COMMON diff --git a/srsue/hdr/stack/upper/tft_packet_filter.h b/srsue/hdr/stack/upper/tft_packet_filter.h index 5fd729fdce..de08712a7a 100644 --- a/srsue/hdr/stack/upper/tft_packet_filter.h +++ b/srsue/hdr/stack/upper/tft_packet_filter.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/upper/usim.h b/srsue/hdr/stack/upper/usim.h index 6645c110c5..dece9189d6 100644 --- a/srsue/hdr/stack/upper/usim.h +++ b/srsue/hdr/stack/upper/usim.h @@ -1,5 +1,5 @@ īģŋ/** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/hdr/stack/upper/usim_base.h b/srsue/hdr/stack/upper/usim_base.h index d72dccf879..e1b80c748d 100644 --- a/srsue/hdr/stack/upper/usim_base.h +++ b/srsue/hdr/stack/upper/usim_base.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -106,6 +106,7 @@ class usim_base : public usim_interface_nas, public usim_interface_rrc, public u void restore_keys_from_failed_ho(srsran::as_security_config_t* as_ctx) final; // NR RRC interface + void generate_nr_as_keys(srsran::as_key_t& k_amf, uint32_t count_ul, srsran::as_security_config_t* sec_cfg) final; bool generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) final; bool update_nr_context(srsran::as_security_config_t* sec_cfg) final; @@ -149,6 +150,8 @@ class usim_base : public usim_interface_nas, public usim_interface_rrc, public u uint8_t k_enb_initial[KEY_LEN] = {}; uint8_t auts[AKA_AUTS_LEN] = {}; + srsran::as_key_t k_gnb_initial = {}; + // Current K_eNB context (K_eNB, NH and NCC) srsran::k_enb_context_t k_enb_ctx = {}; srsran::k_gnb_context_t k_gnb_ctx = {}; diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 12d9667b50..3918f3107f 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -114,6 +114,7 @@ class ue : public ue_metrics_interface private: // UE consists of a radio, a PHY and a stack element std::unique_ptr phy; + std::unique_ptr dummy_phy; std::unique_ptr radio; std::unique_ptr stack; std::unique_ptr gw_inst; diff --git a/srsue/hdr/ue_metrics_interface.h b/srsue/hdr/ue_metrics_interface.h index e11fb996a0..2c95a941cc 100644 --- a/srsue/hdr/ue_metrics_interface.h +++ b/srsue/hdr/ue_metrics_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -31,6 +31,7 @@ #include "srsran/system/sys_metrics.h" #include "stack/mac/mac_metrics.h" #include "stack/rrc/rrc_metrics.h" +#include "stack/rrc_nr/rrc_nr_metrics.h" #include "stack/upper/gw_metrics.h" #include "stack/upper/nas_metrics.h" @@ -43,7 +44,7 @@ typedef struct { srsran::rlc_metrics_t rlc; nas_metrics_t nas; rrc_metrics_t rrc; - rrc_metrics_t rrc_nr; + rrc_nr_metrics_t rrc_nr; } stack_metrics_t; typedef struct { diff --git a/srsue/src/CMakeLists.txt b/srsue/src/CMakeLists.txt index e856c02708..7c0f99ed20 100644 --- a/srsue/src/CMakeLists.txt +++ b/srsue/src/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -76,4 +76,4 @@ else(NOT ${BUILDUE_CMD} STREQUAL "") message(STATUS "No post-build-UE command defined") endif (NOT ${BUILDUE_CMD} STREQUAL "") -install(TARGETS srsue DESTINATION ${RUNTIME_DIR}) +install(TARGETS srsue DESTINATION ${RUNTIME_DIR} OPTIONAL) diff --git a/srsue/src/main.cc b/srsue/src/main.cc index b41c321673..c60584d90e 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -68,7 +68,9 @@ string config_file; static int parse_args(all_args_t* args, int argc, char* argv[]) { - bool use_standard_lte_rates = false; + bool use_standard_lte_rates = false; + std::string scs_khz, ssb_scs_khz; // temporary value to store integer + std::string cfr_mode; // Command line only options bpo::options_description general("General options"); @@ -131,9 +133,14 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) ("rat.eutra.ul_freq", bpo::value(&args->phy.ul_freq)->default_value(-1), "Uplink Frequency (if positive overrides EARFCN)") ("rat.eutra.nof_carriers", bpo::value(&args->phy.nof_lte_carriers)->default_value(1), "Number of carriers") - ("rat.nr.bands", bpo::value(&args->stack.rrc_nr.supported_bands_nr_str)->default_value("78"), "Supported NR bands") + ("rat.nr.bands", bpo::value(&args->stack.rrc_nr.supported_bands_nr_str)->default_value("3"), "Supported NR bands") ("rat.nr.nof_carriers", bpo::value(&args->phy.nof_nr_carriers)->default_value(0), "Number of NR carriers") - ("rat.nr.max_nof_prb", bpo::value(&args->phy.nr_max_nof_prb)->default_value(106), "Maximum NR carrier bandwidth in PRB") + ("rat.nr.max_nof_prb", bpo::value(&args->phy.nr_max_nof_prb)->default_value(52), "Maximum NR carrier bandwidth in PRB") + ("rat.nr.dl_nr_arfcn", bpo::value(&args->stack.rrc_nr.dl_nr_arfcn)->default_value(368500), "DL ARFCN of NR cell") + ("rat.nr.ssb_nr_arfcn", bpo::value(&args->stack.rrc_nr.ssb_nr_arfcn)->default_value(368410), "SSB ARFCN of NR cell") + ("rat.nr.nof_prb", bpo::value(&args->stack.rrc_nr.nof_prb)->default_value(52), "Actual NR carrier bandwidth in PRB") + ("rat.nr.scs", bpo::value(&scs_khz)->default_value("15"), "PDSCH subcarrier spacing in kHz") + ("rat.nr.ssb_scs", bpo::value(&ssb_scs_khz)->default_value("15"), "SSB subcarrier spacing in kHz") ("rrc.feature_group", bpo::value(&args->stack.rrc.feature_group)->default_value(0xe6041000), "Hex value of the featureGroupIndicators field in the" "UECapabilityInformation message. Default 0xe6041000") @@ -154,6 +161,10 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) ("nas.eia", bpo::value(&args->stack.nas.eia)->default_value("1,2,3"), "List of integrity algorithms included in UE capabilities") ("nas.eea", bpo::value(&args->stack.nas.eea)->default_value("0,1,2,3"), "List of ciphering algorithms included in UE capabilities") + ("slicing.enable", bpo::value(&args->stack.nas_5g.enable_slicing)->default_value(false), "enable slicing in the UE") + ("slicing.nssai-sst", bpo::value(&args->stack.nas_5g.nssai_sst)->default_value(1), "sst of requested slice") + ("slicing.nssai-sd", bpo::value(&args->stack.nas_5g.nssai_sd)->default_value(1), "sd of requested slice") + ("pcap.enable", bpo::value(&args->stack.pkt_trace.enable)->default_value("none"), "Enable (MAC, MAC_NR, NAS) packet captures for wireshark") ("pcap.mac_filename", bpo::value(&args->stack.pkt_trace.mac_pcap.filename)->default_value("/tmp/ue_mac.pcap"), "MAC layer capture filename") ("pcap.mac_nr_filename", bpo::value(&args->stack.pkt_trace.mac_nr_pcap.filename)->default_value("/tmp/ue_mac_nr.pcap"), "MAC_NR layer capture filename") @@ -242,6 +253,14 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) ("channel.ul.hst.fd_hz", bpo::value(&args->phy.ul_channel_args.hst_fd_hz)->default_value(+750.0f), "Doppler frequency in Hz") ("channel.ul.hst.init_time_s", bpo::value(&args->phy.ul_channel_args.hst_init_time_s)->default_value(0), "Initial time in seconds") + /* CFR section */ + ("cfr.enable", bpo::value(&args->phy.cfr_args.enable)->default_value(args->phy.cfr_args.enable), "CFR enable") + ("cfr.mode", bpo::value(&cfr_mode)->default_value("manual"), "CFR mode") + ("cfr.manual_thres", bpo::value(&args->phy.cfr_args.manual_thres)->default_value(args->phy.cfr_args.manual_thres), "Fixed manual clipping threshold for CFR manual mode") + ("cfr.strength", bpo::value(&args->phy.cfr_args.strength)->default_value(args->phy.cfr_args.strength), "CFR ratio between amplitude-limited vs original signal (0 to 1)") + ("cfr.auto_target_papr", bpo::value(&args->phy.cfr_args.auto_target_papr)->default_value(args->phy.cfr_args.auto_target_papr), "Signal PAPR target (in dB) in CFR auto modes") + ("cfr.ema_alpha", bpo::value(&args->phy.cfr_args.ema_alpha)->default_value(args->phy.cfr_args.ema_alpha), "Alpha coefficient for the power average in auto_ema mode (0 to 1)") + /* PHY section */ ("phy.worker_cpu_mask", bpo::value(&args->phy.worker_cpu_mask)->default_value(-1), @@ -418,6 +437,10 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) bpo::value(&args->phy.force_N_id_2)->default_value(-1), "Force using a specific PSS (set to -1 to allow all PSSs).") + ("phy.force_N_id_1", + bpo::value(&args->phy.force_N_id_1)->default_value(-1), + "Force using a specific SSS (set to -1 to allow all SSSs).") + // PHY NR args ("phy.nr.store_pdsch_ko", bpo::value(&args->phy.nr_store_pdsch_ko)->default_value(false), @@ -477,10 +500,6 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) bpo::value(&args->stack.have_tti_time_stats)->default_value(true), "Calculate TTI execution statistics") - // NR params - ("vnf.type", bpo::value(&args->phy.vnf_args.type)->default_value("ue"), "VNF instance type [gnb,ue]") - ("vnf.addr", bpo::value(&args->phy.vnf_args.bind_addr)->default_value("localhost"), "Address to bind VNF interface") - ("vnf.port", bpo::value(&args->phy.vnf_args.bind_port)->default_value(3334), "Bind port") ; // Positional options - config file location @@ -551,6 +570,13 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) args->stack.usim.using_op = vm.count("usim.op"); } + // parse the CFR mode string + args->phy.cfr_args.mode = srsran_cfr_str2mode(cfr_mode.c_str()); + if (args->phy.cfr_args.mode == SRSRAN_CFR_THR_INVALID) { + cout << "Error, invalid CFR mode: " << cfr_mode << endl; + exit(1); + } + // Apply all_level to any unset layers if (vm.count("log.all_level")) { if (!vm.count("log.rf_level")) { @@ -629,6 +655,14 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) srsran_use_standard_symbol_size(use_standard_lte_rates); + args->stack.rrc_nr.scs = srsran_subcarrier_spacing_from_str(scs_khz.c_str()); + args->stack.rrc_nr.ssb_scs = srsran_subcarrier_spacing_from_str(ssb_scs_khz.c_str()); + if (args->stack.rrc_nr.scs == srsran_subcarrier_spacing_invalid || + args->stack.rrc_nr.ssb_scs == srsran_subcarrier_spacing_invalid) { + cout << "Invalid subcarrier spacing config" << endl; + return SRSRAN_ERROR; + } + return SRSRAN_SUCCESS; } diff --git a/srsue/src/metrics_csv.cc b/srsue/src/metrics_csv.cc index c121c06c9f..f6cfbc277e 100644 --- a/srsue/src/metrics_csv.cc +++ b/srsue/src/metrics_csv.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/metrics_json.cc b/srsue/src/metrics_json.cc index 4dd5267bf1..fd320f3dab 100644 --- a/srsue/src/metrics_json.cc +++ b/srsue/src/metrics_json.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/metrics_stdout.cc b/srsue/src/metrics_stdout.cc index 901cbd5611..87f146d107 100644 --- a/srsue/src/metrics_stdout.cc +++ b/srsue/src/metrics_stdout.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -190,7 +190,7 @@ void metrics_stdout::set_metrics(const ue_metrics_t& metrics, const uint32_t per return; } - if (metrics.stack.rrc.state != RRC_STATE_CONNECTED) { + if (metrics.stack.rrc.state != RRC_STATE_CONNECTED && metrics.stack.rrc_nr.state != RRC_NR_STATE_CONNECTED) { fmt::print("--- disconnected ---\n"); return; } @@ -202,25 +202,30 @@ void metrics_stdout::set_metrics(const ue_metrics_t& metrics, const uint32_t per display_neighbours |= metrics.stack.rrc.neighbour_cells.size() > 0; } - bool is_nr = metrics.phy_nr.nof_active_cc > 0; + bool has_lte = metrics.phy.nof_active_cc > 0; + bool has_nr = metrics.phy_nr.nof_active_cc > 0; // print table header every 10 reports if (++n_reports > 10) { - print_table(display_neighbours, is_nr); + print_table(display_neighbours, has_nr); } // also print table header if neighbours are added/removed in between if (display_neighbours != table_has_neighbours) { - print_table(display_neighbours, is_nr); + print_table(display_neighbours, has_nr); } - for (uint32_t r = 0; r < metrics.phy.nof_active_cc; r++) { - set_metrics_helper(metrics.phy, metrics.stack.mac, metrics.stack.rrc, display_neighbours, r, false, !is_nr); + if (has_lte) { + for (uint32_t r = 0; r < metrics.phy.nof_active_cc; r++) { + set_metrics_helper(metrics.phy, metrics.stack.mac, metrics.stack.rrc, display_neighbours, r, false, !has_nr); + } } - for (uint32_t r = 0; r < metrics.phy_nr.nof_active_cc; r++) { - // Assumption LTE is followed by the NR carriers. - set_metrics_helper(metrics.phy_nr, metrics.stack.mac_nr, metrics.stack.rrc, display_neighbours, r, true, !is_nr); + if (has_nr) { + for (uint32_t r = 0; r < metrics.phy_nr.nof_active_cc; r++) { + // Assumption LTE is followed by the NR carriers. + set_metrics_helper(metrics.phy_nr, metrics.stack.mac_nr, metrics.stack.rrc, display_neighbours, r, true, !has_nr); + } } if (metrics.rf.rf_error) { diff --git a/srsue/src/phy/CMakeLists.txt b/srsue/src/phy/CMakeLists.txt index de32016328..6f99f7235d 100644 --- a/srsue/src/phy/CMakeLists.txt +++ b/srsue/src/phy/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/src/phy/lte/cc_worker.cc b/srsue/src/phy/lte/cc_worker.cc index 7a767e90f7..5f656d8cf1 100644 --- a/srsue/src/phy/lte/cc_worker.cc +++ b/srsue/src/phy/lte/cc_worker.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -56,6 +56,8 @@ cc_worker::cc_worker(uint32_t cc_idx_, uint32_t max_prb, srsue::phy_common* phy_ cc_idx = cc_idx_; phy = phy_; + srsran_cfr_cfg_t cfr_config = phy->get_cfr_config(); + signal_buffer_max_samples = 3 * SRSRAN_SF_LEN_PRB(max_prb); for (uint32_t i = 0; i < phy->args->nof_rx_ant; i++) { @@ -81,6 +83,11 @@ cc_worker::cc_worker(uint32_t cc_idx_, uint32_t max_prb, srsue::phy_common* phy_ return; } + if (srsran_ue_ul_set_cfr(&ue_ul, &cfr_config) < SRSRAN_SUCCESS) { + Error("Setting the CFR"); + return; + } + phy->set_ue_dl_cfg(&ue_dl_cfg); phy->set_ue_ul_cfg(&ue_ul_cfg); phy->set_pdsch_cfg(&ue_dl_cfg.cfg.pdsch); @@ -94,6 +101,7 @@ cc_worker::cc_worker(uint32_t cc_idx_, uint32_t max_prb, srsue::phy_common* phy_ chest_default_cfg = ue_dl_cfg.chest_cfg; + srsran_softbuffer_rx_init(&mch_softbuffer, 100); // Set default PHY params reset(); @@ -113,6 +121,7 @@ cc_worker::~cc_worker() free(signal_buffer_rx[i]); } } + srsran_softbuffer_rx_free(&mch_softbuffer); srsran_ue_dl_free(&ue_dl); srsran_ue_ul_free(&ue_ul); } @@ -258,24 +267,29 @@ bool cc_worker::work_dl_regular() // If found a dci for this carrier, generate a grant, pass it to MAC and decode the associated PDSCH if (has_dl_grant) { - // Read last TB from last retx for this pid - for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { - ue_dl_cfg.cfg.pdsch.grant.last_tbs[i] = phy->last_dl_tbs[dci_dl.pid][cc_idx][i]; - } - // Generate PHY grant - if (srsran_ue_dl_dci_to_pdsch_grant(&ue_dl, &sf_cfg_dl, &ue_dl_cfg, &dci_dl, &ue_dl_cfg.cfg.pdsch.grant)) { - Info("Converting DCI message to DL dci"); - return false; - } - - // Save TB for next retx - for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { - phy->last_dl_tbs[dci_dl.pid][cc_idx][i] = ue_dl_cfg.cfg.pdsch.grant.last_tbs[i]; - } + // PDCCH order has no associated PDSCH to decode + if (not dci_dl.is_pdcch_order) { + // Read last TB from last retx for this pid + for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { + ue_dl_cfg.cfg.pdsch.grant.last_tbs[i] = phy->last_dl_tbs[dci_dl.pid][cc_idx][i]; + } + // Generate PHY grant + if (srsran_ue_dl_dci_to_pdsch_grant(&ue_dl, &sf_cfg_dl, &ue_dl_cfg, &dci_dl, &ue_dl_cfg.cfg.pdsch.grant)) { + Info("Converting DCI message to DL dci"); + return false; + } - // Set RNTI - ue_dl_cfg.cfg.pdsch.rnti = dci_dl.rnti; + // Save TB for next retx + for (uint32_t i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { + phy->last_dl_tbs[dci_dl.pid][cc_idx][i] = ue_dl_cfg.cfg.pdsch.grant.last_tbs[i]; + } + // Set RNTI + ue_dl_cfg.cfg.pdsch.rnti = dci_dl.rnti; + } else { + ue_dl_cfg.cfg.pdsch.rnti = dci_dl.rnti; + ue_dl_cfg.cfg.pdsch.grant.tb[0].tbs = 0; + } // Generate MAC grant mac_interface_phy_lte::mac_grant_dl_t mac_grant = {}; dl_phy_to_mac_grant(&ue_dl_cfg.cfg.pdsch.grant, &dci_dl, &mac_grant); @@ -341,12 +355,12 @@ bool cc_worker::work_dl_mbsfn(srsran_mbsfn_cfg_t mbsfn_cfg) srsran_ra_dl_compute_nof_re(&cell, &sf_cfg_dl, &pmch_cfg.pdsch_cfg.grant); // Send grant to MAC and get action for this TB, then call tb_decoded to unlock MAC - phy->stack->new_mch_dl(pmch_cfg.pdsch_cfg.grant, &dl_action); + new_mch_dl(&dl_action); bool mch_decoded = true; if (!decode_pmch(&dl_action, &mbsfn_cfg)) { mch_decoded = false; } - phy->stack->mch_decoded((uint32_t)pmch_cfg.pdsch_cfg.grant.tb[0].tbs / 8, mch_decoded); + phy->stack->mch_decoded((uint32_t)pmch_cfg.pdsch_cfg.grant.tb[0].tbs / 8, mch_decoded, mch_payload_buffer); } else if (mbsfn_cfg.is_mcch) { // release lock in phy_common phy->set_mch_period_stop(0); @@ -363,9 +377,14 @@ void cc_worker::dl_phy_to_mac_grant(srsran_pdsch_grant_t* srsue::mac_interface_phy_lte::mac_grant_dl_t* mac_grant) { /* Fill MAC dci structure */ - mac_grant->pid = dl_dci->pid; - mac_grant->rnti = dl_dci->rnti; - mac_grant->tti = CURRENT_TTI; + mac_grant->pid = dl_dci->pid; + mac_grant->rnti = dl_dci->rnti; + mac_grant->tti = CURRENT_TTI; + mac_grant->is_pdcch_order = dl_dci->is_pdcch_order; + if (dl_dci->is_pdcch_order) { + mac_grant->preamble_idx = dl_dci->preamble_idx; + mac_grant->prach_mask_idx = dl_dci->prach_mask_idx; + } for (int i = 0; i < SRSRAN_MAX_CODEWORDS; i++) { mac_grant->tb[i].ndi = dl_dci->tb[i].ndi; @@ -912,5 +931,14 @@ int cc_worker::read_pdsch_d(cf_t* pdsch_d) return ue_dl_cfg.cfg.pdsch.grant.nof_re; } +void cc_worker::new_mch_dl(mac_interface_phy_lte::tb_action_dl_t* action) +{ + action->generate_ack = false; + action->tb[0].enabled = true; + action->tb[0].payload = mch_payload_buffer; + action->tb[0].softbuffer.rx = &mch_softbuffer; + srsran_softbuffer_rx_reset_cb(&mch_softbuffer, 1); +} + } // namespace lte } // namespace srsue diff --git a/srsue/src/phy/lte/sf_worker.cc b/srsue/src/phy/lte/sf_worker.cc index ec623b36c1..c09e422862 100644 --- a/srsue/src/phy/lte/sf_worker.cc +++ b/srsue/src/phy/lte/sf_worker.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/phy/lte/worker_pool.cc b/srsue/src/phy/lte/worker_pool.cc index 6081c292c6..78ab8efd0a 100644 --- a/srsue/src/phy/lte/worker_pool.cc +++ b/srsue/src/phy/lte/worker_pool.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index c04ce63e07..4c69d5dc52 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -54,6 +54,7 @@ cc_worker::cc_worker(uint32_t cc_idx_, srslog::basic_logger& log, state& phy_sta srsran_ssb_args_t ssb_args = {}; ssb_args.enable_measure = true; ssb_args.enable_decode = true; + ssb_args.enable_search = true; if (srsran_ssb_init(&ssb, &ssb_args) < SRSRAN_SUCCESS) { ERROR("Error initiating SSB"); return; @@ -165,6 +166,14 @@ void cc_worker::decode_pdcch_dl() logger.info("PDCCH: cc=%d, %s", cc_idx, str.data()); } + if (logger.debug.enabled()) { + // log coreset info + srsran_coreset_t* coreset = &ue_dl.cfg.coreset[dci_rx[i].ctx.coreset_id]; + std::array coreset_str; + srsran_coreset_to_str(coreset, coreset_str.data(), coreset_str.size()); + logger.info("PDCCH: coreset=%d, %s", cc_idx, coreset_str.data()); + } + // Enqueue UL grants phy.set_dl_pending_grant(cfg, dl_slot_cfg, dci_rx[i]); } @@ -196,15 +205,15 @@ void cc_worker::decode_pdcch_ul() } // Search for grants - int n_dl = + int n_ul = srsran_ue_dl_nr_find_ul_dci(&ue_dl, &dl_slot_cfg, rnti.id, rnti.type, dci_rx.data(), (uint32_t)dci_rx.size()); - if (n_dl < SRSRAN_SUCCESS) { + if (n_ul < SRSRAN_SUCCESS) { logger.error("Error decoding UL NR-PDCCH"); return; } // Iterate over all received grants - for (int i = 0; i < n_dl; i++) { + for (int i = 0; i < n_ul; i++) { // Log found DCI if (logger.info.enabled()) { std::array str; @@ -396,6 +405,7 @@ bool cc_worker::measure_csi() logger.error("PBCH-MIB: NR SFN (%d) does not match current SFN (%d)", mib.sfn, dl_slot_cfg.idx / SRSRAN_NSLOTS_PER_FRAME_NR(cfg.carrier.scs)); + dl_slot_cfg.idx = mib.sfn * SRSRAN_NSLOTS_PER_FRAME_NR(cfg.carrier.scs); } // Log MIB information @@ -671,7 +681,7 @@ bool cc_worker::work_ul() } else if (srsran_uci_nr_total_bits(&uci_data.cfg) > 0) { // Get PUCCH resource srsran_pucch_nr_resource_t resource = {}; - if (srsran_ra_ul_nr_pucch_resource(&cfg.pucch, &uci_data.cfg, &resource) < SRSRAN_SUCCESS) { + if (srsran_ra_ul_nr_pucch_resource(&cfg.pucch, &uci_data.cfg, cfg.carrier.nof_prb, &resource) < SRSRAN_SUCCESS) { ERROR("Selecting PUCCH resource"); return false; } diff --git a/srsue/src/phy/nr/cell_search.cc b/srsue/src/phy/nr/cell_search.cc new file mode 100644 index 0000000000..dc1ef54528 --- /dev/null +++ b/srsue/src/phy/nr/cell_search.cc @@ -0,0 +1,99 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsue/hdr/phy/nr/cell_search.h" +#include "srsran/common/band_helper.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/radio/rf_buffer.h" +#include "srsran/radio/rf_timestamp.h" + +namespace srsue { +namespace nr { +cell_search::cell_search(srslog::basic_logger& logger_) : logger(logger_) {} + +cell_search::~cell_search() +{ + srsran_ssb_free(&ssb); +} + +bool cell_search::init(const args_t& args) +{ + // Prepare SSB initialization arguments + srsran_ssb_args_t ssb_args = {}; + ssb_args.max_srate_hz = args.max_srate_hz; + ssb_args.min_scs = args.ssb_min_scs; + ssb_args.enable_search = true; + ssb_args.enable_decode = true; + + // Initialise SSB + if (srsran_ssb_init(&ssb, &ssb_args) < SRSRAN_SUCCESS) { + logger.error("Cell search: Error initiating SSB"); + return false; + } + + return true; +} + +bool cell_search::start(const cfg_t& cfg) +{ + // Prepare SSB configuration + srsran_ssb_cfg_t ssb_cfg = {}; + ssb_cfg.srate_hz = cfg.srate_hz; + ssb_cfg.center_freq_hz = cfg.center_freq_hz; + ssb_cfg.ssb_freq_hz = cfg.ssb_freq_hz; + ssb_cfg.scs = cfg.ssb_scs; + ssb_cfg.pattern = cfg.ssb_pattern; + ssb_cfg.duplex_mode = cfg.duplex_mode; + + // Print SSB configuration, helps debugging gNb and UE + if (logger.info.enabled()) { + std::array ssb_cfg_str = {}; + srsran_ssb_cfg_to_str(&ssb_cfg, ssb_cfg_str.data(), (uint32_t)ssb_cfg_str.size()); + logger.info("Cell search: Setting SSB configuration %s", ssb_cfg_str.data()); + } + + // Configure SSB + if (srsran_ssb_set_cfg(&ssb, &ssb_cfg) < SRSRAN_SUCCESS) { + logger.error("Cell search: Error setting SSB configuration"); + return false; + } + return true; +} + +cell_search::ret_t cell_search::run_slot(const cf_t* buffer, uint32_t slot_sz) +{ + cell_search::ret_t ret = {}; + + // Search for SSB + if (srsran_ssb_search(&ssb, buffer, slot_sz + ssb.ssb_sz, &ret.ssb_res) < SRSRAN_SUCCESS) { + logger.error("Error occurred searching SSB"); + ret.result = ret_t::ERROR; + } else if (ret.ssb_res.measurements.snr_dB >= -10.0f and ret.ssb_res.pbch_msg.crc) { + // Consider the SSB is found and decoded if the PBCH CRC matched + ret.result = ret_t::CELL_FOUND; + } else { + ret.result = ret_t::CELL_NOT_FOUND; + } + return ret; +} + +} // namespace nr +} // namespace srsue diff --git a/srsue/src/phy/nr/sf_worker.cc b/srsue/src/phy/nr/sf_worker.cc index 6983a9ef1f..fbba2d027b 100644 --- a/srsue/src/phy/nr/sf_worker.cc +++ b/srsue/src/phy/nr/sf_worker.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -74,7 +74,6 @@ uint32_t sf_worker::get_buffer_len() void sf_worker::set_context(const srsran::phy_common_interface::worker_context_t& w_ctx) { - tti_rx = w_ctx.sf_idx; logger.set_context(w_ctx.sf_idx); for (auto& w : cc_workers) { w->set_tti(w_ctx.sf_idx); diff --git a/srsue/src/phy/nr/slot_sync.cc b/srsue/src/phy/nr/slot_sync.cc new file mode 100644 index 0000000000..302822358f --- /dev/null +++ b/srsue/src/phy/nr/slot_sync.cc @@ -0,0 +1,206 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsue/hdr/phy/nr/slot_sync.h" + +namespace srsue { +namespace nr { + +slot_sync::slot_sync(srslog::basic_logger& logger_) : logger(logger_), sfn_sync_buff(1) {} + +slot_sync::~slot_sync() +{ + srsran_ue_sync_nr_free(&ue_sync_nr); +} + +static int slot_sync_recv_callback(void* ptr, cf_t** buffer, uint32_t nsamples, srsran_timestamp_t* ts) +{ + if (ptr == nullptr) { + return SRSRAN_ERROR_INVALID_INPUTS; + } + slot_sync* sync = (slot_sync*)ptr; + + cf_t* buffer_ptr[SRSRAN_MAX_CHANNELS] = {}; + buffer_ptr[0] = buffer[0]; + + srsran::rf_buffer_t rf_buffer(buffer_ptr, nsamples); + + return sync->recv_callback(rf_buffer, ts); +} + +bool slot_sync::init(const args_t& args, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_) +{ + stack = stack_; + radio = radio_; + + srsran_ue_sync_nr_args_t ue_sync_nr_args = {}; + ue_sync_nr_args.max_srate_hz = args.max_srate_hz; + ue_sync_nr_args.min_scs = args.ssb_min_scs; + ue_sync_nr_args.nof_rx_channels = args.nof_rx_channels; + ue_sync_nr_args.disable_cfo = args.disable_cfo; + ue_sync_nr_args.pbch_dmrs_thr = args.pbch_dmrs_thr; + ue_sync_nr_args.cfo_alpha = args.cfo_alpha; + ue_sync_nr_args.recv_obj = this; + ue_sync_nr_args.recv_callback = slot_sync_recv_callback; + + if (srsran_ue_sync_nr_init(&ue_sync_nr, &ue_sync_nr_args) < SRSRAN_SUCCESS) { + logger.error("Error initiating UE SYNC NR object"); + return false; + } + + return true; +} + +int slot_sync::set_sync_cfg(const srsran_ue_sync_nr_cfg_t& cfg) +{ + // Print the configuration, it is essential to make sure the UE synchronizes with the wight cell + if (logger.info.enabled()) { + std::array ssb_cfg_str = {}; + srsran_ssb_cfg_to_str(&cfg.ssb, ssb_cfg_str.data(), (uint32_t)ssb_cfg_str.size()); + logger.info("SYNC: Setting SSB configuration %s Tracking N_id=%d.", ssb_cfg_str.data(), cfg.N_id); + } + + // Set the synchronization configuration + if (srsran_ue_sync_nr_set_cfg(&ue_sync_nr, &cfg) < SRSRAN_SUCCESS) { + logger.error("SYNC: failed to set cell configuration for N_id %d", cfg.N_id); + return SRSRAN_ERROR; + } + + return SRSRAN_SUCCESS; +} + +int slot_sync::recv_callback(srsran::rf_buffer_t& data, srsran_timestamp_t* rx_time) +{ + // This function is designed for being called from the UE sync object which will pass a null rx_time in case + // receive dummy samples. So, rf_timestamp points at dummy timestamp in case rx_time is not provided + srsran::rf_timestamp_t dummy_ts = {}; + srsran::rf_timestamp_t& rf_timestamp = (rx_time == nullptr) ? dummy_ts : last_rx_time; + + // Receive + if (not radio->rx_now(data, rf_timestamp)) { + return SRSRAN_ERROR; + } + + srsran_timestamp_t dummy_flat_ts = {}; + + // Load flat timestamp + if (rx_time == nullptr) { + rx_time = &dummy_flat_ts; + } + *rx_time = rf_timestamp.get(0); + + // Save RF timestamp for the stack + stack_tti_ts_new = rf_timestamp.get(0); + + // Run stack if the sync state is not in camping + logger.debug("run_stack_tti: from recv"); + run_stack_tti(); + + logger.debug("SYNC: received %d samples from radio", data.get_nof_samples()); + + return data.get_nof_samples(); +} + +bool slot_sync::run_sfn_sync() +{ + // Run UE SYNC process using the temporal SFN process buffer + srsran_ue_sync_nr_outcome_t outcome = {}; + if (srsran_ue_sync_nr_zerocopy(&ue_sync_nr, sfn_sync_buff.to_cf_t(), &outcome) < SRSRAN_SUCCESS) { + logger.error("SYNC: error in zerocopy"); + return false; + } + + // If in sync, update slot index + if (outcome.in_sync) { + slot_cfg.idx = outcome.sfn * SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) + outcome.sf_idx; + } + + // Return true if the PHY in-sync + return outcome.in_sync; +} + +bool slot_sync::run_camping(srsran::rf_buffer_t& buffer, srsran::rf_timestamp_t& timestamp) +{ + // Run UE SYNC process using an external baseband buffer + srsran_ue_sync_nr_outcome_t outcome = {}; + if (srsran_ue_sync_nr_zerocopy(&ue_sync_nr, buffer.to_cf_t(), &outcome) < SRSRAN_SUCCESS) { + logger.error("SYNC: error in zerocopy"); + return false; + } + + // If in sync, update slot index + if (outcome.in_sync) { + slot_cfg.idx = outcome.sfn * SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) + outcome.sf_idx; + } + + // Set RF timestamp + *timestamp.get_ptr(0) = outcome.timestamp; + + // Return true if the PHY in-sync + return outcome.in_sync; +} + +void slot_sync::run_stack_tti() +{ // check timestamp reset + if (forced_rx_time_init || srsran_timestamp_iszero(&stack_tti_ts) || + srsran_timestamp_compare(&stack_tti_ts_new, &stack_tti_ts) < 0) { + if (srsran_timestamp_compare(&stack_tti_ts_new, &stack_tti_ts) < 0) { + logger.warning("SYNC: radio time seems to be going backwards (rx_time=%f, tti_ts=%f)", + srsran_timestamp_real(&stack_tti_ts_new), + srsran_timestamp_real(&stack_tti_ts)); + // time-stamp will be set to rx time below and run_tti() will be called with MIN_TTI_JUMP + } + + // init tti_ts with last rx time + logger.debug("SYNC: Setting initial TTI time to %f", srsran_timestamp_real(&stack_tti_ts_new)); + srsran_timestamp_copy(&stack_tti_ts, &stack_tti_ts_new); + forced_rx_time_init = false; + } + + // Advance stack in time + if (srsran_timestamp_compare(&stack_tti_ts_new, &stack_tti_ts) >= 0) { + srsran_timestamp_t temp = {}; + srsran_timestamp_copy(&temp, &stack_tti_ts_new); + srsran_timestamp_sub(&temp, stack_tti_ts.full_secs, stack_tti_ts.frac_secs); + int32_t tti_jump = static_cast(srsran_timestamp_uint64(&temp, 1e3)); + tti_jump = SRSRAN_MAX(tti_jump, MIN_TTI_JUMP); + if (tti_jump > MAX_TTI_JUMP) { + logger.warning("SYNC: TTI jump of %d limited to %d", tti_jump, int(MAX_TTI_JUMP)); + tti_jump = SRSRAN_MIN(tti_jump, MAX_TTI_JUMP); + } + + // Run stack + logger.debug("run_stack_tti: calling stack tti=%d, tti_jump=%d", slot_cfg.idx, tti_jump); + stack->run_tti(slot_cfg.idx, tti_jump); + logger.debug("run_stack_tti: stack called"); + } + + // update timestamp + srsran_timestamp_copy(&stack_tti_ts, &stack_tti_ts_new); +} + +srsran_slot_cfg_t slot_sync::get_slot_cfg() +{ + return slot_cfg; +} + +} // namespace nr +} // namespace srsue \ No newline at end of file diff --git a/srsue/src/phy/nr/worker_pool.cc b/srsue/src/phy/nr/worker_pool.cc index 0168ee8f87..107f6667d7 100644 --- a/srsue/src/phy/nr/worker_pool.cc +++ b/srsue/src/phy/nr/worker_pool.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,12 +24,9 @@ namespace srsue { namespace nr { -worker_pool::worker_pool(uint32_t max_workers) : pool(max_workers), logger(srslog::fetch_basic_logger("PHY-NR")) {} +worker_pool::worker_pool(srslog::basic_logger& logger_, uint32_t max_workers) : pool(max_workers), logger(logger_) {} -bool worker_pool::init(const phy_args_nr_t& args, - srsran::phy_common_interface& common, - stack_interface_phy_nr* stack_, - int prio) +bool worker_pool::init(const phy_args_nr_t& args, srsran::phy_common_interface& common, stack_interface_phy_nr* stack_) { phy_state.stack = stack_; phy_state.args = args; @@ -68,7 +65,7 @@ bool worker_pool::init(const phy_args_nr_t& args, std::lock_guard lock(cfg_mutex); w = new sf_worker(common, phy_state, cfg, log); } - pool.init_worker(i, w, prio, args.worker_cpu_mask); + pool.init_worker(i, w, args.workers_thread_prio, args.worker_cpu_mask); workers.push_back(std::unique_ptr(w)); } @@ -167,10 +164,10 @@ void worker_pool::send_prach(const uint32_t prach_occasion, } // called from Stack thread when processing RAR PDU -int worker_pool::set_ul_grant(uint32_t rar_slot_idx, - std::array packed_ul_grant, - uint16_t rnti, - srsran_rnti_type_t rnti_type) +int worker_pool::set_rar_grant(uint32_t rar_slot_idx, + std::array packed_ul_grant, + uint16_t rnti, + srsran_rnti_type_t rnti_type) { // Copy DCI bits and setup DCI context srsran_dci_msg_nr_t dci_msg = {}; @@ -303,10 +300,5 @@ void worker_pool::get_metrics(phy_metrics_t& m) phy_state.get_metrics(m); } -int worker_pool::tx_request(const phy_interface_mac_nr::tx_request_t& request) -{ - return 0; -} - } // namespace nr } // namespace srsue diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 5f4ad696cc..44ed903848 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -101,18 +101,11 @@ bool phy::check_args(const phy_args_t& args_) int phy::init(const phy_args_t& args_, stack_interface_phy_lte* stack_, srsran::radio_interface_phy* radio_) { + std::unique_lock lock(config_mutex); + stack = stack_; radio = radio_; - init(args_); - - return SRSRAN_SUCCESS; -} - -int phy::init(const phy_args_t& args_) -{ - std::unique_lock lock(config_mutex); - args = args_; // Force frequency if given as argument @@ -133,12 +126,12 @@ int phy::init(const phy_args_t& args_) logger_phy.set_hex_dump_max_size(args.log.phy_hex_limit); if (!check_args(args)) { - return false; + return SRSRAN_ERROR; } is_configured = false; start(); - return true; + return SRSRAN_SUCCESS; } // Initializes PHY in a thread @@ -168,7 +161,7 @@ void phy::wait_initialize() } } -bool phy::is_initiated() +bool phy::is_initialized() { return is_configured; } @@ -256,12 +249,11 @@ void phy::configure_prach_params() void phy::set_cells_to_meas(uint32_t earfcn, const std::set& pci) { + uint32_t pcell_earfcn = selected_earfcn; // As the SCell configuration is performed asynchronously through the cmd_worker, append the command adding the // measurements to avoid a concurrency issue - cmd_worker.add_cmd([this, earfcn, pci]() { + cmd_worker.add_cmd([this, earfcn, pci, pcell_earfcn]() { // Check if the EARFCN matches with serving cell - uint32_t pcell_earfcn = 0; - sfsync.get_current_cell(nullptr, &pcell_earfcn); bool available = (pcell_earfcn == earfcn); // Find if there is secondary serving cell configured with the specified EARFCN @@ -270,12 +262,17 @@ void phy::set_cells_to_meas(uint32_t earfcn, const std::set& pci) // If it is configured... if (common.cell_state.is_configured(cc)) { // ... Check if the EARFCN match + logger_phy.info( + "Setting new SCell measurement cc=%d is configured and earfcn=%d", cc, common.cell_state.get_earfcn(cc)); if (common.cell_state.get_earfcn(cc) == earfcn) { available = true; } - } else if (cc_empty == 0) { - // ... otherwise, save the CC as non-configured - cc_empty = cc; + } else { + logger_phy.info("Setting new SCell measurement cc=%d is not configured", cc); + if (cc_empty == 0) { + // ... otherwise, save the CC as non-configured + cc_empty = cc; + } } } @@ -291,7 +288,7 @@ void phy::set_cells_to_meas(uint32_t earfcn, const std::set& pci) // Configure a the empty carrier as it was CA logger_phy.info("Setting new SCell measurement cc_idx=%d, earfcn=%d, pci=%d...", cc_empty, earfcn, cell.id); - set_scell(cell, cc_empty, earfcn); + set_scell(cell, cc_empty, earfcn, false); } // Finally, set the serving cell measure @@ -316,9 +313,17 @@ bool phy::cell_select(phy_cell_t cell) // Update PCI before starting the background command to make sure PRACH gets the updated value selected_cell.id = cell.pci; + // Update EARFCN before starting the background task to make sure is taken into account when finding carriers to + // measure inter-frequency neighbours (see set_cells_to_meas) + selected_earfcn = cell.earfcn; + // Indicate workers that cell selection is in progress common.cell_is_selecting = true; + // Update EARFCN before starting the background task to make sure is taken into account when finding carriers to + // measure inter-frequency neighbours (see set_cells_to_meas) + selected_earfcn = cell.earfcn; + cmd_worker_cell.add_cmd([this, cell]() { // Wait SYNC transitions to IDLE sfsync.wait_idle(); @@ -336,7 +341,6 @@ bool phy::cell_select(phy_cell_t cell) // Indicate workers that cell selection has finished common.cell_is_selecting = false; - }); return true; } else { @@ -347,12 +351,12 @@ bool phy::cell_select(phy_cell_t cell) // This function executes one part of the procedure immediatly and returns to continue in the background. // When it returns, the caller thread can expect the PHY to have switched to IDLE and have stopped all DL/UL/PRACH -// processing. -bool phy::cell_search() +// processing. If a valid EARFCN (>0) is given, this is used for cell search. +bool phy::cell_search(int earfcn) { sfsync.scell_sync_stop(); if (sfsync.cell_search_init()) { - cmd_worker_cell.add_cmd([this]() { + cmd_worker_cell.add_cmd([this, earfcn]() { // Wait SYNC transitions to IDLE sfsync.wait_idle(); @@ -360,7 +364,7 @@ bool phy::cell_search() reset(); phy_cell_t found_cell = {}; - rrc_interface_phy_lte::cell_search_ret_t ret = sfsync.cell_search_start(&found_cell); + rrc_interface_phy_lte::cell_search_ret_t ret = sfsync.cell_search_start(&found_cell, earfcn); stack->cell_search_complete(ret, found_cell); }); } else { @@ -457,7 +461,7 @@ void phy::start_plot() bool phy::set_config(const srsran::phy_cfg_t& config_, uint32_t cc_idx) { - if (!is_initiated()) { + if (!is_initialized()) { fprintf(stderr, "Error calling set_config(): PHY not initialized\n"); return false; } @@ -466,7 +470,7 @@ bool phy::set_config(const srsran::phy_cfg_t& config_, uint32_t cc_idx) if (cc_idx >= args.nof_lte_carriers) { srsran::console("Received SCell configuration for index %d but there are not enough CC workers available\n", cc_idx); - return false; + return true; } Info("Setting configuration"); @@ -493,7 +497,12 @@ bool phy::set_config(const srsran::phy_cfg_t& config_, uint32_t cc_idx) bool phy::set_scell(srsran_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn) { - if (!is_initiated()) { + return set_scell(cell_info, cc_idx, earfcn, true); +} + +bool phy::set_scell(srsran_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn, bool run_in_background) +{ + if (!is_initialized()) { fprintf(stderr, "Error calling set_config(): PHY not initialized\n"); return false; } @@ -527,49 +536,58 @@ bool phy::set_scell(srsran_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn) // Component carrier index zero should be reserved for PCell // Send configuration to workers - cmd_worker.add_cmd([this, cell_info, cc_idx, earfcn, earfcn_is_different]() { - logger_phy.info("Setting new SCell configuration cc_idx=%d, earfcn=%d, pci=%d...", cc_idx, earfcn, cell_info.id); - for (uint32_t i = 0; i < args.nof_phy_threads; i++) { - // set_cell is not protected so run when worker has finished to ensure no PHY processing is done at the time of - // cell setting - lte::sf_worker* w = lte_workers.wait_worker_id(i); - if (w) { - // Reset secondary serving cell configuration, this needs to be done when the sf_worker is reserved to prevent - // resetting the cell while it is working - w->reset_cell_nolock(cc_idx); + if (run_in_background) { + cmd_worker.add_cmd([this, cell_info, cc_idx, earfcn, earfcn_is_different]() { + set_scell_cmd(cell_info, cc_idx, earfcn, earfcn_is_different); + }); + } else { + set_scell_cmd(cell_info, cc_idx, earfcn, earfcn_is_different); + } + return true; +} - // Set the new cell - w->set_cell_nolock(cc_idx, cell_info); +void phy::set_scell_cmd(srsran_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn, bool earfcn_is_different) +{ + logger_phy.info("Setting new SCell configuration cc_idx=%d, earfcn=%d, pci=%d...", cc_idx, earfcn, cell_info.id); + for (uint32_t i = 0; i < args.nof_phy_threads; i++) { + // set_cell is not protected so run when worker has finished to ensure no PHY processing is done at the time of + // cell setting + lte::sf_worker* w = lte_workers.wait_worker_id(i); + if (w) { + // Reset secondary serving cell configuration, this needs to be done when the sf_worker is reserved to prevent + // resetting the cell while it is working + w->reset_cell_nolock(cc_idx); - // Release the new worker, it should not start processing until the SCell state is set to configured - w->release(); - } + // Set the new cell + w->set_cell_nolock(cc_idx, cell_info); + + // Release the new worker, it should not start processing until the SCell state is set to configured + w->release(); } + } - // Reset measurements for the given CC after all workers finished processing and have been configured to ensure the - // measurements are not overwritten - common.reset_measurements(cc_idx); + // Reset measurements for the given CC after all workers finished processing and have been configured to ensure the + // measurements are not overwritten + common.reset_measurements(cc_idx); - // Change frequency only if the earfcn was modified - if (earfcn_is_different) { - double dl_freq = srsran_band_fd(earfcn) * 1e6; - double ul_freq = srsran_band_fu(common.get_ul_earfcn(earfcn)) * 1e6; - radio->set_rx_freq(cc_idx, dl_freq); - radio->set_tx_freq(cc_idx, ul_freq); - } + // Change frequency only if the earfcn was modified + if (earfcn_is_different) { + double dl_freq = srsran_band_fd(earfcn) * 1e6; + double ul_freq = srsran_band_fu(common.get_ul_earfcn(earfcn)) * 1e6; + radio->set_rx_freq(cc_idx, dl_freq); + radio->set_tx_freq(cc_idx, ul_freq); + } - // Set secondary serving cell synchronization - sfsync.scell_sync_set(cc_idx, cell_info); + // Set secondary serving cell synchronization + sfsync.scell_sync_set(cc_idx, cell_info); - logger_phy.info( - "Finished setting new SCell configuration cc_idx=%d, earfcn=%d, pci=%d", cc_idx, earfcn, cell_info.id); + logger_phy.info( + "Finished setting new SCell configuration cc_idx=%d, earfcn=%d, pci=%d", cc_idx, earfcn, cell_info.id); - // Configure secondary serving cell, allows this component carrier to execute PHY processing - common.cell_state.configure(cc_idx, earfcn, cell_info.id); + // Configure secondary serving cell, allows this component carrier to execute PHY processing + common.cell_state.configure(cc_idx, earfcn, cell_info.id); - stack->set_scell_complete(true); - }); - return true; + stack->set_scell_complete(true); } void phy::set_config_tdd(srsran_tdd_config_t& tdd_config_) @@ -633,19 +651,19 @@ void phy::set_mch_period_stop(uint32_t stop) int phy::init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_) { stack_nr = stack_; - if (!nr_workers.init(args_, common, stack_, WORKERS_THREAD_PRIO)) { + if (!nr_workers.init(args_, common, stack_)) { return SRSRAN_ERROR; } return SRSRAN_SUCCESS; } -int phy::set_ul_grant(uint32_t rar_slot_idx, - std::array packed_ul_grant, - uint16_t rnti, - srsran_rnti_type_t rnti_type) +int phy::set_rar_grant(uint32_t rar_slot_idx, + std::array packed_ul_grant, + uint16_t rnti, + srsran_rnti_type_t rnti_type) { - return nr_workers.set_ul_grant(rar_slot_idx, packed_ul_grant, rnti, rnti_type); + return nr_workers.set_rar_grant(rar_slot_idx, packed_ul_grant, rnti, rnti_type); } void phy::send_prach(const uint32_t prach_occasion, @@ -656,11 +674,6 @@ void phy::send_prach(const uint32_t prach_occasion, nr_workers.send_prach(prach_occasion, preamble_index, preamble_received_target_power); } -int phy::tx_request(const phy_interface_mac_nr::tx_request_t& request) -{ - return 0; -} - void phy::set_earfcn(std::vector earfcns) { // Do nothing diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 6dd9828924..88f290732e 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -65,6 +65,14 @@ void phy_common::init(phy_args_t* _args, ul_channel = srsran::channel_ptr( new srsran::channel(args->ul_channel_args, args->nof_lte_carriers * args->nof_rx_ant, logger)); } + + // Init the CFR config struct with the CFR args + cfr_config.cfr_enable = args->cfr_args.enable; + cfr_config.cfr_mode = args->cfr_args.mode; + cfr_config.alpha = args->cfr_args.strength; + cfr_config.manual_thr = args->cfr_args.manual_thres; + cfr_config.max_papr_db = args->cfr_args.auto_target_papr; + cfr_config.ema_alpha = args->cfr_args.ema_alpha; } void phy_common::set_ue_dl_cfg(srsran_ue_dl_cfg_t* ue_dl_cfg) @@ -682,9 +690,9 @@ void phy_common::update_measurements(uint32_t cc_idx, return; } - // Only worker 0 reads the RSSI sensor + // Only worker 0 updates RX gain offset every 10 ms if (rssi_power_buffer) { - if (!rssi_read_cnt) { + if (!update_rxgain_cnt) { // Average RSSI over all symbols in antenna port 0 (make sure SF length is non-zero) float rssi_dbm = SRSRAN_SF_LEN_PRB(cell.nof_prb) > 0 ? (srsran_convert_power_to_dB( @@ -697,9 +705,9 @@ void phy_common::update_measurements(uint32_t cc_idx, rx_gain_offset = get_radio()->get_rx_gain() + args->rx_gain_offset; } - rssi_read_cnt++; - if (rssi_read_cnt >= 1000) { - rssi_read_cnt = 0; + update_rxgain_cnt++; + if (update_rxgain_cnt >= update_rxgain_period) { + update_rxgain_cnt = 0; } } @@ -945,6 +953,7 @@ void phy_common::reset() void phy_common::build_mch_table() { // First reset tables + std::lock_guard lock(mch_mutex); bzero(&mch_table[0], sizeof(uint8_t) * 40); // 40 element table represents 4 frames (40 subframes) @@ -967,6 +976,7 @@ void phy_common::build_mch_table() void phy_common::build_mcch_table() { + std::lock_guard lock(mch_mutex); // First reset tables bzero(&mcch_table[0], sizeof(uint8_t) * 10); generate_mcch_table(&mcch_table[0], (uint32_t)mbsfn_config.mbsfn_area_info.mcch_cfg.sf_alloc_info); @@ -1024,7 +1034,7 @@ bool phy_common::is_mch_subframe(srsran_mbsfn_cfg_t* cfg, uint32_t phy_tti) cfg->mbsfn_mcs = 2; cfg->enable = false; cfg->is_mcch = false; - + std::lock_guard lock(mch_mutex); // Check for MCCH if (is_mcch_subframe(cfg, phy_tti)) { cfg->is_mcch = true; diff --git a/srsue/src/phy/phy_nr_sa.cc b/srsue/src/phy/phy_nr_sa.cc new file mode 100644 index 0000000000..aa6baacbb7 --- /dev/null +++ b/srsue/src/phy/phy_nr_sa.cc @@ -0,0 +1,283 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsue/hdr/phy/phy_nr_sa.h" +#include "srsran/common/standard_streams.h" +#include "srsran/srsran.h" + +namespace srsue { + +static void srsran_phy_handler(phy_logger_level_t log_level, void* ctx, char* str) +{ + phy_nr_sa* r = (phy_nr_sa*)ctx; + r->srsran_phy_logger(log_level, str); +} + +void phy_nr_sa::srsran_phy_logger(phy_logger_level_t log_level, char* str) +{ + switch (log_level) { + case LOG_LEVEL_INFO_S: + logger_phy_lib.info(" %s", str); + break; + case LOG_LEVEL_DEBUG_S: + logger_phy_lib.debug(" %s", str); + break; + case LOG_LEVEL_ERROR_S: + logger_phy_lib.error(" %s", str); + break; + default: + break; + } +} + +void phy_nr_sa::set_default_args(phy_args_nr_t& args_) +{ + args_.nof_phy_threads = DEFAULT_WORKERS; + // TODO +} + +bool phy_nr_sa::check_args(const phy_args_nr_t& args_) +{ + if (args_.nof_phy_threads > MAX_WORKERS) { + srsran::console("Error in PHY args: nof_phy_threads must be 1, 2 or 3\n"); + return false; + } + return true; +} + +phy_nr_sa::phy_nr_sa(const char* logname) : + logger(srslog::fetch_basic_logger(logname)), + logger_phy_lib(srslog::fetch_basic_logger("PHY_LIB")), + sync(logger, workers), + workers(logger, 4) +{} + +int phy_nr_sa::init(const phy_args_nr_t& args_, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_) +{ + args = args_; + stack = stack_; + radio = radio_; + + // Add PHY lib log + auto lib_log_level = srslog::str_to_basic_level(args.log.phy_lib_level); + logger_phy_lib.set_level(lib_log_level); + logger_phy_lib.set_hex_dump_max_size(args.log.phy_hex_limit); + if (lib_log_level != srslog::basic_levels::none) { + srsran_phy_log_register_handler(this, srsran_phy_handler); + } + + // set default logger + logger.set_level(srslog::str_to_basic_level(args.log.phy_level)); + logger.set_hex_dump_max_size(args.log.phy_hex_limit); + + logger.set_context(0); + + if (!check_args(args)) { + return SRSRAN_ERROR; + } + + is_configured = false; + std::thread t([this]() { init_background(); }); + init_thread = std::move(t); + + return SRSRAN_SUCCESS; +} + +void phy_nr_sa::init_background() +{ + nr::sync_sa::args_t sync_args = {}; + sync_args.srate_hz = args.srate_hz; + sync_args.thread_priority = args.slot_recv_thread_prio; + if (not sync.init(sync_args, stack, radio)) { + logger.error("Error initialising SYNC"); + return; + } + workers.init(args, sync, stack); + + is_configured = true; +} + +void phy_nr_sa::stop() +{ + cmd_worker.stop(); + cmd_worker_cell.stop(); + if (is_configured) { + sync.stop(); + workers.stop(); + is_configured = false; + } +} + +bool phy_nr_sa::is_initialized() +{ + return is_configured; +} + +void phy_nr_sa::wait_initialize() +{ + init_thread.join(); +} + +phy_interface_rrc_nr::phy_nr_state_t phy_nr_sa::get_state() +{ + { + switch (sync.get_state()) { + case sync_state::state_t::IDLE: + return phy_interface_rrc_nr::PHY_NR_STATE_IDLE; + case sync_state::state_t::CELL_SEARCH: + return phy_interface_rrc_nr::PHY_NR_STATE_CELL_SEARCH; + case sync_state::state_t::SFN_SYNC: + return phy_interface_rrc_nr::PHY_NR_STATE_CELL_SELECT; + case sync_state::state_t::CAMPING: + return phy_interface_rrc_nr::PHY_NR_STATE_CAMPING; + } + } + return phy_interface_rrc_nr::PHY_NR_STATE_IDLE; +} + +void phy_nr_sa::reset_nr() +{ + sync.reset(); + + sync.cell_go_idle(); +} + +// This function executes one part of the procedure immediately and returns to continue in the background. +// When it returns, the caller thread can expect the PHY to have switched to IDLE and have stopped all DL/UL/PRACH +// processing. +// It will perform cell search procedure in the background and will signal stack with function cell_search_found_cell() +// when finished +bool phy_nr_sa::start_cell_search(const cell_search_args_t& req) +{ + // TODO: verify arguments are valid before starting procedure + + cmd_worker_cell.add_cmd([this, req]() { + logger.info("Cell Search: Going to IDLE"); + sync.cell_go_idle(); + + // Prepare cell search configuration from the request + nr::cell_search::cfg_t cfg = {}; + cfg.srate_hz = args.srate_hz; + cfg.center_freq_hz = req.center_freq_hz; + cfg.ssb_freq_hz = req.ssb_freq_hz; + cfg.ssb_scs = req.ssb_scs; + cfg.ssb_pattern = req.ssb_pattern; + cfg.duplex_mode = req.duplex_mode; + + // Request cell search to lower synchronization instance. + nr::cell_search::ret_t ret = sync.cell_search_run(cfg); + + // Pass result to stack + rrc_interface_phy_nr::cell_search_result_t rrc_cs_ret = {}; + rrc_cs_ret.cell_found = ret.result == nr::cell_search::ret_t::CELL_FOUND; + if (rrc_cs_ret.cell_found) { + rrc_cs_ret.pci = ret.ssb_res.N_id; + rrc_cs_ret.pbch_msg = ret.ssb_res.pbch_msg; + rrc_cs_ret.measurements = ret.ssb_res.measurements; + } + stack->cell_search_found_cell(rrc_cs_ret); + }); + + return true; +} + +// This function executes one part of the procedure immediately and returns to continue in the background. +// When it returns, the caller thread can expect the PHY to have switched to IDLE and have stopped all DL/UL/PRACH +// processing. +// It will perform cell search procedure in the background and will signal stack with function cell_search_found_cell() +// when finished +bool phy_nr_sa::start_cell_select(const cell_select_args_t& req) +{ + // TODO: verify arguments are valid before starting procedure + + logger.info("Cell Select: Going to IDLE"); + sync.cell_go_idle(); + + selected_cell = req.carrier; + + cmd_worker_cell.add_cmd([this, req]() { + // Request cell search to lower synchronization instance and push the result directly to the stack + stack->cell_select_completed(sync.cell_select_run(req)); + }); + + return true; +} + +bool phy_nr_sa::has_valid_sr_resource(uint32_t sr_id) +{ + return workers.has_valid_sr_resource(sr_id); +} + +void phy_nr_sa::clear_pending_grants() +{ + workers.clear_pending_grants(); +} + +void phy_nr_sa::send_prach(const uint32_t prach_occasion, + const int preamble_index, + const float preamble_received_target_power, + const float ta_base_sec) +{ + workers.send_prach(prach_occasion, preamble_index, preamble_received_target_power); +} + +void phy_nr_sa::set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) +{ + sync.add_ta_cmd_rar(tti, ta_cmd); +} + +void phy_nr_sa::set_timeadv(uint32_t tti, uint32_t ta_cmd) +{ + sync.add_ta_cmd_new(tti, ta_cmd); +} + +int phy_nr_sa::set_rar_grant(uint32_t rar_slot_idx, + std::array packed_ul_grant, + uint16_t rnti, + srsran_rnti_type_t rnti_type) +{ + return workers.set_rar_grant(rar_slot_idx, packed_ul_grant, rnti, rnti_type); +} + +bool phy_nr_sa::set_config(const srsran::phy_cfg_nr_t& cfg) +{ + // Stash NR configuration + config_nr = cfg; + + // Setup carrier configuration asynchronously + cmd_worker.add_cmd([this]() { + // Set UE configuration + bool ret = workers.set_config(config_nr); + + // Pass n_ta_offset to sync + sync.add_ta_offset(config_nr.t_offset); + + // Notify PHY config completion + if (stack != nullptr) { + stack->set_phy_config_complete(ret); + } + + return ret; + }); + return true; +} + +} // namespace srsue diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index 6dae6abebb..e8f6098408 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/phy/scell/intra_measure_base.cc b/srsue/src/phy/scell/intra_measure_base.cc index 254a6aee8a..78b33f3968 100644 --- a/srsue/src/phy/scell/intra_measure_base.cc +++ b/srsue/src/phy/scell/intra_measure_base.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/phy/scell/intra_measure_lte.cc b/srsue/src/phy/scell/intra_measure_lte.cc index fe8cb5f4d4..9e783fa472 100644 --- a/srsue/src/phy/scell/intra_measure_lte.cc +++ b/srsue/src/phy/scell/intra_measure_lte.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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 8a63d0b86c..2947d5aef3 100644 --- a/srsue/src/phy/scell/intra_measure_nr.cc +++ b/srsue/src/phy/scell/intra_measure_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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/phy/scell/scell_recv.cc b/srsue/src/phy/scell/scell_recv.cc index 3c9d62342a..650e0fc0e5 100644 --- a/srsue/src/phy/scell/scell_recv.cc +++ b/srsue/src/phy/scell/scell_recv.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/phy/search.cc b/srsue/src/phy/search.cc index 32006da291..19d32cbd11 100644 --- a/srsue/src/phy/search.cc +++ b/srsue/src/phy/search.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -55,7 +55,7 @@ search::~search() srsran_ue_cellsearch_free(&cs); } -void search::init(srsran::rf_buffer_t& buffer_, uint32_t nof_rx_channels, search_callback* parent, int force_N_id_2_) +void search::init(srsran::rf_buffer_t& buffer_, uint32_t nof_rx_channels, search_callback* parent, int force_N_id_2_, int force_N_id_1_) { p = parent; @@ -74,6 +74,7 @@ void search::init(srsran::rf_buffer_t& buffer_, uint32_t nof_rx_channels, search p->set_ue_sync_opts(&cs.ue_sync, 0); force_N_id_2 = force_N_id_2_; + force_N_id_1 = force_N_id_1_; } void search::set_cp_en(bool enable) @@ -120,7 +121,7 @@ search::ret_code search::run(srsran_cell_t* cell_, std::array= 0 && force_N_id_2 < 3) { + if (force_N_id_2 >= 0 && force_N_id_2 < SRSRAN_NOF_NID_2) { ret = srsran_ue_cellsearch_scan_N_id_2(&cs, force_N_id_2, &found_cells[force_N_id_2]); max_peak_cell = force_N_id_2; } else { @@ -134,6 +135,38 @@ search::ret_code search::run(srsran_cell_t* cell_, std::array= 0 && force_N_id_1 < SRSRAN_NOF_NID_1) { + /* Note that srsran_ue_cellsearch_scan_N_id_2 only finds the strongest cell for a given N_id_2/PSS within the search + * window. A cell with the desired SSS can be occluded by other cells with the same PSS, if their PSS is stronger and + * within the same search window. + */ + bool N_id_1_found = false; + if (force_N_id_2 >= 0 && force_N_id_2 < SRSRAN_NOF_NID_2) { + // N_id_2 (PSS) was forced, so there is only one search result to check + if (found_cells[max_peak_cell].cell_id / SRSRAN_NOF_NID_2 == (uint32_t)force_N_id_1) { + N_id_1_found = true; + } + } else { + // Go through the results for all N_id_2 (PSS); pick strongest with matching N_id_1 (SSS) + float max_peak_value = -1.0; + for (uint32_t N_id_2 = 0; N_id_2 < SRSRAN_NOF_NID_2; N_id_2++) { + if (found_cells[N_id_2].cell_id / SRSRAN_NOF_NID_2 == (uint32_t)force_N_id_1) { + if (found_cells[N_id_2].peak > max_peak_value) { + N_id_1_found = true; + max_peak_value = found_cells[N_id_2].peak; + max_peak_cell = N_id_2; + } + } + } + } + if (!N_id_1_found) { + Info("SYNC: Could not find any cell with preselected SSS (force_N_id_1=%d)", force_N_id_1); + return CELL_NOT_FOUND; + } + } + // Save result new_cell.id = found_cells[max_peak_cell].cell_id; new_cell.cp = found_cells[max_peak_cell].cp; @@ -203,4 +236,4 @@ search::ret_code search::run(srsran_cell_t* cell_, std::arrayargs->force_N_id_2); + search_p.init(sf_buffer, nof_rf_channels, this, worker_com->args->force_N_id_2, worker_com->args->force_N_id_1); search_p.set_cp_en(worker_com->args->detect_cp); // Initialize SFN synchronizer, it uses only pcell buffer sfn_p.init(&ue_sync, worker_com->args, sf_buffer, sf_buffer.size()); @@ -137,17 +137,19 @@ sync::~sync() void sync::stop() { + running = false; + std::lock_guard lock(intra_freq_cfg_mutex); - worker_com->semaphore.wait_all(); for (auto& q : intra_freq_meas) { q->stop(); } - running = false; - - wait_thread_finish(); // Reset (stop Rx stream) as soon as possible to avoid base-band Rx buffer overflow radio_h->reset(); + + // let the sync FSM finish before waiting for workers semaphores to avoid workers locking + wait_thread_finish(); + worker_com->semaphore.wait_all(); } void sync::reset() @@ -188,10 +190,10 @@ void sync::reset() * */ -/* A call to cell_search() finds the strongest cell in the set of supported EARFCNs. When the first cell is found, - * returns 1 and stores cell information and RSRP values in the pointers (if provided). If a cell is not found in the - * current frequency it moves to the next one and the next call to cell_search() will look in the next EARFCN in the - * set. If no cells are found in any frequency it returns 0. If error returns -1. +/* A call to cell_search() finds the strongest cell at a given EARFCN or in the set of supported EARFCNs. When the first + * cell is found, returns 1 and stores cell information and RSRP values in the pointers (if provided). If a cell is not + * found in the current frequency it moves to the next one and the next call to cell_search() will look in the next + * EARFCN in the set. If no cells are found in any frequency it returns 0. If error returns -1. * * The first part of the procedure (call to _init()) moves the PHY To IDLE, ensuring that no UL/DL/PRACH will happen * @@ -206,7 +208,6 @@ bool sync::cell_search_init() } // Move state to IDLE - Info("Cell Search: Start EARFCN index=%u/%zd", cellsearch_earfcn_index, worker_com->args->dl_earfcn_list.size()); phy_state.go_idle(); // Stop all intra-frequency measurement before changing frequency @@ -217,10 +218,16 @@ bool sync::cell_search_init() return true; } -rrc_interface_phy_lte::cell_search_ret_t sync::cell_search_start(phy_cell_t* found_cell) +rrc_interface_phy_lte::cell_search_ret_t sync::cell_search_start(phy_cell_t* found_cell, int earfcn) { std::unique_lock ul(rrc_mutex); + if (earfcn < 0) { + Info("Cell Search: Start EARFCN index=%u/%zd", cellsearch_earfcn_index, worker_com->args->dl_earfcn_list.size()); + } else { + Info("Cell Search: Start EARFCN=%d", earfcn); + } + rrc_interface_phy_lte::cell_search_ret_t ret = {}; ret.found = rrc_interface_phy_lte::cell_search_ret_t::ERROR; ret.last_freq = rrc_interface_phy_lte::cell_search_ret_t::NO_MORE_FREQS; @@ -238,16 +245,20 @@ rrc_interface_phy_lte::cell_search_ret_t sync::cell_search_start(phy_cell_t* fou Info("SYNC: Setting Cell Search sampling rate"); } - try { - if (current_earfcn != (int)worker_com->args->dl_earfcn_list.at(cellsearch_earfcn_index)) { - current_earfcn = (int)worker_com->args->dl_earfcn_list[cellsearch_earfcn_index]; - Info("Cell Search: changing frequency to EARFCN=%d", current_earfcn); - set_frequency(); + if (earfcn < 0) { + try { + if (current_earfcn != (int)worker_com->args->dl_earfcn_list.at(cellsearch_earfcn_index)) { + current_earfcn = (int)worker_com->args->dl_earfcn_list[cellsearch_earfcn_index]; + } + } catch (const std::out_of_range& oor) { + Error("Index %d is not a valid EARFCN element.", cellsearch_earfcn_index); + return ret; } - } catch (const std::out_of_range& oor) { - Error("Index %d is not a valid EARFCN element.", cellsearch_earfcn_index); - return ret; + } else { + current_earfcn = earfcn; } + Info("Cell Search: changing frequency to EARFCN=%d", current_earfcn); + set_frequency(); // Move to CELL SEARCH and wait to finish Info("Cell Search: Setting Cell search state"); @@ -275,7 +286,7 @@ rrc_interface_phy_lte::cell_search_ret_t sync::cell_search_start(phy_cell_t* fou } cellsearch_earfcn_index++; - if (cellsearch_earfcn_index >= worker_com->args->dl_earfcn_list.size()) { + if (cellsearch_earfcn_index >= worker_com->args->dl_earfcn_list.size() or earfcn < 0) { Info("Cell Search: No more frequencies in the current EARFCN set"); cellsearch_earfcn_index = 0; ret.last_freq = rrc_interface_phy_lte::cell_search_ret_t::NO_MORE_FREQS; diff --git a/srsue/src/phy/sync_sa.cc b/srsue/src/phy/sync_sa.cc new file mode 100644 index 0000000000..5529aaf79e --- /dev/null +++ b/srsue/src/phy/sync_sa.cc @@ -0,0 +1,393 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsue/hdr/phy/nr/sync_sa.h" +#include "srsran/radio/rf_buffer.h" + +namespace srsue { +namespace nr { +sync_sa::sync_sa(srslog::basic_logger& logger_, worker_pool& workers_) : + logger(logger_), workers(workers_), slot_synchronizer(logger_), searcher(logger_), ta(logger_), srsran::thread("SYNC") +{} + +sync_sa::~sync_sa() +{ + if (rx_buffer != nullptr) { + free(rx_buffer); + } +} + +bool sync_sa::init(const args_t& args, stack_interface_phy_nr* stack_, srsran::radio_interface_phy* radio_) +{ + stack = stack_; + radio = radio_; + srate_hz = args.srate_hz; + slot_sz = (uint32_t)(args.srate_hz / 1000.0f); + + // Initialise cell search internal object + if (not searcher.init(args.get_cell_search())) { + logger.error("Error initialising cell searcher"); + return false; + } + + // Initialise slot synchronizer object + if (not slot_synchronizer.init(args.get_slot_sync(), stack, radio)) { + logger.error("Error initialising slot synchronizer"); + return false; + } + + // Cell bandwidth must be provided at init so set now sampling rate + radio->set_rx_srate(args.srate_hz); + radio->set_tx_srate(args.srate_hz); + + // Compute subframe size + slot_sz = (uint32_t)(args.srate_hz / 1000.0f); + + // Allocate receive buffer + rx_buffer = srsran_vec_cf_malloc(2 * slot_sz); + if (rx_buffer == nullptr) { + logger.error("Error allocating buffer"); + return false; + } + + // Thread control + running = true; + start(args.thread_priority); + + // If reached here it was successful + return true; +} + +void sync_sa::stop() +{ + running = false; + wait_thread_finish(); + radio->reset(); +} + +bool sync_sa::reset() +{ + // Wait worker pool to finish any processing + tti_semaphore.wait_all(); + ta.set_base_sec(0); + + return true; +} + +void sync_sa::add_ta_cmd_rar(uint32_t tti_, uint32_t ta_cmd) +{ + ta.add_ta_cmd_rar(tti_, ta_cmd); +} + +void sync_sa::add_ta_cmd_new(uint32_t tti_, uint32_t ta_cmd) +{ + ta.add_ta_cmd_new(tti_, ta_cmd); +} + +void sync_sa::add_ta_offset(uint32_t ta_offset) +{ + ta.add_ta_offset(ta_offset); +} + +void sync_sa::cell_go_idle() +{ + std::unique_lock ul(rrc_mutex); + phy_state.go_idle(); +} + +bool sync_sa::wait_idle() +{ + // Wait for SYNC thread to transition to IDLE (max. 2000ms) + if (!phy_state.wait_idle(100)) { + return false; + } + + // Reset UE sync. Attention: doing this reset when the FSM is NOT IDLE can cause PSS/SSS out-of-sync + //... + + // Wait for workers to finish PHY processing + tti_semaphore.wait_all(); + + // As workers have finished, make sure the Tx burst is ended + radio->tx_end(); + + return phy_state.is_idle(); +} + +cell_search::ret_t sync_sa::cell_search_run(const cell_search::cfg_t& cfg) +{ + std::unique_lock ul(rrc_mutex); + + cs_ret = {}; + cs_ret.result = cell_search::ret_t::ERROR; + + // Wait the FSM to transition to IDLE + if (!wait_idle()) { + logger.error("Cell Search: SYNC thread didn't transition to IDLE after 100 ms\n"); + return cs_ret; + } + + rrc_proc_state = PROC_SEARCH_RUNNING; + + // tune radio + logger.info("Tuning Rx channel %d to %.2f MHz", 0, cfg.center_freq_hz / 1e6); + radio->set_rx_freq(0, cfg.center_freq_hz); + + if (not searcher.start(cfg)) { + logger.error("Sync: failed to start cell search"); + return cs_ret; + } + + logger.info("Cell Search: Running Cell search state"); + cell_search_nof_trials = 0; + phy_state.run_cell_search(); + + rrc_proc_state = PROC_IDLE; + + return cs_ret; +} + +rrc_interface_phy_nr::cell_select_result_t sync_sa::cell_select_run(const phy_interface_rrc_nr::cell_select_args_t& req) +{ + std::unique_lock ul(rrc_mutex); + + // By default, the result is set to error + rrc_interface_phy_nr::cell_select_result_t result = {}; + result.status = rrc_interface_phy_nr::cell_select_result_t::ERROR; + + // Wait the FSM to transition to IDLE + if (!wait_idle()) { + logger.error("Cell Search: SYNC thread didn't transition to IDLE after 100 ms\n"); + + // Return default result with error status + return result; + } + + rrc_proc_state = PROC_SELECT_RUNNING; + + // tune radio + logger.info("Tuning Rx channel %d to %.2f MHz", 0, req.carrier.dl_center_frequency_hz / 1e6); + radio->set_rx_freq(0, req.carrier.dl_center_frequency_hz); + logger.info("Tuning Tx channel %d to %.2f MHz", 0, req.carrier.ul_center_frequency_hz / 1e6); + radio->set_tx_freq(0, req.carrier.ul_center_frequency_hz); + + // Configure cell + srsran_ue_sync_nr_cfg_t cfg = {}; + cfg.N_id = req.carrier.pci; + cfg.ssb = req.ssb_cfg; + cfg.ssb.srate_hz = srate_hz; + if (slot_synchronizer.set_sync_cfg(cfg)) { + logger.error("Cell Search: Failed setting slot synchronizer configuration"); + + // Return default result with error status + return result; + } + + // SFN synchronization + phy_state.run_sfn_sync(); + + // Determine if the procedure was successful if the current state is camping, otherwise it is unsuccessful + if (phy_state.is_camping()) { + logger.info("Cell Select: SFN synchronized. CAMPING..."); + result.status = rrc_interface_phy_nr::cell_select_result_t::SUCCESSFUL; + } else { + logger.info("Cell Select: Could not synchronize SFN"); + result.status = rrc_interface_phy_nr::cell_select_result_t::UNSUCCESSFUL; + } + + rrc_proc_state = PROC_IDLE; + return result; +} + +sync_state::state_t sync_sa::get_state() +{ + return phy_state.get_state(); +} + +void sync_sa::run_state_idle() +{ + if (not radio->is_init()) { + return; + } + + logger.debug("Discarding samples and sending tx_end"); + srsran::rf_buffer_t rf_buffer = {}; + rf_buffer.set_nof_samples(slot_sz); + rf_buffer.set(0, rx_buffer); + if (not slot_synchronizer.recv_callback(rf_buffer, last_rx_time.get_ptr(0))) { + logger.error("SYNC: receiving from radio\n"); + } + radio->tx_end(); +} + +void sync_sa::run_state_cell_search() +{ + // Initialise buffer + if (cell_search_nof_trials == 0) { + srsran_vec_cf_zero(rx_buffer, slot_sz); + } + + // Receive samples + srsran::rf_buffer_t rf_buffer = {}; + rf_buffer.set_nof_samples(slot_sz); + rf_buffer.set(0, rx_buffer + slot_sz); + if (not slot_synchronizer.recv_callback(rf_buffer, last_rx_time.get_ptr(0))) { + logger.error("SYNC: receiving from radio\n"); + } + + // Run Searcher + cs_ret = searcher.run_slot(rx_buffer, slot_sz); + if (cs_ret.result < 0) { + logger.error("Failed to run searcher. Transitioning to IDLE..."); + } + + srsran_vec_cf_copy(rx_buffer, rx_buffer + slot_sz, slot_sz); + + cell_search_nof_trials++; + + // Leave CELL_SEARCH state if error or success and transition to IDLE + if (cs_ret.result == cell_search::ret_t::CELL_FOUND || cell_search_nof_trials >= cell_search_max_trials) { + phy_state.state_exit(); + } +} + +void sync_sa::run_state_sfn_sync() +{ + // Run SFN synchronization + if (slot_synchronizer.run_sfn_sync()) { + tti = slot_synchronizer.get_slot_cfg().idx; + + logger.info("SYNC: SFN synchronised successfully (SFN=%d). Transitioning to IDLE...", + tti / SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz)); + + phy_state.state_exit(true); + return; + } + + // If not synchonized, increment number of trials + sfn_sync_nof_trials++; + + // Abort SFN synchronization if the maximum number of trials is reached + if (sfn_sync_nof_trials >= sfn_sync_max_trials) { + logger.info("SYNC: The SFN sync reached the maximum number of trials (%d). Transitioning to IDLE...", + sfn_sync_nof_trials); + phy_state.state_exit(false); + } +} + +void sync_sa::run_state_cell_camping() +{ + nr::sf_worker* nr_worker = workers.wait_worker(tti); + if (nr_worker == nullptr) { + running = false; + return; + } + + // Receive samples + srsran::rf_buffer_t rf_buffer = {}; + rf_buffer.set_nof_samples(slot_sz); + rf_buffer.set(0, nr_worker->get_buffer(0, 0)); + if (not slot_synchronizer.run_camping(rf_buffer, last_rx_time)) { + logger.error("SYNC: detected out-of-sync... skipping slot ..."); + is_pending_tx_end = true; + nr_worker->release(); + return; + } + + srsran::phy_common_interface::worker_context_t context; + context.sf_idx = tti; + context.worker_ptr = nr_worker; + context.last = true; // Set last if standalone + last_rx_time.add(FDD_HARQ_DELAY_DL_MS * 1e-3); + context.tx_time.copy(last_rx_time); + // Apply current TA + context.tx_time.sub((double)ta.get_sec()); + + nr_worker->set_context(context); + + // NR worker needs to be launched first, phy_common::worker_end expects first the NR worker and the LTE worker. + tti_semaphore.push(nr_worker); + workers.start_worker(nr_worker); + + tti = TTI_ADD(tti, 1); +} + +void sync_sa::run_thread() +{ + while (running.load(std::memory_order_relaxed)) { + logger.set_context(tti); + + logger.debug("SYNC: state=%s, tti=%d", phy_state.to_string(), tti); + + switch (phy_state.run_state()) { + case sync_state::IDLE: + run_state_idle(); + break; + case sync_state::CELL_SEARCH: + run_state_cell_search(); + break; + case sync_state::SFN_SYNC: + run_state_sfn_sync(); + break; + case sync_state::CAMPING: + run_state_cell_camping(); + break; + } + } +} +void sync_sa::worker_end(const srsran::phy_common_interface::worker_context_t& w_ctx, + const bool& tx_enable, + srsran::rf_buffer_t& tx_buffer) +{ + // Wait for the green light to transmit in the current TTI + tti_semaphore.wait(w_ctx.worker_ptr); + + // Add current time alignment + srsran::rf_timestamp_t tx_time = w_ctx.tx_time; // get transmit time from the last worker + // todo: tx_time.sub((double)ta.get_sec()); + + // Check if any worker had a transmission + if (tx_enable) { + // Actual baseband transmission + radio->tx(tx_buffer, tx_time); + } else { + if (radio->is_continuous_tx()) { + if (is_pending_tx_end) { + radio->tx_end(); + is_pending_tx_end = false; + } else { + if (!radio->get_is_start_of_burst()) { + srsran::rf_buffer_t zeros_multi; + zeros_multi.set_nof_samples(tx_buffer.get_nof_samples()); + radio->tx(zeros_multi, tx_time); + } + } + } else { + radio->tx_end(); + } + } + + // Allow next TTI to transmit + tti_semaphore.release(); +} + +} // namespace nr +} // namespace srsue diff --git a/srsue/src/phy/test/CMakeLists.txt b/srsue/src/phy/test/CMakeLists.txt index d782a3abd5..addbaff5ee 100644 --- a/srsue/src/phy/test/CMakeLists.txt +++ b/srsue/src/phy/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -82,4 +82,15 @@ target_link_libraries(nr_cell_search_rf srsran_phy srsran_radio ${CMAKE_THREAD_LIBS_INIT} + ${Boost_LIBRARIES}) + +# RF based Usage example: nr_sa_cell_search_test --phy.log.level=info --stack.log.level=info --duration=10000 --freq_dl=3.67536e9 --rf.freq_offset=10e3 --rf.rx_gain=90 +add_executable(nr_sa_cell_search_test nr_sa_cell_search_test.cc) +target_link_libraries(nr_sa_cell_search_test + srsue_phy + srsran_common + srsran_phy + srsran_radio + rrc_nr_asn1 + ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES}) \ No newline at end of file diff --git a/srsue/src/phy/test/gnb_emulator.h b/srsue/src/phy/test/gnb_emulator.h new file mode 100644 index 0000000000..8456317127 --- /dev/null +++ b/srsue/src/phy/test/gnb_emulator.h @@ -0,0 +1,117 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_GNB_EMULATOR_H +#define SRSRAN_GNB_EMULATOR_H + +#include +#include +#include +#include + +class gnb_emulator +{ +private: + uint32_t sf_len = 0; + srsran_carrier_nr_t carrier = {}; + srsran_ssb_t ssb = {}; + srsran::channel channel; + std::vector buffer; + srslog::basic_logger& logger = srslog::fetch_basic_logger("GNB-EMULATOR"); + +public: + struct args_t { + double srate_hz; + srsran_carrier_nr_t carrier; + srsran_subcarrier_spacing_t ssb_scs; + srsran_ssb_pattern_t ssb_pattern; + uint32_t ssb_periodicity_ms; + srsran_duplex_mode_t duplex_mode; + srsran::channel::args_t channel; + std::string log_level = "warning"; + }; + + gnb_emulator(const args_t& args) : channel(args.channel, 1, srslog::fetch_basic_logger("GNB-EMULATOR")) + { + logger.set_level(srslog::str_to_basic_level(args.log_level)); + + srsran_assert( + std::isnormal(args.srate_hz) and args.srate_hz > 0, "Invalid sampling rate (%.2f MHz)", args.srate_hz); + + // Initialise internals + sf_len = args.srate_hz / 1000; + carrier = args.carrier; + buffer.resize(sf_len); + + srsran_ssb_args_t ssb_args = {}; + ssb_args.enable_encode = true; + srsran_assert(srsran_ssb_init(&ssb, &ssb_args) == SRSRAN_SUCCESS, "SSB initialisation failed"); + + srsran_ssb_cfg_t ssb_cfg = {}; + ssb_cfg.srate_hz = args.srate_hz; + ssb_cfg.center_freq_hz = args.carrier.dl_center_frequency_hz; + ssb_cfg.ssb_freq_hz = args.carrier.ssb_center_freq_hz; + ssb_cfg.scs = args.ssb_scs; + ssb_cfg.pattern = args.ssb_pattern; + ssb_cfg.duplex_mode = args.duplex_mode; + ssb_cfg.periodicity_ms = args.ssb_periodicity_ms; + srsran_assert(srsran_ssb_set_cfg(&ssb, &ssb_cfg) == SRSRAN_SUCCESS, "SSB set config failed"); + + // Configure channel + channel.set_srate((uint32_t)args.srate_hz); + } + + int work(uint32_t sf_idx, cf_t* baseband_buffer, const srsran::rf_timestamp_t& ts) + { + logger.set_context(sf_idx); + + // Zero buffer + srsran_vec_cf_zero(buffer.data(), sf_len); + + // Check if SSB needs to be sent + if (srsran_ssb_send(&ssb, sf_idx)) { + // Prepare PBCH message + srsran_pbch_msg_nr_t msg = {}; + + // Add SSB + if (srsran_ssb_add(&ssb, carrier.pci, &msg, buffer.data(), buffer.data()) < SRSRAN_SUCCESS) { + logger.error("Error adding SSB"); + return SRSRAN_ERROR; + } + } + + // Run channel + cf_t* in[SRSRAN_MAX_CHANNELS] = {}; + cf_t* out[SRSRAN_MAX_CHANNELS] = {}; + in[0] = buffer.data(); + out[0] = buffer.data(); + channel.run(in, out, sf_len, ts.get(0)); + + // Add buffer to baseband buffer + srsran_vec_sum_ccc(baseband_buffer, buffer.data(), baseband_buffer, sf_len); + + return SRSRAN_SUCCESS; + } + + ~gnb_emulator() { srsran_ssb_free(&ssb); } +}; + +#endif // SRSRAN_GNB_EMULATOR_H diff --git a/srsue/src/phy/test/gnb_rf_emulator.h b/srsue/src/phy/test/gnb_rf_emulator.h new file mode 100644 index 0000000000..d3f55da4eb --- /dev/null +++ b/srsue/src/phy/test/gnb_rf_emulator.h @@ -0,0 +1,158 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_GNB_RF_EMULATOR_H +#define SRSRAN_GNB_RF_EMULATOR_H + +#include "gnb_emulator.h" +#include +#include +#include +#include +#include + +class gnb_rf_emulator final : public srsran::radio_interface_phy +{ +private: + const uint32_t BUFFER_SIZE_SF = 10; + const std::string LOGNAME = "RF"; + uint32_t sf_len = 0; + srsran_ringbuffer_t ringbuffer = {}; + uint32_t slot_idx = 0; + std::atomic running = {true}; + srsran::rf_timestamp_t ts_write = {}; + std::vector buffer; + std::vector > gnb_vector; + + void run_async_slot() + { + // Early return if not running + if (not running) { + return; + } + + // Zero slot buffer + srsran_vec_cf_zero(buffer.data(), sf_len); + + for (std::shared_ptr& gnb : gnb_vector) { + srsran_assert(gnb->work(slot_idx, buffer.data(), ts_write) == SRSRAN_SUCCESS, "Failed to run gNb emulator"); + } + + // Write slot samples in ringbuffer + srsran_assert(srsran_ringbuffer_write(&ringbuffer, buffer.data(), (int)sizeof(cf_t) * sf_len) > SRSRAN_SUCCESS, + "Error writing in ringbuffer"); + + // Increment time + ts_write.add(0.001f); + } + +public: + struct args_t { + double srate_hz; + srsran_carrier_nr_t base_carrier; + srsran_subcarrier_spacing_t ssb_scs; + srsran_ssb_pattern_t ssb_pattern; + uint32_t ssb_periodicity_ms; + srsran_duplex_mode_t duplex_mode; + std::set pci_list; + float channel_hst_fd_hz = 0.0f; + float channel_hst_period_s = 7.2f; + }; + + gnb_rf_emulator(const args_t& args) + { + srsran_assert( + std::isnormal(args.srate_hz) and args.srate_hz > 0, "Invalid sampling rate (%.2f MHz)", args.srate_hz); + + sf_len = args.srate_hz / 1000; + + for (uint32_t pci : args.pci_list) { + gnb_emulator::args_t gnb_args = {}; + gnb_args.srate_hz = args.srate_hz; + gnb_args.carrier = args.base_carrier; + gnb_args.carrier.pci = pci; + gnb_args.ssb_scs = args.ssb_scs; + gnb_args.ssb_pattern = args.ssb_pattern; + gnb_args.ssb_periodicity_ms = args.ssb_periodicity_ms; + gnb_args.duplex_mode = args.duplex_mode; + + gnb_args.channel.hst_enable = std::isnormal(args.channel_hst_fd_hz) and std::isnormal(args.channel_hst_period_s); + gnb_args.channel.hst_fd_hz = args.channel_hst_fd_hz; + gnb_args.channel.hst_period_s = args.channel_hst_period_s; + gnb_args.channel.enable = gnb_args.channel.hst_enable; + + gnb_vector.emplace_back(std::make_shared(gnb_args)); + } + + srsran_assert(srsran_ringbuffer_init(&ringbuffer, sizeof(cf_t) * BUFFER_SIZE_SF * sf_len) >= SRSRAN_SUCCESS, + "Ringbuffer initialisation failed"); + + buffer.resize(BUFFER_SIZE_SF * sf_len); + } + ~gnb_rf_emulator() = default; + void tx_end() override {} + bool tx(srsran::rf_buffer_interface& tx_buffer, const srsran::rf_timestamp_interface& tx_time) override + { + return false; + } + bool rx_now(srsran::rf_buffer_interface& rx_buffer, srsran::rf_timestamp_interface& rxd_time) override + { + int nbytes = (int)(sizeof(cf_t) * rx_buffer.get_nof_samples()); + cf_t* temp_buffer = rx_buffer.get(0); + + // If the buffer is invalid, use internal temporal buffer + if (temp_buffer == nullptr) { + temp_buffer = buffer.data(); + } + + // As long as there are not enough samples + while (srsran_ringbuffer_status(&ringbuffer) < nbytes and running) { + run_async_slot(); + } + + if (not running) { + return true; + } + + srsran_assert(srsran_ringbuffer_read(&ringbuffer, temp_buffer, nbytes) >= SRSRAN_SUCCESS, + "Error reading from ringbuffer"); + + return true; + } + void set_tx_freq(const uint32_t& carrier_idx, const double& freq) override {} + void set_rx_freq(const uint32_t& carrier_idx, const double& freq) override {} + void release_freq(const uint32_t& carrier_idx) override {} + void set_tx_gain(const float& gain) override {} + void set_rx_gain_th(const float& gain) override {} + void set_rx_gain(const float& gain) override {} + void set_tx_srate(const double& srate) override {} + void set_rx_srate(const double& srate) override {} + void set_channel_rx_offset(uint32_t ch, int32_t offset_samples) override {} + double get_freq_offset() override { return 0; } + float get_rx_gain() override { return 0; } + bool is_continuous_tx() override { return false; } + bool get_is_start_of_burst() override { return false; } + bool is_init() override { return false; } + void reset() override { running = false; } + srsran_rf_info_t* get_info() override { return nullptr; } +}; + +#endif // SRSRAN_GNB_RF_EMULATOR_H diff --git a/srsue/src/phy/test/nr_cell_search_rf.cc b/srsue/src/phy/test/nr_cell_search_rf.cc index 1569bc78bd..d18db86123 100644 --- a/srsue/src/phy/test/nr_cell_search_rf.cc +++ b/srsue/src/phy/test/nr_cell_search_rf.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/phy/test/nr_cell_search_test.cc b/srsue/src/phy/test/nr_cell_search_test.cc index 1b78d1e6a0..8f21d1eebd 100644 --- a/srsue/src/phy/test/nr_cell_search_test.cc +++ b/srsue/src/phy/test/nr_cell_search_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -57,7 +57,7 @@ class test_gnb srsran::channel::args_t channel; std::string log_level = "error"; - srsran_ssb_patern_t get_ssb_pattern() const { return srsran::srsran_band_helper().get_ssb_pattern(band, ssb_scs); } + srsran_ssb_pattern_t get_ssb_pattern() const { return srsran::srsran_band_helper().get_ssb_pattern(band, ssb_scs); } srsran_duplex_mode_t get_duplex_mode() const { return srsran::srsran_band_helper().get_duplex_mode(band); } }; diff --git a/srsue/src/phy/test/nr_sa_cell_search_test.cc b/srsue/src/phy/test/nr_sa_cell_search_test.cc new file mode 100644 index 0000000000..1f77697a0e --- /dev/null +++ b/srsue/src/phy/test/nr_sa_cell_search_test.cc @@ -0,0 +1,455 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "gnb_rf_emulator.h" +#include "srsran/common/band_helper.h" +#include "srsran/common/crash_handler.h" +#include "srsran/common/string_helpers.h" +#include "srsue/hdr/phy/phy_nr_sa.h" +#include "test/phy/dummy_ue_stack.h" +#include +#include +#include + +struct args_t { + // Generic parameters + double srate_hz = 11.52e6; + srsran_carrier_nr_t base_carrier = SRSRAN_DEFAULT_CARRIER_NR; + srsran_ssb_pattern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; + srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_15kHz; + srsran_duplex_mode_t duplex_mode = SRSRAN_DUPLEX_MODE_FDD; + uint32_t duration_ms = 1000; + std::string phy_log_level = "warning"; + std::string stack_log_level = "warning"; + + // Simulation parameters + uint32_t sim_ssb_periodicity_ms = 10; + float sim_channel_hst_fd_hz = 0.0f; + float sim_channel_hst_period_s = 7.2f; + std::set sim_cell_pci; + + // RF parameters + std::string rf_device_name = "auto"; + std::string rf_device_args = "auto"; + std::string rf_log_level = "info"; + float rf_rx_gain_dB = 20.0f; + float rf_freq_offset_Hz = 0.0f; + + void set_ssb_from_band() + { + srsran::srsran_band_helper bands; + + // Deduce band number + uint16_t band = bands.get_band_from_dl_freq_Hz(base_carrier.dl_center_frequency_hz); + srsran_assert(band != UINT16_MAX, "Invalid band"); + + // Deduce point A in Hz + double pointA_Hz = + bands.get_abs_freq_point_a_from_center_freq(base_carrier.nof_prb, base_carrier.dl_center_frequency_hz); + + // Deduce DL center frequency ARFCN + uint32_t pointA_arfcn = bands.freq_to_nr_arfcn(pointA_Hz); + srsran_assert(pointA_arfcn != 0, "Invalid frequency"); + + // Select a valid SSB subcarrier spacing + ssb_scs = bands.get_ssb_scs(band); + + // Deduce SSB center frequency ARFCN + uint32_t ssb_arfcn = bands.get_abs_freq_ssb_arfcn(band, ssb_scs, pointA_arfcn); + srsran_assert(ssb_arfcn, "Invalid SSB center frequency"); + + duplex_mode = bands.get_duplex_mode(band); + ssb_pattern = bands.get_ssb_pattern(band, ssb_scs); + base_carrier.ssb_center_freq_hz = bands.nr_arfcn_to_freq(ssb_arfcn); + } +}; + +// shorten boost program options namespace +namespace bpo = boost::program_options; + +static void pci_list_parse_helper(std::string& list_str, std::set& list) +{ + if (list_str == "all") { + // Add all possible cells + for (int i = 0; i < 504; i++) { + list.insert(i); + } + } else if (list_str == "none") { + // Do nothing + } else if (not list_str.empty()) { + // Remove spaces from neightbour cell list + list_str = srsran::string_remove_char(list_str, ' '); + + // Add cell to known cells + srsran::string_parse_list(list_str, ',', list); + } +} + +int parse_args(int argc, char** argv, args_t& args) +{ + int ret = SRSRAN_SUCCESS; + + std::string simulation_cell_list = ""; + + bpo::options_description options("General options"); + bpo::options_description phy("Physical layer options"); + bpo::options_description stack("Stack options"); + bpo::options_description over_the_air("Mode 1: Over the air options (Default)"); + bpo::options_description simulation("Mode 2: Simulation options (enabled if simulation_cell_list is not empty)"); + + // clang-format off + over_the_air.add_options() + ("rf.device_name", bpo::value(&args.rf_device_name)->default_value(args.rf_device_name), "RF Device Name") + ("rf.device_args", bpo::value(&args.rf_device_args)->default_value(args.rf_device_args), "RF Device arguments") + ("rf.log_level", bpo::value(&args.rf_log_level)->default_value(args.rf_log_level), "RF Log level (none, warning, info, debug)") + ("rf.rx_gain", bpo::value(&args.rf_rx_gain_dB)->default_value(args.rf_rx_gain_dB), "RF Receiver gain in dB") + ("rf.freq_offset", bpo::value(&args.rf_freq_offset_Hz)->default_value(args.rf_freq_offset_Hz), "RF Frequency offset") + ; + + simulation.add_options() + ("sim.pci_list", bpo::value(&simulation_cell_list)->default_value(simulation_cell_list), "Comma separated PCI cell list to simulate") + ("sim.bw", bpo::value(&args.base_carrier.nof_prb)->default_value(args.base_carrier.nof_prb), "Carrier bandwidth in RB") + ("sim.ssb_period", bpo::value(&args.sim_ssb_periodicity_ms)->default_value(args.sim_ssb_periodicity_ms), "SSB period in ms") + ("sim.channel.hst.fd", bpo::value(&args.sim_channel_hst_fd_hz)->default_value(args.sim_channel_hst_fd_hz), "Channel emulator HST maximum frequency") + ("sim.channel.hst.period", bpo::value(&args.sim_channel_hst_period_s)->default_value(args.sim_channel_hst_period_s), "Channel emulator HST period") + ; + + phy.add_options() + ("phy.srate", bpo::value(&args.srate_hz)->default_value(args.srate_hz), "Sampling Rate in Hz") + ("phy.log.level", bpo::value(&args.phy_log_level)->default_value(args.phy_log_level), "Physical layer logging level") + ; + + stack.add_options() + ("stack.log.level", bpo::value(&args.stack_log_level)->default_value(args.stack_log_level), "Stack logging level") + ; + + options.add(over_the_air).add(simulation).add(phy).add(stack).add_options() + ("help,h", "Show this message") + ("duration", bpo::value(&args.duration_ms)->default_value(args.duration_ms), "Duration of the test in milli-seconds") + ("freq_dl", bpo::value(&args.base_carrier.dl_center_frequency_hz)->default_value(args.base_carrier.dl_center_frequency_hz), "Carrier center frequency in Hz") + ; + // clang-format on + + bpo::variables_map vm; + try { + bpo::store(bpo::command_line_parser(argc, argv).options(options).run(), vm); + bpo::notify(vm); + } catch (bpo::error& e) { + std::cerr << e.what() << std::endl; + ret = SRSRAN_ERROR; + } + + // help option was given or error - print usage and exit + if (vm.count("help") || ret) { + std::cout << "Usage: " << argv[0] << " [OPTIONS] config_file" << std::endl << std::endl; + std::cout << options << std::endl << std::endl; + ret = SRSRAN_ERROR; + } + + // Parse PCI lists + pci_list_parse_helper(simulation_cell_list, args.sim_cell_pci); + + args.set_ssb_from_band(); + + return ret; +} + +class dummy_ue +{ +private: + ue_dummy_stack stack; + srsue::phy_nr_sa phy; + +public: + struct args_t { + srsue::phy_args_nr_t phy; + ue_dummy_stack::args_t stack; + }; + dummy_ue(const args_t& args, srsran::radio_interface_phy* radio) : stack(args.stack, phy), phy("PHY") + { + srsran_assert(phy.init(args.phy, &stack, radio) == SRSRAN_SUCCESS, "Failed to initialise PHY"); + phy.wait_initialize(); + } + + bool cell_search_read_and_clear() { return stack.get_cell_search_finished(); } + + bool start_cell_search(const srsue::phy_interface_stack_nr::cell_search_args_t& args) + { + return phy.start_cell_search(args); + } + + bool start_cell_select(const srsue::phy_interface_stack_nr::cell_select_args_t& args) + { + return phy.start_cell_select(args); + } + + void run_tti() { stack.tick(); } + void stop() + { + // First transition PHY to IDLE + phy.reset_nr(); + + // Make sure PHY transitioned to IDLE + // ... + + // Stop stack, it will let PHY free run + stack.stop(); + + // Stop PHY + phy.stop(); + } + + const ue_dummy_stack::metrics_t& get_metrics() const { return stack.get_metrics(); } + void reset_metrics() { stack.reset_metrics(); } +}; + +struct cell_search_result_t { + bool found = false; + double ssb_abs_freq_hz = 0.0f; + srsran_subcarrier_spacing_t ssb_scs = srsran_subcarrier_spacing_15kHz; + srsran_ssb_pattern_t ssb_pattern = SRSRAN_SSB_PATTERN_A; + srsran_duplex_mode_t duplex_mode = SRSRAN_DUPLEX_MODE_FDD; + srsran_mib_nr_t mib = {}; + uint32_t pci = 0; +}; + +/* + * The following function searches for cells in all possible SSB absolute frequencies within the baseband range. It + * returns the first found cell. + */ +static cell_search_result_t cell_search(const args_t& args, dummy_ue& ue) +{ + cell_search_result_t ret = {}; + + // Base cell search arguments + srsue::phy_nr_sa::cell_search_args_t cs_args = {}; + cs_args.center_freq_hz = args.base_carrier.dl_center_frequency_hz; + cs_args.ssb_scs = args.ssb_scs; + cs_args.ssb_pattern = args.ssb_pattern; + cs_args.duplex_mode = args.duplex_mode; + + // Deduce band number + srsran::srsran_band_helper bands; + uint16_t band = bands.get_band_from_dl_freq_Hz(args.base_carrier.dl_center_frequency_hz); + srsran_assert(band != UINT16_MAX, "Invalid band"); + + // Calculate SSB center frequency boundaries + double ssb_bw_hz = SRSRAN_SSB_BW_SUBC * bands.get_ssb_scs(band); + double ssb_center_freq_min_hz = args.base_carrier.dl_center_frequency_hz - (args.srate_hz * 0.7 - ssb_bw_hz) / 2.0; + double ssb_center_freq_max_hz = args.base_carrier.dl_center_frequency_hz + (args.srate_hz * 0.7 - ssb_bw_hz) / 2.0; + uint32_t ssb_scs_hz = SRSRAN_SUBC_SPACING_NR(args.ssb_scs); + + // Get sync raster + srsran::srsran_band_helper::sync_raster_t ss = bands.get_sync_raster(band, args.ssb_scs); + srsran_assert(ss.valid(), "Invalid synchronization raster"); + + // Iterate every possible frequency in the synchronization raster + while (not ss.end()) { + // Get SSB center frequency + cs_args.ssb_freq_hz = ss.get_frequency(); + + // Advance SSB frequency raster + ss.next(); + + // Calculate frequency offset between the base-band center frequency and the SSB absolute frequency + uint32_t offset_hz = (uint32_t)std::abs(std::round(cs_args.ssb_freq_hz - args.base_carrier.dl_center_frequency_hz)); + + // The SSB absolute frequency is invalid if it is outside the range and the offset is NOT multiple of the subcarrier + // spacing + if ((cs_args.ssb_freq_hz < ssb_center_freq_min_hz) or (cs_args.ssb_freq_hz > ssb_center_freq_max_hz) or + (offset_hz % ssb_scs_hz != 0)) { + // Skip this frequency + continue; + } + + // Transition PHY to cell search + srsran_assert(ue.start_cell_search(cs_args), "Failed cell search start"); + + // Run slot until the PHY reported to the stack + while (not ue.cell_search_read_and_clear()) { + ue.run_tti(); + } + + const ue_dummy_stack::metrics_t& metrics = ue.get_metrics(); + + // Skip printing cell search findings if no SSB is found + if (metrics.cell_search.empty()) { + continue; + } + + // Print found cells + printf("Cells found at SSB center frequency %.2f MHz:\n", cs_args.ssb_freq_hz / 1e6); + printf("| %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s | %10s |\n", + "PCI", + "SSB", + "Count", + "RSRP min", + "RSRP avg", + "RSRP max", + "SNR min", + "SNR avg", + "SNR max", + "CFO min", + "CFO avg", + "CFO max"); + + // For each found PCI... + for (auto& pci : metrics.cell_search) { + // For each found beam... + for (auto& ssb : pci.second) { + // Print stats + printf("| %10d | %10d | %10d | %+10.1f | %+10.1f | %+10.1f | %+10.1f | %+10.1f | %+10.1f | %+10.1f | %+10.1f | " + "%+10.1f |\n", + pci.first, + ssb.first, + (uint32_t)ssb.second.count, + ssb.second.rsrp_db_min, + ssb.second.rsrp_db_avg, + ssb.second.rsrp_db_max, + ssb.second.snr_db_min, + ssb.second.snr_db_avg, + ssb.second.snr_db_max, + ssb.second.cfo_hz_min, + ssb.second.cfo_hz_avg, + ssb.second.cfo_hz_max); + + // If this is the first found cell, then set return value + if (not ret.found) { + ret.found = true; + ret.ssb_abs_freq_hz = cs_args.ssb_freq_hz; + ret.ssb_scs = cs_args.ssb_scs; + ret.ssb_pattern = cs_args.ssb_pattern; + ret.duplex_mode = cs_args.duplex_mode; + ret.pci = pci.first; + srsran_assert(srsran_pbch_msg_nr_mib_unpack(&ssb.second.last_result.pbch_msg, &ret.mib) == SRSRAN_SUCCESS, + "Error unpacking MIB"); + } + } + } + + // Reset stack metrics + ue.reset_metrics(); + } + + return ret; +} + +int main(int argc, char** argv) +{ + srsran_debug_handle_crash(argc, argv); + + // Parse Test arguments + args_t args; + srsran_assert(parse_args(argc, argv, args) == SRSRAN_SUCCESS, "Failed to parse arguments"); + + // Initialise logging infrastructure + srslog::init(); + + // Radio can be constructed from different options + std::shared_ptr radio = nullptr; + + // Build radio + if (not args.sim_cell_pci.empty()) { + // Create Radio as gNb emulator if the device RF name is not defined + gnb_rf_emulator::args_t gnb_args = {}; + gnb_args.srate_hz = args.srate_hz; + gnb_args.base_carrier = args.base_carrier; + gnb_args.ssb_pattern = args.ssb_pattern; + gnb_args.ssb_periodicity_ms = args.sim_ssb_periodicity_ms; + gnb_args.ssb_scs = args.ssb_scs; + gnb_args.duplex_mode = args.duplex_mode; + gnb_args.pci_list = args.sim_cell_pci; + gnb_args.channel_hst_fd_hz = args.sim_channel_hst_fd_hz; + gnb_args.channel_hst_period_s = args.sim_channel_hst_period_s; + + radio = std::make_shared(gnb_args); + } else { + // Create an actual radio based on RF + srsran::rf_args_t rf_args = {}; + rf_args.type = "multi"; + rf_args.log_level = args.rf_log_level; + rf_args.srate_hz = args.srate_hz; + rf_args.rx_gain = args.rf_rx_gain_dB; + rf_args.nof_carriers = 1; + rf_args.nof_antennas = 1; + rf_args.device_args = args.rf_device_args; + rf_args.device_name = args.rf_device_name; + rf_args.freq_offset = args.rf_freq_offset_Hz; + + // Instantiate + std::shared_ptr r = std::make_shared(); + srsran_assert(r->init(rf_args, nullptr) == SRSRAN_SUCCESS, "Failed Radio initialisation"); + + // Move to base pointer + radio = std::move(r); + + // Set sampling rate + radio->set_rx_srate(args.srate_hz); + + // Set DL center frequency + radio->set_rx_freq(0, args.base_carrier.dl_center_frequency_hz); + + // Set Rx gain + radio->set_rx_gain(args.rf_rx_gain_dB); + } + + // Create dummy UE + dummy_ue::args_t ue_args = {}; + ue_args.phy.srate_hz = args.srate_hz; + ue_args.phy.log.phy_level = args.phy_log_level; + ue_args.stack.log_level = args.stack_log_level; + dummy_ue ue(ue_args, radio.get()); + + // Perform cell search + cell_search_result_t found_cell = cell_search(args, ue); + + // Perform cell select + if (found_cell.found) { + srsue::phy_interface_stack_nr::cell_select_args_t cs_args = {}; + cs_args.ssb_cfg.srate_hz = args.srate_hz; + cs_args.ssb_cfg.center_freq_hz = args.base_carrier.dl_center_frequency_hz; + cs_args.ssb_cfg.ssb_freq_hz = found_cell.ssb_abs_freq_hz; + cs_args.ssb_cfg.scs = found_cell.ssb_scs; + cs_args.ssb_cfg.pattern = found_cell.ssb_pattern; + cs_args.ssb_cfg.duplex_mode = found_cell.duplex_mode; + cs_args.ssb_cfg.periodicity_ms = 10; + cs_args.carrier = args.base_carrier; + cs_args.carrier.pci = found_cell.pci; + + srsran_assert(ue.start_cell_select(cs_args), "Failed to start cell selection\n"); + + for (uint32_t i = 0; i < 1000; i++) { + ue.run_tti(); + } + } + + // Tear down UE + ue.stop(); + + for (uint32_t i = 0; i < 1000; i++) { + ue.run_tti(); + } + + // Stop Radio + radio->reset(); + + return 0; +} \ No newline at end of file diff --git a/srsue/src/phy/test/scell_search_test.cc b/srsue/src/phy/test/scell_search_test.cc index c334f63532..9ffaabd0e7 100644 --- a/srsue/src/phy/test/scell_search_test.cc +++ b/srsue/src/phy/test/scell_search_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -636,13 +636,13 @@ int main(int argc, char** argv) dci.rnti = serving_cell_pdsch_rnti; dci.is_tdd = false; dci.is_dwpts = false; - dci.is_ra_order = false; + dci.is_pdcch_order = false; dci.tb_cw_swap = false; dci.pconf = false; dci.power_offset = false; dci.tpc_pucch = 0; - dci.ra_preamble = 0; - dci.ra_mask_idx = 0; + dci.preamble_idx = 0; + dci.prach_mask_idx = 0; dci.srs_request = false; dci.srs_request_present = false; dci.cif_present = false; diff --git a/srsue/src/phy/test/ue_phy_test.cc b/srsue/src/phy/test/ue_phy_test.cc index daf38f1ed6..52d635e8ad 100644 --- a/srsue/src/phy/test/ue_phy_test.cc +++ b/srsue/src/phy/test/ue_phy_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -111,8 +111,7 @@ class phy_test_bench : public srsran::thread } void tb_decoded(uint32_t cc_idx, mac_grant_dl_t grant, bool* ack) override {} void bch_decoded_ok(uint32_t cc_idx, uint8_t* payload, uint32_t len) override {} - void mch_decoded(uint32_t len, bool crc) override {} - void new_mch_dl(const srsran_pdsch_grant_t& phy_grant, tb_action_dl_t* action) override {} + void mch_decoded(uint32_t len, bool crc, uint8_t* payload) override {} void set_mbsfn_config(uint32_t nof_mbsfn_services) override {} void run_tti(const uint32_t tti, const uint32_t tti_jump) override { @@ -517,7 +516,7 @@ int main(int argc, char** argv) phy_test->start(); // 1. Cell search - TESTASSERT(phy_test->get_phy_interface_rrc()->cell_search()); + TESTASSERT(phy_test->get_phy_interface_rrc()->cell_search(-1)); TESTASSERT(phy_test->get_stack()->wait_cell_search(default_timeout)); TESTASSERT(phy_test->get_stack()->cell_search_ret.found == srsue::rrc_interface_phy_lte::cell_search_ret_t::CELL_FOUND); diff --git a/srsue/src/stack/CMakeLists.txt b/srsue/src/stack/CMakeLists.txt index 9355307164..7cac33dd0b 100644 --- a/srsue/src/stack/CMakeLists.txt +++ b/srsue/src/stack/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -20,12 +20,13 @@ add_subdirectory(mac_common) add_subdirectory(mac) +add_subdirectory(mac_nr) add_subdirectory(rrc) +add_subdirectory(rrc_nr) add_subdirectory(upper) set(SOURCES ue_stack_lte.cc) add_library(srsue_stack STATIC ${SOURCES}) -add_subdirectory(mac_nr) set(SOURCES ue_stack_nr.cc) add_library(srsue_nr_stack STATIC ${SOURCES}) diff --git a/srsue/src/stack/mac/CMakeLists.txt b/srsue/src/stack/mac/CMakeLists.txt index 31cacc1f0e..5c3c13f9e2 100644 --- a/srsue/src/stack/mac/CMakeLists.txt +++ b/srsue/src/stack/mac/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/src/stack/mac/demux.cc b/srsue/src/stack/mac/demux.cc index 1d1d306eb7..18881fcd43 100644 --- a/srsue/src/stack/mac/demux.cc +++ b/srsue/src/stack/mac/demux.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -261,7 +261,7 @@ void demux::process_mch_pdu(srsran::mch_pdu* mch_msg) } Debug("Wrote MCH LCID=%d to RLC", lcid); if (1 == mch_lcids[lcid]) { - rlc->write_pdu_mch(lcid, mch_msg->get()->get_sdu_ptr(), mch_msg->get()->get_payload_size()); + rlc->write_pdu_mch(0, lcid, mch_msg->get()->get_sdu_ptr(), mch_msg->get()->get_payload_size()); } } } diff --git a/srsue/src/stack/mac/dl_harq.cc b/srsue/src/stack/mac/dl_harq.cc index 61afe18fac..beb9788808 100644 --- a/srsue/src/stack/mac/dl_harq.cc +++ b/srsue/src/stack/mac/dl_harq.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/mac/mac.cc b/srsue/src/stack/mac/mac.cc index 62bb6bd06e..51c977d1eb 100644 --- a/srsue/src/stack/mac/mac.cc +++ b/srsue/src/stack/mac/mac.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -50,7 +50,6 @@ mac::mac(const char* logname, ext_task_sched_handle task_sched_) : dl_harq.at(PCELL_CC_IDX) = dl_harq_entity_ptr(new dl_harq_entity(PCELL_CC_IDX)); srsran_softbuffer_rx_init(&pch_softbuffer, 100); - srsran_softbuffer_rx_init(&mch_softbuffer, 100); // Keep initialising members bzero(&metrics, sizeof(mac_metrics_t)); @@ -62,7 +61,6 @@ mac::~mac() stop(); srsran_softbuffer_rx_free(&pch_softbuffer); - srsran_softbuffer_rx_free(&mch_softbuffer); } bool mac::init(phy_interface_mac_lte* phy, rlc_interface_mac* rlc, rrc_interface_mac* rrc) @@ -333,12 +331,12 @@ void mac::bch_decoded_ok(uint32_t cc_idx, uint8_t* payload, uint32_t len) } } -void mac::mch_decoded(uint32_t len, bool crc) +void mac::mch_decoded(uint32_t len, bool crc, uint8_t* payload) { // Parse MAC header if (crc) { mch_msg.init_rx(len); - mch_msg.parse_packet(mch_payload_buffer); + mch_msg.parse_packet(payload); while (mch_msg.next()) { for (uint32_t i = 0; i < phy_mbsfn_cfg.nof_mbsfn_services; i++) { if (srsran::mch_lcid::MCH_SCHED_INFO == mch_msg.get()->mch_ce_type()) { @@ -352,11 +350,11 @@ void mac::mch_decoded(uint32_t len, bool crc) } } - demux_unit.push_pdu_mch(mch_payload_buffer, len); + demux_unit.push_pdu_mch(payload, len); process_pdus(); if (pcap) { - pcap->write_dl_mch(mch_payload_buffer, len, true, phy_h->get_current_tti(), 0); + pcap->write_dl_mch(payload, len, true, phy_h->get_current_tti(), 0); } std::lock_guard lock(metrics_mutex); @@ -371,7 +369,10 @@ void mac::mch_decoded(uint32_t len, bool crc) void mac::tb_decoded(uint32_t cc_idx, mac_grant_dl_t grant, bool ack[SRSRAN_MAX_CODEWORDS]) { - if (SRSRAN_RNTI_ISRAR(grant.rnti)) { + if (grant.is_pdcch_order) { + ra_procedure.set_config_ded(grant.preamble_idx, grant.prach_mask_idx); + ra_procedure.start_pdcch_order(); + } else if (SRSRAN_RNTI_ISRAR(grant.rnti)) { if (ack[0]) { ra_procedure.tb_decoded_ok(cc_idx, grant.tti); } @@ -439,6 +440,9 @@ void mac::new_grant_dl(uint32_t cc_idx, action->tb[0].rv = grant.tb[0].rv; srsran_softbuffer_rx_reset_cb(&pch_softbuffer, 1); } + } else if (grant.is_pdcch_order) { + // if the grant is a PDCCH order then there is no associated PDSCH + action->tb[0].enabled = false; } else if (!(grant.rnti == SRSRAN_SIRNTI && cc_idx != 0)) { // If PDCCH for C-RNTI and RA procedure in Contention Resolution, notify it if (grant.rnti == uernti.get_crnti() && ra_procedure.is_contention_resolution()) { @@ -524,14 +528,6 @@ void mac::new_grant_ul(uint32_t cc_idx, } // end of holding metrics mutex } -void mac::new_mch_dl(const srsran_pdsch_grant_t& phy_grant, tb_action_dl_t* action) -{ - action->generate_ack = false; - action->tb[0].enabled = true; - action->tb[0].payload = mch_payload_buffer; - action->tb[0].softbuffer.rx = &mch_softbuffer; - srsran_softbuffer_rx_reset_cb(&mch_softbuffer, 1); -} void mac::setup_timers(int time_alignment_timer) { @@ -674,11 +670,11 @@ void mac::get_metrics(mac_metrics_t m[SRSRAN_MAX_CARRIERS]) dl_avg_ret /= dl_avg_ret_count; } - Info("DL retx: %.2f \%%, perpkt: %.2f, UL retx: %.2f \%% perpkt: %.2f", - rx_pkts ? ((float)100 * rx_errors / rx_pkts) : 0.0f, - dl_avg_ret, - tx_pkts ? ((float)100 * tx_errors / tx_pkts) : 0.0f, - ul_harq.at(PCELL_CC_IDX)->get_average_retx()); + Debug("DL retx: %.2f \%%, perpkt: %.2f, UL retx: %.2f \%% perpkt: %.2f", + rx_pkts ? ((float)100 * rx_errors / rx_pkts) : 0.0f, + dl_avg_ret, + tx_pkts ? ((float)100 * tx_errors / tx_pkts) : 0.0f, + ul_harq.at(PCELL_CC_IDX)->get_average_retx()); metrics[PCELL_CC_IDX].ul_buffer = (int)bsr_procedure.get_buffer_state(); memcpy(m, metrics, sizeof(mac_metrics_t) * SRSRAN_MAX_CARRIERS); diff --git a/srsue/src/stack/mac/mux.cc b/srsue/src/stack/mac/mux.cc index 40623f59fd..aa131cc813 100644 --- a/srsue/src/stack/mac/mux.cc +++ b/srsue/src/stack/mac/mux.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/mac/proc_bsr.cc b/srsue/src/stack/mac/proc_bsr.cc index 12707d6c4a..dab30ec20a 100644 --- a/srsue/src/stack/mac/proc_bsr.cc +++ b/srsue/src/stack/mac/proc_bsr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/mac/proc_phr.cc b/srsue/src/stack/mac/proc_phr.cc index 7ff724ea82..ea7a81ce04 100644 --- a/srsue/src/stack/mac/proc_phr.cc +++ b/srsue/src/stack/mac/proc_phr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/mac/proc_ra.cc b/srsue/src/stack/mac/proc_ra.cc index ccab33d56a..59d2527feb 100644 --- a/srsue/src/stack/mac/proc_ra.cc +++ b/srsue/src/stack/mac/proc_ra.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -32,13 +32,11 @@ namespace srsue { -const char* state_str[] = {"RA: INIT: ", - "RA: PDCCH: ", - "RA: Rx: ", +const char* state_str[] = {"RA: IDLE: ", + "RA: PDCCH: ", + "RA: Rx: ", "RA: Backoff: ", - "RA: ConRes: ", - "RA: WaitComplt: ", - "RA: Complt: "}; + "RA: ConRes: "}; #define rError(fmt, ...) logger.error("%s" fmt, state_str[state], ##__VA_ARGS__) #define rInfo(fmt, ...) logger.info("%s" fmt, state_str[state], ##__VA_ARGS__) @@ -159,8 +157,11 @@ void ra_proc::state_pdcch_setup() ra_tti = info.tti_ra; ra_rnti = 1 + (ra_tti % 10) + (10 * info.f_id); rInfo("seq=%d, ra-rnti=0x%x, ra-tti=%d, f_id=%d", sel_preamble.load(), ra_rnti, info.tti_ra, info.f_id); - srsran::console( - "Random Access Transmission: seq=%d, tti=%d, ra-rnti=0x%x\n", sel_preamble.load(), info.tti_ra, ra_rnti); + srsran::console("Random Access Transmission%s: seq=%d, tti=%d, ra-rnti=0x%x\n", + (started_by_pdcch) ? " (PDCCH order)" : "", + sel_preamble.load(), + info.tti_ra, + ra_rnti); rar_window_st = ra_tti + 3; rntis->set_rar_rnti(ra_rnti); state = RESPONSE_RECEPTION; @@ -525,7 +526,7 @@ void ra_proc::start_pdcch_order() rInfo("Starting PRACH by PDCCH order"); initialization(); } else { - logger.warning("Trying to start PRACH by MAC order in invalid state (%s)", state_str[state]); + logger.warning("Trying to start PRACH by PDCCH order in invalid state (%s)", state_str[state]); } } diff --git a/srsue/src/stack/mac/proc_sr.cc b/srsue/src/stack/mac/proc_sr.cc index 5e8a04a6db..ad401a9abe 100644 --- a/srsue/src/stack/mac/proc_sr.cc +++ b/srsue/src/stack/mac/proc_sr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/mac/test/CMakeLists.txt b/srsue/src/stack/mac/test/CMakeLists.txt index a1f9a2df6e..cd26ece30a 100644 --- a/srsue/src/stack/mac/test/CMakeLists.txt +++ b/srsue/src/stack/mac/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/src/stack/mac/test/mac_test.cc b/srsue/src/stack/mac/test/mac_test.cc index 7cd4894bd1..4f8a3d71ea 100644 --- a/srsue/src/stack/mac/test/mac_test.cc +++ b/srsue/src/stack/mac/test/mac_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/mac/ul_harq.cc b/srsue/src/stack/mac/ul_harq.cc index 89185a4c24..387e61e957 100644 --- a/srsue/src/stack/mac/ul_harq.cc +++ b/srsue/src/stack/mac/ul_harq.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/mac_common/CMakeLists.txt b/srsue/src/stack/mac_common/CMakeLists.txt index 06a7c1f2ea..2c6e09cbf8 100644 --- a/srsue/src/stack/mac_common/CMakeLists.txt +++ b/srsue/src/stack/mac_common/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/src/stack/mac_common/mac_common.cc b/srsue/src/stack/mac_common/mac_common.cc index 3c6dfda24d..fcf45d50d6 100644 --- a/srsue/src/stack/mac_common/mac_common.cc +++ b/srsue/src/stack/mac_common/mac_common.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/mac_nr/CMakeLists.txt b/srsue/src/stack/mac_nr/CMakeLists.txt index 2b98a9b3d8..dbcfcf625f 100644 --- a/srsue/src/stack/mac_nr/CMakeLists.txt +++ b/srsue/src/stack/mac_nr/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/src/stack/mac_nr/demux_nr.cc b/srsue/src/stack/mac_nr/demux_nr.cc index 4620a9e534..d691dc5f27 100644 --- a/srsue/src/stack/mac_nr/demux_nr.cc +++ b/srsue/src/stack/mac_nr/demux_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -30,47 +30,80 @@ demux_nr::demux_nr(srslog::basic_logger& logger_) : logger(logger_) {} demux_nr::~demux_nr() {} -int32_t demux_nr::init(rlc_interface_mac* rlc_) +int32_t demux_nr::init(rlc_interface_mac* rlc_, phy_interface_mac_nr* phy_) { rlc = rlc_; + phy = phy_; return SRSRAN_SUCCESS; } +uint64_t demux_nr::get_received_crueid() +{ + return received_crueid; +} + // Enqueues PDU and returns quickly void demux_nr::push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti) { pdu_queue.push(std::move(pdu)); } +void demux_nr::push_bcch(srsran::unique_byte_buffer_t pdu) +{ + bcch_queue.push(std::move(pdu)); +} + +/* Demultiplexing of MAC PDU associated with a Temporal C-RNTI. The PDU will + * remain in buffer until demultiplex_pending_pdu() is called. + * This features is provided to enable the Random Access Procedure to decide + * whether the PDU shall pass to upper layers or not, which depends on the + * Contention Resolution result. + * + * Warning: this function does some processing here assuming ACK deadline is not an + * issue here because Temp C-RNTI messages have small payloads + */ +void demux_nr::push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tti) +{ + received_crueid = 0; + handle_pdu(rx_pdu_tcrnti, std::move(pdu)); +} + void demux_nr::process_pdus() { + // Handle first BCCH + while (not bcch_queue.empty()) { + srsran::unique_byte_buffer_t pdu = bcch_queue.wait_pop(); + logger.debug(pdu->msg, pdu->N_bytes, "Handling MAC BCCH PDU (%d B)", pdu->N_bytes); + rlc->write_pdu_bcch_dlsch(pdu->msg, pdu->N_bytes); + } + // Then user PDUs while (not pdu_queue.empty()) { srsran::unique_byte_buffer_t pdu = pdu_queue.wait_pop(); - handle_pdu(std::move(pdu)); + handle_pdu(rx_pdu, std::move(pdu)); } } /// Handling of DLSCH PDUs only -void demux_nr::handle_pdu(srsran::unique_byte_buffer_t pdu) +void demux_nr::handle_pdu(srsran::mac_sch_pdu_nr& pdu_buffer, srsran::unique_byte_buffer_t pdu) { logger.debug(pdu->msg, pdu->N_bytes, "Handling MAC PDU (%d B)", pdu->N_bytes); - rx_pdu.init_rx(); - if (rx_pdu.unpack(pdu->msg, pdu->N_bytes) != SRSRAN_SUCCESS) { + pdu_buffer.init_rx(); + if (pdu_buffer.unpack(pdu->msg, pdu->N_bytes) != SRSRAN_SUCCESS) { return; } if (logger.info.enabled()) { fmt::memory_buffer str_buffer; - rx_pdu.to_string(str_buffer); + pdu_buffer.to_string(str_buffer); logger.info("%s", srsran::to_c_str(str_buffer)); } - for (uint32_t i = 0; i < rx_pdu.get_num_subpdus(); ++i) { - srsran::mac_sch_subpdu_nr subpdu = rx_pdu.get_subpdu(i); + for (uint32_t i = 0; i < pdu_buffer.get_num_subpdus(); ++i) { + srsran::mac_sch_subpdu_nr subpdu = pdu_buffer.get_subpdu(i); logger.debug("Handling subPDU %d/%d: rnti=0x%x lcid=%d, sdu_len=%d", i + 1, - rx_pdu.get_num_subpdus(), + pdu_buffer.get_num_subpdus(), subpdu.get_c_rnti(), subpdu.get_lcid(), subpdu.get_sdu_length()); @@ -81,10 +114,12 @@ void demux_nr::handle_pdu(srsran::unique_byte_buffer_t pdu) logger.info("DRX CE not implemented."); break; case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::TA_CMD: - logger.info("Timing Advance CE not implemented."); + logger.info("Received TA=%d.", subpdu.get_ta().ta_command); + phy->set_timeadv(0, subpdu.get_ta().ta_command); break; case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CON_RES_ID: - logger.info("Contention Resolution CE not implemented."); + received_crueid = subpdu.get_ue_con_res_id_ce_packed(); + logger.info("Received Contention Resolution ID 0x%lx", subpdu.get_ue_con_res_id_ce_packed()); break; default: if (subpdu.is_sdu()) { diff --git a/srsue/src/stack/mac_nr/dl_harq_nr.cc b/srsue/src/stack/mac_nr/dl_harq_nr.cc index ed4e86efba..ee3e172c65 100644 --- a/srsue/src/stack/mac_nr/dl_harq_nr.cc +++ b/srsue/src/stack/mac_nr/dl_harq_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -35,6 +35,14 @@ dl_harq_entity_nr::dl_harq_entity_nr(uint8_t cc_idx_, // Init broadcast HARQ process bcch_proc.init(-1); pthread_rwlock_init(&rwlock, NULL); + + // Create default number of processes + for (uint32_t i = 0; i < cfg.nof_procs; i++) { + harq_procs[i] = std::unique_ptr(new dl_harq_process_nr(this)); + if (!harq_procs.at(i)->init(i)) { + logger.error("Error while initializing DL-HARQ process %d", i); + } + } } dl_harq_entity_nr::~dl_harq_entity_nr() @@ -51,17 +59,19 @@ int32_t dl_harq_entity_nr::set_config(const srsran::dl_harq_cfg_nr_t& cfg_) return SRSRAN_ERROR; } - // clear old processees - for (auto& proc : harq_procs) { - proc = nullptr; - } - - // Allocate and init configured HARQ processes - for (uint32_t i = 0; i < cfg.nof_procs; i++) { - harq_procs[i] = std::unique_ptr(new dl_harq_process_nr(this)); - if (!harq_procs.at(i)->init(i)) { - logger.error("Error while initializing DL-HARQ process %d", i); - return SRSRAN_ERROR; + if (cfg_.nof_procs < cfg.nof_procs) { + // clear old processes if not needed + for (uint32_t i = cfg.nof_procs - 1; i < cfg_.nof_procs; i++) { + harq_procs[i] = nullptr; + } + } else { + // Add new processes + for (uint32_t i = cfg.nof_procs; i < cfg_.nof_procs; i++) { + harq_procs[i] = std::unique_ptr(new dl_harq_process_nr(this)); + if (!harq_procs.at(i)->init(i)) { + logger.error("Error while initializing DL-HARQ process %d", i); + return SRSRAN_ERROR; + } } } @@ -228,12 +238,13 @@ void dl_harq_entity_nr::dl_harq_process_nr::tb_decoded(const mac_nr_grant_dl_t& if (acked and result.payload != nullptr) { if (is_bcch) { - logger.warning("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH) not implemented", grant.tbs); - reset(); + harq_entity->demux_unit->push_bcch(std::move(result.payload)); } else { if (grant.rnti == harq_entity->mac->get_temp_crnti()) { logger.debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI) not implemented", grant.tbs); + harq_entity->demux_unit->push_pdu_temp_crnti(std::move(result.payload), grant.tti); + result.ack = harq_entity->mac->received_contention_id(harq_entity->demux_unit->get_received_crueid()); } else { logger.debug("Delivering PDU=%d bytes to Dissassemble and Demux unit", grant.tbs); harq_entity->demux_unit->push_pdu(std::move(result.payload), grant.tti); diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index d0cbc66958..5de14005a8 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -74,7 +74,7 @@ int mac_nr::init(const mac_nr_args_t& args_, return SRSRAN_ERROR; } - if (demux.init(rlc) != SRSRAN_SUCCESS) { + if (demux.init(rlc, phy) != SRSRAN_SUCCESS) { logger.error("Couldn't initialize demux unit."); return SRSRAN_ERROR; } @@ -112,6 +112,16 @@ void mac_nr::reset() proc_sr.reset(); proc_ra.reset(); mux.reset(); + for (const auto& cc : dl_harq) { + if (cc != nullptr) { + cc->reset(); + } + } + for (const auto& cc : ul_harq) { + if (cc != nullptr) { + cc->reset(); + } + } } void mac_nr::run_tti(const uint32_t tti) @@ -162,13 +172,16 @@ void mac_nr::update_buffer_states() mac_interface_phy_nr::sched_rnti_t mac_nr::get_ul_sched_rnti_nr(const uint32_t tti) { + if (has_temp_crnti() && has_crnti() == false) { + logger.debug("SCHED: Searching temp C-RNTI=0x%x (proc_ra)", rntis.get_temp_rnti()); + return {rntis.get_temp_rnti(), srsran_rnti_type_c}; + } return {rntis.get_crnti(), srsran_rnti_type_c}; } bool mac_nr::is_si_opportunity() { - // TODO: ask RRC if we need SI - return false; + return search_bcch; } bool mac_nr::is_paging_opportunity() @@ -191,9 +204,9 @@ mac_interface_phy_nr::sched_rnti_t mac_nr::get_dl_sched_rnti_nr(const uint32_t t return {proc_ra.get_rar_rnti(), srsran_rnti_type_ra}; } - if (proc_ra.has_temp_crnti() && has_crnti() == false) { - logger.debug("SCHED: Searching temp C-RNTI=0x%x (proc_ra)", proc_ra.get_temp_crnti()); - return {proc_ra.get_temp_crnti(), srsran_rnti_type_c}; + if (has_temp_crnti() && has_crnti() == false) { + logger.debug("SCHED: Searching temp C-RNTI=0x%x (proc_ra)", rntis.get_temp_rnti()); + return {rntis.get_temp_rnti(), srsran_rnti_type_c}; } if (has_crnti()) { @@ -205,6 +218,26 @@ mac_interface_phy_nr::sched_rnti_t mac_nr::get_dl_sched_rnti_nr(const uint32_t t return {SRSRAN_INVALID_RNTI, srsran_rnti_type_c}; } +bool mac_nr::has_temp_crnti() +{ + return rntis.get_temp_rnti() != SRSRAN_INVALID_RNTI; +} + +uint16_t mac_nr::get_temp_crnti() +{ + return rntis.get_temp_rnti(); +} + +void mac_nr::set_temp_crnti(uint16_t temp_crnti) +{ + rntis.set_temp_rnti(temp_crnti); +} + +void mac_nr::set_crnti_to_temp() +{ + rntis.set_crnti_to_temp(); +} + bool mac_nr::has_crnti() { return rntis.get_crnti() != SRSRAN_INVALID_RNTI; @@ -215,11 +248,6 @@ uint16_t mac_nr::get_crnti() return rntis.get_crnti(); } -uint16_t mac_nr::get_temp_crnti() -{ - return proc_ra.get_temp_crnti(); -} - srsran::mac_sch_subpdu_nr::lcg_bsr_t mac_nr::generate_sbsr() { return proc_bsr.generate_sbsr(); @@ -305,7 +333,7 @@ void mac_nr::new_grant_dl(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, void mac_nr::tb_decoded(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, tb_action_dl_result_t result) { - logger.debug("tb_decoded(): cc_idx=%d, tti=%d, rnti=%d, pid=%d, tbs=%d, ndi=%d, rv=%d, result=%s", + logger.debug("tb_decoded(): cc_idx=%d, tti=%d, rnti=0x%X, pid=%d, tbs=%d, ndi=%d, rv=%d, result=%s", cc_idx, grant.tti, grant.rnti, @@ -330,11 +358,16 @@ void mac_nr::tb_decoded(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, t dl_harq.at(cc_idx)->tb_decoded(grant, std::move(result)); } + + // If proc ra is in contention resolution (RA connection request procedure) + if (proc_ra.is_contention_resolution() && grant.rnti == rntis.get_temp_rnti()) { + proc_ra.received_contention_resolution(contention_res_successful); + } } void mac_nr::new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, tb_action_ul_t* action) { - logger.debug("new_grant_ul(): cc_idx=%d, tti=%d, rnti=%d, pid=%d, tbs=%d, ndi=%d, rv=%d, is_rar=%d", + logger.debug("new_grant_ul(): cc_idx=%d, tti=%d, rnti=0x%X, pid=%d, tbs=%d, ndi=%d, rv=%d, is_rar=%d", cc_idx, grant.tti, grant.rnti, @@ -347,7 +380,7 @@ void mac_nr::new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, // Clear UL action *action = {}; - // if proc ra is in contention resolution and c_rnti == grant.c_rnti resolve contention resolution + // if proc ra is in contention resolution and c_rnti == grant.c_rnti (RA connection resume procedure) if (proc_ra.is_contention_resolution() && grant.rnti == get_crnti()) { proc_ra.pdcch_to_crnti(); } @@ -441,7 +474,7 @@ int mac_nr::set_config(const srsran::sr_cfg_nr_t& sr_cfg) return proc_sr.set_config(sr_cfg); } -void mac_nr::set_config(const srsran::rach_nr_cfg_t& rach_cfg) +void mac_nr::set_config(const srsran::rach_cfg_nr_t& rach_cfg) { proc_ra.set_config(rach_cfg); } @@ -451,6 +484,11 @@ void mac_nr::set_contention_id(uint64_t ue_identity) rntis.set_contention_id(ue_identity); } +void mac_nr::bcch_search(bool enabled) +{ + search_bcch = enabled; +} + bool mac_nr::set_crnti(const uint16_t c_rnti_) { if (is_valid_crnti(c_rnti_)) { @@ -534,9 +572,10 @@ void mac_nr::process_pdus() demux.process_pdus(); } -uint64_t mac_nr::get_contention_id() +bool mac_nr::received_contention_id(uint64_t rx_contention_id) { - return 0xdeadbeef; // TODO when rebased on PR + contention_res_successful = rntis.get_contention_id() == rx_contention_id; + return contention_res_successful; } // TODO same function as for mac_eutra diff --git a/srsue/src/stack/mac_nr/mux_nr.cc b/srsue/src/stack/mac_nr/mux_nr.cc index 18da2f802e..78eef7ee58 100644 --- a/srsue/src/stack/mac_nr/mux_nr.cc +++ b/srsue/src/stack/mac_nr/mux_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -77,59 +77,61 @@ srsran::unique_byte_buffer_t mux_nr::get_pdu(uint32_t max_pdu_len) logger.debug("Building new MAC PDU (%d B)", max_pdu_len); tx_pdu.init_tx(phy_tx_pdu.get(), max_pdu_len, true); - if (msg3_is_pending()) { - // only C-RNTI or CCCH SDU can be transmitted in Msg3 - if (mac.has_crnti()) { - tx_pdu.add_crnti_ce(mac.get_crnti()); - } - // TODO: add CCCH check + if (msg3_is_pending() && mac.has_crnti()) { + tx_pdu.add_crnti_ce(mac.get_crnti()); msg3_transmitted(); - } else { - // Pack normal UL data PDU - int32_t remaining_len = tx_pdu.get_remaing_len(); // local variable to reserve space for CEs - - if (add_bsr_ce == sbsr_ce) { - // reserve space for SBSR - remaining_len -= 2; - } - - // First add MAC SDUs - for (const auto& lc : logical_channels) { - // TODO: Add proper priority handling - logger.debug("Adding SDUs for LCID=%d (max %d B)", lc.lcid, remaining_len); - while (remaining_len >= MIN_RLC_PDU_LEN) { - // read RLC PDU - rlc_buff->clear(); - uint8_t* rd = rlc_buff->msg; + } - // Determine space for RLC - int32_t subpdu_header_len = (remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2); + // Pack normal UL data PDU + int32_t remaining_len = tx_pdu.get_remaing_len(); // local variable to reserve space for CEs - // Read PDU from RLC (account for subPDU header) - int pdu_len = rlc->read_pdu(lc.lcid, rd, remaining_len - subpdu_header_len); + if (!msg3_is_pending() && add_bsr_ce == sbsr_ce) { + // reserve space for SBSR + remaining_len -= 2; + } - if (pdu_len > remaining_len) { - logger.error("Can't add SDU of %d B. Available space %d B", pdu_len, remaining_len); - break; - } else { - // Add SDU if RLC has something to tx - if (pdu_len > 0) { - rlc_buff->N_bytes = pdu_len; - logger.debug(rlc_buff->msg, rlc_buff->N_bytes, "Read %d B from RLC", rlc_buff->N_bytes); - - // add to MAC PDU and pack - if (tx_pdu.add_sdu(lc.lcid, rlc_buff->msg, rlc_buff->N_bytes) != SRSRAN_SUCCESS) { - logger.error("Error packing MAC PDU"); - break; - } - } else { - // couldn't read PDU from RLC + // First add MAC SDUs + for (const auto& lc : logical_channels) { + // TODO: Add proper priority handling + logger.debug("Adding SDUs for LCID=%d (max %d B)", lc.lcid, remaining_len); + while (remaining_len >= MIN_RLC_PDU_LEN) { + // read RLC PDU + rlc_buff->clear(); + uint8_t* rd = rlc_buff->msg; + + // Determine space for RLC + int32_t subpdu_header_len = (remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2); + + // Read PDU from RLC (account for subPDU header) + int pdu_len = rlc->read_pdu(lc.lcid, rd, remaining_len - subpdu_header_len); + + if (pdu_len > remaining_len) { + logger.error("Can't add SDU of %d B. Available space %d B", pdu_len, remaining_len); + break; + } else { + // Add SDU if RLC has something to tx + if (pdu_len > 0) { + rlc_buff->N_bytes = pdu_len; + logger.debug(rlc_buff->msg, rlc_buff->N_bytes, "Read %d B from RLC", rlc_buff->N_bytes); + + // add to MAC PDU and pack + if (tx_pdu.add_sdu(lc.lcid, rlc_buff->msg, rlc_buff->N_bytes) != SRSRAN_SUCCESS) { + logger.error("Error packing MAC PDU"); break; } - remaining_len -= (pdu_len + subpdu_header_len); - logger.debug("%d B remaining PDU", remaining_len); + if (lc.lcid == 0 && msg3_is_pending()) { + // TODO: + msg3_transmitted(); + } + + } else { + // couldn't read PDU from RLC + break; } + + remaining_len -= (pdu_len + subpdu_header_len); + logger.debug("%d B remaining PDU", remaining_len); } } } diff --git a/srsue/src/stack/mac_nr/proc_bsr_nr.cc b/srsue/src/stack/mac_nr/proc_bsr_nr.cc index 5bdceba405..7355b0fe6b 100644 --- a/srsue/src/stack/mac_nr/proc_bsr_nr.cc +++ b/srsue/src/stack/mac_nr/proc_bsr_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index 5baebc9c40..f94489d81d 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -53,7 +53,7 @@ void proc_ra_nr::init(phy_interface_mac_nr* phy_, srsran::ext_task_sched_handle* } /* Sets a new configuration. The configuration is applied by initialization() function */ -void proc_ra_nr::set_config(const srsran::rach_nr_cfg_t& rach_cfg_) +void proc_ra_nr::set_config(const srsran::rach_cfg_nr_t& rach_cfg_) { if (state != IDLE) { logger.warning("Wrong state for ra reponse reception %s (expected state %s)", @@ -124,16 +124,10 @@ bool proc_ra_nr::has_rar_rnti() return false; } -bool proc_ra_nr::has_temp_crnti() +void proc_ra_nr::received_contention_resolution(bool is_successful) { std::lock_guard lock(mutex); - return temp_crnti != SRSRAN_INVALID_RNTI; -} - -uint16_t proc_ra_nr::get_temp_crnti() -{ - std::lock_guard lock(mutex); - return temp_crnti; + ra_contention_resolution(is_successful); } void proc_ra_nr::timer_expired(uint32_t timer_id) @@ -219,15 +213,18 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_ for (auto& subpdu : pdu.get_subpdus()) { if (subpdu.has_rapid() && subpdu.get_rapid() == preamble_index) { logger.debug("PROC RA NR: Setting UL grant and prepare Msg3"); - temp_crnti = subpdu.get_temp_crnti(); + mac.set_temp_crnti(subpdu.get_temp_crnti()); // Set Temporary-C-RNTI if provided, otherwise C-RNTI is ok - phy->set_ul_grant(tb.rx_slot_idx, subpdu.get_ul_grant(), temp_crnti, srsran_rnti_type_ra); + phy->set_rar_grant(tb.rx_slot_idx, subpdu.get_ul_grant(), subpdu.get_temp_crnti(), srsran_rnti_type_ra); + + // Apply TA CMD + current_ta = subpdu.get_ta(); + phy->set_timeadv_rar(tb.rx_slot_idx, current_ta); // reset all parameters that are used before rar rar_rnti = SRSRAN_INVALID_RNTI; mac.msg3_prepare(); - current_ta = subpdu.get_ta(); // Set Backoff parameter if (subpdu.has_backoff()) { @@ -246,7 +243,7 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_ // TS 38.321 Section 5.1.5 2 ways to resolve contention resolution // if the C-RNTI MAC CE was included in Msg3: (only this one is implemented) -void proc_ra_nr::ra_contention_resolution() +void proc_ra_nr::ra_contention_resolution(bool received_con_res_matches_ue_id) { if (state != WAITING_FOR_CONTENTION_RESOLUTION) { logger.warning( @@ -255,8 +252,12 @@ void proc_ra_nr::ra_contention_resolution() srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, WAITING_FOR_CONTENTION_RESOLUTION)); return; } - if (started_by == initiators_t::RRC || started_by == initiators_t::MAC) { - logger.info("PDCCH to C-RNTI received with a new UL grant of transmission"); + if (started_by == initiators_t::RRC || started_by == initiators_t::MAC || received_con_res_matches_ue_id) { + if (received_con_res_matches_ue_id) { + logger.info("Received CONRES ID matches transmitted UE ID"); + } else { + logger.info("PDCCH to C-RNTI received with a new UL grant of transmission"); + } contention_resolution_timer.stop(); state = WAITING_FOR_COMPLETION; ra_completion(); @@ -265,31 +266,25 @@ void proc_ra_nr::ra_contention_resolution() } } -// or else if the CCCH SDU was included in Msg3 and the PDCCH transmission is addressed to its TEMPORARY_C-RNTI: -void proc_ra_nr::ra_contention_resolution(uint64_t rx_contention_id) -{ - if (state != WAITING_FOR_CONTENTION_RESOLUTION) { - logger.warning( - "Wrong state for ra contention resolution by phy %s (expected state %s)", - srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state), - srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, WAITING_FOR_CONTENTION_RESOLUTION)); - return; - } - // TODO -} - void proc_ra_nr::ra_completion() { - std::lock_guard lock(mutex); if (state != WAITING_FOR_COMPLETION) { logger.warning("Wrong state for ra completion by phy %s (expected state %s)", srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state), srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, WAITING_FOR_COMPLETION)); return; } + + // Start looking for PDCCH CRNTI + if (!mac.get_crnti()) { + // promote temp RNTI to new C-RNTI + mac.set_crnti_to_temp(); + mac.set_temp_crnti(SRSRAN_INVALID_RNTI); + } + srsran::console("Random Access Complete. c-rnti=0x%x, ta=%d\n", mac.get_crnti(), current_ta); logger.info("Random Access Complete. c-rnti=0x%x, ta=%d", mac.get_crnti(), current_ta); - temp_crnti = SRSRAN_INVALID_RNTI; + mac.rrc_ra_completed(); reset(); } @@ -297,9 +292,9 @@ void proc_ra_nr::ra_completion() void proc_ra_nr::ra_error() { std::lock_guard lock(mutex); - temp_crnti = SRSRAN_INVALID_RNTI; preamble_transmission_counter++; contention_resolution_timer.stop(); + mac.set_temp_crnti(SRSRAN_INVALID_RNTI); uint32_t backoff_wait; bool ra_procedure_completed = false; // true = (unsuccessfully) completed, false = uncompleted @@ -381,7 +376,7 @@ void proc_ra_nr::handle_rar_pdu(mac_interface_phy_nr::tb_action_dl_result_t& res // Called from PHY thread, defer actions therefore. void proc_ra_nr::pdcch_to_crnti() { - task_queue.push([this]() { ra_contention_resolution(); }); + task_queue.push([this]() { ra_contention_resolution(false); }); } bool proc_ra_nr::is_contention_resolution() @@ -393,6 +388,7 @@ void proc_ra_nr::reset() { state = IDLE; started_by = initiators_t::initiators_t_NULLTYPE; + mac.set_temp_crnti(SRSRAN_INVALID_RNTI); prach_send_timer.stop(); rar_timeout_timer.stop(); contention_resolution_timer.stop(); diff --git a/srsue/src/stack/mac_nr/proc_sr_nr.cc b/srsue/src/stack/mac_nr/proc_sr_nr.cc index b84494a550..b3cb85bc7d 100644 --- a/srsue/src/stack/mac_nr/proc_sr_nr.cc +++ b/srsue/src/stack/mac_nr/proc_sr_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -54,8 +54,11 @@ void proc_sr_nr::reset_nolock() int32_t proc_sr_nr::set_config(const srsran::sr_cfg_nr_t& cfg_) { - // disable by default - cfg.enabled = false; + { + std::lock_guard lock(mutex); + // disable by default + cfg.enabled = false; + } if (cfg_.num_items != 1) { logger.error("Only one SR config supported. Disabling SR."); @@ -78,8 +81,11 @@ int32_t proc_sr_nr::set_config(const srsran::sr_cfg_nr_t& cfg_) logger.info("SR: Disabling procedure"); } - // store config - cfg = cfg_; + { + std::lock_guard lock(mutex); + // store config + cfg = cfg_; + } return SRSRAN_SUCCESS; } diff --git a/srsue/src/stack/mac_nr/test/CMakeLists.txt b/srsue/src/stack/mac_nr/test/CMakeLists.txt index b466fc2169..518c96ab84 100644 --- a/srsue/src/stack/mac_nr/test/CMakeLists.txt +++ b/srsue/src/stack/mac_nr/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/src/stack/mac_nr/test/mac_nr_test.cc b/srsue/src/stack/mac_nr/test/mac_nr_test.cc index 373d8ac6ea..098a94b2be 100644 --- a/srsue/src/stack/mac_nr/test/mac_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/mac_nr_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -44,11 +44,10 @@ class dummy_phy : public phy_interface_mac_nr preamble_index = preamble_index_; preamble_received_target_power = preamble_received_target_power_; } - int tx_request(const tx_request_t& request) override { return 0; } - int set_ul_grant(uint32_t rar_slot_idx, - std::array, - uint16_t rnti, - srsran_rnti_type_t rnti_type) override + int set_rar_grant(uint32_t rar_slot_idx, + std::array, + uint16_t rnti, + srsran_rnti_type_t rnti_type) override { return 0; } @@ -62,6 +61,9 @@ class dummy_phy : public phy_interface_mac_nr bool has_valid_sr_resource(uint32_t sr_id) override { return false; } void clear_pending_grants() override {} + void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) final{}; + void set_timeadv(uint32_t tti, uint32_t ta_cmd) final{}; + private: uint32_t prach_occasion = 0; uint32_t preamble_index = 0; diff --git a/srsue/src/stack/mac_nr/test/proc_bsr_nr_test.cc b/srsue/src/stack/mac_nr/test/proc_bsr_nr_test.cc index a27cc9a435..00b09d2314 100644 --- a/srsue/src/stack/mac_nr/test/proc_bsr_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/proc_bsr_nr_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc b/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc index 38615c5397..4ae6e41daf 100644 --- a/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/proc_ra_nr_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -38,14 +38,6 @@ class dummy_phy : public phy_interface_mac_nr preamble_index = preamble_index_; preamble_received_target_power = preamble_received_target_power_; } - int tx_request(const tx_request_t& request) override { return 0; } - int set_ul_grant(uint32_t rar_slot_idx, - std::array, - uint16_t rnti, - srsran_rnti_type_t rnti_type) override - { - return 0; - } void get_last_send_prach(uint32_t* prach_occasion_, uint32_t* preamble_index_, int* preamble_received_target_power_) { @@ -56,6 +48,16 @@ class dummy_phy : public phy_interface_mac_nr bool has_valid_sr_resource(uint32_t sr_id) override { return false; } void clear_pending_grants() override {} + int set_rar_grant(uint32_t rar_slot_idx, + std::array packed_ul_grant, + uint16_t rnti, + srsran_rnti_type_t rnti_type) override + { + return -1; + } + void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) final {} + void set_timeadv(uint32_t tti, uint32_t ta_cmd) final {} + private: uint32_t prach_occasion = 0; uint32_t preamble_index = 0; @@ -73,6 +75,8 @@ class dummy_mac : public mac_interface_proc_ra_nr crnti = c_rnti; return true; } + void set_temp_crnti(uint16_t c_rnti) {} + void set_crnti_to_temp() {} bool msg3_is_transmitted() { return true; } void msg3_flush() {} @@ -100,7 +104,7 @@ int proc_ra_normal_test() proc_ra_nr.init(&dummy_phy, &ext_task_sched_h); TESTASSERT(proc_ra_nr.is_rar_opportunity(1) == false); - srsran::rach_nr_cfg_t rach_cfg; + srsran::rach_cfg_nr_t rach_cfg; rach_cfg.powerRampingStep = 4; rach_cfg.prach_ConfigurationIndex = 16; rach_cfg.PreambleReceivedTargetPower = -110; @@ -162,7 +166,7 @@ int proc_ra_timeout_test() proc_ra_nr.init(&dummy_phy, &ext_task_sched_h); TESTASSERT(proc_ra_nr.is_rar_opportunity(1) == false); - srsran::rach_nr_cfg_t rach_cfg; + srsran::rach_cfg_nr_t rach_cfg; rach_cfg.powerRampingStep = 4; rach_cfg.prach_ConfigurationIndex = 16; rach_cfg.PreambleReceivedTargetPower = -110; diff --git a/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc b/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc index 8d9be3a637..7384fcd677 100644 --- a/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/proc_sr_nr_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -39,11 +39,10 @@ class dummy_phy : public phy_interface_mac_nr preamble_index = preamble_index_; preamble_received_target_power = preamble_received_target_power_; } - int tx_request(const tx_request_t& request) override { return 0; } - int set_ul_grant(uint32_t rar_slot_idx, - std::array, - uint16_t rnti, - srsran_rnti_type_t rnti_type) override + int set_rar_grant(uint32_t rar_slot_idx, + std::array, + uint16_t rnti, + srsran_rnti_type_t rnti_type) override { return 0; } @@ -57,6 +56,9 @@ class dummy_phy : public phy_interface_mac_nr bool has_valid_sr_resource(uint32_t sr_id) override { return false; } void clear_pending_grants() override {} + void set_timeadv_rar(uint32_t tti, uint32_t ta_cmd) final{}; + void set_timeadv(uint32_t tti, uint32_t ta_cmd) final{}; + private: uint32_t prach_occasion = 0; uint32_t preamble_index = 0; diff --git a/srsue/src/stack/mac_nr/ul_harq_nr.cc b/srsue/src/stack/mac_nr/ul_harq_nr.cc index 2f7eea3598..4b1963c7dd 100644 --- a/srsue/src/stack/mac_nr/ul_harq_nr.cc +++ b/srsue/src/stack/mac_nr/ul_harq_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -215,7 +215,7 @@ void ul_harq_entity_nr::ul_harq_process_nr::new_grant_ul(const mac_interface_phy // retransmission if (harq_buffer == nullptr) { // ignore the UL grant - logger.info("UL %d: HARQ buffer empty. Ignoring grant."); + logger.info("UL %d: HARQ buffer empty. Ignoring grant.", pid); return; } diff --git a/srsue/src/stack/rrc/CMakeLists.txt b/srsue/src/stack/rrc/CMakeLists.txt index d797aa4ef1..61306a467d 100644 --- a/srsue/src/stack/rrc/CMakeLists.txt +++ b/srsue/src/stack/rrc/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -21,8 +21,4 @@ add_subdirectory(test) set(SOURCES rrc.cc rrc_procedures.cc rrc_meas.cc rrc_cell.cc rrc_rlf_report.cc phy_controller.cc) -add_library(srsue_rrc STATIC ${SOURCES}) - -set(SOURCES rrc_nr.cc) -add_library(srsue_rrc_nr STATIC ${SOURCES}) - +add_library(srsue_rrc STATIC ${SOURCES}) \ No newline at end of file diff --git a/srsue/src/stack/rrc/phy_controller.cc b/srsue/src/stack/rrc/phy_controller.cc index 42ce10f8ac..93a4ce49da 100644 --- a/srsue/src/stack/rrc/phy_controller.cc +++ b/srsue/src/stack/rrc/phy_controller.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -175,13 +175,13 @@ void phy_controller::selecting_cell::wait_in_sync::enter(selecting_cell* f) *************************************/ //! Searches for a cell in the current frequency and retrieves SIB1 if not retrieved yet -bool phy_controller::start_cell_search(srsran::event_observer observer) +bool phy_controller::start_cell_search(srsran::event_observer observer, int earfcn) { if (is_in_state()) { fsmInfo("Cell search already launched."); return true; } - trigger(cell_search_cmd{}); + trigger(cell_search_cmd{earfcn}); if (not is_in_state()) { fsmWarning("Failed to launch cell search"); return false; @@ -195,10 +195,10 @@ void phy_controller::cell_search_completed(cell_search_ret_t cs_ret, phy_cell_t trigger(cell_srch_res{cs_ret, found_cell}); } -void phy_controller::searching_cell::enter(phy_controller* f) +void phy_controller::searching_cell::enter(phy_controller* f, const cell_search_cmd& ev) { otherfsmInfo(f, "Initiating Cell search"); - f->phy->cell_search(); + f->phy->cell_search(ev.earfcn); } void phy_controller::handle_cell_search_res(searching_cell& s, const cell_srch_res& result) diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 2c5ce575c7..cb5bbec462 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -466,7 +466,8 @@ void rrc::process_new_cell_meas(const std::vector& meas) bool neighbour_added = meas_cells.process_new_cell_meas(meas, filter); // Instruct measurements subclass to update phy with new cells to measure based on strongest neighbours - if (state == RRC_STATE_CONNECTED && neighbour_added) { + // Avoid updating PHY while HO procedure is busy + if (state == RRC_STATE_CONNECTED && neighbour_added && !ho_handler.is_busy()) { measurements->update_phy(); } } @@ -788,13 +789,10 @@ bool rrc::nr_reconfiguration_proc(const rrc_conn_recfg_r8_ies_s& rx_recfg, bool* return true; } - bool endc_release_and_add_r15 = false; - bool nr_secondary_cell_group_cfg_r15_present = false; - asn1::dyn_octstring nr_secondary_cell_group_cfg_r15; - bool sk_counter_r15_present = false; - uint32_t sk_counter_r15 = 0; - bool nr_radio_bearer_cfg1_r15_present = false; - asn1::dyn_octstring nr_radio_bearer_cfg1_r15; + bool endc_release_and_add_r15 = false; + + asn1::rrc_nr::rrc_recfg_s rrc_nr_reconf = {}; + rrc_nr_reconf.crit_exts.set_rrc_recfg(); switch (rrc_conn_recfg_v1510_ies->nr_cfg_r15.type()) { case setup_opts::options::release: @@ -803,8 +801,28 @@ bool rrc::nr_reconfiguration_proc(const rrc_conn_recfg_r8_ies_s& rx_recfg, bool* case setup_opts::options::setup: endc_release_and_add_r15 = rrc_conn_recfg_v1510_ies->nr_cfg_r15.setup().endc_release_and_add_r15; if (rrc_conn_recfg_v1510_ies->nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15_present) { - nr_secondary_cell_group_cfg_r15_present = true; - nr_secondary_cell_group_cfg_r15 = rrc_conn_recfg_v1510_ies->nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15; + asn1::cbit_ref bref0(rrc_conn_recfg_v1510_ies->nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15.data(), + rrc_conn_recfg_v1510_ies->nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15.size()); + + asn1::rrc_nr::rrc_recfg_s secondary_cell_group_r15; + if (secondary_cell_group_r15.unpack(bref0) != SRSASN_SUCCESS) { + logger.error("Could not unpack secondary cell group r15."); + return false; + } + + if (secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group.size() > 0) { + asn1::cbit_ref bref1(secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group.data(), + secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group.size()); + + asn1::rrc_nr::cell_group_cfg_s cell_group_cfg; + if (cell_group_cfg.unpack(bref1) != SRSASN_SUCCESS) { + logger.error("Could not unpack secondary cell group config."); + return false; + } + + rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group = + secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group; + } } break; default: @@ -812,22 +830,29 @@ bool rrc::nr_reconfiguration_proc(const rrc_conn_recfg_r8_ies_s& rx_recfg, bool* break; } if (rrc_conn_recfg_v1510_ies->sk_counter_r15_present) { - sk_counter_r15_present = true; - sk_counter_r15 = rrc_conn_recfg_v1510_ies->sk_counter_r15; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext.sk_counter_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext.sk_counter = + rrc_conn_recfg_v1510_ies->sk_counter_r15; } if (rrc_conn_recfg_v1510_ies->nr_radio_bearer_cfg1_r15_present) { - nr_radio_bearer_cfg1_r15_present = true; - nr_radio_bearer_cfg1_r15 = rrc_conn_recfg_v1510_ies->nr_radio_bearer_cfg1_r15; + rrc_nr_reconf.crit_exts.rrc_recfg().radio_bearer_cfg_present = true; + asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_conf = {}; + asn1::cbit_ref bref(rrc_conn_recfg_v1510_ies->nr_radio_bearer_cfg1_r15.data(), + rrc_conn_recfg_v1510_ies->nr_radio_bearer_cfg1_r15.size()); + if (radio_bearer_conf.unpack(bref) != SRSASN_SUCCESS) { + logger.error("Could not unpack radio bearer config."); + return false; + } + + rrc_nr_reconf.crit_exts.rrc_recfg().radio_bearer_cfg = radio_bearer_conf; } *has_5g_nr_reconfig = true; - return rrc_nr->rrc_reconfiguration(endc_release_and_add_r15, - nr_secondary_cell_group_cfg_r15_present, - nr_secondary_cell_group_cfg_r15, - sk_counter_r15_present, - sk_counter_r15, - nr_radio_bearer_cfg1_r15_present, - nr_radio_bearer_cfg1_r15); + + return rrc_nr->rrc_reconfiguration(endc_release_and_add_r15, rrc_nr_reconf); } /******************************************************************************* * @@ -1138,8 +1163,9 @@ void rrc::handle_rrc_con_reconfig(uint32_t lcid, const rrc_conn_recfg_s& reconfi } /* Actions upon reception of RRCConnectionRelease 5.3.8.3 */ -void rrc::rrc_connection_release(const std::string& cause) +void rrc::handle_rrc_connection_release(const asn1::rrc::rrc_conn_release_s& release) { + std::string cause = release.crit_exts.c1().rrc_conn_release_r8().release_cause.to_string(); // Save idleModeMobilityControlInfo, etc. srsran::console("Received RRC Connection Release (releaseCause: %s)\n", cause.c_str()); @@ -1149,6 +1175,36 @@ void rrc::rrc_connection_release(const std::string& cause) // delay actions by 60ms as per 5.3.8.3 task_sched.defer_callback(60, [this]() { start_go_idle(); }); + + uint32_t earfcn = 0; + if (release.crit_exts.c1().rrc_conn_release_r8().redirected_carrier_info_present) { + switch (release.crit_exts.c1().rrc_conn_release_r8().redirected_carrier_info.type()) { + case asn1::rrc::redirected_carrier_info_c::types_opts::options::eutra: + earfcn = release.crit_exts.c1().rrc_conn_release_r8().redirected_carrier_info.eutra(); + break; + default: + srsran::console("Ignoring RedirectedCarrierInfo with unsupported type (%s)\n", + release.crit_exts.c1().rrc_conn_release_r8().redirected_carrier_info.type().to_string()); + break; + } + if (earfcn != 0) { + srsran::console("RedirectedCarrierInfo present (type %s, earfcn: %d) - Redirecting\n", + release.crit_exts.c1().rrc_conn_release_r8().redirected_carrier_info.type().to_string(), + earfcn); + logger.info("RedirectedCarrierInfo present (type %s, earfcn: %d) - Redirecting", + release.crit_exts.c1().rrc_conn_release_r8().redirected_carrier_info.type().to_string(), + earfcn); + + // delay actions by 60ms as per 5.3.8.3 + task_sched.defer_callback(60, [this, earfcn]() { start_rrc_redirect(earfcn); }); + } + } +} + +void rrc::start_rrc_redirect(uint32_t new_dl_earfcn) +{ + cell_search_earfcn = (int)new_dl_earfcn; + plmn_search(); } /// TS 36.331, 5.3.12 - UE actions upon leaving RRC_CONNECTED @@ -1314,6 +1370,21 @@ void rrc::write_pdu_bcch_dlsch(unique_byte_buffer_t pdu) parse_pdu_bcch_dlsch(std::move(pdu)); } +/// \brief Helper function to get the SIB number from the SIB type. +static unsigned get_sib_number(const asn1::rrc::sib_info_item_c::types& sib) +{ + unsigned sib_n = 2 + (unsigned)sib.value; + if (sib_n > 21) { + // sib22 and sib23 skipped. + sib_n += 2; + if (sib_n > 26) { + // account for sib26a. + sib_n--; + } + } + return sib_n; +} + void rrc::parse_pdu_bcch_dlsch(unique_byte_buffer_t pdu) { // Stop BCCH search after successful reception of 1 BCCH block @@ -1339,7 +1410,7 @@ void rrc::parse_pdu_bcch_dlsch(unique_byte_buffer_t pdu) sys_info_r8_ies_s::sib_type_and_info_l_& sib_list = dlsch_msg.msg.c1().sys_info().crit_exts.sys_info_r8().sib_type_and_info; for (uint32_t i = 0; i < sib_list.size(); ++i) { - logger.info("Processing SIB%d (%d/%d)", sib_list[i].type().to_number(), i, sib_list.size()); + logger.info("Processing SIB%d (%d/%d)", get_sib_number(sib_list[i].type()), i, sib_list.size()); switch (sib_list[i].type().value) { case sib_info_item_c::types::sib2: if (not meas_cells.serving_cell().has_sib2()) { @@ -1363,7 +1434,7 @@ void rrc::parse_pdu_bcch_dlsch(unique_byte_buffer_t pdu) si_acquirer.trigger(si_acquire_proc::sib_received_ev{}); break; default: - logger.warning("SIB%d is not supported", sib_list[i].type().to_number()); + logger.warning("SIB%d is not supported", get_sib_number(sib_list[i].type())); } } } @@ -1382,7 +1453,7 @@ void rrc::handle_sib1() si_periodicity_r12_e p = sib1->sched_info_list[i].si_periodicity; for (uint32_t j = 0; j < sib1->sched_info_list[i].sib_map_info.size(); ++j) { sib_type_e t = sib1->sched_info_list[i].sib_map_info[j]; - logger.debug("SIB scheduling info, sib_type=%d, si_periodicity=%d", t.to_number(), p.to_number()); + logger.debug("SIB scheduling info, sib_type=%d, si_periodicity=%d", get_sib_number(t), p.to_number()); } } @@ -1803,7 +1874,7 @@ void rrc::parse_dl_dcch(uint32_t lcid, unique_byte_buffer_t pdu) handle_ue_capability_enquiry(c1->ue_cap_enquiry()); break; case dl_dcch_msg_type_c::c1_c_::types::rrc_conn_release: - rrc_connection_release(c1->rrc_conn_release().crit_exts.c1().rrc_conn_release_r8().release_cause.to_string()); + handle_rrc_connection_release(c1->rrc_conn_release()); break; case dl_dcch_msg_type_c::c1_c_::types::ue_info_request_r9: transaction_id = c1->ue_info_request_r9().rrc_transaction_id; @@ -1945,8 +2016,11 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) phy_layer_params_v1020.multi_cluster_pusch_within_cc_r10_present = false; phy_layer_params_v1020.non_contiguous_ul_ra_within_cc_list_r10_present = false; + rf_params_v1020_s rf_params; band_combination_params_r10_l combination_params; if (args.support_ca) { + // add Intra‑band Contiguous or Inter‑band Non-contiguous CA band combination + // note that nof_supported_bands=1 when all cells are in the same but non-contiguous band for (uint32_t k = 0; k < args.nof_supported_bands; k++) { ca_mimo_params_dl_r10_s ca_mimo_params_dl; ca_mimo_params_dl.ca_bw_class_dl_r10 = ca_bw_class_r10_e::f; @@ -1966,10 +2040,35 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) combination_params.push_back(band_params); } } - - rf_params_v1020_s rf_params; rf_params.supported_band_combination_r10.push_back(combination_params); + // add all 2CC, 3CC and 4CC Intra‑band Non-contiguous CA band combinations + for (uint32_t k = 0; k < args.nof_supported_bands; k++) { + for (uint32_t j = 2; j <= args.nof_lte_carriers; j++) { + combination_params.clear(); + + ca_mimo_params_dl_r10_s ca_mimo_params_dl; + ca_mimo_params_dl.ca_bw_class_dl_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_dl.supported_mimo_cap_dl_r10_present = false; + + ca_mimo_params_ul_r10_s ca_mimo_params_ul; + ca_mimo_params_ul.ca_bw_class_ul_r10 = ca_bw_class_r10_e::a; + ca_mimo_params_ul.supported_mimo_cap_ul_r10_present = false; + + band_params_r10_s band_params; + band_params.band_eutra_r10 = args.supported_bands[k]; + band_params.band_params_dl_r10_present = true; + band_params.band_params_dl_r10.push_back(ca_mimo_params_dl); + band_params.band_params_ul_r10_present = true; + band_params.band_params_ul_r10.push_back(ca_mimo_params_ul); + + for (uint32_t l = 0; l < j; l++) { + combination_params.push_back(band_params); + } + rf_params.supported_band_combination_r10.push_back(combination_params); + } + } + ue_eutra_cap_v1020_ies_s cap_v1020; if (args.ue_category >= 6 && args.ue_category <= 8) { cap_v1020.ue_category_v1020_present = true; @@ -2140,7 +2239,7 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) } // Pack caps and copy to cap info - uint8_t buf[64] = {}; + uint8_t buf[128] = {}; asn1::bit_ref bref(buf, sizeof(buf)); if (cap.pack(bref) != asn1::SRSASN_SUCCESS) { logger.error("Error packing EUTRA capabilities"); @@ -2436,6 +2535,8 @@ void rrc::apply_phy_scell_config(const scell_to_add_mod_r10_s& scell_config, boo logger.error("Adding SCell cc_idx=%d", scell_config.scell_idx_r10); } else if (!phy_ctrl->set_cell_config(scell_cfg, scell_config.scell_idx_r10)) { logger.error("Setting SCell configuration for cc_idx=%d", scell_config.scell_idx_r10); + } else { + meas_cells.set_scell_cc_idx(scell_config.scell_idx_r10, earfcn, scell.id); } } @@ -2852,7 +2953,7 @@ bool rrc::has_nr_dc() void rrc::add_mrb(uint32_t lcid, uint32_t port) { gw->add_mch_port(lcid, port); - rlc->add_bearer_mrb(lcid); + rlc->add_bearer_mrb(0, lcid); mac->mch_start_rx(lcid); logger.info("Added MRB bearer for lcid:%d", lcid); } diff --git a/srsue/src/stack/rrc/rrc_cell.cc b/srsue/src/stack/rrc/rrc_cell.cc index ef501f6ccd..9abc2d68e3 100644 --- a/srsue/src/stack/rrc/rrc_cell.cc +++ b/srsue/src/stack/rrc/rrc_cell.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -23,6 +23,20 @@ namespace srsue { +/// \brief Helper function to get the SIB number from the SIB type. +unsigned get_sib_number(const asn1::rrc::sib_type_e& sib) +{ + unsigned sib_number = 3 + (unsigned)sib.value; + if (sib_number > 21) { + // skip sib22 and sib23 + sib_number += 2; + if (sib_number > 26) { + sib_number--; + } + } + return sib_number; +} + meas_cell::meas_cell(srsran::unique_timer timer_) : timer(std::move(timer_)) { timer.set(neighbour_timeout_ms); @@ -59,7 +73,7 @@ void meas_cell_eutra::set_sib1(const asn1::rrc::sib_type1_s& sib1_) sib_info_map.clear(); for (uint32_t i = 0; i < sib1.sched_info_list.size(); ++i) { for (uint32_t j = 0; j < sib1.sched_info_list[i].sib_map_info.size(); ++j) { - sib_info_map.insert(std::make_pair(sib1.sched_info_list[i].sib_map_info[j].to_number() - 1, i)); + sib_info_map.insert(std::make_pair(get_sib_number(sib1.sched_info_list[i].sib_map_info[j]) - 1, i)); } } } @@ -80,6 +94,12 @@ void meas_cell_eutra::set_sib13(const asn1::rrc::sib_type13_r9_s& sib13_) has_valid_sib13 = true; } +void meas_cell_nr::set_sib1(const asn1::rrc_nr::sib1_s& sib1_) +{ + sib1 = sib1_; + has_valid_sib1 = true; +} + bool meas_cell::is_sib_scheduled(uint32_t sib_index) const { return sib_info_map.find(sib_index) != sib_info_map.end(); @@ -180,6 +200,41 @@ uint16_t meas_cell_eutra::get_mnc() const return 0; } +uint16_t meas_cell_nr::get_mcc() const +{ + uint16_t mcc = 0; + if (has_valid_sib1) { + if (sib1.cell_access_related_info.plmn_id_list.size() > 0) { + // PLMN ID list is nested twice + if (sib1.cell_access_related_info.plmn_id_list[0].plmn_id_list.size() > 0) { + if (sib1.cell_access_related_info.plmn_id_list[0].plmn_id_list[0].mcc_present) { + if (srsran::bytes_to_mcc(&sib1.cell_access_related_info.plmn_id_list[0].plmn_id_list[0].mcc[0], &mcc)) { + // successfully read MCC + } + } + } + } + } + return mcc; +} + +uint16_t meas_cell_nr::get_mnc() const +{ + uint16_t mnc = 0; + if (has_valid_sib1) { + if (sib1.cell_access_related_info.plmn_id_list.size() > 0) { + if (sib1.cell_access_related_info.plmn_id_list[0].plmn_id_list.size() > 0) { + if (srsran::bytes_to_mnc(&sib1.cell_access_related_info.plmn_id_list[0].plmn_id_list[0].mnc[0], + &mnc, + sib1.cell_access_related_info.plmn_id_list[0].plmn_id_list[0].mnc.size())) { + // successfully read MNC + } + } + } + } + return mnc; +} + /********************************************* * Neighbour Cell List ********************************************/ @@ -402,6 +457,25 @@ int meas_cell_list::set_serving_cell(phy_cell_t phy_cell, bool discard_servin return SRSRAN_SUCCESS; } +template +void meas_cell_list::set_scell_cc_idx(uint32_t cc_idx, uint32_t earfcn, uint32_t pci) +{ + current_cell_pci_earfcn[cc_idx].first = earfcn; + current_cell_pci_earfcn[cc_idx].second = pci; +} + +template +bool meas_cell_list::get_scell_cc_idx(uint32_t earfcn, uint32_t& pci) +{ + for (auto& cell : current_cell_pci_earfcn) { + if (cell.first == earfcn) { + pci = cell.second; + return true; + } + } + return false; +} + template bool meas_cell_list::process_new_cell_meas(const std::vector& meas, const std::function& filter_meas) diff --git a/srsue/src/stack/rrc/rrc_meas.cc b/srsue/src/stack/rrc/rrc_meas.cc index 9d6f3ae34b..51103dba30 100644 --- a/srsue/src/stack/rrc/rrc_meas.cc +++ b/srsue/src/stack/rrc/rrc_meas.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,9 +20,9 @@ */ #include "srsue/hdr/stack/rrc/rrc_meas.h" +#include "srsran/asn1/obj_id_cmp_utils.h" #include "srsran/asn1/rrc/dl_dcch_msg.h" #include "srsran/interfaces/ue_phy_interfaces.h" -#include "srsran/rrc/rrc_cfg_utils.h" #include "srsue/hdr/stack/rrc/rrc.h" /************************************************************************ @@ -127,7 +127,6 @@ bool rrc::rrc_meas::parse_meas_config(const rrc_conn_recfg_r8_ies_s* mob_reconf_ void rrc::rrc_meas::ho_reest_actions(const uint32_t src_earfcn, const uint32_t dst_earfcn) { meas_cfg.ho_reest_finish(src_earfcn, dst_earfcn); - update_phy(); } void rrc::rrc_meas::run_tti() @@ -233,12 +232,10 @@ void rrc::rrc_meas::var_meas_report_list::generate_report_eutra(meas_results_s* for (auto& cell : var_meas.cell_triggered_list) { // report neighbour cells only if (cell.pci == serv_cell->get_pci() && cell.earfcn == serv_cell->get_earfcn()) { - logger.info("MEAS: skipping serving cell in report neighbour=%d, pci=%d, earfcn=%d, rsrp=%+.1f, rsrq=%+.1f", + logger.info("MEAS: skipping serving cell in report neighbour=%d, pci=%d, earfcn=%d", neigh_list.size(), cell.pci, - var_meas.carrier_freq, - rrc_ptr->get_cell_rsrp(var_meas.carrier_freq, cell.pci), - rrc_ptr->get_cell_rsrq(var_meas.carrier_freq, cell.pci)); + var_meas.carrier_freq); continue; } if (neigh_list.size() <= var_meas.report_cfg_eutra.max_report_cells) { @@ -412,7 +409,7 @@ void rrc::rrc_meas::var_meas_report_list::generate_report(const uint32_t measId) meas_results_s* report = &ul_dcch_msg.msg.c1().meas_report().crit_exts.c1().meas_report_r8().meas_results; - report->meas_id = (uint8_t)measId; + report->meas_id = (uint8_t)measId; report->meas_result_pcell.rsrp_result = rrc_value_to_range(quant_rsrp, serv_cell->get_rsrp()); report->meas_result_pcell.rsrq_result = rrc_value_to_range(quant_rsrq, serv_cell->get_rsrq()); @@ -776,16 +773,31 @@ void rrc::rrc_meas::var_meas_cfg::eval_triggers_eutra(uint32_t meas_i } }; + eutra_event_s::event_id_c_ event_id = report_cfg.trigger_type.event().event_id; + + // For A1/A2 events, get serving cell from current carrier + if (event_id.type().value < eutra_event_s::event_id_c_::types::event_a3 && + meas_obj.carrier_freq != serv_cell->get_earfcn()) { + uint32_t scell_pci = 0; + if (!rrc_ptr->meas_cells.get_scell_cc_idx(meas_obj.carrier_freq, scell_pci)) { + logger.error("MEAS: Could not find serving cell for carrier earfcn=%d", meas_obj.carrier_freq); + return; + } + serv_cell = rrc_ptr->meas_cells.get_neighbour_cell_handle(meas_obj.carrier_freq, scell_pci); + if (!serv_cell) { + logger.error( + "MEAS: Could not find serving cell for carrier earfcn=%d and pci=%d", meas_obj.carrier_freq, scell_pci); + return; + } + } + double hyst = 0.5 * report_cfg.trigger_type.event().hysteresis; float Ms = is_rsrp(report_cfg.trigger_quant.value) ? serv_cell->get_rsrp() : serv_cell->get_rsrq(); - if (!std::isnormal(Ms)) { logger.debug("MEAS: Serving cell Ms=%f invalid when evaluating triggers", Ms); return; } - eutra_event_s::event_id_c_ event_id = report_cfg.trigger_type.event().event_id; - if (report_cfg.trigger_type.type() == report_cfg_eutra_s::trigger_type_c_::types::event) { // A1 & A2 are for serving cell only if (event_id.type().value < eutra_event_s::event_id_c_::types::event_a3) { @@ -1216,17 +1228,17 @@ void rrc::rrc_meas::var_meas_cfg::measObject_addmod_eutra(const meas_obj_to_add_ } } - // Do the same with black list + // Do the same with excluded list { - if (cfg_obj.black_cells_to_rem_list_present) { - apply_remlist_diff(local_obj.black_cells_to_add_mod_list, - cfg_obj.black_cells_to_rem_list, - local_obj.black_cells_to_add_mod_list); + if (cfg_obj.excluded_cells_to_rem_list_present) { + apply_remlist_diff(local_obj.excluded_cells_to_add_mod_list, + cfg_obj.excluded_cells_to_rem_list, + local_obj.excluded_cells_to_add_mod_list); } - if (cfg_obj.black_cells_to_add_mod_list_present) { - apply_addmodlist_diff(local_obj.black_cells_to_add_mod_list, - cfg_obj.black_cells_to_add_mod_list, - local_obj.black_cells_to_add_mod_list); + if (cfg_obj.excluded_cells_to_add_mod_list_present) { + apply_addmodlist_diff(local_obj.excluded_cells_to_add_mod_list, + cfg_obj.excluded_cells_to_add_mod_list, + local_obj.excluded_cells_to_add_mod_list); } } @@ -1238,19 +1250,19 @@ void rrc::rrc_meas::var_meas_cfg::measObject_addmod_eutra(const meas_obj_to_add_ } } - logger.info("MEAS: %s objectId=%d, carrier_freq=%d, %u cells, %u black-listed cells", + logger.info("MEAS: %s objectId=%d, carrier_freq=%d, %u cells, %u excluded-listed cells", !entry_exists ? "Added" : "Modified", l.meas_obj_id, local_obj.carrier_freq, local_obj.cells_to_add_mod_list.size(), - local_obj.black_cells_to_add_mod_list.size()); + local_obj.excluded_cells_to_add_mod_list.size()); if (logger.debug.enabled()) { for (auto& c : local_obj.cells_to_add_mod_list) { logger.debug( "MEAS: cell idx=%d, pci=%d, q_offset=%d", c.cell_idx, c.pci, c.cell_individual_offset.to_number()); } - for (auto& b : local_obj.black_cells_to_add_mod_list) { - logger.debug("MEAS: black-listed cell idx=%d", b.cell_idx); + for (auto& b : local_obj.excluded_cells_to_add_mod_list) { + logger.debug("MEAS: excluded-listed cell idx=%d", b.cell_idx); } } } @@ -1272,17 +1284,17 @@ void rrc::rrc_meas::var_meas_cfg::measObject_addmod_nr_r15(const meas_obj_to_add local_obj.carrier_freq_r15 = cfg_obj.carrier_freq_r15; // Combine the new cells with the existing ones and remove the cells indicated in config - // Do the same with black list + // Do the same with excluded list { - if (cfg_obj.black_cells_to_rem_list_r15_present) { - apply_remlist_diff(local_obj.black_cells_to_add_mod_list_r15, - cfg_obj.black_cells_to_rem_list_r15, - local_obj.black_cells_to_add_mod_list_r15); + if (cfg_obj.excluded_cells_to_rem_list_r15_present) { + apply_remlist_diff(local_obj.excluded_cells_to_add_mod_list_r15, + cfg_obj.excluded_cells_to_rem_list_r15, + local_obj.excluded_cells_to_add_mod_list_r15); } - if (cfg_obj.black_cells_to_add_mod_list_r15_present) { - apply_addmodlist_diff(local_obj.black_cells_to_add_mod_list_r15, - cfg_obj.black_cells_to_add_mod_list_r15, - local_obj.black_cells_to_add_mod_list_r15); + if (cfg_obj.excluded_cells_to_add_mod_list_r15_present) { + apply_addmodlist_diff(local_obj.excluded_cells_to_add_mod_list_r15, + cfg_obj.excluded_cells_to_add_mod_list_r15, + local_obj.excluded_cells_to_add_mod_list_r15); } } // for each measId associated with this measObjectId in the measIdList within the VarMeasConfig @@ -1293,14 +1305,14 @@ void rrc::rrc_meas::var_meas_cfg::measObject_addmod_nr_r15(const meas_obj_to_add } } - logger.info("MEAS (NR R15): %s objectId=%d, carrier_freq=%d, %u black-listed cells", + logger.info("MEAS (NR R15): %s objectId=%d, carrier_freq=%d, %u excluded-listed cells", !entry_exists ? "Added" : "Modified", l.meas_obj_id, local_obj.carrier_freq_r15, - local_obj.black_cells_to_add_mod_list_r15.size()); + local_obj.excluded_cells_to_add_mod_list_r15.size()); if (logger.debug.enabled()) { - for (auto& b : local_obj.black_cells_to_add_mod_list_r15) { - logger.debug("MEAS: black-listed cell idx=%d", b.cell_idx_r15); + for (auto& b : local_obj.excluded_cells_to_add_mod_list_r15) { + logger.debug("MEAS: excluded-listed cell idx=%d", b.cell_idx_r15); } } } diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index 677c4aefc3..6b2de8e2bc 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -50,7 +50,7 @@ proc_outcome_t rrc::cell_search_proc::init() { Info("Starting..."); state = state_t::phy_cell_search; - if (not rrc_ptr->phy_ctrl->start_cell_search(rrc_ptr->cell_searcher)) { + if (not rrc_ptr->phy_ctrl->start_cell_search(rrc_ptr->cell_searcher, rrc_ptr->cell_search_earfcn)) { Warning("Failed to initiate Cell Search."); return proc_outcome_t::error; } @@ -200,7 +200,7 @@ std::pair compute_si_periodicity_and_idx(uint32_t sib_index, // SIB3+ scheduling Section 5.2.3 for (uint32_t i = 0; i < sib1->sched_info_list.size(); ++i) { for (uint32_t j = 0; j < sib1->sched_info_list[i].sib_map_info.size(); ++j) { - if (sib1->sched_info_list[i].sib_map_info[j].to_number() == sib_index + 1) { + if (get_sib_number(sib1->sched_info_list[i].sib_map_info[j]) == sib_index + 1) { return {sib1->sched_info_list[i].si_periodicity.to_number(), i}; } } @@ -1265,11 +1265,14 @@ proc_outcome_t rrc::go_idle_proc::step() void rrc::go_idle_proc::then(const srsran::proc_state_t& result) { - if (rrc_ptr->nas->is_registered() and not rrc_ptr->cell_reselector.launch()) { - rrc_ptr->logger.error("Failed to initiate a Cell Reselection procedure..."); - return; + // only start cell reselection if no RRC redirect is present (redirect will trigger a cell search) + if (rrc_ptr->cell_search_earfcn < 0) { + if (rrc_ptr->nas->is_registered() and not rrc_ptr->cell_reselector.launch()) { + rrc_ptr->logger.error("Failed to initiate a Cell Reselection procedure..."); + return; + } + rrc_ptr->callback_list.add_proc(rrc_ptr->cell_reselector); } - rrc_ptr->callback_list.add_proc(rrc_ptr->cell_reselector); } /************************************** @@ -1371,7 +1374,7 @@ proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause) { // Save Current RNTI before MAC Reset uint16_t crnti = rrc_ptr->mac->get_crnti(); - size_t nof_scells_active = rrc_ptr->phy_ctrl->current_config_scells().count(); + size_t nof_scells_active = rrc_ptr->phy_ctrl->current_config_scells().count(); // 5.3.7.1 - Conditions for Reestablishment procedure if (not rrc_ptr->security_is_activated or rrc_ptr->state != RRC_STATE_CONNECTED or crnti == SRSRAN_INVALID_RNTI) { @@ -1393,9 +1396,9 @@ proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause) reest_cellid = rrc_ptr->meas_cells.find_cell(reest_source_freq, reest_source_pci)->get_cell_id(); Info("Starting... cause: \"%s\", UE context: {C-RNTI=0x%x, PCI=%d, CELL ID=%d}", - reest_cause == asn1::rrc::reest_cause_opts::recfg_fail - ? "Reconfiguration failure" - : cause == asn1::rrc::reest_cause_opts::ho_fail ? "Handover failure" : "Other failure", + reest_cause == asn1::rrc::reest_cause_opts::recfg_fail ? "Reconfiguration failure" + : cause == asn1::rrc::reest_cause_opts::ho_fail ? "Handover failure" + : "Other failure", reest_rnti, reest_source_pci, reest_cellid); @@ -1561,6 +1564,8 @@ srsran::proc_outcome_t rrc::connection_reest_proc::react(const asn1::rrc::rrc_co // 1> perform the measurement related actions as specified in 5.5.6.1; rrc_ptr->measurements->ho_reest_actions(rrc_ptr->get_serving_cell()->get_earfcn(), rrc_ptr->get_serving_cell()->get_earfcn()); + // Update PHY measurements after HO Reestablishment actions. + rrc_ptr->measurements->update_phy(); // 1> submit the RRCConnectionReestablishmentComplete message to lower layers for transmission, upon which the // procedure ends; @@ -1744,11 +1749,7 @@ srsran::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc // perform the measurement related actions as specified in 5.5.6.1; rrc_ptr->measurements->ho_reest_actions(ho_src_cell.earfcn, target_earfcn); - // if the RRCConnectionReconfiguration message includes the measConfig: - if (not rrc_ptr->measurements->parse_meas_config(&recfg_r8, true, ho_src_cell.earfcn)) { - Error("Parsing measurementConfig. TODO: Send ReconfigurationReject"); - return proc_outcome_t::yield; // wait for t304 expiry - } + // Do not update PHY measurements here since it will be updated after the HO procedure finishes // Note: We delay the enqueuing of RRC Reconf Complete message to avoid that the message goes in an UL grant // directed at the old RNTI. @@ -1785,6 +1786,12 @@ srsran::proc_outcome_t rrc::ho_proc::react(ra_completed_ev ev) if (ev.success) { Info("Random Access completed. Applying final configuration and finishing procedure"); + // if the RRCConnectionReconfiguration message includes the measConfig: + if (not rrc_ptr->measurements->parse_meas_config(&recfg_r8, true, ho_src_cell.earfcn)) { + Error("Parsing measurementConfig. TODO: Send ReconfigurationReject"); + return proc_outcome_t::yield; // wait for t304 expiry + } + // TS 36.331, sec. 5.3.5.4, last "1>" rrc_ptr->t304.stop(); rrc_ptr->apply_rr_config_dedicated_on_ho_complete(recfg_r8.rr_cfg_ded); @@ -1802,6 +1809,8 @@ void rrc::ho_proc::then(const srsran::proc_state_t& result) srsran::console("HO %ssuccessful\n", result.is_success() ? "" : "un"); rrc_ptr->t304.stop(); + + rrc_ptr->measurements->update_phy(); } } // namespace srsue diff --git a/srsue/src/stack/rrc/rrc_rlf_report.cc b/srsue/src/stack/rrc/rrc_rlf_report.cc index eb5f977e39..292fb5efe5 100644 --- a/srsue/src/stack/rrc/rrc_rlf_report.cc +++ b/srsue/src/stack/rrc/rrc_rlf_report.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/rrc/test/CMakeLists.txt b/srsue/src/stack/rrc/test/CMakeLists.txt index 7567f75a97..9b591eaa93 100644 --- a/srsue/src/stack/rrc/test/CMakeLists.txt +++ b/srsue/src/stack/rrc/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -36,17 +36,4 @@ add_test(rrc_cell_test rrc_cell_test) add_executable(rrc_rlf_report_test rrc_rlf_report_test.cc) target_link_libraries(rrc_rlf_report_test srsue_rrc srsue_upper srsran_pdcp srsran_phy rrc_asn1 rrc_nr_asn1) -add_test(rrc_rlf_report_test rrc_rlf_report_test) - -add_executable(ue_rrc_nr_test ue_rrc_nr_test.cc) -target_link_libraries(ue_rrc_nr_test srsue_rrc_nr srsue_upper srsran_common srsran_pdcp srsran_phy rrc_asn1 rrc_nr_asn1) - -######################################################################## -# Option to run command after build (useful for remote builds) -######################################################################## -if (NOT ${BUILD_CMD} STREQUAL "") - message(STATUS "Added custom post-build command: ${BUILD_CMD}") - add_custom_command(TARGET ip_test POST_BUILD COMMAND ${BUILD_CMD}) -else(NOT ${BUILD_CMD} STREQUAL "") - message(STATUS "No post-build command defined") -endif (NOT ${BUILD_CMD} STREQUAL "") +add_test(rrc_rlf_report_test rrc_rlf_report_test) \ No newline at end of file diff --git a/srsue/src/stack/rrc/test/rrc_cell_test.cc b/srsue/src/stack/rrc/test/rrc_cell_test.cc index 3d68eaf8fd..da707247cf 100644 --- a/srsue/src/stack/rrc/test/rrc_cell_test.cc +++ b/srsue/src/stack/rrc/test/rrc_cell_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -66,6 +66,7 @@ int test_add_neighbours() TESTASSERT(list.get_neighbour_cell_handle(0, 0) == nullptr); phy_meas_t pmeas; + pmeas.rat = srsran::srsran_rat_t::lte; pmeas.cfo_hz = 4; pmeas.rsrp = -20; pmeas.pci = 1; diff --git a/srsue/src/stack/rrc/test/rrc_meas_test.cc b/srsue/src/stack/rrc/test/rrc_meas_test.cc index d36a1cb723..dac4bea625 100644 --- a/srsue/src/stack/rrc/test/rrc_meas_test.cc +++ b/srsue/src/stack/rrc/test/rrc_meas_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -26,7 +26,7 @@ #include "srsran/upper/pdcp.h" #include "srsue/hdr/stack/rrc/rrc.h" #include "srsue/hdr/stack/rrc/rrc_meas.h" -#include "srsue/hdr/stack/rrc/rrc_nr.h" +#include "srsue/hdr/stack/rrc_nr/rrc_nr.h" #include "srsue/hdr/stack/upper/nas.h" #include @@ -49,7 +49,7 @@ class phy_test final : public phy_interface_rrc_lte void set_config_mbsfn_sib2(srsran::mbsfn_sf_cfg_t* cfg_list, uint32_t nof_cfgs) override {} void set_config_mbsfn_sib13(const srsran::sib13_t& sib13) override {} void set_config_mbsfn_mcch(const srsran::mcch_msg_t& mcch) override {} - bool cell_search() override { return true; } + bool cell_search(int earfcn) override { return true; } bool cell_is_camping() override { return true; } void deactivate_scells() override {} bool cell_select(phy_cell_t cell) override @@ -180,13 +180,7 @@ class rrc_nr_test final : public srsue::rrc_nr_interface_rrc int get_nr_capabilities(srsran::byte_buffer_t* nr_cap) override { return SRSRAN_SUCCESS; }; void phy_set_cells_to_meas(uint32_t carrier_freq_r15) override{}; void phy_meas_stop() override{}; - bool rrc_reconfiguration(bool endc_release_and_add_r15, - bool nr_secondary_cell_group_cfg_r15_present, - asn1::dyn_octstring nr_secondary_cell_group_cfg_r15, - bool sk_counter_r15_present, - uint32_t sk_counter_r15, - bool nr_radio_bearer_cfg1_r15_present, - asn1::dyn_octstring nr_radio_bearer_cfg1_r15) override + bool rrc_reconfiguration(bool endc_release_and_add_r15, const asn1::rrc_nr::rrc_recfg_s& rrc_nr_reconf) override { return false; } diff --git a/srsue/src/stack/rrc/test/rrc_phy_ctrl_test.cc b/srsue/src/stack/rrc/test/rrc_phy_ctrl_test.cc index afbbca0240..fcea9429cf 100644 --- a/srsue/src/stack/rrc/test/rrc_phy_ctrl_test.cc +++ b/srsue/src/stack/rrc/test/rrc_phy_ctrl_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -90,7 +90,7 @@ int test_phy_ctrl_fsm() TESTASSERT(phy_ctrl.is_in_sync()); // TEST: Correct initiation of Cell Search state - TESTASSERT(phy_ctrl.start_cell_search(csearch_tester)); + TESTASSERT(phy_ctrl.start_cell_search(csearch_tester, -1)); TESTASSERT(not phy_ctrl.is_in_sync()); // TEST: Cell Search only listens to a cell search result event diff --git a/srsue/src/stack/rrc/test/rrc_reconfig_test.cc b/srsue/src/stack/rrc/test/rrc_reconfig_test.cc index 5535c03381..7e4b6e61f6 100644 --- a/srsue/src/stack/rrc/test/rrc_reconfig_test.cc +++ b/srsue/src/stack/rrc/test/rrc_reconfig_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/rrc/test/rrc_rlf_report_test.cc b/srsue/src/stack/rrc/test/rrc_rlf_report_test.cc index 2d639b1724..eba59f9ee5 100644 --- a/srsue/src/stack/rrc/test/rrc_rlf_report_test.cc +++ b/srsue/src/stack/rrc/test/rrc_rlf_report_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc b/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc deleted file mode 100644 index 7fc102a5a4..0000000000 --- a/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc +++ /dev/null @@ -1,224 +0,0 @@ -/** - * Copyright 2013-2021 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/. - * - */ - -#include "srsran/common/test_common.h" -#include "srsran/interfaces/ue_gw_interfaces.h" -#include "srsran/interfaces/ue_interfaces.h" -#include "srsran/interfaces/ue_pdcp_interfaces.h" -#include "srsran/interfaces/ue_rlc_interfaces.h" -#include "srsran/interfaces/ue_usim_interfaces.h" -#include "srsue/hdr/stack/rrc/rrc_nr.h" - -using namespace srsue; - -class dummy_phy : public phy_interface_rrc_nr -{ - bool set_config(const srsran::phy_cfg_nr_t& cfg) { return true; } -}; - -class dummy_mac : public mac_interface_rrc_nr -{ - void reset() {} - int setup_lcid(const srsran::logical_channel_config_t& config) { return SRSRAN_SUCCESS; } - int set_config(const srsran::bsr_cfg_nr_t& bsr_cfg) { return SRSRAN_SUCCESS; } - int set_config(const srsran::sr_cfg_nr_t& sr_cfg) { return SRSRAN_SUCCESS; } - int set_config(const srsran::dl_harq_cfg_nr_t& dl_hrq_cfg) { return SRSRAN_SUCCESS; } - void set_config(const srsran::rach_nr_cfg_t& rach_cfg) {} - int add_tag_config(const srsran::tag_cfg_nr_t& tag_cfg) { return SRSRAN_SUCCESS; } - int set_config(const srsran::phr_cfg_nr_t& phr_cfg) { return SRSRAN_SUCCESS; } - int remove_tag_config(const uint32_t tag_id) { return SRSRAN_SUCCESS; } - - void start_ra_procedure() {} - - void set_contention_id(const uint64_t ue_identity){}; - - bool set_crnti(const uint16_t crnti) { return true; }; -}; - -class dummy_rlc : public rlc_interface_rrc -{ - void reset() {} - void reestablish() {} - void reestablish(uint32_t lcid) {} - int add_bearer(uint32_t lcid, const srsran::rlc_config_t& cnfg) { return SRSRAN_SUCCESS; } - int add_bearer_mrb(uint32_t lcid) { return SRSRAN_SUCCESS; } - void del_bearer(uint32_t lcid) {} - void suspend_bearer(uint32_t lcid) {} - void resume_bearer(uint32_t lcid) {} - void change_lcid(uint32_t old_lcid, uint32_t new_lcid) {} - bool has_bearer(uint32_t lcid) { return true; } - bool has_data(const uint32_t lcid) { return true; } - bool is_suspended(const uint32_t lcid) { return true; } - void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} -}; - -class dummy_pdcp : public pdcp_interface_rrc -{ - void set_enabled(uint32_t lcid, bool enabled){}; - void reestablish(){}; - void reestablish(uint32_t lcid){}; - void reset(){}; - void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu, int sn = -1){}; - int add_bearer(uint32_t lcid, const srsran::pdcp_config_t& cnfg) { return SRSRAN_SUCCESS; }; - void del_bearer(uint32_t lcid){}; - void change_lcid(uint32_t old_lcid, uint32_t new_lcid){}; - void config_security(uint32_t lcid, const srsran::as_security_config_t& sec_cfg){}; - void config_security_all(const srsran::as_security_config_t& sec_cfg){}; - void enable_integrity(uint32_t lcid, srsran::srsran_direction_t direction){}; - void enable_encryption(uint32_t lcid, - srsran::srsran_direction_t direction = srsran::srsran_direction_t::DIRECTION_TXRX){}; - void send_status_report(){}; - void send_status_report(uint32_t lcid){}; -}; - -class dummy_gw : public gw_interface_rrc -{ - void add_mch_port(uint32_t lcid, uint32_t port){}; - bool is_running() { return true; }; -}; - -class dummy_eutra : public rrc_eutra_interface_rrc_nr -{ - void new_cell_meas_nr(const std::vector& meas){}; - void nr_rrc_con_reconfig_complete(bool status){}; - void nr_notify_reconfiguration_failure(){}; - void nr_scg_failure_information(const srsran::scg_failure_cause_t cause){}; -}; - -class dummy_sim : public usim_interface_rrc_nr -{ - bool generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) { return true; } - bool update_nr_context(srsran::as_security_config_t* sec_cfg) { return true; } -}; - -class dummy_stack : public stack_interface_rrc -{ - srsran::tti_point get_current_tti() final { return srsran::tti_point(); }; - void add_eps_bearer(uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid) final{}; - void remove_eps_bearer(uint8_t eps_bearer_id) final{}; - void reset_eps_bearers() final{}; -}; - -int rrc_nr_cap_request_test() -{ - srslog::init(); - srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR"); - logger.set_level(srslog::basic_levels::debug); - logger.set_hex_dump_max_size(-1); - srsran::task_scheduler task_sched{512, 100}; - srsran::task_sched_handle task_sched_handle(&task_sched); - rrc_nr rrc_nr(task_sched_handle); - srsran::byte_buffer_t caps; - - dummy_phy dummy_phy; - dummy_mac dummy_mac; - dummy_rlc dummy_rlc; - dummy_pdcp dummy_pdcp; - dummy_gw dummy_gw; - dummy_eutra dummy_eutra; - dummy_sim dummy_sim; - dummy_stack dummy_stack; - rrc_nr_args_t rrc_nr_args; - - rrc_nr_args.supported_bands_eutra.push_back(7); - rrc_nr_args.supported_bands_nr.push_back(78); - - TESTASSERT(rrc_nr.init(&dummy_phy, - &dummy_mac, - &dummy_rlc, - &dummy_pdcp, - &dummy_gw, - &dummy_eutra, - &dummy_sim, - task_sched.get_timer_handler(), - &dummy_stack, - rrc_nr_args) == SRSRAN_SUCCESS); - - TESTASSERT(rrc_nr.get_eutra_nr_capabilities(&caps) == SRSRAN_SUCCESS); - TESTASSERT(rrc_nr.get_nr_capabilities(&caps) == SRSRAN_SUCCESS); - return SRSRAN_SUCCESS; -} - -int rrc_nr_reconfig_test() -{ - srslog::init(); - srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR"); - logger.set_level(srslog::basic_levels::debug); - logger.set_hex_dump_max_size(-1); - srsran::task_scheduler task_sched{512, 100}; - srsran::task_sched_handle task_sched_handle(&task_sched); - rrc_nr rrc_nr(task_sched_handle); - - dummy_phy dummy_phy; - dummy_mac dummy_mac; - dummy_rlc dummy_rlc; - dummy_pdcp dummy_pdcp; - dummy_gw dummy_gw; - dummy_eutra dummy_eutra; - dummy_sim dummy_sim; - dummy_stack dummy_stack; - rrc_nr_args_t rrc_nr_args; - TESTASSERT(rrc_nr.init(&dummy_phy, - &dummy_mac, - &dummy_rlc, - &dummy_pdcp, - &dummy_gw, - &dummy_eutra, - &dummy_sim, - task_sched.get_timer_handler(), - &dummy_stack, - rrc_nr_args) == SRSRAN_SUCCESS); - - uint8_t nr_secondary_cell_group_cfg_r15_bytes[] = { - 0x08, 0x81, 0x19, 0x5c, 0x40, 0xb1, 0x42, 0x7e, 0x08, 0x30, 0xf3, 0x20, 0x3e, 0x00, 0x80, 0x34, 0x1e, 0x00, 0x80, - 0x02, 0xe8, 0x5b, 0x98, 0xc0, 0x06, 0x93, 0x5a, 0x40, 0x04, 0xd2, 0x6b, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x8d, 0xb2, - 0x45, 0xe2, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1b, 0x82, 0x21, 0x00, 0x00, 0x44, 0x04, 0x00, 0xd0, - 0x1a, 0xe2, 0x00, 0x00, 0x01, 0x98, 0x71, 0xb6, 0x48, 0x95, 0x00, 0x20, 0x07, 0xb7, 0x25, 0x58, 0xf0, 0x00, 0x00, - 0x13, 0x8c, 0x21, 0xb8, 0x83, 0x69, 0x92, 0xa0, 0xb8, 0x75, 0x01, 0x08, 0x1c, 0x0c, 0x00, 0x30, 0x78, 0x00, 0x03, - 0x49, 0xa9, 0xe0, 0x07, 0xb7, 0x25, 0x58, 0x00, 0x25, 0x06, 0xa0, 0x00, 0x80, 0xe0, 0x12, 0xd8, 0x0c, 0x88, 0x03, - 0x70, 0x84, 0x20, 0x00, 0x11, 0x11, 0x6d, 0x00, 0x00, 0x00, 0x12, 0x08, 0x00, 0x00, 0x83, 0xa6, 0x02, 0x66, 0xaa, - 0xe9, 0x28, 0x38, 0x00, 0x20, 0x81, 0x84, 0x0a, 0x18, 0x39, 0x38, 0x81, 0x22, 0x85, 0x8c, 0x1a, 0x38, 0x78, 0xfc, - 0x00, 0x00, 0x66, 0x02, 0x18, 0x10, 0x00, 0xcc, 0x04, 0xb0, 0x40, 0x01, 0x98, 0x0a, 0x60, 0xc0, 0x03, 0x30, 0x16, - 0xc2, 0x00, 0x06, 0x60, 0x31, 0x85, 0x00, 0x0c, 0xc0, 0x6b, 0x0c, 0x00, 0x19, 0x80, 0xe6, 0x1c, 0x00, 0x33, 0x21, - 0x40, 0x31, 0x00, 0x01, 0x72, 0x58, 0x62, 0x40, 0x02, 0xe4, 0xb2, 0xc5, 0x00, 0x05, 0xc9, 0x69, 0x8b, 0x00, 0x0b, - 0x92, 0xdb, 0x18, 0x00, 0x17, 0x25, 0xc6, 0x34, 0x00, 0x2e, 0x4b, 0xac, 0x70, 0x00, 0x5c, 0x97, 0x98, 0xf0, 0x00, - 0xcd, 0x85, 0x07, 0x95, 0xe5, 0x79, 0x43, 0x01, 0xe4, 0x07, 0x23, 0x45, 0x67, 0x89, 0x7d, 0x42, 0x10, 0x84, 0x00, - 0x0c, 0xd0, 0x1a, 0x41, 0x07, 0x82, 0xb8, 0x03, 0x04, 0x28, 0x01, 0x63, 0xff, 0x4a, 0x52, 0x63, 0x18, 0xdc, 0xa0, - 0x50, 0x00, 0x08, 0x72, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12, 0x00, 0x00, 0x00, 0x04, 0x8a, 0x80}; - - asn1::dyn_octstring nr_secondary_cell_group_cfg_r15; - nr_secondary_cell_group_cfg_r15.resize(sizeof(nr_secondary_cell_group_cfg_r15_bytes)); - memcpy(nr_secondary_cell_group_cfg_r15.data(), - nr_secondary_cell_group_cfg_r15_bytes, - sizeof(nr_secondary_cell_group_cfg_r15_bytes)); - - asn1::dyn_octstring nr_radio_bearer_cfg1_r15; - rrc_nr.rrc_reconfiguration(true, true, nr_secondary_cell_group_cfg_r15, false, 0, false, nr_radio_bearer_cfg1_r15); - task_sched.run_pending_tasks(); - return SRSRAN_SUCCESS; -} - -int main(int argc, char** argv) -{ - TESTASSERT(rrc_nr_cap_request_test() == SRSRAN_SUCCESS); - TESTASSERT(rrc_nr_reconfig_test() == SRSRAN_SUCCESS); - return SRSRAN_SUCCESS; -} diff --git a/srsue/src/stack/rrc_nr/CMakeLists.txt b/srsue/src/stack/rrc_nr/CMakeLists.txt new file mode 100644 index 0000000000..5f0d532f09 --- /dev/null +++ b/srsue/src/stack/rrc_nr/CMakeLists.txt @@ -0,0 +1,24 @@ +# +# Copyright 2013-2023 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/. +# + +add_subdirectory(test) + +set(SOURCES rrc_nr.cc rrc_nr_procedures.cc ../rrc/rrc_cell.cc) +add_library(srsue_rrc_nr STATIC ${SOURCES}) \ No newline at end of file diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc_nr/rrc_nr.cc similarity index 57% rename from srsue/src/stack/rrc/rrc_nr.cc rename to srsue/src/stack/rrc_nr/rrc_nr.cc index e61059c37a..325ee70adb 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc_nr/rrc_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -19,29 +19,34 @@ * */ -#include "srsue/hdr/stack/rrc/rrc_nr.h" +#include "srsue/hdr/stack/rrc_nr/rrc_nr.h" #include "srsran/common/band_helper.h" #include "srsran/common/security.h" #include "srsran/common/standard_streams.h" #include "srsran/interfaces/ue_pdcp_interfaces.h" #include "srsran/interfaces/ue_rlc_interfaces.h" +#include "srsue/hdr/stack/rrc_nr/rrc_nr_procedures.h" #include "srsue/hdr/stack/upper/usim.h" -#define Error(fmt, ...) rrc_ptr->logger.error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define Warning(fmt, ...) rrc_ptr->logger.warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define Info(fmt, ...) rrc_ptr->logger.info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) -#define Debug(fmt, ...) rrc_ptr->logger.debug("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) - using namespace asn1::rrc_nr; using namespace asn1; using namespace srsran; + namespace srsue { -const char* rrc_nr::rrc_nr_state_text[] = {"IDLE", "CONNECTED", "CONNECTED-INACTIVE"}; +const static char* rrc_nr_state_text[] = {"IDLE", "CONNECTED", "CONNECTED-INACTIVE"}; rrc_nr::rrc_nr(srsran::task_sched_handle task_sched_) : - logger(srslog::fetch_basic_logger("RRC-NR")), task_sched(task_sched_), conn_recfg_proc(this) -{} + logger(srslog::fetch_basic_logger("RRC-NR")), + task_sched(task_sched_), + conn_recfg_proc(*this), + conn_setup_proc(*this), + setup_req_proc(*this), + cell_selector(*this), + meas_cells(task_sched_) +{ + set_phy_default_config(); +} rrc_nr::~rrc_nr() = default; @@ -49,7 +54,9 @@ int rrc_nr::init(phy_interface_rrc_nr* phy_, mac_interface_rrc_nr* mac_, rlc_interface_rrc* rlc_, pdcp_interface_rrc* pdcp_, + sdap_interface_rrc* sdap_, gw_interface_rrc* gw_, + nas_5g_interface_rrc_nr* nas_, rrc_eutra_interface_rrc_nr* rrc_eutra_, usim_interface_rrc_nr* usim_, srsran::timer_handler* timers_, @@ -59,13 +66,52 @@ int rrc_nr::init(phy_interface_rrc_nr* phy_, phy = phy_; rlc = rlc_; pdcp = pdcp_; + sdap = sdap_; gw = gw_; + nas = nas_; mac = mac_; rrc_eutra = rrc_eutra_; usim = usim_; stack = stack_; args = args_; + // allocate RRC timers + t300 = task_sched.get_unique_timer(); + t301 = task_sched.get_unique_timer(); + t302 = task_sched.get_unique_timer(); + t304 = task_sched.get_unique_timer(); + t310 = task_sched.get_unique_timer(); + t311 = task_sched.get_unique_timer(); + + if (rrc_eutra == nullptr) { + // SA mode + plmn_is_selected = true; + + // setup inital HARQ config + srsran::dl_harq_cfg_nr_t harq_cfg = {}; + harq_cfg.nof_procs = 8; + mac->set_config(harq_cfg); + + // Setup SRB0 + logical_channel_config_t lch = {}; + mac->setup_lcid(lch); + + // Carrier config + srsran::srsran_band_helper bands; + phy_cfg.carrier.dl_center_frequency_hz = bands.nr_arfcn_to_freq(args.dl_nr_arfcn); + phy_cfg.carrier.ul_center_frequency_hz = bands.nr_arfcn_to_freq(bands.get_ul_arfcn_from_dl_arfcn(args.dl_nr_arfcn)); + phy_cfg.carrier.ssb_center_freq_hz = bands.nr_arfcn_to_freq(args.ssb_nr_arfcn); + phy_cfg.carrier.nof_prb = args.nof_prb; + phy_cfg.carrier.max_mimo_layers = 1; + phy_cfg.carrier.scs = args.scs; + phy_cfg.duplex.mode = bands.get_duplex_mode(bands.get_band_from_dl_arfcn(args.dl_nr_arfcn)); + + // SSB configuration + phy_cfg.ssb.periodicity_ms = 10; + phy_cfg.ssb.position_in_burst[0] = true; + phy_cfg.ssb.scs = args.ssb_scs; + } + running = true; sim_measurement_timer = task_sched.get_unique_timer(); return SRSRAN_SUCCESS; @@ -76,26 +122,10 @@ void rrc_nr::stop() running = false; } -void rrc_nr::init_core_less() +void rrc_nr::get_metrics(rrc_nr_metrics_t& m) { - logger.info("Creating dummy DRB on LCID=%d", args.coreless.drb_lcid); - srsran::rlc_config_t rlc_cnfg = srsran::rlc_config_t::default_rlc_um_nr_config(6); - rlc->add_bearer(args.coreless.drb_lcid, rlc_cnfg); - - srsran::pdcp_config_t pdcp_cnfg{args.coreless.drb_lcid, - srsran::PDCP_RB_IS_DRB, - srsran::SECURITY_DIRECTION_DOWNLINK, - srsran::SECURITY_DIRECTION_UPLINK, - srsran::PDCP_SN_LEN_18, - srsran::pdcp_t_reordering_t::ms500, - srsran::pdcp_discard_timer_t::ms100, - false, - srsran_rat_t::nr}; - - pdcp->add_bearer(args.coreless.drb_lcid, pdcp_cnfg); - return; + m.state = state; } -void rrc_nr::get_metrics(rrc_nr_metrics_t& m) {} const char* rrc_nr::get_rb_name(uint32_t lcid) { @@ -113,7 +143,7 @@ const char* rrc_nr::get_rb_name(uint32_t lcid) void rrc_nr::timer_expired(uint32_t timeout_id) { logger.debug("Handling Timer Expired"); - if (timeout_id == sim_measurement_timer.id()) { + if (timeout_id == sim_measurement_timer.id() && rrc_eutra != nullptr) { logger.debug("Triggered simulated measurement"); phy_meas_nr_t sim_meas = {}; @@ -211,13 +241,584 @@ void rrc_nr::out_of_sync() {} void rrc_nr::run_tti(uint32_t tti) {} // PDCP interface -void rrc_nr::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) {} +void rrc_nr::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) +{ + logger.debug("RX PDU, LCID: %d", lcid); + switch (static_cast(lcid)) { + case nr_srb::srb0: + decode_dl_ccch(std::move(pdu)); + break; + case nr_srb::srb1: + case nr_srb::srb2: + decode_dl_dcch(lcid, std::move(pdu)); + break; + default: + logger.error("RX PDU with invalid bearer id: %d", lcid); + break; + } +} + +void rrc_nr::decode_dl_ccch(unique_byte_buffer_t pdu) +{ + asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); + asn1::rrc_nr::dl_ccch_msg_s dl_ccch_msg; + if (dl_ccch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or + dl_ccch_msg.msg.type().value != dl_ccch_msg_type_c::types_opts::c1) { + logger.error(pdu->msg, pdu->N_bytes, "Failed to unpack DL-CCCH message (%d B)", pdu->N_bytes); + return; + } + log_rrc_message( + get_rb_name(srb_to_lcid(nr_srb::srb0)), Rx, pdu.get(), dl_ccch_msg, dl_ccch_msg.msg.c1().type().to_string()); + + dl_ccch_msg_type_c::c1_c_* c1 = &dl_ccch_msg.msg.c1(); + switch (dl_ccch_msg.msg.c1().type().value) { + case dl_ccch_msg_type_c::c1_c_::types::rrc_reject: { + // 5.3.15 + const auto& reject = c1->rrc_reject(); + srsran::console("Received RRC Reject\n"); + + t300.stop(); + + if (reject.crit_exts.rrc_reject().wait_time_present) { + // nas->set_barring(srsran::barring_t::all); + t302.set(reject.crit_exts.rrc_reject().wait_time * 1000, [this](uint32_t tid) { timer_expired(tid); }); + t302.run(); + } else { + // Perform the actions upon expiry of T302 if wait time is zero + // nas->set_barring(srsran::barring_t::none); + // start_go_idle(); + } + } break; + case dl_ccch_msg_type_c::c1_c_::types::rrc_setup: { + transaction_id = c1->rrc_setup().rrc_transaction_id; + rrc_setup_s rrc_setup_copy = c1->rrc_setup(); + task_sched.defer_task([this, rrc_setup_copy]() { handle_rrc_setup(rrc_setup_copy); }); + break; + } + default: + logger.error("The provided DL-CCCH message type is not recognized"); + break; + } +} + +void rrc_nr::decode_dl_dcch(uint32_t lcid, unique_byte_buffer_t pdu) +{ + asn1::cbit_ref bref(pdu->msg, pdu->N_bytes); + asn1::rrc_nr::dl_dcch_msg_s dl_dcch_msg; + if (dl_dcch_msg.unpack(bref) != asn1::SRSASN_SUCCESS or + dl_dcch_msg.msg.type().value != dl_dcch_msg_type_c::types_opts::c1) { + logger.error(pdu->msg, pdu->N_bytes, "Failed to unpack DL-DCCH message (%d B)", pdu->N_bytes); + return; + } + log_rrc_message(get_rb_name(lcid), Rx, pdu.get(), dl_dcch_msg, dl_dcch_msg.msg.c1().type().to_string()); + + dl_dcch_msg_type_c::c1_c_* c1 = &dl_dcch_msg.msg.c1(); + switch (dl_dcch_msg.msg.c1().type().value) { + // TODO: ADD missing cases + case dl_dcch_msg_type_c::c1_c_::types::rrc_recfg: { + rrc_recfg_s recfg = c1->rrc_recfg(); + task_sched.defer_task([this, recfg]() { handle_rrc_reconfig(recfg); }); + break; + } + case dl_dcch_msg_type_c::c1_c_::types::dl_info_transfer: { + dl_info_transfer_s dl_info_transfer = c1->dl_info_transfer(); + task_sched.defer_task([this, dl_info_transfer]() { handle_dl_info_transfer(dl_info_transfer); }); + break; + } + case dl_dcch_msg_type_c::c1_c_::types::security_mode_cmd: { + security_mode_cmd_s smc = c1->security_mode_cmd(); + task_sched.defer_task([this, smc]() { handle_security_mode_command(smc); }); + break; + } + case dl_dcch_msg_type_c::c1_c_::types::rrc_release: { + rrc_release_s rrc_release = c1->rrc_release(); + task_sched.defer_task([this, rrc_release]() { handle_rrc_release(rrc_release); }); + break; + } + case dl_dcch_msg_type_c::c1_c_::types::ue_cap_enquiry: { + ue_cap_enquiry_s ue_cap_enquiry = c1->ue_cap_enquiry(); + task_sched.defer_task([this, ue_cap_enquiry]() { handle_ue_capability_enquiry(ue_cap_enquiry); }); + break; + } + default: + logger.error("The provided DL-DCCH message type is not recognized or supported."); + break; + } +} + void rrc_nr::write_pdu_bcch_bch(srsran::unique_byte_buffer_t pdu) {} -void rrc_nr::write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu) {} +void rrc_nr::write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu) +{ + decode_pdu_bcch_dlsch(std::move(pdu)); +} + +void rrc_nr::decode_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu) +{ + // Stop BCCH search after successful reception of 1 BCCH block + // mac->bcch_stop_rx(); + + bcch_dl_sch_msg_s dlsch_msg; + asn1::cbit_ref dlsch_bref(pdu->msg, pdu->N_bytes); + asn1::SRSASN_CODE err = dlsch_msg.unpack(dlsch_bref); + + if (err != asn1::SRSASN_SUCCESS or dlsch_msg.msg.type().value != bcch_dl_sch_msg_type_c::types_opts::c1) { + logger.error(pdu->msg, pdu->N_bytes, "Could not unpack BCCH DL-SCH message (%d B).", pdu->N_bytes); + return; + } + + log_rrc_message("BCCH-DLSCH", Rx, pdu.get(), dlsch_msg, dlsch_msg.msg.c1().type().to_string()); + + if (dlsch_msg.msg.c1().type() == bcch_dl_sch_msg_type_c::c1_c_::types::sib_type1) { + logger.info("Processing SIB1 (1/1)"); + handle_sib1(dlsch_msg.msg.c1().sib_type1()); + } +} + +void rrc_nr::set_phy_default_config() +{ + phy_cfg = {}; + + // uses default values provided in 38.311 TS 138 331 V16.6 page 361 + if (make_phy_beta_offsets({}, &phy_cfg.pusch.beta_offsets) == false) { + logger.warning("Couldn't set default beta_offsets config"); + } + + // no default value provided, asume factor 1.0 + uci_on_pusch_s uci_on_pusch = {}; + uci_on_pusch.scaling = uci_on_pusch_s::scaling_opts::f1; + if (make_phy_pusch_scaling(uci_on_pusch, &phy_cfg.pusch.scaling) == false) { + logger.warning("Couldn't set default scaling config"); + } + + // no default value specified, use dynamic + phys_cell_group_cfg_s phys_cell_group_cfg = {}; + phys_cell_group_cfg.pdsch_harq_ack_codebook = phys_cell_group_cfg_s::pdsch_harq_ack_codebook_opts::dynamic_value; + if (make_phy_harq_ack_cfg(phys_cell_group_cfg, &phy_cfg.harq_ack) == false) { + logger.warning("Couldn't set default HARQ ack config"); + } +} + +void rrc_nr::handle_sib1(const sib1_s& sib1) +{ + if (meas_cells.serving_cell().has_sib1()) { + logger.info("SIB1 already processed"); + return; + } + + meas_cells.serving_cell().set_sib1(sib1); + + logger.info("SIB1 received, CellID=%d", meas_cells.serving_cell().get_cell_id() & 0xfff); + + // clang-format off + // unhandled fields: + // - cellSelectionInfo + // - cellAccessRelatedInfo + // - connEstFailureControl + // - servingCellConfigCommon: + // - downlinkConfigCommon.frequencyInfoDL.frequencyBandList + // - downlinkConfigCommon.frequencyInfoDL.offsetToPointA + // - downlinkConfigCommon.initialDownlinkBWP.genericParameters + // - downlinkConfigCommon.initialDownlinkBWP.pdcch-ConfigCommon.commonSearchSpaceList.searchSpaceSIB1 + // - downlinkConfigCommon.initialDownlinkBWP.pdcch-ConfigCommon.commonSearchSpaceList.search_space_other_sys_info + // - downlinkConfigCommon.initialDownlinkBWP.pdcch-ConfigCommon.commonSearchSpaceList.paging_search_space + // - downlinkConfigCommon.bcch-Config + // - downlinkConfigCommon.pcch-Config + // - uplinkConfigCommon.frequencyInfoUL.frequencyBandList + // - uplinkConfigCommon.frequencyInfoUL.p_max + // - uplinkConfigCommon.initialUplinkBWP.genericParameters + // - uplinkConfigCommon.initialUplinkBWP.rach-ConfigCommon.rach-ConfigGeneric.msg1-FDM + // - uplinkConfigCommon.initialUplinkBWP.rach-ConfigCommon.ssb_per_rach_occasion_and_cb_preambs_per_ssb + // - uplinkConfigCommon.initialUplinkBWP.rach-ConfigCommon.restricted_set_cfg + // - uplinkConfigCommon.initialUplinkBWP.pusch-ConfigCommon.pusch-TimeDomainResourceAllocationList.p0-NominalWithGrant + // - ss-PBCH-BlockPower + // clang-format on + + // ue-TimersAndConstants + auto timer_expire_func = [this](uint32_t tid) { timer_expired(tid); }; + t300.set(sib1.ue_timers_and_consts.t300.to_number(), timer_expire_func); + t301.set(sib1.ue_timers_and_consts.t301.to_number(), timer_expire_func); + t310.set(sib1.ue_timers_and_consts.t310.to_number(), timer_expire_func); + t311.set(sib1.ue_timers_and_consts.t311.to_number(), timer_expire_func); + N310 = sib1.ue_timers_and_consts.n310.to_number(); + N311 = sib1.ue_timers_and_consts.n311.to_number(); + + logger.info("Set Constants and Timers: N310=%d, N311=%d, t300=%d, t301=%d, t310=%d, t311=%d", + N310, + N311, + t300.duration(), + t301.duration(), + t310.duration(), + t311.duration()); + + // Apply RACH and timeAlginmentTimer configuration + mac_cfg_nr_t mac_cfg = {}; + make_mac_rach_cfg(sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common.setup(), &mac_cfg.rach_cfg); + mac_cfg.time_alignment_timer = sib1.serving_cell_cfg_common.ul_cfg_common.time_align_timer_common.to_number(); + + mac->set_config(mac_cfg.rach_cfg); + + // Apply PDSCH Config Common + if (sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup() + .pdsch_time_domain_alloc_list.size() > 0) { + if (not fill_phy_pdsch_cfg_common(sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup(), + &phy_cfg.pdsch)) { + logger.warning("Could not set PDSCH config."); + } + } + + // Apply PUSCH Config Common + if (not fill_phy_pusch_cfg_common(sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup(), + &phy_cfg.pusch)) { + logger.warning("Could not set PUSCH config."); + } + + // Apply PUCCH Config Common + fill_phy_pucch_cfg_common(sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.pucch_cfg_common.setup(), + &phy_cfg.pucch.common); + + // Apply RACH Config Common + if (not make_phy_rach_cfg(sib1.serving_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common.setup(), + sib1.serving_cell_cfg_common.tdd_ul_dl_cfg_common_present ? SRSRAN_DUPLEX_MODE_TDD + : SRSRAN_DUPLEX_MODE_FDD, + &phy_cfg.prach)) { + logger.warning("Could not set phy rach config."); + return; + } + + // Apply PDCCH Config Common + fill_phy_pdcch_cfg_common(sib1.serving_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdcch_cfg_common.setup(), + &phy_cfg.pdcch); + + // Apply Carrier Config + fill_phy_carrier_cfg(sib1.serving_cell_cfg_common, &phy_cfg.carrier); + + // Apply SSB Config + fill_phy_ssb_cfg(sib1.serving_cell_cfg_common, &phy_cfg.ssb); + + // Apply n-TimingAdvanceOffset + if (sib1.serving_cell_cfg_common.n_timing_advance_offset_present) { + switch (sib1.serving_cell_cfg_common.n_timing_advance_offset.value) { + case serving_cell_cfg_common_sib_s::n_timing_advance_offset_opts::n0: + phy_cfg.t_offset = 0; + break; + case serving_cell_cfg_common_sib_s::n_timing_advance_offset_opts::n25600: + phy_cfg.t_offset = 25600; + break; + case serving_cell_cfg_common_sib_s::n_timing_advance_offset_opts::n39936: + phy_cfg.t_offset = 39936; + break; + default: + logger.error("Invalid n_ta_offset option"); + break; + } + } else { + phy_cfg.t_offset = 25600; + } + + phy_cfg_state = PHY_CFG_STATE_SA_SIB_CFG; + if (not phy->set_config(phy_cfg)) { + logger.warning("Could not set phy config."); + return; + } + + // Notify cell selector of successful SIB1 reception + cell_selector.trigger(true); +} + void rrc_nr::write_pdu_pcch(srsran::unique_byte_buffer_t pdu) {} void rrc_nr::write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) {} void rrc_nr::notify_pdcp_integrity_error(uint32_t lcid) {} +// NAS interface +int rrc_nr::write_sdu(srsran::unique_byte_buffer_t sdu) +{ + if (state == RRC_NR_STATE_IDLE) { + logger.warning("Received ULInformationTransfer SDU when in IDLE"); + return SRSRAN_ERROR; + } + send_ul_info_transfer(std::move(sdu)); + return SRSRAN_SUCCESS; +} + +bool rrc_nr::is_connected() +{ + return state == RRC_NR_STATE_CONNECTED; +} + +int rrc_nr::connection_request(srsran::nr_establishment_cause_t cause, srsran::unique_byte_buffer_t dedicated_info_nas_) +{ + if (not setup_req_proc.launch(cause, std::move(dedicated_info_nas_))) { + logger.error("Failed to initiate setup request procedure"); + return SRSRAN_ERROR; + } + callback_list.add_proc(setup_req_proc); + return SRSRAN_SUCCESS; +} + +uint16_t rrc_nr::get_mcc() +{ + return meas_cells.serving_cell().get_mcc(); +} + +uint16_t rrc_nr::get_mnc() +{ + return meas_cells.serving_cell().get_mnc(); +} + +// Senders +void rrc_nr::send_ul_info_transfer(unique_byte_buffer_t nas_msg) +{ + logger.debug("Preparing UL Info Transfer"); + + ul_dcch_msg_s ul_dcch_msg; + ul_info_transfer_ies_s* ul_info_transfer = + &ul_dcch_msg.msg.set_c1().set_ul_info_transfer().crit_exts.set_ul_info_transfer(); + + // Try to resize target buffer first + ul_info_transfer->ded_nas_msg.resize(nas_msg->N_bytes); + + // check we have enough space in target buffer + if (nas_msg->N_bytes > ul_info_transfer->ded_nas_msg.size()) { + logger.error("NAS message too big to send in UL Info transfer (%d > %d).", + nas_msg->N_bytes, + ul_info_transfer->ded_nas_msg.size()); + return; + } + + // copy message content + memcpy(ul_info_transfer->ded_nas_msg.data(), nas_msg->msg, nas_msg->N_bytes); + + // send message + send_ul_dcch_msg(srb_to_lcid(nr_srb::srb1), ul_dcch_msg); +} + +void rrc_nr::send_security_mode_complete() +{ + ul_dcch_msg_s ul_dcch_msg; + auto& smc = ul_dcch_msg.msg.set_c1().set_security_mode_complete().crit_exts.set_security_mode_complete(); + ul_dcch_msg.msg.c1().security_mode_complete().rrc_transaction_id = transaction_id; + send_ul_dcch_msg(srb_to_lcid(nr_srb::srb1), ul_dcch_msg); +} + +void rrc_nr::send_setup_request(srsran::nr_establishment_cause_t cause) +{ + logger.debug("Preparing RRC Setup Request"); + + // Prepare SetupRequest packet + ul_ccch_msg_s ul_ccch_msg; + rrc_setup_request_ies_s* rrc_setup_req = &ul_ccch_msg.msg.set_c1().set_rrc_setup_request().rrc_setup_request; + + // TODO: implement ng_minus5_g_s_tmsi_part1 + rrc_setup_req->ue_id.set_random_value(); + // TODO use proper RNG + uint64_t random_id = 0; + for (uint i = 0; i < 5; i++) { // fill random ID bytewise, 40 bits = 5 bytes + random_id |= ((uint64_t)rand() & 0xFF) << i * 8; + } + rrc_setup_req->ue_id.random_value().from_number(random_id, rrc_setup_req->ue_id.random_value().length()); + rrc_setup_req->establishment_cause = (establishment_cause_opts::options)cause; + + send_ul_ccch_msg(ul_ccch_msg); +} + +void rrc_nr::send_ul_ccch_msg(const asn1::rrc_nr::ul_ccch_msg_s& msg) +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (pdu == nullptr) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return; + } + + asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); + if (msg.pack(bref) != SRSASN_SUCCESS) { + logger.error("Coulnd't pack UL-CCCH message."); + return; + } + bref.align_bytes_zero(); + pdu->N_bytes = (uint32_t)bref.distance_bytes(pdu->msg); + pdu->set_timestamp(); + + // Set UE contention resolution ID in MAC + uint64_t uecri = 0; + uint8_t* ue_cri_ptr = (uint8_t*)&uecri; + uint32_t nbytes = 6; + for (uint32_t i = 0; i < nbytes; i++) { + ue_cri_ptr[nbytes - i - 1] = pdu->msg[i]; + } + + logger.debug("Setting UE contention resolution ID: %" PRIu64 "", uecri); + mac->set_contention_id(uecri); + + uint32_t lcid = 0; + log_rrc_message(get_rb_name(lcid), Tx, pdu.get(), msg, msg.msg.c1().type().to_string()); + + rlc->write_sdu(lcid, std::move(pdu)); +} + +void rrc_nr::send_ul_dcch_msg(uint32_t lcid, const ul_dcch_msg_s& msg) +{ + // Reset and reuse sdu buffer if provided + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (pdu == nullptr) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return; + } + + asn1::bit_ref bref(pdu->msg, pdu->get_tailroom()); + msg.pack(bref); + bref.align_bytes_zero(); + pdu->N_bytes = (uint32_t)bref.distance_bytes(pdu->msg); + pdu->set_timestamp(); + + if (msg.msg.type() == ul_dcch_msg_type_c::types_opts::options::c1) { + log_rrc_message(get_rb_name(lcid), Tx, pdu.get(), msg, msg.msg.c1().type().to_string()); + } + + pdcp->write_sdu(lcid, std::move(pdu)); +} + +void rrc_nr::send_con_setup_complete(srsran::unique_byte_buffer_t nas_msg) +{ + logger.debug("Preparing RRC Connection Setup Complete"); + + // Prepare ConnectionSetupComplete packet + asn1::rrc_nr::ul_dcch_msg_s ul_dcch_msg; + rrc_setup_complete_ies_s* rrc_setup_complete = + &ul_dcch_msg.msg.set_c1().set_rrc_setup_complete().crit_exts.set_rrc_setup_complete(); + + ul_dcch_msg.msg.c1().rrc_setup_complete().rrc_transaction_id = transaction_id; + + rrc_setup_complete->sel_plmn_id = 1; + rrc_setup_complete->registered_amf_present = false; + rrc_setup_complete->guami_type_present = false; + rrc_setup_complete->ng_minus5_g_s_tmsi_value_present = false; + + rrc_setup_complete->ded_nas_msg.resize(nas_msg->N_bytes); + memcpy(rrc_setup_complete->ded_nas_msg.data(), nas_msg->msg, nas_msg->N_bytes); + + send_ul_dcch_msg(srb_to_lcid(nr_srb::srb1), ul_dcch_msg); +} + +void rrc_nr::send_rrc_reconfig_complete() +{ + logger.debug("Preparing RRC Connection Reconfig Complete"); + + asn1::rrc_nr::ul_dcch_msg_s ul_dcch_msg; + auto& rrc_reconfig_complete = ul_dcch_msg.msg.set_c1().set_rrc_recfg_complete().crit_exts.set_rrc_recfg_complete(); + ul_dcch_msg.msg.c1().rrc_recfg_complete().rrc_transaction_id = transaction_id; + + send_ul_dcch_msg(srb_to_lcid(nr_srb::srb1), ul_dcch_msg); +} + +int rrc_nr::send_ue_capability_info(const asn1::rrc_nr::ue_cap_enquiry_s& msg) +{ + transaction_id = msg.rrc_transaction_id; + + ue_cap_enquiry_ies_s ue_cap_enquiry_ies = msg.crit_exts.ue_cap_enquiry(); + + asn1::rrc_nr::ul_dcch_msg_s ul_dcch_msg; + + auto& ue_cap_info = ul_dcch_msg.msg.set_c1().set_ue_cap_info().crit_exts.set_ue_cap_info(); + ul_dcch_msg.msg.c1().ue_cap_info().rrc_transaction_id = msg.rrc_transaction_id; + + for (auto ue_cap_rat_request : ue_cap_enquiry_ies.ue_cap_rat_request_list) { + if (ue_cap_rat_request.rat_type.value == rat_type_opts::nr) { + ue_cap_info.ue_cap_rat_container_list_present = true; + ue_cap_rat_container_s ue_cap_rat_container; + ue_cap_rat_container.rat_type.value = rat_type_opts::nr; + + ue_nr_cap_s ue_cap; + ue_cap.access_stratum_release = access_stratum_release_opts::rel15; + + // RLC params + ue_cap.rlc_params_present = true; + ue_cap.rlc_params.am_with_short_sn_present = true; + ue_cap.rlc_params.um_with_short_sn_present = true; + ue_cap.rlc_params.um_with_long_sn_present = true; + + // PDCP parameters + ue_cap.pdcp_params.supported_rohc_profiles.profile0x0000 = false; + ue_cap.pdcp_params.supported_rohc_profiles.profile0x0001 = false; + ue_cap.pdcp_params.supported_rohc_profiles.profile0x0002 = false; + ue_cap.pdcp_params.supported_rohc_profiles.profile0x0003 = false; + ue_cap.pdcp_params.supported_rohc_profiles.profile0x0004 = false; + ue_cap.pdcp_params.supported_rohc_profiles.profile0x0006 = false; + ue_cap.pdcp_params.supported_rohc_profiles.profile0x0101 = false; + ue_cap.pdcp_params.supported_rohc_profiles.profile0x0102 = false; + ue_cap.pdcp_params.supported_rohc_profiles.profile0x0103 = false; + ue_cap.pdcp_params.supported_rohc_profiles.profile0x0104 = false; + ue_cap.pdcp_params.max_num_rohc_context_sessions.value = pdcp_params_s::max_num_rohc_context_sessions_opts::cs2; + + if (args.pdcp_short_sn_support) { + ue_cap.pdcp_params.short_sn_present = true; + } + // PHY Parameters + ue_cap.phy_params.phy_params_common_present = true; + + // RF Parameters + for (const auto band : args.supported_bands_nr) { + band_nr_s band_nr; + band_nr.band_nr = band; + ue_cap.rf_params.supported_band_list_nr.push_back(band_nr); + + // supportedBandCombinationList + band_combination_s band_combination; + band_params_c band_params; + band_params.set_nr().band_nr = band; + band_combination.band_list.push_back(band_params); + ue_cap.rf_params.supported_band_combination_list.push_back(band_combination); + } + // featureSets + ue_cap.feature_sets_present = true; + feature_set_dl_per_cc_s feature_set_dl_per_cc; + feature_set_ul_per_cc_s feature_set_ul_per_cc; + + feature_set_dl_per_cc.supported_bw_dl.set_fr1().value = supported_bw_c::fr1_opts::mhz10; + feature_set_ul_per_cc.supported_bw_ul.set_fr1().value = supported_bw_c::fr1_opts::mhz10; + + switch (args.scs) { + case srsran_subcarrier_spacing_15kHz: + feature_set_dl_per_cc.supported_subcarrier_spacing_dl = subcarrier_spacing_opts::khz15; + feature_set_ul_per_cc.supported_subcarrier_spacing_ul = subcarrier_spacing_opts::khz15; + break; + case srsran_subcarrier_spacing_30kHz: + feature_set_dl_per_cc.supported_subcarrier_spacing_dl = subcarrier_spacing_opts::khz30; + feature_set_ul_per_cc.supported_subcarrier_spacing_ul = subcarrier_spacing_opts::khz30; + break; + default: + logger.warning("Unsupported subcarrier spacing value"); + } + + ue_cap.feature_sets.feature_sets_dl_per_cc.push_back(feature_set_dl_per_cc); + ue_cap.feature_sets.feature_sets_ul_per_cc.push_back(feature_set_ul_per_cc); + +#if 1 + ue_cap_rat_container.ue_cap_rat_container.resize(512); + asn1::bit_ref bref_pack(ue_cap_rat_container.ue_cap_rat_container.data(), + ue_cap_rat_container.ue_cap_rat_container.size()); + + if (ue_cap.pack(bref_pack) != asn1::SRSASN_SUCCESS) { + logger.error("Failed to pack UE NR Capabilities in UE Capability Info"); + return SRSRAN_ERROR; + } + ue_cap_rat_container.ue_cap_rat_container.resize(bref_pack.distance_bytes()); +#else + // hard-coded capabilities from third-party + ue_cap_rat_container.ue_cap_rat_container.from_string("E1A01000074F5A03020000C0A0241262C001206A0609B00C39F30C7942" + "C0E098040623809506C4DD608D21A08107CA01165B262A87813E43" + "9F40CF88E3C639F30C7942C0E070F09C0013C0070004F0001601C00140" + "A836036B04690D04083E500892D931541439F11C78C73E618F2858" + "1C0E1E04FE0000003F80000000A00E05"); +#endif + + ue_cap_info.ue_cap_rat_container_list.push_back(ue_cap_rat_container); + } + } + send_ul_dcch_msg(srb_to_lcid(nr_srb::srb1), ul_dcch_msg); + return SRSASN_SUCCESS; +} + +// EUTRA-RRC interface int rrc_nr::get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps_pdu) { struct ue_mrdc_cap_s mrdc_cap; @@ -248,7 +849,6 @@ int rrc_nr::get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps_pdu) } mrdc_cap.rf_params_mrdc.supported_band_combination_list.push_back(band_combination); - mrdc_cap.rf_params_mrdc.supported_band_combination_list_present = true; mrdc_cap.rf_params_mrdc.ext = true; @@ -269,8 +869,6 @@ int rrc_nr::get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps_pdu) mrdc_cap.rf_params_mrdc.applied_freq_band_list_filt.push_back(band_info_nr); } - mrdc_cap.rf_params_mrdc.applied_freq_band_list_filt_present = true; - // rf_params_mrdc supported band combination list v1540 band_combination_list_v1540_l* band_combination_list_v1450 = new band_combination_list_v1540_l(); @@ -324,8 +922,6 @@ int rrc_nr::get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps_pdu) mrdc_cap.feature_set_combinations.push_back(feature_set_combination); - mrdc_cap.feature_set_combinations_present = true; - // Pack mrdc_cap asn1::bit_ref bref(eutra_nr_caps_pdu->msg, eutra_nr_caps_pdu->get_tailroom()); mrdc_cap.pack(bref); @@ -347,22 +943,9 @@ int rrc_nr::get_eutra_nr_capabilities(srsran::byte_buffer_t* eutra_nr_caps_pdu) return SRSRAN_SUCCESS; } -bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, - bool nr_secondary_cell_group_cfg_r15_present, - asn1::dyn_octstring nr_secondary_cell_group_cfg_r15, - bool sk_counter_r15_present, - uint32_t sk_counter_r15, - bool nr_radio_bearer_cfg1_r15_present, - asn1::dyn_octstring nr_radio_bearer_cfg1_r15) -{ - if (not conn_recfg_proc.launch(reconf_initiator_t::mcg_srb1, - endc_release_and_add_r15, - nr_secondary_cell_group_cfg_r15_present, - nr_secondary_cell_group_cfg_r15, - sk_counter_r15_present, - sk_counter_r15, - nr_radio_bearer_cfg1_r15_present, - nr_radio_bearer_cfg1_r15)) { +bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15, const asn1::rrc_nr::rrc_recfg_s& rrc_nr_reconf) +{ + if (not conn_recfg_proc.launch(reconf_initiator_t::mcg_srb1, endc_release_and_add_r15, rrc_nr_reconf)) { logger.error("Unable to launch NR RRC reconfiguration procedure"); return false; } else { @@ -377,6 +960,11 @@ void rrc_nr::rrc_release() pdcp->reset(); mac->reset(); lcid_drb.clear(); + + // Apply actions only applicable in SA mode + if (rrc_eutra == nullptr) { + stack->reset_eps_bearers(); + } } int rrc_nr::get_nr_capabilities(srsran::byte_buffer_t* nr_caps_pdu) @@ -427,8 +1015,8 @@ int rrc_nr::get_nr_capabilities(srsran::byte_buffer_t* nr_caps_pdu) void rrc_nr::phy_meas_stop() { - // possbile race condition for sim_measurement timer, which might be set at the same moment as stopped => fix with - // phy integration + // possbile race condition for sim_measurement timer, which might be set at the same moment as stopped => fix + // with phy integration logger.debug("Stopping simulated measurements"); sim_measurement_timer.stop(); } @@ -449,6 +1037,7 @@ bool rrc_nr::configure_sk_counter(uint16_t sk_counter) if (usim->generate_nr_context(sk_counter, &sec_cfg) == false) { return false; } + security_is_activated = true; return true; } @@ -466,12 +1055,17 @@ bool rrc_nr::apply_rlc_add_mod(const rlc_bearer_cfg_s& rlc_bearer_cfg) uint32_t drb_id = 0; uint32_t srb_id = 0; rlc_config_t rlc_cfg; + // We set this to true if below we detect it's a DRB + bool is_drb = false; lc_ch_id = rlc_bearer_cfg.lc_ch_id; if (rlc_bearer_cfg.served_radio_bearer_present == true) { if (rlc_bearer_cfg.served_radio_bearer.type() == rlc_bearer_cfg_s::served_radio_bearer_c_::types::drb_id) { drb_id = rlc_bearer_cfg.served_radio_bearer.drb_id(); add_lcid_drb(lc_ch_id, drb_id); + is_drb = true; + } else if (rlc_bearer_cfg.served_radio_bearer.type() == rlc_bearer_cfg_s::served_radio_bearer_c_::types::srb_id) { + srb_id = rlc_bearer_cfg.served_radio_bearer.srb_id(); } } else { logger.error("In RLC bearer cfg does not contain served radio bearer"); @@ -479,10 +1073,14 @@ bool rrc_nr::apply_rlc_add_mod(const rlc_bearer_cfg_s& rlc_bearer_cfg) } if (rlc_bearer_cfg.rlc_cfg_present == true) { - if (srsran::make_rlc_config_t(rlc_bearer_cfg.rlc_cfg, &rlc_cfg) != SRSRAN_SUCCESS) { + uint8_t bearer_id = static_cast(is_drb ? drb_id : srb_id); + if (srsran::make_rlc_config_t(rlc_bearer_cfg.rlc_cfg, bearer_id, &rlc_cfg) != SRSRAN_SUCCESS) { logger.error("Failed to build RLC config"); return false; } + } else if (not is_drb) { + logger.debug("Using default RLC configs for SRB%d", srb_id); + rlc_cfg = rlc_config_t::default_rlc_am_nr_config(); } else { logger.error("In RLC bearer cfg does not contain rlc cfg"); return false; @@ -501,10 +1099,11 @@ bool rrc_nr::apply_rlc_add_mod(const rlc_bearer_cfg_s& rlc_bearer_cfg) } return true; } + bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg) { if (mac_cell_group_cfg.sched_request_cfg_present) { - if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list_present) { + if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list.size() > 0) { if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list.size() == 1) { const sched_request_to_add_mod_s& asn1_cfg = mac_cell_group_cfg.sched_request_cfg.sched_request_to_add_mod_list[0]; @@ -526,7 +1125,7 @@ bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg } } - if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_release_list_present) { + if (mac_cell_group_cfg.sched_request_cfg.sched_request_to_release_list.size() > 0) { logger.warning("Not handling sched request to release list"); return false; } @@ -544,7 +1143,7 @@ bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg } if (mac_cell_group_cfg.tag_cfg_present) { - if (mac_cell_group_cfg.tag_cfg.tag_to_add_mod_list_present) { + if (mac_cell_group_cfg.tag_cfg.tag_to_add_mod_list.size() > 0) { for (uint32_t i = 0; i < mac_cell_group_cfg.tag_cfg.tag_to_add_mod_list.size(); i++) { tag_cfg_nr_t tag_cfg_nr = {}; tag_cfg_nr.tag_id = mac_cell_group_cfg.tag_cfg.tag_to_add_mod_list[i].tag_id; @@ -555,7 +1154,7 @@ bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg } } } - if (mac_cell_group_cfg.tag_cfg.tag_to_release_list_present) { + if (mac_cell_group_cfg.tag_cfg.tag_to_release_list.size() > 0) { for (uint32_t i = 0; i < mac_cell_group_cfg.tag_cfg.tag_to_release_list.size(); i++) { uint32_t tag_id = mac_cell_group_cfg.tag_cfg.tag_to_release_list[i]; if (mac->remove_tag_config(tag_id) != SRSRAN_SUCCESS) { @@ -567,7 +1166,7 @@ bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg } if (mac_cell_group_cfg.phr_cfg_present) { - if (mac_cell_group_cfg.phr_cfg.type() == setup_release_c::types_opts::setup) { + if (mac_cell_group_cfg.phr_cfg.is_setup()) { phr_cfg_nr_t phr_cfg_nr; if (make_mac_phr_cfg_t(mac_cell_group_cfg.phr_cfg.setup(), &phr_cfg_nr) != true) { logger.warning("Unable to build PHR config"); @@ -588,7 +1187,7 @@ bool rrc_nr::apply_mac_cell_group(const mac_cell_group_cfg_s& mac_cell_group_cfg bool rrc_nr::apply_sp_cell_init_dl_pdcch(const asn1::rrc_nr::pdcch_cfg_s& pdcch_cfg) { - if (pdcch_cfg.search_spaces_to_add_mod_list_present) { + if (pdcch_cfg.search_spaces_to_add_mod_list.size() > 0) { for (uint32_t i = 0; i < pdcch_cfg.search_spaces_to_add_mod_list.size(); i++) { srsran_search_space_t search_space; if (make_phy_search_space_cfg(pdcch_cfg.search_spaces_to_add_mod_list[i], &search_space) == true) { @@ -603,7 +1202,7 @@ bool rrc_nr::apply_sp_cell_init_dl_pdcch(const asn1::rrc_nr::pdcch_cfg_s& pdcch_ logger.warning("Option search_spaces_to_add_mod_list not present"); return false; } - if (pdcch_cfg.ctrl_res_set_to_add_mod_list_present) { + if (pdcch_cfg.ctrl_res_set_to_add_mod_list.size() > 0) { for (uint32_t i = 0; i < pdcch_cfg.ctrl_res_set_to_add_mod_list.size(); i++) { srsran_coreset_t coreset; if (make_phy_coreset_cfg(pdcch_cfg.ctrl_res_set_to_add_mod_list[i], &coreset) == true) { @@ -641,15 +1240,9 @@ bool rrc_nr::apply_sp_cell_init_dl_pdsch(const asn1::rrc_nr::pdsch_cfg_s& pdsch_ if (pdsch_cfg.dmrs_dl_for_pdsch_map_type_a_present) { if (pdsch_cfg.dmrs_dl_for_pdsch_map_type_a.type() == setup_release_c::types_opts::setup) { - srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos; - if (make_phy_dmrs_dl_additional_pos(pdsch_cfg.dmrs_dl_for_pdsch_map_type_a.setup(), &srsran_dmrs_sch_add_pos) == - true) { - phy_cfg.pdsch.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos; - phy_cfg.pdsch.dmrs_typeA.present = true; - } else { - logger.warning("Warning while build srsran_dmrs_sch_add_pos structure"); - return false; - } + // See TS 38.331, DMRS-DownlinkConfig. Also, see TS 38.214, 5.1.6.2 - DM-RS reception procedure. + phy_cfg.pdsch.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos_2; + phy_cfg.pdsch.dmrs_typeA.present = true; } else { logger.warning("Option dmrs_dl_for_pdsch_map_type_a not of type setup"); return false; @@ -664,7 +1257,7 @@ bool rrc_nr::apply_sp_cell_init_dl_pdsch(const asn1::rrc_nr::pdsch_cfg_s& pdsch_ phy_cfg.pdsch.alloc = resource_alloc; } - if (pdsch_cfg.zp_csi_rs_res_to_add_mod_list_present) { + if (pdsch_cfg.zp_csi_rs_res_to_add_mod_list.size() > 0) { for (uint32_t i = 0; i < pdsch_cfg.zp_csi_rs_res_to_add_mod_list.size(); i++) { srsran_csi_rs_zp_resource_t zp_csi_rs_resource; if (make_phy_zp_csi_rs_resource(pdsch_cfg.zp_csi_rs_res_to_add_mod_list[i], &zp_csi_rs_resource) == true) { @@ -679,7 +1272,7 @@ bool rrc_nr::apply_sp_cell_init_dl_pdsch(const asn1::rrc_nr::pdsch_cfg_s& pdsch_ if (pdsch_cfg.p_zp_csi_rs_res_set_present) { // check if resources have been processed - if (not pdsch_cfg.zp_csi_rs_res_to_add_mod_list_present) { + if (pdsch_cfg.zp_csi_rs_res_to_add_mod_list.size() == 0) { logger.warning("Can't build ZP-CSI config, option zp_csi_rs_res_to_add_mod_list not present"); return false; } @@ -733,43 +1326,37 @@ bool rrc_nr::apply_res_csi_report_cfg(const asn1::rrc_nr::csi_report_cfg_s& csi_ bool rrc_nr::apply_csi_meas_cfg(const asn1::rrc_nr::csi_meas_cfg_s& csi_meas_cfg) { - if (csi_meas_cfg.csi_report_cfg_to_add_mod_list_present) { - for (uint32_t i = 0; i < csi_meas_cfg.csi_report_cfg_to_add_mod_list.size(); i++) { - if (apply_res_csi_report_cfg(csi_meas_cfg.csi_report_cfg_to_add_mod_list[i]) == false) { - return false; - } + for (uint32_t i = 0; i < csi_meas_cfg.csi_report_cfg_to_add_mod_list.size(); i++) { + if (apply_res_csi_report_cfg(csi_meas_cfg.csi_report_cfg_to_add_mod_list[i]) == false) { + return false; } } - if (csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list_present) { - for (uint32_t i = 0; i < csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.size(); i++) { - srsran_csi_rs_nzp_resource_t csi_rs_nzp_resource; - if (make_phy_nzp_csi_rs_resource(csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list[i], &csi_rs_nzp_resource) == true) { - // temporally store csi_rs_zp_res - csi_rs_nzp_res[csi_rs_nzp_resource.id] = csi_rs_nzp_resource; - } else { - logger.warning("Warning while building phy_nzp_csi_rs resource"); - return false; - } + for (uint32_t i = 0; i < csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list.size(); i++) { + srsran_csi_rs_nzp_resource_t csi_rs_nzp_resource; + if (make_phy_nzp_csi_rs_resource(csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list[i], &csi_rs_nzp_resource) == true) { + // temporally store csi_rs_zp_res + csi_rs_nzp_res[csi_rs_nzp_resource.id] = csi_rs_nzp_resource; + } else { + logger.warning("Warning while building phy_nzp_csi_rs resource"); + return false; } } - if (csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list_present) { - for (uint32_t i = 0; i < csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.size(); i++) { - uint8_t set_id = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list[i].nzp_csi_res_set_id; - for (uint32_t j = 0; j < csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list[i].nzp_csi_rs_res.size(); j++) { - uint8_t res = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list[i].nzp_csi_rs_res[j]; - // use temporally stored values to assign - if (csi_rs_nzp_res.find(res) == csi_rs_nzp_res.end()) { - logger.warning("Can not find nzp_csi_rs_res in temporally stored csi_rs_nzp_res"); - return false; - } - phy_cfg.pdsch.nzp_csi_rs_sets[set_id].data[j] = csi_rs_nzp_res[res]; - phy_cfg.pdsch.nzp_csi_rs_sets[set_id].count += 1; - } - if (csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list[i].trs_info_present) { - phy_cfg.pdsch.nzp_csi_rs_sets[set_id].trs_info = true; + for (uint32_t i = 0; i < csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list.size(); i++) { + uint8_t set_id = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list[i].nzp_csi_res_set_id; + for (uint32_t j = 0; j < csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list[i].nzp_csi_rs_res.size(); j++) { + uint8_t res = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list[i].nzp_csi_rs_res[j]; + // use temporally stored values to assign + if (csi_rs_nzp_res.find(res) == csi_rs_nzp_res.end()) { + logger.warning("Can not find nzp_csi_rs_res in temporally stored csi_rs_nzp_res"); + return false; } + phy_cfg.pdsch.nzp_csi_rs_sets[set_id].data[j] = csi_rs_nzp_res[res]; + phy_cfg.pdsch.nzp_csi_rs_sets[set_id].count += 1; + } + if (csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list[i].trs_info_present) { + phy_cfg.pdsch.nzp_csi_rs_sets[set_id].trs_info = true; } } @@ -789,8 +1376,7 @@ bool rrc_nr::apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_com } if (dl_cfg_common.init_dl_bwp_present) { if (dl_cfg_common.init_dl_bwp.pdsch_cfg_common_present) { - if (dl_cfg_common.init_dl_bwp.pdsch_cfg_common.type() == - asn1::rrc_nr::setup_release_c::types_opts::setup) { + if (dl_cfg_common.init_dl_bwp.pdsch_cfg_common.is_setup()) { const pdcch_cfg_common_s& pdcch_cfg_common = dl_cfg_common.init_dl_bwp.pdcch_cfg_common.setup(); // Load CORESET Zero @@ -842,7 +1428,7 @@ bool rrc_nr::apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_com logger.warning("Option common_ctrl_res_set not present"); return false; } - if (pdcch_cfg_common.common_search_space_list_present) { + if (pdcch_cfg_common.common_search_space_list.size() > 0) { for (uint32_t i = 0; i < pdcch_cfg_common.common_search_space_list.size(); i++) { srsran_search_space_t search_space; if (make_phy_search_space_cfg(pdcch_cfg_common.common_search_space_list[i], &search_space) == true) { @@ -859,7 +1445,6 @@ bool rrc_nr::apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_com } if (pdcch_cfg_common.ra_search_space_present) { if (phy_cfg.pdcch.search_space_present[pdcch_cfg_common.ra_search_space] == true) { - // phy_cfg.pdcch.ra_rnti = 0x16; //< Supposed to be deduced from PRACH configuration phy_cfg.pdcch.ra_search_space = phy_cfg.pdcch.search_space[pdcch_cfg_common.ra_search_space]; phy_cfg.pdcch.ra_search_space_present = true; phy_cfg.pdcch.ra_search_space.type = srsran_search_space_type_common_1; @@ -882,7 +1467,7 @@ bool rrc_nr::apply_dl_common_cfg(const asn1::rrc_nr::dl_cfg_common_s& dl_cfg_com if (dl_cfg_common.init_dl_bwp.pdsch_cfg_common_present) { if (dl_cfg_common.init_dl_bwp.pdsch_cfg_common.type() == setup_release_c::types::setup) { pdsch_cfg_common_s pdsch_cfg_common = dl_cfg_common.init_dl_bwp.pdsch_cfg_common.setup(); - if (pdsch_cfg_common.pdsch_time_domain_alloc_list_present) { + if (pdsch_cfg_common.pdsch_time_domain_alloc_list.size() > 0) { for (uint32_t i = 0; i < pdsch_cfg_common.pdsch_time_domain_alloc_list.size(); i++) { srsran_sch_time_ra_t common_time_ra; if (make_phy_common_time_ra(pdsch_cfg_common.pdsch_time_domain_alloc_list[i], &common_time_ra) == true) { @@ -924,11 +1509,13 @@ bool rrc_nr::apply_ul_common_cfg(const asn1::rrc_nr::ul_cfg_common_s& ul_cfg_com if (ul_cfg_common.init_ul_bwp_present) { if (ul_cfg_common.init_ul_bwp.rach_cfg_common_present) { if (ul_cfg_common.init_ul_bwp.rach_cfg_common.type() == setup_release_c::types_opts::setup) { - rach_nr_cfg_t rach_nr_cfg = make_mac_rach_cfg(ul_cfg_common.init_ul_bwp.rach_cfg_common.setup()); - mac->set_config(rach_nr_cfg); + rach_cfg_nr_t rach_cfg_nr = {}; + make_mac_rach_cfg(ul_cfg_common.init_ul_bwp.rach_cfg_common.setup(), &rach_cfg_nr); + mac->set_config(rach_cfg_nr); // Make the RACH configuration for PHY - if (not make_phy_rach_cfg(ul_cfg_common.init_ul_bwp.rach_cfg_common.setup(), &phy_cfg.prach)) { + if (not make_phy_rach_cfg( + ul_cfg_common.init_ul_bwp.rach_cfg_common.setup(), SRSRAN_DUPLEX_MODE_FDD, &phy_cfg.prach)) { logger.warning("Error parsing rach_cfg_common"); return false; } @@ -943,7 +1530,7 @@ bool rrc_nr::apply_ul_common_cfg(const asn1::rrc_nr::ul_cfg_common_s& ul_cfg_com } if (ul_cfg_common.init_ul_bwp.pusch_cfg_common_present) { if (ul_cfg_common.init_ul_bwp.pusch_cfg_common.type() == setup_release_c::types_opts::setup) { - if (ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list_present) { + if (ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list.size() > 0) { for (uint32_t i = 0; i < ul_cfg_common.init_ul_bwp.pusch_cfg_common.setup().pusch_time_domain_alloc_list.size(); i++) { @@ -1003,7 +1590,7 @@ bool rrc_nr::apply_sp_cell_ded_ul_pucch(const asn1::rrc_nr::pucch_cfg_s& pucch_c } // now look up resource and assign into internal struct - if (pucch_cfg.res_to_add_mod_list_present) { + if (pucch_cfg.res_to_add_mod_list.size() > 0) { for (uint32_t i = 0; i < pucch_cfg.res_to_add_mod_list.size(); i++) { uint32_t res_id = pucch_cfg.res_to_add_mod_list[i].pucch_res_id; pucch_res_list.insert(res_id, {}); @@ -1019,7 +1606,7 @@ bool rrc_nr::apply_sp_cell_ded_ul_pucch(const asn1::rrc_nr::pucch_cfg_s& pucch_c // Check first all resource lists and phy_cfg.pucch.enabled = true; - if (pucch_cfg.res_set_to_add_mod_list_present) { + if (pucch_cfg.res_set_to_add_mod_list.size() > 0) { for (uint32_t i = 0; i < pucch_cfg.res_set_to_add_mod_list.size(); i++) { uint32_t set_id = pucch_cfg.res_set_to_add_mod_list[i].pucch_res_set_id; phy_cfg.pucch.sets[set_id].nof_resources = pucch_cfg.res_set_to_add_mod_list[i].res_list.size(); @@ -1035,7 +1622,7 @@ bool rrc_nr::apply_sp_cell_ded_ul_pucch(const asn1::rrc_nr::pucch_cfg_s& pucch_c } } - if (pucch_cfg.sched_request_res_to_add_mod_list_present) { + if (pucch_cfg.sched_request_res_to_add_mod_list.size() > 0) { for (uint32_t i = 0; i < pucch_cfg.sched_request_res_to_add_mod_list.size(); i++) { uint32_t sr_res_id = pucch_cfg.sched_request_res_to_add_mod_list[i].sched_request_res_id; srsran_pucch_nr_sr_resource_t srsran_pucch_nr_sr_resource; @@ -1069,7 +1656,7 @@ bool rrc_nr::apply_sp_cell_ded_ul_pucch(const asn1::rrc_nr::pucch_cfg_s& pucch_c return false; } - if (pucch_cfg.dl_data_to_ul_ack_present) { + if (pucch_cfg.dl_data_to_ul_ack.size() > 0) { for (uint32_t i = 0; i < pucch_cfg.dl_data_to_ul_ack.size(); i++) { phy_cfg.harq_ack.dl_data_to_ul_ack[i] = pucch_cfg.dl_data_to_ul_ack[i]; } @@ -1108,15 +1695,9 @@ bool rrc_nr::apply_sp_cell_ded_ul_pusch(const asn1::rrc_nr::pusch_cfg_s& pusch_c if (pusch_cfg.dmrs_ul_for_pusch_map_type_a_present) { if (pusch_cfg.dmrs_ul_for_pusch_map_type_a.type() == setup_release_c::types_opts::setup) { - srsran_dmrs_sch_add_pos_t srsran_dmrs_sch_add_pos; - if (make_phy_dmrs_ul_additional_pos(pusch_cfg.dmrs_ul_for_pusch_map_type_a.setup(), &srsran_dmrs_sch_add_pos) == - true) { - phy_cfg.pusch.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos; - phy_cfg.pusch.dmrs_typeA.present = true; - } else { - logger.warning("Warning while build srsran_dmrs_sch_add_pos structure"); - return false; - } + // // See TS 38.331, DMRS-UplinkConfig. Also, see TS 38.214, 6.2.2 - UE DM-RS transmission procedure. + phy_cfg.pusch.dmrs_typeA.additional_pos = srsran_dmrs_sch_add_pos_2; + phy_cfg.pusch.dmrs_typeA.present = true; } else { logger.warning("Option dmrs_ul_for_pusch_map_type_a not of type setup"); return false; @@ -1141,9 +1722,11 @@ bool rrc_nr::apply_sp_cell_ded_ul_pusch(const asn1::rrc_nr::pusch_cfg_s& pusch_c logger.warning("Option beta_offsets not of type semi_static"); return false; } - if (make_phy_pusch_scaling(pusch_cfg.uci_on_pusch.setup(), &phy_cfg.pusch.scaling) == false) { - logger.warning("Warning while building scaling structure"); - return false; + if (pusch_cfg.uci_on_pusch_present) { + if (make_phy_pusch_scaling(pusch_cfg.uci_on_pusch.setup(), &phy_cfg.pusch.scaling) == false) { + logger.warning("Warning while building scaling structure"); + return false; + } } } else { logger.warning("Option beta_offsets not present"); @@ -1162,7 +1745,16 @@ bool rrc_nr::apply_sp_cell_ded_ul_pusch(const asn1::rrc_nr::pusch_cfg_s& pusch_c bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) { + update_sp_cell_cfg(sp_cell_cfg); + + return true; +} + +bool rrc_nr::update_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) +{ + // NSA specific handling to defer CSI, SR, SRS config until after RA (see TS 38.331, Section 5.3.5.3) srsran_csi_hl_cfg_t prev_csi = phy_cfg.csi; + if (sp_cell_cfg.recfg_with_sync_present) { const recfg_with_sync_s& recfg_with_sync = sp_cell_cfg.recfg_with_sync; mac->set_crnti(recfg_with_sync.new_ue_id); @@ -1200,21 +1792,22 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) return false; } if (recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common_present) { - logger.info("TDD UL DL config present, using TDD"); + logger.debug("TDD UL DL config present, using TDD"); srsran_duplex_config_nr_t duplex; - if (make_phy_tdd_cfg(recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common, &duplex) == true) { - phy_cfg.duplex = duplex; + if (make_phy_tdd_cfg(recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common, &duplex)) { + phy_cfg.duplex = duplex; + phy_cfg.prach.tdd_config.configured = true; } else { logger.warning("Warning while building duplex structure"); return false; } } else { - logger.info("TDD UL DL config not present, using FDD"); + logger.debug("TDD UL DL config not present, using FDD"); } } } else { - logger.warning("Reconfig with with sync not present"); - return false; + // for SA this is not sent + logger.debug("Reconfig with sync not present"); } // Dedicated config @@ -1306,8 +1899,7 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) mac->set_config(dl_harq_cfg_nr); } } else { - logger.warning("Option pdsch_serving_cell_cfg not present"); - return false; + logger.debug("Option pdsch_serving_cell_cfg not present"); } if (sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg_present) { @@ -1321,7 +1913,6 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) } } else { logger.warning("Option csi_meas_cfg in spCellConfigDedicated not present"); - return false; } } else { @@ -1330,12 +1921,17 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) } // Configure PHY - // Note: CSI config is deferred to when RA is complete. See TS 38.331, Section 5.3.5.3 - srsran::phy_cfg_nr_t current_phycfg = phy_cfg; - current_phycfg.csi = prev_csi; - phy->set_config(current_phycfg); - - phy_cfg_state = PHY_CFG_STATE_APPLY_SP_CELL; + if (sp_cell_cfg.recfg_with_sync_present) { + // defer CSI config until after RA complete + srsran::phy_cfg_nr_t current_phycfg = phy_cfg; + current_phycfg.csi = prev_csi; + phy_cfg_state = PHY_CFG_STATE_NSA_APPLY_SP_CELL; + phy->set_config(current_phycfg); + } else { + // apply full config immediately + phy_cfg_state = PHY_CFG_STATE_SA_FULL_CFG; + phy->set_config(phy_cfg); + } return true; } @@ -1354,7 +1950,14 @@ bool rrc_nr::apply_phy_cell_group_cfg(const phys_cell_group_cfg_s& phys_cell_gro bool rrc_nr::apply_cell_group_cfg(const cell_group_cfg_s& cell_group_cfg) { - if (cell_group_cfg.rlc_bearer_to_add_mod_list_present) { + update_cell_group_cfg(cell_group_cfg); + + return true; +} + +bool rrc_nr::update_cell_group_cfg(const cell_group_cfg_s& cell_group_cfg) +{ + if (cell_group_cfg.rlc_bearer_to_add_mod_list.size() > 0) { for (uint32_t i = 0; i < cell_group_cfg.rlc_bearer_to_add_mod_list.size(); i++) { if (apply_rlc_add_mod(cell_group_cfg.rlc_bearer_to_add_mod_list[i]) == false) { return false; @@ -1372,7 +1975,7 @@ bool rrc_nr::apply_cell_group_cfg(const cell_group_cfg_s& cell_group_cfg) } } if (cell_group_cfg.sp_cell_cfg_present) { - if (apply_sp_cell_cfg(cell_group_cfg.sp_cell_cfg) == false) { + if (update_sp_cell_cfg(cell_group_cfg.sp_cell_cfg) == false) { return false; } } @@ -1395,8 +1998,23 @@ bool rrc_nr::apply_drb_release(const uint8_t drb) return true; } +bool rrc_nr::apply_srb_add_mod(const srb_to_add_mod_s& srb_cfg) +{ + logger.debug("Applying SRB Add/Mod to SRB%d", srb_cfg.srb_id); + if (srb_cfg.pdcp_cfg_present) { + logger.error("Cannot add SRB - only default configuration supported."); + return false; + } + + srsran::pdcp_config_t pdcp_cfg = srsran::make_nr_srb_pdcp_config_t(srb_cfg.srb_id, true); + pdcp->add_bearer(srb_cfg.srb_id, pdcp_cfg); + + return true; +} + bool rrc_nr::apply_drb_add_mod(const drb_to_add_mod_s& drb_cfg) { + logger.debug("Applying DRB Add/Mod to DRB%d", drb_cfg.drb_id); if (!drb_cfg.pdcp_cfg_present) { logger.error("Cannot add DRB - incomplete configuration"); return false; @@ -1419,12 +2037,40 @@ bool rrc_nr::apply_drb_add_mod(const drb_to_add_mod_s& drb_cfg) return false; } - if (!(drb_cfg.cn_assoc.type() == drb_to_add_mod_s::cn_assoc_c_::types_opts::eps_bearer_id)) { - logger.error("CN association type not supported %s ", drb_cfg.cn_assoc.type().to_string()); + if (drb_cfg.cn_assoc.type() == drb_to_add_mod_s::cn_assoc_c_::types_opts::eps_bearer_id) { + // register EPS bearer over NR PDCP + uint32_t eps_bearer_id = drb_cfg.cn_assoc.eps_bearer_id(); + drb_eps_bearer_id[drb_cfg.drb_id] = eps_bearer_id; + stack->add_eps_bearer(eps_bearer_id, srsran::srsran_rat_t::nr, lcid); + } else if (drb_cfg.cn_assoc.type() == drb_to_add_mod_s::cn_assoc_c_::types_opts::sdap_cfg) { + const auto& sdap_cfg = drb_cfg.cn_assoc.sdap_cfg(); + + // Check supported configuration + if (sdap_cfg.sdap_hdr_dl.value == sdap_cfg_s::sdap_hdr_dl_opts::present || !sdap_cfg.default_drb || + sdap_cfg.mapped_qos_flows_to_add.size() != 1) { + logger.error( + "Configuring SDAP: only UL headder is supported. Default DRB must be set and number of QoS flows must be 1"); + return false; + } + + sdap_interface_rrc::bearer_cfg_t sdap_bearer_cfg = {}; + sdap_bearer_cfg.add_downlink_header = sdap_cfg.sdap_hdr_dl.value == sdap_cfg_s::sdap_hdr_dl_opts::present; + sdap_bearer_cfg.add_uplink_header = sdap_cfg.sdap_hdr_ul.value == sdap_cfg_s::sdap_hdr_ul_opts::present; + sdap_bearer_cfg.is_data = true; + sdap_bearer_cfg.qfi = sdap_cfg.mapped_qos_flows_to_add[0]; + + if (not sdap->set_bearer_cfg(lcid, sdap_bearer_cfg)) { + logger.error("Configuring SDAP"); + return false; + } + + uint32_t pdu_session_id = drb_cfg.cn_assoc.sdap_cfg().pdu_session; + // Register PDU session as "EPS bearer" in bearer manager + stack->add_eps_bearer(pdu_session_id, srsran::srsran_rat_t::nr, lcid); + } else { + logger.error("CN association type not supported %s", drb_cfg.cn_assoc.type().to_string()); return false; } - uint32_t eps_bearer_id = drb_cfg.cn_assoc.eps_bearer_id(); - drb_eps_bearer_id[drb_cfg.drb_id] = eps_bearer_id; if (drb_cfg.pdcp_cfg.drb.pdcp_sn_size_dl_present && drb_cfg.pdcp_cfg.drb.pdcp_sn_size_ul_present && (drb_cfg.pdcp_cfg.drb.pdcp_sn_size_ul.to_number() != drb_cfg.pdcp_cfg.drb.pdcp_sn_size_dl.to_number())) { @@ -1432,18 +2078,25 @@ bool rrc_nr::apply_drb_add_mod(const drb_to_add_mod_s& drb_cfg) drb_cfg.pdcp_cfg.drb.pdcp_sn_size_dl.to_number()); } + if (not security_is_activated) { + logger.error("Trying to setup DRB%d, but security is not activated", drb_cfg.drb_id); + return false; + } srsran::pdcp_config_t pdcp_cfg = make_drb_pdcp_config_t(drb_cfg.drb_id, true, drb_cfg.pdcp_cfg); pdcp->add_bearer(lcid, pdcp_cfg); - // register EPS bearer over NR PDCP - stack->add_eps_bearer(eps_bearer_id, srsran::srsran_rat_t::nr, lcid); - + // Use already configured sec config, if no other sec config present in the RadioBearerConfig + pdcp->config_security(lcid, sec_cfg); + pdcp->enable_encryption(lcid, DIRECTION_TXRX); + if (drb_cfg.pdcp_cfg.drb.integrity_protection_present) { + pdcp->enable_integrity(lcid, DIRECTION_TXRX); + } return true; } bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) { - // TODO derive correct keys + logger.debug("Applying Security config"); if (security_cfg.key_to_use_present) { if (security_cfg.key_to_use.value != security_cfg_s::key_to_use_opts::options::secondary) { logger.warning("Only secondary key supported yet"); @@ -1484,6 +2137,7 @@ bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) // Apply security config for all known NR lcids for (auto& lcid : lcid_drb) { + logger.debug("Applying PDCP security config. LCID=%d", lcid.first); pdcp->config_security(lcid.first, sec_cfg); pdcp->enable_encryption(lcid.first); } @@ -1492,194 +2146,219 @@ bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) bool rrc_nr::apply_radio_bearer_cfg(const radio_bearer_cfg_s& radio_bearer_cfg) { - if (radio_bearer_cfg.drb_to_add_mod_list_present) { - for (uint32_t i = 0; i < radio_bearer_cfg.drb_to_add_mod_list.size(); i++) { - if (apply_drb_add_mod(radio_bearer_cfg.drb_to_add_mod_list[i]) == false) { - return false; - } + for (const auto& srb : radio_bearer_cfg.srb_to_add_mod_list) { + if (apply_srb_add_mod(srb) == false) { + logger.error("Couldn't apply config for SRB%d.", srb.srb_id); + return false; } } - if (radio_bearer_cfg.drb_to_release_list_present) { - for (uint32_t i = 0; i < radio_bearer_cfg.drb_to_release_list.size(); i++) { - if (apply_drb_release(radio_bearer_cfg.drb_to_release_list[i]) == false) { - return false; - } + for (const auto& drb : radio_bearer_cfg.drb_to_add_mod_list) { + if (apply_drb_add_mod(drb) == false) { + return false; + } + } + for (const auto& drb : radio_bearer_cfg.drb_to_release_list) { + if (apply_drb_release(drb) == false) { + return false; } } + if (radio_bearer_cfg.security_cfg_present) { if (apply_security_cfg(radio_bearer_cfg.security_cfg) == false) { return false; } + } else { + logger.debug("No Security Config Present"); } return true; } -// RLC interface -void rrc_nr::max_retx_attempted() {} -void rrc_nr::protocol_failure() {} -// MAC interface -void rrc_nr::ra_completed() +bool rrc_nr::handle_rrc_setup(const rrc_setup_s& setup) { - logger.info("RA completed. Applying remaining CSI configuration."); - phy->set_config(phy_cfg); - phy_cfg_state = PHY_CFG_STATE_RA_COMPLETED; -} -void rrc_nr::ra_problem() -{ - rrc_eutra->nr_scg_failure_information(scg_failure_cause_t::random_access_problem); -} + // Unpack masterCellGroup into container + asn1::cbit_ref bref_cg(setup.crit_exts.rrc_setup().master_cell_group.data(), + setup.crit_exts.rrc_setup().master_cell_group.size()); -void rrc_nr::release_pucch_srs() {} + asn1::rrc_nr::cell_group_cfg_s cell_group; + if (cell_group.unpack(bref_cg) != asn1::SRSASN_SUCCESS) { + logger.error("Could not unpack master cell group config."); + return false; + } + asn1::json_writer js; + cell_group.to_json(js); + logger.debug("Containerized MasterCellGroup: %s", js.to_string().c_str()); -// STACK interface -void rrc_nr::cell_search_completed(const rrc_interface_phy_lte::cell_search_ret_t& cs_ret, const phy_cell_t& found_cell) -{} + state = RRC_NR_STATE_CONNECTED; + srsran::console("RRC Connected\n"); -void rrc_nr::set_phy_config_complete(bool status) -{ - switch (phy_cfg_state) { - case PHY_CFG_STATE_NONE: - logger.warning("PHY configuration completed without a clear state."); - break; - case PHY_CFG_STATE_APPLY_SP_CELL: - // Start RA procedure - logger.info("PHY configuration completed. Starting RA procedure."); - mac->start_ra_procedure(); - break; - case PHY_CFG_STATE_RA_COMPLETED: - logger.info("Remaining CSI configuration completed."); - break; + // defer transmission of Setup Complete until PHY reconfiguration has been completed + if (not conn_setup_proc.launch( + setup.crit_exts.rrc_setup().radio_bearer_cfg, cell_group, std::move(dedicated_info_nas))) { + logger.error("Failed to initiate connection setup procedure"); + return false; } - phy_cfg_state = PHY_CFG_STATE_NONE; + callback_list.add_proc(conn_setup_proc); + return true; } -/* Procedures */ -rrc_nr::connection_reconf_no_ho_proc::connection_reconf_no_ho_proc(rrc_nr* parent_) : rrc_ptr(parent_), initiator(nr) {} - -proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::init(const reconf_initiator_t initiator_, - const bool endc_release_and_add_r15, - const bool nr_secondary_cell_group_cfg_r15_present, - const asn1::dyn_octstring nr_secondary_cell_group_cfg_r15, - const bool sk_counter_r15_present, - const uint32_t sk_counter_r15, - const bool nr_radio_bearer_cfg1_r15_present, - const asn1::dyn_octstring nr_radio_bearer_cfg1_r15) -{ - Info("Starting..."); - initiator = initiator_; - - rrc_recfg_s rrc_recfg; - cell_group_cfg_s cell_group_cfg; - radio_bearer_cfg_s radio_bearer_cfg; - asn1::SRSASN_CODE err; - - if (nr_secondary_cell_group_cfg_r15_present) { - cbit_ref bref(nr_secondary_cell_group_cfg_r15.data(), nr_secondary_cell_group_cfg_r15.size()); - err = rrc_recfg.unpack(bref); - if (err != asn1::SRSASN_SUCCESS) { - Error("Could not unpack NR reconfiguration message."); - return proc_outcome_t::error; - } +void rrc_nr::handle_rrc_reconfig(const rrc_recfg_s& reconfig) +{ + transaction_id = reconfig.rrc_transaction_id; - rrc_ptr->log_rrc_message( - "RRC NR Reconfiguration", Rx, nr_secondary_cell_group_cfg_r15, rrc_recfg, "NR Secondary Cell Group Cfg R15"); + if (not conn_recfg_proc.launch(nr, false, reconfig)) { + logger.error("Unable to launch connection reconfiguration procedure"); + return; + } + callback_list.add_proc(conn_recfg_proc); +} +void rrc_nr::handle_ue_capability_enquiry(const ue_cap_enquiry_s& ue_cap_enquiry) +{ + logger.info("Received UE Capability Enquiry"); + send_ue_capability_info(ue_cap_enquiry); +} - if (rrc_recfg.crit_exts.type() != asn1::rrc_nr::rrc_recfg_s::crit_exts_c_::types::rrc_recfg) { - Error("Reconfiguration does not contain Secondary Cell Group Config"); - return proc_outcome_t::error; - } +void rrc_nr::handle_dl_info_transfer(const dl_info_transfer_s& dl_info_transfer) +{ + transaction_id = dl_info_transfer.rrc_transaction_id; + + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (pdu == nullptr) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return; + } + if (pdu->get_tailroom() < dl_info_transfer.crit_exts.dl_info_transfer().ded_nas_msg.size()) { + logger.error("DL Info Transfer too big (%d > %d)", + dl_info_transfer.crit_exts.dl_info_transfer().ded_nas_msg.size(), + pdu->get_tailroom()); + return; + } + pdu->N_bytes = dl_info_transfer.crit_exts.dl_info_transfer().ded_nas_msg.size(); + memcpy(pdu->msg, dl_info_transfer.crit_exts.dl_info_transfer().ded_nas_msg.data(), pdu->N_bytes); + nas->write_pdu(std::move(pdu)); +} - if (not rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group_present) { - Error("Reconfiguration does not contain Secondary Cell Group Config"); - return proc_outcome_t::error; - } +void rrc_nr::handle_security_mode_command(const asn1::rrc_nr::security_mode_cmd_s& smc) +{ + transaction_id = smc.rrc_transaction_id; - cbit_ref bref0(rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group.data(), - rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group.size()); + const auto& sec_algo_cfg = smc.crit_exts.security_mode_cmd().security_cfg_smc.security_algorithm_cfg; + sec_cfg.cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM)sec_algo_cfg.ciphering_algorithm.value; + if (sec_algo_cfg.integrity_prot_algorithm_present) { + sec_cfg.integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM)sec_algo_cfg.integrity_prot_algorithm.value; + } else { + logger.error("Missing Integrity Algorithm Config"); + } - err = cell_group_cfg.unpack(bref0); - if (err != asn1::SRSASN_SUCCESS) { - Error("Could not unpack cell group message message."); - return proc_outcome_t::error; - } + logger.info("Received Security Mode Command nea: %s, nia: %s", + ciphering_algorithm_id_nr_text[sec_cfg.cipher_algo], + integrity_algorithm_id_nr_text[sec_cfg.integ_algo]); - rrc_ptr->log_rrc_message("RRC NR Reconfiguration", - Rx, - rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group, - cell_group_cfg, - "Secondary Cell Group Config"); + // Generate AS security keys + generate_as_keys(); + security_is_activated = true; - Info("Applying Cell Group Cfg"); - if (!rrc_ptr->apply_cell_group_cfg(cell_group_cfg)) { - return proc_outcome_t::error; - } - } + // Configure PDCP for security + uint32_t lcid = srb_to_lcid(nr_srb::srb1); + pdcp->config_security(lcid, sec_cfg); + pdcp->enable_integrity(lcid, DIRECTION_TXRX); + send_security_mode_complete(); + pdcp->enable_encryption(lcid, DIRECTION_TXRX); +} - if (sk_counter_r15_present) { - Info("Applying Cell Group Cfg"); - if (!rrc_ptr->configure_sk_counter((uint16_t)sk_counter_r15)) { - return proc_outcome_t::error; - } - } +void rrc_nr::handle_rrc_release(const asn1::rrc_nr::rrc_release_s& msg) +{ + logger.info("Received RRC Release"); + srsran::console("Received RRC Release\n"); - if (nr_radio_bearer_cfg1_r15_present) { - cbit_ref bref1(nr_radio_bearer_cfg1_r15.data(), nr_radio_bearer_cfg1_r15.size()); + rrc_release(); +} - err = radio_bearer_cfg.unpack(bref1); - if (err != asn1::SRSASN_SUCCESS) { - Error("Could not unpack radio bearer config."); - return proc_outcome_t::error; - } +// Security helper used by Security Mode Command and Mobility handling routines +void rrc_nr::generate_as_keys() +{ + as_key_t k_amf = {}; + nas->get_k_amf(k_amf); + logger.debug(k_amf.data(), 32, "UE K_amf"); + logger.debug("Generating K_gnb with UL NAS COUNT: %d", nas->get_ul_nas_count()); + usim->generate_nr_as_keys(k_amf, nas->get_ul_nas_count(), &sec_cfg); + logger.info(sec_cfg.k_rrc_enc.data(), 32, "RRC encryption key - k_rrc_enc"); + logger.info(sec_cfg.k_rrc_int.data(), 32, "RRC integrity key - k_rrc_int"); + logger.info(sec_cfg.k_up_enc.data(), 32, "UP encryption key - k_up_enc"); +} - rrc_ptr->log_rrc_message( - "RRC NR Reconfiguration", Rx, nr_radio_bearer_cfg1_r15, radio_bearer_cfg, "Radio Bearer Config R15"); +// RLC interface +void rrc_nr::max_retx_attempted() {} +void rrc_nr::protocol_failure() {} - Info("Applying Radio Bearer Cfg"); - if (!rrc_ptr->apply_radio_bearer_cfg(radio_bearer_cfg)) { - return proc_outcome_t::error; - } +// MAC interface +void rrc_nr::ra_completed() +{ + logger.info("RA completed."); + if (rrc_eutra) { + logger.debug("Applying remaining CSI configuration."); + phy_cfg_state = PHY_CFG_STATE_NSA_RA_COMPLETED; + phy->set_config(phy_cfg); + } else { + phy_cfg_state = PHY_CFG_STATE_NONE; } - - return proc_outcome_t::success; } -proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::react(const bool& config_complete) +void rrc_nr::ra_problem() { - if (not config_complete) { - Error("NR reconfiguration failed"); - return proc_outcome_t::error; + if (rrc_eutra) { + rrc_eutra->nr_scg_failure_information(scg_failure_cause_t::random_access_problem); + } else { + // TODO: handle RA problem } +} - // TODO phy ctrl - // in case there are scell to configure, wait for second phy configuration - // if (not rrc_ptr->phy_ctrl->is_config_pending()) { - // return proc_outcome_t::yield; - // } +void rrc_nr::release_pucch_srs() {} - Info("Reconfig NR return successful"); - return proc_outcome_t::success; +// STACK interface +void rrc_nr::cell_search_found_cell(const rrc_interface_phy_nr::cell_search_result_t& result) +{ + cell_selector.trigger(result); } -void rrc_nr::connection_reconf_no_ho_proc::then(const srsran::proc_state_t& result) +void rrc_nr::cell_select_completed(const rrc_interface_phy_nr::cell_select_result_t& result) { - if (result.is_success()) { - Info("Finished %s successfully", name()); - srsran::console("RRC NR reconfiguration successful.\n"); - rrc_ptr->rrc_eutra->nr_rrc_con_reconfig_complete(true); - } else { - // 5.3.5.8.2 Inability to comply with RRCReconfiguration - switch (initiator) { - case reconf_initiator_t::mcg_srb1: - rrc_ptr->rrc_eutra->nr_notify_reconfiguration_failure(); - break; - default: - Warning("Reconfiguration failure not implemented for initiator %d", initiator); - break; - } - srsran::console("RRC NR reconfiguration failed.\n"); - Warning("Finished %s with failure", name()); + cell_selector.trigger(result); +} + +void rrc_nr::set_phy_config_complete(bool status) +{ + // inform procedures if they are running + if (conn_setup_proc.is_busy()) { + conn_setup_proc.trigger(status); + } + + if (conn_recfg_proc.is_busy()) { + conn_recfg_proc.trigger(status); + } + + switch (phy_cfg_state) { + case PHY_CFG_STATE_NONE: + logger.warning("PHY configuration completed without a clear state."); + break; + case PHY_CFG_STATE_SA_MIB_CFG: + logger.info("PHY configuration with MIB parameters completed."); + break; + case PHY_CFG_STATE_SA_SIB_CFG: + logger.info("PHY configuration with SIB parameters completed."); + break; + case PHY_CFG_STATE_SA_FULL_CFG: + logger.info("PHY configuration completed."); + break; + case PHY_CFG_STATE_NSA_APPLY_SP_CELL: + // Start RA procedure + logger.info("PHY configuration completed. Starting RA procedure."); + mac->start_ra_procedure(); + break; + case PHY_CFG_STATE_NSA_RA_COMPLETED: + logger.info("Remaining CSI configuration completed."); + break; } - return; + phy_cfg_state = PHY_CFG_STATE_NONE; } } // namespace srsue diff --git a/srsue/src/stack/rrc_nr/rrc_nr_procedures.cc b/srsue/src/stack/rrc_nr/rrc_nr_procedures.cc new file mode 100644 index 0000000000..619eac6de4 --- /dev/null +++ b/srsue/src/stack/rrc_nr/rrc_nr_procedures.cc @@ -0,0 +1,567 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsue/hdr/stack/rrc_nr/rrc_nr_procedures.h" +#include "srsran/common/standard_streams.h" + +#define Error(fmt, ...) rrc_handle.logger.error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define Warning(fmt, ...) rrc_handle.logger.warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define Info(fmt, ...) rrc_handle.logger.info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define Debug(fmt, ...) rrc_handle.logger.debug("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) + +using namespace asn1::rrc_nr; +using namespace asn1; +using namespace srsran; + +namespace srsue { + +rrc_nr::connection_reconf_no_ho_proc::connection_reconf_no_ho_proc(rrc_nr& parent_) : rrc_handle(parent_), initiator(nr) +{} + +proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::init(const reconf_initiator_t initiator_, + const bool endc_release_and_add_r15, + const asn1::rrc_nr::rrc_recfg_s& rrc_nr_reconf) +{ + Info("Starting..."); + initiator = initiator_; + + asn1::json_writer js; + rrc_nr_reconf.to_json(js); + Debug("RRC NR Reconfiguration: %s", js.to_string().c_str()); + + if (rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group.size() > 0) { + if (rrc_nr_reconf.crit_exts.type() != asn1::rrc_nr::rrc_recfg_s::crit_exts_c_::types::rrc_recfg) { + Error("Reconfiguration does not contain Secondary Cell Group Config."); + return proc_outcome_t::error; + } + + cbit_ref bref0(rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group.data(), + rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group.size()); + + cell_group_cfg_s secondary_cell_group_cfg; + if (secondary_cell_group_cfg.unpack(bref0) != asn1::SRSASN_SUCCESS) { + Error("Could not unpack Secondary Cell Group Config."); + return proc_outcome_t::error; + } + + asn1::json_writer js1; + secondary_cell_group_cfg.to_json(js1); + Debug("Secondary Cell Group: %s", js1.to_string().c_str()); + + Info("Applying Secondary Cell Group Cfg."); + if (!rrc_handle.apply_cell_group_cfg(secondary_cell_group_cfg)) { + return proc_outcome_t::error; + } + } + + if (rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext.sk_counter_present) { + Info("Applying SK Counter"); + if (!rrc_handle.configure_sk_counter( + (uint16_t)rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext.sk_counter)) { + return proc_outcome_t::error; + } + } + + if (rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.master_cell_group.size() > 0) { + cbit_ref bref1(rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.master_cell_group.data(), + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.master_cell_group.size()); + + cell_group_cfg_s master_cell_group_cfg; + if (master_cell_group_cfg.unpack(bref1) != asn1::SRSASN_SUCCESS) { + Error("Could not unpack Master Cell Group Config."); + return proc_outcome_t::error; + } + + asn1::json_writer js2; + master_cell_group_cfg.to_json(js2); + Debug("Master Cell Group: %s", js2.to_string().c_str()); + + Info("Applying Master Cell Group Cfg."); + if (!rrc_handle.apply_cell_group_cfg(master_cell_group_cfg)) { + return proc_outcome_t::error; + } + } + + if (rrc_nr_reconf.crit_exts.rrc_recfg().radio_bearer_cfg_present) { + Info("Applying Radio Bearer Cfg."); + if (!rrc_handle.apply_radio_bearer_cfg(rrc_nr_reconf.crit_exts.rrc_recfg().radio_bearer_cfg)) { + return proc_outcome_t::error; + } + } + + // only send reconfig complete in SA mode + if (rrc_handle.rrc_eutra == nullptr) { + rrc_handle.send_rrc_reconfig_complete(); + } + + // Handle NAS messages + if (rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.ded_nas_msg_list.size() > 0) { + for (uint32_t i = 0; i < rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.ded_nas_msg_list.size(); ++i) { + srsran::unique_byte_buffer_t nas_pdu = srsran::make_byte_buffer(); + if (nas_pdu != nullptr) { + memcpy(nas_pdu->msg, + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.ded_nas_msg_list[i].data(), + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.ded_nas_msg_list[i].size()); + nas_pdu->N_bytes = rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.ded_nas_msg_list[i].size(); + rrc_handle.nas->write_pdu(std::move(nas_pdu)); + } else { + rrc_handle.logger.error("Couldn't allocate SDU in %s.", __FUNCTION__); + return proc_outcome_t::error; + } + } + } + + return proc_outcome_t::success; +} + +proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::react(const bool& config_complete) +{ + if (not config_complete) { + Error("NR reconfiguration failed"); + return proc_outcome_t::error; + } + + // TODO phy ctrl + // in case there are scell to configure, wait for second phy configuration + // if (not rrc_ptr->phy_ctrl->is_config_pending()) { + // return proc_outcome_t::yield; + // } + + Info("Reconfig NR return successful"); + return proc_outcome_t::success; +} + +void rrc_nr::connection_reconf_no_ho_proc::then(const srsran::proc_state_t& result) +{ + if (result.is_success()) { + Info("Finished %s successfully", name()); + srsran::console("RRC NR reconfiguration successful.\n"); + if (rrc_handle.rrc_eutra) { + rrc_handle.rrc_eutra->nr_rrc_con_reconfig_complete(true); + } + } else { + // 5.3.5.8.2 Inability to comply with RRCReconfiguration + switch (initiator) { + case reconf_initiator_t::mcg_srb1: + if (rrc_handle.rrc_eutra) { + rrc_handle.rrc_eutra->nr_notify_reconfiguration_failure(); + } + break; + default: + Warning("Reconfiguration failure not implemented for initiator %d", initiator); + break; + } + srsran::console("RRC NR reconfiguration failed.\n"); + Warning("Finished %s with failure", name()); + } + return; +} + +/************************************** + * RRC Setup Request Procedure + *************************************/ + +rrc_nr::setup_request_proc::setup_request_proc(rrc_nr& parent_) : + rrc_handle(parent_), logger(srslog::fetch_basic_logger("RRC-NR")) +{} + +proc_outcome_t rrc_nr::setup_request_proc::init(srsran::nr_establishment_cause_t cause_, + srsran::unique_byte_buffer_t dedicated_info_nas_) +{ + cause = cause_; + dedicated_info_nas = std::move(dedicated_info_nas_); + + if (!rrc_handle.plmn_is_selected) { + Error("Trying to connect but PLMN not selected."); + return proc_outcome_t::error; + } + + if (rrc_handle.state != RRC_NR_STATE_IDLE) { + logger.warning("Requested RRC connection establishment while not in IDLE"); + return proc_outcome_t::error; + } + + // TODO: add T302 handling + + Info("Initiation of Setup request procedure"); + + cell_search_ret = rrc_cell_search_result_t::no_cell; + + state = state_t::cell_selection; + if (rrc_handle.cell_selector.is_idle()) { + // No one is running cell selection + if (not rrc_handle.cell_selector.launch()) { + Error("Failed to initiate cell selection procedure..."); + return proc_outcome_t::error; + } + rrc_handle.callback_list.add_proc(rrc_handle.cell_selector); + } else { + Info("Cell selection proc already on-going. Wait for its result"); + } + return proc_outcome_t::yield; +} + +proc_outcome_t rrc_nr::setup_request_proc::step() +{ + if (state == state_t::cell_selection) { + // NOTE: cell selection will signal back with an event trigger + return proc_outcome_t::yield; + } + + if (state == state_t::config_serving_cell) { + // TODO: start serving cell config and start T300 + + // start T300 + rrc_handle.t300.run(); + + // Send setup request message to lower layers + rrc_handle.send_setup_request(cause); + + // Save dedicatedInfoNAS SDU, if needed (TODO: this should be passed to procedure without temp storage) + if (dedicated_info_nas.get()) { + if (rrc_handle.dedicated_info_nas.get()) { + Warning("Received a new dedicatedInfoNAS SDU but there was one still in queue. Removing it."); + rrc_handle.dedicated_info_nas.reset(); + } + + Debug("Updating dedicatedInfoNAS in RRC"); + rrc_handle.dedicated_info_nas = std::move(dedicated_info_nas); + } else { + Debug("dedicatedInfoNAS has already been provided to RRC."); + } + + Info("Waiting for RRCSetup/Reject or expiry"); + state = state_t::wait_t300; + return step(); + + } else if (state == state_t::wait_t300) { + // Wait until t300 stops due to RRCConnectionSetup/Reject or expiry + if (rrc_handle.t300.is_running()) { + return proc_outcome_t::yield; + } + + if (rrc_handle.state == RRC_NR_STATE_CONNECTED) { + // Received ConnectionSetup + return proc_outcome_t::success; + } + } + + return proc_outcome_t::error; +} + +void rrc_nr::setup_request_proc::then(const srsran::proc_state_t& result) +{ + if (result.is_error()) { + logger.warning("Could not finish setup request. Deallocating dedicatedInfoNAS PDU"); + dedicated_info_nas.reset(); + rrc_handle.dedicated_info_nas.reset(); + } else { + Info("Finished connection request procedure successfully."); + } + // TODO: signal back to NAS + // rrc_handle.nas->connection_request_completed(result.is_success()); +} + +srsran::proc_outcome_t rrc_nr::setup_request_proc::react(const cell_selection_proc::cell_selection_complete_ev& e) +{ + if (state != state_t::cell_selection) { + // ignore if we are not expecting an cell selection result + return proc_outcome_t::yield; + } + if (e.is_error()) { + return proc_outcome_t::error; + } + cell_search_ret = *e.value(); + // .. and SI acquisition + // TODO @ismagom use appropiate PHY interface + if (true /*rrc_handle.phy->cell_is_camping()*/) { + // TODO: Set default configurations + // rrc_handle.set_phy_default(); + // rrc_handle.set_mac_default(); + + // CCCH configuration applied already at start + // timeAlignmentCommon applied in configure_serving_cell + + Info("Configuring serving cell..."); + state = state_t::config_serving_cell; + + // Skip SI acquisition + return step(); + } +} + +/****************************************** + * Connection Setup Procedure + *****************************************/ + +// Simple procedure mainly do defer the transmission of the SetupComplete until all PHY reconfiguration are done +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_) +{ + Info("Starting..."); + + if (dedicated_info_nas_ == nullptr) { + logger.error("Connection Setup Failed, no dedicatedInfoNAS available"); + return proc_outcome_t::error; + } + + dedicated_info_nas = std::move(dedicated_info_nas_); + + // Stop T300 + rrc_handle.t300.stop(); + + // Apply the Cell Group configuration + if (!rrc_handle.update_cell_group_cfg(cell_group_)) { + return proc_outcome_t::error; + } + + // Apply the Radio Bearer configuration + if (!rrc_handle.apply_radio_bearer_cfg(radio_bearer_cfg_)) { + return proc_outcome_t::error; + } + + return proc_outcome_t::yield; +} + +srsran::proc_outcome_t rrc_nr::connection_setup_proc::react(const bool& config_complete) +{ + if (not config_complete) { + logger.error("Connection Setup Failed"); + return proc_outcome_t::error; + } + + rrc_handle.send_con_setup_complete(std::move(dedicated_info_nas)); + return proc_outcome_t::success; +} + +void rrc_nr::connection_setup_proc::then(const srsran::proc_state_t& result) +{ + if (result.is_success()) { + logger.info("Finished %s successfully", name()); + return; + } +} + +/************************************** + * Combined Cell Search/Selection Procedure + *************************************/ + +rrc_nr::cell_selection_proc::cell_selection_proc(rrc_nr& parent_) : rrc_handle(parent_) {} + +// Starts PHY's cell search in the current ARFCN +proc_outcome_t rrc_nr::cell_selection_proc::init() +{ + Info("Starting..."); + state = state_t::phy_cell_search; + + // TODO: add full cell selection + // Start cell search + phy_interface_rrc_nr::cell_search_args_t cs_args = {}; + cs_args.center_freq_hz = rrc_handle.phy_cfg.carrier.dl_center_frequency_hz; + cs_args.ssb_freq_hz = rrc_handle.phy_cfg.carrier.ssb_center_freq_hz; + cs_args.ssb_scs = rrc_handle.phy_cfg.ssb.scs; + cs_args.ssb_pattern = rrc_handle.phy_cfg.ssb.pattern; + cs_args.duplex_mode = rrc_handle.phy_cfg.duplex.mode; + if (not rrc_handle.phy->start_cell_search(cs_args)) { + Error("Failed to initiate Cell Search."); + return proc_outcome_t::error; + } + + return proc_outcome_t::yield; +} + +proc_outcome_t rrc_nr::cell_selection_proc::step() +{ + switch (state) { + case state_t::phy_cell_search: + case state_t::phy_cell_select: + case state_t::sib_acquire: + // Waits for cell select/search to complete + return proc_outcome_t::yield; + } + return proc_outcome_t::yield; +} + +// Handles result of PHY's cell search and triggers PHY cell select when new cell was found +proc_outcome_t +rrc_nr::cell_selection_proc::handle_cell_search_result(const rrc_interface_phy_nr::cell_search_result_t& result) +{ + if (!result.cell_found) { + Info("Cell search did not find any cell."); + return proc_outcome_t::error; + } + + // Convert Cell measurement in Text + std::array csi_info_str = {}; + srsran_csi_meas_info_short(&result.measurements, csi_info_str.data(), (uint32_t)csi_info_str.size()); + + // Unpack MIB and convert to text + srsran_mib_nr_t mib = {}; + std::array mib_info_str = {}; + if (srsran_pbch_msg_nr_mib_unpack(&result.pbch_msg, &mib) == SRSASN_SUCCESS) { + // Convert to text + srsran_pbch_msg_nr_mib_info(&mib, mib_info_str.data(), (uint32_t)mib_info_str.size()); + } else { + // It could be the PBCH does not carry MIB + strcpy(mib_info_str.data(), "No MIB found"); + Error("No MIB found\n"); + return proc_outcome_t::error; + } + + // Check unsupported settings + if (mib.cell_barred) { + Error("Cell barred"); + return proc_outcome_t::error; + } + if (mib.scs_common != srsran_subcarrier_spacing_15kHz) { + Error("Unsupported SCS %s", srsran_subcarrier_spacing_to_str(mib.scs_common)); + return proc_outcome_t::error; + } + + // Logs the PCI, cell measurements and decoded MIB + Info("Cell search found ARFCN=%d PCI=%d %s %s", + result.ssb_arfcn, + result.pci, + csi_info_str.data(), + mib_info_str.data()); + + // Apply MIB settings + srsran::phy_cfg_nr_t& phy_cfg = rrc_handle.phy_cfg; + phy_cfg.pdsch.typeA_pos = mib.dmrs_typeA_pos; + phy_cfg.pdsch.scs_cfg = mib.scs_common; + phy_cfg.carrier.pci = result.pci; + + // Get pointA and SSB absolute frequencies + double pointA_abs_freq_Hz = phy_cfg.carrier.dl_center_frequency_hz - + phy_cfg.carrier.nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(phy_cfg.carrier.scs) / 2; + double ssb_abs_freq_Hz = phy_cfg.carrier.ssb_center_freq_hz; + // Calculate integer SSB to pointA frequency offset in Hz + uint32_t ssb_pointA_freq_offset_Hz = + (ssb_abs_freq_Hz > pointA_abs_freq_Hz) ? (uint32_t)(ssb_abs_freq_Hz - pointA_abs_freq_Hz) : 0; + + // Create coreset0 + if (srsran_coreset_zero(phy_cfg.carrier.pci, + ssb_pointA_freq_offset_Hz, + phy_cfg.ssb.scs, + phy_cfg.carrier.scs, + mib.coreset0_idx, + &phy_cfg.pdcch.coreset[0])) { + Error("Error generating coreset0"); + return proc_outcome_t::error; + } + phy_cfg.pdcch.coreset_present[0] = true; + + // Create SearchSpace0 + make_phy_search_space0_cfg(&phy_cfg.pdcch.search_space[0]); + phy_cfg.pdcch.search_space_present[0] = true; + + // Set dummy offset to pass PRACH config check, real value is provided in SIB1 + phy_cfg.prach.freq_offset = 1; + + // Update PHY configuration + rrc_handle.phy_cfg_state = PHY_CFG_STATE_SA_MIB_CFG; + if (not rrc_handle.phy->set_config(phy_cfg)) { + Error("Setting PHY configuration"); + return proc_outcome_t::error; + } + + phy_interface_rrc_nr::cell_select_args_t cs_args = {}; + cs_args.carrier = rrc_handle.phy_cfg.carrier; + cs_args.ssb_cfg = rrc_handle.phy_cfg.get_ssb_cfg(); + + // Transition to cell selection ignoring the cell search result + state = state_t::phy_cell_select; + if (not rrc_handle.phy->start_cell_select(cs_args)) { + Error("Could not set start cell search."); + return proc_outcome_t::error; + } + return proc_outcome_t::yield; +} + +proc_outcome_t rrc_nr::cell_selection_proc::react(const rrc_interface_phy_nr::cell_select_result_t& event) +{ + if (state != state_t::phy_cell_select) { + Warning("Received unexpected cell select result"); + return proc_outcome_t::yield; + } + + if (event.status != rrc_interface_phy_nr::cell_select_result_t::SUCCESSFUL) { + Error("Couldn't select new serving cell"); + phy_search_result.cell_found = false; + rrc_search_result = rrc_nr::rrc_cell_search_result_t::no_cell; + return proc_outcome_t::error; + } + + rrc_search_result = rrc_nr::rrc_cell_search_result_t::same_cell; + + // PHY is now camping on serving cell + Info("Cell selection completed. Starting SIB1 acquisition"); + + // Transition to cell selection ignoring the cell search result + state = state_t::sib_acquire; + rrc_handle.mac->bcch_search(true); + return proc_outcome_t::yield; +} + +proc_outcome_t rrc_nr::cell_selection_proc::react(const bool sib1_found) +{ + if (state != state_t::sib_acquire) { + Warning("Received unexpected cell select result"); + return proc_outcome_t::yield; + } + + Info("SIB1 acquired successfully"); + rrc_handle.mac->bcch_search(false); + + return proc_outcome_t::success; +} + +proc_outcome_t rrc_nr::cell_selection_proc::react(const rrc_interface_phy_nr::cell_search_result_t& event) +{ + if (state != state_t::phy_cell_search) { + Error("Received unexpected cell search result"); + return proc_outcome_t::error; + } + phy_search_result = event; + + if (phy_search_result.cell_found) { + return handle_cell_search_result(phy_search_result); + } + return proc_outcome_t::error; +} + +void rrc_nr::cell_selection_proc::then(const cell_selection_complete_ev& proc_result) const +{ + Info("Completed with %s.", proc_result.is_success() ? "success" : "failure"); + // Inform Connection Request Procedure + rrc_handle.task_sched.defer_task([this, proc_result]() { + if (rrc_handle.setup_req_proc.is_busy()) { + rrc_handle.setup_req_proc.trigger(proc_result); + } + }); +} + +} // namespace srsue diff --git a/srsue/src/stack/rrc_nr/test/CMakeLists.txt b/srsue/src/stack/rrc_nr/test/CMakeLists.txt new file mode 100644 index 0000000000..77c27a1ab4 --- /dev/null +++ b/srsue/src/stack/rrc_nr/test/CMakeLists.txt @@ -0,0 +1,22 @@ +# +# Copyright 2013-2023 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/. +# + +add_executable(ue_rrc_nr_test ue_rrc_nr_test.cc) +target_link_libraries(ue_rrc_nr_test srsue_rrc srsue_rrc_nr srsue_upper srsran_common srsran_pdcp srsran_phy rrc_asn1 rrc_nr_asn1) \ No newline at end of file diff --git a/srsue/src/stack/rrc_nr/test/ue_rrc_nr_test.cc b/srsue/src/stack/rrc_nr/test/ue_rrc_nr_test.cc new file mode 100644 index 0000000000..afad79a7d5 --- /dev/null +++ b/srsue/src/stack/rrc_nr/test/ue_rrc_nr_test.cc @@ -0,0 +1,615 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsran/common/test_common.h" +#include "srsran/interfaces/ue_gw_interfaces.h" +#include "srsran/interfaces/ue_interfaces.h" +#include "srsran/interfaces/ue_pdcp_interfaces.h" +#include "srsran/interfaces/ue_rlc_interfaces.h" +#include "srsran/interfaces/ue_usim_interfaces.h" +#include "srsue/hdr/stack/rrc/rrc.h" +#include "srsue/hdr/stack/rrc_nr/rrc_nr.h" + +using namespace srsue; + +class dummy_phy : public phy_interface_rrc_nr +{ + bool set_config(const srsran::phy_cfg_nr_t& cfg) override { return true; } + phy_nr_state_t get_state() override { return PHY_NR_STATE_IDLE; }; + void reset_nr() override{}; + bool start_cell_search(const cell_search_args_t& req) override { return false; }; + bool start_cell_select(const cell_select_args_t& req) override { return false; }; +}; + +class dummy_mac : public mac_interface_rrc_nr +{ + void reset() {} + int setup_lcid(const srsran::logical_channel_config_t& config) { return SRSRAN_SUCCESS; } + int set_config(const srsran::bsr_cfg_nr_t& bsr_cfg) { return SRSRAN_SUCCESS; } + int set_config(const srsran::sr_cfg_nr_t& sr_cfg) { return SRSRAN_SUCCESS; } + int set_config(const srsran::dl_harq_cfg_nr_t& dl_hrq_cfg) { return SRSRAN_SUCCESS; } + void set_config(const srsran::rach_cfg_nr_t& rach_cfg) {} + int add_tag_config(const srsran::tag_cfg_nr_t& tag_cfg) { return SRSRAN_SUCCESS; } + int set_config(const srsran::phr_cfg_nr_t& phr_cfg) { return SRSRAN_SUCCESS; } + int remove_tag_config(const uint32_t tag_id) { return SRSRAN_SUCCESS; } + void bcch_search(bool) {} + + void start_ra_procedure() {} + + void set_contention_id(const uint64_t ue_identity){}; + + bool set_crnti(const uint16_t crnti) { return true; }; +}; + +class dummy_rlc : public rlc_interface_rrc +{ + void reset() {} + void reestablish() {} + void reestablish(uint32_t lcid) {} + int add_bearer(uint32_t lcid, const srsran::rlc_config_t& cnfg) { return SRSRAN_SUCCESS; } + int add_bearer_mrb(uint32_t mch_idx, uint32_t lcid) { return SRSRAN_SUCCESS; } + void del_bearer(uint32_t lcid) {} + void suspend_bearer(uint32_t lcid) {} + void resume_bearer(uint32_t lcid) {} + void change_lcid(uint32_t old_lcid, uint32_t new_lcid) {} + bool has_bearer(uint32_t lcid) { return true; } + bool has_data(const uint32_t lcid) { return true; } + bool is_suspended(const uint32_t lcid) { return true; } + void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu) + { + last_lcid = lcid; + last_sdu = std::move(sdu); + } + +public: + uint32_t last_lcid = 99; + srsran::unique_byte_buffer_t last_sdu; +}; + +class dummy_pdcp : public pdcp_interface_rrc +{ + void set_enabled(uint32_t lcid, bool enabled){}; + void reestablish(){}; + void reestablish(uint32_t lcid){}; + void reset(){}; + void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu, int sn = -1){}; + int add_bearer(uint32_t lcid, const srsran::pdcp_config_t& cnfg) { return SRSRAN_SUCCESS; }; + void del_bearer(uint32_t lcid){}; + void change_lcid(uint32_t old_lcid, uint32_t new_lcid){}; + void config_security(uint32_t lcid, const srsran::as_security_config_t& sec_cfg){}; + void config_security_all(const srsran::as_security_config_t& sec_cfg){}; + void enable_integrity(uint32_t lcid, srsran::srsran_direction_t direction){}; + void enable_encryption(uint32_t lcid, + srsran::srsran_direction_t direction = srsran::srsran_direction_t::DIRECTION_TXRX){}; + void send_status_report(){}; + void send_status_report(uint32_t lcid){}; +}; + +class dummy_sdap : public sdap_interface_pdcp_nr, public sdap_interface_gw_nr, public sdap_interface_rrc +{ + void write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) final{}; + void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) final{}; + bool set_bearer_cfg(uint32_t lcid, const sdap_interface_rrc::bearer_cfg_t& cfg) final { return true; }; +}; + +class dummy_gw : public gw_interface_rrc +{ + void add_mch_port(uint32_t lcid, uint32_t port){}; + bool is_running() { return true; }; +}; + +class dummy_eutra : public rrc_eutra_interface_rrc_nr +{ + void new_cell_meas_nr(const std::vector& meas){}; + void nr_rrc_con_reconfig_complete(bool status){}; + void nr_notify_reconfiguration_failure(){}; + void nr_scg_failure_information(const srsran::scg_failure_cause_t cause){}; +}; + +class dummy_nas : public nas_5g_interface_rrc_nr +{ + int write_pdu(srsran::unique_byte_buffer_t pdu) { return SRSRAN_SUCCESS; }; + int get_k_amf(srsran::as_key_t& k_amf) { return SRSRAN_SUCCESS; }; + uint32_t get_ul_nas_count() { return SRSRAN_SUCCESS; }; +}; + +class dummy_sim : public usim_interface_rrc_nr +{ + void generate_nr_as_keys(srsran::as_key_t& k_amf, uint32_t count_ul, srsran::as_security_config_t* sec_cfg){}; + bool generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) { return true; } + bool update_nr_context(srsran::as_security_config_t* sec_cfg) { return true; } +}; + +class dummy_stack : public stack_interface_rrc +{ + srsran::tti_point get_current_tti() final { return srsran::tti_point(); }; + void add_eps_bearer(uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid) final{}; + void remove_eps_bearer(uint8_t eps_bearer_id) final{}; + void reset_eps_bearers() final{}; +}; + +int rrc_nr_cap_request_test() +{ + srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR"); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(-1); + srsran::task_scheduler task_sched{512, 100}; + srsran::task_sched_handle task_sched_handle(&task_sched); + srsue::rrc_nr rrc_nr(task_sched_handle); + srsran::byte_buffer_t caps; + + dummy_phy dummy_phy; + dummy_mac dummy_mac; + dummy_rlc dummy_rlc; + dummy_pdcp dummy_pdcp; + dummy_sdap dummy_sdap; + dummy_gw dummy_gw; + dummy_nas dummy_nas; + dummy_eutra dummy_eutra; + dummy_sim dummy_sim; + dummy_stack dummy_stack; + rrc_nr_args_t rrc_nr_args = {}; + + rrc_nr_args.supported_bands_eutra.push_back(7); + rrc_nr_args.supported_bands_nr.push_back(78); + + TESTASSERT(rrc_nr.init(&dummy_phy, + &dummy_mac, + &dummy_rlc, + &dummy_pdcp, + &dummy_sdap, + &dummy_gw, + &dummy_nas, + &dummy_eutra, + &dummy_sim, + task_sched.get_timer_handler(), + &dummy_stack, + rrc_nr_args) == SRSRAN_SUCCESS); + + TESTASSERT(rrc_nr.get_eutra_nr_capabilities(&caps) == SRSRAN_SUCCESS); + TESTASSERT(rrc_nr.get_nr_capabilities(&caps) == SRSRAN_SUCCESS); + return SRSRAN_SUCCESS; +} + +int rrc_nsa_reconfig_tdd_test() +{ + srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR"); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(-1); + srsran::task_scheduler task_sched{512, 100}; + srsran::task_sched_handle task_sched_handle(&task_sched); + srsue::rrc_nr rrc_nr(task_sched_handle); + + dummy_phy dummy_phy; + dummy_mac dummy_mac; + dummy_rlc dummy_rlc; + dummy_pdcp dummy_pdcp; + dummy_sdap dummy_sdap; + dummy_gw dummy_gw; + dummy_nas dummy_nas; + dummy_eutra dummy_eutra; + dummy_sim dummy_sim; + dummy_stack dummy_stack; + rrc_nr_args_t rrc_nr_args = {}; + TESTASSERT(rrc_nr.init(&dummy_phy, + &dummy_mac, + &dummy_rlc, + &dummy_pdcp, + &dummy_sdap, + &dummy_gw, + &dummy_nas, + &dummy_eutra, + &dummy_sim, + task_sched.get_timer_handler(), + &dummy_stack, + rrc_nr_args) == SRSRAN_SUCCESS); + + uint8_t msg[] = { + 0x20, 0x12, 0xaa, 0x00, 0x02, 0x00, 0x80, 0x23, 0x00, 0x01, 0xfb, 0x54, 0x94, 0x10, 0x43, 0xc6, 0x40, 0x62, 0x04, + 0x40, 0x60, 0xae, 0x20, 0x58, 0xe0, 0x3e, 0xa4, 0x1d, 0x02, 0x60, 0x19, 0x00, 0x82, 0x28, 0x01, 0x64, 0x29, 0xdc, + 0x6f, 0xa3, 0x49, 0xad, 0x40, 0x02, 0x69, 0x35, 0x89, 0x00, 0x00, 0x00, 0x66, 0xc6, 0xd9, 0x22, 0x51, 0x00, 0xff, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xc1, 0x10, 0x80, 0x01, 0x24, 0x42, 0x00, 0x68, 0x0a, 0x36, 0x00, 0x9a, 0x4d, + 0x62, 0x40, 0x00, 0x00, 0x19, 0xb8, 0xdb, 0x24, 0x48, 0x01, 0x00, 0x04, 0x17, 0x12, 0x8c, 0x78, 0x01, 0x25, 0x18, + 0x83, 0x70, 0xc6, 0xe3, 0xa2, 0x47, 0x01, 0x80, 0x22, 0x07, 0x03, 0x00, 0x10, 0x1e, 0x23, 0x00, 0xd2, 0x4b, 0x81, + 0xb5, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xe1, 0x10, 0x40, 0x00, 0x92, 0x22, 0x4a, 0x00, 0x00, + 0x90, 0x40, 0x00, 0x04, 0x0d, 0x3a, 0x00, 0x08, 0x02, 0x91, 0x8a, 0x92, 0x42, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4e, 0x04, 0x08, 0x10, 0x20, 0x40, 0x81, 0x02, 0x08, 0x00, 0x00, 0x21, 0x40, 0x00, 0x23, 0x34, 0x1c, + 0x01, 0x0c, 0xc8, 0x50, 0x09, 0x08, 0x60, 0x51, 0x00, 0xab, 0x2a, 0x22, 0x24, 0x40, 0x02, 0x90, 0x5f, 0xfd, 0x29, + 0x49, 0x8c, 0x63, 0x62, 0x45, 0x6a, 0x00, 0x00, 0x01, 0x80, 0x0c, 0x00, 0x04, 0x10, 0x00, 0x71, 0x00, 0x04, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x8a, 0x04, 0x94, 0x0b, 0xc3, 0xe0, 0x06, 0x80, 0x40, 0x00}; + + asn1::cbit_ref bref(msg, sizeof(msg)); + asn1::rrc::dl_dcch_msg_s dl_dcch_msg; + + TESTASSERT(dl_dcch_msg.unpack(bref) == asn1::SRSASN_SUCCESS); + TESTASSERT(dl_dcch_msg.msg.type().value == dl_dcch_msg_type_c::types_opts::c1); + + dl_dcch_msg_type_c::c1_c_* c1 = &dl_dcch_msg.msg.c1(); + rrc_conn_recfg_r8_ies_s rx_recfg = c1->rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8(); + + const asn1::rrc::rrc_conn_recfg_v1510_ies_s rrc_conn_recfg_v1510_ies = + rx_recfg.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext; + + bool endc_release_and_add_r15 = false; + + asn1::rrc_nr::rrc_recfg_s rrc_nr_reconf = {}; + rrc_nr_reconf.crit_exts.set_rrc_recfg(); + + TESTASSERT(rrc_conn_recfg_v1510_ies.nr_cfg_r15.type() == setup_opts::options::setup); + + endc_release_and_add_r15 = rrc_conn_recfg_v1510_ies.nr_cfg_r15.setup().endc_release_and_add_r15; + + TESTASSERT(rrc_conn_recfg_v1510_ies.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15_present); + + asn1::cbit_ref bref0(rrc_conn_recfg_v1510_ies.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15.data(), + rrc_conn_recfg_v1510_ies.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15.size()); + + asn1::rrc_nr::rrc_recfg_s secondary_cell_group_r15; + TESTASSERT(secondary_cell_group_r15.unpack(bref0) == asn1::SRSASN_SUCCESS); + TESTASSERT(secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group.size() > 0); + + rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group = + secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group; + + TESTASSERT(rrc_conn_recfg_v1510_ies.sk_counter_r15_present); + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext.sk_counter_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext.sk_counter = + rrc_conn_recfg_v1510_ies.sk_counter_r15; + + TESTASSERT(rrc_conn_recfg_v1510_ies.nr_radio_bearer_cfg1_r15_present); + rrc_nr_reconf.crit_exts.rrc_recfg().radio_bearer_cfg_present = true; + asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_conf = {}; + asn1::cbit_ref bref2(rrc_conn_recfg_v1510_ies.nr_radio_bearer_cfg1_r15.data(), + rrc_conn_recfg_v1510_ies.nr_radio_bearer_cfg1_r15.size()); + TESTASSERT(radio_bearer_conf.unpack(bref2) == asn1::SRSASN_SUCCESS); + + rrc_nr_reconf.crit_exts.rrc_recfg().radio_bearer_cfg = radio_bearer_conf; + + rrc_nr.rrc_reconfiguration(endc_release_and_add_r15, rrc_nr_reconf); + + task_sched.run_pending_tasks(); + return SRSRAN_SUCCESS; +} + +int rrc_nsa_reconfig_fdd_test() +{ + srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR"); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(-1); + srsran::task_scheduler task_sched{512, 100}; + srsran::task_sched_handle task_sched_handle(&task_sched); + srsue::rrc_nr rrc_nr(task_sched_handle); + + dummy_phy dummy_phy; + dummy_mac dummy_mac; + dummy_rlc dummy_rlc; + dummy_pdcp dummy_pdcp; + dummy_sdap dummy_sdap; + dummy_gw dummy_gw; + dummy_nas dummy_nas; + dummy_eutra dummy_eutra; + dummy_sim dummy_sim; + dummy_stack dummy_stack; + rrc_nr_args_t rrc_nr_args = {}; + TESTASSERT(rrc_nr.init(&dummy_phy, + &dummy_mac, + &dummy_rlc, + &dummy_pdcp, + &dummy_sdap, + &dummy_gw, + &dummy_nas, + &dummy_eutra, + &dummy_sim, + task_sched.get_timer_handler(), + &dummy_stack, + rrc_nr_args) == SRSRAN_SUCCESS); + + uint8_t msg[] = { + 0x20, 0x12, 0xaa, 0x00, 0x02, 0x00, 0x80, 0x23, 0x00, 0x01, 0xfb, 0x54, 0x94, 0x10, 0x43, 0xc6, 0x40, 0x62, 0x04, + 0x40, 0x60, 0xae, 0x20, 0x58, 0xe0, 0x3e, 0xa4, 0x1d, 0x02, 0x60, 0x19, 0x00, 0x82, 0x28, 0x01, 0x64, 0x29, 0xdc, + 0x6f, 0xa3, 0x49, 0xad, 0x40, 0x02, 0x69, 0x35, 0x89, 0x00, 0x00, 0x00, 0x66, 0xc6, 0xd9, 0x22, 0x51, 0x00, 0xff, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xc1, 0x10, 0x80, 0x01, 0x24, 0x42, 0x00, 0x68, 0x0a, 0x36, 0x00, 0x9a, 0x4d, + 0x62, 0x40, 0x00, 0x00, 0x19, 0xb8, 0xdb, 0x24, 0x48, 0x01, 0x00, 0x04, 0x17, 0x12, 0x8c, 0x78, 0x01, 0x25, 0x18, + 0x83, 0x70, 0xc6, 0xe3, 0xa2, 0x47, 0x01, 0x80, 0x22, 0x07, 0x03, 0x00, 0x10, 0x1e, 0x23, 0x00, 0xd2, 0x4b, 0x81, + 0xb5, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xe1, 0x10, 0x40, 0x00, 0x92, 0x22, 0x4a, 0x00, 0x00, + 0x90, 0x40, 0x00, 0x04, 0x0d, 0x3a, 0x00, 0x08, 0x02, 0x91, 0x8a, 0x92, 0x42, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4e, 0x04, 0x08, 0x10, 0x20, 0x40, 0x81, 0x02, 0x08, 0x00, 0x00, 0x21, 0x40, 0x00, 0x23, 0x34, 0x1c, + 0x01, 0x0c, 0xc8, 0x50, 0x09, 0x08, 0x60, 0x51, 0x00, 0xab, 0x2a, 0x22, 0x24, 0x40, 0x02, 0x90, 0x5f, 0xfd, 0x29, + 0x49, 0x8c, 0x63, 0x62, 0x45, 0x6a, 0x00, 0x00, 0x01, 0x80, 0x0c, 0x00, 0x04, 0x10, 0x00, 0x71, 0x00, 0x04, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x8a, 0x04, 0x94, 0x0b, 0xc3, 0xe0, 0x06, 0x80, 0x40, 0x00}; + + asn1::cbit_ref bref(msg, sizeof(msg)); + asn1::rrc::dl_dcch_msg_s dl_dcch_msg; + + TESTASSERT(dl_dcch_msg.unpack(bref) == asn1::SRSASN_SUCCESS); + TESTASSERT(dl_dcch_msg.msg.type().value == dl_dcch_msg_type_c::types_opts::c1); + + dl_dcch_msg_type_c::c1_c_* c1 = &dl_dcch_msg.msg.c1(); + rrc_conn_recfg_r8_ies_s rx_recfg = c1->rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8(); + + const asn1::rrc::rrc_conn_recfg_v1510_ies_s rrc_conn_recfg_v1510_ies = + rx_recfg.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext.non_crit_ext; + + bool endc_release_and_add_r15 = false; + + asn1::rrc_nr::rrc_recfg_s rrc_nr_reconf = {}; + rrc_nr_reconf.crit_exts.set_rrc_recfg(); + + TESTASSERT(rrc_conn_recfg_v1510_ies.nr_cfg_r15.type() == setup_opts::options::setup); + + endc_release_and_add_r15 = rrc_conn_recfg_v1510_ies.nr_cfg_r15.setup().endc_release_and_add_r15; + + TESTASSERT(rrc_conn_recfg_v1510_ies.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15_present); + + asn1::cbit_ref bref0(rrc_conn_recfg_v1510_ies.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15.data(), + rrc_conn_recfg_v1510_ies.nr_cfg_r15.setup().nr_secondary_cell_group_cfg_r15.size()); + + asn1::rrc_nr::rrc_recfg_s secondary_cell_group_r15; + TESTASSERT(secondary_cell_group_r15.unpack(bref0) == asn1::SRSASN_SUCCESS); + TESTASSERT(secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group.size() > 0); + + rrc_nr_reconf.crit_exts.rrc_recfg().secondary_cell_group = + secondary_cell_group_r15.crit_exts.rrc_recfg().secondary_cell_group; + + TESTASSERT(rrc_conn_recfg_v1510_ies.sk_counter_r15_present); + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext.sk_counter_present = true; + rrc_nr_reconf.crit_exts.rrc_recfg().non_crit_ext.non_crit_ext.non_crit_ext.sk_counter = + rrc_conn_recfg_v1510_ies.sk_counter_r15; + + TESTASSERT(rrc_conn_recfg_v1510_ies.nr_radio_bearer_cfg1_r15_present); + rrc_nr_reconf.crit_exts.rrc_recfg().radio_bearer_cfg_present = true; + asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_conf = {}; + asn1::cbit_ref bref2(rrc_conn_recfg_v1510_ies.nr_radio_bearer_cfg1_r15.data(), + rrc_conn_recfg_v1510_ies.nr_radio_bearer_cfg1_r15.size()); + TESTASSERT(radio_bearer_conf.unpack(bref2) == asn1::SRSASN_SUCCESS); + + rrc_nr_reconf.crit_exts.rrc_recfg().radio_bearer_cfg = radio_bearer_conf; + + rrc_nr.rrc_reconfiguration(endc_release_and_add_r15, rrc_nr_reconf); + + task_sched.run_pending_tasks(); + return SRSRAN_SUCCESS; +} + +int rrc_nr_setup_request_test() +{ + srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR"); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(-1); + srsran::task_scheduler task_sched{512, 100}; + srsran::task_sched_handle task_sched_handle(&task_sched); + srsue::rrc_nr rrc_nr(task_sched_handle); + srsran::byte_buffer_t caps; + + dummy_phy dummy_phy; + dummy_mac dummy_mac; + dummy_rlc dummy_rlc; + dummy_pdcp dummy_pdcp; + dummy_sdap dummy_sdap; + dummy_gw dummy_gw; + dummy_nas dummy_nas; + dummy_eutra dummy_eutra; + dummy_sim dummy_sim; + dummy_stack dummy_stack; + rrc_nr_args_t rrc_nr_args = {}; + + rrc_nr_args.supported_bands_nr.push_back(78); + + TESTASSERT(rrc_nr.init(&dummy_phy, + &dummy_mac, + &dummy_rlc, + &dummy_pdcp, + &dummy_sdap, + &dummy_gw, + &dummy_nas, + &dummy_eutra, + &dummy_sim, + task_sched.get_timer_handler(), + &dummy_stack, + rrc_nr_args) == SRSRAN_SUCCESS); + rrc_nr.connection_request(srsran::nr_establishment_cause_t::mt_Access, nullptr); + task_sched.run_pending_tasks(); + + TESTASSERT(dummy_rlc.last_lcid == 0); // SRB0 transmission + TESTASSERT(dummy_rlc.last_sdu->N_bytes == 6); // RRC Setup Request is 6 Bytes long + + return SRSRAN_SUCCESS; +} + +int rrc_nr_sib1_decoding_test() +{ + srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR"); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(-1); + srsran::task_scheduler task_sched{512, 100}; + srsran::task_sched_handle task_sched_handle(&task_sched); + srsue::rrc_nr rrc_nr(task_sched_handle); + + dummy_phy dummy_phy; + dummy_mac dummy_mac; + dummy_rlc dummy_rlc; + dummy_pdcp dummy_pdcp; + dummy_sdap dummy_sdap; + dummy_gw dummy_gw; + dummy_nas dummy_nas; + dummy_eutra dummy_eutra; + dummy_sim dummy_sim; + dummy_stack dummy_stack; + rrc_nr_args_t rrc_nr_args = {}; + TESTASSERT(rrc_nr.init(&dummy_phy, + &dummy_mac, + &dummy_rlc, + &dummy_pdcp, + &dummy_sdap, + &dummy_gw, + &dummy_nas, + &dummy_eutra, + &dummy_sim, + task_sched.get_timer_handler(), + &dummy_stack, + rrc_nr_args) == SRSRAN_SUCCESS); + + uint8_t msg[] = {0x74, 0x81, 0x01, 0x70, 0x10, 0x40, 0x04, 0x02, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x33, 0x60, 0x38, + 0x05, 0x01, 0x00, 0x40, 0x1a, 0x00, 0x00, 0x06, 0x6c, 0x6d, 0x92, 0x21, 0xf3, 0x70, 0x40, 0x20, + 0x00, 0x00, 0x80, 0x80, 0x00, 0x41, 0x06, 0x80, 0xa0, 0x90, 0x9c, 0x20, 0x08, 0x55, 0x19, 0x40, + 0x00, 0x00, 0x33, 0xa1, 0xc6, 0xd9, 0x22, 0x40, 0x00, 0x00, 0x20, 0xb8, 0x94, 0x63, 0xc0, 0x09, + 0x28, 0x44, 0x1b, 0x7e, 0xad, 0x8e, 0x1d, 0x00, 0x9e, 0x2d, 0xa3, 0x0a}; + + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + memcpy(pdu->msg, msg, sizeof(msg)); + pdu->N_bytes = sizeof(msg); + + rrc_nr.write_pdu_bcch_dlsch(std::move(pdu)); + task_sched.run_pending_tasks(); + + return SRSRAN_SUCCESS; +} + +int rrc_nr_setup_test() +{ + srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR"); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(-1); + srsran::task_scheduler task_sched{512, 100}; + srsran::task_sched_handle task_sched_handle(&task_sched); + srsue::rrc_nr rrc_nr(task_sched_handle); + + dummy_phy dummy_phy; + dummy_mac dummy_mac; + dummy_rlc dummy_rlc; + dummy_pdcp dummy_pdcp; + dummy_sdap dummy_sdap; + dummy_gw dummy_gw; + dummy_nas dummy_nas; + dummy_eutra dummy_eutra; + dummy_sim dummy_sim; + dummy_stack dummy_stack; + rrc_nr_args_t rrc_nr_args = {}; + TESTASSERT(rrc_nr.init(&dummy_phy, + &dummy_mac, + &dummy_rlc, + &dummy_pdcp, + &dummy_sdap, + &dummy_gw, + &dummy_nas, + &dummy_eutra, + &dummy_sim, + task_sched.get_timer_handler(), + &dummy_stack, + rrc_nr_args) == SRSRAN_SUCCESS); + + uint8_t msg[] = {0x20, 0x40, 0x04, 0x05, 0x9a, 0xe0, 0x05, 0x80, 0x08, 0x8b, 0xd7, 0x63, 0x80, 0x83, 0x0f, 0x00, 0x03, + 0xa0, 0x10, 0x45, 0x41, 0xc2, 0x0a, 0x20, 0x92, 0x40, 0x0c, 0xa8, 0x00, 0x17, 0xf8, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x37, 0x08, 0x82, 0x00, 0x04, 0x91, 0x12, 0x50, 0x00, 0x04, 0x82, 0x00, 0x00, 0x20, 0x69, + 0x84, 0x0c, 0x55, 0x92, 0x10, 0x70, 0x00, 0x41, 0x03, 0x08, 0x14, 0x30, 0x72, 0x71, 0x02, 0x45, 0x0b, + 0x18, 0x34, 0x70, 0xf2, 0x38, 0x01, 0x98, 0x00, 0x85, 0x00, 0xc0, 0x8c, 0xc0, 0x05, 0x28, 0x06, 0x08, + 0x66, 0x00, 0x31, 0x40, 0x30, 0x63, 0x30, 0x01, 0x0a, 0x03, 0x84, 0x19, 0x80, 0x0a, 0x50, 0x1c, 0x28, + 0xcc, 0x00, 0x62, 0x80, 0xe1, 0x86, 0x60, 0x02, 0x14, 0x0b, 0x0e, 0x33, 0x00, 0x14, 0xa0, 0x58, 0x80, + 0x08, 0xc9, 0x04, 0x31, 0x20, 0x11, 0x92, 0x09, 0x62, 0x80, 0x23, 0x24, 0x14, 0xc5, 0x80, 0x46, 0x48, + 0x2d, 0x8c, 0x00, 0x8c, 0x90, 0x63, 0x1a, 0x01, 0x19, 0x20, 0xd6, 0x38, 0x02, 0x32, 0x41, 0xcc, 0x78, + 0xc8, 0x02, 0x82, 0x19, 0x01, 0x98, 0x00, 0xc5, 0x02, 0xc8, 0x8c, 0x80, 0x28, 0x25, 0x02, 0x42, 0x18, + 0x14, 0x40, 0x20, 0x91, 0x00, 0x0a, 0x41, 0x7f, 0xf4, 0xa5, 0x26, 0x31, 0x8d, 0x80}; + + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + memcpy(pdu->msg, msg, sizeof(msg)); + pdu->N_bytes = sizeof(msg); + + rrc_nr.write_pdu(0, std::move(pdu)); + task_sched.run_pending_tasks(); + + return SRSRAN_SUCCESS; +} + +int rrc_nr_reconfig_test() +{ + srslog::basic_logger& logger = srslog::fetch_basic_logger("RRC-NR"); + logger.set_level(srslog::basic_levels::debug); + logger.set_hex_dump_max_size(-1); + srsran::task_scheduler task_sched{512, 100}; + srsran::task_sched_handle task_sched_handle(&task_sched); + srsue::rrc_nr rrc_nr(task_sched_handle); + + dummy_phy dummy_phy; + dummy_mac dummy_mac; + dummy_rlc dummy_rlc; + dummy_pdcp dummy_pdcp; + dummy_sdap dummy_sdap; + dummy_gw dummy_gw; + dummy_nas dummy_nas; + dummy_eutra dummy_eutra; + dummy_sim dummy_sim; + dummy_stack dummy_stack; + rrc_nr_args_t rrc_nr_args = {}; + TESTASSERT(rrc_nr.init(&dummy_phy, + &dummy_mac, + &dummy_rlc, + &dummy_pdcp, + &dummy_sdap, + &dummy_gw, + &dummy_nas, + &dummy_eutra, + &dummy_sim, + task_sched.get_timer_handler(), + &dummy_stack, + rrc_nr_args) == SRSRAN_SUCCESS); + + uint8_t msg[] = {0x04, 0x8a, 0x80, 0x40, 0x9a, 0x01, 0xe0, 0x02, 0x05, 0xe1, 0xf0, 0x05, 0x00, 0x9a, 0x00, 0x15, 0x84, + 0x88, 0x8b, 0xd7, 0x63, 0x80, 0x83, 0x2f, 0x00, 0x05, 0x8e, 0x03, 0xea, 0x41, 0xd0, 0x23, 0x00, 0x20, + 0x25, 0x5f, 0x80, 0xa2, 0xef, 0x22, 0xc8, 0x40, 0xdf, 0x80, 0x1a, 0x00, 0x40, 0x21, 0x8b, 0x80, 0x40, + 0x70, 0x84, 0xc0, 0x02, 0x40, 0x40, 0x01, 0x8c, 0x4c, 0x40, 0x40, 0x7f, 0xc0, 0x41, 0x82, 0xc0, 0x00, + 0x42, 0xc0, 0x00, 0x4a, 0x43, 0x40, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x82, 0x8b, 0x40, + 0x01, 0x88, 0x80, 0x40, 0x5e, 0x40, 0x01, 0x80, 0x48, 0x10, 0x40, 0x40, 0x42, 0x5e, 0xc0, 0x12, 0x20, + 0x20, 0x08, 0x44, 0x00, 0x80, 0x00, 0x04, 0x20, 0x41, 0x82, 0x02, 0x02, 0x02, 0x20, 0xc1, 0x82, 0x02, + 0x01, 0x01, 0x00, 0x00, 0xc4, 0x08, 0x00, 0x52, 0x18, 0x12, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0xc4, 0x08, 0x00, 0x52, 0x18, 0x12, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0x11, 0x00, 0x03, 0x41, 0x02, 0x02, 0x02, 0x02, 0x00, 0x03, 0x41, 0x02, + 0x02, 0x01, 0x01, 0x09, 0x41, 0xc1, 0x9c, 0xdc, 0x9c, 0xd8, 0x5c, 0x1b, 0x84, 0x80, 0x40}; + + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + memcpy(pdu->msg, msg, sizeof(msg)); + pdu->N_bytes = sizeof(msg); + + rrc_nr.write_pdu(1, std::move(pdu)); + task_sched.run_pending_tasks(); + + return SRSRAN_SUCCESS; +} + +int main(int argc, char** argv) +{ + srslog::init(); + + TESTASSERT(rrc_nr_cap_request_test() == SRSRAN_SUCCESS); + TESTASSERT(rrc_nsa_reconfig_tdd_test() == SRSRAN_SUCCESS); + TESTASSERT(rrc_nsa_reconfig_fdd_test() == SRSRAN_SUCCESS); + TESTASSERT(rrc_nr_setup_request_test() == SRSRAN_SUCCESS); + TESTASSERT(rrc_nr_sib1_decoding_test() == SRSRAN_SUCCESS); + TESTASSERT(rrc_nr_setup_test() == SRSRAN_SUCCESS); + TESTASSERT(rrc_nr_reconfig_test() == SRSRAN_SUCCESS); + + return SRSRAN_SUCCESS; +} diff --git a/srsue/src/stack/ue_stack_lte.cc b/srsue/src/stack/ue_stack_lte.cc index fe222eb21d..4d60503044 100644 --- a/srsue/src/stack/ue_stack_lte.cc +++ b/srsue/src/stack/ue_stack_lte.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -42,6 +42,7 @@ ue_stack_lte::ue_stack_lte() : rrc_logger(srslog::fetch_basic_logger("RRC", false)), usim_logger(srslog::fetch_basic_logger("USIM", false)), nas_logger(srslog::fetch_basic_logger("NAS", false)), + nas5g_logger(srslog::fetch_basic_logger("NAS5G", false)), mac_nr_logger(srslog::fetch_basic_logger("MAC-NR")), rrc_nr_logger(srslog::fetch_basic_logger("RRC-NR", false)), rlc_nr_logger(srslog::fetch_basic_logger("RLC-NR", false)), @@ -56,7 +57,10 @@ ue_stack_lte::ue_stack_lte() : rrc_nr(&task_sched), pdcp(&task_sched, "PDCP"), pdcp_nr(&task_sched, "PDCP-NR"), + sdap("SDAP-NR"), + sdap_pdcp(&pdcp_nr, &sdap), nas(srslog::fetch_basic_logger("NAS", false), &task_sched), + nas_5g(srslog::fetch_basic_logger("NAS5G", false), &task_sched), thread("STACK"), task_sched(512, 64), tti_tprof("tti_tprof", "STCK", TTI_STAT_PERIOD) @@ -125,6 +129,8 @@ int ue_stack_lte::init(const stack_args_t& args_) nas_logger.set_level(srslog::str_to_basic_level(args.log.nas_level)); nas_logger.set_hex_dump_max_size(args.log.nas_hex_limit); + nas5g_logger.set_level(srslog::str_to_basic_level(args.log.nas_level)); + nas5g_logger.set_hex_dump_max_size(args.log.nas_hex_limit); mac_nr_logger.set_level(srslog::str_to_basic_level(args.log.mac_level)); mac_nr_logger.set_hex_dump_max_size(args.log.mac_hex_limit); rrc_nr_logger.set_level(srslog::str_to_basic_level(args.log.rrc_level)); @@ -198,6 +204,7 @@ int ue_stack_lte::init(const stack_args_t& args_) if (args.pkt_trace.nas_pcap.enable) { if (nas_pcap.open(args.pkt_trace.nas_pcap.filename.c_str()) == SRSRAN_SUCCESS) { nas.start_pcap(&nas_pcap); + nas_5g.start_pcap(&nas_pcap); stack_logger.info("Open nas pcap file %s", args.pkt_trace.nas_pcap.filename.c_str()); } else { stack_logger.error("Can not open pcap file %s", args.pkt_trace.nas_pcap.filename.c_str()); @@ -216,17 +223,37 @@ int ue_stack_lte::init(const stack_args_t& args_) mac.init(phy, &rlc, &rrc); rlc.init(&pdcp, &rrc, task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */); - pdcp.init(&rlc, &rrc, gw); nas.init(usim.get(), &rrc, gw, args.nas); + if (!args.sa_mode) { + pdcp.init(&rlc, &rrc, gw); + } else { + pdcp.init(&rlc, &rrc, &sdap_pdcp); + sdap.init(&sdap_pdcp, gw); + } + mac_nr_args_t mac_nr_args = {}; mac_nr.init(mac_nr_args, phy_nr, &rlc_nr, &rrc_nr); rlc_nr.init(&pdcp_nr, &rrc_nr, task_sched.get_timer_handler(), 0 /* RB_ID_SRB0 */); pdcp_nr.init(&rlc_nr, &rrc_nr, gw); - rrc_nr.init( - phy_nr, &mac_nr, &rlc_nr, &pdcp_nr, gw, &rrc, usim.get(), task_sched.get_timer_handler(), this, args.rrc_nr); + rrc_nr.init(phy_nr, + &mac_nr, + &rlc_nr, + &pdcp_nr, + &sdap, + gw, + &nas_5g, + args.sa_mode ? nullptr : &rrc, + usim.get(), + task_sched.get_timer_handler(), + this, + args.rrc_nr); rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, &rrc_nr, args.rrc); + if (args.sa_mode) { + nas_5g.init(usim.get(), &rrc_nr, gw, args.nas_5g); + } + running = true; start(STACK_MAIN_THREAD_PRIO); @@ -247,6 +274,7 @@ void ue_stack_lte::stop_impl() usim->stop(); nas.stop(); + nas_5g.stop(); rrc.stop(); rlc.stop(); @@ -270,8 +298,14 @@ void ue_stack_lte::stop_impl() bool ue_stack_lte::switch_on() { if (running) { - stack_logger.info("Triggering NAS switch on\n"); - if (!ue_task_queue.try_push([this]() { nas.switch_on(); })) { + stack_logger.info("Triggering NAS switch on"); + if (!ue_task_queue.try_push([this]() { + if (args.sa_mode) { + nas_5g.switch_on(); + } else { + nas.switch_on(); + } + })) { stack_logger.error("Triggering NAS switch on: ue_task_queue is full\n"); } } else { @@ -318,7 +352,13 @@ bool ue_stack_lte::disable_data() bool ue_stack_lte::start_service_request() { if (running) { - ue_task_queue.try_push([this]() { nas.start_service_request(srsran::establishment_cause_t::mo_data); }); + ue_task_queue.try_push([this]() { + if (args.sa_mode) { + nas_5g.start_service_request(); + } else { + nas.start_service_request(srsran::establishment_cause_t::mo_data); + } + }); } return true; } @@ -334,6 +374,7 @@ bool ue_stack_lte::get_metrics(stack_metrics_t* metrics) rlc.get_metrics(metrics.rlc, metrics.mac[0].nof_tti); nas.get_metrics(&metrics.nas); rrc.get_metrics(metrics.rrc); + rrc_nr.get_metrics(metrics.rrc_nr); pending_stack_metrics.push(metrics); }); // wait for result @@ -381,12 +422,17 @@ void ue_stack_lte::remove_eps_bearer(uint8_t eps_bearer_id) void ue_stack_lte::write_sdu(uint32_t eps_bearer_id, srsran::unique_byte_buffer_t sdu) { auto bearer = bearers.get_radio_bearer(eps_bearer_id); + auto task = [this, eps_bearer_id, bearer](srsran::unique_byte_buffer_t& sdu) { // route SDU to PDCP entity if (bearer.rat == srsran_rat_t::lte) { pdcp.write_sdu(bearer.lcid, std::move(sdu)); } else if (bearer.rat == srsran_rat_t::nr) { - pdcp_nr.write_sdu(bearer.lcid, std::move(sdu)); + if (args.sa_mode) { + sdap.write_sdu(bearer.lcid, std::move(sdu)); + } else { + pdcp_nr.write_sdu(bearer.lcid, std::move(sdu)); + } } else { stack_logger.warning("Can't deliver SDU for EPS bearer %d. Dropping it.", eps_bearer_id); } @@ -486,6 +532,7 @@ void ue_stack_lte::run_tti_impl(uint32_t tti, uint32_t tti_jump) rrc.run_tti(); rrc_nr.run_tti(tti); nas.run_tti(); + nas_5g.run_tti(); if (args.have_tti_time_stats) { std::chrono::nanoseconds dur = tti_tprof.stop(); @@ -506,4 +553,13 @@ void ue_stack_lte::set_phy_config_complete(bool status) cfg_task_queue.push([this, status]() { rrc_nr.set_phy_config_complete(status); }); } +void ue_stack_lte::cell_search_found_cell(const cell_search_result_t& result) +{ + cfg_task_queue.push([this, result]() { rrc_nr.cell_search_found_cell(result); }); +} +void ue_stack_lte::cell_select_completed(const rrc_interface_phy_nr::cell_select_result_t& result) +{ + cfg_task_queue.push([this, result]() { rrc_nr.cell_select_completed(result); }); +} + } // namespace srsue diff --git a/srsue/src/stack/ue_stack_nr.cc b/srsue/src/stack/ue_stack_nr.cc index 45f7e32752..0fc83f5673 100644 --- a/srsue/src/stack/ue_stack_nr.cc +++ b/srsue/src/stack/ue_stack_nr.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -21,7 +21,7 @@ #include "srsue/hdr/stack/ue_stack_nr.h" #include "srsran/srsran.h" -#include "srsue/hdr/stack/rrc/rrc_nr.h" +#include "srsue/hdr/stack/rrc_nr/rrc_nr.h" using namespace srsran; @@ -85,11 +85,18 @@ int ue_stack_nr::init(const stack_args_t& args_) rrc_nr_args_t rrc_args = {}; rrc_args.log_level = args.log.rrc_level; rrc_args.log_hex_limit = args.log.rrc_hex_limit; - rrc_args.coreless.drb_lcid = 4; - rrc_args.coreless.ip_addr = "192.168.1.3"; - rrc->init( - phy, mac.get(), rlc.get(), pdcp.get(), gw, nullptr, nullptr, task_sched.get_timer_handler(), this, rrc_args); - rrc->init_core_less(); + rrc->init(phy, + mac.get(), + rlc.get(), + pdcp.get(), + sdap.get(), + gw, + nullptr, + nullptr, + nullptr, + task_sched.get_timer_handler(), + this, + rrc_args); running = true; start(STACK_MAIN_THREAD_PRIO); @@ -194,7 +201,7 @@ void ue_stack_nr::out_of_sync() // pending_tasks.push(sync_task_queue, task_t{[this](task_t*) { rrc.out_of_sync(); }}); } -void ue_stack_nr::run_tti(uint32_t tti) +void ue_stack_nr::run_tti(uint32_t tti, uint32_t tti_jump) { sync_task_queue.push([this, tti]() { run_tti_impl(tti); }); } @@ -211,4 +218,14 @@ void ue_stack_nr::set_phy_config_complete(bool status) sync_task_queue.push([this, status]() { rrc->set_phy_config_complete(status); }); } +void ue_stack_nr::cell_search_found_cell(const cell_search_result_t& result) +{ + sync_task_queue.push([this, result]() { rrc->cell_search_found_cell(result); }); +} + +void ue_stack_nr::cell_select_completed(const rrc_interface_phy_nr::cell_select_result_t& result) +{ + sync_task_queue.push([this, result]() { rrc->cell_select_completed(result); }); +} + } // namespace srsue diff --git a/srsue/src/stack/upper/CMakeLists.txt b/srsue/src/stack/upper/CMakeLists.txt index 701dbbdde0..460404f4bd 100644 --- a/srsue/src/stack/upper/CMakeLists.txt +++ b/srsue/src/stack/upper/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -20,7 +20,7 @@ add_subdirectory(test) -set(SOURCES nas.cc nas_emm_state.cc nas_idle_procedures.cc gw.cc usim_base.cc usim.cc tft_packet_filter.cc nas_base.cc nas_5g_procedures.cc nas_5g.cc nas_5gmm_state.cc) +set(SOURCES nas.cc nas_emm_state.cc nas_idle_procedures.cc gw.cc usim_base.cc usim.cc tft_packet_filter.cc nas_base.cc nas_5g_procedures.cc nas_5g.cc nas_5gmm_state.cc sdap.cc) if(HAVE_PCSC) list(APPEND SOURCES "pcsc_usim.cc") diff --git a/srsue/src/stack/upper/gw.cc b/srsue/src/stack/upper/gw.cc index 308c728dd3..bec193446c 100644 --- a/srsue/src/stack/upper/gw.cc +++ b/srsue/src/stack/upper/gw.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -118,11 +118,11 @@ void gw::get_metrics(gw_metrics_t& m, const uint32_t nof_tti) m.dl_tput_mbps = (nof_tti > 0) ? ((dl_tput_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; m.ul_tput_mbps = (nof_tti > 0) ? ((ul_tput_bytes * 8 / (double)1e6) / (nof_tti / 1000.0)) : 0.0; - logger.info("gw_rx_rate_mbps=%4.2f (real=%4.2f), gw_tx_rate_mbps=%4.2f (real=%4.2f)", - m.dl_tput_mbps, - dl_tput_mbps_real_time, - m.ul_tput_mbps, - ul_tput_mbps_real_time); + logger.debug("gw_rx_rate_mbps=%4.2f (real=%4.2f), gw_tx_rate_mbps=%4.2f (real=%4.2f)", + m.dl_tput_mbps, + dl_tput_mbps_real_time, + m.ul_tput_mbps, + ul_tput_mbps_real_time); // reset counters and store time metrics_tp = std::chrono::high_resolution_clock::now(); @@ -161,7 +161,7 @@ void gw::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) } } -void gw::write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) +void gw::write_pdu_mch(uint32_t mch_idx, uint32_t lcid, srsran::unique_byte_buffer_t pdu) { if (pdu->N_bytes > 2) { logger.info(pdu->msg, diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index 147e035ce5..18ba9bf496 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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 14ca4a0c6a..a3ebdedacc 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -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) @@ -278,6 +278,12 @@ int nas_5g::send_registration_request() reg_req.ue_security_capability_present = true; fill_security_caps(reg_req.ue_security_capability); + if (cfg.enable_slicing) { + reg_req.requested_nssai_present = true; + s_nssai_t nssai; + set_nssai(nssai); + reg_req.requested_nssai.s_nssai_list.push_back(nssai); + } if (initial_registration_request_stored.pack(pdu) != SRSASN_SUCCESS) { logger.error("Failed to pack registration request"); return SRSRAN_ERROR; @@ -302,6 +308,11 @@ int nas_5g::send_registration_request() } } + if (has_sec_ctxt) { + set_k_gnb_count(ctxt_base.tx_count); + ctxt_base.tx_count++; + } + state.set_registered_initiated(); return SRSRAN_SUCCESS; @@ -421,14 +432,14 @@ int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_comm // TODO: Save TMSI registration_request_t& modified_registration_request = initial_registration_request_stored.registration_request(); modified_registration_request.capability_5gmm_present = true; - modified_registration_request.requested_nssai_present = true; modified_registration_request.update_type_5gs_present = true; - s_nssai_t s_nssai{}; - s_nssai.type = s_nssai_t::SST_type_::options::sst; - s_nssai.sst = 1; - modified_registration_request.requested_nssai.s_nssai_list = {s_nssai}; - + if (cfg.enable_slicing) { + s_nssai_t s_nssai{}; + modified_registration_request.requested_nssai_present = true; + set_nssai(s_nssai); + modified_registration_request.requested_nssai.s_nssai_list = {s_nssai}; + } modified_registration_request.capability_5gmm.lpp = 0; modified_registration_request.capability_5gmm.ho_attach = 0; modified_registration_request.capability_5gmm.s1_mode = 0; @@ -462,6 +473,7 @@ int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_comm pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); } + has_sec_ctxt = true; logger.info("Sending Security Mode Complete"); rrc_nr->write_sdu(std::move(pdu)); ctxt_base.tx_count++; @@ -523,6 +535,17 @@ void nas_5g::release_proc_trans_id(uint32_t proc_id) return; } +void nas_5g::set_nssai(srsran::nas_5g::s_nssai_t& s_nssai) +{ + if (cfg.nssai_sd == 0) { + s_nssai.type = s_nssai_t::SST_type_::options::sst; + } else { + s_nssai.type = s_nssai_t::SST_type_::options::sst_and_sd; + } + s_nssai.sst = cfg.nssai_sst; + s_nssai.sd = cfg.nssai_sd; +} + int nas_5g::send_pdu_session_establishment_request(uint32_t transaction_identity, uint16_t pdu_session_id, const pdu_session_cfg_t& pdu_session_cfg) @@ -578,11 +601,10 @@ int nas_5g::send_pdu_session_establishment_request(uint32_t tran ul_nas_msg.request_type_present = true; ul_nas_msg.request_type.request_type_value = request_type_t::Request_type_value_type_::options::initial_request; - ul_nas_msg.s_nssai_present = true; - ul_nas_msg.s_nssai.type = s_nssai_t::SST_type_::options::sst_and_sd; - ul_nas_msg.s_nssai.sst = 1; - ul_nas_msg.s_nssai.sd = 0; - + if (cfg.enable_slicing) { + ul_nas_msg.s_nssai_present = true; + set_nssai(ul_nas_msg.s_nssai); + } ul_nas_msg.dnn_present = true; ul_nas_msg.dnn.dnn_value.resize(pdu_session_cfg.apn_name.size() + 1); ul_nas_msg.dnn.dnn_value.data()[0] = static_cast(pdu_session_cfg.apn_name.size()); @@ -769,7 +791,7 @@ int nas_5g::send_configuration_update_complete() pdu->N_bytes - SEQ_5G_OFFSET, &pdu->msg[MAC_5G_OFFSET]); - logger.error("Sending Configuration Update Complete"); + logger.info("Sending Configuration Update Complete"); rrc_nr->write_sdu(std::move(pdu)); ctxt_base.tx_count++; return SRSRAN_SUCCESS; @@ -807,6 +829,7 @@ int nas_5g::handle_registration_accept(registration_accept_t& registration_accep int nas_5g::handle_registration_reject(registration_reject_t& registration_reject) { logger.info("Handling Registration Reject"); + has_sec_ctxt = false; ctxt_base.rx_count++; state.set_deregistered(mm5g_state_t::deregistered_substate_t::plmn_search); @@ -835,14 +858,11 @@ int nas_5g::handle_registration_reject(registration_reject_t& registration_rejec int nas_5g::handle_authentication_request(authentication_request_t& authentication_request) { - logger.info("Handling Registration Request"); + logger.info("Handling Authentication Request"); ctxt_base.rx_count++; // Generate authentication response using RAND, AUTN & KSI-ASME - uint16 mcc, mnc; - mcc = rrc_nr->get_mcc(); - mnc = rrc_nr->get_mnc(); plmn_id_t plmn_id; - plmn_id.from_number(mcc, mnc); + usim->get_home_plmn_id(&plmn_id); if (authentication_request.authentication_parameter_rand_present == false) { logger.error("authentication_parameter_rand_present is not present"); @@ -854,6 +874,7 @@ int nas_5g::handle_authentication_request(authentication_request_t& authenticati return SRSRAN_ERROR; } + initial_sec_command = true; uint8_t res_star[16]; logger.info(authentication_request.authentication_parameter_rand.rand.data(), @@ -882,10 +903,10 @@ int nas_5g::handle_authentication_request(authentication_request_t& authenticati logger.info(res_star, 16, "Generated res_star (%d):", 16); } else if (auth_result == AUTH_FAILED) { - logger.error("Network authentication failure."); + logger.error("Network authentication failure"); send_authentication_failure(cause_5gmm_t::cause_5gmm_type::mac_failure, res_star); } else if (auth_result == AUTH_SYNCH_FAILURE) { - logger.error("Network authentication synchronization failure."); + logger.error("Network authentication synchronization failure"); send_authentication_failure(cause_5gmm_t::cause_5gmm_type::synch_failure, res_star); } else { logger.error("Unhandled authentication failure cause"); @@ -897,6 +918,7 @@ int nas_5g::handle_authentication_request(authentication_request_t& authenticati int nas_5g::handle_authentication_reject(srsran::nas_5g::authentication_reject_t& authentication_reject) { logger.info("Handling Authentication Reject"); + has_sec_ctxt = false; ctxt_base.rx_count++; state.set_deregistered(mm5g_state_t::deregistered_substate_t::plmn_search); return SRSRAN_SUCCESS; @@ -920,6 +942,7 @@ int nas_5g::handle_service_accept(srsran::nas_5g::service_accept_t& service_acce int nas_5g::handle_service_reject(srsran::nas_5g::service_reject_t& service_reject) { logger.info("Handling Service Reject"); + has_sec_ctxt = false; ctxt_base.rx_count++; return SRSRAN_SUCCESS; } @@ -941,10 +964,8 @@ int nas_5g::handle_security_mode_command(security_mode_command_t& security_m return SRSRAN_ERROR; } - initial_sec_command = false; // TODO - if (initial_sec_command) { - ctxt_base.rx_count = 0; + set_k_gnb_count(0); ctxt_base.tx_count = 0; initial_sec_command = false; } @@ -1115,6 +1136,27 @@ void nas_5g::get_metrics(nas_5g_metrics_t& metrics) metrics.state = state.get_state(); } +int nas_5g::get_k_amf(as_key_t& k_amf) +{ + if (not has_sec_ctxt) { + logger.error("K_amf requested before a valid NAS security context was established"); + return SRSRAN_ERROR; + } + + std::copy(std::begin(ctxt_5g.k_amf), std::end(ctxt_5g.k_amf), k_amf.begin()); + return SRSRAN_SUCCESS; +} + +uint32_t nas_5g::get_ul_nas_count() +{ + return ctxt_5g.k_gnb_count; +} + +void nas_5g::set_k_gnb_count(uint32_t count) +{ + ctxt_5g.k_gnb_count = count; +} + /******************************************************************************* * Helpers ******************************************************************************/ @@ -1339,4 +1381,4 @@ int nas_5g::add_pdu_session(uint16_t pdu_session_id, return SRSRAN_SUCCESS; } -} // namespace srsue \ No newline at end of file +} // namespace srsue diff --git a/srsue/src/stack/upper/nas_5g_procedures.cc b/srsue/src/stack/upper/nas_5g_procedures.cc index cbe1dc7ba2..687a57929d 100644 --- a/srsue/src/stack/upper/nas_5g_procedures.cc +++ b/srsue/src/stack/upper/nas_5g_procedures.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,7 +20,7 @@ */ #include "srsue/hdr/stack/upper/nas_5g_procedures.h" - +#include "srsran/common/standard_streams.h" #include #include #include @@ -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(); @@ -86,7 +86,11 @@ srsran::proc_outcome_t nas_5g::pdu_session_establishment_procedure::react( srsran::proc_outcome_t nas_5g::pdu_session_establishment_procedure::react( const srsran::nas_5g::pdu_session_establishment_reject_t& session_est_reject) { - return srsran::proc_outcome_t::success; + logger.error("PDU Session Establishment Reject with cause: %s", + session_est_reject.cause_5gsm.cause_value.to_string()); + srsran::console("PDU Session Establishment Reject with cause: %s\n", + session_est_reject.cause_5gsm.cause_value.to_string()); + return srsran::proc_outcome_t::error; } srsran::proc_outcome_t nas_5g::pdu_session_establishment_procedure::step() diff --git a/srsue/src/stack/upper/nas_5gmm_state.cc b/srsue/src/stack/upper/nas_5gmm_state.cc index 491f52a879..5463d7b4c0 100644 --- a/srsue/src/stack/upper/nas_5gmm_state.cc +++ b/srsue/src/stack/upper/nas_5gmm_state.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/nas_base.cc b/srsue/src/stack/upper/nas_base.cc index d1ef68ac88..79aa484019 100644 --- a/srsue/src/stack/upper/nas_base.cc +++ b/srsue/src/stack/upper/nas_base.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/nas_emm_state.cc b/srsue/src/stack/upper/nas_emm_state.cc index 7c2d158368..ce52b7f807 100644 --- a/srsue/src/stack/upper/nas_emm_state.cc +++ b/srsue/src/stack/upper/nas_emm_state.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/nas_idle_procedures.cc b/srsue/src/stack/upper/nas_idle_procedures.cc index 3f06aeb4d0..5fbd0eafb3 100644 --- a/srsue/src/stack/upper/nas_idle_procedures.cc +++ b/srsue/src/stack/upper/nas_idle_procedures.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/pcsc_usim.cc b/srsue/src/stack/upper/pcsc_usim.cc index bb132011b0..dfe1ada609 100644 --- a/srsue/src/stack/upper/pcsc_usim.cc +++ b/srsue/src/stack/upper/pcsc_usim.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -32,12 +32,7 @@ using namespace srsran; namespace srsue { -pcsc_usim::pcsc_usim(srslog::basic_logger& logger) : usim_base(logger), sc(logger) -{ - bzero(ck, CK_LEN); - bzero(ik, IK_LEN); - bzero(auts, IK_LEN); -} +pcsc_usim::pcsc_usim(srslog::basic_logger& logger) : usim_base(logger), sc(logger) {} pcsc_usim::~pcsc_usim() { diff --git a/srsue/src/stack/upper/sdap.cc b/srsue/src/stack/upper/sdap.cc new file mode 100644 index 0000000000..a6bb157560 --- /dev/null +++ b/srsue/src/stack/upper/sdap.cc @@ -0,0 +1,85 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#include "srsue/hdr/stack/upper/sdap.h" + +namespace srsue { + +sdap::sdap(const char* logname) : logger(srslog::fetch_basic_logger(logname)) {} + +bool sdap::init(pdcp_interface_sdap_nr* pdcp_, srsue::gw_interface_pdcp* gw_) +{ + m_pdcp = pdcp_; + m_gw = gw_; + + running = true; + return true; +} + +void sdap::stop() +{ + if (running) { + running = false; + } +} + +void sdap::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) +{ + if (!running) { + return; + } + m_gw->write_pdu(lcid, std::move(pdu)); +} + +void sdap::write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) +{ + if (!running) { + return; + } + if (lcid < bearers.size()) { + if (bearers[lcid].add_uplink_header) { + if (pdu->get_headroom() > 1) { + pdu->msg -= 1; + pdu->N_bytes += 1; + pdu->msg[0] = ((bearers[lcid].is_data ? 1 : 0) << 7) | (bearers[lcid].qfi & 0x3f); + } else { + logger.error("Not enough headroom in PDU to add header\n"); + } + } + } + m_pdcp->write_sdu(lcid, std::move(pdu)); +} + +bool sdap::set_bearer_cfg(uint32_t lcid, const sdap_interface_rrc::bearer_cfg_t& cfg) +{ + if (lcid >= bearers.size()) { + logger.error("Error setting configuration: invalid lcid=%d\n", lcid); + return false; + } + if (cfg.add_downlink_header) { + logger.error("Error setting configuration: downlink header not supported\n"); + return false; + } + bearers[lcid] = cfg; + return true; +} + +} // namespace srsue diff --git a/srsue/src/stack/upper/test/CMakeLists.txt b/srsue/src/stack/upper/test/CMakeLists.txt index aacda4d6f8..a0590940e8 100644 --- a/srsue/src/stack/upper/test/CMakeLists.txt +++ b/srsue/src/stack/upper/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/src/stack/upper/test/gw_test.cc b/srsue/src/stack/upper/test/gw_test.cc index 6f547fb108..0431436f64 100644 --- a/srsue/src/stack/upper/test/gw_test.cc +++ b/srsue/src/stack/upper/test/gw_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/test/nas_5g_test.cc b/srsue/src/stack/upper/test/nas_5g_test.cc index 0c62f1b160..ad8f365718 100644 --- a/srsue/src/stack/upper/test/nas_5g_test.cc +++ b/srsue/src/stack/upper/test/nas_5g_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/test/nas_test.cc b/srsue/src/stack/upper/test/nas_test.cc index c3d418670d..58bdb8a7ec 100644 --- a/srsue/src/stack/upper/test/nas_test.cc +++ b/srsue/src/stack/upper/test/nas_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/test/pcsc_usim_test.cc b/srsue/src/stack/upper/test/pcsc_usim_test.cc index b52d9b28a0..b61430f915 100644 --- a/srsue/src/stack/upper/test/pcsc_usim_test.cc +++ b/srsue/src/stack/upper/test/pcsc_usim_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/test/tft_test.cc b/srsue/src/stack/upper/test/tft_test.cc index 61136e08be..681fda693e 100644 --- a/srsue/src/stack/upper/test/tft_test.cc +++ b/srsue/src/stack/upper/test/tft_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/test/usim_test.cc b/srsue/src/stack/upper/test/usim_test.cc index 32f9e3f5dd..c724721a30 100644 --- a/srsue/src/stack/upper/test/usim_test.cc +++ b/srsue/src/stack/upper/test/usim_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/tft_packet_filter.cc b/srsue/src/stack/upper/tft_packet_filter.cc index 1a8f7f97a6..72664fa87d 100644 --- a/srsue/src/stack/upper/tft_packet_filter.cc +++ b/srsue/src/stack/upper/tft_packet_filter.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/usim.cc b/srsue/src/stack/upper/usim.cc index b3db759bd3..95f92f2b03 100644 --- a/srsue/src/stack/upper/usim.cc +++ b/srsue/src/stack/upper/usim.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/stack/upper/usim_base.cc b/srsue/src/stack/upper/usim_base.cc index 95522dc8b7..5cdac7aa4e 100644 --- a/srsue/src/stack/upper/usim_base.cc +++ b/srsue/src/stack/upper/usim_base.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -231,6 +231,7 @@ void usim_base::generate_nas_keys(uint8_t* k_asme, /* * RRC Interface */ + void usim_base::generate_as_keys(uint8_t* k_asme_, uint32_t count_ul, srsran::as_security_config_t* sec_cfg) { if (!initiated) { @@ -376,6 +377,42 @@ bool usim_base::generate_nas_keys_5g(uint8_t* k_amf, * NR RRC Interface */ +void usim_base::generate_nr_as_keys(srsran::as_key_t& k_amf, uint32_t count_ul, srsran::as_security_config_t* sec_cfg) +{ + if (!initiated) { + logger.error("USIM not initiated!"); + return; + } + + logger.info("Generating NR AS Keys. NAS UL COUNT %d", count_ul); + logger.debug(k_amf.data(), 32, "K_amf"); + + // Generate K_gnb + srsran::security_generate_k_gnb(k_amf, count_ul, k_gnb_ctx.k_gnb); + logger.info(k_gnb_ctx.k_gnb.data(), 32, "K_gnb"); + + // Save initial k_gnb + k_gnb_initial = k_gnb_ctx.k_gnb; + + security_generate_k_nr_rrc(k_gnb_ctx.k_gnb.data(), + sec_cfg->cipher_algo, + sec_cfg->integ_algo, + sec_cfg->k_rrc_enc.data(), + sec_cfg->k_rrc_int.data()); + + security_generate_k_nr_up(k_gnb_ctx.k_gnb.data(), + sec_cfg->cipher_algo, + sec_cfg->integ_algo, + sec_cfg->k_up_enc.data(), + sec_cfg->k_up_int.data()); + + logger.info(k_gnb_ctx.k_gnb.data(), 32, "Initial K_gnb"); + logger.info(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "NR K_RRC_int"); + logger.info(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "NR K_RRC_enc"); + logger.info(sec_cfg->k_up_int.data(), sec_cfg->k_up_int.size(), "NR K_UP_int"); + logger.info(sec_cfg->k_up_enc.data(), sec_cfg->k_up_enc.size(), "NR K_UP_enc"); +} + bool usim_base::generate_nr_context(uint16_t sk_counter, srsran::as_security_config_t* sec_cfg) { if (!initiated) { diff --git a/srsue/src/test/CMakeLists.txt b/srsue/src/test/CMakeLists.txt index 59ad11dbea..4def2c8c42 100644 --- a/srsue/src/test/CMakeLists.txt +++ b/srsue/src/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/src/test/metrics_test.cc b/srsue/src/test/metrics_test.cc index c5dfa85856..3b0ce8100f 100644 --- a/srsue/src/test/metrics_test.cc +++ b/srsue/src/test/metrics_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -20,7 +20,7 @@ */ #include "srsran/common/metrics_hub.h" -#include "srsran/srsran.h" +#include "srsran/common/test_common.h" #include "srsue/hdr/metrics_csv.h" #include "srsue/hdr/metrics_stdout.h" #include "srsue/hdr/ue_metrics_interface.h" @@ -34,10 +34,12 @@ using namespace srsue; namespace srsue { -char* csv_file_name = NULL; +static char* csv_file_name = NULL; +static float period = 1.0; +static int duration_s = 5; // fake classes -class ue_dummy : public ue_metrics_interface +class eutra_ue_dummy : public ue_metrics_interface { public: bool get_metrics(ue_metrics_t* m) @@ -72,6 +74,51 @@ class ue_dummy : public ue_metrics_interface m->phy.nof_active_cc = 1; m->phy.ch[0].rsrp = -10.0f; m->phy.ch[0].pathloss = 32; + + m->stack.rrc.state = (rand() % 2 == 0) ? RRC_STATE_CONNECTED : RRC_STATE_IDLE; + + return true; + } +}; + +class nsa_ue_dummy : public ue_metrics_interface +{ +public: + bool get_metrics(ue_metrics_t* m) + { + *m = {}; + + // fill dummy values + m->rf.rf_o = 10; + m->phy.nof_active_cc = 1; + m->phy.ch[0].rsrp = -10.0f; + m->phy.ch[0].pathloss = 74; + m->stack.mac[0].rx_pkts = 100; + m->stack.mac[0].rx_errors = 0; + m->stack.mac[0].rx_brate = 200; + m->stack.mac[0].nof_tti = 1; + + m->phy.info[1].pci = UINT32_MAX; + m->stack.mac[1].rx_pkts = 100; + m->stack.mac[1].rx_errors = 100; + m->stack.mac[1].rx_brate = 150; + m->stack.mac[1].nof_tti = 1; + + // random neighbour cells + if (rand() % 2 == 0) { + phy_meas_t neighbor = {}; + neighbor.pci = 8; + neighbor.rsrp = -33; + m->stack.rrc.neighbour_cells.push_back(neighbor); + m->stack.rrc.neighbour_cells.push_back(neighbor); // need to add twice since we use CA + } + + m->phy.nof_active_cc = 1; + m->phy.ch[0].rsrp = -10.0f; + m->phy.ch[0].pathloss = 32; + + // NR + m->phy_nr.nof_active_cc = 1; m->stack.mac_nr[0].rx_pkts = 100; m->stack.mac_nr[0].rx_errors = 2; m->stack.mac_nr[0].rx_brate = 223; @@ -83,6 +130,31 @@ class ue_dummy : public ue_metrics_interface } }; +class sa_ue_dummy : public ue_metrics_interface +{ +public: + bool get_metrics(ue_metrics_t* m) + { + *m = {}; + + // fill dummy values + m->rf.rf_o = 10; + m->phy.nof_active_cc = 0; + + // NR + m->phy_nr.nof_active_cc = 1; + m->phy_nr.info[0].pci = 501; + m->stack.mac_nr[0].rx_pkts = 100; + m->stack.mac_nr[0].rx_errors = 2; + m->stack.mac_nr[0].rx_brate = 223; + m->stack.mac_nr[0].nof_tti = 1; + + m->stack.rrc_nr.state = (rand() % 2 == 0) ? RRC_NR_STATE_CONNECTED : RRC_NR_STATE_IDLE; + + return true; + } +}; + } // namespace srsue void usage(char* prog) @@ -110,38 +182,50 @@ void parse_args(int argc, char** argv) } } -int main(int argc, char** argv) +int ue_test(std::string name, ue_metrics_interface* ue) { - float period = 1.0; - ue_dummy ue; - - if (argc < 3) { - usage(argv[0]); - exit(-1); - } - - parse_args(argc, argv); - // the default metrics type for stdout output metrics_stdout metrics_screen; - metrics_screen.set_ue_handle(&ue); + metrics_screen.set_ue_handle(ue); // the CSV file writer metrics_csv metrics_file(csv_file_name); - metrics_file.set_ue_handle(&ue); + metrics_file.set_ue_handle(ue); // create metrics hub and register metrics for stdout srsran::metrics_hub metricshub; - metricshub.init(&ue, period); + metricshub.init(ue, period); metricshub.add_listener(&metrics_screen); metricshub.add_listener(&metrics_file); // enable printing metrics_screen.toggle_print(true); - std::cout << "Running for 5 seconds .." << std::endl; - usleep(5e6); + std::cout << "Running " << name << " UE test for " << duration_s << " seconds .." << std::endl; + usleep(duration_s * 1e6); metricshub.stop(); - return 0; + + return SRSRAN_SUCCESS; +} + +int main(int argc, char** argv) +{ + if (argc < 3) { + usage(argv[0]); + exit(-1); + } + + parse_args(argc, argv); + + eutra_ue_dummy eutra_ue; + TESTASSERT_SUCCESS(ue_test("EUTRA", &eutra_ue)); + + nsa_ue_dummy nsa_ue; + TESTASSERT_SUCCESS(ue_test("NSA", &nsa_ue)); + + sa_ue_dummy sa_ue; + TESTASSERT_SUCCESS(ue_test("SA", &sa_ue)); + + return SRSRAN_SUCCESS; } diff --git a/srsue/src/test/ttcn3/CMakeLists.txt b/srsue/src/test/ttcn3/CMakeLists.txt index 9dc670ea73..82842213ac 100644 --- a/srsue/src/test/ttcn3/CMakeLists.txt +++ b/srsue/src/test/ttcn3/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/src/test/ttcn3/hdr/dut_utils.h b/srsue/src/test/ttcn3/hdr/dut_utils.h index 528a16ae46..a0897a0bf6 100644 --- a/srsue/src/test/ttcn3/hdr/dut_utils.h +++ b/srsue/src/test/ttcn3/hdr/dut_utils.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/lte_ttcn3_phy.h b/srsue/src/test/ttcn3/hdr/lte_ttcn3_phy.h index 729e62e982..17347cbc8f 100644 --- a/srsue/src/test/ttcn3/hdr/lte_ttcn3_phy.h +++ b/srsue/src/test/ttcn3/hdr/lte_ttcn3_phy.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -25,7 +25,7 @@ #include "srsran/common/task_scheduler.h" #include "srsran/interfaces/ue_interfaces.h" #include "srsran/interfaces/ue_phy_interfaces.h" -#include "srsue/hdr/phy/ue_lte_phy_base.h" +#include "srsue/hdr/phy/ue_phy_base.h" #include "srsue/hdr/ue.h" #include "ttcn3_interfaces.h" #include @@ -35,7 +35,7 @@ using namespace srsran; namespace srsue { -class lte_ttcn3_phy : public ue_lte_phy_base +class lte_ttcn3_phy : public ue_phy_base, public phy_interface_stack_lte { public: void set_cells_to_meas(uint32_t earfcn, const std::set& pci) override; @@ -51,12 +51,9 @@ class lte_ttcn3_phy : public ue_lte_phy_base int init(const phy_args_t& args_, stack_interface_phy_lte* stack_, syssim_interface_phy* syssim_); - int init(const phy_args_t& args_, stack_interface_phy_lte* stack_, srsran::radio_interface_phy* radio_) override; - - // ue_phy_base interface - int init(const phy_args_t& args_) override; void stop() override; void wait_initialize() override; + bool is_initialized() override; void start_plot() override; void get_metrics(const srsran::srsran_rat_t& rat, phy_metrics_t* m) override; std::string get_type() override; @@ -81,7 +78,7 @@ class lte_ttcn3_phy : public ue_lte_phy_base void set_mch_period_stop(uint32_t stop) override{}; // Cell search and selection procedures - bool cell_search() override; + bool cell_search(int earfcn) override; bool cell_select(phy_cell_t cell) override; bool cell_is_camping() override; @@ -105,10 +102,6 @@ class lte_ttcn3_phy : public ue_lte_phy_base void new_grant_ul(mac_interface_phy_lte::mac_grant_ul_t ul_mac_grant); void new_tb(const srsue::mac_interface_phy_lte::mac_grant_dl_t, const uint8_t* data); - // Radio interface - void radio_overflow() override; - void radio_failure() override; - void run_tti(); private: diff --git a/srsue/src/test/ttcn3/hdr/swappable_sink.h b/srsue/src/test/ttcn3/hdr/swappable_sink.h index 56ca64a612..537e80f708 100644 --- a/srsue/src/test/ttcn3/hdr/swappable_sink.h +++ b/srsue/src/test/ttcn3/hdr/swappable_sink.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_common.h b/srsue/src/test/ttcn3/hdr/ttcn3_common.h index 0aba8e2a45..46bbd38ea7 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_common.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_drb_interface.h b/srsue/src/test/ttcn3/hdr/ttcn3_drb_interface.h index b4dc6536f2..f5ccb2263d 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_drb_interface.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_drb_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_helpers.h b/srsue/src/test/ttcn3/hdr/ttcn3_helpers.h index 3d36c1c2fa..751875fe38 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_helpers.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_helpers.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_interfaces.h b/srsue/src/test/ttcn3/hdr/ttcn3_interfaces.h index b174335eb8..6ea4aa2b9c 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_interfaces.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_interfaces.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_ip_ctrl_interface.h b/srsue/src/test/ttcn3/hdr/ttcn3_ip_ctrl_interface.h index a82a3f029c..71b7a9fc0b 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_ip_ctrl_interface.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_ip_ctrl_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_ip_sock_interface.h b/srsue/src/test/ttcn3/hdr/ttcn3_ip_sock_interface.h index f302077f69..2b004f8d0e 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_ip_sock_interface.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_ip_sock_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_port_handler.h b/srsue/src/test/ttcn3/hdr/ttcn3_port_handler.h index 58b78f9af6..bc769a81bc 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_port_handler.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_port_handler.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_srb_interface.h b/srsue/src/test/ttcn3/hdr/ttcn3_srb_interface.h index 329a522bcf..f597f79095 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_srb_interface.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_srb_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_sys_interface.h b/srsue/src/test/ttcn3/hdr/ttcn3_sys_interface.h index afc3375869..6fc9cfffc1 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_sys_interface.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_sys_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_syssim.h b/srsue/src/test/ttcn3/hdr/ttcn3_syssim.h index d45debb165..3b779974f1 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_syssim.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_syssim.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_ue.h b/srsue/src/test/ttcn3/hdr/ttcn3_ue.h index ac3a138137..fc92a465bd 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_ue.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_ue.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_ut_interface.h b/srsue/src/test/ttcn3/hdr/ttcn3_ut_interface.h index e25250f327..482ccb904e 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_ut_interface.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_ut_interface.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/src/CMakeLists.txt b/srsue/src/test/ttcn3/src/CMakeLists.txt index b742814961..9e59ba56eb 100644 --- a/srsue/src/test/ttcn3/src/CMakeLists.txt +++ b/srsue/src/test/ttcn3/src/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/src/test/ttcn3/src/lte_ttcn3_phy.cc b/srsue/src/test/ttcn3/src/lte_ttcn3_phy.cc index 5cb64bc975..ab9949c21d 100644 --- a/srsue/src/test/ttcn3/src/lte_ttcn3_phy.cc +++ b/srsue/src/test/ttcn3/src/lte_ttcn3_phy.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -36,17 +36,6 @@ int lte_ttcn3_phy::init(const phy_args_t& args_, stack_interface_phy_lte* stack_ stack = stack_; syssim = syssim_; - return init(args_); -} - -int lte_ttcn3_phy::init(const phy_args_t& args_, stack_interface_phy_lte* stack_, srsran::radio_interface_phy* radio_) -{ - return init(args_); -} - -// ue_phy_base interface -int lte_ttcn3_phy::init(const phy_args_t& args_) -{ logger.set_level(srslog::str_to_basic_level(args_.log.phy_level)); logger.set_hex_dump_max_size(-1); @@ -55,6 +44,11 @@ int lte_ttcn3_phy::init(const phy_args_t& args_) void lte_ttcn3_phy::stop(){}; +bool lte_ttcn3_phy::is_initialized() +{ + return true; +} + void lte_ttcn3_phy::wait_initialize() {} void lte_ttcn3_phy::start_plot() {} @@ -102,7 +96,7 @@ void lte_ttcn3_phy::meas_stop() {} // configured by the SS, including the ones that we should not even detect because // their power is too weak. The cell search should only report the cells that // are actually visible though. -bool lte_ttcn3_phy::cell_search() +bool lte_ttcn3_phy::cell_search(int earfcn) { std::lock_guard lock(phy_mutex); @@ -344,16 +338,6 @@ void lte_ttcn3_phy::new_tb(const srsue::mac_interface_phy_lte::mac_grant_dl_t dl stack->tb_decoded(cc_idx, dl_grant, dl_ack); } -void lte_ttcn3_phy::radio_overflow() -{ - logger.debug("%s not implemented.", __FUNCTION__); -} - -void lte_ttcn3_phy::radio_failure() -{ - logger.debug("%s not implemented.", __FUNCTION__); -} - // Calling function set_tti() is holding mutex void lte_ttcn3_phy::run_tti() { diff --git a/srsue/src/test/ttcn3/src/ttcn3_dut.cc b/srsue/src/test/ttcn3/src/ttcn3_dut.cc index 6484865fc7..c750778f96 100644 --- a/srsue/src/test/ttcn3/src/ttcn3_dut.cc +++ b/srsue/src/test/ttcn3/src/ttcn3_dut.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/src/ttcn3_syssim.cc b/srsue/src/test/ttcn3/src/ttcn3_syssim.cc index 994dece1e8..11387ef6e2 100644 --- a/srsue/src/test/ttcn3/src/ttcn3_syssim.cc +++ b/srsue/src/test/ttcn3/src/ttcn3_syssim.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/src/ttcn3_ue.cc b/srsue/src/test/ttcn3/src/ttcn3_ue.cc index 831e6c73e3..1980408e26 100644 --- a/srsue/src/test/ttcn3/src/ttcn3_ue.cc +++ b/srsue/src/test/ttcn3/src/ttcn3_ue.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/test/CMakeLists.txt b/srsue/src/test/ttcn3/test/CMakeLists.txt index c083fd91cb..dd4cddbc5a 100644 --- a/srsue/src/test/ttcn3/test/CMakeLists.txt +++ b/srsue/src/test/ttcn3/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/srsue/src/test/ttcn3/test/rapidjson_test.cc b/srsue/src/test/ttcn3/test/rapidjson_test.cc index c0472619c9..d96b72761d 100644 --- a/srsue/src/test/ttcn3/test/rapidjson_test.cc +++ b/srsue/src/test/ttcn3/test/rapidjson_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/test/ttcn3/test/ttcn3_if_handler_test.cc b/srsue/src/test/ttcn3/test/ttcn3_if_handler_test.cc index 208add09a6..6da8ac058b 100644 --- a/srsue/src/test/ttcn3/test/ttcn3_if_handler_test.cc +++ b/srsue/src/test/ttcn3/test/ttcn3_if_handler_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 32a67b3459..038c2103cb 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -26,7 +26,9 @@ #include "srsran/radio/radio.h" #include "srsran/radio/radio_null.h" #include "srsran/srsran.h" +#include "srsue/hdr/phy/dummy_phy.h" #include "srsue/hdr/phy/phy.h" +#include "srsue/hdr/phy/phy_nr_sa.h" #include "srsue/hdr/stack/ue_stack_lte.h" #include "srsue/hdr/stack/ue_stack_nr.h" #include @@ -69,36 +71,18 @@ int ue::init(const all_args_t& args_) return SRSRAN_ERROR; } - std::unique_ptr gw_ptr(new gw(srslog::fetch_basic_logger("GW"))); + std::unique_ptr gw_ptr(new gw(srslog::fetch_basic_logger("GW", false))); if (!gw_ptr) { srsran::console("Error creating a GW instance.\n"); return SRSRAN_ERROR; } - std::unique_ptr lte_phy = std::unique_ptr(new srsue::phy); - if (!lte_phy) { - srsran::console("Error creating LTE PHY instance.\n"); - return SRSRAN_ERROR; - } - std::unique_ptr lte_radio = std::unique_ptr(new srsran::radio); if (!lte_radio) { srsran::console("Error creating radio multi instance.\n"); return SRSRAN_ERROR; } - // init layers - if (lte_radio->init(args.rf, lte_phy.get())) { - srsran::console("Error initializing radio.\n"); - return SRSRAN_ERROR; - } - - // from here onwards do not exit immediately if something goes wrong as sub-layers may already use interfaces - if (lte_phy->init(args.phy, lte_stack.get(), lte_radio.get())) { - srsran::console("Error initializing PHY.\n"); - ret = SRSRAN_ERROR; - } - srsue::phy_args_nr_t phy_args_nr = {}; phy_args_nr.max_nof_prb = args.phy.nr_max_nof_prb; phy_args_nr.rf_channel_offset = args.phy.nof_lte_carriers; @@ -107,14 +91,69 @@ int ue::init(const all_args_t& args_) phy_args_nr.worker_cpu_mask = args.phy.worker_cpu_mask; phy_args_nr.log = args.phy.log; phy_args_nr.store_pdsch_ko = args.phy.nr_store_pdsch_ko; - if (lte_phy->init(phy_args_nr, lte_stack.get(), lte_radio.get())) { - srsran::console("Error initializing NR PHY.\n"); - ret = SRSRAN_ERROR; - } + phy_args_nr.srate_hz = args.rf.srate_hz; - if (lte_stack->init(args.stack, lte_phy.get(), lte_phy.get(), gw_ptr.get())) { - srsran::console("Error initializing stack.\n"); - ret = SRSRAN_ERROR; + // init layers + if (args.phy.nof_lte_carriers == 0) { + // SA mode + std::unique_ptr nr_phy = std::unique_ptr(new srsue::phy_nr_sa("PHY-SA")); + if (!nr_phy) { + srsran::console("Error creating NR PHY instance.\n"); + return SRSRAN_ERROR; + } + + // In SA mode, pass the NR SA phy to the radio + if (lte_radio->init(args.rf, nr_phy.get())) { + srsran::console("Error initializing radio.\n"); + return SRSRAN_ERROR; + } + if (nr_phy->init(phy_args_nr, lte_stack.get(), lte_radio.get())) { + srsran::console("Error initializing PHY NR SA.\n"); + ret = SRSRAN_ERROR; + } + + std::unique_ptr dummy_lte_phy = std::unique_ptr(new srsue::dummy_phy); + if (!dummy_lte_phy) { + srsran::console("Error creating dummy LTE PHY instance.\n"); + return SRSRAN_ERROR; + } + + // In SA mode, pass NR PHY pointer to stack + args.stack.sa_mode = true; + if (lte_stack->init(args.stack, dummy_lte_phy.get(), nr_phy.get(), gw_ptr.get())) { + srsran::console("Error initializing stack.\n"); + ret = SRSRAN_ERROR; + } + phy = std::move(nr_phy); + dummy_phy = std::move(dummy_lte_phy); + } else { + // LTE or NSA mode + std::unique_ptr lte_phy = std::unique_ptr(new srsue::phy); + if (!lte_phy) { + srsran::console("Error creating LTE PHY instance.\n"); + return SRSRAN_ERROR; + } + + if (lte_radio->init(args.rf, lte_phy.get())) { + srsran::console("Error initializing radio.\n"); + return SRSRAN_ERROR; + } + // from here onwards do not exit immediately if something goes wrong as sub-layers may already use interfaces + if (lte_phy->init(args.phy, lte_stack.get(), lte_radio.get())) { + srsran::console("Error initializing PHY.\n"); + ret = SRSRAN_ERROR; + } + if (args.phy.nof_nr_carriers > 0) { + if (lte_phy->init(phy_args_nr, lte_stack.get(), lte_radio.get())) { + srsran::console("Error initializing NR PHY.\n"); + ret = SRSRAN_ERROR; + } + } + if (lte_stack->init(args.stack, lte_phy.get(), lte_phy.get(), gw_ptr.get())) { + srsran::console("Error initializing stack.\n"); + ret = SRSRAN_ERROR; + } + phy = std::move(lte_phy); } if (gw_ptr->init(args.gw, lte_stack.get())) { @@ -125,7 +164,6 @@ int ue::init(const all_args_t& args_) // move ownership stack = std::move(lte_stack); gw_inst = std::move(gw_ptr); - phy = std::move(lte_phy); radio = std::move(lte_radio); if (phy) { @@ -133,7 +171,6 @@ int ue::init(const all_args_t& args_) phy->wait_initialize(); srsran::console("done!\n"); } - return ret; } @@ -240,8 +277,51 @@ int ue::parse_args(const all_args_t& args_) args.stack.rrc.ue_category = (uint32_t)strtoul(args.stack.rrc.ue_category_str.c_str(), nullptr, 10); // Consider Carrier Aggregation support if more than one + args.stack.rrc.nof_lte_carriers = args.phy.nof_lte_carriers; + args.stack.rrc.nof_nr_carriers = args.phy.nof_nr_carriers; args.stack.rrc.support_ca = (args.phy.nof_lte_carriers > 1); + // Make sure fix sampling rate is set for SA mode + if (args.phy.nof_lte_carriers == 0 and not std::isnormal(args.rf.srate_hz)) { + srsran::console("Error. NR Standalone PHY requires a fixed RF sampling rate.\n"); + return SRSRAN_ERROR; + } + + // SA params + if (args.phy.nof_lte_carriers == 0 && args.phy.nof_nr_carriers > 0) { + // Update NAS-5G args + args.stack.nas_5g.ia5g = args.stack.nas.eia; + args.stack.nas_5g.ea5g = args.stack.nas.eea; + args.stack.nas_5g.pdu_session_cfgs.push_back({args.stack.nas.apn_name}); + } + + // Validate the CFR args + srsran_cfr_cfg_t cfr_test_cfg = {}; + cfr_test_cfg.cfr_enable = args.phy.cfr_args.enable; + cfr_test_cfg.cfr_mode = args.phy.cfr_args.mode; + cfr_test_cfg.alpha = args.phy.cfr_args.strength; + cfr_test_cfg.manual_thr = args.phy.cfr_args.manual_thres; + cfr_test_cfg.max_papr_db = args.phy.cfr_args.auto_target_papr; + cfr_test_cfg.ema_alpha = args.phy.cfr_args.ema_alpha; + + if (!srsran_cfr_params_valid(&cfr_test_cfg)) { + srsran::console("Invalid CFR parameters: cfr_mode=%d, alpha=%.2f, manual_thr=%.2f, \n " + "max_papr_db=%.2f, ema_alpha=%.2f\n", + cfr_test_cfg.cfr_mode, + cfr_test_cfg.alpha, + cfr_test_cfg.manual_thr, + cfr_test_cfg.max_papr_db, + cfr_test_cfg.ema_alpha); + + logger.error("Invalid CFR parameters: cfr_mode=%d, alpha=%.2f, manual_thr=%.2f, max_papr_db=%.2f, ema_alpha=%.2f\n", + cfr_test_cfg.cfr_mode, + cfr_test_cfg.alpha, + cfr_test_cfg.manual_thr, + cfr_test_cfg.max_papr_db, + cfr_test_cfg.ema_alpha); + return SRSRAN_ERROR; + } + return SRSRAN_SUCCESS; } @@ -304,7 +384,7 @@ void ue::start_plot() bool ue::get_metrics(ue_metrics_t* m) { - bzero(m, sizeof(ue_metrics_t)); + *m = {}; phy->get_metrics(srsran::srsran_rat_t::lte, &m->phy); phy->get_metrics(srsran::srsran_rat_t::nr, &m->phy_nr); radio->get_metrics(&m->rf); diff --git a/srsue/ue.conf.example b/srsue/ue.conf.example index 67ad686347..bdd115efb4 100644 --- a/srsue/ue.conf.example +++ b/srsue/ue.conf.example @@ -6,18 +6,19 @@ # RF configuration # # freq_offset: Uplink and Downlink optional frequency offset (in Hz) -# tx_gain: Transmit gain (dB). +# tx_gain: Transmit gain (dB). # rx_gain: Optional receive gain (dB). If disabled, AGC if enabled +# srate: Optional fixed sampling rate (Hz), corresponding to cell bandwidth. Must be set for 5G-SA. # # nof_antennas: Number of antennas per carrier (all carriers have the same number of antennas) -# device_name: Device driver family. Supported options: "auto" (uses first found), "UHD" or "bladeRF" -# device_args: Arguments for the device driver. Options are "auto" or any string. +# device_name: Device driver family. Supported options: "auto" (uses first found), "UHD" or "bladeRF" +# device_args: Arguments for the device driver. Options are "auto" or any string. # Default for UHD: "recv_frame_size=9232,send_frame_size=9232" # Default for bladeRF: "" # device_args_2: Arguments for the RF device driver 2. # device_args_3: Arguments for the RF device driver 3. # time_adv_nsamples: Transmission time advance (in number of samples) to compensate for RF delay -# from antenna to timestamp insertion. +# from antenna to timestamp insertion. # Default "auto". B210 USRP: 100 samples, bladeRF: 27. # continuous_tx: Transmit samples continuously to the radio or on bursts (auto/yes/no). # Default is auto (yes for UHD, no for rest) @@ -26,6 +27,7 @@ freq_offset = 0 tx_gain = 80 #rx_gain = 40 +#srate = 11.52e6 #nof_antennas = 1 @@ -45,10 +47,10 @@ tx_gain = 80 ##################################################################### # EUTRA RAT configuration -# +# # dl_earfcn: Downlink EARFCN list. # -# Optional parameters: +# Optional parameters: # dl_freq: Override DL frequency corresponding to dl_earfcn # ul_freq: Override UL frequency corresponding to dl_earfcn # nof_carriers: Number of carriers @@ -59,8 +61,8 @@ dl_earfcn = 3350 ##################################################################### # NR RAT configuration -# -# Optional parameters: +# +# Optional parameters: # bands: List of support NR bands seperated by a comma (default 78) # nof_carriers: Number of NR carriers (must be at least 1 for NR support) ##################################################################### @@ -71,19 +73,19 @@ dl_earfcn = 3350 ##################################################################### # Packet capture configuration # -# Packet capture is supported at the MAC, MAC_NR, and NAS layer. -# MAC-layer packets are captured to file a the compact format decoded -# by the Wireshark. For decoding, use the UDP dissector and the UDP -# heuristic dissection. Edit the preferences (Edit > Preferences > -# Protocols > DLT_USER) for DLT_USER to add an entry for DLT=149 with +# Packet capture is supported at the MAC, MAC_NR, and NAS layer. +# MAC-layer packets are captured to file a the compact format decoded +# by the Wireshark. For decoding, use the UDP dissector and the UDP +# heuristic dissection. Edit the preferences (Edit > Preferences > +# Protocols > DLT_USER) for DLT_USER to add an entry for DLT=149 with # Protocol=udp. Further, enable the heuristic dissection in UDP under: # Analyze > Enabled Protocols > MAC-LTE > mac_lte_udp and MAC-NR > mac_nr_udp # For more information see: https://wiki.wireshark.org/MAC-LTE # Using the same filename for mac_filename and mac_nr_filename writes both -# MAC-LTE and MAC-NR to the same file allowing a better analysis. +# MAC-LTE and MAC-NR to the same file allowing a better analysis. # NAS-layer packets are dissected with DLT=148, and Protocol = nas-eps. # -# enable: Enable packet captures of layers (mac/mac_nr/nas/none) multiple option list +# enable: Enable packet captures of layers (mac/mac_nr/nas/none) multiple option list # mac_filename: File path to use for MAC packet capture # mac_nr_filename: File path to use for MAC NR packet capture # nas_filename: File path to use for NAS packet capture @@ -136,12 +138,12 @@ file_max_size = -1 ##################################################################### [usim] mode = soft -algo = xor -#opc = 63BFA50EE6523365FF14C1F45F88737D +algo = milenage +opc = 63BFA50EE6523365FF14C1F45F88737D k = 00112233445566778899aabbccddeeff -imsi = 001010123456789 +imsi = 001010123456780 imei = 353490069873319 -#reader = +#reader = #pin = 1234 ##################################################################### @@ -173,9 +175,9 @@ imei = 353490069873319 # pass: Password for CHAP authentication # force_imsi_attach: Whether to always perform an IMSI attach # eia: List of integrity algorithms included in UE capabilities -# Supported: 1 - Snow3G, 2 - AES +# Supported: 1 - Snow3G, 2 - AES, 3 - ZUC # eea: List of ciphering algorithms included in UE capabilities -# Supported: 0 - NULL, 1 - Snow3G, 2 - AES +# Supported: 0 - NULL, 1 - Snow3G, 2 - AES, 3 - ZUC ##################################################################### [nas] #apn = internetinternet @@ -183,8 +185,20 @@ imei = 353490069873319 #user = srsuser #pass = srspass #force_imsi_attach = false -#eia = 1,2 -#eea = 0,1,2 +#eia = 1,2,3 +#eea = 0,1,2,3 + +##################################################################### +# Slice configuration +# +# enable: Enable a specific slice +# nssai-sst: Specfic Slice Type +# nssai-sd: Slice diffentiator +##################################################################### +[slicing] +#enable = false +#nssai-sst = 1 +#nssai-sd = 1 ##################################################################### # GW configuration @@ -303,18 +317,18 @@ enable = false # # rx_gain_offset: RX Gain offset to add to rx_gain to calibrate RSRP readings # prach_gain: PRACH gain (dB). If defined, forces a gain for the tranmsission of PRACH only., -# Default is to use tx_gain in [rf] section. -# cqi_max: Upper bound on the maximum CQI to be reported. Default 15. +# Default is to use tx_gain in [rf] section. +# cqi_max: Upper bound on the maximum CQI to be reported. Default 15. # cqi_fixed: Fixes the reported CQI to a constant value. Default disabled. # snr_ema_coeff: Sets the SNR exponential moving average coefficient (Default 0.1) # snr_estim_alg: Sets the noise estimation algorithm. (Default refs) -# Options: pss: use difference between received and known pss signal, +# Options: pss: use difference between received and known pss signal, # refs: use difference between noise references and noiseless (after filtering) # empty: use empty subcarriers in the boarder of pss/sss signal # pdsch_max_its: Maximum number of turbo decoder iterations (Default 4) # pdsch_meas_evm: Measure PDSCH EVM, increases CPU load (default false) # nof_phy_threads: Selects the number of PHY threads (maximum 4, minimum 1, default 3) -# equalizer_mode: Selects equalizer mode. Valid modes are: "mmse", "zf" or any +# equalizer_mode: Selects equalizer mode. Valid modes are: "mmse", "zf" or any # non-negative real number to indicate a regularized zf coefficient. # Default is MMSE. # correct_sync_error: Channel estimator measures and pre-compensates time synchronization error. Increases CPU usage, @@ -322,7 +336,7 @@ enable = false # sfo_ema: EMA coefficient to average sample offsets used to compute SFO # sfo_correct_period: Period in ms to correct sample time to adjust for SFO # sss_algorithm: Selects the SSS estimation algorithm. Can choose between -# {full, partial, diff}. +# {full, partial, diff}. # estimator_fil_auto: The channel estimator smooths the channel estimate with an adaptative filter. # estimator_fil_stddev: Sets the channel estimator smooth gaussian filter standard deviation. # estimator_fil_order: Sets the channel estimator smooth gaussian filter order (even values perform better). @@ -343,6 +357,9 @@ enable = false # nof_in_sync_events: Number of PHY in-sync events before sending an in-sync event to RRC # nof_out_of_sync_events: Number of PHY out-sync events before sending an out-sync event to RRC # +# force_N_id_2: Force using a specific PSS (set to -1 to allow all PSSs). +# force_N_id_1: Force using a specific SSS (set to -1 to allow all SSSs). +# ##################################################################### [phy] #rx_gain_offset = 62 @@ -374,6 +391,9 @@ enable = false #nof_in_sync_events = 10 #nof_out_of_sync_events = 20 +#force_N_id_2 = 1 +#force_N_id_1 = 10 + ##################################################################### # PHY NR specific configuration options # @@ -383,6 +403,33 @@ enable = false [phy.nr] #store_pdsch_ko = false +##################################################################### +# CFR configuration options +# +# The CFR module provides crest factor reduction for the transmitted signal. +# +# enable: Enable or disable the CFR. Default: disabled +# +# mode: manual: CFR threshold is set by cfr_manual_thres (default). +# auto_ema: CFR threshold is adaptive based on the signal PAPR. Power avg. with Exponential Moving Average. +# The time constant of the averaging can be tweaked with the ema_alpha parameter. +# auto_cma: CFR threshold is adaptive based on the signal PAPR. Power avg. with Cumulative Moving Average. +# Use with care, as CMA's increasingly slow response may be unsuitable for most use cases. +# +# strength: Ratio between amplitude-limited vs unprocessed signal (0 to 1). Default: 1 +# manual_thres: Fixed manual clipping threshold for CFR manual mode. Default: 2 +# auto_target_papr: Signal PAPR target (in dB) in CFR auto modes. output PAPR can be higher due to peak smoothing. Default: 7 +# ema_alpha: Alpha coefficient for the power average in auto_ema mode. Default: 1/7 +# +##################################################################### +[cfr] +#enable = false +#mode = manual +#manual_thres = 2.0 +#strength = 1.0 +#auto_target_papr = 7.0 +#ema_alpha = 0.0143 + ##################################################################### # Simulation configuration options # diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7ee3b05b00..5cdcdd14d0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # diff --git a/test/phy/CMakeLists.txt b/test/phy/CMakeLists.txt index 4869d31b25..a195d24650 100644 --- a/test/phy/CMakeLists.txt +++ b/test/phy/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN # @@ -40,6 +40,7 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) target_link_libraries(nr_phy_test srsue_phy srsran_common + rrc_nr_asn1 srsran_phy srsran_radio srsenb_phy diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index f5f0abfa92..a487d51166 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,11 +24,11 @@ #include "dummy_rx_harq_proc.h" #include "dummy_tx_harq_proc.h" -#include "srsenb/hdr/stack/mac/nr/mac_nr.h" -#include "srsenb/hdr/stack/mac/nr/sched_nr.h" -#include "srsenb/test/common/dummy_classes_nr.h" #include "srsenb/test/common/rlc_test_dummy.h" -#include "srsenb/test/mac/nr/sched_nr_cfg_generators.h" +#include "srsgnb/hdr/stack/common/test/dummy_nr_classes.h" +#include "srsgnb/hdr/stack/mac/mac_nr.h" +#include "srsgnb/hdr/stack/mac/sched_nr.h" +#include "srsgnb/src/stack/mac/test/sched_nr_cfg_generators.h" #include "srsran/srslog/srslog.h" #include #include @@ -96,7 +96,9 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr srsenb::rlc_dummy rlc_obj; std::unique_ptr mac; srslog::basic_logger& sched_logger; - bool autofill_sch_bsr = false; + bool autofill_sch_bsr = false; + bool wait_preamble = false; + std::atomic enable_user_sched = {false}; std::mutex metrics_mutex; metrics_t metrics = {}; @@ -175,7 +177,8 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr bool schedule_pdsch(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) { - if (dl.slots.count(SRSRAN_SLOT_NR_MOD(srsran_subcarrier_spacing_15kHz, slot_cfg.idx)) == 0) { + if (dl.slots.count(SRSRAN_SLOT_NR_MOD(srsran_subcarrier_spacing_15kHz, slot_cfg.idx)) == 0 or + not enable_user_sched) { return true; } @@ -250,7 +253,8 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr bool schedule_pusch(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) { - if (ul.slots.count(SRSRAN_SLOT_NR_MOD(srsran_subcarrier_spacing_15kHz, slot_cfg.idx + 4)) == 0) { + if (ul.slots.count(SRSRAN_SLOT_NR_MOD(srsran_subcarrier_spacing_15kHz, slot_cfg.idx + 4)) == 0 or + not enable_user_sched) { return true; } @@ -362,7 +366,8 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr phy_cfg(args.phy_cfg), ss_id(args.ss_id), use_dummy_mac(args.use_dummy_mac == "dummymac"), - sched_logger(srslog::fetch_basic_logger("MAC")) + sched_logger(srslog::fetch_basic_logger("MAC")), + wait_preamble(args.wait_preamble) { logger.set_level(srslog::str_to_basic_level(args.log_level)); sched_logger.set_level(srslog::str_to_basic_level(args.log_level)); @@ -378,17 +383,9 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr mac_args.sched_cfg.fixed_dl_mcs = args.pdsch.mcs; mac_args.sched_cfg.fixed_ul_mcs = args.pusch.mcs; mac->init(mac_args, nullptr, nullptr, &rlc_obj, &rrc_obj); - std::vector cells_cfg = srsenb::get_default_cells_cfg(1, phy_cfg); + std::vector cells_cfg = srsenb::get_default_cells_cfg(1, phy_cfg); mac->cell_cfg(cells_cfg); - // add UE to scheduler - if (not use_dummy_mac and not args.wait_preamble) { - srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg); - ue_cfg.ue_bearers[4].direction = srsenb::mac_lc_ch_cfg_t::BOTH; - - mac->reserve_rnti(0, ue_cfg); - } - dl.mcs = args.pdsch.mcs; ul.mcs = args.pusch.mcs; @@ -463,11 +460,33 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr ~gnb_dummy_stack() = default; + void stop() + { + if (not use_dummy_mac) { + mac->stop(); + } + } + bool is_valid() const { return valid; } + void start_scheduling() + { + // add UE to scheduler + if (not use_dummy_mac and not wait_preamble) { + srsenb::sched_nr_ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg); + ue_cfg.lc_ch_to_add.emplace_back(); + ue_cfg.lc_ch_to_add.back().lcid = 4; + ue_cfg.lc_ch_to_add.back().cfg.direction = srsenb::mac_lc_ch_cfg_t::BOTH; + + mac->reserve_rnti(0, ue_cfg); + } + + enable_user_sched = true; + } + int slot_indication(const srsran_slot_cfg_t& slot_cfg) override { return 0; } - int get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) override + dl_sched_t* get_dl_sched(const srsran_slot_cfg_t& slot_cfg) override { logger.set_context(slot_cfg.idx); sched_logger.set_context(slot_cfg.idx); @@ -478,36 +497,60 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr mac->ul_bsr(rnti, 0, 100000); } - int ret = mac->get_dl_sched(slot_cfg, dl_sched); + dl_sched_t* dl_res = mac->get_dl_sched(slot_cfg); + if (dl_res == nullptr) { + return nullptr; + } - for (pdsch_t& pdsch : dl_sched.pdsch) { + for (pdsch_t& pdsch : dl_res->pdsch) { // Set TBS // Select grant and set data pdsch.data[0] = tx_harq_proc[slot_cfg.idx].get_tb(pdsch.sch.grant.tb[0].tbs); pdsch.data[1] = nullptr; } - return ret; + return dl_res; } + dl_sched_t& dl_sched = dl_scheds[slot_cfg.idx]; + dl_sched = {}; // Check if it is TDD DL slot and PDSCH mask, if no PDSCH shall be scheduled, do not set any grant and skip if (not srsran_duplex_nr_is_dl(&phy_cfg.duplex, phy_cfg.carrier.scs, slot_cfg.idx)) { - return SRSRAN_SUCCESS; + return nullptr; } if (not schedule_pdsch(slot_cfg, dl_sched)) { logger.error("Error scheduling PDSCH"); - return SRSRAN_ERROR; + return nullptr; + } + + // Schedule SSB before UL + for (uint32_t ssb_idx = 0; ssb_idx < SRSRAN_SSB_NOF_CANDIDATES; ssb_idx++) { + if (phy_cfg.ssb.position_in_burst[ssb_idx]) { + srsran_mib_nr_t mib = {}; + mib.ssb_idx = ssb_idx; + mib.sfn = slot_cfg.idx / SRSRAN_NSLOTS_PER_FRAME_NR(phy_cfg.carrier.scs); + mib.hrf = (slot_cfg.idx % SRSRAN_NSLOTS_PER_FRAME_NR(phy_cfg.carrier.scs)) >= + SRSRAN_NSLOTS_PER_FRAME_NR(phy_cfg.carrier.scs) / 2; + + mac_interface_phy_nr::ssb_t ssb = {}; + if (srsran_pbch_msg_nr_mib_pack(&mib, &ssb.pbch_msg) < SRSRAN_SUCCESS) { + logger.error("Error Packing MIB in slot %d", slot_cfg.idx); + continue; + } + ssb.pbch_msg.ssb_idx = (uint32_t)ssb_idx; + dl_sched.ssb.push_back(ssb); + } } // Check if the UL slot is valid, if not skip UL scheduling if (not srsran_duplex_nr_is_ul(&phy_cfg.duplex, phy_cfg.carrier.scs, TTI_TX(slot_cfg.idx))) { - return SRSRAN_SUCCESS; + return &dl_sched; } if (not schedule_pusch(slot_cfg, dl_sched)) { logger.error("Error scheduling PUSCH"); - return SRSRAN_ERROR; + return nullptr; } // Schedule NZP-CSI-RS, iterate all NZP-CSI-RS sets @@ -524,38 +567,21 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr } } - // Schedule SSB - for (uint32_t ssb_idx = 0; ssb_idx < SRSRAN_SSB_NOF_CANDIDATES; ssb_idx++) { - if (phy_cfg.ssb.position_in_burst[ssb_idx]) { - srsran_mib_nr_t mib = {}; - mib.ssb_idx = ssb_idx; - mib.sfn = slot_cfg.idx / SRSRAN_NSLOTS_PER_FRAME_NR(phy_cfg.carrier.scs); - mib.hrf = (slot_cfg.idx % SRSRAN_NSLOTS_PER_FRAME_NR(phy_cfg.carrier.scs)) >= - SRSRAN_NSLOTS_PER_FRAME_NR(phy_cfg.carrier.scs) / 2; - - mac_interface_phy_nr::ssb_t ssb = {}; - if (srsran_pbch_msg_nr_mib_pack(&mib, &ssb.pbch_msg) < SRSRAN_SUCCESS) { - logger.error("Error Packing MIB in slot %d", slot_cfg.idx); - continue; - } - ssb.pbch_msg.ssb_idx = (uint32_t)ssb_idx; - dl_sched.ssb.push_back(ssb); - } - } - - return SRSRAN_SUCCESS; + return &dl_sched; } - int get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) override + ul_sched_t* get_ul_sched(const srsran_slot_cfg_t& slot_cfg) override { logger.set_context(slot_cfg.idx); sched_logger.set_context(slot_cfg.idx); if (not use_dummy_mac) { - int ret = mac->get_ul_sched(slot_cfg, ul_sched); - - return ret; + ul_sched_t* ul_res = mac->get_ul_sched(slot_cfg); + return ul_res; } + ul_sched_t& ul_sched = ul_scheds[slot_cfg.idx]; + ul_sched.pucch.clear(); + ul_sched.pusch.clear(); // Get ACK information srsran_pdsch_ack_nr_t ack = pending_ack[slot_cfg.idx % pending_ack.size()].get_ack(); @@ -575,7 +601,7 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr srsran_uci_cfg_nr_t uci_cfg = {}; if (not phy_cfg.get_uci_cfg(slot_cfg, ack, uci_cfg)) { logger.error("Error getting UCI configuration"); - return SRSRAN_ERROR; + return nullptr; } // Schedule PUSCH @@ -586,15 +612,12 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr // Put UCI configuration in PUSCH config if (not phy_cfg.get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { logger.error("Error setting UCI configuration in PUSCH"); - return SRSRAN_ERROR; + return nullptr; } ul_sched.pusch.push_back(pusch); - return SRSRAN_SUCCESS; - } - - // If any UCI information is triggered, schedule PUCCH - if (uci_cfg.ack.count > 0 || uci_cfg.nof_csi > 0 || uci_cfg.o_sr > 0) { + } else if ((uci_cfg.ack.count > 0 || uci_cfg.nof_csi > 0 || uci_cfg.o_sr > 0) and enable_user_sched) { + // If any UCI information is triggered, schedule PUCCH ul_sched.pucch.emplace_back(); uci_cfg.pucch.rnti = rnti; @@ -604,7 +627,7 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr pucch.candidates.back().uci_cfg = uci_cfg; if (not phy_cfg.get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { logger.error("Error getting UCI CFG"); - return SRSRAN_ERROR; + return nullptr; } // If this slot has a SR opportunity and the selected PUCCH format is 1, consider positive SR. @@ -620,15 +643,12 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr pucch.candidates.back().uci_cfg = uci_cfg; if (not phy_cfg.get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { logger.error("Error getting UCI CFG"); - return SRSRAN_ERROR; + return nullptr; } } - - return SRSRAN_SUCCESS; } - // Otherwise no UL scheduling - return SRSRAN_SUCCESS; + return &ul_sched; } int pucch_info(const srsran_slot_cfg_t& slot_cfg, const pucch_info_t& pucch_info) override @@ -730,6 +750,10 @@ class gnb_dummy_stack : public srsenb::stack_interface_phy_nr } return metrics; } + +private: + srsran::circular_array dl_scheds; + srsran::circular_array ul_scheds; }; #endif // SRSRAN_DUMMY_GNB_STACK_H diff --git a/test/phy/dummy_phy_common.h b/test/phy/dummy_phy_common.h index f14aff03a1..8b3fdcf43d 100644 --- a/test/phy/dummy_phy_common.h +++ b/test/phy/dummy_phy_common.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -155,9 +155,7 @@ class phy_common : public srsran::phy_common_interface uint32_t nof_channels = 1; args_t(double srate_hz_, uint32_t buffer_sz_ms_, uint32_t nof_channels_) : - srate_hz(srate_hz_), - buffer_sz_ms(buffer_sz_ms_), - nof_channels(nof_channels_) + srate_hz(srate_hz_), buffer_sz_ms(buffer_sz_ms_), nof_channels(nof_channels_) {} }; diff --git a/test/phy/dummy_rx_harq_proc.h b/test/phy/dummy_rx_harq_proc.h index cef536d645..d037c1b805 100644 --- a/test/phy/dummy_rx_harq_proc.h +++ b/test/phy/dummy_rx_harq_proc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/test/phy/dummy_tx_harq_proc.h b/test/phy/dummy_tx_harq_proc.h index 79b66e786c..56fc1cb8e8 100644 --- a/test/phy/dummy_tx_harq_proc.h +++ b/test/phy/dummy_tx_harq_proc.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * diff --git a/test/phy/dummy_ue_phy.h b/test/phy/dummy_ue_phy.h new file mode 100644 index 0000000000..23a5b20f8e --- /dev/null +++ b/test/phy/dummy_ue_phy.h @@ -0,0 +1,74 @@ +/** + * Copyright 2013-2023 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/. + * + */ + +#ifndef SRSRAN_DUMMY_UE_PHY_H +#define SRSRAN_DUMMY_UE_PHY_H + +#include "srsue/hdr/phy/nr/worker_pool.h" + +class ue_dummy_phy : public srsue::phy_interface_stack_nr +{ +public: + ue_dummy_phy(const char* logname, uint32_t max_workers) : + logger(srslog::fetch_basic_logger(logname)), workers(logger, max_workers) + {} + bool init(const srsue::phy_args_nr_t& args_, + srsran::phy_common_interface& common, + srsue::stack_interface_phy_nr* stack_, + int prio) + { + return workers.init(args_, common, stack_, prio); + } + void stop() { workers.stop(); } + srsue::nr::sf_worker* wait_worker(uint32_t tti) { return workers.wait_worker(tti); } + void start_worker(srsue::nr::sf_worker* w) { workers.start_worker(w); } + void get_metrics(srsue::phy_metrics_t& m) { return workers.get_metrics(m); } + + int set_rar_grant(uint32_t rar_slot_idx, + std::array packed_ul_grant, + uint16_t rnti, + srsran_rnti_type_t rnti_type) override + { + return workers.set_rar_grant(rar_slot_idx, packed_ul_grant, rnti, rnti_type); + } + void send_prach(const uint32_t prach_occasion, + const int preamble_index, + const float preamble_received_target_power, + const float ta_base_sec = 0.0f) override + {} + + bool has_valid_sr_resource(uint32_t sr_id) override { return workers.has_valid_sr_resource(sr_id); } + void clear_pending_grants() override { return workers.clear_pending_grants(); } + + bool set_config(const srsran::phy_cfg_nr_t& cfg) override { return workers.set_config(cfg); } + phy_nr_state_t get_state() override { return PHY_NR_STATE_IDLE; } + void reset_nr() override {} + + bool start_cell_search(const cell_search_args_t& req) override { return false; } + + bool start_cell_select(const cell_select_args_t& req) override { return false; } + +private: + srslog::basic_logger& logger; + srsue::nr::worker_pool workers; +}; + +#endif // SRSRAN_DUMMY_UE_PHY_H diff --git a/test/phy/dummy_ue_stack.h b/test/phy/dummy_ue_stack.h index 5b969e2377..8057a8267c 100644 --- a/test/phy/dummy_ue_stack.h +++ b/test/phy/dummy_ue_stack.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -22,7 +22,10 @@ #ifndef SRSRAN_DUMMY_UE_STACK_H #define SRSRAN_DUMMY_UE_STACK_H -#include +#include "dummy_rx_harq_proc.h" +#include "dummy_tx_harq_proc.h" +#include "srsran/asn1/rrc_nr.h" +#include "srsran/interfaces/ue_nr_interfaces.h" class ue_dummy_stack : public srsue::stack_interface_phy_nr { @@ -31,12 +34,34 @@ class ue_dummy_stack : public srsue::stack_interface_phy_nr uint32_t count; }; + struct cell_search_metrics_t { + // Last cell search result for the PCI and SSB candidate + srsue::stack_interface_phy_nr::cell_search_result_t last_result; + + // Signal Measurements + float epre_db_avg = 0.0f; + float epre_db_min = +INFINITY; + float epre_db_max = -INFINITY; + float rsrp_db_avg = 0.0f; + float rsrp_db_min = +INFINITY; + float rsrp_db_max = -INFINITY; + float snr_db_avg = 0.0f; + float snr_db_min = +INFINITY; + float snr_db_max = -INFINITY; + float cfo_hz_avg = 0.0f; + float cfo_hz_min = +INFINITY; + float cfo_hz_max = -INFINITY; + uint32_t count = 0; + }; + struct metrics_t { + std::map > cell_search; std::map prach = {}; ///< PRACH metrics indexed with premable index uint32_t sr_count = 0; ///< Counts number of transmitted SR }; private: + srslog::basic_logger& logger = srslog::fetch_basic_logger("UE-STCK"); std::mutex rnti_mutex; srsran_random_t random_gen = srsran_random_init(0x1323); srsran_rnti_type_t dl_rnti_type = srsran_rnti_type_c; @@ -50,25 +75,53 @@ class ue_dummy_stack : public srsue::stack_interface_phy_nr metrics_t metrics = {}; srsue::phy_interface_stack_nr& phy; + // Atributes to flag configuration PHy complete + bool configuration_complete = false; + std::mutex configuration_complete_mutex; + std::condition_variable configuration_complete_cvar; + + // Attributes for throttling PHY and avoiding PHY free-running + bool pending_tti = false; + std::mutex pending_tti_mutex; + std::condition_variable pending_tti_cvar; + std::atomic running = {true}; + dummy_tx_harq_entity tx_harq_proc; dummy_rx_harq_entity rx_harq_proc; + std::atomic cell_search_finished = {false}; + std::atomic cell_select_finished = {false}; + cell_select_result_t cell_select_result = {}; + public: struct args_t { - uint16_t rnti = 0x1234; ///< C-RNTI for PUSCH and PDSCH transmissions - uint32_t sr_period = 0; ///< Indicates positive SR period in number of opportunities. Set to 0 to disable. - uint32_t prach_period = 0; ///< Requests PHY to transmit PRACH periodically in frames. Set to 0 to disable. + uint16_t rnti = 0x1234; ///< C-RNTI for PUSCH and PDSCH transmissions + uint32_t sr_period = 0; ///< Indicates positive SR period in number of opportunities. Set to 0 to disable. + uint32_t prach_period = 0; ///< Requests PHY to transmit PRACH periodically in frames. Set to 0 to disable. + std::string log_level = "warning"; }; ue_dummy_stack(const args_t& args, srsue::phy_interface_stack_nr& phy_) : rnti(args.rnti), sr_period(args.sr_period), prach_period(args.prach_period), phy(phy_) { + logger.set_level(srslog::str_to_basic_level(args.log_level)); valid = true; } ~ue_dummy_stack() { srsran_random_free(random_gen); } + void in_sync() override {} void out_of_sync() override {} - void run_tti(const uint32_t tti) override + void run_tti(const uint32_t tti, const uint32_t tti_jump) override { + // Wait for tick from test bench + std::unique_lock lock(pending_tti_mutex); + while (not pending_tti and running) { + pending_tti_cvar.wait_for(lock, std::chrono::milliseconds(1)); + } + + // Let the tick proceed + pending_tti = false; + pending_tti_cvar.notify_all(); + // Run PRACH if (prach_period != 0) { uint32_t slot_idx = tti % SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz); @@ -80,7 +133,24 @@ class ue_dummy_stack : public srsue::stack_interface_phy_nr } } } - int sf_indication(const uint32_t tti) override { return 0; } + void tick() + { + // Wait for TTI to get processed + std::unique_lock lock(pending_tti_mutex); + while (pending_tti and running) { + pending_tti_cvar.wait_for(lock, std::chrono::milliseconds(1)); + } + + // Let the TTI proceed + pending_tti = true; + pending_tti_cvar.notify_all(); + } + + void stop() + { + running = false; + pending_tti_cvar.notify_all(); + } sched_rnti_t get_dl_sched_rnti_nr(const uint32_t tti) override { std::unique_lock lock(rnti_mutex); @@ -131,11 +201,113 @@ class ue_dummy_stack : public srsue::stack_interface_phy_nr } bool is_valid() const { return valid; } - metrics_t get_metrics() { return metrics; } + const metrics_t& get_metrics() const { return metrics; } + void reset_metrics() + { + metrics.cell_search.clear(); + metrics.prach.clear(); + metrics.sr_count = 0; + } void set_phy_config_complete(bool status) override { + std::unique_lock lock(configuration_complete_mutex); + configuration_complete = true; + configuration_complete_cvar.notify_all(); + } + + void wait_phy_config_complete() + { + std::unique_lock lock(configuration_complete_mutex); + while (not configuration_complete) { + configuration_complete_cvar.wait(lock); + } + configuration_complete = false; + } + + bool get_cell_search_finished() + { + bool ret = cell_search_finished; + cell_search_finished = false; + + return ret; + } + + void cell_search_found_cell(const cell_search_result_t& result) override + { + if (not result.cell_found) { + logger.info("Cell search finished without detecting any cell"); + + // Flag as cell search is done + cell_search_finished = true; + + return; + } + + // Pack PBCH message bits + std::array bit_pack_pbch_msg = {}; + asn1::cbit_ref cbit(bit_pack_pbch_msg.data(), bit_pack_pbch_msg.size()); + srsran_bit_pack_vector((uint8_t*)result.pbch_msg.payload, bit_pack_pbch_msg.data(), SRSRAN_PBCH_MSG_NR_SZ); + + // Unpack MIB with ASN1 + asn1::rrc_nr::bcch_bch_msg_s bcch; + bcch.unpack(cbit); + + // Convert MIB to JSON + asn1::json_writer json; + bcch.to_json(json); + + // Unpack MIB with C lib + srsran_mib_nr_t mib_c = {}; + srsran_pbch_msg_nr_mib_unpack(&result.pbch_msg, &mib_c); + + // Convert MIB from C lib to info + std::array mib_info = {}; + srsran_pbch_msg_nr_mib_info(&mib_c, mib_info.data(), (uint32_t)mib_info.size()); + + // Convert CSI to string + std::array csi_info = {}; + srsran_csi_meas_info_short(&result.measurements, csi_info.data(), (uint32_t)csi_info.size()); + + logger.info( + "Cell found pci=%d %s %s ASN1: %s", result.pci, mib_info.data(), csi_info.data(), json.to_string().c_str()); + + cell_search_metrics_t& m = metrics.cell_search[result.pci][result.pbch_msg.ssb_idx]; + m.last_result = result; + m.epre_db_min = SRSRAN_MIN(m.epre_db_min, result.measurements.epre_dB); + m.epre_db_max = SRSRAN_MAX(m.epre_db_max, result.measurements.epre_dB); + m.epre_db_avg = SRSRAN_VEC_SAFE_CMA(result.measurements.epre_dB, m.epre_db_avg, m.count); + m.rsrp_db_min = SRSRAN_MIN(m.rsrp_db_min, result.measurements.rsrp_dB); + m.rsrp_db_max = SRSRAN_MAX(m.rsrp_db_max, result.measurements.rsrp_dB); + m.rsrp_db_avg = SRSRAN_VEC_SAFE_CMA(result.measurements.rsrp_dB, m.rsrp_db_avg, m.count); + m.snr_db_min = SRSRAN_MIN(m.snr_db_min, result.measurements.snr_dB); + m.snr_db_max = SRSRAN_MAX(m.snr_db_max, result.measurements.snr_dB); + m.snr_db_avg = SRSRAN_VEC_SAFE_CMA(result.measurements.snr_dB, m.snr_db_avg, m.count); + m.cfo_hz_min = SRSRAN_MIN(m.cfo_hz_min, result.measurements.cfo_hz); + m.cfo_hz_max = SRSRAN_MAX(m.cfo_hz_max, result.measurements.cfo_hz); + m.cfo_hz_avg = SRSRAN_VEC_SAFE_CMA(result.measurements.cfo_hz, m.cfo_hz_avg, m.count); + m.count++; + + // Flag as cell search is done + cell_search_finished = true; + } + + bool get_cell_select_finished() + { + bool ret = cell_select_finished; + + cell_select_finished = false; + + return ret; + } + + cell_select_result_t get_cell_select_result() { return cell_select_result; } + + void cell_select_completed(const cell_select_result_t& result) override + { + cell_select_result = result; + cell_select_finished = true; } }; diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index 49f03750ec..950a1adbe7 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -41,13 +41,17 @@ static double assert_pucch_snr_min = 0.000; test_bench::args_t::args_t(int argc, char** argv) { - std::string reference_cfg_str = ""; - bpo::options_description options("Test bench options"); + std::string config_file; + std::string reference_cfg_str; + bpo::options_description options; + bpo::options_description options_tb("Test bench options"); bpo::options_description options_gnb_stack("gNb stack and scheduling related options"); bpo::options_description options_gnb_phy("gNb PHY related options"); bpo::options_description options_ue_stack("UE stack options"); - bpo::options_description options_ue_phy("UE stack options"); + bpo::options_description options_ue_phy("UE PHY options"); + bpo::options_description options_ue_rf("UE RF options"); bpo::options_description options_assertion("Test assertions"); + bpo::options_description options_conf_file("Configuration file"); uint16_t rnti = 17921; @@ -55,10 +59,10 @@ test_bench::args_t::args_t(int argc, char** argv) gnb_stack.pusch.slots = "6,7,8,9"; // clang-format off - options.add_options() + options_tb.add_options() ("rnti", bpo::value(&rnti)->default_value(rnti), "UE RNTI") ("duration", bpo::value(&durations_slots)->default_value(durations_slots), "Test duration in slots") - ("lib.log.level", bpo::value(&phy_lib_log_level)->default_value(phy_lib_log_level), "PHY librray log level") + ("lib.log.level", bpo::value(&phy_lib_log_level)->default_value(phy_lib_log_level), "PHY library log level") ("reference", bpo::value(&reference_cfg_str)->default_value(reference_cfg_str), "Reference PHY configuration arguments") ("dl_channel.awgn_enable", bpo::value(&dl_channel.awgn_enable)->default_value(dl_channel.awgn_enable), "DL Channel AWGN enable / disable") ("dl_channel.awgn_snr", bpo::value(&dl_channel.awgn_snr_dB)->default_value(dl_channel.awgn_snr_dB), "DL Channel AWGN SNR in dB") @@ -93,10 +97,15 @@ test_bench::args_t::args_t(int argc, char** argv) ; options_ue_phy.add_options() - ("ue.phy.nof_threads", bpo::value(&ue_phy.nof_phy_threads)->default_value(1), "Number of threads") - ("ue.phy.log.level", bpo::value(&ue_phy.log.phy_level)->default_value("warning"), "UE PHY log level") - ("ue.phy.log.hex_limit", bpo::value(&ue_phy.log.phy_hex_limit)->default_value(0), "UE PHY log hex limit") - ("ue.phy.log.id_preamble", bpo::value(&ue_phy.log.id_preamble)->default_value(" UE/"), "UE PHY log ID preamble") + ("ue.phy.fix_wideband_cqi", bpo::value(&ue_phy.fix_wideband_cqi)->default_value(15), "Fix wideband CQI value, set to 0 or greater than 15 to disable") + ("ue.phy.nof_threads", bpo::value(&ue_phy.nof_phy_threads)->default_value(1), "Number of threads") + ("ue.phy.log.level", bpo::value(&ue_phy.log.phy_level)->default_value("warning"), "UE PHY log level") + ("ue.phy.log.hex_limit", bpo::value(&ue_phy.log.phy_hex_limit)->default_value(0), "UE PHY log hex limit") + ("ue.phy.log.id_preamble", bpo::value(&ue_phy.log.id_preamble)->default_value(" UE/"), "UE PHY log ID preamble") + ; + + options_ue_rf.add_options() + ("ue.rf.log.level", bpo::value(&ue_radio_log_level)->default_value("warning"), "UE RF log level") ; options_ue_stack.add_options() @@ -114,14 +123,21 @@ test_bench::args_t::args_t(int argc, char** argv) ("assert.pucch.snr.min", bpo::value(&assert_pucch_snr_min)->default_value(assert_pucch_snr_min), "PUCCH DMRS minimum SNR allowed threshold") ; - options.add(options_gnb_stack).add(options_gnb_phy).add(options_ue_stack).add(options_ue_phy).add_options() + options_conf_file.add_options() + ("config_file", bpo::value(&config_file), "Configuration file") + ; + bpo::positional_options_description p; + p.add("config_file", -1); + + options.add(options_tb).add(options_assertion).add(options_gnb_stack).add(options_gnb_phy).add(options_ue_stack) + .add(options_ue_phy).add(options_ue_rf).add(options_conf_file).add_options() ("help", "Show this message") ; // clang-format on bpo::variables_map vm; try { - bpo::store(bpo::command_line_parser(argc, argv).options(options).run(), vm); + bpo::store(bpo::command_line_parser(argc, argv).options(options).positional(p).run(), vm); bpo::notify(vm); // Apply the High Speed Train args to the DL channel as well @@ -136,14 +152,35 @@ test_bench::args_t::args_t(int argc, char** argv) // help option was given or error - print usage and exit if (vm.count("help")) { std::cout << "Usage: " << argv[0] << " [OPTIONS] config_file" << std::endl << std::endl; - std::cout << options << std::endl << std::endl; - return; + std::cout << options_tb << std::endl << options_assertion << std::endl; + std::cout << options_gnb_phy << std::endl << options_gnb_stack << std::endl; + std::cout << options_ue_phy << std::endl << options_ue_stack << std::endl; + exit(0); + } + + // if config file given + if (vm.count("config_file") != 0U) { + std::cout << "Reading configuration file " << config_file << "..." << std::endl; + std::ifstream conf(config_file.c_str(), std::ios::in); + if (conf.fail()) { + std::cout << "Failed to read configuration file " << config_file << " - exiting" << std::endl; + exit(1); + } + + // parse config file and handle errors gracefully + try { + bpo::store(bpo::parse_config_file(conf, options), vm); + bpo::notify(vm); + } catch (const boost::program_options::error& e) { + std::cerr << e.what() << std::endl; + exit(1); + } } // Load default reference configuration phy_cfg = srsran::phy_cfg_nr_default_t(srsran::phy_cfg_nr_default_t::reference_cfg_t(reference_cfg_str)); - // Calulate the DL signal power from the number of PRBs + // Calculate the DL signal power from the number of PRBs dl_channel.awgn_signal_power_dBfs = srsran_gnb_dl_get_maximum_signal_power_dBfs(phy_cfg.carrier.nof_prb); // Reverses the Doppler shift for the UL @@ -151,12 +188,12 @@ test_bench::args_t::args_t(int argc, char** argv) // Calculate sampling rate in Hz srate_hz = (double)(srsran_min_symbol_sz_rb(phy_cfg.carrier.nof_prb) * SRSRAN_SUBC_SPACING_NR(phy_cfg.carrier.scs)); + ue_phy.srate_hz = srate_hz; cell_list.resize(1); cell_list[0].carrier = phy_cfg.carrier; cell_list[0].rf_port = 0; cell_list[0].cell_id = 0; - cell_list[0].pdcch = phy_cfg.pdcch; ue_stack.rnti = rnti; @@ -174,6 +211,10 @@ test_bench::args_t::args_t(int argc, char** argv) gnb_stack.pdsch.rb_start = 0; } + // Disable RT priority in the UE PHY + ue_phy.workers_thread_prio = -1; + ue_phy.slot_recv_thread_prio = -1; + // Flag configuration as valid valid = true; } @@ -194,6 +235,12 @@ int main(int argc, char** argv) // Assert bench is initialised correctly TESTASSERT(tb.is_initialised()); + // Start cell selection procedure + srsue::rrc_interface_phy_nr::cell_select_result_t cs_res = + tb.run_cell_select(args.phy_cfg.carrier, args.phy_cfg.get_ssb_cfg()); + srsran_assert(cs_res.status == srsue::rrc_interface_phy_nr::cell_select_result_t::SUCCESSFUL, + "Failed to perform cell selection"); + // Run per TTI basis while (tb.run_tti()) { ; // Do nothing @@ -274,7 +321,7 @@ int main(int argc, char** argv) "EPRE (dB)", metrics.gnb_stack.pucch.epre_db_avg, metrics.gnb_stack.pucch.epre_db_min, - metrics.gnb_stack.pucch.epre_db_min); + metrics.gnb_stack.pucch.epre_db_max); srsran::console(" | %10s | %+10.2f | %+10.2f | %+10.2f |\n", "RSRP (dB)", metrics.gnb_stack.pucch.rsrp_db_avg, @@ -341,7 +388,7 @@ int main(int argc, char** argv) "EPRE (dB)", metrics.gnb_stack.pusch.epre_db_avg, metrics.gnb_stack.pusch.epre_db_min, - metrics.gnb_stack.pusch.epre_db_min); + metrics.gnb_stack.pusch.epre_db_max); srsran::console(" | %10s | %+10.2f | %+10.2f | %+10.2f |\n", "RSRP (dB)", metrics.gnb_stack.pusch.rsrp_db_avg, diff --git a/test/phy/test_bench.h b/test/phy/test_bench.h index d381db19e0..e5df773b7e 100644 --- a/test/phy/test_bench.h +++ b/test/phy/test_bench.h @@ -1,5 +1,5 @@ /** - * Copyright 2013-2021 Software Radio Systems Limited + * Copyright 2013-2023 Software Radio Systems Limited * * This file is part of srsRAN. * @@ -24,7 +24,9 @@ #include "dummy_phy_common.h" #include "srsenb/hdr/phy/nr/worker_pool.h" +#include "srsran/radio/radio_dummy.h" #include "srsue/hdr/phy/nr/worker_pool.h" +#include "srsue/hdr/phy/phy_nr_sa.h" class test_bench { @@ -39,10 +41,13 @@ class test_bench srsenb::nr::worker_pool gnb_phy; phy_common gnb_phy_com; ue_dummy_stack ue_stack; - srsue::nr::worker_pool ue_phy; - phy_common ue_phy_com; - bool initialised = false; - uint32_t sf_sz = 0; + srsue::phy_nr_sa ue_phy; + srsran::radio_dummy ue_radio; + srsran::rf_timestamp_t gnb_rx_time = {}; + + bool initialised = false; + uint32_t sf_sz = 0; + srsran::rf_buffer_t rf_buffer; // Channel simulator srsran::channel dl_channel; srsran::channel ul_channel; @@ -59,9 +64,10 @@ class test_bench gnb_dummy_stack::args_t gnb_stack; srsue::phy_args_nr_t ue_phy; ue_dummy_stack::args_t ue_stack; - std::string phy_com_log_level = "info"; - std::string phy_lib_log_level = "none"; - uint64_t durations_slots = 100; + std::string gnb_phy_com_log_level = "info"; + std::string ue_radio_log_level = "info"; + std::string phy_lib_log_level = "none"; + uint64_t durations_slots = 100; // channel simulator args srsran::channel::args_t dl_channel; @@ -79,19 +85,18 @@ class test_bench gnb_stack(args.gnb_stack), gnb_phy(gnb_phy_com, gnb_stack, srslog::get_default_sink(), args.gnb_phy.nof_phy_threads), ue_stack(args.ue_stack, ue_phy), - ue_phy(args.ue_phy.nof_phy_threads), - - ue_phy_com(phy_common::args_t(args.srate_hz, args.buffer_sz_ms, args.nof_channels), - srslog::fetch_basic_logger(UE_PHY_COM_LOG_NAME, srslog::get_default_sink(), false)), + ue_phy("PHY"), + ue_radio(), gnb_phy_com(phy_common::args_t(args.srate_hz, args.buffer_sz_ms, args.nof_channels), srslog::fetch_basic_logger(GNB_PHY_COM_LOG_NAME, srslog::get_default_sink(), false)), sf_sz((uint32_t)std::round(args.srate_hz * 1e-3)), duration_slots(args.durations_slots), dl_channel(args.dl_channel, 1, srslog::fetch_basic_logger(CHANNEL_LOG_NAME, srslog::get_default_sink(), false)), - ul_channel(args.ul_channel, 1, srslog::fetch_basic_logger(CHANNEL_LOG_NAME, srslog::get_default_sink(), false)) + ul_channel(args.ul_channel, 1, srslog::fetch_basic_logger(CHANNEL_LOG_NAME, srslog::get_default_sink(), false)), + rf_buffer(1) { - srslog::fetch_basic_logger(UE_PHY_COM_LOG_NAME).set_level(srslog::str_to_basic_level(args.phy_com_log_level)); - srslog::fetch_basic_logger(GNB_PHY_COM_LOG_NAME).set_level(srslog::str_to_basic_level(args.phy_com_log_level)); + srslog::fetch_basic_logger(UE_PHY_COM_LOG_NAME).set_level(srslog::str_to_basic_level(args.gnb_phy_com_log_level)); + srslog::fetch_basic_logger(GNB_PHY_COM_LOG_NAME).set_level(srslog::str_to_basic_level(args.gnb_phy_com_log_level)); srslog::fetch_basic_logger(CHANNEL_LOG_NAME).set_level(srslog::basic_levels::error); if (not gnb_phy.init(args.gnb_phy, args.cell_list)) { @@ -109,16 +114,32 @@ class test_bench return; } + // Initialise radio + srsran::rf_args_t rf_args = {}; + rf_args.nof_antennas = 1; + rf_args.nof_carriers = 1; + rf_args.srate_hz = args.srate_hz; + rf_args.log_level = args.ue_radio_log_level; + if (ue_radio.init(rf_args, &ue_phy) != SRSRAN_SUCCESS) { + return; + } + // Initialise UE PHY - if (not ue_phy.init(args.ue_phy, ue_phy_com, &ue_stack, 31)) { + if (ue_phy.init(args.ue_phy, &ue_stack, &ue_radio) != SRSRAN_SUCCESS) { return; } + // Wait for PHY to initialise + ue_phy.wait_initialize(); + // Set UE configuration if (not ue_phy.set_config(args.phy_cfg)) { return; } + // Wait for UE to notify stack that the configuration is completed + ue_stack.wait_phy_config_complete(); + // Make sure PHY log is not set by UE or gNb PHY set_handler_enabled(false); if (args.phy_lib_log_level == "info") { @@ -135,17 +156,54 @@ class test_bench initialised = true; } + srsue::rrc_interface_phy_nr::cell_select_result_t run_cell_select(const srsran_carrier_nr_t& carrier, + const srsran_ssb_cfg_t& ssb_cfg) + { + // Prepare return value + srsue::rrc_interface_phy_nr::cell_select_result_t ret = {}; + + // Prepare cell selection arguments + srsue::phy_interface_rrc_nr::cell_select_args_t cs_args = {}; + cs_args.carrier = carrier; + cs_args.ssb_cfg = ssb_cfg; + + // Start cell selection procedure + if (not ue_phy.start_cell_select(cs_args)) { + // Return unsuccessful cell select result + return {}; + } + + // Run test bench until the cell selection is completed + while (not ue_stack.get_cell_select_finished()) { + run_tti(); + } + + // It is now the right time to start scheduling + gnb_stack.start_scheduling(); + + // Reset slot counting + slot_count = 0; + + return ue_stack.get_cell_select_result(); + } + void stop() { - ue_phy_com.stop(); + ue_stack.stop(); + ue_radio.stop(); gnb_phy_com.stop(); gnb_phy.stop(); ue_phy.stop(); + gnb_stack.stop(); } ~test_bench() = default; - bool is_initialised() const { return ue_stack.is_valid() and gnb_stack.is_valid() and initialised; } + bool is_initialised() + { + return ue_stack.is_valid() and ue_radio.is_init() and ue_phy.is_initialized() and gnb_stack.is_valid() and + initialised; + } bool run_tti() { @@ -156,18 +214,21 @@ class test_bench } // Feed gNb the UE transmitted signal - srsran::rf_timestamp_t gnb_time = {}; - std::vector gnb_rx_buffers(1); + std::vector gnb_rx_buffers(1); gnb_rx_buffers[0] = gnb_worker->get_buffer_rx(0); - ue_phy_com.read(gnb_rx_buffers, sf_sz, gnb_time); + ue_radio.read_tx(gnb_rx_buffers.data(), sf_sz); + + // Run the UL channel simulator + ul_channel.run(gnb_rx_buffers.data(), gnb_rx_buffers.data(), (uint32_t)sf_sz, gnb_rx_time.get(0)); - // Set gNb time + // Set gNb TX time + srsran::rf_timestamp_t gnb_time = gnb_rx_time; gnb_time.add(TX_ENB_DELAY * 1e-3); - // Run the UL channel simulator - ul_channel.run(gnb_rx_buffers.data(), gnb_rx_buffers.data(), (uint32_t)sf_sz, gnb_time.get(0)); + // Advance gNb Rx time + gnb_rx_time.add(1e-3); - // Set gnb context + // Set gNb context srsran::phy_common_interface::worker_context_t gnb_context; gnb_context.sf_idx = slot_idx; gnb_context.worker_ptr = gnb_worker; @@ -179,41 +240,26 @@ class test_bench gnb_phy_com.push_semaphore(gnb_worker); gnb_phy.start_worker(gnb_worker); - // Get UE worker - srsue::nr::sf_worker* ue_worker = ue_phy.wait_worker(slot_idx); - if (ue_worker == nullptr) { - return false; - } - // Feed UE the gNb transmitted signal srsran::rf_timestamp_t ue_time = {}; std::vector ue_rx_buffers(1); - ue_rx_buffers[0] = ue_worker->get_buffer(0, 0); + ue_rx_buffers[0] = rf_buffer.get(0); gnb_phy_com.read(ue_rx_buffers, sf_sz, ue_time); - // Set UE time - ue_time.add(TX_ENB_DELAY * 1e-3); - // Run the DL channel simulator dl_channel.run(ue_rx_buffers.data(), ue_rx_buffers.data(), (uint32_t)sf_sz, ue_time.get(0)); - // Set gnb context - srsran::phy_common_interface::worker_context_t ue_context; - ue_context.sf_idx = slot_idx; - ue_context.worker_ptr = ue_worker; - ue_context.last = true; // Set last if standalone - ue_context.tx_time.copy(gnb_time); - ue_worker->set_context(ue_context); + // Write signal in UE radio buffer, this triggers UE to work + ue_radio.write_rx(ue_rx_buffers.data(), sf_sz); - // Run UE stack - ue_stack.run_tti(slot_idx); + // Throttle UE PHY by running stack tick + ue_stack.tick(); - // Start UE work - ue_phy_com.push_semaphore(ue_worker); - ue_phy.start_worker(ue_worker); + // Increment slot index, the slot index shall be continuous + slot_idx = (slot_idx + 1) % (1024 * SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz)); + // Increment slot counter and determine end of execution slot_count++; - slot_idx = slot_count % (1024 * SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz)); return slot_count <= duration_slots; } @@ -222,7 +268,7 @@ class test_bench metrics_t metrics = {}; metrics.gnb_stack = gnb_stack.get_metrics(); metrics.ue_stack = ue_stack.get_metrics(); - ue_phy.get_metrics(metrics.ue_phy); // get the metrics from the ue_phy + ue_phy.get_metrics(srsran::srsran_rat_t::nr, &metrics.ue_phy); // get the metrics from the ue_phy return metrics; } }; diff --git a/test/run_lte.sh b/test/run_lte.sh index fa5f6e755f..0d4c4c3610 100755 --- a/test/run_lte.sh +++ b/test/run_lte.sh @@ -1,7 +1,7 @@ #!/bin/bash # -# Copyright 2013-2021 Software Radio Systems Limited +# Copyright 2013-2023 Software Radio Systems Limited # # This file is part of srsRAN #